Phaser AE

Cave flyer

Pro packv3.0.0-32DArcade

The session of a cave-flying thrust game: fly a heavy ship down into a planet against gravity, deal with the guns that defend it, do the job and get back out to orbit. What the job is, is a rule you choose or write, so one session plays several classic designs and your own.

This is a Pro pack. Upgrade to Phaser Pro to use it in your games.See Phaser Pro →

Released October 14, 2026 · updated October 20, 2026

Cave flyer: a screenshot of its demo
A note about these graphics

Expansion packs don't come with graphics. This screenshot is one way of drawing what the pack does, made for its demo: none of the sprites, tiles or backgrounds in it are in the pack.

That's by design. A pack is a game's logic, mechanics and effects, and it works with whatever art you give it. Some packs draw effects, backdrops or 3D scenes of their own, but none carries a game's sprites.

So the look is yours. Make the art on phaser.io, bring your own, or let your agent draw it in code: the same pack can look like anything.

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 a cone gun, radians (y down: -PI/2 is up). Default straight up.
  • spread?: number — Half-width of the cone, 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 to range.
  • popUp?: { range: number; shot?: number; time?: number } — Hidden until the ship comes within range or a bullet lands within shot; rises over time seconds.
  • refuel?: { range: number; rate: number } — Refuels a ship landed within range at rate units/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 to count on 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 — Shortest b - a across 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 of x nearest ref.
  • inBox(p: Vec2, c: Vec2, w: number, h: number, pad?: number): boolean — p inside the box of centre c, size w by h, grown by pad.
  • 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, with pad to 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 of x nearest ref on 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' reactorRule and podRule (Thrust), oids-rescue's rescueRule and treesRule (Oids), this pack's clearBasesRule (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 every scaled gun's rate: start for missions before from, then one more per mission up to cap; a destroyed planet adds destroyed to 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). Default keep.
  • 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 with surface.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 in state.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 at at: 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 at at.
  • 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 marked gated hold 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's fromUpright).
  • 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's rng.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 within spread of 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. Default timer.
  • 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. Default tree<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.