Skip to content

reparent_node flattens instanced sub-scenes: the do path sets owner = scene_root on every descendant #1118

Description

@rangogamedev

Version: observed on 4.0.4 with Godot 4.7.2. The do-path code below is unchanged in 4.2.3 (f58314d, also current main); I checked the source, but did not re-run the repro on 4.2.3.

Code: plugin/addons/godot_ai/handlers/node_handler.gd, reparent_node. After snapshotting
descendants := _collect_descendants(node), the do path records
add_do_method(child, "set_owner", scene_root) for every descendant. The undo path (fixed for
#904) restores each descendant's prior owner correctly.

Effect: when the reparented node is, or contains, an instanced scene, the instance's
internal nodes (owned by the instance root, not the edited scene root) become scene-owned. On save
they are written into the parent .tscn as local nodes, and the instance's overrides are lost.
Seen on a real scene: four instanced widgets were flattened, and one lost its rect override.

Repro:

  1. In a scene, instance a sub-scene W.tscn that has at least one child node, under node A.
  2. reparent_node A (or the instance itself) to another parent.
  3. Save, and open the .tscn: W's internal nodes now appear as local nodes of the parent scene.

Expected: the same as the editor's Scene-dock reparent: only nodes that were owned by the
edited scene root get scene_root again. Nodes owned by an instance root keep that owner, and a
null owner stays null.

Suggested fix: in the do path, record each descendant's snapshotted prior owner (the same
prior_owner the undo loop already uses), instead of scene_root. remove_child clears only
owners that sit outside the pruned subtree (which is scene_root here), so restoring the snapshot
is enough. Regression test: reparent a subtree containing an instance, then assert that an
internal node's owner is still the instance root.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions