Readonlyappseconds elapsed in the previous frame, clamped by maxDelta
Readonlyonfires after every frame's update, for systems that are not scene-owned
multiplies elapsed time; 0 pauses the game without stopping the renderer
total seconds since the current scene was created
the scene currently updating: the top of the stack
true while suspended by suspend (a page hide, usually)
true while a transition is playing or one is held by queue: true, for a scene that should ignore input until it ends
the viewport width in css pixels, which is what scenes lay out against
Staticactivethe running game, or null before one exists, for code that works with or without one
Staticcurrentthe running game, for the few places that genuinely need a global
Briefly dips timeScale toward scale for duration real seconds, then restores it
to 1 - a heavy hit's momentary freeze-frame, distinct from render.Camera.shake (which
moves the view, not the clock) and from ui.FloatingText (a damage number, not a time
effect). A second call while one is still running simply replaces it, the same way
Camera.shake restarts rather than stacking.
Queues the top scene's removal; it happens at the start of the next frame.
Optionalresult: unknown
reported back to the resumed scene's onResume
Queues a scene on top of the current one; it starts at the next frame.
The scene underneath suspends but is not destroyed: it stops updating and
keeps rendering, so the new scene can layer over it or replace it
outright, and popScene resumes exactly where play left off.
The counterpart to suspend: restores the parked clock, fires onResume on the top
scene, and unsilences the audio rig. Calling it without a suspend does nothing.
Advances the game by one frame and draws it, without waiting for the browser.
The loop normally runs on requestAnimationFrame, which browsers suspend while a tab is not visible. That is right for a game and wrong for a test or a screenshot, so this drives a frame directly.
seconds to advance by
Freezes the simulation for a page hide: the clock (timeScale) parks at 0, the top
scene hears onSuspend, and the game's own audio rig is silenced. The renderer keeps
going and step(dt) still works, so consoles and screenshots are unaffected.
Idempotent; resume restores the parked clock and audio, and the player's own mute
setting is never touched.
Queues a scene change; it happens at the start of the next frame.
The whole stack goes: every scene is destroyed, suspended or not, and the new one starts alone. For a scene that returns, push it instead.
Optionaloptions: TransitionOptionsChanges what the current scene shows under a transition: swap runs at the start of the next
frame, once the outgoing picture has been photographed, and the transition then plays over the
result. For a scene that replaces its decor, level or layout in place rather than switching scenes;
Scene2D.transitionTo is the same call from inside the scene. While a transition is
already playing this one is ignored unless its options say queue: true (play after
it) or interrupt: true (finish it at once and play this one); see TransitionOptions.
The application: owns the renderer, the loop, and the current scene.
Construct it,
await start(FirstScene), and the rest is scenes.The canvas is drawn at the display's
devicePixelRatio, up to what the device can actually make: a backing store ofviewport * devicePixelRatiopixels is refused past the GPU'sMAX_TEXTURE_SIZE(WebGL clamps it rather than failing, with nothing reported), so the resolution is reduced to the largest whole number that fits and a warning says so. A game therefore keeps rendering on a device with a small limit, softer than the display asked for rather than wrong; nothing changes on a device that can afford what it asked for.