BS-PR-602 - Hierarchy, parenting, and prefab structure hardening #40

Closed
opened 2026-07-10 04:03:18 -04:00 by Rbanh · 3 comments
Owner

Summary

Make the outliner a production-safe structural editor for actors, groups, and prefab instances.

Scope

  • Full-row drag targets with explicit attach, root, reorder, invalid, and multi-drag feedback.
  • Preserve world transforms when parenting/unparenting and capture parent, sibling order, and local transform in one undoable command.
  • Reject hierarchy cycles and normalize parent-plus-descendant multi-drags so subtrees are not flattened.
  • Define prefab instance boundaries, nested instance policy, and allowed structural overrides.
  • Stress deep trees, duplicate names, filtering, sort modes, locks, generated children, save/load, and undo/redo.

Acceptance criteria

  • Attach, unparent, and manual reorder are discoverable and deterministic.
  • Reparent/undo/redo preserve world placement within documented transform limits.
  • Invalid cycles and prefab-boundary violations explain why the drop is blocked.
  • Scene round-trip retains hierarchy and sibling order.
  • Automated tests cover cycle rejection, subtree multi-drag, transform preservation, and history replay.
## Summary Make the outliner a production-safe structural editor for actors, groups, and prefab instances. ## Scope - Full-row drag targets with explicit attach, root, reorder, invalid, and multi-drag feedback. - Preserve world transforms when parenting/unparenting and capture parent, sibling order, and local transform in one undoable command. - Reject hierarchy cycles and normalize parent-plus-descendant multi-drags so subtrees are not flattened. - Define prefab instance boundaries, nested instance policy, and allowed structural overrides. - Stress deep trees, duplicate names, filtering, sort modes, locks, generated children, save/load, and undo/redo. ## Acceptance criteria - [ ] Attach, unparent, and manual reorder are discoverable and deterministic. - [ ] Reparent/undo/redo preserve world placement within documented transform limits. - [ ] Invalid cycles and prefab-boundary violations explain why the drop is blocked. - [ ] Scene round-trip retains hierarchy and sibling order. - [ ] Automated tests cover cycle rejection, subtree multi-drag, transform preservation, and history replay.
Rbanh added this to the M6 - Reliability, recovery, and project workflow milestone 2026-07-10 04:03:18 -04:00
Author
Owner

Local implementation in progress (2026-07-10)

The current uncommitted pass now covers the first structural slice:

  • full remaining hierarchy row is a deterministic attach target;
  • pointer card names attach/root/reorder/blocked actions;
  • Manual sort exposes between-row reorder and a drag-only Scene Root target;
  • reparent/unparent preserves world placement and records local transform with sibling/parent history;
  • cycles are rejected;
  • parent+descendant multi-drag keeps only top-level actors so subtrees are not flattened;
  • the destination parent expands after drop;
  • focused tests cover transform preservation through undo/redo, cycle rejection, and subtree normalization.

Remaining before this ticket can close: live interaction QA, prefab-boundary policy, scene round-trip stress, deep/filter/lock cases, and committed evidence.

## Local implementation in progress (2026-07-10) The current uncommitted pass now covers the first structural slice: - full remaining hierarchy row is a deterministic attach target; - pointer card names attach/root/reorder/blocked actions; - Manual sort exposes between-row reorder and a drag-only Scene Root target; - reparent/unparent preserves world placement and records local transform with sibling/parent history; - cycles are rejected; - parent+descendant multi-drag keeps only top-level actors so subtrees are not flattened; - the destination parent expands after drop; - focused tests cover transform preservation through undo/redo, cycle rejection, and subtree normalization. Remaining before this ticket can close: live interaction QA, prefab-boundary policy, scene round-trip stress, deep/filter/lock cases, and committed evidence.
Author
Owner

Live interaction QA update

The corrected row interaction now uses Sense::click_and_drag(); the previous click-only widget was the root cause of drag-to-parent never starting.

Verified in the running ultrawide editor:

  • source drag starts from the full actor row;
  • amber full-row ATTACH target and pointer card render correctly;
  • drop attaches the actor and expands the destination;
  • the viewport actor does not jump;
  • local transform is recomputed to preserve world placement;
  • status/history exposes one Reorder Hierarchy undo entry;
  • Ctrl+Z restores the root hierarchy and original local transform.

Focused tests and strict dev-feature Clippy remain green. The ticket stays open for prefab-boundary policy and broader hierarchy stress/round-trip coverage.

