Skip to content

feat: Scene | Runtime tabs in the graph during play mode (closes #898)#900

Open
marquezmiguel wants to merge 1 commit into
BabylonJS:masterfrom
marquezmiguel:feat/live-graph-during-play
Open

feat: Scene | Runtime tabs in the graph during play mode (closes #898)#900
marquezmiguel wants to merge 1 commit into
BabylonJS:masterfrom
marquezmiguel:feat/live-graph-during-play

Conversation

@marquezmiguel

Copy link
Copy Markdown

Summary

Implements #898: while playing, the graph now shows two tabs following the inspector's tabs pattern — Scene keeps the edited scene fully editable exactly as before (undo/redo, context menu, drag and drop, save), and Runtime shows the live hierarchy of the play scene: objects created by scripts appear as they spawn, can be selected and inspected, and tweaked through the inspector (volatile changes, lost on stop). This mirrors the Local/Remote workflow of other editors for data-driven games where most content is spawned at runtime.

When the game is not playing, behavior is byte-equivalent to the current editor: no tabs, no guards, nothing changes.

Changes made

  • Graph: dual tree state (edited scene / play scene) with tabs rendered only while playing. Separate trees keep id collisions between the exported scene and the play scene from leaking selection or expansion states across tabs.
  • Selection/expansion preservation across refreshes is now indexed by id (Map) instead of scanning the previous tree per node: runtime scenes can hold tens of thousands of nodes and the previous O(n²) matching froze the UI (measured 46s → ~0.2s per refresh on a 22k-node scene).
  • Structural operations (rename, reparent, remove, clone, paste, drops, enabled toggles) are guarded per object: play scene objects are read-only, edited scene objects keep the exact current behavior even while playing.
  • Undo/redo: registerUndoRedo items now carry an optional object used by a volatile predicate installed during play — edits on edited scene objects keep recording history, edits on play scene objects execute without polluting the stack (they would reference disposed objects after stop).
  • Play lifecycle hardening: re-entrance guards on restart (double restart / src watcher / ipc triggers), stop-during-loading and stop-during-restart are now safe, and forceCompileAllSceneMaterials resolves when its scene is disposed mid-compilation instead of hanging forever.
  • Scene inspector: global sections (physics gravity, rendering pipelines) are hidden when inspecting the play scene — they edit the edited scene and would silently persist without undo.
  • New tools/scene/play/runtime.ts helpers (isScenePlaying, getObjectScene, isPlaySceneObject) shared by all the guards, with unit tests. Existing behavior is preserved by 72 passing tests.

Benefits

  • The editor becomes usable for data-driven / procedurally-loaded games (worlds loaded from data at runtime), where today the graph shows nothing of what actually runs.
  • Runtime objects can be selected and inspected live (materials, transforms) like in other engines' play modes.
  • No behavior change at all outside play mode, and the edited scene can still be worked on while the game runs.

Follow-ups (out of scope, happy to discuss)

  • Viewport picking of runtime objects while playing.
  • Gizmos attached to runtime objects (requires a utility layer on the play scene).
  • Structural editing of the play scene (Unity-like volatile hierarchy edits) and an "apply play changes to scene" action.

Note for reviewers: future registerUndoRedo call sites should pass object when reachable during play; items without it fall back to the inspector's edited object to classify volatility.

🤖 Generated with Claude Code

While playing, the graph shows two tabs following the editor's tabs
pattern: "Scene" keeps the edited scene fully editable exactly as
before (undo/redo, context menu, drag and drop, save), and "Runtime"
shows the live hierarchy of the play scene — script-created objects
appear as they spawn, can be selected and tweaked in the inspector
(volatile changes, lost on stop).

The play scene lives in a separate tree state so id collisions with
the exported scene never leak selection or expansion between tabs, and
preservation matching is indexed by id so large runtime scenes (tens of
thousands of nodes) refresh in milliseconds. Structural operations are
guarded per object instead of globally, undo/redo registration
classifies items by the scene the edited object belongs to, and the
play lifecycle is hardened against re-entrance and stop-during-loading
races.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant