← The API

Phaser AE

API docs

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

Contents2D and 3D worlds

Need to get started? Install the Phaser AE CLI →

On stage

2D and 3D worlds

The shared gathers that build instance tables, and the 2D and 3D camera transforms

engine/kernel/src/world2d.tsengine/kernel/src/world3d.ts

Functions

installCamera2d

function installCamera2d(cam: { x: number; y: number; zoom: number; install?(a: unknown, b: unknown): void }, screen: { width: number; height: number }): { toWorld(sx: number, sy: number): { x: number; y: number }; toScreen(wx: number, wy: number): { x: number; y: number }; view(): { x: number; y: number; w: number; h: number; cx: number; cy: number } }

From @phaser-ae/kernel/internal

Install the 2D camera transform on the kernel camera: screen = (world − cam) · zoom + half-screen, measured across the seam in a wrapping world. Snaps the camera to the screen centre, so world (0, 0) starts at the top-left corner. Returns the transforms and view(), the rectangle the camera sees in world units, derived fresh at each call.

installCamera3d

function installCamera3d( cam: { x: number; y: number; z: number; yaw: number; pitch: number; fov: number; install?(a: unknown, b: unknown, c: unknown): void }, screen: { width: number; height: number }, viewOf: () => View3d, ): { toWorld(sx: number, sy: number): { x: number; y: number }; toScreen(wx: number, wy: number, wz?: number): { x: number; y: number }; screenRay(sx: number, sy: number): { origin: V3; dir: V3 } }

From @phaser-ae/kernel/internal

Install the 3D camera transform. toScreen projects a world point to logical pixels (behind the camera comes back off-screen); toWorld returns where the screen point meets the y = 0 ground plane, which is what a pointer usually means in a 3D game — screenRay is there for everything else.

lerpAngle

function lerpAngle(from: number, to: number, a: number): number

From @phaser-ae/kernel/internal

Interpolate an angle along the SHORTEST arc: +π → −π is a hair's turn, not a full spin through 0.

view3dFrom

function view3dFrom(cam: { x: number; y: number; z: number; yaw: number; pitch: number; fov: number }, aspect: number, near: number, far: number, distance = 0): View3d

From @phaser-ae/kernel/internal

Build a 3D camera's matrices from the kernel camera's fields. The kernel camera carries x y z (the eye), yaw/pitch (where it looks) and fov; a rig writes those, and this turns them into the matrices once a frame. distance > 0 orbits: the eye is pulled back that far along the look direction, so x y z is the point of interest instead.

Classes

Gather2d

class Gather2d

From @phaser-ae/kernel/internal

