The pack
coverShooter
function coverShooter(): Pack<{ coverShooter: typeof api }>
Install the cover shooter API.
Helpers
actor
function actor(kind: string, at: Partial<StopPoint>, o: Partial<Omit<ActorSpec, "kind" | "at">> = {}): ActorSpec
An actor spec.
areaBuilder
function areaBuilder(id: string, name: string, opts: Partial<Omit<AreaDef, "id" | "name" | "sections" | "scenery">> = {}): AreaBuilder
Start authoring an area.
conditionHolds
function conditionHolds(c: Condition, flags: Readonly<Record<string, boolean | number | string>>): boolean
Does a condition hold for these flags.
COVER_STEP
const COVER_STEP: number
The default fixed step: 1/60 s.
coverDifficulty
function coverDifficulty(name: DifficultyName): CoverDifficulty
Built-in difficulty presets. Arcade is the original tables.
createCoverShooter
function createCoverShooter(def: CoverDef): CoverShooter
Build a session.
fmtTime
function fmtTime(seconds: number): string
Format seconds as the arcade's 00'00"00.
groundAt
function groundAt(boxes: readonly SceneryBox[], x: number, z: number, fallback: number): number
The highest walkable top under (x, z), or fallback when there is none.
houseOfTheDeadChapters
function houseOfTheDeadChapters(): StageDef[]
The four chapters of the arcade game.
houseOfTheDeadKinds
function houseOfTheDeadKinds(): ActorKind[]
The House of the Dead actor kinds.
houseOfTheDeadPreset
function houseOfTheDeadPreset(o: HouseOfTheDeadOptions = {}): CoverDef
The House of the Dead (Sega 1996).
houseOfTheDeadProjectiles
function houseOfTheDeadProjectiles(): CoverProjectile[]
Projectiles: axes, knives, barrels, wrecking balls, darts, web balls and fireballs; all can be shot down.
insideBox
function insideBox(b: SceneryBox, p: Vec3, margin = 0): boolean
Is a point inside a box.
isWalkable
const isWalkable = (b: SceneryBox): boolean=> …
Do actors stand on this box.
lineOfSight
function lineOfSight(boxes: readonly SceneryBox[], from: Vec3, to: Vec3): boolean
Can a point see another: no occluding box between them.
occludes
const occludes = (b: SceneryBox): boolean=> …
Does this box stop shots and block sight (walkable boxes never do: an actor stands on them).
overFootprint
function overFootprint(b: SceneryBox, x: number, z: number, margin = 0): boolean
Is a ground point (x, z) over a box's footprint (with a margin).
popUp
function popUp(o: { from?: "below" | "left" | "right" | "above" | "behind" | "none"; aim?: number; shots?: number; gap?: number; rest?: number; first?: number; dist?: number } = {}): ActorStep[]
Script: pop up from cover, aim, fire, duck and repeat (Time Crisis gunmen).
rayBox
function rayBox(b: SceneryBox, origin: Vec3, dir: Vec3, maxT = Infinity): { t: number; normal: Vec3 } | null
Where a ray enters a box: distance along the (unit) direction and the face normal, or null.
sceneryRay
function sceneryRay(boxes: readonly SceneryBox[], origin: Vec3, dir: Vec3, maxT = Infinity, filter: (b: SceneryBox) => boolean = () => true): { t: number; normal: Vec3; box: SceneryBox } | null
The nearest box a ray meets within maxT, among the boxes filter accepts.
SEE_THROUGH_MODELS
const SEE_THROUGH_MODELS: ReadonlySet<string>
Models that never stop a shot or block sight by default (lights, water surfaces, skirting).
shamble
function shamble(o: { stop?: number; windup?: number; rest?: number; first?: number; from?: "below" | "left" | "right" | "above" | "none" | "behind" } = {}): ActorStep[]
Script: lumber toward the camera and strike when close; repeat (zombies).
standAndFire
function standAndFire(o: { from?: "below" | "left" | "right" | "above" | "none"; aim?: number; shots?: number; gap?: number; rest?: number; first?: number } = {}): ActorStep[]
Script: step out and keep shooting from the open (no cover).
timeCrisisKinds
function timeCrisisKinds(): ActorKind[]
The Time Crisis actor kinds (accuracy from the GameSurge enemy guide; see the docs).
timeCrisisPreset
function timeCrisisPreset(o: TimeCrisisOptions = {}): CoverDef
Time Crisis (Namco 1995).
timeCrisisProjectiles
function timeCrisisProjectiles(): CoverProjectile[]
Projectiles: grenades, bazooka rockets and Sherudo's daggers.
timeCrisisStages
function timeCrisisStages(): StageDef[]
The three stages of the arcade game.
validateCover
function validateCover(def: CoverDef): void
Validate a definition; throws with a clear message.
WALK_MODELS
const WALK_MODELS: ReadonlySet<string>
Models actors stand on by default.
wave
function wave(actors: ActorSpec[], o: Partial<Omit<WaveDef, "actors">> = {}): WaveDef
A wave.
Types
ActorKind
interface ActorKind
A kind of actor: enemies, bosses, civilians, breakables, items and switches.
id: string— Unique id.role?: Role | undefined— Rules role (default'enemy').hp?: number | undefined— Hit points (default 1). Bosses: the session's hit counter.radius?: number | undefined— Sphere radius when there are no regions (default 40).regions?: CoverRegion[] | undefined— Hit regions in the actor's frame (xright,yup from its feet,ztoward the camera).script?: ActorStep[] | undefined— The script it runs when a spawn gives none.speed?: number | undefined— Walking speed, units per second (default 150).accuracy?: number | number[] | undefined— Chance each hitscan shot hits (Time Crisis: red soldiers 0.9 for the first, blue 0.2–0.4). Default 0.3.points?: number | undefined— Points for a kill.headPoints?: number | undefined— Points for each hit on a part named 'head' (cumulative: House of the Dead headshots).stagger?: { time: number; knock?: number | undefined } | undefined— Hit reaction: seconds staggered (attack interrupted) and units knocked back.reel?: number | undefined— Bosses: seconds it reels after each damaging hit (unhittable, attack interrupted).timeBonus?: { max: number; decay: number } | undefined— Time Crisis orange soldiers: seconds added for a kill,maxfalling to 0 overdecayseconds of its life.drop?: string | undefined— Breakables: the item kind it drops.reward?: { points?: number | undefined; lives?: number | undefined } | undefined— Items: what shooting it gives.rescue?: { time: number; points?: number | undefined; lives?: number | undefined } | undefined— Civilians: rescued if every attacker grabbing it dies withintimeseconds; reward on rescue.protect?: string | undefined— Civilians: the protected label light-gun reports (default 'civilian').sets?: string | undefined— A flag set when it is destroyed (switches also setshot:<name>; any named actor killed setskilled:<name>).boss?: { name?: string | undefined; phases: BossPhase[]; points?: number | undefined } | undefined— Bosses: phases, a name and points for the kill.flies?: boolean | undefined— It flies or hangs (helicopters, bats, items, wall switches): it may be placed above the ground. Everything else stands on the ground (spawn heights must be 0).blocks?: boolean | undefined— Holds the stop until it is gone (default true for enemies and bosses, false otherwise).look?: Look | undefined— Presentation hints.
ActorMode
type ActorMode = | "hidden" | "enter" | "idle" | "move" | "leap" | "aim" | "fire" | "throw" | "approach" | "windup" | "strike" | "stagger" | "reel" | "exit" | "rescued" | "flee"
What an actor is doing (for presenters' animation).
ActorSpec
interface ActorSpec
One actor in a wave.
kind: string— Kind id.at: StopPoint— Its spot in the stop frame.delay?: number | undefined— Seconds after the wave fires (default 0).script?: ActorStep[] | undefined— A script instead of the kind's.name?: string | undefined— A name for rescues, flags and branches (rescued:<name>,lost:<name>,shot:<name>).grab?: string | undefined— Civilians it is attacking (names, comma-separated): their rescue fails if it is still alive when their time is up. A switch can hold civilians the same way (a cage).hp?: number | undefined— Hit points instead of the kind's.drop?: string | undefined— Item kind it drops when destroyed (overrides the kind's).
ActorState
interface ActorState
A live actor (plain data). Its rail-route target has the same id.
id: string— Id (the rail target's).kind: string— Kind id.section: string— Section whose stop frameposis in.name: string— Name from its spawn ('' when unnamed).pos: StopPoint— Position in the stop frame.home: StopPoint— Its authored spot.script: ActorStep[]— The script it runs (plain data).step: number— Current step index.t: number— Seconds into the current step.loops: Record<string, number>— Loop counters by step index.mode: ActorMode— What it is doing.modeTime: number— Seconds in the current mode.hidden: boolean— Out of sight behind cover: shots cannot hit it.motion: { from: StopPoint; to: StopPoint; time: number; arc: number } | null— Motion of the current step: start, end, duration, arc height.shots: { left: number; index: number; next: number }— Shots or throws left in the current step, and the index of the next for accuracy lists.stagger: number— Seconds of stagger or reel left.age: number— Seconds alive.grab: string— Civilian it is attacking ('' for none).hp: number— Hit points (bosses: the session's counter; others mirror the rail target).hpMax: number— Maximum hit points.phase: number— Boss phase index.drop: string— Item it drops.fired: number— Seconds since it last fired (presenters' muzzle flash).danger: boolean— The last shot it fired will hit unless the player takes cover (presenters' red flash).lost: string[]— Body parts shot off.done: boolean— Rescued, killed or gone: no longer acting.delay: number— Seconds before it appears (a wave member'sdelay); not drawn or hittable until then.lastPart: string— The part its last hit struck (a kill by a 'head' hit is a headshot).boss: boolean— A boss (the session counts its hit points and phases).pending: boolean— A boss phase's minions and banner wait for the camera to reach the phase's scene.
ActorStep
type ActorStep = /** Come out from cover: from an offset (behind a crate, dropping from the ceiling, round a corner) to the actor's spot (`at` moves the spot first). Unhittable for the first half. */ | { do: "enter"; from?: Side | undefined; time?: number | undefined; dist?: number | undefined; at?: Partial<StopPoint> | undefined } /** Go back into cover (the reverse of `enter`); unhittable from half way. */ | { do: "hide"; to?: Side | undefined; time?: number | undefined; dist?: number | undefined } /** Move to a point of the stop frame (missing fields keep the current value). */ | { do: "move"; to: Partial<StopPoint>; time: number } /** Move by an offset. */ | { do: "shift"; by: Partial<StopPoint>; time: number } /** Jump in an arc to a point (ninjas between pillars). */ | { do: "leap"; to: Partial<StopPoint>; time: number; height?: number | undefined } /** Do nothing for a while. */ | { do: "wait"; time: number } /** Raise the gun: the wind-up before `fire` (scaled by the difficulty's `windup`). */ | { do: "aim"; time: number } /** Fire hitscan shots at the player. Each shot hits with `accuracy` (the kind's by default; a list gives the first shots' chances, the last repeating). */ | { do: "fire"; shots?: number | undefined; gap?: number | undefined; accuracy?: number | number[] | undefined } /** Throw or launch projectiles (grenades, rockets, knives, axes, fireballs) that can be dodged in cover or shot down. `needs`: a part that must still be on (a barrel shot out of a zombie's hands is not thrown). */ | { do: "throw"; projectile: string; count?: number | undefined; gap?: number | undefined; accuracy?: number | undefined; from?: StopPoint | undefined; needs?: string | undefined } /** Close in to `reach` of the camera (at the kind's speed), wind up for `windup` seconds, then strike. */ | { do: "melee"; windup?: number | undefined; reach?: number | undefined; damage?: number | undefined } /** Walk toward the camera until within `stop` units. */ | { do: "approach"; stop: number; speed?: number | undefined } /** Leave the scene (`escape` marks it as got away). */ | { do: "exit"; to?: Side | "away" | undefined; time?: number | undefined; escape?: boolean | undefined } /** Jump to one of these steps, chosen at random (seeded): a boss's random attack variations. */ | { do: "branch"; to: number[] } /** Jump back to a step (default 0) up to `times` times (default for ever). */ | { do: "loop"; to?: number | undefined; times?: number | undefined } /** Call minions mid-script (boss summons, the Hanged Man's bats). */ | { do: "summon"; actors: ActorSpec[] } /** Set a session flag. */ | { do: "flag"; name: string; value?: boolean | number | string | undefined }
One step of an actor's script. Times are seconds at the Arcade difficulty.
AreaBuilder
interface AreaBuilder
An area being authored.
stop(id: string, at: Vec3, look: Vec3, opts?: Partial<Omit<SectionDef, "id" | "stop" | "look">>): StopBuilder— Add a stop:atandlookare world floor points; options go onto the section.box(model: string, at: Vec3, size: Vec3, color: string, extra?: { yaw?: number; glow?: number; walk?: boolean; solid?: boolean }): AreaBuilder— Add world-space scenery.room(x0: number, x1: number, z0: number, z1: number, o: { h: number; floor: string; wall: string; ceiling?: string; y?: number; open?: Array<"n" | "s" | "e" | "w">; lamps?: string; trim?: string }): AreaBuilder— A room: floor, walls and optionally a ceiling, spanningx0..x1andz0..z1(world).build(): AreaDef— The finished area.
AreaDef
interface AreaDef
An area: part of a stage with its own timer start (Time Crisis) and scenery.
id: string— Id.name: string— Name for banners ('AREA 1').time?: number | undefined— Timer at the start of the area (default the timer'sstart).sections: SectionDef[]— The stops in order.scenery?: SceneryBox[] | undefined— Scenery.mood?: { sky?: string | undefined; fog?: string | undefined; fogEnd?: number | undefined; light?: number | undefined } | undefined— Presentation: background, fog and light.
BossPhase
interface BossPhase
A boss phase: what the boss does until its hit points fall to until (a fraction of the maximum).
until?: number | undefined— The phase ends when hp / max falls to this (default 0: the last phase).scene?: string | undefined— Move the camera to this section when the phase begins (Time Crisis boss scenes, the Hanged Man's rooftop).at?: StopPoint | undefined— The boss's spot for the phase (stop frame of the current scene).script: ActorStep[]— The looping attack pattern.weak?: Record<string, number> | undefined— Damage multiplier per region this phase; regions not listed take none (shots are blocked). Default: the kind's regions.spawn?: ActorSpec[] | undefined— Minions that join at the start of the phase.guarded?: boolean | undefined— The boss cannot be hit while this phase's minions live.stun?: number | undefined— Seconds it reels at the start of the phase (unhittable, not attacking).extend?: number | undefined— Seconds added to the timer when the phase begins.banner?: string | undefined— A banner for presenters ('ACTION!', 'WEAK POINT').
Condition
type Condition = | { flag: string; is?: boolean | number | string | undefined } | { all: Condition[] } | { any: Condition[] } | { not: Condition }
A condition on session flags.
CoverDef
interface CoverDef
The full game.
title?: string | undefined— Title.view: { w: number; h: number }— The screen the gun points at (logical pixels; aim and hit tests use it).camera?: CameraDef | undefined— Camera (field of view, aspect).eye?: number | undefined— Eye height above the floor (default 160).speed?: number | undefined— Camera travel speed between stops (default 360 units per second).stages: StageDef[]— Stages in order.kinds: ActorKind[]— Actor kinds.projectiles?: CoverProjectile[] | undefined— Enemy projectiles.gun: CoverGun— The gun.cover?: CoverRules | null | undefined— The cover pedal, or null for no cover (The House of the Dead).timer?: TimerRules | null | undefined— The area timer, or null for none.lives: { start: number; max?: number | undefined; immunity?: number | undefined }— Lives: at the start, most held, and seconds of immunity after a hit (default 1).warn?: number | undefined— Seconds a hitscan shot takes from its flash to impact at Arcade (default 0.3).fireWhileMoving?: boolean | undefined— Shooting allowed while walking between stops (default false).continues?: number | undefined— Continues (default 3; Infinity for free play).continueSeconds?: number | undefined— Continue countdown seconds (default 10).scoring?: ScoringRules | undefined— Scoring, results and endings.difficulty?: CoverDifficulty | undefined— Difficulty (default Arcade).timing?: Partial<{ intro: number; clear: number; ending: number; over: number }> | undefined— Seconds of the intro, clear, ending and game-over screens.startStage?: number | undefined— Starting stage index (default 0).seed?: number | undefined— Seed.step?: number | undefined— Fixed step (default 1/60).hiScore?: number | undefined— High score kept across sessions.records?: Record<string, number> | undefined— Best stage times kept across sessions (stage id to seconds).maxActors?: number | undefined— Resource bound: actors alive at once (default 64).
CoverDifficulty
interface CoverDifficulty
Easy / Normal / Arcade scaling. Arcade is the original tables (all 1, no extra lives).
name: string— Preset name.accuracy: number— Enemy hit chance multiplier.windup: number— Wind-up multiplier: aiming, melee and boss attack wind-ups take this much longer.warn: number— Red-flash multiplier: the time between a hitting shot's flash and its impact.speed: number— Enemy speed multiplier (walking, projectiles).lives: number— Extra lives at the start.time: number— Timer extension multiplier.
CoverEvent
type CoverEvent = | { type: "phase"; phase: CoverPhase } | { type: "stage"; stage: number; name: string } | { type: "area"; area: string; name: string } | { type: "wait"; section: string } | { type: "action"; section: string } | { type: "section-clear"; section: string } | { type: "time-extend"; seconds: number; timer: number } | { type: "time-up" } | { type: "cover"; down: boolean } | { type: "shot"; x: number; y: number; onScreen: boolean } | { type: "reload"; via: string } | { type: "reloaded" } | { type: "dry" } | { type: "hit"; actor: string; kind: string; region: string; part: string; at: Vec3 } | { type: "impact"; at: Vec3; normal: Vec3 } | { type: "blocked"; actor: string; kind: string; at: Vec3 } | { type: "limb"; actor: string; kind: string; region: string; at: Vec3 } | { type: "kill"; actor: string; kind: string; at: Vec3; headshot: boolean; points: number } | { type: "escape"; actor: string; kind: string } | { type: "enemy-aim"; actor: string } | { type: "enemy-fire"; actor: string; hits: boolean; at: Vec3 } | { type: "ricochet"; actor: string } | { type: "throw"; actor: string; projectile: string; id: string } | { type: "projectile-shot"; id: string; kind: string; at: Vec3; points: number } | { type: "windup"; actor: string } | { type: "strike"; actor: string; hits: boolean } | { type: "player-hit"; cause: string; lives: number } | { type: "civilian-hit"; actor: string; name: string; lives: number } | { type: "rescued"; actor: string; name: string; points: number; lives: number } | { type: "civilian-lost"; actor: string; name: string } | { type: "item"; actor: string; kind: string; points: number; lives: number } | { type: "switch"; actor: string; name: string; flag: string } | { type: "life-up"; lives: number } | { type: "boss"; actor: string; kind: string; state: "appear" | "phase" | "reel" | "defeated"; phase: number } | { type: "branch"; from: string; to: string; label: string } | { type: "score"; points: number; reason: string } | { type: "stage-clear"; stage: number; time: number; record: boolean } | { type: "continue"; left: number } | { type: "game-over"; score: number; time: number } | { type: "ending"; ending: string; score: number; time: number }
Events for presenters and sound.
CoverGun
interface CoverGun
The player's gun: light-gun's definition without the view (the session supplies it).
weapons: WeaponDef[]— Weapons (the first is the pistol).primary?: string | undefined— Primary weapon id.parts?: Record<string, PartDef> | undefined— Body parts.protect?: ProtectDef | undefined— Protected targets (civilians): penalties are applied as lives.combo?: ComboDef | undefined— Streaks.smoothing?: number | undefined— Crosshair smoothing (seconds; default 0).
CoverInput
interface CoverInput
Input each step. Aim is in view pixels; every field is optional.
x?: number | undefined— Crosshair x.y?: number | undefined— Crosshair y.onScreen?: boolean | undefined— Is the gun pointed at the screen (default: the point is inside the view). False with the trigger reloads an off-screen-reload gun.snap?: boolean | undefined— No smoothing this step (a touch tap).trigger?: boolean | undefined— Trigger held.pedal?: boolean | undefined— Cover pedal held: out of cover, shooting (Time Crisis). Released: in cover, reloading.reload?: boolean | undefined— Reload button held (guns with button reloads and no cover).
CoverPhase
type CoverPhase = "attract" | "intro" | "play" | "continue" | "clear" | "ending" | "over"
Session phases.
CoverProjectile
interface CoverProjectile
An enemy projectile: rail-route's projectile kinds, launched by throw steps.
id: string— Unique id.speed: number— Speed, units per second.radius?: number | undefined— Radius for hits on the player and by shots (default 20).damage?: number | undefined— Lives taken on a hit (default 1).shootable?: boolean | undefined— Can be shot down (default true).hp?: number | undefined— Hit points (default 1).points?: number | undefined— Points when shot down.look?: Look | undefined— Presentation hints.
CoverRegion
interface CoverRegion extends RegionDef
A hit region: a rail-route region plus the rules' body part.
part?: string | undefined— Body part for light-gun statistics and headshot scoring (default the region id).wound?: number | undefined— Withhp: damage dealt to the actor when this part is shot off (House of the Dead limbs). Default 0.
CoverRules
interface CoverRules
The cover pedal (Time Crisis).
duck?: number | undefined— Seconds to duck fully into cover (default 0.18).rise?: number | undefined— Seconds to rise fully out (default 0.18).safe?: number | undefined— Cover fraction above which the player is safe (default 0.5).fire?: number | undefined— Cover fraction at or below which the gun can fire (default 0.15).reload?: boolean | undefined— Reload when the pedal is released (default true).startIn?: boolean | undefined— Start each stop in cover (default true: Time Crisis begins each fight ducked until the pedal is pressed).
CoverShooter
interface CoverShooter
A running game.
readonly def: CoverDef— The definition.readonly state: CoverState— State (plain data).readonly rail: Rail— The current stage's rail (route, targets, projectiles).readonly gun: Gun— The player's gun.readonly stage: StageDef— The current stage.readonly area: AreaDef— The current area.readonly section: SectionDef— The current section.readonly difficulty: CoverDifficulty— The difficulty in use.sectionDef(id: string): SectionDef— A section of the current stage.areaOf(section: string): AreaDef— The area a section of the current stage belongs to.kind(id: string): ActorKind— A kind.projectile(id: string): CoverProjectile— A projectile kind.actor(id: string): ActorState | undefined— A live actor.stopFrame(section: string): Frame— A section's stop frame (origin on the floor at the stop, forward toward its look point, y up).toWorld(section: string, p: StopPoint): Vec3— A stop-frame point in world space.pose(): CameraPose— The camera pose including the cover drop.visible(id: string): boolean— Is an actor out of cover, on the screen and in plain sight of the player (no scenery in between).ground(section: string, x: number, z: number): number— The ground height under a world point in a section's area (walkable scenery, else the stop's floor).safe(): boolean— Is the player safe from shots now (in cover or immune).canFire(): boolean— Can the gun fire now.attract(): void— Attract mode (the first stage's scene, no play).begin(stage?: number): void— Start a game atstartStageor the given stage.continueGame(): boolean— Use a continue in the continue phase.tick(seconds: number, input?: CoverInput): void— Advance by seconds (whole fixed steps).step(input?: CoverInput): void— One fixed step.drain(): CoverEvent[]— Take events.setDifficulty(d: CoverDifficulty): void— Change the difficulty (enemy tables apply at once; extra lives at the next game).snapshot(): CoverSnapshot— Deep copy of the session, rail and gun.restore(s: CoverSnapshot): void— Restore a snapshot into a session built from the same definition.
CoverSnapshot
interface CoverSnapshot
A snapshot: the session's state with its rail's and gun's.
state: CoverState— Session state.rail: RailState— Rail state.gun: GunState— Gun state.
CoverState
interface CoverState
Plain-data session state.
phase: CoverPhase— Phase.phaseTime: number— Seconds in the phase.stage: number— Stage index.area: string— Current area id.section: string— Current section id.moving: boolean— Travelling between stops (WAIT).atStop: number— Seconds at the current stop (0 while moving).sectionTime: number— Seconds since the camera set off toward the current stop.score: number— Score.hiScore: number— High score.lives: number— Lives.livesMax: number— Most lives.immunity: number— Seconds of immunity left after a hit.continues: number— Continues left.countdown: number— Continue countdown.timer: number | null— Area timer (null without timer rules).time: { stage: number; total: number }— Seconds played this stage, and in all (Time Crisis ranks by these).cover: { amount: number; down: boolean }— Cover: 0 out, 1 fully ducked;downis where the pedal is taking it.actors: ActorState[]— Live actors.bullets: EnemyBullet[]— Enemy shots in flight.waves: Array<{ fired: boolean; skipped: boolean; ids: string[]; due: number }>— This section's waves: fired, the actors each spawned, and seconds since the trigger.flags: Record<string, boolean | number | string>— Session flags:rescued:<name>,lost:<name>,shot:<name>,killed:<name>, kinds'setsandrescued-all(no civilian lost so far).rescues: { stage: { rescued: number; lost: number; total: number }; all: { rescued: number; lost: number; total: number } }— Civilians this stage and in all.stats: { kills: number; headshots: number; damage: number; continues: number; escaped: number }— Statistics.results: Array<{ text: string; value: string }>— Lines of the stage results screen.ending: string— The ending reached ('' until then).records: Record<string, number>— Best stage times.banner: { text: string; t: number } | null— Current banner and seconds shown.steps: number— Fixed steps run.rng: number[]— The seeded random stream's state: four words, from the kernel'srng.snapshot(). It advances in place and is saved with the state.
DifficultyName
type DifficultyName = "easy" | "normal" | "arcade"
Built-in difficulty presets.
EnemyBullet
interface EnemyBullet
A hitscan enemy shot in flight: it lands after the red flash unless the player is in cover.
from: string— Actor that fired it.t: number— Seconds until impact.total: number— Total flight time.
HouseOfTheDeadOptions
interface HouseOfTheDeadOptions
Options for The House of the Dead preset.
difficulty?: CoverDifficulty | undefined— Difficulty (default Normal).lives?: number | undefined— Life torches at the start before the difficulty's extras (default 3).maxLives?: number | undefined— Most torches (default 5).continues?: number | undefined— Continues (default 3; Infinity for free play).trueEnding?: number | undefined— Score at or above which the true ending plays (default 62000, the arcade's; see the docs on chapter length).startStage?: number | undefined— First chapter (0-based).reloadMargin?: number | undefined— The edge band, as a fraction of the screen, where a shot reloads like one fired off the screen (default 0.07).seed?: number | undefined— Seed.hiScore?: number | undefined— High score.stages?: StageDef[] | undefined— Chapters instead of the arcade's.
Look
interface Look
Presentation hints a kind carries for a renderer (no rules read them).
model: string— Model name the presenter builds ('soldier', 'ninja', 'zombie', 'scientist', 'crate', 'helicopter' ...).color?: string | undefined— Main colour (CSS).accent?: string | undefined— Second colour (trousers, armour).detail?: string | undefined— Third colour (skin, visor).scale?: number | undefined— Scale on the model's authored size (default 1). The kind's hit regions scale with it, so it is hit where it is drawn.weapon?: string | undefined— What the actor holds ('pistol', 'machine-gun', 'grenade', 'pole', 'bazooka', 'knife', 'axe', 'chainsaw', 'barrel', 'shield' ...).
NextDef
interface NextDef
A branch after a section: the first option whose condition holds, else default.
options: Array<{ section: string; when?: Condition | undefined; label?: string | undefined }>— Options in order.default?: string | undefined— Fallback section (default the last option's).
Role
type Role = "enemy" | "boss" | "civilian" | "breakable" | "item" | "switch"
What part a kind plays in the rules.
SceneryBox
interface SceneryBox
Scenery: drawn by presenters, and read by the rules as the ground actors stand on and the walls and crates that stop shots and block sight.
model?: string | undefined— Model: 'box' (default), 'crate', 'pillar', 'barrel', 'door', 'water', 'stairs', 'window', 'lamp', 'tree', 'statue' ...at: Vec3— Centre of the base (world).size: Vec3— Full size x (width), y (height), z (depth).yaw?: number | undefined— Turn about y (radians).color: string— Colour.glow?: number | undefined— Glow (emissive).walk?: boolean | undefined— Actors stand on it (default for floor, platform, stairs, catwalk, helipad and ledge models).solid?: boolean | undefined— It stops shots and blocks sight (default: every box that is not walkable, except lamps, water and trim).
ScoringRules
interface ScoringRules
Scoring, results and endings.
rank?: "time" | "score" | undefined— Rank players by'time'(Time Crisis: total time, lower is better) or'score'(default 'score').allRescued?: number | undefined— Lives added when every civilian of a stage was rescued (The House of the Dead). Default 0.perContinue?: number | undefined— Points added for each continue used (The House of the Dead adds 1, which decides its third ending). Default 0.endings?: Array<{ id: string; min?: number | undefined; allRescued?: boolean | undefined; digit?: "zero" | "nonzero" | undefined }> | undefined— Endings by final score: the first whose rule holds.
SectionDef
interface SectionDef
A stop on the route: the camera travels here, the actors act, and it moves on when the stop is cleared.
id: string— Unique id in the stage.stop: Vec3— The camera's spot (world, on the floor; the eye iseyeabove it).look: Vec3— The point the camera looks at once it arrives (world).from?: Vec3 | undefined— Where the camera comes from when the area starts here (world floor point; default 200 behind the stop).via?: Vec3[] | undefined— Points the camera passes through on the way (world floor points).speed?: number | undefined— Travel speed (default the definition's).waves?: WaveDef[] | undefined— What appears here.extend?: number | undefined— Seconds added to the timer when it is cleared.next?: string | NextDef | undefined— The next section (default the following one in the stage), or a branch.end?: boolean | undefined— The stage ends here.hold?: { min?: number | undefined; max?: number | undefined } | undefined— At leastminseconds at the stop (a window to shoot a switch); at mostmax(then it moves on regardless).cover?: { drop?: number | undefined; side?: number | undefined } | false | undefined— Cover at this stop (with cover rules): the camera drop and sideways shift when ducked.false: no cover here.fireWhileMoving?: boolean | undefined— Shooting allowed while walking here (default the definition'sfireWhileMoving).banner?: string | undefined— A banner for presenters on arrival.
Side
type Side = "below" | "above" | "left" | "right" | "behind" | "none"
Where an actor appears from or leaves to.
StageDef
interface StageDef
A stage (Time Crisis) or chapter (The House of the Dead).
id: string— Id.name: string— Name ('STAGE 1', 'CHAPTER 1').title?: string[] | undefined— Title lines on the intro screen.areas: AreaDef[]— Areas in order.
StopBuilder
interface StopBuilder
A stop being authored: its section and helpers working in its frame.
readonly def: SectionDef— The section definition (mutable until the area is built).world(p: Partial<StopPoint>): Vec3— A stop-frame point in world space.wave(w: WaveDef): StopBuilder— Add a wave.prop(model: string, at: Partial<StopPoint>, size: Vec3, color: string, extra?: { yaw?: number; glow?: number; walk?: boolean; solid?: boolean }): StopBuilder— Add scenery at a stop-frame point (atis the centre of its base).cover(color?: string, size?: Vec3): StopBuilder— The crate the camera ducks behind (just ahead of the stop).
StopPoint
type StopPoint = Vec3
Positions are in a stop's frame: x right, y up from the ground under the point, z ahead of the camera's stop.
TimeCrisisOptions
interface TimeCrisisOptions
Options for the Time Crisis preset.
difficulty?: CoverDifficulty | undefined— Difficulty (default Normal).lives?: number | undefined— Lives at the start before the difficulty's extras (default 3, the arcade's).continues?: number | undefined— Continues (default 3).areaTime?: number | undefined— Timer at the start of each area (default 60).magazine?: number | undefined— Bullets per magazine (default 6; Time Crisis 2 used 9).startStage?: number | undefined— First stage (0-based).seed?: number | undefined— Seed.records?: Record<string, number> | undefined— Best stage times kept across sessions.stages?: StageDef[] | undefined— Stages instead of the arcade's (customised layouts).
TimerRules
interface TimerRules
The area timer (Time Crisis).
start?: number | undefined— Seconds at the start of an area (default 60).max?: number | undefined— Most seconds the timer can hold (default 60).whileMoving?: boolean | undefined— Runs while the camera travels between stops (default true: Time Crisis counts the WAIT walks).continueTime?: number | undefined— Seconds after a continue (defaultstart).
WaveDef
interface WaveDef
A group of actors that appears at a stop.
id?: string | undefined— Id (forafter).at?: number | undefined— Seconds after the trigger (default 0).after?: string | undefined— Wait until this wave (or'prev', the one before) has spawned and every blocking actor of it is gone.alive?: number | undefined— Only while at most this many blocking actors are alive.on?: "arrive" | "enter" | undefined—'arrive'(default): when the camera reaches the stop;'enter': as it sets off toward it.if?: Condition | undefined— Only if this holds when it is due (a switch shot, a rescue made); skipped otherwise.actors: ActorSpec[]— The actors.


