Saving as Packedscene: avoid duplicate data and infinite loops with "PackedNodeReference" #9275
LO-0116
started this conversation in
Engine Core
Replies: 1 comment 2 replies
-
I think they should use id just as Resource do so something like
I feel like this would be more consistent. Moreover the parent could also use the id instead of a path but not sure if it would be usefull. |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Describe the project you are working on
A game which saves and loads game states using
PackedScene
. Some nodes saved contain references to other nodes which ought to be saved. Some of these references are stored in arrays and dictionaries. Some nodes contain references to other nodes which contain a reference pointing back to the first node (mutual reference).Describe the problem or limitation you are having in your project
When calling
pack(...)
on a PackedScene instance, several errors appear due to the way Godot currently stores node references:For the first problem, consider this class:
If your scene contains two
Person
nodes, call them Adam and Eve, they may have mutual references. E.g.:Adam.spouse = Eve; Eve.spouse = Adam
When attempting to save Adam, Godot will not only create a block of information containing everything about Adam, but it will also create a block of information containing everything about Eve, and because Eve contains a reference to Adam, the block of information about Eve will also contain a complete block of information about Adam, and so on, causing the game to stall.For the second problem, while storing references to other nodes in the scene as a single
@export var
is okay, trying to save references inside exported dictionaries and arrays cause strange, dysfunctional behaviors when loading. See details here.Describe the feature / enhancement and how it helps to overcome the problem or limitation
I believe the problems above are caused by
PackedScene.pack
creating a complete block of information when trying to save any node references stored in any@export
variables. The solution to this would be saving only a reference of some kind instead of the complete information.Here is what my suggestion for how
PackedScene.pack
should function:root
, find all nodes whose owner isroot
.root
and all nodes it owns. PackedNodeReference should be a unique string created based on the node it corresponds to.pack
as usual, but when attempting to pack a variable that references another node, check to see if the node being packed has a PackedNodeReference in the list created above, if so, the variable should store that PackedNodeReference instead of a complete block of information.instantiate()
on a PackedScene, use PackedNodeReference to reestablish saved references.Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
This is what a PackedScene currently looks like when saving both a node and a reference to a node:
this is what it should look like with with PackedNodeReference:
Note that the massive line in the
my_gamma_array
field used to store information functionally identical to the block about the nodeGamma
right below it.If this enhancement will not be used often, can it be worked around with a few lines of script?
I believe it will be used often as the user community move away from manually saving with JSON or resources. Both JSON and resource-based saves require manual saving and loading functions in the objects affected and are thus error-prone. JSON lacks many of Godot's data types and resource-based saves have known security issues.
Is there a reason why this should be core and not an add-on in the asset library?
Because it addresses problems with an existing core feature (saving via PackedScene).
Beta Was this translation helpful? Give feedback.
All reactions