SceneTime
Defined in: SceneTime.ts:108
Per-scene time-effect arbitration: hitstop, slow motion / bullet time,
freeze frames, and speed-ups that would corrupt each other if every caller
wrote scene.timeScale directly (the “restore to what?” bug).
Resolved via the scene-scoped SceneTimeKey; the engine registers one instance per scene.
const time = this.use(SceneTimeKey);time.freezeFor(0.08); // hitstopconst slow = time.scaleBy(0.25, { key: "slowmo" }); // bullet timeslow.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 × Π(channel winners).
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 and are not saved; games re-issue them after loading a snapshot.
Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new SceneTime(
scene):SceneTime
Defined in: SceneTime.ts:122
Parameters
Section titled “Parameters”Returns
Section titled “Returns”SceneTime
Accessors
Section titled “Accessors”activeLabels
Section titled “activeLabels”Get Signature
Section titled “Get Signature”get activeLabels(): readonly
string[]
Defined in: SceneTime.ts:184
Display labels of all active requests, in creation order per channel.
Returns
Section titled “Returns”readonly string[]
effectiveScale
Section titled “effectiveScale”Get Signature
Section titled “Get Signature”get effectiveScale():
number
Defined in: SceneTime.ts:131
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).
Returns
Section titled “Returns”number
elapsed
Section titled “elapsed”Get Signature
Section titled “Get Signature”get elapsed():
number
Defined in: SceneTime.ts:142
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.
Returns
Section titled “Returns”number
fixedElapsed
Section titled “fixedElapsed”Get Signature
Section titled “Get Signature”get fixedElapsed():
number
Defined in: SceneTime.ts:174
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.
Returns
Section titled “Returns”number
isFrozen
Section titled “isFrozen”Get Signature
Section titled “Get Signature”get isFrozen():
boolean
Defined in: SceneTime.ts:179
True while SceneTime.effectiveScale is 0.
Returns
Section titled “Returns”boolean
Methods
Section titled “Methods”_releaseAll()
Section titled “_releaseAll()”_releaseAll():
void
Defined in: SceneTime.ts:344
Internal
Release every request. Called by the engine on scene exit.
Returns
Section titled “Returns”void
_tick()
Section titled “_tick()”_tick(
dt):void
Defined in: SceneTime.ts:298
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 from exclusion sets.
Parameters
Section titled “Parameters”number
Returns
Section titled “Returns”void
_tickFixed()
Section titled “_tickFixed()”_tickFixed(
fixedDt):void
Defined in: SceneTime.ts:336
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.
Parameters
Section titled “Parameters”fixedDt
Section titled “fixedDt”number
Returns
Section titled “Returns”void
effectiveScaleForUpdates()
Section titled “effectiveScaleForUpdates()”effectiveScaleForUpdates(
entity):number
Defined in: SceneTime.ts:198
The scale entity’s component updates, ProcessComponent, and particle
emitters run at: like SceneTime.effectiveScale, but a channel
whose winner excludes the entity contributes 1. entity.timeScale is not
included — the update pipeline composes it on top.
Parameters
Section titled “Parameters”entity
Section titled “entity”Returns
Section titled “Returns”number
freezeFor()
Section titled “freezeFor()”freezeFor(
duration,options?):TimeEffectHandle
Defined in: SceneTime.ts:233
Freeze the scene (a ×0 factor) for duration real-time seconds. Returns
the same handle shape as scaleBy for an early release. Freezes are
whole-scene by design — a shared physics world has no per-entity time, so
freeze requests take no excludeUpdates.
Parameters
Section titled “Parameters”duration
Section titled “duration”number
options?
Section titled “options?”Returns
Section titled “Returns”scaleBy()
Section titled “scaleBy()”scaleBy(
factor,options?):TimeEffectHandle
Defined in: SceneTime.ts:208
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.
Parameters
Section titled “Parameters”factor
Section titled “factor”number