Blacksite/docs/adr/0026-stable-scene-composition-and-active-document.md
Rbanh 0553a85220
Some checks are pending
CI / Format, lint, test, build (push) Waiting to run
Build production-ready editor authoring workflows
2026-07-11 12:41:04 -04:00

2.7 KiB

ADR 0026: Stable Scene Composition And Active Document

Status

Accepted

Context

One monolithic dynamic scene does not scale to daily content production. Multiple authors and disciplines need geometry, lighting, gameplay, and set dressing to remain separable, but Bevy Entity identifiers are allocated at runtime and cannot identify actors or ownership across files. The editor also materializes one authored document into the live ECS world, where hydration, selection, history, PIE, and rendering operate.

Decision

  • Persist one reflected SceneComposition resource in each dynamic scene. It owns a stable scene_id and project-relative SubsceneReference entries with stable reference IDs plus loaded and locked flags.
  • Reject absolute/escaping paths, empty or duplicate reference IDs, missing targets, duplicate scene IDs, and cyclic graphs through the same scene crate validator used by editor load, project inspection, and cargo validate-levels.
  • Keep one scene tab materialized in the ECS world. Inactive tabs retain normalized authored RON, path, dirty state, and recovery location in memory. Switching serializes the outgoing authored roots and hydrates the incoming snapshot.
  • Tag hydrated subscene actors with runtime-only ComposedSceneMember ownership. They participate in the active composition and PIE but are excluded from the owner scene's save and recovery payload.
  • Treat an unloaded reference as absent from the world. Loaded references inherit their authored visibility; locked references enter the hierarchy's existing read-only lock path. Nested locks propagate downward.
  • Composition add/remove/load/lock changes are ordinary undoable history commands. Because existing entity-edit history stores runtime entity IDs, activating another tab clears that tab's history instead of retaining commands that could target rematerialized entities incorrectly.

Consequences

  • Cross-scene identity is stable and reviewable without leaking runtime entity IDs into files.
  • PIE, viewport rendering, and build validation see the same active materialized composition.
  • Saved dirty tabs, including inactive ones, receive independent bounded recovery generations.
  • Legacy scenes load without a composition resource using a deterministic path-derived identity; their next save promotes that identity into the scene resource.
  • The open tab set is session-local; safe restart resumes the last active authored scene. Unsaved untitled tabs remain outside automatic recovery until a future session schema can restore them without guessing a destination.
  • Preserving entity-edit undo stacks across tab materialization requires stable-ID history commands and is future work; clearing them is explicit and safe.