Skip to content

LayeredAnimationController

Defined in: renderer/src/LayeredAnimationController.ts:44

Fan-out wrapper around N sibling AnimationController instances.

Use this when a single logical character is composed of multiple sprite layers (head + body + outfit) — each layer has its own AnimatedSpriteComponent + AnimationController, but they all need to play("walk") or playOneShot("attack") in unison.

  • play(name) is forwarded to every child controller.
  • playOneShot(name, opts) computes a single shared duration from the first child (or opts.duration) and passes it to every child as options.duration — so all layers unlock on the same frame regardless of per-layer frame counts.
  • The wrapper owns the master lock timer and fires the user’s onComplete exactly once.
class Hero extends Entity {
setup() {
this.add(new Transform());
const body = this.spawnChild("body", HeroLayer, { sheet: "body.png" });
const head = this.spawnChild("head", HeroLayer, { sheet: "head.png" });
this.add(new LayeredAnimationController({
controllers: [body.get(AnimationController), head.get(AnimationController)],
}));
}
}
  • Component

T extends string = string

new LayeredAnimationController<T>(options): LayeredAnimationController<T>

Defined in: renderer/src/LayeredAnimationController.ts:54

LayeredAnimationControllerOptions<T>

LayeredAnimationController<T>

Component.constructor

entity: Entity

Defined in: core/dist/index.d.ts:2716

Back-reference to the owning entity. Set by the engine when the component is added to an entity. Do not set manually.

Component.entity


static optional restorePriority?: number

Defined in: core/dist/index.d.ts:2874

Snapshot restore order. On load, an entity’s components are re-added in ascending priority, so a component whose onAdd() reads a sibling can rely on lower-priority siblings being present and initialized. Undeclared = 100. Engine components reserve 0-99; game and addon components declare a value only when a sibling onAdd() dependency requires it. Equal priorities restore in save-time add order. Subclasses inherit their base class’s priority unless they declare their own.

Component.restorePriority


static optional updatePriority?: number

Defined in: core/dist/index.d.ts:2889

Class-level default for updatePriority: every instance runs at this priority unless its own updatePriority is written. Undeclared = 0. Subclasses inherit their base class’s value unless they declare their own. Declare it on a component whose behavior depends on running after (or before) a sibling, so the entity that adds it does not have to control the add order.

class BoundsClamp extends Component {
static updatePriority = 10; // after the follow that moves the camera
}

Component.updatePriority

get context(): EngineContext

Defined in: core/dist/index.d.ts:2770

Access the EngineContext from the entity’s scene. Throws if the entity is not in a scene.

EngineContext

Component.context


get controllers(): readonly AnimationController<T>[]

Defined in: renderer/src/LayeredAnimationController.ts:65

Sibling controllers being driven.

readonly AnimationController<T>[]


get current(): "" | T

Defined in: renderer/src/LayeredAnimationController.ts:70

Currently playing animation name, or "" if none.

"" | T


get effectiveEnabled(): boolean

Defined in: core/dist/index.d.ts:2740

Whether the component is actually running: enabled, on an active entity, and past onAdd. This is the state onEnable and onDisable track — read it when a method has to behave one way live and another way dormant.

boolean

Component.effectiveEnabled


get enabled(): boolean

Defined in: core/dist/index.d.ts:2732

Whether this component runs. Disabled components are skipped by ComponentUpdateSystem.

Writing this fires onEnable / onDisable when the effective state changes — enabled && entity.isActive. A component disabled here stays disabled through a setActive(false) / setActive(true) cycle on its entity.

boolean

set enabled(value): void

Defined in: core/dist/index.d.ts:2733

boolean

void

Component.enabled


get locked(): boolean

Defined in: renderer/src/LayeredAnimationController.ts:75

True if a one-shot animation is blocking.

boolean


get scene(): Scene

Defined in: core/dist/index.d.ts:2765

Access the entity’s scene. Throws if the entity is not in a scene. Prefer this over threading through this.entity.scene in component code.

Scene

Component.scene


get updatePriority(): number

Defined in: core/dist/index.d.ts:2758

Where this component runs among its siblings. ComponentUpdateSystem calls update / fixedUpdate on an entity’s components in ascending priority; equal priorities run in add order. Undeclared = 0, so a negative value runs before siblings that keep the default and a positive value runs after them. Writable at any time, before or after add(). Defaults to the class’s static updatePriority.

class Player extends Entity {
setup() {
this.add(new Mover());
this.add(new Brain()).updatePriority = -1; // decides before Mover moves
}
}

number

set updatePriority(value): void

Defined in: core/dist/index.d.ts:2759

number

void

Component.updatePriority

_applyEnabled(effective): void

Defined in: core/dist/index.d.ts:2824

Internal

Force an effective-enabled transition, firing the hook on a flip. Used by Entity for teardown, where enabled and the entity’s activeness both still read true.

boolean

void

Component._applyEnabled


_refreshEnabled(): void

Defined in: core/dist/index.d.ts:2817

Internal

Recompute effective enabled-ness from enabled and the entity’s activeness, firing the hook on a flip.

void

Component._refreshEnabled


_runCleanups(): void

