Phaser AE

Polygon rail

Pro packv3.0.0-33DArcade

The rules of on-rails polygon shooters in which the ship flies itself and the player is its gunner. You author missions, waves, forks and bosses as data; the session runs the gun, the shield, the scoring and the continues, and your 3D presenter draws what it reports.

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

Polygon rail: 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

polygonRail

function polygonRail(): Pack<{ polygonRail: typeof api }>

Install the polygon rail API.

Helpers

bend

function bend(id: string, phase: string, seconds: number, speed: number, dx: number, dy: number, more: Partial<SectionDef> = {}, roll = 0.35): SectionDef

An S-bend: shifts dx right and dy up over the section, ending straight ahead. Banks into it with roll.

buildScenery

function buildScenery(m: MissionDef, rail: Rail, seed: number, map: Map<string, SectionDef>): SceneryItem[]

Place a mission's scenery in world space along its built route (deterministic for a seed).

createPolyRail

function createPolyRail(def: PolyRailDef): PolyRail

Validate and build a session.

expandWave

function expandWave(w: WaveDef, section: string, random: () => number): Array<{ time: number; spec: SpawnSpec }>

Expand a wave into one spawn per member: the time it is due and its spawn spec.

flight

function flight(name: PatternName, p: PatternParams = {}): MotionDef

A rail-route motion for a pattern.

flightKeys

function flightKeys(name: PatternName, p: PatternParams = {}): FlightKey[]

