Compiled scenes
Resolving frames, reading typed exports, looking up actors, memoizing, and reflecting for editors.
CompiledScene is what createScene returns. It
holds the authored record and turns frame numbers into state.
compiled.fps; // 30
compiled.totalDuration; // authored length, in framesResolving a frame
const state = compiled.at(90);
// Scene exports — typed
state.scene.title;
// Camera
state.camera.zoom;
state.camera.centerX;Typed lookup
For actors that were not exported, look them up by blueprint rather than by string type. The blueprint carries the type, so no cast is needed.
state.findActor(TextBlock); // first instance
state.findActors(TextBlock); // all instances
state.getActor("title", TextBlock); // by id, typedPrefer exports
A lookup is a search; an export is a name. Return the actors that matter from the scene generator and the call sites stay refactor-safe.
Resolution options
Pass host values at resolution time rather than baking them into the scene.
const state = compiled.at(frame, {
channelValues: new Map([[createCellKey(actorId, "measuredBox"), box]]),
viewport: { width: 1920, height: 1080 },
});channelValues overrides are per-resolution only — they never write through to the
channel publication store, which is what makes them safe to
compute inside a React render.
Memoization
memoizedScene(compiled) wraps at() with an LRU keyed on (frame, viewport) and
invalidated per channel key: publishing to channel A does not bust a cached frame that
only read channel B.
const memo = memoizedScene(compiled, { lru: 4 });
const state = memo.at(frame);SceneRenderer uses it by default.
Reflection
compiled.reflect(frame?) returns editor-facing data — ids, types, tree structure and
signal values — without needing a typed blueprint. This is the surface an editor or an
inspector reads.
const reflection = compiled.reflect(90);
reflection.getActor("title"); // by id, untypedResolvedActor
What every lookup and export resolves to:
interface ResolvedActor {
id: string;
type: string;
scopeId: string;
parentId: string | null;
slotName: string | null;
slotChildren: Record<string, string[]>;
signals: Record<string, unknown>;
channels: Record<string, ResolvedChannelHandle<unknown>>;
localLayout: ResolvedLayoutBox;
worldLayout: ResolvedLayoutBox;
effects: ActiveEffect[];
spawnFrame: number;
despawnFrame?: number;
}Do not read signals by string key
signals and channels exist for reflection and tooling. In application and renderer
code the blueprint is known, so use scene exports or findActor(Blueprint) — reaching
into signals["opacity"] throws away the types the runtime went to trouble to give you.