Defined in: core/dist/index.d.ts:2811

Internal

Run and clear all registered cleanups. Called by Entity.remove() and Entity._performDestroy() before onRemove/onDestroy.

void

Component._runCleanups


protected addCleanup(fn): void

Defined in: core/dist/index.d.ts:2805

Register a cleanup function to run when this component is removed or destroyed.

() => void

void

Component.addCleanup


optional afterRestore(data, resolve): void

Defined in: core/dist/index.d.ts:2893

Called after onAdd() during save/load restoration. Apply state that depends on onAdd() having run.

unknown

SnapshotResolver

void

Component.afterRestore


optional fixedUpdate(dt): void

Defined in: core/dist/index.d.ts:2863

Called every fixed timestep by the built-in ComponentUpdateSystem.

number

Fixed timestep in seconds, scaled by scene and entity timeScale.

void

Component.fixedUpdate


forcePlay(name): void

Defined in: renderer/src/LayeredAnimationController.ts:117

Clear the lock and force-switch every layer to the given animation.

T

void


protected listen<T>(entity, token, handler): void

Defined in: core/dist/index.d.ts:2797

Subscribe to events on any entity, auto-unsubscribe on removal.

T

Entity

EventToken<T>

(data) => void

void

Component.listen


protected listenScene<T>(token, handler): void

Defined in: core/dist/index.d.ts:2803

Subscribe to scene-level events, auto-unsubscribe on removal. Handlers fire for bubbled entity events (entity = source) and scene.emit events (entity = undefined).

T

EventToken<T>

(data, entity?) => void

void

Component.listenScene


optional onAdd(): void

Defined in: core/dist/index.d.ts:2832

Called when the component is added to an entity. Validate dependencies here — a service, a sibling component, a render layer — and throw when one is missing. The throw is attributed to this component, recorded in Inspector.getErrors().callbackErrors, and rethrown, so it reaches the caller of entity.add() unchanged.

void

Component.onAdd


optional onDestroy(): void

Defined in: core/dist/index.d.ts:2853

Called when the component is destroyed (entity destroyed or component removed).

void

Component.onDestroy


optional onDisable(): void

Defined in: core/dist/index.d.ts:2849

Called when the component stops being effectively enabled — enabled went false, the entity (or an ancestor) was deactivated, or the component is being removed or destroyed. Put live resources to sleep here; the component is reused afterwards, so do not free anything onEnable cannot rebuild.

void

Component.onDisable


optional onEnable(): void

Defined in: core/dist/index.d.ts:2841

Called when the component becomes effectively enabled — enabled is true and the entity is active. Fires right after onAdd() for a component added to an active entity, and again on every later flip. Bring live resources back online here (unpause a sound, show a display object, re-enable a physics body). Game-state reset does not belong here: the hook sees whatever state the component held while dormant.

void

Component.onEnable


optional onRemove(): void

Defined in: core/dist/index.d.ts:2851

Called when the component is removed from an entity.

void

Component.onRemove


play(name): void

Defined in: renderer/src/LayeredAnimationController.ts:80

Play a named animation on every layer. No-op if already current or locked.

T

void


playOneShot(name, options?): void

Defined in: renderer/src/LayeredAnimationController.ts:97

Play a one-shot on every layer with a shared lock duration.

If options.duration is omitted, the duration is computed once from the first controller via AnimationController.calcDuration and stored on this wrapper as the single source of truth. Children are given an Infinity per-controller duration so their own lock timers never expire independently — clearing them happens through this wrapper’s unlock when the master timer fires. This avoids a race where a child’s update() could tick out a frame before the wrapper’s (e.g. if components are ordered differently in the scheduler, or accumulated float drift makes one timer cross the threshold a frame earlier).

T

number

() => void

void


serialize(): null

Defined in: renderer/src/LayeredAnimationController.ts:147

Return a JSON-serializable snapshot of this component’s state. Used by the save system.

null

Component.serialize


protected service<T>(key): T

Defined in: core/dist/index.d.ts:2787

Lazy proxy-based service resolution. Can be used at field-declaration time:

readonly input = this.service(InputManagerKey);

The actual resolution is deferred until first property access.

T extends object

ServiceKey<T>

T

Component.service


protected sibling<C>(cls): C

Defined in: core/dist/index.d.ts:2795

Lazy proxy-based sibling component resolution. Can be used at field-declaration time:

readonly anim = this.sibling(AnimatedSpriteComponent);

The actual resolution is deferred until first property access.

C extends Component

ComponentClass<C>

C

Component.sibling


unlock(): void

Defined in: renderer/src/LayeredAnimationController.ts:124

Manually release the one-shot lock on this wrapper and every child.

void


update(dt): void

Defined in: renderer/src/LayeredAnimationController.ts:133

Tick the shared one-shot lock timer.

number

void

Component.update


protected use<T>(key): T

Defined in: core/dist/index.d.ts:2778

Resolve a service by key, cached after first lookup. Scene-scoped values (registered via scene._registerScoped) take precedence over engine scope. A key declared with scope: "scene" that falls back to engine scope emits a one-shot dev warning — almost always signals a missed beforeEnter hook.

T

ServiceKey<T>

T

Component.use