Keys for a named pattern. Every pattern ends past or beside the camera so an enemy that is not shot leaves (it is removed as passed once behind the eye, or by its kind's life).

  • head-on: appears far ahead and flies straight at and past the camera (Starblade's "flying directly towards you").
  • sweep: enters from a side at depth, curves across the view and leaves past the camera on the far side.
  • cross: a straight crossing at constant depth.
  • behind: overtakes from behind the camera and flies away into the distance.
  • behind-turn: overtakes from behind, turns round at depth and comes back head-on ("before turning around and firing").
  • rise / drop: comes up from below / down from above into view, then head-on.
  • hover: closes slowly to the working depth, drifts there, then closes and passes (hovering spike-ball throwers).
  • flyby: a fast diagonal pass close to the camera (the Commander and its escorts).
  • dive: from high and to a side, diving across the view toward the camera.

forks

function forks(port: { tier: "easy" | "hard"; waves: WaveDef[]; id: string; skm?: number }, star: { tier: "easy" | "hard"; waves: WaveDef[]; id: string; skm?: number }, phase: string, seconds: number, speed: number, swing: number, scenery?: SceneryDef[]): SectionDef["branch"]

A branch whose two options swing out to port and starboard and meet again on the same line (swing units out).

formation

function formation(shape: FormationShape, n: number, spread = 140, stagger = 0, random: () => number = () => 0.5): FormationSlot[]

Offsets for n members. spread is the spacing in world units, stagger the seconds between members (a column arrives one after another), random a seeded generator for scatter.

lancerKinds

function lancerKinds(): PolyKind[]

Solar Lancer's enemies.

lancerProjectiles

function lancerProjectiles(): PolyProjectile[]

Solar Lancer's projectiles (damage in shield units of 100).

lancerRingRun

function lancerRingRun(): MissionDef

Mission A: the ring run around the gas giant Calder, through its ice rings, a loop, and the dreadnought.

lancerSolarForge

function lancerSolarForge(): MissionDef

Mission B: a dive into the star Vesta's forge, the corona and the Sun Crown.

placed

function placed(at: number, kind: string, ahead: number, xs: number[], y = 0, o: WaveOpts = {}): WaveDef[]

A wave placed on the route ahead of the rider (turrets, doors, mines): ahead units, at lateral xs.

polyDifficulty

function polyDifficulty(name: "easy" | "normal" | "arcade"): PolyDifficulty

Built-in difficulty presets.

solarLancerPreset

function solarLancerPreset(o: LancerOptions = {}): PolyRailDef

Solar Lancer: the second configuration.

starbladeKinds

function starbladeKinds(): PolyKind[]

Starblade's enemies, named by the walkthrough's types. Point values are the walkthrough's; hit points follow its "a shot" (1) or "enough shots" (several: estimates), and activation times (the first shot) are estimates.

starbladeMission1

function starbladeMission1(): MissionDef

Mission 1: from the mother ship to the mechanized planet Red Eye (507.90 skm).

starbladeMission2

function starbladeMission2(): MissionDef

Mission 2: over Red Eye's surface and down its canyons to the Octopus reactor and its Power Stone (285.75 skm).

starbladeMission3

function starbladeMission3(): MissionDef

Mission 3: the Iceberg, its Control Centre and Power Stone, and the final battle with the Commander.

starbladePreset

function starbladePreset(o: StarbladeOptions = {}): PolyRailDef

Starblade (Namco 1991).

starbladeProjectiles

function starbladeProjectiles(): PolyProjectile[]

Starblade's enemy projectiles. Damage is in shield units at operator setting 1 (64 is a full gauge); estimates.

straight

function straight(id: string, phase: string, seconds: number, speed: number, more: Partial<SectionDef> = {}): SectionDef

A straight section seconds long at speed.

turn

function turn(id: string, phase: string, seconds: number, speed: number, angle: number, more: Partial<SectionDef> = {}, roll = 0.5): SectionDef

A turn: heads angle radians to the right (negative left) over the section, along a circular arc, with a bank.

wave

function wave(at: number, kind: string, n: number, pattern: PatternName, o: WaveOpts = {}): WaveDef

A wave: n of kind at at seconds flying pattern.

Types

AttackStep

interface AttackStep

One step of an attack cycle.

  • projectile?: string | undefined — Projectile kind fired in this step (none: a pause or a charge).
  • count?: number | undefined — Shots in the step (default 1).
  • duration: number — Seconds the step lasts.
  • charge?: boolean | undefined — A charge before a shot that cannot be dodged: reported so a presenter can show it.

Backdrop

interface Backdrop

A far object drawn at infinity (planets, a sun, Red Eye growing).

  • model: string — Model ('planet', 'sun', 'ring-planet', 'red-eye' ...).
  • dir: Vec3 — World direction from the eye.
  • size: number — Angular radius (radians).
  • color: string — Colour.
  • color2?: string | undefined — Second colour.
  • grow?: number | undefined — Grows to size * grow over the mission (default 1).

BossDef

interface BossDef

A boss that stops the route until it is destroyed (Starblade's are unscripted and unlimited).

  • kind: string — Core kind, spawned in route space ahead of the stop as the section starts.
  • ahead?: number | undefined — Distance of the core ahead of the section's end (default 600).
  • x?: number | undefined — Core offsets.
  • y?: number | undefined — Core offset up.
  • station?: { x: number; y: number; depth: number; drift?: number; rate?: number; enter?: Side } | undefined — Rider-space boss instead (a flagship that keeps station): its station and drift.
  • guards?: GuardDef | undefined — Guards that circle the core; the core cannot be hit until they are all gone.
  • attack?: AttackStep[] | undefined — Timed attack cycle (the final Commander's missiles, energy balls and undodgeable beam).
  • armour?: number | undefined — Shots pass through the core until the attack cycle has run this many steps (Starblade's Commander cannot be stopped before its first beam: that beam always hits). Default 0.
  • escorts?: WaveDef[] | undefined — Escorts spawned with the boss.

BranchPolicy

type BranchPolicy = "performance" | "random" | "aim" | "easy" | "hard"

Branch choice policies.

BranchSpec

interface BranchSpec

A branch after a section: options with a screen side and a tier.

  • options: Array<{ side: "port" | "starboard"; tier: "easy" | "hard"; sections: SectionDef[] }> — The options.

FlightKey

interface FlightKey

A keyframe over a target's age, in rider space.

  • t: number — Seconds since spawn.
  • x: number — Right of the camera.
  • y: number — Up.
  • z: number — Ahead (negative is behind the eye).

FormationShape

type FormationShape = "line" | "column" | "v" | "ring" | "pair" | "scatter"

How a wave's members are spread.

FormationSlot

interface FormationSlot

One member's offset in a formation and its spawn delay.

  • x: number — Lateral offset.
  • y: number — Vertical offset.
  • delay: number — Seconds after the wave's time.

GuardDef

interface GuardDef

Guards orbiting a boss core.

  • kind: string — Guard kind.
  • n: number — How many, evenly spaced.
  • radius: number — Orbit radius.
  • speed: number — Angular speed, radians per second (positive is anticlockwise on screen).
  • enrage?: { after: number; speed: number; fire?: number } | undefined — After after seconds the guards turn (data.enraged), speed up to speed and fire every fire seconds (Starblade's crystals turn red).

LancerOptions

interface LancerOptions

Options for Solar Lancer.

  • difficulty?: PolyDifficulty — Difficulty (default Normal with gunsight-side branches).
  • shield?: number — Shield energy (default 100).
  • recharge?: number — Recharge per section (default 12).
  • accuracy?: boolean — Pay the hit-ratio bonus (default true).
  • continues?: number — Continues (default 0: one life).
  • seed?: number — Seed.
  • startMission?: number — Starting mission index.

Look

interface Look

Presentation hints a kind carries for a renderer (no rules read them).

  • model: string — Model name the presenter builds.
  • color?: string | undefined — Main colour (CSS).
  • accent?: string | undefined — Accent colour.
  • scale?: number | undefined — Model scale (default 1: the model is authored at the kind's size).

MissionDef

interface MissionDef

A mission: the route from launch to its objective.

  • id: string — Id.
  • name: string — Name shown on the briefing ('MISSION 1').
  • target: string — Objective shown on the briefing and the readout ('RED EYE').
  • skm: number — Total distance on the readout (skm); 0 shows the enemy proximity readout instead.
  • briefing?: string[] | undefined — Briefing lines.
  • sections: SectionDef[] — Sections in order.
  • backdrops?: Backdrop[] | undefined — Far objects.
  • sky?: string | undefined — Space colour for presenters.
  • refill?: boolean | undefined — Refill the shield at the start (Starblade: every mission). Default true.

PatternName

type PatternName = | "head-on" | "sweep" | "cross" | "behind" | "behind-turn" | "rise" | "drop" | "hover" | "flyby" | "dive"

The named flight patterns.

PatternParams

interface PatternParams

Parameters every pattern understands; each uses the ones that make sense for it.

  • side?: Side | undefined — Entry side (default by pattern).
  • x?: number | undefined — Lateral offset of the path (world units, + right).
  • y?: number | undefined — Vertical offset (+ up).
  • depth?: number | undefined — Working depth ahead of the camera (default 1400).
  • duration?: number | undefined — Seconds the pass takes (default 6).
  • width?: number | undefined — Half-width of the screen at the working depth, for entries from the side (default 0.9 x depth).

PolyDifficulty

interface PolyDifficulty

Easy / Normal / Arcade scaling.

  • name: string — Preset name.
  • shield: number — The operator SHIELD setting (1 lowest damage .. 8): projectile and collision damage are multiplied by it.
  • fire: number — Enemy fire interval divisor (1 = the original).
  • projectile: number — Enemy projectile speed multiplier.
  • rapid: boolean — Rapid fire.
  • branch: BranchPolicy — Branch policy.
  • threshold: number — Kill ratio at or above which performance takes the hard branch.

PolyEvent

type PolyEvent = | { type: "phase"; phase: PolyPhase } | { type: "mission-start"; mission: number; name: string; target: string } | { type: "section"; id: string; phase: string } | { type: "laser"; aim: { u: number; v: number } } | { type: "hit"; kind: string; at: Vec3; invulnerable: boolean } | { type: "explode"; kind: string; at: Vec3; size: number; look?: Look | undefined } | { type: "part"; kind: string; region: string; at: Vec3 } | { type: "score"; points: number; reason: string; at?: Vec3 } | { type: "fired"; kind: string; at: Vec3 } | { type: "shot-down"; kind: string; at: Vec3 } | { type: "shield-hit"; amount: number; shields: number; cause: string } | { type: "crash"; kind: string; at: Vec3 } | { type: "warning"; on: boolean } | { type: "branch"; side: string; tier: string } | { type: "speech"; line: string } | { type: "boss"; kind: string; state: "appear" | "exposed" | "enraged" | "charge" | "destroyed" } | { type: "mission-clear"; mission: number } | { type: "continue"; left: number } | { type: "game-over"; score: number } | { type: "ending"; score: number }

Events for presenters and sound.

PolyGun

interface PolyGun

The gun: one press fires a burst; holding repeats only with rapid.

  • burst: number — Shots per press (Starblade: three in succession).
  • gap: number — Seconds between shots of a burst.
  • pause: number — Seconds after a burst before the next press fires.
  • rapid: boolean — Holding the trigger keeps firing (the rapid-fire devices Japanese operators fitted).
  • delay: number — Seconds from shot to hit test (the beams' travel).
  • damage?: number | undefined — Damage per shot.

PolyInput

interface PolyInput

Input each step.

  • aim?: { u: number; v: number } | undefined — Gunsight as a view-plane aim (u, v).
  • steer?: { x: number; y: number } | undefined — Steering, -1 to 1 on each axis, for sections with a pilot (ignored elsewhere).
  • fire?: boolean | undefined — Trigger held.

PolyKind

interface PolyKind extends TargetKind

An enemy, door or boss kind: a rail-route target kind plus the rules' fields.

  • role?: Role | undefined — Rules role (default 'enemy').
  • perHit?: number | undefined — Points per hit while the kind cannot be destroyed (Starblade's Commander: 100 a hit).
  • tally?: boolean | undefined — Counts toward the branch performance ratio (default true for enemies and mines).
  • look?: Look | undefined — Presentation hints.

PolyPhase

type PolyPhase = "attract" | "briefing" | "play" | "continue" | "clear" | "ending" | "over"

Session phases.

PolyProjectile

interface PolyProjectile extends ProjectileKind

An enemy projectile kind: a rail-route projectile plus presentation hints. damage is in shield units at setting 1.

  • look?: Look | undefined — Presentation hints (model: 'laser', 'missile', 'spike', 'barrel', 'ball', 'shock', 'beam' ...).

PolyRail

interface PolyRail

A running game.

  • readonly def: PolyRailDef — The definition.
  • readonly state: PolyState — State.
  • readonly rail: Rail — The current mission's rail.
  • readonly mission: MissionDef — The current mission.
  • readonly scenery: readonly SceneryItem[] — The current mission's scenery in world space.
  • section(id: string): SectionDef | undefined — Section definitions by leg id for the current mission.
  • kind(id: string): PolyKind — A kind.
  • projectile(id: string): PolyProjectile — A projectile kind.
  • attract(): void — Attract mode.
  • begin(mission?: number): void — Start a game (at startMission, or the given mission).
  • continueGame(): boolean — Use a continue in the continue phase.
  • tick(seconds: number, input?: PolyInput): void — Advance by seconds.
  • step(input?: PolyInput): void — One fixed step.
  • drain(): PolyEvent[] — Take events.
  • setDifficulty(d: PolyDifficulty): void — Set the difficulty (applies from the next mission or game).
  • snapshot(): { state: PolyState; rail: ReturnType<Rail["snapshot"]> } — Snapshot.
  • restore(s: { state: PolyState; rail: ReturnType<Rail["snapshot"]> }): void — Restore a snapshot into a session built from the same definition.

PolyRailDef

interface PolyRailDef

The full game.

  • title?: string | undefined — Title.
  • missions: MissionDef[] — Missions in order.
  • kinds: PolyKind[] — Enemy, door and boss kinds.
  • projectiles: PolyProjectile[] — Enemy projectiles.
  • shield: number — Full shield energy (units).
  • warning?: number | undefined — Shield energy at or below which the warning sounds (default a quarter).
  • gun: PolyGun — Gun.
  • difficulty?: PolyDifficulty | undefined — Difficulty.
  • continues?: number | undefined — Continues (Infinity for the arcade's unlimited credits). Default 3.
  • continueSeconds?: number | undefined — Seconds the continue countdown runs (default 20).
  • tally?: PolyTally | undefined — Tally per mission.
  • timing?: Partial<{ briefing: number; clear: number; ending: number; over: number; ready: number }> | undefined — Seconds of the briefing, clear and ending screens.
  • camera?: CameraDef | undefined — Camera (field of view, gunsight limits).
  • riderRadius?: number | undefined — Rider collision radius (default 20).
  • startMission?: number | undefined — Starting mission index (default 0).
  • seed?: number | undefined — Seed.
  • step?: number | undefined — Fixed step (default 1/60).
  • hiScore?: number | undefined — Initial high score.
  • behaviours?: Record<string, Behaviour> | undefined — Extra behaviours for kinds' motion: { type: 'behaviour' }.
  • recharge?: number | undefined — Shields recharge after each section by this many units (0 in Starblade).
  • fireOffScreen?: boolean | undefined — Let enemies fire from off screen (default false: a due shot waits until its firer is in view).

PolyState

interface PolyState

Plain-data session state.

  • phase: PolyPhase — Phase.
  • phaseTime: number — Seconds in the phase.
  • mission: number — Mission index.
  • score: number — Score.
  • hiScore: number — High score.
  • last: { points: number; age: number } — Last points and seconds since.
  • shields: number — Shield energy (mirrors the rail).
  • shieldMax: number — Full energy.
  • ready: number — Seconds left of the gauge filling at a mission start.
  • section: string — Current section id (leg id).
  • sectionPhase: string — Current section phase.
  • distance: { travelled: number; total: number; proximity: number } — The readout: skm travelled of the mission's total, or the nearest enemy distance on proximity missions.
  • skmDone: number — skm of sections already flown this mission.
  • continues: number — Continues left.
  • countdown: number — Continue countdown seconds.
  • stats: { shots: number; hits: number; kills: number; spawned: number; damage: number } — Whole-game stats.
  • missionStats: { shots: number; hits: number; kills: number; spawned: number } — This mission's stats.
  • window: { spawned: number; kills: number } — The branch window's counters (since the last branch).
  • branches: Array<{ from: string; to: string; side: string; tier: string }> — Branches taken.
  • gun: { left: number; next: number; pause: number; trigger: boolean } — Gun: shots left in the burst, seconds to the next, cooldown, trigger last step.
  • warning: boolean — The warning is sounding.
  • bosses: Record<string, { core: string; guards: string[]; exposed: boolean; attackStep: number; attackTime: number; fired: number; armour: number }> — Bosses alive: section id to core target id and their state.
  • tally: Array<{ text: string; points: number }> — Tally lines shown on the clear screen.
  • steps: number — Fixed steps.
  • 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.

PolyTally

interface PolyTally

Mission-clear tally rules.

  • perShield?: number | undefined — Points per shield unit left.
  • accuracy?: Array<[number, number]> | undefined — Accuracy bonus: the first row whose ratio (hits / shots) the mission reaches pays its points.
  • mission?: number | undefined — Points for the mission.

Role

type Role = "enemy" | "door" | "stalker" | "guard" | "core" | "boss" | "mine"

What part a kind plays in the rules.

SceneryDef

type SceneryDef = | { /** One object. */ type: "object"; /** Model name. */ model: string; /** Fraction of the section where it stands (0 start, 1 end; may be outside). */ at: number; /** Right of the route. */ x: number; /** Up from the route. */ y: number; /** Ahead of `at` along the route's tangent (default 0). */ z?: number | undefined; /** Scale (default 1). */ scale?: number | undefined; /** Turn off the route frame. */ yaw?: number | undefined; /** Pitch. */ pitch?: number | undefined; /** Roll. */ roll?: number | undefined; /** Colour override. */ color?: string | undefined; /** Spin, radians per second about its up axis (presenters animate it). */ spin?: number | undefined; } | { /** A seeded field of objects around the route (asteroids, debris). */ type: "field"; /** Model name (a `-n` variant suffix is added: `rock-0` .. `rock-(variants-1)`). */ model: string; /** Variants (default 1: no suffix). */ variants?: number | undefined; /** Section fractions it spans. */ from: number; /** End fraction. */ to: number; /** How many. */ count: number; /** Radius kept clear around the route (the ship's lane). */ clear: number; /** Outer radius. */ spread: number; /** Size range [min, max] (scale). */ size: [number, number]; /** Colours chosen per item. */ colors?: string[] | undefined; /** Spin range (radians per second). */ spin?: number | undefined; } | { /** Rows of objects at fixed lateral positions every `step` units (ground blocks, canyon walls, tunnel rings). */ type: "grid"; /** Model name (with `variants`, a `-n` suffix). */ model: string; /** Variants (default 1). */ variants?: number | undefined; /** Section fraction where the rows start. */ from: number; /** End fraction. */ to: number; /** Distance between rows. */ step: number; /** Lateral positions of each row's objects. */ x: number[]; /** Height of the rows. */ y: number; /** Random offset in x, y and z (default 0). */ jitter?: number | undefined; /** Size range [min, max]. */ size: [number, number]; /** Colours chosen per item. */ colors?: string[] | undefined; /** Turn off the route frame (radians). */ yaw?: number | undefined; /** Roll (radians). */ roll?: number | undefined; /** Mirror the roll for objects left of the route (walls lean inward on both sides). */ mirrorRoll?: boolean | undefined; }

Scenery: drawn, never collided with (Starblade's ships avoid asteroids and structures by themselves).

SceneryItem

interface SceneryItem

A scenery item placed in world space.

  • id: string — Stable id.
  • model: string — Model name.
  • pos: Vec3 — World position.
  • forward: Vec3 — Forward axis.
  • up: Vec3 — Up axis.
  • scale: number — Scale.
  • color?: string | undefined — Colour override.
  • spin: number — Spin (radians per second).
  • section: string — Section it belongs to.

SectionDef

interface SectionDef

One section of a mission: a leg of the route and what happens on it.

  • id: string — Unique id in the mission.
  • phase?: string | undefined — Phase for presenters ('launch', 'space', 'warp', 'asteroids', 'fleet', 'surface', 'canyon', 'interior', 'boss' ...).
  • length?: number | undefined — Straight run length (when there is no path).
  • path?: PathDef | undefined — A spline path (usually relative).
  • speed?: number | undefined — Route speed (units per second).
  • keys?: LegKey[] | undefined — Keys along the leg: speed, roll, yaw, pitch, look-at.
  • pilot?: PilotDef | undefined — Let the player steer inside this section: rail-route's pilot corridor (offset ranges, rate, bank), driven by PolyInput.steer (or by the gunsight with follow: 'aim'). Default none: the ship flies itself, as in Starblade. Steering moves the rider, so projectiles and solid targets can be dodged; scenery is still never collided with.
  • look?: LookDef | undefined — View turn toward the steer or aim direction inside this section (rail-route's LookDef). Default none.
  • waves?: WaveDef[] | undefined — Timed waves.
  • skm?: number | undefined — Distance shown on the readout for this section (skm).
  • boss?: BossDef | undefined — A boss that holds the route at the section's end until destroyed.
  • pause?: number | undefined — A scripted pause at the end (seconds).
  • branch?: BranchSpec | undefined — A branch after this section.
  • scenery?: SceneryDef[] | undefined — Scenery.

Side

type Side = "left" | "right" | "top" | "bottom" | "ahead" | "behind"

Where a pattern enters from.

StarbladeOptions

interface StarbladeOptions

Options for the Starblade preset.

  • difficulty?: PolyDifficulty — Difficulty (default Normal).
  • missions?: Array<"red-eye" | "octopus" | "iceberg"> — Missions to play (default all three).
  • continues?: number — Continues (default 3; the arcade has unlimited credits).
  • shield?: number — Full shield energy (default 64).
  • seed?: number — Seed.
  • startMission?: number — Starting mission index.

WaveDef

interface WaveDef

A timed wave: n members of a kind, flying a pattern in rider space or placed on the route.

  • at: number — Seconds into the section.
  • kind: string — Kind id.
  • n?: number | undefined — Members (default 1).
  • pattern?: PatternName | undefined — Rider-space flight pattern (default 'head-on'; ignored when place, motion or keys is set).
  • keys?: FlightKey[] | undefined — Authored rider-space keyframes instead of a named pattern (seconds since spawn, x right, y up, z ahead). Each member's copy is offset by the wave's x/y and its formation slot; mirrored members flip x. End behind the eye (z below 0) or give the kind a life, so an enemy that is not shot leaves.
  • motion?: MotionDef | undefined — Any rail-route motion for every member instead (velocity, a behaviour from the definition's behaviours, or static). Members spawn in rider space at the wave's x/y plus their formation slot, depth ahead (default 1400). Takes precedence over keys and pattern; place takes precedence over it.
  • side?: Side | undefined — Entry side for the pattern.
  • x?: number | undefined — Lateral offset of the formation centre.
  • y?: number | undefined — Vertical offset.
  • depth?: number | undefined — Working depth.
  • duration?: number | undefined — Seconds the pass takes.
  • width?: number | undefined — Half-width of the screen used by side entries (default 0.9 x depth): narrow it inside a canyon.
  • shape?: FormationShape | undefined — Formation shape (default 'line').
  • spread?: number | undefined — Spacing between members (default 140).
  • stagger?: number | undefined — Seconds between members (default 0.25).
  • mirror?: boolean | undefined — Alternate members' sides for sweep, flyby, cross, dive and behind (both sides of the screen).
  • place?: { ahead: number; x?: number; y?: number; drift?: number; yaw?: number } | undefined — Placed on the route instead (turrets, doors, mines, parked ships): ahead of the rider, offsets, drift toward the camera.
  • group?: string | undefined — Group (for rules queries).
  • data?: TargetData | undefined — Data copied onto the members.

WaveOpts

type WaveOpts = Omit<WaveDef, "at" | "kind" | "n" | "pattern">

Options for a wave written with wave.