## Live interaction QA update The corrected row interaction now uses `Sense::click_and_drag()`; the previous click-only widget was the root cause of drag-to-parent never starting. Verified in the running ultrawide editor: - source drag starts from the full actor row; - amber full-row ATTACH target and pointer card render correctly; - drop attaches the actor and expands the destination; - the viewport actor does not jump; - local transform is recomputed to preserve world placement; - status/history exposes one Reorder Hierarchy undo entry; - Ctrl+Z restores the root hierarchy and original local transform. Focused tests and strict dev-feature Clippy remain green. The ticket stays open for prefab-boundary policy and broader hierarchy stress/round-trip coverage.
Author
Owner

Completed the remaining hierarchy hardening locally and verified the ticket acceptance surface.

Final structural policy:

  • PrefabInstance contents are hydrated/generated and structurally read-only.
  • Supported instance overrides remain transform, material, and generated-child visibility.
  • Authored child insertion, drops into an instance boundary, and nested instances are blocked with an explicit unpack the instance first status/pointer explanation.
  • The prefab instance root itself remains movable/reorderable as one authored actor.
  • Nested/structural overrides remain owned by BS-PR-605 (#43).

Lock hardening:

  • Locked actors are excluded from viewport/hierarchy selection, gizmos, multi-drag payloads, Delete/Backspace, Ctrl+D, reset transform, F2/double-click rename, and mutating context actions.
  • Locked rows/parents are invalid structural targets.
  • Live held-drag QA showed a full-row red BLOCKED target and pointer card Cannot attach: target is locked; release left both actors at scene root. Temporary QA locks were cleared.

Regression/stress coverage now includes:

  • cycle rejection;
  • prefab-boundary and nested-instance rejection;
  • parent+descendant multi-drag normalization;
  • locked source exclusion and locked target reason;
  • world-transform preservation with undo/redo;
  • deterministic duplicate-name sorting;
  • 64-level filtered-tree descendant discovery;
  • actual serialize/deserialize round trip preserving ChildOf relationships and manual HierarchySiblingIndex order.

Documentation:

  • ADR 0005 now records the prefab structural boundary and BS-PR-605 ownership.
  • Root controls, editor feature guide, and roadmap status describe lock/prefab behavior and the shipped v2 override surface.

Final verification:

  • cargo fmt --all -- --check
  • git diff --check
  • strict workspace Clippy
  • strict dev-feature editor Clippy
  • cargo test --workspace: 146 passed, 1 intentionally ignored
  • cargo validate-levels: ok

This builds on the prior live attach/unparent/world-placement/undo QA already recorded above.

Completed the remaining hierarchy hardening locally and verified the ticket acceptance surface. Final structural policy: - `PrefabInstance` contents are hydrated/generated and structurally read-only. - Supported instance overrides remain transform, material, and generated-child visibility. - Authored child insertion, drops into an instance boundary, and nested instances are blocked with an explicit **unpack the instance first** status/pointer explanation. - The prefab instance root itself remains movable/reorderable as one authored actor. - Nested/structural overrides remain owned by BS-PR-605 (#43). Lock hardening: - Locked actors are excluded from viewport/hierarchy selection, gizmos, multi-drag payloads, Delete/Backspace, Ctrl+D, reset transform, F2/double-click rename, and mutating context actions. - Locked rows/parents are invalid structural targets. - Live held-drag QA showed a full-row red `BLOCKED` target and pointer card `Cannot attach: target is locked`; release left both actors at scene root. Temporary QA locks were cleared. Regression/stress coverage now includes: - cycle rejection; - prefab-boundary and nested-instance rejection; - parent+descendant multi-drag normalization; - locked source exclusion and locked target reason; - world-transform preservation with undo/redo; - deterministic duplicate-name sorting; - 64-level filtered-tree descendant discovery; - actual serialize/deserialize round trip preserving `ChildOf` relationships and manual `HierarchySiblingIndex` order. Documentation: - ADR 0005 now records the prefab structural boundary and BS-PR-605 ownership. - Root controls, editor feature guide, and roadmap status describe lock/prefab behavior and the shipped v2 override surface. Final verification: - `cargo fmt --all -- --check` - `git diff --check` - strict workspace Clippy - strict dev-feature editor Clippy - `cargo test --workspace`: 146 passed, 1 intentionally ignored - `cargo validate-levels`: ok This builds on the prior live attach/unparent/world-placement/undo QA already recorded above.
Rbanh closed this issue 2026-07-10 11:57:22 -04:00
Sign in to join this conversation.
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: Falling-Metal-Interactive/Blacksite#40
No description provided.