Play switches to scene tab; graph tab strictly follows selection
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
9060da615a
commit
551a50ffc9
4 files changed
+26
-6
No files matched your search
@@ -54,8 +54,11 @@ shown on the node and editable in the inspector.
|
||||
(types are checked; a data input holds one link and is replaced), drag nodes, right-click a
|
||||
node or port to delete/disconnect, `Delete` removes the selected node, wheel zooms, dragging
|
||||
the empty canvas pans. Everything is undoable.
|
||||
- **Live view**: while playing with the Graph tab open, the exec edges and nodes that just ran
|
||||
light up – the same canvas draws editor and game, so this costs nothing extra.
|
||||
- **Selection-bound**: the Graph tab shows the behavior the current selection refers to
|
||||
(asset, placed object or node); with nothing or a non-behavior selected it is empty.
|
||||
- **Live view**: Play always switches to the Scene tab; switch back to Graph while playing and
|
||||
the exec edges and nodes that just ran light up – the same canvas draws editor and game, so
|
||||
this costs nothing extra.
|
||||
- **Runtime**: `BehaviorSystem` creates one `GraphInterpreter` per behavior entity; graphs only
|
||||
touch world entities. A runaway loop throws after 1000 steps and stops play with a notice.
|
||||
|
||||
|
||||
@@ -256,6 +256,8 @@ class Editor {
|
||||
this.world.addSystem(this.behaviors);
|
||||
this.viewport.setWorld(this.world);
|
||||
this.state.setMode('play');
|
||||
// Play always starts on the scene; the graph tab stays reachable for live tracing.
|
||||
this.showTab('scene');
|
||||
this.state.setNotice(this.world.firstOfType('camera') ? 'Playing · Esc stops' : 'This scene has no camera – nothing is rendered · Esc stops');
|
||||
if (this.world.stopRequested) this.stop();
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@ interface PortAnchor {
|
||||
|
||||
/**
|
||||
* The node graph editor for one behavior asset. Shows the graph of whatever behavior the
|
||||
* selection refers to (asset, placed object or node) and keeps showing it while unrelated
|
||||
* things are selected, so the user can flip between Scene and Graph tabs freely.
|
||||
* selection refers to (asset, placed object or node). When nothing or a non-behavior is
|
||||
* selected the editor is empty – the graph strictly mirrors the selection.
|
||||
*
|
||||
* Interactions: drag nodes, drag from port to port to connect, right-click the canvas for
|
||||
* the node palette, right-click a node or port for delete/disconnect, wheel to zoom, drag
|
||||
@@ -100,7 +100,7 @@ export class GraphEditor extends Widget {
|
||||
this.sync();
|
||||
this.needsFit = true;
|
||||
this.fitView();
|
||||
} else if (!this.asset()) {
|
||||
} else if (!wanted || !this.asset()) {
|
||||
this.assetId = null;
|
||||
this.sync();
|
||||
} else {
|
||||
|
||||
+16
-1
@@ -424,9 +424,13 @@ try {
|
||||
const restored = await graphCounts();
|
||||
check('undo restores node and edge', restored.nodes === before13.nodes + 1 && restored.edges === before13.edges + 1, JSON.stringify(restored));
|
||||
|
||||
// 13e. Live highlight: play with the graph open, hold ArrowRight → the exec edge is hot.
|
||||
// 13e. Play always starts on the Scene tab; switching back to Graph while playing shows
|
||||
// the live highlight: hold ArrowRight → the exec edge is hot.
|
||||
await clickText('▶ Play');
|
||||
await sleep(200);
|
||||
check('play switches to the scene tab', (await evaluate('__gm.tab()')) === 'scene');
|
||||
await evaluate(`__gm.showTab('graph')`);
|
||||
await sleep(100);
|
||||
await cdp.send('Input.dispatchKeyEvent', { type: 'keyDown', key: 'ArrowRight', code: 'ArrowRight', windowsVirtualKeyCode: 39 });
|
||||
await sleep(300);
|
||||
await shot('19-graph-live');
|
||||
@@ -448,6 +452,17 @@ try {
|
||||
await sleep(150);
|
||||
const varsUndone = JSON.parse(await evaluate(`JSON.stringify(__gm.state.project.assets.find(a => a.id === 'mover').variables.map(v => v.key))`));
|
||||
check('undo removes the variable', varsUndone.join(',') === 'speed', varsUndone.join(','));
|
||||
|
||||
// 13g. The graph strictly mirrors the selection: nothing / a non-behavior → empty editor.
|
||||
await evaluate(`__gm.state.select(null)`);
|
||||
await sleep(100);
|
||||
check('graph editor empties when nothing is selected', (await evaluate(`__gm.graph.current()`)) === null);
|
||||
await evaluate(`__gm.state.select({ kind: 'asset', assetId: 'cam' })`);
|
||||
await sleep(100);
|
||||
check('graph editor stays empty for a non-behavior asset', (await evaluate(`__gm.graph.current()`)) === null);
|
||||
await evaluate(`__gm.state.select({ kind: 'asset', assetId: 'mover' })`);
|
||||
await sleep(100);
|
||||
check('graph editor rebinds when a behavior is selected again', (await evaluate(`__gm.graph.current()`)) === 'mover');
|
||||
await evaluate(`__gm.showTab('scene')`);
|
||||
|
||||
check('no exceptions during run', !consoleLog.some((l) => l.startsWith('EXCEPTION')), consoleLog.filter((l) => l.startsWith('EXCEPTION')).slice(0, 3).join(' | '));
|
||||
|
||||
Reference in new issue
Block a user