godot: Resource.duplicate(true) doesn't duplicate subresources stored in Array or Dictionary properties
Godot version
4.0.stable
System information
Manjaro Linux
Issue description
This behavior is poorly documented, and it breaks expectations. It is mentioned in the docs only under Array.duplicate(), but not Dictionary class, or Resource.duplicate().
This affects also “Make Unique” and “Make Unique (Recursive)” for custom resources.
Here’s the problematic code: https://github.com/godotengine/godot/blob/fc7adaab7b3856a7831d402ea2bbb27efe7b7d8a/core/variant/variant_setget.cpp#L1889-L1900
Steps to reproduce
For simple code see reproduction project.
To reproduce on your own:
- Have a resource with a property of type Array[SomeOtherResource]
- One of the following: 2a) “Make Unique” on parent resource in inspector. 2b) Or duplicate(true) from code.
- Check if SomeOtherResource items inside array are unique.
Minimal reproduction project
About this issue
- Original URL
- State: open
- Created a year ago
- Reactions: 49
- Comments: 18 (1 by maintainers)
It’s troublesome that this isn’t fixed yet, my game relies a lot on duplicating resources and arrays and I was really miffed when I just found out deep copying isn’t functioning properly. This should be tracked and added to a milestone.
I confim that
my_resource = my_resource.duplicate(true)doesn’t make unique sub-resources as the documentation says. Godot 4.1.Can this at least be updated in the documentation ASAP even if it won’t be fixed any time soon? The Resource.duplicate docs confidently state:
Which is clearly not true and causing headaches for many users in this thread. It’s now been over 1 year with no comments from the team.
Oh my god, I was confused why all my enemy mobs die at the same time like they have shared HP. Had to make multiple loops to manually duplicate subresources in my ready function to work around this. This is rough for stat heavy games out there.
I can’t believe this hasn’t been fixed, my project relies heavily on resources that have arrays or dictionaries in them, for localToScene to not work with them is really bad. I’m now having to write duplication methods for more than 10 different classes.
I’ve tested this recently in 4.2.1 and no, it wasn’t fixed when using
Arrayat least. If you think it’s fixed, please post a simple example of it working, as it might help solve the issue.Edit: So, I kinda figured it out where my (and many others) issues come from regarding duplicating resources and saving and loading them.
The initial problem is that saving and loading subresources just does not work if you simply save and load using ResourceSaver and RexourceLoader IF any of your subresources are actually instanced. ResourceSaver will just save a reference to the project file instance.
Now, the "FLAG_BUNDLE_RESOURCES " should fix it, but it is actually not working right now (#65393)
If you want to save your instanced subresources you need to deep duplicate them using “BaseResource”.
It’s also important du make deep duplications when you have a resource “template” saved that you later want to add to an array List multiple times.
I am trying to use this, together with: https://github.com/godotengine/godot/issues/65393#issuecomment-1847601360 to save and load resources that contain an Array with other Resources.
It does not work unfortunately:
Has anyone managed to save and load resources that contain an Array of another resources?