API reference

Every public class, method, and event in @codexo/exojs. Generated from source.

C

classSceneDirector

@codexo/exojs / core / stable

Single-active-scene controller owned by Application. Holds at most one active Scene (the current "screen"); SceneDirector.change switches to a new scene - ending the previous one permanently - with an optional SceneTransition. The `Registry` generic (inferred from `ApplicationOptions.scenes`) types the scene registry passed at construction. This class stores it bidirectionally (`byConstructor`/`byKey`) - `byConstructor` backs constructor-target registration/diagnostics checks, `byKey` backs key-based navigation (`change`/`restore` given a registered string key instead of a constructor). There is no scene stack: overlays, HUDs and pause menus belong on Scene.ui (the screen-fixed UI layer). Each activation is owned internally by a `SceneScope`, which attaches the scene's facilities, gates per-frame dispatch by SceneState, and runs teardown in the normative order; `SceneDirector` itself only tracks which scope is active and drives the transition machinery. Per-frame dispatch is split into entry points called by Application.update in normative order: SceneDirector.fixedUpdate (zero or more times), SceneDirector.update, then SceneDirector.draw. An active SceneTransitionSession is driven separately each frame via SceneDirector._updateTransition and SceneDirector._renderTransition, composited above or below the app draw systems depending on the session's `placement`.

3
props
14
methods
7
events
Import
import { SceneDirector } from '@codexo/exojs'

Single-active-scene controller owned by Application. Holds at most one active Scene (the current "screen"); SceneDirector.change switches to a new scene - ending the previous one permanently - with an optional SceneTransition.

The `Registry` generic (inferred from `ApplicationOptions.scenes`) types the scene registry passed at construction. This class stores it bidirectionally (`byConstructor`/`byKey`) - `byConstructor` backs constructor-target registration/diagnostics checks, `byKey` backs key-based navigation (`change`/`restore` given a registered string key instead of a constructor).

There is no scene stack: overlays, HUDs and pause menus belong on Scene.ui (the screen-fixed UI layer). Each activation is owned internally by a `SceneScope`, which attaches the scene's facilities, gates per-frame dispatch by SceneState, and runs teardown in the normative order; `SceneDirector` itself only tracks which scope is active and drives the transition machinery.

Per-frame dispatch is split into entry points called by Application.update in normative order: SceneDirector.fixedUpdate (zero or more times), SceneDirector.update, then SceneDirector.draw. An active SceneTransitionSession is driven separately each frame via SceneDirector._updateTransition and SceneDirector._renderTransition, composited above or below the app draw systems depending on the session's `placement`.

