godotengine / godotengine/godot
`EditorExportPlugin`: `skip()` can cause issues when customizing a `CompressedTexture2D`
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Tested versions
Commit 932c191 onwards
### System information
Godot v4.3.beta (b97110cd3) - Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 980 Ti (NVIDIA; 31.0.15.3699) - Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz (8 Threads)
### Issue description
I made changes to `EditorExportPlugin` in PR #93878 that allowed all resources to be skipped through the `_export_file` function. I have found no issues with most imported files, such as `.wav` audio files, but have found an issue that I believe is specific to `Texture2D`'s interaction between `_customize_resource` and `skip()`.
**Works:** Skipping an `AudioStreamWAV` and customizing a different `AudioStreamWAV` to be replaced by the skipped `AudioStreamWAV`.
**Does not work:** Skipping a `CompressedTexture2D` and customizing a different `CompressedTexture2D` to be replaced by the skipped `CompressedTexture2D`.
~~This is important functionality for porting because it allows the developer to, for example, replace existing PC-specific textures (such as an Xbox controller diagram) with mobile-specific textures (such as a touch-screen controls diagram). This functionality is needed to fully implement https://github.com/godotengine/godot-proposals/issues/10051 as an add-on for all resource types, including textures.~~ (**Update:** there is a workaround, see my [next comment](https://github.com/godotengine/godot/issues/94045#issuecomment-2214680116).)
### Explanation
When a resource is customized in `EditorExportPlugin` , a new `.res` file is added to the `exported` folder. For something like `AudioStreamWAV`, this will contain all of the resource data, so it doesn't matter if the source resource data is skipped because a full copy is made into the newly customized resource.
...But for a `CompressedTexture2D` resource, the full resource data is not copied. Instead, the new `.res` file will simply point to a `.ctex` file inside of the `imported` folder. So if this source texture is skipped, it will no be copied to the `imported` folder and this customized resource will now be invalid.
### Development Status
I'm looking into a fix for this, but I would appreciate any thoughts that others might have on how to correctly solve this.
I don't see this as a regression in any way. It's just a very specific interaction that was not fully addressed when texture skipping was introduced in PR #93878.
### Steps to reproduce
Create an `EditorExportPlugin` with something like this:
``` GDScript
func _begin_customize_resources(platform: EditorExportPlatform, features: PackedStringArray) -> bool:
return true
func _customize_resource(resource: Resource, path: String) -> Resource:
if path == "res://default.svg":
return load("res://mobile.svg")
return null
func _export_file(path: String, type: String, features: PackedStringArray) -> void:
if path == "res://mobile.svg":
skip()
```
...And then export a project that uses `res://default.svg`.
Additionally, order doesn't matter: Renaming `res://mobile.svg` to `res://amobile.svg` does not change the behaivour.
### Minimal reproduction project (MRP)
[Testxport-customize-skip.zip](https://github.com/user-attachments/files/16120201/Testxport-customize-skip.zip)
Contributor guide
Research direction
Start with the EditorExportPlugin entry points _export_file(), _customize_resource(), and skip(), then reproduce the behavior with the linked minimal reproduction project. Trace how customized CompressedTexture2D resources reference imported .ctex data, and verify that replacing a texture while skipping its source still produces a valid export without breaking the existing AudioStreamWAV behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- game-dev, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100