Skip to content

SceneTime

Defined in: SceneTime.ts:142

Scene-wide and entity-scoped time-effect arbitration: hitstop, slow motion, freeze frames, and speed-ups that would corrupt each other if every caller wrote base time-scale properties directly.

Resolved via the scene-scoped SceneTimeKey; the engine registers one instance per scene.

const time = this.use(SceneTimeKey);
time.freezeFor(0.08); // hitstop
const slow = time.scaleBy(0.25, { key: "slowmo" }); // bullet time
slow.release();

Composition: each key is a channel. Within a channel the latest active request wins (a newer request masks an older still-active one and reveals it again on expiry); across channels the winning factors multiply. A freeze is a ×0 factor, so it dominates arithmetically. scene.timeScale stays the game’s persistent speed knob — this service reads it as an input and never writes it: effectiveScale = scene.timeScale × Π(scene channel winners). Entity requests multiply into SceneTime.effectiveScaleForUpdates after the scene result and never affect physics.

Request timers age on raw frame time, before any systems run, and only while the scene is active — a stack-paused scene holds its effects (note: that means pause-menu time does not consume a hitstop). Effects are transient: they release on scene exit. Games re-issue them after rebuilding a scene from saved domain state.

new SceneTime(scene): SceneTime

Defined in: SceneTime.ts:159

Scene

SceneTime

get activeLabels(): readonly string[]

Defined in: SceneTime.ts:221

Display labels of all active scene and entity requests.

readonly string[]


get effectiveScale(): number

Defined in: SceneTime.ts:168

The scale every non-excluded consumer runs at: scene.timeScale × Π(channel winners). Physics always steps under this full value (exclusions never apply to the shared world).

number


get elapsed(): number

Defined in: SceneTime.ts:179

Simulation seconds elapsed in this scene: raw frame time scaled by SceneTime.effectiveScale, accrued once per rendered frame and only while the scene is active. A stack-paused scene, a timeScale of 0, and an active freeze all hold it. Starts at 0 each time the scene is entered and is not saved. SceneTime.fixedElapsed is the fixed-timestep reading.

number


get fixedElapsed(): number

Defined in: SceneTime.ts:211

Simulation seconds elapsed in this scene on the fixed timestep: one fixedTimestep × SceneTime.effectiveScale increment per fixed step the loop runs, accrued only while the scene is active.

Stamp a gameplay time from fixed-step code against this reading and compare it there. SceneTime.elapsed moves with the rendered frame, so the same window spans a different number of simulation steps run to run.

Holds under the same conditions as SceneTime.elapsed: stack pause, a timeScale of 0, and an active freeze. Starts at 0 each time the scene is entered and is not saved.

This reading and elapsed advance on different cadences, so at any moment they can differ by one or more fixed steps in either direction. The loop’s fixed-step accumulator is engine-wide: a scene entered mid-run starts counting against the time already in it. A frame that hits maxFixedStepsPerFrame leaves its unrun steps for the following frames. Time waiting in the accumulator is converted at the scale in force when its step runs, not at the scale of the frame it arrived in. Stamp and compare against the same reading — subtracting one from the other does not give a meaningful lag.

The increment uses the whole-scene SceneTime.effectiveScale, so it does not follow entity.timeScale or an excludeUpdates exclusion. An entity running at its own rate should time itself against its ProcessComponent, which composes both.

number


get isFrozen(): boolean

Defined in: SceneTime.ts:216

True while SceneTime.effectiveScale is 0.

boolean

_releaseAll(): void

Defined in: SceneTime.ts:449

Internal

Release every request. Called by the engine on scene exit.

void


_tick(dt): void

Defined in: SceneTime.ts:417

Internal

Age request timers by raw frame time. Called by the engine at the start of earlyUpdate for each active scene, so a request created later in the frame is not aged until the next frame. Masked entries keep aging. Also prunes destroyed entities and ended pooled lives from exclusions.

number

void


_tickFixed(fixedDt): void

Defined in: SceneTime.ts:441

Internal

Accrue one fixed step of simulation time. Called by the engine once per fixed step for each active scene. Request timers age once per frame in _tick, never here.

number

void


effectiveScaleForUpdates(entity): number

Defined in: SceneTime.ts:243

The scale entity’s component updates, ProcessComponent, and particle emitters run at: like SceneTime.effectiveScale, but a scene channel whose winner excludes the entity contributes 1, and entity-scoped channel winners multiply on top. entity.timeScale is not included — the update pipeline composes it last.

Entity

number


freezeEntityFor(entity, duration, options?): TimeEffectHandle

Defined in: SceneTime.ts:341

Freeze one entity’s component updates, ProcessComponent, and particle emitters for a real-time duration. The entity’s rigid body keeps simulating with the scene’s shared physics world.

Entity

number

Omit<EntityTimeScaleOptions, "for">

TimeEffectHandle


freezeFor(duration, options?): TimeEffectHandle

Defined in: SceneTime.ts:290

Freeze the scene (a ×0 factor) for duration real-time seconds. Returns the same handle shape as scaleBy for an early release. Freezes are scene-wide for physics. excludeUpdates can keep selected entities’ components, processes, and particle emitters running during the freeze.

number

SceneTimeFreezeOptions

TimeEffectHandle


scaleBy(factor, options?): TimeEffectHandle

Defined in: SceneTime.ts:265

Add a scale request. factor must be finite and > 0 (freezing goes through SceneTime.freezeFor); factors above 1 speed the scene up — physics catch-up is capped at ~8 sub-steps per frame.

number

SceneTimeScaleOptions

TimeEffectHandle


scaleEntityBy(entity, factor, options?): TimeEffectHandle

Defined in: SceneTime.ts:310

Scale one entity’s component updates, ProcessComponent, and particle emitters without changing the scene or the entity’s rigid body. The request composes with scene requests and the entity’s base timeScale.

Entity

number

EntityTimeScaleOptions

TimeEffectHandle