Packing a scene appears to save fields inconsistently

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Solid_Turner

I’m working on a project where I routinely pack scenes and save them in a data structure to be instantiated again later. In my initial tests, this worked out exactly as desired. Certain fields that were changed in real time are preserved, including the position of the scene itself and the internal positions of its children, and modulate colors applied to the scene. Even children of the scene that are physics bodies ‘remember’ attributes such as rotation and velocity when the scene is packed.

However, other fields seem to not be saved, and I can’t figure out any rhyme or reason behind it. One child of the scene is a door that has an AnimatedSprite and StaticBody2D as children, and part of the functionality of the door is that I set the value for its CollisionShape2D “disabled” to true. But when the scene is packed, all of the values are returned to their defaults, so the AnimatedSprite does not remember which animation it is set to, and the CollisionShape2D stops being disabled.

I don’t really understand what the rule is for which fields are saved and which ones are returned to their defaults. I even tried looping through all the children of the door and setting their owners to be the scene that gets packed, but to no avail.

:bust_in_silhouette: Reply From: omggomb

Are you adding nodes via code? If so this might be an issue of setting the owner property of the added nodes. See here: Node — Godot Engine (latest) documentation in English

I’m adding some nodes via code, but those all function properly. The offending scene is added entirely through the editor. Here’s my hierarchy, since I don’t think the original post was very clear:

>Main Scene Root Node
    -> Scene A (this is the scene that get packed and re-instantiated)
            -> X
                    -> Door
            -> Y
            -> Z
            -> ...

X is one of several scenes added to Scene A through code, but this happens once when the scene is first generated, and I am careful to set their owner as Scene A. They are the scenes that function as expected (their positions within Scene A are remembered). My door is the child of one of these scenes, and it is the offending scene.

EDIT: I just tried changing my implementation so that the door is added to the hierarchy through code as a child of Scene A directly, since the other children of Scene A added through code seem to be saved fine, but it still exhibits the same problems.

Solid_Turner | 2021-06-03 18:24

If you don’t mind, I’d like to dig deeper. What is the overall goal (savegame, destroy and spawn again later etc.)? Do you actually save the packed scenes to disk (if so where?), or are you just keeping them around in memory after packing? Does this happen in the editor or in the exported game?

omggomb | 2021-06-04 06:48

Right now, it’s never saved to the disk. It’s a “destroy and spawn later” situation that I’m using to improve performance. I intend to save it to the disk eventually, but right now it’s all in memory.

Solid_Turner | 2021-06-04 12:45

OK I can reporduce this. My guess is, that because SceneX is instanced in SceneA, when packing SceneA it will still reference the original SceneX on disk. If you pack SceneX instead the disabled property is actually preserved. I also tried saving to disk or duplicating SceneA but that didn’t work. As you said, playing around with the owner property doesn’t help either. I’m out of ideas here, sorry.

If you have enough system memory you could just remove SceneA from the scene tree and keep a reference to it in code. Then add it back once you need it. Of course this will still take up memory, but at least it won’t hurt rendering. Keep in mind that _ready() is only called the first time a node enters the scene tree, so you’d have to use _enter_tree() or so where needed.

omggomb | 2021-06-05 09:06