Time
The game clock: how fast the game runs and what a frame is worth. Time.scale slows or speeds up
the whole game, Time.paused freezes it, and both reach physics, animators and particles. Wall-clock
delays in an app are setTimeout / setInterval (globals); dates are date
(datetime).
- pause the game and freeze physics and animations
- keep a pause menu animating while the game is paused
- slow motion or speed up the whole game
- move something by the frame's delta time
- run logic at a fixed 60 Hz step
- read the game time or the frame count since the start
Platforms: every host. In a 2D-only app (no 3D Scene) on Android, in the windowless server
(lecodes serve) and in headless tests, the clock starts only once the 2D engine has begun loading
a texture — until then Time.frame stays 0 and no update runs.
At a glance
class PauseMenu extends System<'pauseMenu'> {
updateWhilePaused = true // keeps ticking while the world is frozen
fade = 0
private onKey = (e: InputKeyEvent) => { if (e.code === 'Escape' && !e.repeat) Time.paused = !Time.paused }
onAttach() { Input.on('keydown', this.onKey) }
onDetach() { Input.off('keydown', this.onKey) }
update() { // dt is 0 while paused: use the wall clock
this.fade = Time.paused ? Math.min(1, this.fade + Time.unscaledDt * 4) : 0
}
}
const scene = new Scene().system(PauseMenu)
scene.open()
Time.scale = 0.25 // slow motion for a kill camGame clock properties: Time.dt, now, scale, paused
Time.scale: number // 1 normal · 0.5 half speed · 2 double (≤ 0 / NaN / Infinity → 0, frozen)
Time.paused: boolean // freeze the game; `scale` is remembered and restored on resume
Time.effectiveScale // the multiplier the engines run at right now (0 while paused)
Time.dt: number // this frame's delta in GAME seconds — what update(dt) receives; 0 while paused
Time.unscaledDt: number // this frame's wall-clock delta, seconds (the engines clamp it to 0.05)
Time.fixedDt: number // 1/60 — what updateFixed(dt) always receives (read-only)
Time.now: number // game seconds since the clock started (scaled; stops while paused)
Time.unscaledNow: number // wall-clock seconds since the clock started
Time.frame: number // frames dispatched since the clock started (paused frames count)Frame delta time: update(dt)
update(dt) / updateBefore(dt) receive Time.dt: game seconds, scaled by Time.scale, 0 while
paused. Multiply speeds by it and the motion is the same at any frame rate.
class Spinner extends Aspect<'spinner', Sprite> {
speed = 90 // degrees per GAME second
update(dt: number) { // dt = Time.dt: slows with Time.scale, 0 while paused
this.node.rotation += this.speed * dt
}
}
const scene = new Scene2D()
scene.add(new Sprite({ size: [40, 40], color: '#4f7cff' }).aspect(Spinner))
scene.open()The clock is driven by the aspect dispatch, which starts with the first aspect or
system that defines an update method: before that, dt, now and frame stay 0.
Pause the game, keep the pause menu animating: Time.paused, updateWhilePaused
Time.paused = true pauses the game: physics, animators and particles stop, and every updater is
skipped except those with updateWhilePaused = true — a pause menu's fade keeps animating there.
Those are called with dt = 0 and read Time.unscaledDt themselves — the same split as Unity's
deltaTime / unscaledDeltaTime (the pause menu of At a glance).
Fixed step: updateFixed and Time.fixedDt
updateFixed(dt) always receives Time.fixedDt (1/60); scale changes how many fixed steps a
frame holds, never their length. While paused there are none — not even for updateWhilePaused.
class Drift extends Aspect<'drift', Sprite> {
speed = 120 // pixels per game second
updateFixed(dt: number) { // dt is always Time.fixedDt (1/60)
this.node.x += this.speed * dt
}
}
const scene = new Scene2D()
scene.add(new Sprite({ size: [32, 32], color: '#ff7a45' }).aspect(Drift))
scene.open()Slow motion for physics, animators and particles: Time.scale
The scale is pushed to each engine through its setTimeScale bridge (feature-detected): physics
steps, animator clocks and particle systems advance by dt × scale. A host whose engine predates
the hook keeps its simulations at wall-clock speed while game code still scales — pause the bodies
yourself there.
Tweens on the 'game' clock (animate) take the 3D engine's scale:
they slow down and pause with Time only once a 3D Scene exists. In a 2D- or UI-only app, on the
web and in headless tests, a 'game' tween runs at wall-clock speed.
Timers are not on the game clock: setTimeout, setLoop
setTimeout / setInterval / setLoop are host timers on the wall clock — they neither scale
nor pause with Time (globals). A delay that must stop while the game is
paused counts dt in an aspect or system.
See also
- Aspects —
updateWhilePaused, the phases that consumedt - Input —
Input.on('keydown')for one-shot keys like the pause toggle - Host globals —
setLoop,setTimeout