Constructors1
Methods14
Switch to a fresh instance of target (a registered key or a constructor), ending the previously active scene permanently - unless options.suspendCurrent is set, in which case the outgoing scene is suspended and retained (keyed by its constructor) for a later SceneDirector.restore call instead. Ordinary switching always creates a fresh instance. The new scene completes load()+init() while the outgoing scene is still fully live and driving frames; the switch itself is then atomic: once the incoming scope has been prepared, nothing past that point can fail or roll back - the outgoing scope is suspended or torn down and the incoming scope activated as one uninterruptible step, and the returned promise additionally waits for the outgoing scope's permanent teardown to fully settle (skipped when suspendCurrent is set, since there is nothing to tear down). An optional transition (see ChangeSceneOptions.transition) drives the switch through a SceneTransitionSession: the atomic commit boundary is deferred until the session requests it via environment.commit(), and the returned promise resolves only once the session finishes. With no transition - and no registry-level default for the target - the switch runs the direct fast path. Rejects with ConcurrentSceneNavigationError when another navigation is already in flight (dev and production builds - no queueing); with UnregisteredSceneError (dev builds for a constructor target, every build for an unresolvable registry key) when target is not present in ApplicationOptions.scenes; with RetainedSceneConflictError when target already has a retained instance (restore or unload it first).
Switch to a fresh instance of target (a registered key or a constructor), ending the previously active scene permanently - unless options.suspendCurrent is set, in which case the outgoing scene is suspended and retained (keyed by its constructor) for a later SceneDirector.restore call instead. Ordinary switching always creates a fresh instance. The new scene completes load()+init() while the outgoing scene is still fully live and driving frames; the switch itself is then atomic: once the incoming scope has been prepared, nothing past that point can fail or roll back - the outgoing scope is suspended or torn down and the incoming scope activated as one uninterruptible step, and the returned promise additionally waits for the outgoing scope's permanent teardown to fully settle (skipped when suspendCurrent is set, since there is nothing to tear down). An optional transition (see ChangeSceneOptions.transition) drives the switch through a SceneTransitionSession: the atomic commit boundary is deferred until the session requests it via environment.commit(), and the returned promise resolves only once the session finishes. With no transition - and no registry-level default for the target - the switch runs the direct fast path. Rejects with ConcurrentSceneNavigationError when another navigation is already in flight (dev and production builds - no queueing); with UnregisteredSceneError (dev builds for a constructor target, every build for an unresolvable registry key) when target is not present in ApplicationOptions.scenes; with RetainedSceneConflictError when target already has a retained instance (restore or unload it first).
destroy(): void
Tear down every owned resource: abort an in-flight transition session, await any scene teardown already in flight, destroy the active scene, destroy every retained scene, destroy every preloaded-but-never-consumed scene, then destroy all Signals. Fires _dispose() (async teardown) and returns immediately - errors are reported through the app error pipeline rather than propagated, matching every other synchronous destroy() in the engine. An async shutdown path that needs to know teardown has fully finished may await SceneDirector._dispose directly instead of calling this method.
Draw entry point called by Application.update, after this frame's SceneDirector.update: draws the active scene - gated by its SceneScope state - then its systems' draw phase, then its screen-fixed UI layer on top. No-op when no scene is active or the active scope's state does not permit drawing. An active transition session's own visual output is drawn separately - see SceneDirector._renderTransition. When a session requested currentFrame: 'texture', the active scope's full render surface is redirected into the pooled offscreen texture instead of straight to the canvas, so the session can composite it itself.
Drive one fixed-timestep step on the active scene, gated by its SceneScope state (only Active dispatches): the scene's fixedUpdate() hook, then its systems' fixed-update phase. Called zero or more times per frame by the Application loop, ahead of SceneDirector.update. No drawing or transition advance happens here - those are per-frame, not per fixed step.
pause(): boolean
Pause the active scene. Its fixedUpdate/update stop running, but draw keeps rendering - the canonical "pause menu drawn over a frozen world" shape. Input and interaction are not both gated the same way: a SceneInputs binding whose SceneAvailability when option is left at its default ('active') stops dispatching while paused, but SceneInteraction.observe/SceneInteraction.scope have no pause gate at all and keep firing pointer hit-testing and Tab traversal against the frozen world - a caller that needs interaction to stop too has to check SceneDirector.paused in its own handlers. This does not change SceneDirector.state - see SceneDirector.paused instead. No-op (returns false) when no scene is active, it is not currently Active, or it is already paused.
Frame-closing entry point called by Application.update once the backend has flushed: runs the active scene's systems' postFrame phase, gated by its SceneScope state. budget reports the frame's remaining time - see FrameBudget.
Frame-opening entry point called by Application.update ahead of every other phase: runs the active scene's systems' preFrame phase, gated by its SceneScope state.
Transparently pre-warm a fresh instance of target into SceneState.Ready - fully prepared (load() + init() complete), but never activated. A later SceneDirector.change call for the same constructor with Object.is()-matching data consumes it automatically, skipping load()/ init() entirely. Not exclusive of an active or retained instance of the same constructor - preloading "the next GameScene" while a different GameScene instance is currently playing, or already retained, is fully supported. A racing second preload() call for the same constructor shares this same in-flight preparation when its data matches (Object.is()); a call with different data discards the stale entry (once its own preparation settles) and starts a fresh one with the new data - the newest call's data always wins, never silently ignored. Rejects with UnregisteredSceneError (dev builds) when target is not present in ApplicationOptions.scenes.
Reactivate a scene previously retained via change(..., { suspendCurrent: true }) or restore(..., { suspendCurrent: true }) - the same instance, returned to whichever of Active/Paused it had before suspension. load()/ init() do not run again. Shares the same atomic commit boundary and optional SceneTransition behavior as SceneDirector.change - see its doc comment for the exact guarantee. Rejects with ConcurrentSceneNavigationError when another navigation is already in flight; with RetainedSceneNotFoundError when target has no retained instance.
Reactivate a scene previously retained via change(..., { suspendCurrent: true }) or restore(..., { suspendCurrent: true }) - the same instance, returned to whichever of Active/Paused it had before suspension. load()/ init() do not run again. Shares the same atomic commit boundary and optional SceneTransition behavior as SceneDirector.change - see its doc comment for the exact guarantee. Rejects with ConcurrentSceneNavigationError when another navigation is already in flight; with RetainedSceneNotFoundError when target has no retained instance.
resume(): boolean
Resume a paused scene, undoing SceneDirector.pause. No-op (returns false) when no scene is active or it is not currently paused.
unload(target: C, options: UnloadOptionsOptions passed to SceneDirector.unload.): Promise<boolean>
Discard whatever is parked or active for target's constructor - the single, unified replacement for the removed releaseScene(). Checks every candidate (active, retained, preloaded); when more than one exists, options.instance must disambiguate which one - there is no priority order. options.transition only materializes for an active-scope match (a retained or preloaded match has nothing visible on screen to transition, and always runs the direct, non-transitioned teardown path). Returns false if nothing matched target at all. Rejects with AmbiguousSceneInstanceError when options.instance is omitted and more than one candidate exists; with SceneInstanceNotFoundError when options.instance names a specific kind that doesn't exist for target.
Per-frame logic entry point called by Application.update, after this frame's fixed steps: for the active scene, gated by its SceneScope state, runs update() then its systems' update phase. Dispatches SceneDirector.onUpdateScene whenever a scene is active, regardless of state. Drawing is a separate call - see SceneDirector.draw.
Properties3
paused: boolean
true while the active scene is paused, or false when no scene is active. See SceneDirector.pause/SceneDirector.resume.
Events7
Source