The pack
fsm
function fsm(): Pack<{ fsm: FsmApi }, {}, { fsm: FsmData }, { brain?: Brain }>
The fsm pack: game.fsm (brains, plus phase graphs and sequences for the game's own flow), the fsm columns (state u32, time f32) with go/is methods on h.fsm, the brain spawn field, and a simulate step before collision. No options.
Helpers
createPhases
function createPhases<C>(ctx: C, defs: Record<string, PhaseDef<C>>): Phases<C>
Creates a Phases graph over the shared context ctx.
createSequence
function createSequence(steps: SceneStep[], opts: { loop?: boolean } = {}): Sequence
Creates a Sequence of timed steps.
Classes
Phases
class Phases<C>
A phase graph. Transitions are queued and applied between frames, never
inside update, so a phase cannot be torn down while its own code is running.
readonly ctx: C— The shared game context, passed to every phase callback.time: number— Seconds since this phase was entered.prev: string | null— The phase left behind, or null.constructor(ctx: C, defs: Record<string, PhaseDef<C>>)get name(): string | null— The active phase name, or null before the firstgo().in(...names: string[]): boolean— True whilenameis any of these — reads better than a chain of===.go(next: string): void— Queue a transition. Applied at the top of the nextupdate.restart(): void— Back to this phase'srestartAt, or a fresh entry into it. The death → respawn edge:restartAtis what stops a restart re-running an intro.own<T extends Disposable | (() => void)>(thing: T): T— Dispose of this when the phase exits — shapes, trails, starfields, bodies, or a plain function. Retained objects outlive a phase otherwise, and a vector game that forgets one leaves it burning on the screen for good.at(t: number, fn: (ctx: C) => void): void— Runfnonce,tseconds into this phase. Cleared on exit.every(period: number, fn: (ctx: C) => void): void— Runfneveryperiodseconds while this phase is active.update(dt: number): void— Applies a queued transition, then runs the phase, its timers and its edges. Call once a frame.
Sequence
class Sequence
A timed run of named steps. Attract loops; a cut scene does not.
readonly steps: SceneStep[]— The steps, in play order.loop: boolean— True to start again after the last step. Default true.time: number— Seconds into the current step.index: number— Index of the current step.finished: boolean— True once a non-looping sequence has run out.onStep: ((name: string, index: number) => void) | null— Called as each step starts.constructor(steps: SceneStep[], opts: { loop?: boolean } = {})get current(): string— The name of the current step, or an empty string when there are no steps.get frac(): number— 0..1 through the current step — for fades and slides.update(dt: number): void— Advances the clock and moves to the next step when the current one is done. Call once a frame.go(step: string | number): void— Jump to a step by name (or index), resetting its clock.reset(): void— Back to the first step with the clock at zero.
Types
Brain
interface Brain<S extends string = string, H extends Handle = Handle>
A state machine definition: pass as brain at spawn or to game.fsm.brain.
initial: S— The state entered when the brain is attached.states: Record<S, StateDef<S, H>>— Every state by name;goto a name not here throws.
Disposable
interface Disposable
Anything the phase system can dispose of when its phase exits.
kill?(): void— Removes the object from play. Called on phase exit when present.destroy?(): void— Frees the object. Called on phase exit when present.
FsmApi
interface FsmApi
What game.fsm presents.
brain<S extends string>(h: Handle, brain: Brain<S>): void— Give a handle a brain and enter itsinitialstate now; replaces any brain it had without callingexit.go(h: Handle, state: string): void— Transitionh; same rules ash.fsm.go.state(h: Handle): string | null— The current state's name, ornullwhenhhas no brain.define<S extends string>(brain: Brain<S>): Brain<S>— A brain helper: states as a typed union, checked at the call site.phases<C>(ctx: C, defs: Record<string, PhaseDef<C>>): Phases<C>— The game's own flow as a phase graph over a context object: the same as thecreatePhaseshelper.sequence(steps: SceneStep[], opts?: { loop?: boolean }): Sequence— A timed run of named steps, for an attract mode or a cut scene: the same as thecreateSequencehelper.
FsmData
interface FsmData
What h.fsm presents: the columns plus the methods the pack attaches.
readonly state: number— The current state as its INDEX in the brain's state list (a roster column). For the name useis()orgame.fsm.state(h).readonly time: number— Seconds in the current state; reset to 0 bygo.go(state: string): void— Transition:exiton the old state,enteron the new. Throws on an unknown state or a handle without a brain.is(state: string): boolean— True when the current state isstate.
PhaseDef
interface PhaseDef<C>
One phase: its callbacks, edges and timed exit.
enter?(ctx: C, from: string | null): void— Entered —fromis the phase left behind, or null on the first entry.update?(ctx: C, dt: number, time: number): void— Once a frame while active, before the edges are tested.exit?(ctx: C, to: string | null): void— Left —tois where it is going. Owned objects are disposed after this.to?: PhaseEdge<C>[]— Tested in order afterupdate; the first true one wins.after?: number— Leave forthenautomatically after this many seconds.then?: string— Whereaftergoes.restartAt?: string—restart()returns here instead of re-entering this phase.
PhaseEdge
interface PhaseEdge<C>
An outward edge: when when reads true, go to go.
when(ctx: C): boolean— Tested each frame; true means take this edge.go: string— The name of the phase to enter.
SceneStep
interface SceneStep
One step of a Sequence: a name and how long it holds.
name: string— The labelcurrentreports.time: number— Seconds this step holds.
StateDef
interface StateDef<S extends string, H extends Handle = Handle>
One state of a brain. Every hook is optional.
enter?(h: H, from: S | null): void— Called on entering the state;fromisnullon the first entry.tick?(h: H, dt: number): void— Called every simulate step while current, withdtin seconds.exit?(h: H, to: S): void— Called on leaving the state forto.