The shared 2D gather. Construct with the roster, the world's layer names, the world's first global layer index (from registerWorld), and the space.

  • readonly tables: Table2d[] — One table per layer, in layer order; the same objects every frame, rewritten.
  • wrap: Wrap | null — In a wrapping world every object draws at its nearest image to the rendered camera.
  • camera: { render: { x: number; y: number; zoom: number } } | null — The rendered camera; needed for wrap (nearest image) and for the view rect. Null draws at raw positions.
  • screen: { width: number; height: number } | null — The logical screen, for the view rect aggregates cull against.
  • readonly space: 'world' | 'screen' — 'world' goes through the camera; 'screen' is logical pixels.
  • inset: { local: number; above: LayerName | undefined } | null — A SCREEN gather's layer that draws inside a 2D world's stack instead of with the screen's own layers — world-screen's underlay — and the world layer it sits directly above (undefined: the first 2D world's first layer). Its table moves into that world's list, drawn in the world pass, and its depth onto the seam between that layer and the next, so roster.at agrees with what is drawn. With no 2D world composed it stays on screen, drawn before the screen's other layers. Set it once, before the first frame. An above no 2D world declares takes the default.
  • constructor(private readonly r: KernelRoster, readonly layers: ReadonlyArray<LayerName>, readonly first = 0, space: 'world' | 'screen' = 'world')
  • worlds(): ReadonlyArray<Gather2d> — The 2D worlds' gathers on this roster, in composed order: the stacks an inset can sit inside.
  • resolveDepth(rule: (slot: number) => number): void — Write depth for every live slot from the world's rule. An inset layer's rule is squeezed onto its seam, keeping its order.
  • tables_(alpha: number): ReadonlyArray<InstanceTable> — Build this frame's tables: live, visible slots per layer sorted by depth, interpolated at alpha; aggregates emit in place. A world's tables() returns this: its own tables in layer order, with any screen layer placed inside this stack straight after the layer it sits on, and a screen gather's inset either handed to its world or first.

Gather3d

class Gather3d

From @phaser-ae/kernel/internal

The gather every 3D world shares: per layer, sort the live, visible slots and write an interpolated mesh instance table from the roster's columns. The same shape as the 2D gather — a world supplies only its depth rule — but the pose is the full 3D one: position xyz, yaw/pitch/roll, scale xyz, and the mesh each instance wears. Construct with the roster, the world's layer names and its first global layer index.

The depth buffer does not make sorting unnecessary. Opaque meshes are sorted FRONT to BACK so early-z rejects the hidden ones, and the renderer draws transparent ones back to front afterwards. The rule a world hands in is distance from the camera, so both orders come from one number.

  • readonly tables: Table3d[] — One table per layer, in layer order; the same objects every frame, rewritten.
  • meshOf: (() => Uint32Array | undefined) | null — How to find the mesh id column, called once a frame. It must be looked up rather than cached: the roster REALLOCATES its column arrays when it grows, so a reference taken at attach goes stale.
  • billboardOf: (() => Uint8Array | undefined) | null — The same for the billboard flag column.
  • materialOf: (() => Uint32Array | undefined) | null — And for the material index column.
  • surfaceOf: (() => Uint32Array | undefined) | null — And for the extended-surface slot column.
  • pickableOf: (() => Uint8Array | undefined) | null — And for the pickable flag column.
  • quadMesh: number — The mesh instances an aggregate emits are all the same quad; the world sets which.
  • planes: Float32Array | null — Set to this frame's frustum planes to drop objects the camera cannot see; null draws everything.
  • radii: Float32Array | null — Each mesh's cull radius at scale 1 (meshCullRadius), indexed by mesh id; the world keeps it current as meshes are registered and changed. Null, an id past its end or a 0 entry is culled as a unit mesh.
  • culled: number — Objects skipped by the frustum last gather — what culling actually saved.
  • constructor(private readonly r: KernelRoster, readonly layers: ReadonlyArray<LayerName>, readonly first = 0)
  • resolveDepth(rule: (slot: number) => number): void — Write depth for every live slot from the world's rule (distance from the camera).
  • tables_(alpha: number): ReadonlyArray<InstanceTable> — Build this frame's tables: live, visible slots per layer, sorted near→far, interpolated at alpha.

Table2d

class Table2d implements InstanceTable

From @phaser-ae/kernel/internal

One 2D layer's instance table, reused every frame. Its columns grow by doubling and never shrink.

  • readonly kind: "sprites2d" — Always sprites.
  • space: 'world' | 'screen' — Set by the gather from its world: 'world' goes through the camera, 'screen' is logical pixels.
  • pass: 'world' | 'screen' — Which sprite pass draws it: its space, except a screen layer placed inside a world's stack, which is drawn with the world.
  • count: number — Instances written this frame.
  • order: Uint32Array<ArrayBuffer> — Slot per instance, draw order. Starts at 64 and doubles.
  • x: Float32Array<ArrayBuffer> — Interpolated centre x.
  • y: Float32Array<ArrayBuffer> — Interpolated centre y.
  • z: Float32Array<ArrayBuffer> — z, copied.
  • rot: Float32Array<ArrayBuffer> — Interpolated rotation, radians.
  • sx: Float32Array<ArrayBuffer> — Interpolated scale x.
  • sy: Float32Array<ArrayBuffer> — Interpolated scale y.
  • width: Float32Array<ArrayBuffer> — Width, world units.
  • height: Float32Array<ArrayBuffer> — Height, world units.
  • frame: Uint32Array<ArrayBuffer> — Global frame index.
  • tint: Uint32Array<ArrayBuffer> — Packed rgba8 tint.
  • flags: Uint8Array<ArrayBuffer> — The object's drawBy (an aggregate's instances carry their object's).
  • alpha: Float32Array<ArrayBuffer> — Opacity.
  • blend: Uint8Array<ArrayBuffer> — Blend mode index.
  • repeatX: Float32Array<ArrayBuffer> — Texture repeats x.
  • repeatY: Float32Array<ArrayBuffer> — Texture repeats y.
  • scrollX: Float32Array<ArrayBuffer> — UV scroll x.
  • scrollY: Float32Array<ArrayBuffer> — UV scroll y.
  • deformKind: Uint8Array<ArrayBuffer> — Deform kind index.
  • deformAmount: Float32Array<ArrayBuffer> — Deform amount.
  • deformSpeed: Float32Array<ArrayBuffer> — Deform speed.
  • deformPhase: Float32Array<ArrayBuffer> — Deform phase.
  • constructor(readonly layer: LayerName)
  • ensure(n: number): void — Grow every column to hold at least n instances, doubling. Existing contents are KEPT: an aggregate grows the table from inside its own emit, one instance at a time, so a grow that dropped what was already written would erase the tiles or particles emitted before it and leave holes in the layer.

Table3d

class Table3d implements InstanceTable

From @phaser-ae/kernel/internal

One 3D layer's mesh instance table, reused every frame. Columns a mesh does not use are kept for the shared contract.

  • readonly kind: "meshes3d" — Always meshes.
  • readonly space: "world" — 3D tables always go through the camera.
  • count: number — Instances written this frame.
  • order: Uint32Array<ArrayBuffer> — Slot per instance, draw order.
  • x: Float32Array<ArrayBuffer> — Interpolated x.
  • y: Float32Array<ArrayBuffer> — Interpolated y (UP).
  • z: Float32Array<ArrayBuffer> — Interpolated z.
  • rot: Float32Array<ArrayBuffer> — Interpolated yaw, radians.
  • pitch: Float32Array<ArrayBuffer> — Interpolated pitch, radians.
  • roll: Float32Array<ArrayBuffer> — Interpolated roll, radians.
  • sx: Float32Array<ArrayBuffer> — Interpolated scale x.
  • sy: Float32Array<ArrayBuffer> — Interpolated scale y.
  • sz: Float32Array<ArrayBuffer> — Interpolated scale z.
  • mesh: Uint32Array<ArrayBuffer> — The mesh each instance wears; the renderer batches by it.
  • billboard: Uint8Array<ArrayBuffer> — 0 the object's own rotation, 1 faces the camera, 2 turns about y only; an aggregate's quads may also use 3 (along a direction carried in rot/pitch/roll) and 4 (flat on XZ).
  • material: Uint32Array<ArrayBuffer> — Which registered material each instance wears; 0 is the default.
  • surface: Uint32Array<ArrayBuffer> — Which extended-surface slot each instance wears; 0 is none.
  • pickable: Uint8Array<ArrayBuffer> — Whether each instance answers a pick; 0 is not.
  • width: Float32Array<ArrayBuffer> — Unused by meshes; the width column the contract requires.
  • height: Float32Array<ArrayBuffer> — Unused by meshes.
  • frame: Uint32Array<ArrayBuffer> — Atlas frame a textured mesh wears; 0 (the white square) means untextured.
  • tint: Uint32Array<ArrayBuffer> — Packed rgba8 colour.
  • flags: Uint8Array<ArrayBuffer> — The object's drawBy.
  • alpha: Float32Array<ArrayBuffer> — Opacity; below 1 the renderer draws it in the transparent pass.
  • blend: Uint8Array<ArrayBuffer> — Blend mode index.
  • repeatX: Float32Array<ArrayBuffer> — Unused by meshes.
  • repeatY: Float32Array<ArrayBuffer> — Unused by meshes.
  • scrollX: Float32Array<ArrayBuffer> — Unused by meshes.
  • scrollY: Float32Array<ArrayBuffer> — Unused by meshes.
  • deformKind: Uint8Array<ArrayBuffer> — Unused by meshes.
  • deformAmount: Float32Array<ArrayBuffer> — Unused by meshes.
  • deformSpeed: Float32Array<ArrayBuffer> — Unused by meshes.
  • deformPhase: Float32Array<ArrayBuffer> — Unused by meshes.
  • constructor(readonly layer: LayerName)
  • ensure(n: number): void — Grow every column without erasing rows already emitted by an aggregate this frame.

Constants

LAYER_SPAN

const LAYER_SPAN: 1000000

From @phaser-ae/kernel/internal

Depth = layer × LAYER_SPAN + the world's rule, so a layer never interleaves with its neighbour. A rule must stay within ±5e5.

MESH_COLUMN

const MESH_COLUMN: "mesh3d"

From @phaser-ae/kernel/internal

Where a 3D object's mesh id lives: the column world-3d declares under this key.

Types

View3d

interface View3d

From @phaser-ae/kernel/internal

A 3D camera's matrices for one frame, plus what the renderer and picking both need from it.

  • eye: V3 — Where the camera is.
  • target: V3 — What it looks at.
  • view: Mat4 — World → view.
  • proj: Mat4 — View → clip.
  • viewProj: Mat4 — World → clip.
  • invViewProj: Mat4 — Clip → world, for rays and unprojection.
  • planes: Float32Array — The six frustum planes, for culling.