The pack
caveFlyer
function caveFlyer(): Pack<{ caveFlyer: typeof api }>
Install the cave flyer API.
Helpers
clearBasesOf
function clearBasesOf(state: CaveState): ClearBasesState | undefined
clearBasesRule's state in a session.
clearBasesRule
function clearBasesRule(o: ClearBasesOptions = {}): CaveRule
Gravitar's objective: destroy every bunker, then leave through the orbit line for the bonus. Leaving early flies the
planet again. Pair it with cells the beam lifts whole (take: 'collect') and a beam with no pod.
createCaveFlyer
function createCaveFlyer(def: CaveFlyerDef): CaveFlyer
Build a cave-flyer game.
SHIP
const SHIP: "ship"
The ship's id in the thrust-craft world.
Types
BaseDef
interface BaseDef
A placed ground installation.
id: string— Stable id.kind: string— Kind name, a key of the definition's kinds.x: number— Centre x, world units.y: number— Centre y, world units (y down).dir?: number— Centre direction of aconegun, radians (y down: -PI/2 is up). Default straight up.spread?: number— Half-width of thecone, radians. Default 0.4.data?: Record<string, unknown>— Free data for a presenter.
BaseKind
interface BaseKind
A ground installation kind: a limpet gun, a fuel base, a launcher, a gravity station, a home base...
w: number— Box size (centred on the base).h: number— Box height.hp?: number— Pellet hits to destroy it. Default 1. Infinity: indestructible.hardened?: boolean— Only a bomb blast destroys it. Default false.score?: number— Score when destroyed. Default 0.solid?: boolean— Touching it destroys the ship (unless the shield protects from enemies). Default true.fire?: FireDef— Its gun.fires?: FireDef[]— Several guns (a home base fires photons and missiles).gated?: boolean— Fire stops while a rule gates the guns (Thrust's reactor, stunned or counting down). Default false.launch?: { flyer: string; every: number; max: number; range?: number }— Launches flyers.well?: { mass: number; range: number; G?: number }— Gravity (positive mass attracts, negative repels) out torange.popUp?: { range: number; shot?: number; time?: number }— Hidden until the ship comes withinrangeor a bullet lands withinshot; rises overtimeseconds.refuel?: { range: number; rate: number }— Refuels a ship landed withinrangeatrateunits/s.hanging?: boolean— Hangs from a ceiling (a Thrust gun facing down). Presentation hint.look?: string— Look hint for a presenter.
BaseState
interface BaseState
A ground installation's live state.
id: string— Stable id.kind: string— Kind name, a key of the definition's kinds.x: number— Centre x, world units.y: number— Centre y, world units (y down).hp: number— Hit points left (Infinity: unshootable).alive: boolean— Still standing.risen: number— How far a pop-up base has risen, 0..1.triggered: boolean— A pop-up base has been woken.timers: number[]— Seconds to each gun's next shot.launched: number— Flyers launched so far.launchT: number— Seconds to the next launch.
BlastState
interface BlastState
A bomb's fireball.
id: string— Stable id.x: number— Centre x, world units.y: number— Centre y, world units (y down).t: number— Seconds in this state.r: number— Current radius.
BombDef
interface BombDef
Nova bombs (Oids).
count: number— Bombs carried.restock?: boolean— Restocked tocounton docking with the mothership. Default true.radius: number— Blast radius at its largest.time: number— Seconds the fireball lasts.gravity?: number— Bombs fall under the planet's gravity (multiplier). Default 1.manual?: boolean— Holding the bomb key after the drop detonates it on release. Default true.
BombState
interface BombState
A falling nova bomb.
id: string— Stable id.x: number— Centre x, world units.y: number— Centre y, world units (y down).vx: number— Velocity x, units/s.vy: number— Velocity y, units/s.held: number— Seconds the bomb key has been held since the drop.holding: boolean— The bomb key is still held since the drop.
BulletState
interface BulletState
A player bullet.
id: string— Stable id.x: number— Centre x, world units.y: number— Centre y, world units (y down).vx: number— Velocity x, units/s.vy: number— Velocity y, units/s.life: number— Seconds left.
CaveContext
interface CaveContext
What a rule may read and do: the session's state and world, and the moves the session itself makes.
readonly def: CaveFlyerDef— The definition.readonly state: CaveState— The live state.readonly world: ThrustWorld— The current planet's thrust-craft world.readonly dt: number— The fixed step, seconds.readonly ship: CaveShipDef— The ship's definition.planet(): CavePlanetDef— The current planet.craft(): CraftState— The ship's flight state.rng(): Rng— The session's seeded stream (saved with the state).emit(e: CaveEvent): void— Queue an event.addScore(n: number): void— Add points (and any extra lives they earn).awardLife(): void— Award one extra ship.die(cause: string, at?: Vec2): void— Destroy the ship.loseLife(): boolean— Spend a ship; false (and the game over) when there were none.gameOver(): void— End the game.complete(): void— The last planet is done.nextPlanet(): void— On to the next planet (or complete).following(): { index: number; loop: number } | null— The planet and pass after this one, or null when the game would be complete.enterPlanet(index: number, newMission: boolean): void— Begin a planet.respawn(top?: boolean): void— Put the ship back on the planet (top: at its start, ignoring checkpoints).setPhase(phase: CavePhase): void— Set the phase (and restart its clock).say(message: string): void— Show a banner.snapView(): void— Jump the view onto the followed point.fuelOut(): boolean— Fuel is out and the definition ends the game for it.delta(a: Vec2, b: Vec2): Vec2— Shortestb - aacross a wrapping planet's seam.dist(a: Vec2, b: Vec2): number— Distance across the seam.wrapX(x: number): number— Wrap an x onto the planet.near(x: number, ref: number): number— The image ofxnearestref.inBox(p: Vec2, c: Vec2, w: number, h: number, pad?: number): boolean—pinside the box of centrec, sizewbyh, grown bypad.hullHits(x: number, y: number, w: number, h: number): boolean— The ship's hull overlaps this box.groundAt(x: number, y: number): number | null— The ground under (x, y), or null.onScreen(p: Vec2, pad?: number): boolean— On screen, withpadto spare.nid(prefix: string): string— A fresh id with this prefix.protectedBy(what: "bullets" | "ground" | "enemies"): boolean— The shield is up and stops this.destroyBase(b: BaseState, score: boolean): void— Destroy a base (scoring it or not).removeCell(id: string, score: number): void— Remove a fuel cell (scoring it or not).rule<T>(id: string): T | undefined— Another rule's state, or undefined when that rule is not composed.
CaveDifficulty
type CaveDifficulty = "easy" | "normal" | "arcade"
Easy / Normal / Arcade. Arcade is the original's tables; each preset documents what the other two change.
CaveEvent
type CaveEvent = { [K in keyof CaveEvents]: { type: K } & CaveEvents[K] }[keyof CaveEvents]
What happened this step (for sounds and effects): one of CaveEvents, with its type.
CaveEvents
interface CaveEvents
The events a session emits, by type. Rule packs add theirs by augmenting this interface (declare module "@phaser-ae/cave-flyer" { interface CaveEvents { ... } }), so CaveEvent covers every rule composed.
planet: { planet: number; name: string; loop: number; mission: number }— A planet began.loop: { loop: number; message: string }— A new modifier pass began, with its first-time message.fire: { x: number; y: number }— The ship fired."enemy-fire": { x: number; y: number; kind: string }— An installation or flyer fired.destroyed: { what: "base" | "flyer" | "shot" | "cell" | (string & {}); kind: string; id: string; x: number; y: number; score: number }— Something was destroyed, for the score shown.spark: { x: number; y: number }— A shot struck something without destroying it.crash: { x: number; y: number; cause: string }— The ship was destroyed.beam: { cell: string }— The beam is on a cell.cell: { id: string; fuel: number; score: number }— A fuel cell was taken.door: { id: string; opening: boolean }— A door started to open or to close.switch: { id: string }— A switch was shot.escape: { outcome: "complete" | "incomplete" | "destroyed"; bonus: number }— The ship left through the orbit line."extra-life": { lives: number }— An extra ship was awarded.respawn: { x: number; y: number }— The ship was put back on the planet.landed: { x: number; y: number }— The ship touched down."took-off": Record<never, never>— The ship lifted off.bomb: { x: number; y: number }— A bomb was dropped.blast: { x: number; y: number }— A bomb went off."shield-hit": { charge: number }— The shield took a hit.recharge: { on: boolean }— The shield recharger started or stopped.refuel: { units: number }— Fuel taken on at a fuel base.teleport: { from: string; to: string }— The ship went through a teleporter.launch: { base: string; flyer: string }— A base launched a flyer.tower: { id: string }— A pop-up tower rose.over: { score: number }— The game is over.complete: { score: number }— The last planet is done.
CaveFlyer
interface CaveFlyer
A running cave-flyer game.
readonly def: CaveFlyerDef— The definition it was built from.readonly state: CaveState— The live state (plain data).readonly world: ThrustWorld— The current planet's thrust-craft world (ship, loads, cells, terrain, doors).planet(): CavePlanetDef— The current planet.ship(): CraftState— The ship's flight state.hull(): Vec2[]— The ship's hull in world space.focus(): Vec2— The point the view follows (the ship, or what a rule says: the middle of the ship and its pod).start(opts?: { planet?: number; loop?: number }): void— Start a game (optionally on another planet or loop).attract(): void— Back to the attract state.step(input?: CaveInput): void— Advance one fixed step.drain(): CaveEvent[]— Take queued events.baseKind(kind: string): BaseKind— A base kind by name.flyerKind(kind: string): FlyerKind— A flyer kind by name.projectileKind(kind: string): ProjectileKind— A projectile kind by name.near(x: number, ref: number): number— The image ofxnearestrefon a wrapping planet (for drawing across the seam).doorOutline(id: string): Vec2[]— The live outline of a door.snapshot(): CaveSnapshot— Capture everything.restore(s: CaveSnapshot): void— Restore a capture.
CaveFlyerDef
interface CaveFlyerDef
Everything a cave-flyer game is built from.
step?: number— Fixed step, seconds. Default 1/60.seed?: number— Seed for the game's random rolls (gun aim, reactor damage, launches).ship: CaveShipDef— The ship.planets: CavePlanetDef[]— Planets in play order.loops?: LoopDef[]— Modifier passes: after the last planet the list restarts with the next loop (Thrust: normal, reverse gravity, invisible, both). Default one plain loop, then the game is complete.endless?: boolean— Repeat the loops forever (Thrust). Default false: after the last loop the game is complete.bases?: Record<string, BaseKind>— Base kinds by name.flyers?: Record<string, FlyerKind>— Flyer kinds.projectiles?: Record<string, ProjectileKind>— Projectile kinds.lives: number— Lives at the start.scoring: CaveScoring— Scores.rules?: CaveRule[]— What each planet asks of the player and everything that goes with it: thrust-rules'reactorRuleandpodRule(Thrust), oids-rescue'srescueRuleandtreesRule(Oids), this pack'sclearBasesRule(Gravitar), or a game's own. With none, leaving through a planet's orbit line completes it. Default none.gunLevel?: { start: number; from: number; cap: number; destroyed: number }— Thrust's gun level per mission, multiplying everyscaledgun's rate:startfor missions beforefrom, then one more per mission up tocap; a destroyed planet addsdestroyedto the next mission only.fuelEndsGame?: boolean— Running out of fuel ends the game when the ship next dies or leaves (Thrust). Default false.respawnFuel?: "keep" | "refill"— Fuel after a lost life: kept (Thrust) or refilled (Oids). Defaultkeep.view: { /** View width, world units. */ w: number; /** View height, world units. */ h: number; /** The dead zone the followed point may roam before the view scrolls, as fractions of the view. */ dead: { x0: number; x1: number; y0: number; y1: number }; /** Scroll speed per unit of overshoot, 1/s. Default 8. */ catchUp?: number; /** Look ahead along the ship's velocity by this many seconds (at most a quarter of the view). Default 0. */ lead?: number; }— The view: size and the dead zone the followed point may roam before it scrolls (fractions of the view).timing: CaveTiming— Timings.difficulty?: CaveDifficulty— Difficulty this was built for (informational).name?: string— Name of the planet set (Oids: the galaxy), for the journey screen.
CaveInput
interface CaveInput
One step's controls.
turn?: number— -1 counter-clockwise .. 1 clockwise.thrust?: boolean— Thrust.fire?: boolean— Fire held.shield?: boolean— Shield (and tractor) held.bomb?: boolean— Bomb key held.recharge?: boolean— Recharge key held (Oids' spacebar).
CavePhase
type CavePhase = "attract" | "intro" | "play" | "dying" | "result" | "over" | "complete" | (string & {})
Session phases: the session's own, and any a rule adds (oids-rescue's docked, departing and warp).
CavePlanetDef
interface CavePlanetDef
One planet (Thrust) or planetoid (Oids).
id: string— Stable id.name: string— Name shown on arrival.width: number— World size.height: number— World height.wrap?: boolean— Wrap left to right. Default true.gravity: number— Gravity, units/s^2 down the screen.terrain: TerrainDef[]— Terrain (thrust-craft chains). Mark landable ground withsurface.landable.start: Vec2— Where the ship enters (its centre).checkpoints?: Vec2[]— Respawn points below the start, top to bottom (Thrust's checkpoints).orbit?: number— Flying above this y leaves the planet (Thrust's orbit). Omit: the top is a wall and leaving is by docking.bases?: BaseDef[]— Ground installations.flyers?: FlyerDef[]— Flyers in the air at the start.cells?: CellDef[]— Fuel cells (Thrust).reactor?: ReactorDef— The reactor (Thrust).pod?: PodDef— The pod on its stand (Thrust).doors?: DoorDef[]— Doors.switches?: SwitchDef[]— Switches that open doors.factories?: FactoryDef[]— Factories of Oids.teleporters?: TeleporterDef[]— Teleporter pairs.mothership?: Vec2— Where the mothership hovers to take the Oids aboard (its probe hangs below). Default above the start.trees?: TreeDef[]— Trees and bushes: shot, they catch fire, burn and leave stumps.data?: Record<string, unknown>— Free data for a presenter (colours, scenery).
CaveRule
interface CaveRule
A rule: the objectives and the objects that go with them. Every hook is optional; the session calls them in the order the rules are listed.
readonly id: string— Unique id: the key of its state instate.rules.readonly reads?: readonly (keyof CavePlanetDef)[]— Fields of a planet this rule reads (pod,factories…): a planet with one of them and no rule reading it fails validation.validate?(def: CaveFlyerDef): void— Throw if the definition cannot be played with this rule.init?(): unknown— The rule's state at the start of a game. Default{}.build?(ctx: CaveContext): void— The world was built for a planet (on entering it, in attract mode, before a restore): add loads or items.enter?(ctx: CaveContext): void— A planet begins: set up its part of the state.intro?(ctx: CaveContext): void— The planet's banner is done and play begins.step?(ctx: CaveContext, input: CaveInput): void— Early in each step of play, after the ship's bullets fly (Thrust's reactor).late?(ctx: CaveContext, input: CaveInput): void— Late in each step of play, after teleporters (Oids' rescue, trees).dying?(ctx: CaveContext): void— Each step while the wreck burns.bullet?(ctx: CaveContext, at: Vec2): boolean— A player bullet atat: true when this rule's object took it.blast?(ctx: CaveContext, blast: { x: number; y: number; r: number }): void— A bomb's fireball this step.collide?(ctx: CaveContext): string | null— The cause, when the hull touches one of this rule's solid objects (checked unless the shield stops enemies).died?(ctx: CaveContext): void— The ship was destroyed.afterDeath?(ctx: CaveContext): boolean— The wreck burnt out: return true when this rule decides what happens next (Thrust: a critical reactor).respawnPoint?(ctx: CaveContext, top: boolean): number | null— Which respawn point to use: an index into the planet's[start, ...checkpoints].respawned?(ctx: CaveContext, at: Vec2, top: boolean): void— The ship was put back atat.orbit?(ctx: CaveContext): OrbitResult | null— The followed point crossed the orbit line: how the planet ends, or null to leave it to the next rule.world?(ctx: CaveContext, e: ThrustEvent): void— A thrust-craft world event.focus?(ctx: CaveContext): Vec2 | null— The point the view follows, or null for the ship.gated?(ctx: CaveContext): boolean— True while bases markedgatedhold fire.tractor?(ctx: CaveContext): boolean— False while the beam may not be used (Thrust: while towing).phases?: Record<string, (ctx: CaveContext, input: CaveInput) => void>— Phases this rule runs, by name, each step while the session is in one.
CaveScoring
interface CaveScoring
Scores.
cellCollected?: number— A fuel cell taken by the beam.cellShot?: number— A fuel cell shot.extraLifeEvery?: number— Extra life every this many points.
CaveShipDef
interface CaveShipDef
The player's craft and everything it carries.
hull: Vec2[]— Local hull outline, nose along +x (use thrust-craft'sfromUpright).feet?: number[]— Hull indices that are landing feet.mass?: number— Mass (the pod is tethered by mass ratio). Default 1.turnRate: number— Turn rate, rad/s.steps?: number— Quantised headings (Thrust and Oids: 32).thrust: number— Main engine acceleration along the nose, units/s^2.drag?: Drag— Linear drag per second, scalar or per axis.maxSpeed?: number— Speed cap.fuel: { start: number; capacity: number; burn: number }— Fuel.landing?: LandingDef— Landing rules. Omit: every touch of the ground is a crash (Thrust).gun: GunDef— Gun.shield: ShieldDef— Shield.tractor?: { /** Item reach below the ship. */ range: number; /** Half-angle of the item cone around straight down. */ halfAngle: number; /** Fuel per second drained from a cell. */ drain: number; /** Pod: arm the beam closer than \near`, tether it by pulling `far` away, on a rod of `length`. Omit for a beam * that only takes cells (Gravitar's). */ pod?: { near: number; far: number; length: number; kind?: "rod" | "rope" }; }` — Tractor beam (Thrust: fuel cells drained from below, the pod pulled up on a rod).bombs?: BombDef— Nova bombs.capacity?: number— Passengers carried (Oids: 8). Default 0.exhaust?: { length: number; halfAngle: number }— The engine flame: kills walkers caught in it (Oids).
CaveSnapshot
interface CaveSnapshot
A session capture.
state: CaveState— The session state.world: ThrustSnapshot— The planet's thrust-craft world.
CaveState
interface CaveState
The whole session state (plain data, snapshotted).
phase: CavePhase— Session phase.t: number— Seconds in this state.planet: number— Index into the planet list.loop: number— Modifier pass index.mission: number— Missions flown (Thrust's mission number, 1-based).score: number— Score.lives: number— Spare ships.livesAwarded: number— Extra ships awarded so far.reverse: boolean— Reverse gravity and invisible landscape for this pass.invisible: boolean— The landscape is invisible this pass.landscapeVisible: boolean— The landscape is visible this step (false on invisible passes unless the shield is held).gunLevel: number— Thrust's gun level this mission, and the punishment carried to the next.gunPenalty: number— Extra gun level carried to the next mission.shieldCharge: number— Shield charge 0..1 (Oids).shieldUp: boolean— The shield is up this step.recharging: boolean— The shield recharger is running.quick: boolean— A recharge started with the shield up (the costly quick charge).rechargeLatch: boolean— The recharge key was held last step.beamCell: string | null— The fuel cell the beam is draining this step (Thrust), for the beam drawing.refuelling: boolean— Refuelling at a fuel base this step (Oids).teleT: number— Seconds before a teleporter works again.bombs: number— Bombs left.checkpoint: number— Checkpoint index the ship last respawned at (0 is the planet's start).bases: BaseState[]— Ground installations.flyers: FlyerState[]— Flyers in the air at the start.shots: ShotState[]— Enemy projectiles.bullets: BulletState[]— The ship's bullets in flight.bombsLive: BombState[]— Falling bombs.blasts: BlastState[]— Bomb fireballs.doors: DoorState[]— Doors.cells: string[]— Fuel cells (Thrust).view: CaveView— The followed view.result: { kind: "complete" | "incomplete" | "destroyed" | (string & {}); bonus: number; planetDestroyed: boolean } | null— The last planet's result, for the banner: how it ended, the bonus paid, and whether the planet blew up.rules: Record<string, unknown>— Each rule's own state, by rule id (plain data, saved with the session). Read it with the rule pack's accessor.shown: string[]— First-time loop messages already shown.fireT: number— Seconds since the last fire / press latches.fireLatch: boolean— Fire was held (one shot per press).bombLatch: boolean— The bomb key was held last step.deathY: number— Where the followed point was when the ship died (for the respawn choice).message: string— Banner text and its age.messageT: number— Seconds since the banner changed.nextId: number— Next id suffix.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.
CaveTiming
interface CaveTiming
Timings, seconds.
intro: number— Planet name banner before play.respawn: number— From a crash to the respawn.result: number— Mission result screen.
CaveView
interface CaveView
The followed view. x is continuous across a wrapping planet's seam (it may leave 0..width).
x: number— Centre x, world units.y: number— Centre y, world units (y down).w: number— Box width.h: number— Box height.vx: number— Velocity x, units/s.vy: number— Velocity y, units/s.
CellDef
interface CellDef
Thrust's fuel cell: drained by the tractor beam, or shot.
id: string— Stable id.x: number— Centre x, world units.y: number— Centre y, world units (y down).fuel: number— Fuel it holds.take?: "drain" | "collect"— How the beam takes it: drained over time (Thrust) or lifted whole (Gravitar). Default 'drain'.w?: number— Box. Default 16 x 20.h?: number— Box height.
ClearBasesOptions
interface ClearBasesOptions
Options for clearBasesRule.
kinds?: string[]— Base kinds that must all be destroyed. Default every kind with hit points (not hardened).bonus?: number— Points for leaving a cleared planet. Default 0.loseLife?: boolean— Leaving before the planet is cleared costs a ship. Default false: fly it again from the top.
ClearBasesState
interface ClearBasesState
clearBasesRule's state.
cleared: boolean— Every base it counts is destroyed.
DoorDef
interface DoorDef
A door: terrain whose outline moves from closed to open while a switch holds it open.
id: string— Stable id.closed: Vec2[]— Closed outline (a closed polygon).open: Vec2[]— Open outline, same vertex count.hold?: number— Seconds a switch holds it open. Default 7.65 (Thrust's 255 ticks).move?: number— Seconds to slide fully open or closed. Default 0.5.
DoorState
interface DoorState
A door's live state.
id: string— Stable id.open: number— Open (factory) or open fraction 0..1 (door).hold: number— Seconds a switch holds it open.timer: number— Seconds left open.shown: number— Openness last written to the terrain.
FactoryDef
interface FactoryDef
Oids' factory: holds Oids until a pellet blasts it open.
id: string— Stable id.x: number— Centre x, world units.y: number— Centre y, world units (y down).oids: number— Oids inside.w?: number— Box. Default 32 x 14.h?: number— Box height.
FireDef
interface FireDef
How a ground installation or a flyer shoots.
aim: "cone" | "aimed"—cone: at random withinspreadof the base's own direction, never aimed (Thrust's limpet guns);aimed: at the ship.rate: number— Mean shots per second.timing?: "chance" | "timer"—chance: each step fires with probability rate x dt (Thrust's per-tick roll);timer: every 1/rate seconds with jitter. Defaulttimer.projectile: string— Projectile kind.range?: number— Fires only while the ship is within this distance. Default unlimited.onScreen?: boolean— Fires only while it is inside the view (Thrust's guns fire only on screen). Default false.lead?: number— Aimed shots lead the ship by this fraction of its velocity x flight time. Default 0.error?: number— Random aim error, radians. Default 0.scaled?: boolean— The rate is multiplied by the mission's gun level (Thrust's probability that rises with each mission). Default false.
FlyerDef
interface FlyerDef
A flyer already in the air at the start of a planet.
id: string— Stable id.kind: string— Kind name, a key of the definition's kinds.x: number— Centre x, world units.y: number— Centre y, world units (y down).
FlyerKind
interface FlyerKind
A flyer kind (Oids' Biocrete ships).
speed: number— Cruise speed cap, units/s.accel: number— Acceleration toward the ship, units/s^2.radius: number— Collision radius.hp?: number— Pellet hits to destroy it. Default 1.hardened?: boolean— Only a bomb destroys it (a shielded mothership). Default false.score?: number— Score. Default 0.fires?: FireDef[]— Its guns.standoff?: number— Keeps at least this far from the ship (stand-off attackers). Default 0.look?: string— Look hint for a presenter.
FlyerState
interface FlyerState
A flyer's live state.
id: string— Stable id.kind: string— Kind name, a key of the definition's kinds.x: number— Centre x, world units.y: number— Centre y, world units (y down).vx: number— Velocity x, units/s.vy: number— Velocity y, units/s.hp: number— Hit points left (Infinity: unshootable).timers: number[]— Seconds to each gun's next shot.
GunDef
interface GunDef
The ship's gun.
speed: number— Bullet speed along the nose, units/s.life: number— Bullet life, seconds.max: number— Most bullets in flight at once (Thrust: 4).auto?: boolean— Hold to fire repeatedly (Oids' machine gun); false: one shot per press (Thrust). Default false.interval?: number— Shortest time between shots, seconds. Default 0.inherit?: number— Fraction of the ship's velocity a bullet inherits. Default 1.muzzle?: number— Distance ahead of the ship's centre where a bullet starts. Default 8.blockedByShield?: boolean— The gun cannot fire while the shield is up (Thrust). Default false.
LoopDef
interface LoopDef
A modifier pass over the planet list (Thrust's later loops).
reverse?: boolean— Gravity pulls up.invisible?: boolean— The landscape is invisible except while the shield is held.message?: string— Banner shown the first time this loop starts.
OrbitResult
interface OrbitResult
How leaving through the orbit line ends a planet.
outcome: "complete" | "incomplete" | "destroyed"— Complete (on to the next planet), incomplete (fly it again from the top) or destroyed (the planet blew up).bonus: number— Points paid.loseLife?: boolean— Leaving like this costs a ship (Thrust, without the pod).planetDestroyed?: boolean— The planet was destroyed on the way out.
PodDef
interface PodDef
Thrust's pod on its pedestal.
x: number— Centre x, world units.y: number— Centre y, world units (y down).radius?: number— Pod radius. Default 5.mass?: number— Mass (relative to the ship). Default 1.stand?: { w: number; h: number }— Pedestal box (indestructible, absorbs bullets, deadly to touch). Default 20 x 8 under the pod.
ProjectileKind
interface ProjectileKind
A projectile kind (enemy fire).
speed: number— Speed, units/s.life: number— Life, seconds.radius?: number— Collision radius. Default 1.5.homing?: number— Turns toward the ship at this rate, rad/s (Oids' hunting spheres and heat-seeking missiles).hp?: number— Pellet hits to destroy it; omit for unshootable.score?: number— Score for shooting it down. Default 0.look?: string— Look hint for a presenter.
ReactorDef
interface ReactorDef
Thrust's reactor: shooting it stuns the guns; enough damage starts the countdown.
x: number— Centre x, world units.y: number— Centre y, world units (y down).w?: number— Box. Default 20 x 20.h?: number— Box height.
ShieldDef
interface ShieldDef
The shield (and, in Thrust, the tractor on the same key).
burn?: number— Fuel per second while held (Thrust). Default 0.charge?: { /** Charge lost per second while up (full charge is 1). */ drain: number; /** Extra charge lost per enemy hit absorbed. */ hit: number; /** Charge regained per second while recharging. */ recharge: number; /** Fuel per unit of charge regained. */ fuel: number; /** Fuel multiplier for a quick charge (recharging with the shield up). */ quick: number; }— A charge that drains while up and is recharged with fuel (Oids). Omit: the shield lasts while there is fuel.blocks: { bullets: boolean; ground: boolean; enemies: boolean }— What it protects against.tractor?: boolean— The shield key also works the tractor beam (Thrust). Default false.bounce?: { restitution: number; friction?: number }— How the ship rebounds off the ground while the shield protects it. Default restitution 0.5, friction 0.3.
ShotState
interface ShotState
A projectile (enemy fire).
id: string— Stable id.kind: string— Kind name, a key of the definition's kinds.x: number— Centre x, world units.y: number— Centre y, world units (y down).vx: number— Velocity x, units/s.vy: number— Velocity y, units/s.life: number— Seconds left.hp: number— Hit points left (Infinity: unshootable).
SwitchDef
interface SwitchDef
A switch: shooting it opens doors for a while.
id: string— Stable id.x: number— Centre x, world units.y: number— Centre y, world units (y down).w?: number— Box. Default 8 x 16.h?: number— Box height.doors?: string[]— Doors it opens. Default every door on the planet.facing?: "left" | "right"— Which wall it faces (presentation).
TeleporterDef
interface TeleporterDef
A teleporter pair: entering one carries the ship (and its velocity) to the other.
id: string— Stable id.x: number— Centre x, world units.y: number— Centre y, world units (y down).to: string— Partner teleporter id.radius?: number— Trigger radius. Default 10.color?: string— Presentation colour.
TreeDef
interface TreeDef
Scenery that burns when shot (Oids' trees and bushes).
id?: string— Stable id. Defaulttree<index>.x: number— Centre x of the trunk.y: number— The ground it stands on (its base).w?: number— Box width. Default 14.h?: number— Box height above the ground. Default 15.


