Types
Aggregate
interface Aggregate
From @phaser-ae/kernel
ONE roster object, MANY instances: a tilemap, a particle pool. The object sits in its layer at its depth like any other; when the gather reaches it, it emits — only what the view needs. The roster stays small (one handle), the table stays exact (every drawn instance).
readonly count: number— Instances it holds in total (whath.aggregate.countreports), drawn or not.emit(out: InstanceSink, alpha: number, view: ViewRect): void— Append the instances insideviewtoout, interpolated atalpha. Called once per frame when the object is visible. 2D worlds.emit3d?(out: InstanceSink3d, alpha: number): void— The 3D face: append mesh instances, interpolated atalpha. A 3D world calls this instead ofemit; an aggregate that has no 3D form leaves it out and is skipped.
BackendInfo
interface BackendInfo
From @phaser-ae/kernel
A backend pack's declaration of what it can draw.
readonly draws: ReadonlyArray<DrawKind>— The table kinds it can draw; a world needing another is a bake error.
DeformDef
interface DeformDef
From @phaser-ae/kernel
A CUSTOM vertex deformer as data: a deform-* pack registers one under the registry kind 'deform'
and objects request it by name (deform: { kind: 'curl' }). code runs in the VERTEX stage of the 24×64 grid with
in scope: p (vec2f, the vertex in world units, centred on the object, y down — mutate it), shade (f32 brightness
multiplier, 1 lit — mutate it), uvn (vec2f 0..1 across the object), size (vec2f world units), amount (f32),
t (f32: phase + speed·time·2π), TAU, d.uv (vec4f the frame's atlas rect) and tex/samp for
textureSampleLevel(tex, samp, uv, 0.0) in the vertex stage. The optional fragment runs per pixel after the base
sample with color (vec4f straight-alpha, base = texel × tint × shade — mutate it), tint, uvn, uvRect, t,
amount, shade, kind, tex/samp. Every backend that draws sprites2d splices every registered def in.
name: string— The name objects request asdeform.kind. Unique per composed game.description?: string— One line saying what it looks like.code: string— WGSL, vertex stage: displacesp, may setshade.fragment?: string— WGSL, fragment stage, optional: mutatescolor.
DrawerDef
interface DrawerDef
From @phaser-ae/kernel
A pack that draws some objects ITSELF (registry kind 'drawer'): the backend calls draw for every run of
instances whose drawBy equals id, inside its sprite pass, in sorted order. The effects pack is one.
name: string— The registry name: the pack's id.id: number— The value objects carry indrawBy; 1..255, unique per composed game.draw(pass: unknown, table: InstanceTable, first: number, count: number): void— Drawcountinstances oftablestarting atfirst, into the backend's open pass.passis backend-typed (aGPURenderPassEncoderon WebGPU).drawGl?(bag: import('./webgl.js').WebGl2Bag, table: InstanceTable, first: number, count: number): void— Optional GL entry point, invoked in the same sorted position with the shared frame surface.
DrawKind
type DrawKind = 'sprites2d' | 'meshes3d' | 'vectors' | 'text'
From @phaser-ae/kernel
A kind of instance table, and so what a backend must be able to draw.
InstanceSink
interface InstanceSink
From @phaser-ae/kernel
What a 2D gather offers an aggregate: append instances to the current layer's table.
add(x: number, y: number, width: number, height: number, frame: number, tint: number, rot?: number, sx?: number, sy?: number, alpha?: number, blend?: number): void— One instance: centre, size, frame, tint (0xRRGGBBAA), then optionally rotation (radians), scale x/y, alpha (0..1) and blend index. Defaults: 0, 1, 1, 1, 0.
InstanceSink3d
interface InstanceSink3d
From @phaser-ae/kernel
What a 3D gather offers an aggregate: append mesh instances to the current layer's table. A particle system is the reason this exists — one roster object, thousands of billboards, drawn in the object's own sorted place by the renderer that is already there.
add(x: number, y: number, z: number, width: number, height: number, frame: number, tint: number, alpha?: number, roll?: number, blend?: number, billboard?: number, dx?: number, dy?: number, dz?: number): void— One instance: world centre, the quad's size in world units, atlas frame, packed rgba8 tint, then optionally opacity, in-plane roll (radians, about the view axis), blend index, and the billboard mode — 0 none, 1 faces the camera, 2 upright, 3 aligned to the directiondx dy dz(a stretched spark, a raindrop), 4 flat, in the plane whose normal isdx dy dz(up, the XZ plane, unless given: a ripple on the ground, a shockwave on a wall). Defaults: 1, 0, 0, 1, and no direction.
InstanceTable
interface InstanceTable
From @phaser-ae/kernel
One layer's instances, sorted, in columns indexed by draw position. Written fresh each frame by a world's gather.
readonly layer: LayerName— The layer this table draws.readonly kind: DrawKind— What the backend must draw it with.readonly space: 'world' | 'screen'— 'world' tables go through the camera; 'screen' tables are in logical pixels (HUDs, menus).readonly pass?: 'world' | 'screen'— Which of the backend's two sprite passes draws it, when that is not itsspace: 'world' is drawn in place among the world's layers, before anything lights or post-processes the world; 'screen' after all of that. A 'screen' space table in the 'world' pass is world-screen'sunderlay— fixed to the screen, yet over the world's backdrop and under its pieces. The table's place in the frame's list is still the order; the backend never reorders.readonly count: number— Instances in the table; the arrays may be longer.readonly order: Uint32Array— Slot indices in draw order.readonly x: Float32Array— Centre x, world units (or logical px for 'screen'), interpolated.readonly y: Float32Array— Centre y, interpolated.readonly z: Float32Array— z, not interpolated; 3D worlds.readonly rot: Float32Array— Rotation in radians, interpolated along the shortest arc.readonly sx: Float32Array— Scale x; a sign flip is a mirror and is not interpolated through zero.readonly sy: Float32Array— Scale y; same rule assx.readonly width: Float32Array— Width in world units before scale.readonly height: Float32Array— Height in world units before scale.readonly frame: Uint32Array— Atlas frame index.readonly tint: Uint32Array— Packed rgba8 tint (0xRRGGBBAA).readonly flags: Uint8Array— The object'sdrawBy: 0 for the backend's sprite path, else a registered drawer's id. An aggregate's instances carry their object's.readonly alpha: Float32Array— Opacity 0..1, multiplied with the tint alpha.readonly blend: Uint8Array— Blend mode index into BLEND_MODES.readonly repeatX: Float32Array— Texture repeats across the quad's width; 1 = once.readonly repeatY: Float32Array— Texture repeats across the quad's height; 1 = once.readonly scrollX: Float32Array— UV scroll offset x, in frame fractions.readonly scrollY: Float32Array— UV scroll offset y, in frame fractions.readonly deformKind: Uint8Array— Deform kind index into DEFORM_KINDS; 0 = none.readonly deformAmount: Float32Array— Deform amount, a fraction of the quad's size.readonly deformSpeed: Float32Array— Deform speed in cycles per second.readonly deformPhase: Float32Array— Deform phase offset in radians.readonly mesh?: Uint32Array— 3D worlds: mesh id per instance; the renderer batches by it.readonly pitch?: Float32Array— 3D worlds: interpolated pitch about x, radians (rotcarries yaw).readonly roll?: Float32Array— 3D worlds: interpolated roll about z, radians.readonly sz?: Float32Array— 3D worlds: interpolated scale z.readonly billboard?: Uint8Array— 3D worlds: 0 draws with the object's own rotation, 1 turns the mesh to face the camera, 2 turns it about y only (a tree).readonly material?: Uint32Array— 3D worlds: which registered material this instance wears; 0 is the default one. A material carries the things a PBR surface needs beyond its colour — metallic, roughness, emissive, and the normal and metallic-roughness maps — and it is an INDEX rather than a dozen more per-instance floats, because most objects share a handful of materials and a particle field shares one.readonly surface?: Uint32Array— 3D worlds: which EXTENDED SURFACE slot this instance wears, and 0 for none — a bend, a back face, an alpha cutout, decal artwork, a surface effect. It is a slot rather than the sixteen floats those need, because a mesh that wants none of them is the overwhelming majority and must pay nothing.readonly pickable?: Uint8Array— 3D worlds: whether this instance answersrender3d.pick. It is OPT-IN — clicking scenery should select nothing, and a world where every prop is clickable is a world where the player selects the floor.
SpriteCutoutSource
interface SpriteCutoutSource
From @phaser-ae/kernel
The sprite-cutout pack's per-object threshold, registered under its own name so backends can read it without
every game carrying the column. Indexed by roster slot (InstanceTable.order); an aggregate's instances use their
object's. Zero or non-finite disables it; renderers clamp a positive threshold to at most 1 and make the pixels that
survive the cut opaque.
name: string— Registry entry name,sprite-cutout.thresholds(): Float32Array— Current threshold column; resolve again after roster growth.
ViewRect
interface ViewRect
From @phaser-ae/kernel
The camera's view this frame, in world units: top-left + size, and the rendered camera itself.
x: number— Left edge, world units.y: number— Top edge, world units.w: number— Width, world units.h: number— Height, world units.cx: number— The centre, world units —x + w / 2. It exists becausew / 2is NOT it, and the difference is invisible in a wide window: a narrower one letterboxes, soxis where the visible slice starts andw / 2is off by half the letterboxing. Twenty demos centred onw / 2and were perfectly centred in a wide pane while a whole grid sat off the left edge in a tall one.cy: number— The centre, world units —y + h / 2. Seecx.camX: number— The rendered camera's x.camY: number— The rendered camera's y.zoom: number— The rendered camera's zoom.
World
interface World
From @phaser-ae/kernel
A world pack's side of the frame: it orders and gathers the roster into instance tables, and owns the camera transform. Registered with Kernel.registerWorld.
readonly info: WorldInfo— Its declaration.readonly camera: Camera— The camera it transforms through (the kernel's record).resolveDepth(): void— Writedepthfor every live object from layer + transform. Called each frame before sorting.tables(alpha: number): ReadonlyArray<InstanceTable>— Emit this frame's sorted, interpolated tables, afterresolveDepth.afterStep?(dt: number): void— After every fixed step, once all simulate steps have run (a wrapping world brings positions into range here).
WorldInfo
interface WorldInfo
From @phaser-ae/kernel
A world pack's declaration.
readonly kind: '2d' | '3d' | 'screen'— Which space the world simulates in.readonly needs: ReadonlyArray<DrawKind>— The table kinds it emits; the backend must draw every one.readonly layers: ReadonlyArray<LayerName>— Its layer names. The kernel numbers them after every earlier world's, and a spawn that names no layer lands on the first. Back to front, except where a world says otherwise: world-screen declares itsunderlaylast so a screen-only game's unnamed spawns still land onhud. Draw order is the order of the tables the world returns.
