← The API

Phaser AE

API docs

v3.0.0-2206 exports in 26 modulesreleased October 19, 2026

ContentsThe game

Need to get started? Install the Phaser AE CLI →

The game

The game

createGame, the Game that owns every service, the frame loop, boot, stop and destroy, the host contract

engine/kernel/src/game.impl.ts

Functions

createGame

function createGame(opts: GameOptions): Composed<GameFacade, KernelTopics>

From @phaser-ae/kernel

Make a game and return its builder: compose packs with .use(), in order, then take .game. A bake writes this call into engine.ts from the manifest, so game code imports the composed game rather than calling it. Nothing boots until game.start(). In a browser window.game is the game from here on.

Classes

Game

class Game implements GameBase

From @phaser-ae/kernel/internal

The game: the frame loop and every kernel service. One canonical frame, identical on every backend (runFrame):

worker results settle → the clock turns wall time into n steps → input polls → frame.start → n × [ input edges → signals delivered → prev rolled → frame.simulate → steps → worlds' afterStep → anims → timers → roster flush (spawn/kill signals, scene.spawn/scene.kill) ] → camera resolved at alpha → frame.render (and game.frame callbacks) → worlds' depth and tables → passes → frame.end

Game code sees it through the facade createGame builds; packs through kernel().

  • readonly clock: KernelClock — The clock: pause, time scale, frame advance.
  • readonly hooks: KernelHooks — The lifecycle hooks.
  • readonly roster: KernelRoster — Every live object; iterate, query, kill.
  • readonly signals: KernelSignals — The signal bus, every composed pack's topics declared.
  • readonly scheduler: KernelScheduler — The timers behind after and every.
  • readonly rng: KernelRng — The seeded random source. Use it, never Math.random, or the replay diverges.
  • readonly input: KernelInput — The player's input, polled in a step: keyDown(code) while held, keyPressed(code) for one step, pointer, named actions (bind, action), gestures and gamepads. It reads nothing while the game is paused or a menu has it.
  • readonly commands: KernelCommands — Standing commands: screenshot, record, pause, mute, fullscreen.
  • readonly cheats: KernelCheats — Debug controls: jump to a level, give a power-up, infinite lives. add one, run one, list them; bake play's cheat step and the backquote panel run them.
  • readonly scenes: KernelScenes — Define scenes and move between them.
  • readonly camera: KernelCamera — The camera record: position, zoom, bounds, shake.
  • readonly assets: KernelAssets — The loader and the atlas: load files, get what loaded, frames(key) for a picture's first frame.
  • readonly workers: KernelWorkerPool — The worker pool.
  • readonly dev: boolean — Dev mode: misuse throws (GameOptions.dev).
  • readonly opts: GameOptions — The options it was made with. It is also the live screen policy: a resize writes the new size and cssScale back into it.
  • readonly after: (s: Seconds, fn: () => void) => ReturnType<KernelScheduler['after']> — Run fn once after seconds of simulation time; cancelled when the current scene exits.
  • readonly every: (s: Seconds, fn: () => void) => ReturnType<KernelScheduler['every']> — Run fn every seconds of simulation time; cancelled when the current scene exits.
  • readonly backend: Record<string, unknown> — What the backend publishes for the passes after it, handed to every pass as PassContext.backend.
  • canvas: HTMLCanvasElement | null — The canvas in the page; null headless and before boot.
  • surface: { replaceCanvas: (canvas: HTMLCanvasElement) => void; canvas: HTMLCanvasElement | OffscreenCanvas; width: number; height: number; dpr: number; offsetX: number; offsetY: number; safe: { top: number; right: number; bottom: number; left: number }; clear: { r: number; g: number; b: number; a: number } } | null — The surface backends draw to (Kernel.surface); null before boot and after destroy.
  • cssFullscreen: boolean — True while the iOS CSS-fullscreen fallback is up (there is no Fullscreen API to ask).
  • isReady: boolean — THE READY MOMENT (game.ready), once: started, a frame drawn with the first scene current (a game that registers no scenes needs none), every file asked for so far landed, and nothing holding it back (the loading screen holds it while it is up). Checked at the end of every frame until it comes, so it always falls on a frame.
  • readonly ready: Promise<void> — Resolves once, the moment the game can be PLAYED: it has started, a frame has been drawn with its first scene current (a game that registers no scenes needs none), nothing holds it back (the loading screen holds it while it is up: Kernel.holdReady), and every file asked for so far has landed, an asset pack loading quietly in the background included. A file asked for later does not take it back. Before it, debug controls (cheats.run) queue and run at this moment, and a pause or resume from the host is remembered and applied then. window.PhaserGameReady() is called at the same moment.
  • stateReader: (() => unknown) | null — The game's own state, read at every inspection (inspect.state).
  • constructor(opts: GameOptions)
  • kernel(): Kernel<Record<string, unknown>> — The Kernel a pack's attach receives: every service, plus the frame graph, simulate and registry views.
  • holdReady(why: string): () => void — See Kernel.holdReady.
  • get notReadyBecause(): string[] — What still keeps the game from being ready, in words: for a host or a tool that waited too long.
  • own(dispose: () => void): { cancel(): void; readonly cancelled: boolean } — Scope a disposer to the current scene (global if none).
  • attach(pack: Pack<object, object>): object — Compose one pack: check its backends, its requires (each composed before it) and that its id is new; declare its topics and columns; then call its attach. Returns what attach returned. The builder's use calls it.
  • get composedIds(): string[] — Every composed pack's id, in composed order.
  • step(name: string, fn: (dt: number) => void, order: { before?: string; after?: string } = {}): { cancel(): void; readonly cancelled: boolean } — Game code's step, scoped to the scene that registered it: it holds while that scene is suspended. cancel removes this step alone.
  • frame(name: string, fn: (alpha: number) => void): { cancel(): void; readonly cancelled: boolean } — Game code's per-FRAME work, once per rendered frame rather than once per fixed step. Scene-scoped, and cancelled with the scene, exactly like step. IMMEDIATE ART BELONGS HERE. A fixed step runs zero, one or many times between two frames, and an immediate batch is filled between one draw and the next — so a line pushed from a step is drawn once per step, and a frame that has to catch up on six steps draws six copies of it. Retained objects do not care (a step moves them and the frame draws where they ended up); anything emitted per call does.
  • spawn<S extends Record<string, unknown> = Record<string, never>>(spec: Omit<SpawnSpec, 'data'> & { anims?: Record<string, AnimDef>; play?: string; data?: S }): Omit<Handle, 'data'> & { data: S } — The full spawn (game.spawn, Kernel.spawn): the picture and size resolved, the roster's columns, anims, then every pack's spawn-data handler for a key the spec carries.
  • paint(key: string, w: number, h: number, draw: (ctx: import('./assets.js').PaintContext, frame: number) => void, opts?: { frames?: number; res?: number }): number — A picture by name, painted with the 2D canvas: game.paint('cake', 86, 46, ctx => { … }). Returns its first frame index. See Assets.paint.
  • pixels(key: string, rows: ReadonlyArray<string>, palette: Readonly<Record<string, string>>, scale?: number): number — Pixel art by name from rows of characters and a palette. Returns its first frame index. See Assets.pixels.
  • anim(h: Handle): { name: string; done: boolean } | null — What h is playing and whether a one-shot has finished. See GameBase.anim.
  • play(h: Handle, name: string, hold: boolean): void — Start the anim name on h (hold plays it once); see the play verb. Asks the packs' onPlay handlers for a name the object did not declare.
  • runFrame(now: Seconds): void — One tick: advance the clock, run the fixed steps, then render. frame is game code's per-frame hook.
  • async advance(seconds: Seconds, opts: AdvanceOptions = {}): Promise<Advanced> — See GameBase.advance.
  • readonly inspect: InspectFn — See GameBase.inspect.
  • readonly tickSource: TickSource — The tick source. Headless harnesses drive it by hand.
  • readonly registry: KernelRegistry — The definitions registry (Kernel.registry). Two packs registering one name while they compose throws; after that the last definition wins, and an identical one changes nothing. At most 240 deform definitions, the indices the deform column has room for.
  • host: unknown — The composed game (every pack's key), set by the builder: what window.game is.
  • start(): Promise<void> — Boot and start ticking. The first call emits boot.domReady, creates the canvas, then emits boot.surfaceCreated and boot.deviceReady, awaiting every subscriber; then input and the page's listeners attach and the tick source starts. It does NOT enter a scene: call scenes.go(first) after it. A call while one is in flight returns the same promise; after stop() it resumes without booting again; after destroy() it does nothing.
  • get running(): boolean — See GameBase.running.
  • stop(): void — See GameBase.stop.
  • destroyed: boolean — True once destroy() has run. Everything after that is a no-op rather than a half-live game.
  • destroy(): void — See GameBase.destroy.
  • resize(): void — Fit the canvas to its host by the policy's fit: size the canvas element and its backing store, write the logical size, cssScale and safe insets back to the policy, and emit app.resize when any of them changed. Called on every window, viewport, host, fullscreen and device-pixel-ratio change.

Types

AnimDef

interface AnimDef

From @phaser-ae/kernel

A named run of frames, declared at spawn (anims: { walk: { strip: 'crab', fps: 8 } }). The kernel advances it on the game clock, holds it while the object's scene is suspended, and emits anim.complete and anim.marker.

  • frames?: ReadonlyArray<number> — Explicit global frame indices, in order. In dev, a list that starts in a picture must stay in it.
  • strip?: string — A picture's name: every one of its frames, in order. Used when frames is absent; one of the two is required.
  • fps: number — Frames per second of game time.
  • hold?: boolean — Play once and stop on the last frame (game.anim(h).done turns true) instead of looping.
  • markers?: Record<number, string> — Names for frames by position in the run: reaching one emits anim.marker (a footstep, a muzzle flash).