Run Mode Guide
Run mode = live choreography execution. The scene becomes alive.
Lifecycle -- startRunMode():
- Snapshot entity transforms (position, scale, rotation, opacity, visible)
- Lazy-import
@sajou/core(Choreographer, BrowserClock) - Create RenderAdapter (Three.js bridge) + CommandSink + Clock + Choreographer
- Convert editor ChoreographyDefs -> runtime ChoreographyDefinitions
- Choreos with filtered wires -> registered under synthetic type
__f:<choreoId> - Choreos without filters -> registered with original
ontype
- Choreos with filtered wires -> registered under synthetic type
- Create BindingExecutor (peer of choreographer for property bindings)
- Subscribe to
onSignal()-- wire-aware dispatch with filter chains - Activate run mode UI (workspace--running class)
- Start spritesheet animations (idle cycles)
Lifecycle -- stopRunMode(): 0. Clear speech bubbles + stop spritesheet animations (restore original textures)
- Dispose choreographer
- Dispose binding executor
- Unsubscribe signal listener
- Restore entity snapshot (position, scale, rotation, opacity, visible)
- Dispose filter chains
- Clean up state
Signal dispatch flow in run mode:
Signal arrives
|
for each choreography:
|
+-- Check if signal.type is in effectiveTypes
|
+-- If filtered choreo:
| For each input wire matching signal.type:
| Run FilterChain.process(signal)
| If passes -> dispatch "__f:<choreoId>"
|
+-- If unfiltered choreo:
Dispatch original type (once per type)
|
+-- Binding executor evaluates in parallel
+-- Signal counter incrementedBindings:
- Peer of choreographer -- evaluates on every signal dispatch
- Direct property assignments:
animation.state,visible,opacity,rotation,scale,position.x,position.y,teleportTo - Speech:
speechproperty routes text to Canvas2D speech bubbles above entities. Streaming signals (text_delta,thinking) useappendSpeechText()(typewriter effect); non-streaming usesetSpeechText()(full replace). Per-entity visual config viaSpeechBubbleConfigonPlacedEntity(colors, font size, opacity, tail position, retention delay) - Mapping functions:
lerp,clamp,step,smoothstep - Uses
whenclause matching for conditional execution
Editor -> Runtime conversion:
- Strips editor-only fields (id, nodeX, nodeY, collapsed)
- Flattens
paramsbag into step object - Resolves
defaultTargetEntityId-> stepentityfield - Structural actions (parallel, onArrive, onInterrupt) convert recursively
Binding transitions:
Float properties (scale, opacity, rotation, position.x, position.y) support animated transitions instead of instant assignment. When a binding has a transition field, the property animates smoothly to the target value.
transition: {
targetValue: number; // final value
durationMs: number; // animation duration
easing: ChoreographyEasing; // linear | easeIn | easeOut | easeInOut | arc
revert?: boolean; // return to original value after?
revertDelayMs?: number; // wait before reverting
}The animation engine (run-mode-bindings.ts) uses requestAnimationFrame for smooth interpolation. Interrupts are handled gracefully — a new signal starts the transition from the current interpolated value, not the original.
Easing functions:
- linear — constant speed
- easeIn — slow start, accelerating
- easeOut — fast start, decelerating
- easeInOut — slow start and end
- arc — overshoot and settle
Non-float properties (visible, animation.state, moveTo, followRoute, teleportTo) remain instant assignment.
The transition config popup appears in the radial binding menu when binding a float property. It provides range hints: scale (0.1–10), opacity (0–1), rotation (0–360°), position in pixels.
Full-window preview mode:
Press F to toggle full-window preview. This expands the Visual node to fill the entire browser window, automatically activates run mode and the hand tool. Press Escape or F again to exit.
Full-window mode is useful for presentations, demos, and focused monitoring of a running scene.
Key files:
tools/scene-builder/src/run-mode/run-mode-controller.ts-- lifecycle managertools/scene-builder/src/run-mode/run-mode-bindings.ts-- binding executortools/scene-builder/src/run-mode/run-mode-state.ts-- snapshot/statetools/scene-builder/src/run-mode/run-mode-sink.ts-- CommandSink adaptertools/scene-builder/src/run-mode/run-mode-animator.ts-- spritesheet animationstools/scene-builder/src/run-mode/speech-bubble-state.ts-- speech bubble state + ticktools/scene-builder/src/canvas/speech-bubble-renderer.ts-- Canvas2D bubble rendering