godot: Saving custom resources using the ResourceSaver.FLAG_BUNDLE_RESOURCES flag causes crash on load.
Godot version
4.0 dev (106b68050) 4.0 dev (432b25d36)
System information
windows 10
Issue description
it appears loading a custom resource using ResourceLoader.load() on a file saved with the ResourceSaver.FLAG_BUNDLE_RESOURCES can result in a failure to load the file and an error “<custom_class> hides a global script class.”
Steps to reproduce
create a custom Resource, save it with the ResourceSaver.FLAG_BUNDLE_RESOURCES flag, then use ResourceSaver.load()
Minimal reproduction project
About this issue
- Original URL
- State: open
- Created 2 years ago
- Reactions: 18
- Comments: 18 (3 by maintainers)
The problem is that Godot 4.x GDScript favours a lot the use of
class_namein the project, since type inference is much better and mostcyclic dependencyproblems were solved - soResourceSaverwon’t work most of the time the user creates a custom resource with nested resources within. I think there should at least be an option of bundling all nested resources with the exception of scripts, or have a resource setting to force specific subresources to be saved as paths.I thought of a way to mitigate the problem while it’s still present in the engine. It works by changing bundled scripts with a class name to simply extending the class_name instead. Perhaps it helps one or the other. utils.zip
The problem is when the subresource exists in the project files, just a reference to that resource is saved, even if you duplicate the resource holding the subresource. So if you changed the value of those like say an that won’t work. It can be avoided by duplicating them before putting them in the array, or going through the arrays and manually changing them to a duplicate, which is good as long as you are aware of it… or the flag to bundle resources can be used. And that has the problem with the class_names, hence my workaround (even if there are some errors for some cases in it apparently).
Another issue is loading savegames, where there’s a possibility for arbitrary code execution upon load() if those have scripts, so I end up only using scripts with class name for resources I intend to load from the user:// directory and turn all scripts to a single line to extends ClassName or extends Resource.
It seems saving resources is still completely broken? I’ve been searching online and I’ve found many people with this issue with no solution. I am confused because saving resources should be something pretty much everyone does, how can it be not working? Is this way of saving just wrong? Is there another reccomended way to save nested resources, for example by seperating the data and the logic of your resource somehow without losing the conveniences of resources?
still having this issue. Anyone figure out a workaround? Creating the subresources at runtime seems to work if you exclude the ResourceSaver.FLAG_BUNDLE_RESOURCES flag but it’s a pain to do that.
I created a little playground project. Nested Resource Saving.zip
res://Resources/SaveGame.tresis the master resource with save/load flag options. On saving the.tresfile content is displayed in a TextEdit. WhenFLAG_BUNDLE_RESOURCESis selected it embeds the script of nested resources (with class_name) and upon loading it triggers the bug. Any other option refers to the array of classes like this:resources = Array[Resource("res://Resources/CollectibleResource.gd")]([ExtResource("1_avxuu"), ExtResource("2_6my64"), ExtResource("3_oe2tv")])But also they all are saved the same as without flags, is it supposed to be like that? FLAG_BUNDLE_RESOURCES is the only one that packs actual values of nested resources.retested in Godot 4 RC4, The issue is still present. The project still crashes on load, and it appears to be a namespace error of some sort. It’s like Godot is saving the class name of the nested resource, then when it loads the resource it becomes incapable of recognizing that the nested resource is an instance of the class registered in godot viaclass_name, and thus throws an error. That’d be my guess without delving into the editor source code.the problem pops up when
var mrpresource = ResourceLoader.load(file_path)is run, so i’d look into the aspects of theResourceLoader.load()function that are responsible for checking for namespace conflicts and processing the class of the saved resource.