The pack
rescueRaid
function rescueRaid(): Pack<{ rescueRaid: typeof api }>
Install the renderer-independent rescue raid API.
Helpers
choplifterPreset
function choplifterPreset(o: ChoplifterPresetOptions = {}): RescueRaidConfig
Choplifter (Dan Gorlin / Brøderbund 1982; Sega arcade 1985) as data: a bounded desert with the base and its post office at the right edge and enemy territory beyond the border fence; four barracks of 16 hostages that must be shot open; hostages run to the LANDED helicopter (16 seats) and walk into the post office once it lands at the base; landing on a hostage, or shooting one, kills it; tanks in the territory, jets after the first trip home and homing air mines after the second; three helicopters (sorties); a level is cleared at the rescue goal with a tally and a (goal - killed) × 100 bonus, 100,000 when nobody died.
createRescueRaid
function createRescueRaid(config: RescueRaidConfig): RescueRaid
Create an independent rescue raid. No renderer or kernel clock is required.
defenderPreset
function defenderPreset(o: DefenderPresetOptions = {}): RescueRaidConfig
Defender (Williams, 1981) as data. Values from the released Red Label 6809 source (WVTAB, GEXEC, the lander, schitzo, UFO, tie, probe and swarmer processes, PLAYER, SBOMB, HYPER) converted to pixels and seconds at 60 Hz: a 2048-pixel planet; 10 humanoids; landers in squads of 5 (15, then 20 per wave) every 7.5/6.25/5/4 s or at once when none are left, at most 8 active; bombers 0/3/4/5 and pods 0/1/3/4; baiters after 53/49/41/37 s (sooner with 8 or 3 enemies left; at most 12); ten-second escalation; smart bombs and ships every 10,000; hyperspace death 63/256; scores 150/150/200/250/1000/150, catch 500, set down 500, safe fall 250, 25 when shot down; wave bonus 100×wave per humanoid (500 from wave 5); the planet restored every fifth wave.
flatTerrain
function flatTerrain(width: number, y: number): RaidTerrain
A flat ground at y.
generateTerrain
function generateTerrain(o: TerrainOptions): RaidTerrain
A seeded mountain line like Defender's: runs of rising and falling slopes between min and max.
A wrapping profile is corrected so its two ends meet.
Classes
RescueRaid
class RescueRaid
Owns one rescue raid: the craft and its weapons, targets and their abduction, falling, catching, boarding and delivery, sources, enemy AI, waves or levels, scoring, lives and outcomes. Deterministic for a definition, a seed and an input sequence; no renderer or kernel clock needed.
readonly config: RescueRaidConfig— The validated definition (a private copy).constructor(config: RescueRaidConfig)get state(): RaidState— A read-only copy of the whole state.kind(id: string): RaidEnemyKind— An enemy kind by id.waveDef(n = this.s.wave): RaidWave— The wave or level definition in force for waven(the last entry repeats).groundAt(x: number): number— Ground y under x.delta(a: number, b: number): number— Shortest signed distance from a to b along x (wrap-aware).viewOffset(x: number): number— x relative to the visible window's left edge (wrap-aware), for drawing.onScreen(x: number, margin = 0): boolean— Inside the visible window (plus a margin).inTerritory(x: number): boolean— Is x inside the enemy territory?zoneAt(x: number)— The delivery zone containing x, if any.remaining(): number— Counting enemies alive plus those still held in squad reserves.scanner(samples = 64): RaidScanner— Whole-world scanner data (Defender's scanner, a minimap). Wrapping worlds centre it on the view.tick(seconds: number, input: RaidInput = {}): RaidState— Advance by real seconds (whole fixed frames inside); returns the live state (do not mutate it).step(input: RaidInput = {}): void— Advance exactly one simulation frame.drain(): RaidEvent[]— Take the events since the last drain.snapshot(): { state: RaidState; carry: number }— Serializable snapshot of the whole game.restore(snap: { state: RaidState; carry: number }): void— Restore a snapshot taken from an owner built from the same definition.reset(wave = 1): void— Start a new game with the same definition, optionally at a later (1-based) wave or level.
Types
ChoplifterPresetOptions
interface ChoplifterPresetOptions
Options for choplifterPreset.
barracks?: number— Barracks (4 = classic) and hostages in each (16).hostagesPer?: number— Hostages in each barracks (16 = classic).capacity?: number— Passengers the helicopter can carry (16 = classic).sorties?: number— Helicopters (sorties): 3.rescueGoal?: number— Rescues needed to clear a level (40 here, the Sega version's goal; 0 = every hostage resolved).worldWidth?: number— World length (2560) and visible width (256).viewWidth?: number— Visible width in world units (256 = classic).tanks?: boolean— Enemy kinds in play.jets?: boolean— Whether jets appear, after the first trip home (default true).mines?: boolean— Whether homing air mines appear, after the second trip home (default true).speed?: number— Multiplies every enemy speed (difficulty) and every fire gap (lower fires more).fire?: number— Multiplies every enemy fire gap (lower fires more); default 1.deliverScore?: number— Points per hostage delivered.seed?: number— Seed.
DefenderPresetOptions
interface DefenderPresetOptions
Options for defenderPreset: the arcade values unless overridden.
worldWidth?: number— Planet circumference in pixels (2048 = arcade).viewWidth?: number— Visible width (the arcade raster is 304; the preset uses 320).humanoids?: number— Humanoids on the planet (10 = arcade).landers?: number[]— Landers per wave for waves 1..4 ([15, 20, 20, 20] = arcade).squadSize?: number— Landers per squad (5) and squads' interval per wave in seconds ([7.5, 6.25, 5, 4]).squadIntervals?: number[]— Seconds between squads for waves 1..4 ([7.5, 6.25, 5, 4] = arcade).bombers?: number[]— Bombers and pods for waves 1..4 ([0, 3, 4, 5] and [0, 1, 3, 4]).pods?: number[]— Pods for waves 1..4 ([0, 1, 3, 4] = arcade).restoreEvery?: number— Restore the planet at the start of every Nth wave (5 = arcade; 0 = never).lives?: number— Ships (3), smart bombs (3) and the award interval (10,000 = a ship and a bomb).smartBombs?: number— Starting smart bombs (3 = arcade).awardEvery?: number— Score between awards of a ship and a smart bomb (10,000 = arcade).hyperspaceRisk?: number— Chance of dying in hyperspace (63/256 = arcade).baiterTimes?: number[]— Seconds before the first baiter per wave ([53, 49, 41, 37] = arcade).speed?: number— Multiplies every enemy speed (difficulty).fire?: number— Multiplies every enemy fire gap (lower fires more).carry?: number— Most humanoids the ship may carry at once.seed?: number— Seed for the terrain, placements and AI.
Facing
type Facing = -1 | 0 | 1
Which way the craft faces: -1 left, +1 right, 0 toward the viewer (three-facing craft only).
RaidAwards
interface RaidAwards
Score-threshold rewards.
every: number— Points between awards (0 = none).lives: number— Lives per award.smartBombs: number— Smart bombs per award.
RaidBehaviour
type RaidBehaviour = /** Hovers above the ground, finds a target, descends, grabs it and climbs; at `liftTo` the target is lost and it becomes `becomes`. */ | { type: "abductor"; speed: number; climb: number; hover: number; align: number; grabSpeed: number; grabOffset: number; liftTo: number; becomes: string } /** Closes in on the craft horizontally, keeping off its line until close, with a jittery hop. */ | { type: "hunter"; speedX: number; speedY: number; close: number; avoid: number; hop: number } /** Matches the craft's velocity plus a closing speed, re-aiming now and then. */ | { type: "baiter"; speed: number; speedY: number; retarget: number } /** Cruises across, hovering a set distance off the craft's height, laying mines. */ | { type: "bomber"; speed: number; cruiseMin: number; cruiseMax: number; keepAway: number; mineRate: number; mineLife: number; maxMines: number; mineSize: number } /** Drifts; when killed it releases `min`..`max` of `releases` (at most `cap` of them alive). */ | { type: "pod"; speed: number; releases: string; min: number; max: number; cap: number } /** Rushes the craft horizontally with vertical acceleration toward it; overshoots before turning. */ | { type: "swarmer"; speed: number; accel: number; maxSpeedY: number; pass: number } /** Rolls along the ground toward the craft inside the territory, stopping `standoff`..`standoff + spread` short of it (each tank its own distance). */ | { type: "tank"; speed: number; engage: number; standoff: number; spread: number } /** Streaks across at the craft's height and leaves once well past the window; bombs a landed craft. */ | { type: "jet"; speed: number; track: number; bombLanded: boolean } /** Homes on the craft. */ | { type: "mine"; speed: number; accel: number }
Enemy behaviours. Each is an AI policy the pack runs; parameters are per kind.
RaidBlip
interface RaidBlip
One scanner blip, in 0..1 scanner coordinates.
id: string— Stable key for drawing: the enemy, target or shot id, the source/zone id, or "craft".u: number— Horizontal position across the scanner, 0 to 1.v: number— Vertical position, 0 (top of the playfield) to 1 (bottom).role: "craft" | "enemy" | "target" | "source" | "zone" | "mine"—craft,enemy,target,source,zoneormine.kind: string— Enemy kind, target mode, or source/zone id.
RaidBoarding
interface RaidBoarding
Board-the-craft rules for a landing transport.
radius: number— Targets within this distance of a landed (or low-hovering) craft run to it.runSpeed: number— Their running speed.interval: number— Seconds between boardings.followHeight: number— A hovering craft this low (above the ground) also draws targets underneath it.
RaidCraft
interface RaidCraft
The player's craft.
width: number— Hit box.height: number— Hit-box height in world units.startX: number— Start position and facing (each wave or level, and after a death whenrespawnisstart).startY: number— Start y in world units (y grows downwards).startFacing: Facing— Facing at the start.facings: 2 | 3— 2: left/right only (reverse). 3: left, front and right; turning passes through front.thrustMode: "facing" | "stick"—facing: thrust pushes the way the craft faces (Defender).stick: the stick pushes either way (a helicopter).accel: number— Horizontal acceleration, exponential drag per second and speed cap.drag: number— Horizontal drag per second, exponential: each second the speed is multiplied by e to the power of minusdrag. 0 for none.maxSpeed: number— Fastest horizontal speed, in units per second.vertical: RaidVertical— Vertical handling.turnTime: number— Seconds per facing step when turning (0 = instant).autoFace: number— Seconds of stick held against a side facing before the craft turns by itself (0 = never).landing: { crashSpeed: number; crushTargets: boolean; fireWhenLanded: boolean } | null— Landing rules, or null for a craft that never touches the ground.capacity: number— Targets carried at once (caught or aboard).carryOffset: number— Caught targets hang this far below the craft's centre.weapons: { side: RaidWeapon | null; forward: RaidWeapon | null }— Weapons by facing:sidewhen facing left/right,forwardwhen facing front.lives: number— Starting lives (sorties).awards: RaidAwards— Extra lives and smart bombs by score.smartBombs: number— Starting smart bombs (screen-clearing) and the most that can be held.maxSmartBombs: number— Most smart bombs that can be held at once; awards stop at this.hyperspace: { time: number; deathChance: number } | null— Hyperspace: seconds out of the world and the chance of not surviving re-entry; null = none.deathTime: number— Seconds of the death explosion, then the gap before the next craft.respawnTime: number— Seconds between the death explosion ending and the next craft appearing.invulnerable: number— Seconds of protection after appearing.respawn: "start" | "in-place"— Where the next craft appears.bulletScore: number— Points the player scores when an enemy SHOT destroys the craft (Defender awards 25).
RaidCraftState
interface RaidCraftState
The craft's state.
x: number— Centre x in world units.y: number— Centre y in world units (y grows downwards).vx: number— Horizontal speed in units per second.vy: number— Vertical speed in units per second; positive is down.facing: Facing— The way it faces now.turnTo: Facing— Facing being turned toward (equal tofacingwhen not turning).turnTimer: number— Seconds left on the current facing step.alive: boolean— Whether the craft is alive; false from its destruction until the next craft appears.visible: boolean— Whether it is drawn: false in hyperspace and once its explosion has ended.landed: boolean— Whether it is sitting on the ground.hyper: number— Seconds left in hyperspace (0 = not).invulnerable: number— Seconds of protection left after appearing.screenX: number— Position within the view, from its left edge.stick: number— Seconds the stick has pushed against the facing.frontHeld: boolean— The player asked to face front: the stick does not turn the craft away until a side is asked for.cooldown: number— Seconds until the weapon may fire again.boardTimer: number— Seconds until the next target may board or leave.tripCounted: boolean— This landing already counted as a delivery trip.landedFor: number— Seconds landed inside the territory.
RaidEnemyKind
interface RaidEnemyKind
An enemy kind.
id: string— Id, used by waves and events.score: number— Points when destroyed.width: number— Hit box.height: number— Hit-box height in world units.hp: number— Hits to destroy.behaviour: RaidBehaviour— AI policy.shot: RaidShotRules | null— Fire rules, or null.wrapY: boolean— Leaves the top and re-enters at the bottom (and the reverse).counts: boolean— Must be destroyed to finish adestroywave.smartBomb: boolean— Destroyed by a smart bomb while on screen.appear: number— Seconds spent materialising (intangible and still) after spawning.contact?: boolean— Touching the craft destroys both (default true). Choplifter's jets only hurt with their missiles and bombs.
RaidEnemyState
interface RaidEnemyState
One enemy.
id: number— Unique among targets, enemies and shots in the round.kind: string— Id of itsRaidEnemyKind.x: number— Centre x in world units.y: number— Centre y in world units (y grows downwards).vx: number— Horizontal speed in units per second.vy: number— Vertical speed in units per second; positive falls.mode: string— Behaviour sub-state (seek,descend,lift,pass,away...).target: number— Target id (abductors).fire: number— Seconds to the next shot.t: number— Behaviour timer.appear: number— Seconds left materialising.hp: number— Hits left before it is destroyed.dir: number— Heading or per-enemy factor.cruise: number— Cruise height (bombers), random factor (others).
RaidEscalation
interface RaidEscalation
Mid-wave escalation (Defender's ten-second difficulty steps).
every: number— Seconds per step.speed: number— Added to the speed factor, up tomaxSpeed.maxSpeed: number— Highest value the speed factor reaches.fire: number— Removed from the fire factor (gaps shrink), down tominFire.minFire: number— Lowest value the fire factor reaches; lower fires more.
RaidEvent
type RaidEvent = | { kind: "wave-start"; wave: number; restored: boolean } | { kind: "wave-complete"; wave: number; bonus: number; survivors: number; tally: RaidTally } | { kind: "fire"; weapon: "beam" | "projectile"; x: number; y: number; dir: number } | { kind: "enemy-fire"; enemy: string; x: number; y: number } | { kind: "enemy-spawn"; id: number; enemy: string; x: number; y: number } | { kind: "enemy-killed"; id: number; enemy: string; x: number; y: number; score: number; cause: "shot" | "smart-bomb" | "collision" } | { kind: "enemy-converted"; id: number; from: string; to: string; x: number; y: number } | { kind: "pod-burst"; x: number; y: number; released: number } | { kind: "mine-laid"; x: number; y: number } | { kind: "target-captured"; id: number; by: number; x: number; y: number } | { kind: "target-dropped"; id: number; x: number; y: number } | { kind: "target-caught"; id: number; x: number; y: number; score: number } | { kind: "target-set-down"; id: number; x: number; y: number; score: number } | { kind: "target-landed"; id: number; x: number; y: number; score: number } | { kind: "target-killed"; id: number; x: number; y: number; cause: "shot" | "enemy-shot" | "fall" | "crushed" | "abducted" | "craft-lost" } | { kind: "target-boarded"; id: number; aboard: number } | { kind: "target-full"; aboard: number } | { kind: "target-rescued"; id: number; score: number; rescued: number } | { kind: "source-opened"; id: string; x: number; score: number } | { kind: "source-hit"; id: string; x: number; hp: number } | { kind: "world-destroyed" } | { kind: "landed"; x: number; zone: string } | { kind: "takeoff"; x: number } | { kind: "trip"; trips: number } | { kind: "shot-impact"; x: number; y: number; on: "ground" | "source" } | { kind: "smart-bomb"; killed: number } | { kind: "hyperspace"; x: number; y: number } | { kind: "hyperspace-exit"; x: number; y: number; survived: boolean } | { kind: "craft-destroyed"; x: number; y: number; cause: "enemy" | "shot" | "mine" | "hyperspace" | "crash" } | { kind: "craft-respawn"; x: number; y: number } | { kind: "extra-life"; lives: number; smartBombs: number } | { kind: "level-failed"; tally: RaidTally } | { kind: "game-over"; reason: "lives" | "failed" }
Ordered notifications for presentation and sound: drain() them each frame.
RaidGroup
interface RaidGroup
Enemies placed when the wave starts.
kind: string— Id of the enemy kind placed.count: number— Number of enemies placed in all, in groups ofgroup.group: number— Members per group (spaced along x).at: "far" | "random"—far: across the world from the craft;random: anywhere.
RaidInput
interface RaidInput
Player input for one frame. Booleans are HELD states; the pack finds the presses.
x?: number— Stick: -1..1 horizontally (left/right), -1..1 vertically (up/down).y?: number— Vertical stick, -1 (up) to 1 (down); values outside are clamped.thrust?: boolean— Thrust held (facingthrust mode).face?: Facing— Ask to face this way.turn?: -1 | 0 | 1— Turn one facing step (-1 toward left, +1 toward right). Edge-triggered.reverse?: boolean— Reverse (two-facing craft). Edge-triggered.fire?: boolean— Fire held. The weapon'sautoflag decides whether holding repeats.smartBomb?: boolean— Smart bomb pressed; edge-triggered.hyperspace?: boolean— Hyperspace pressed; edge-triggered. Ignored when the craft has no hyperspace or is landed.
RaidRules
interface RaidRules
Round structure and outcomes.
objective: "destroy" | "rescue"—destroy: a wave ends when every counting enemy is gone.rescue: a level ends at the rescue goal.rescueGoal: number— Rescues needed to clear a level (0 = every target resolved). A level that can no longer reach it is failed.levelBonus: { perSaved: number; perfect: number } | null— Rescue level bonus:(goal - killed) * perSaved, orperfectwhen nobody was killed; null for none.waveBreak: number— Seconds of the between-wave tally.ramp: { speed: number; maxSpeed: number; fire: number; minFire: number; spoiler: number }— Factor changes for each wave past the end of the wave table.maxEnemies: number— Resource budgets.maxShots: number— Most shots, beams, bombs and mines alive at once; new ones are not created beyond it.
RaidScanner
interface RaidScanner
Whole-world scanner data.
blips: RaidBlip[]— Every blip to draw: the craft, enemies, targets, sources, zones and mines.u0: number— The visible window, in scanner u (u1 < u0 never happens: wrapping worlds centre the scanner on the view).u1: number— Right edge of the visible window, in scanner u.terrain: { k: number; x: number; u: number; v: number }[]— Ground profile in scanner coordinates (empty once the world is lost). Samples sit at FIXED world positions (x = k * width / samples,k= the sample index), so the line slides smoothly under a scrolling view instead of being re-sampled; on a wrapping world a sample crossing the seam jumps from one end of the scanner to the other (unear 0 ↔ near 1), which a renderer should not interpolate.
RaidShotRules
interface RaidShotRules
How a kind fires.
style: "aimed" | "forward" | "drop"—aimedat the craft;forwardalong the enemy's heading;dropfalls from it.interval: number— Longest gap between shots; each gap is random up to this, scaled by the wave's fire factor.speed: number— Shot speed.spread: number— Random aim error (units at the target).lead: number— Chance of leading the craft by its velocity.life: number— Seconds a shot lives.range: number— Only fires at a craft this close (horizontal distance).reach?: number— Only fires at a craft this close vertically (default: any height). Tanks cannot reach a high helicopter.size: number— Shot hit-box size.
RaidShotState
interface RaidShotState
A shot, beam, bomb or mine.
id: number— Unique among targets, enemies and shots in the round.owner: "craft" | "enemy"— Who fired it: the player's craft or an enemy.style: "beam" | "projectile" | "aimed" | "forward" | "drop" | "mine"—beam,projectile,aimed,forward,dropormine.x: number— Head position (beams: the leading end).y: number— Head y in world units (beams: the leading end).vx: number— Horizontal speed in units per second.vy: number— Vertical speed in units per second; positive falls.gravity: number— Downward acceleration in units per second squared.tail: number— Beams: the trailing end.life: number— Seconds left.range: number— Distance left.width: number— Hit-box width in world units.height: number— Hit-box height in world units.from: string— Firing kind ("craft-side", "craft-forward" or an enemy kind).
RaidSource
interface RaidSource
A container that holds targets until shot open (a barracks).
id: string— Id.x: number— Centre x and size.width: number— Width in world units.height: number— Height in world units.count: number— Targets inside.hp: number— Hits to open.releaseInterval: number— Seconds between targets leaving once open.score: number— Points for opening it.
RaidSourceState
interface RaidSourceState
A source's state.
id: string— Id of itsRaidSource.hp: number— Hits left before it opens.open: boolean— Whether it has been shot open.remaining: number— Targets still inside.timer: number— Seconds until the next target leaves, once open.
RaidSpawner
interface RaidSpawner
A conditional spawner (Choplifter's tanks, jets and mines).
kind: string— Id of the enemy kind spawned.max: number— Most alive at once.interval: number— Seconds between spawns while the condition holds.afterTrips: number— Only after this many completed delivery trips.when: "always" | "territory" | "landed"—always;territory: the craft is over enemy territory;landed: the craft has sat landed in the territory fordelayseconds.delay: number— Seconds the condition must hold first.at: "edge" | "ground-edge" | "above"—edge: just off the visible window at the craft's height;ground-edge: off the window on the ground;above: high over the craft.
RaidSpoiler
interface RaidSpoiler
A timer-driven harasser that punishes a slow wave (Defender's baiters).
kind: string— Id of the enemy kind that harasses.interval: number— Seconds between spoilers.fastBelow: number— With this many counting enemies left the timer halves; withfasterBelowit quarters.fasterBelow: number— With this many counting enemies left the timer quarters.cap: number— Most alive at once.step: number— Seconds removed from the interval at each escalation step, and its floor.min: number— Floor for the interval, in seconds.
RaidSquad
interface RaidSquad
Enemies held in reserve and sent in squads (Defender's landers).
kind: string— Id of the enemy kind sent, fromRescueRaidConfig.enemies.total: number— Enemies of the kind held in reserve for the wave in all.size: number— Enemies sent in each squad.interval: number— Seconds between squads; a squad also comes at once when none of the kind are left.maxActive: number— No squad while this many are active.
RaidState
interface RaidState
Serializable game state; read it through state.
frame: number— Fixed simulation frames run since the game began.wave: number— Wave or level, from 1.waveTime: number— Seconds spent in this wave or level.status: RaidStatus— What the game is doing now: playing, the craft dying, the wave-end tally or game over.statusTime: number— Seconds left in a timed status (dying,wave-complete); 0 while playing.outcome: "" | "lives" | "failed"— Why the game ended.score: number— Points scored.lives: number— Lives left, including the craft in play.smartBombs: number— Smart bombs held.nextAward: number— Score at which the next award comes.craft: RaidCraftState— The craft's state.targets: RaidTargetState[]— Every target in this wave or level, including any already dead or rescued.enemies: RaidEnemyState[]— Every enemy alive.shots: RaidShotState[]— Every shot, beam, bomb and mine alive.sources: RaidSourceState[]— The state of each source, in the order ofconfig.sources.reserves: number[]— Squad reserves and timers, parallel to the wave's squads.squadTimers: number[]— Seconds until each squad next sends a group, parallel to the wave's squads.spoilerTimer: number— Seconds until the next spoiler appears.spoilerInterval: number— The spoiler interval now, in seconds; escalation shortens it.spawnerTimers: number[]— Seconds until each spawner next spawns, parallel to the wave's spawners.speed: number— Current enemy speed and fire-gap factors.fire: number— Current factor on the gaps between enemy shots; lower fires more.escalateTimer: number— Seconds since the last escalation step.worldLost: boolean— All targets lost: the world is gone until a restore wave.viewX: number— Left edge of the visible window.tally: RaidTally— This wave's or level's tally, and the last completed wave's bonus.lastBonus: number— Bonus paid at the end of the last completed wave, in points.targetCursor: number— Abductors pick targets round-robin from here.held: { fire: boolean; smartBomb: boolean; hyperspace: boolean; reverse: boolean; turn: number }— Held inputs on the last frame (press detection).nextId: number— The next id to give a target, enemy or shot.random: number[]— The kernel generator's state (four words fromcreateRng), advanced in place, so a snapshot carries the stream.
RaidStatus
type RaidStatus = "playing" | "dying" | "wave-complete" | "game-over"
Game phases.
RaidTally
interface RaidTally
Per-wave or per-level tally.
rescued: number— Targets rescued this wave or level.killed: number— Targets lost this wave or level.aboard: number— Carried or aboard.remaining: number— In sources or on the ground (not yet aboard).trips: number— Delivery trips completed.
RaidTargetMode
type RaidTargetMode = | "held" // inside a source | "walking" // on the ground | "running" // to a landed craft | "captured" // held by an abductor | "falling" | "carried" // caught, hanging under the craft | "aboard" // inside the craft | "leaving" // walking from the craft to a zone's door | "rescued" | "dead"
Where a target is in its life.
RaidTargets
interface RaidTargets
The people (or things) being rescued.
width: number— Hit box.height: number— Hit-box height in world units.count: number— Targets placed on the terrain at the start (and on restore waves); 0 when they come from sources.walkSpeed: number— Walking speed and chance per second of turning round.turnRate: number— Chance per second, 0 to 1, that a walking target turns round.gravity: number— Falling: gravity, terminal speed and the fastest landing a target survives.maxFall: number— Terminal fall speed, in units per second.safeSpeed: number— Fastest landing speed a falling target survives, in units per second; faster kills it.catch: boolean— True: the craft catches falling targets on contact.catchScores: number[]— Points per catch, indexed by how many are already carried (the last repeats).setDownScore: number— Points for setting a caught target down on the ground (delivery: 'ground').safeLandScore: number— Points when a dropped target lands safely by itself.board: RaidBoarding | null— Boarding rules for a landing transport, or null.delivery: "ground" | "zone"—ground: carried targets are safe once lowered onto the terrain.zone: they must be landed in a delivery zone.disembark: { interval: number; walkSpeed: number }— Leaving the craft in a zone: seconds between targets and their walking speed to the door.deliverScore: number— Points per target delivered through a zone's door.friendlyFire: boolean— Craft fire kills targets it hits.enemyFire: boolean— Enemy fire kills targets it hits.wander: number— How far released targets mill around their source.restoreEvery: number— Restore the terrain targets at the start of every Nth wave (0 = never; Defender: 5).worldLoss: boolean— Losing every target destroys the world: abductors become theirbecomeskind until a restore wave.
RaidTargetState
interface RaidTargetState
One target.
id: number— Unique among targets, enemies and shots in the round.x: number— Centre x in world units.y: number— Centre y in world units (y grows downwards).vy: number— Vertical speed in units per second; positive falls.mode: RaidTargetMode— Where the target is in its life.dir: -1 | 1— Walking direction.carrier: number— Abductor holding it (0 = none).source: string— Source it came from ("" for terrain targets) and the x it mills around.home: number— World x it mills around.dropped: boolean— Fell from a shot abductor (a safe landing scores).waving: boolean— Waving at a full craft.
RaidTerrain
interface RaidTerrain
A ground profile: heights[i] is the ground y at x = i * step (linear between samples).
step: number— Distance between samples.heights: number[]— Ground y per sample. A wrapping world wraps the profile; a bounded world holds the last value.
RaidVertical
type RaidVertical = | { mode: "direct"; speed: number; maxSpeed: number; ramp: number } | { mode: "inertial"; accel: number; drag: number; maxSpeed: number }
Vertical handling: direct (Defender: constant speed that ramps while held) or inertial (a helicopter).
RaidView
interface RaidView
The visible window. The pack owns it because smart bombs, firing and spawning depend on it.
width: number— Visible width in world units.anchor: number— Where a right-facing craft sits, as a fraction of the width (a left-facing craft mirrors it; facing front sits at 0.5).lead: number— Seconds of the craft's speed added to its screen position (positive drifts forward, negative looks ahead).slide: number— Fastest the craft's screen position slides toward its anchor, units per second.
RaidWave
interface RaidWave
One wave or level.
squads: RaidSquad[]— Reserve squads: enemies held back and sent in groups.start: RaidGroup[]— Groups of enemies placed when the wave starts.spoiler: RaidSpoiler | null— The harasser that punishes a slow wave, or null.spawners: RaidSpawner[]— Conditional spawners that run during the wave.speed: number— Enemy speed and fire-gap factors for the wave.fire: number— Factor on the gaps between enemy shots: lower fires more.escalate: RaidEscalation | null— Escalation as the wave goes on, or null for none.bonusPerTarget: number— End-of-wave points per surviving target (destroyobjective).
RaidWeapon
interface RaidWeapon
One craft weapon.
kind: "beam" | "projectile"—beam: an instant-hit line that grows from the nose (Defender's laser);projectile: a moving shot or bomb.speed: number— Beam head speed, or projectile speed along the facing, units per second.inherit: number— Fraction of the craft's velocity added to the shot.vy: number— Initial vertical speed (bombs fall with positive values).gravity: number— Downward acceleration (0 for straight shots).range: number— Distance the shot may travel before it expires.maxActive: number— Shots of this weapon in flight at once.cooldown: number— Seconds between shots.auto: boolean— True: fires while held. False: one shot per press.width: number— Hit-box width (projectiles) and height (beam thickness).height: number— Hit-box height, or beam thickness, in world units.offsetY: number— Vertical offset from the craft's centre where shots start.tilt?: number— Downward speed added per unit of the craft's horizontal speed: a helicopter fires along its tilt (default 0).
RaidWorld
interface RaidWorld
The world strip.
width: number— Circumference (wrapping) or length (bounded).top: number— Highest y anything flies at (the top of the playfield).bottom: number— Lowest y the craft may reach when it cannot land (the bottom of the playfield).wrap: boolean— True: x wraps (a planet). False: x is clamped to[0, width].terrain: RaidTerrain— The ground line targets walk on and landing craft touch down on.
RaidZone
interface RaidZone
A delivery zone: land between x0 and x1; passengers walk to door.
id: string— Id.x0: number— Left edge of the zone, as world x.x1: number— Right edge of the zone, as world x.door: number— World x that passengers walk to after leaving the craft, to be counted as delivered.
RescueRaidConfig
interface RescueRaidConfig
A complete rescue raid. The arcade games are presets: see defenderPreset and choplifterPreset.
hz: number— Simulation frames per second.seed: number— Seed for every random choice.world: RaidWorld— The world strip: its size, whether it wraps, its bounds and its ground.view: RaidView— The visible window and how it follows the craft.craft: RaidCraft— The player's craft.targets: RaidTargets— The targets to protect or recover.sources: RaidSource[]— Containers that hold targets until shot open (barracks); may be empty.zones: RaidZone[]— Delivery zones where carried targets are set down; may be empty.territory: { x0: number; x1: number } | null— Enemy territory: ground enemies stay inside it,territoryspawners need the craft over it. Null: everywhere.enemies: RaidEnemyKind[]— The enemy kinds the waves can use.waves: RaidWave[]— Wave or level table; the last entry repeats withrules.ramp.rules: RaidRules— Round structure, scoring bonuses and resource budgets.
TerrainOptions
interface TerrainOptions
Options for generateTerrain.
width: number— World width the profile covers.step: number— Distance between samples.min: number— Highest (smallest y) and lowest ground.max: number— Lowest ground (largest y).seed: number— Seed.slope?: number— Largest climb per sample (jaggedness).wrap?: boolean— True: the end meets the start (a planet).


