← The API

Phaser AE

API docs

v3.0.0-1187 exports in 24 modulesreleased October 14, 2026

ContentsHooks

Need to get started? Install the Phaser AE CLI →

Time and flow

Hooks

The lifecycle hooks: boot, frame, assets, scene, input, app, debug

engine/kernel/src/hooks.ts

Types

HookName

type HookName = keyof HookPayloads

From @phaser-ae/kernel

Every hook name; the key of HookPayloads.

HookOrder

interface HookOrder

From @phaser-ae/kernel

Where a subscriber sits among the others on the same hook.

  • before?: string — Run before the subscriber named this. An unknown name is ignored.
  • after?: string — Run after the subscriber named this. An unknown name is ignored.
  • as?: string — A name other subscribers may order against. Default: an anonymous #n.

HookPayloads

interface HookPayloads

From @phaser-ae/kernel

Every lifecycle hook and its payload. Hooks are calls, made the moment something happens; compare signals, which are records batched per step. The list is flat and closed: adding a hook is a kernel change. A hook with no subscriber costs nothing.

  • 'boot.domReady': void — First thing start() emits, before the canvas exists.
  • 'boot.surfaceCreated': void — The canvas exists; a backend pack initialises its device here.
  • 'boot.deviceReady': void — Every asynchronous surface and device setup has completed. Input attaches and ticking starts after it.
  • 'boot.contextLost': void — The GPU device or context was lost. Emitted by a backend pack; the kernel never emits it.
  • 'boot.contextRestored': void — The backend has rebuilt its device after a loss. Emitted by a backend pack; the kernel never emits it.
  • 'assets.activity': { job: AssetActivity; silent: boolean } — Observable asset work started; includes file jobs and tracked decoding operations. silent is true for work started after the preload or asked to be quiet, and the automatic loading screen leaves that work alone.
  • 'assets.prepare': { item: LoadItem; value: unknown } — One file has arrived and is about to count as loaded. A pack that turns bytes into something ready to use does it here and the job WAITS for it (subscribers are awaited), so await job means ready rather than merely downloaded: the audio pack decodes kind: 'audio' here. Throwing fails the attempt like a bad fetch.
  • 'assets.loadStart': { total: number } — An assets.load job began; total items.
  • 'assets.itemLoaded': { key: string; loaded: number; total: number } — One item landed: key, the count so far and the total.
  • 'assets.itemFailed': { key: string; url: string; attempt: number; final: boolean; error: string } — One attempt at an item failed; attempt counts from 1; final when no retry follows.
  • 'assets.loadDone': { loaded: number; failed: number; aborted: boolean } — A job finished: failed items gave up, aborted if by abort().
  • 'frame.start': { dt: Seconds } — Once per tick, first; dt is the wall-clock delta in seconds, clamped to clock.catchUpClamp.
  • 'frame.simulate': { step: Seconds } — Once per fixed step, after signals are delivered and before the steps run; step in seconds. Zero to many per tick.
  • 'frame.render': { alpha: number } — Once per tick, after the fixed steps and before the worlds build their tables; alpha is the prev→curr interpolation fraction.
  • 'frame.end': void — Once per tick, last, after the passes.
  • 'game.ready': void — The game can be played, once: it has started, its first scene has drawn a frame, the loading screen has gone, and every file asked for so far has landed. game.ready resolves and window.PhaserGameReady() is called at the same moment. Debug controls run before it were queued and run now.
  • 'scene.enter': { scene: string; from: string | null } — A scene became current by go or push (not by pop); from is the scene that was current, null on the first. Emitted before the scene's own enter.
  • 'scene.exit': { scene: string; to: string | null } — A scene is leaving, after its own exit and before its objects, timers, steps and owned disposers go; to is null when the game is destroyed.
  • 'scene.spawn': { handle: Handle } — An object was spawned; emitted at the roster flush that ends each fixed step, not inside spawn().
  • 'scene.kill': { handle: Handle } — An object was killed; emitted at the roster flush that ends each fixed step, the handle still readable.
  • 'input.firstGesture': void — The first pointer or key the user gave: the moment audio may unlock and pointer lock may be asked for.
  • 'input.pointerLockLost': void — Pointer lock was released by the browser (Escape, focus loss).
  • 'app.resize': { width: number; height: number; dpr: number } — The logical size, device pixel ratio, CSS scale or safe insets changed. In a browser, also at boot when the first measurement differs from the policy; never headless.
  • 'app.hidden': void — The tab was hidden (visibilitychange). Held input has been cancelled.
  • 'app.shown': void — The tab became visible again.
  • 'app.focus': void — The window gained focus.
  • 'app.blur': void — The window lost focus. Held input has been cancelled.
  • 'app.shutdown': void — game.stop() ran: the tick source is stopped and input is detached.
  • 'app.dispose': void — The game is being destroyed: every pack gives back what it owns — GPU buffers, textures, pipelines, listeners. Fires after app.shutdown.
  • 'debug.ray': { x: number; y: number; dx: number; dy: number; maxDist: number; hitX: number | null; hitY: number | null; source: string } — A raycast a pack performed: origin, direction, range, the hit (null = miss) and which pack cast it.

Hooks

interface Hooks

From @phaser-ae/kernel

Subscribe to and publish lifecycle hooks.

  • on<K extends HookName>(hook: K, fn: (payload: HookPayloads[K]) => void, order?: HookOrder): Cancel — Subscribe. Subscribers run in subscription order, adjusted by order's before/after; a cycle throws at the next emit. Returns a cancel.
  • emitAsync<K extends HookName>(hook: K, payload: HookPayloads[K]): Promise<void> — Publish and await each subscriber in turn, in order. The kernel's boot hooks go this way, so a backend can await its device.
  • emit<K extends HookName>(hook: K, payload: HookPayloads[K]): void — Publish, synchronously. The kernel emits the lifecycle; a pack emits what it did (debug.ray) or what its backend saw (boot.contextLost).