Phaser AE

Road racer

Pro packv3.0.0-32DArcade

The rules of pseudo-3D road racers seen from behind the car or bike, or from the cockpit: branching road trips, circuits with qualifying, motorbike races and timed night drives. It drives one vehicle along a road file and owns everything that is a rule, from the clock to the crashes to the endings.

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

Released October 14, 2026 · updated October 19, 2026

Road racer: 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

roadRacer

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

Install the road racer API.

Helpers

byDifficulty

function byDifficulty<T>(v: ByDifficulty<T>, d: Difficulty): T

Resolve a per-difficulty value.

createRoadRace

function createRoadRace(config: RoadRaceConfig): RoadRace

Create a road race.

DIFFICULTIES

const DIFFICULTIES: readonly Difficulty[]

The three levels in order.

HANG_ON_KINDS

const HANG_ON_KINDS: Record<string, SceneryKind>

Kinds the race spawns itself (the thrown rider, debris, smoke). Roadside kinds are in the road files.

HANG_ON_RIDERS

const HANG_ON_RIDERS: TrafficKind[]

Rival riders (their colours are art).

hangOnPreset

function hangOnPreset(o: HangOnOptions = {}): RoadRaceConfig

Hang-On as a road-racer configuration.

laneX

function laneX(i: number, hw: number, lanes: number): number

Lane centre (metres) of lane i (fractional allowed) on a road of half-width hw with lanes lanes.

nightDriverPreset

function nightDriverPreset(o: NightDriverOptions = {}): RoadRaceConfig

Night Driver as a road-racer configuration.

OUT_RUN_ENDINGS

const OUT_RUN_ENDINGS: Record<string, { letter: string; name: string }>

The five endings by goal stage.

OUT_RUN_KINDS

const OUT_RUN_KINDS: Record<string, SceneryKind>

Kinds the race spawns itself: smoke and dust off the tyres, the thrown couple, the crash flash.

OUT_RUN_SPEED_SCORE

const OUT_RUN_SPEED_SCORE: number[]

Cannonball OStats::convert_speed_score: points per 30 Hz tick on the road, indexed by speed / 16 km/h.

OUT_RUN_TIME

const OUT_RUN_TIME: Readonly<Record<string, { easy: number; normal: number; hard: number }>>

Cannonball OStats::TIME: seconds by stage id for the Easy and Normal DIP settings (Normal is the factory default).

OUT_RUN_TRAFFIC

const OUT_RUN_TRAFFIC: { readonly easy: readonly [2, 2, 3, 4, 5]; readonly normal: readonly [3, 4, 5, 6, 7]; readonly hard: readonly [4, 5, 6, 7, 8]; }

Cannonball OTraffic::set_max_traffic: live traffic cap by stage column (Easy, Normal, Hard DIP).

OUT_RUN_TRAFFIC_KINDS

const OUT_RUN_TRAFFIC_KINDS: TrafficKind[]

Traffic: cars, a camper van, pickups and trucks (Cannonball's spawn_car draws from twenty traffic sprite types weighted toward the cars), all at Cannonball's speeds (200 +- 32 km/h).

outRunPreset

function outRunPreset(o: OutRunOptions = {}): RoadRaceConfig

Out Run as a road-racer configuration.

pickKind

function pickKind(kinds: readonly TrafficKind[], rng: Rng): TrafficKind

Pick a kind by weight.

POLE_POSITION_GRID

const POLE_POSITION_GRID: { time: number; bonus: number; }[]

Grid slots by qualifying lap time and their bonus.

POLE_POSITION_KINDS

const POLE_POSITION_KINDS: Record<string, SceneryKind>

Kinds the race spawns itself (the explosion, smoke). The billboards, arrows and stands are in the road file.

POLE_POSITION_RIVALS

const POLE_POSITION_RIVALS: TrafficKind[]

The rival cars (their colours are art; speeds in m/s).

polePositionPreset

function polePositionPreset(o: PolePositionOptions = {}): RoadRaceConfig

Pole Position as a road-racer configuration.

RACE_STEP

const RACE_STEP: number

The fixed simulation step (seconds).

RACER_ROADS

const RACER_ROADS: Record<string, RoadDocument>

The road files of this folder, by name.

SUPER_HANG_ON_COURSES

const SUPER_HANG_ON_COURSES: { readonly africa: { readonly stages: 6; readonly radius: [number, number]; readonly look: "africa"; readonly time: 50; readonly extend: 32; }; readonly asia: { readonly stages: 10; readonly radius: [number, number]; readonly look: "asia"; readonly time: 50; readonly extend: 30; }; readonly america: { ...; }; readon... …

Super Hang-On's courses: stage count, bend tightness and look (the road file's generator settings), clock.

superHangOnPreset

function superHangOnPreset(o: SuperHangOnOptions = {}): RoadRaceConfig

Super Hang-On (one course) as a road-racer configuration: the turbo bike, more stages, tighter clocks.

Classes

Course

class Course

A road file being raced.

  • readonly road: RoadData — The loaded road-data file.
  • path: RoadPath — The path being driven; replaced when setConditions starts it again.
  • readonly segmentLength: number — Length of a route segment, metres.
  • readonly drawDistance: number — Segments drawn ahead.
  • readonly options: CourseOptions — A copy of the options the course was made with; conditions follows setConditions.
  • leg!: RouteLeg — The current leg: route options and per-segment data, and the PseudoRoad built from it.
  • pseudo!: PseudoRoad — The PseudoRoad the presenter draws, built from leg and rebuilt with it.
  • constructor(doc: RoadDocument, o: CourseOptions = {})
  • setConditions(conditions: string[], at: number): void — Start the path again with other conditions (Pole Position's race has puddles the qualifying lap does not).
  • column(section: string): number — Stage column (1-based) of a section in the route map.
  • name(section: string): string — Display name of a section.
  • isSection(id: string): boolean — Is a section one of the file's own sections (not a fork connector)?
  • get sections(): string[] — Every section id.
  • get circuit(): boolean — Is the start a closed circuit (a section that leads back to itself)?
  • length(section: string): number — Length of a section.
  • ensureLeg(s: number): void — Rebuild the drawn leg when the car has moved on or a fork was decided.
  • buildLeg(from: number): void — Lay the leg starting at path distance from.
  • tunnelOn(seg: number): CourseTunnel | null — The tunnel over a leg segment (null: open road).
  • tunnelAt(z: number): CourseTunnel | null — The tunnel at path distance z: road-data's tunnel feature with its clearance (default 6 m), light (default 0.4) and walls (default solid), standing gap metres outside the road edges: the cross-section's shoulder, at least 0.5 m.
  • patchesAt(seg: number): { from: number; to: number; surface: string }[] | null — Surface patches drawn on a leg segment (null: none).
  • seg(z: number): number — Leg segment of a path distance.
  • under(z: number): RoadUnder — The road at path distance z.
  • env(z: number, bounds: number, surfaces: { road?: string; off?: string; kerb?: number } = {}): RoadEnv — vehicle-handling's environment at distance z plus hard lateral bounds bounds metres beyond the edges.

RoadRace

class RoadRace

A road race. Create with createRoadRace(config).

  • readonly config: RoadRaceConfig — The configuration the race was built from.
  • readonly course: Course — The road being raced: its path, route legs and the road under the car.
  • readonly field: DepthField — The depth field holding every object on the road: scenery, traffic, rivals, the player and effects.
  • vehicle: Vehicle — The player's vehicle (a vehicle-handling vehicle).
  • state: RaceState — Everything the presenter reads; updated by each step.
  • traffic: TrafficCar[] — The live traffic cars.
  • rivals: RivalCar[] — The rival race cars.
  • readonly spec: VehicleSpec — The vehicle spec in use (difficulty assist applied).
  • constructor(config: RoadRaceConfig)
  • start(): void — Start (from attract): the start signals, then the race.
  • tick(dt: number, input: RaceInput = {}): void — Advance by dt seconds of wall time (fixed steps inside, at most 0.25 s per call).
  • drain(): RaceEvent[] — Events since the last drain.
  • get leg(): Course["leg"] — The route leg the presenter draws now (route options and per-segment data).
  • get speedDisplay(): number — Speed in the vehicle's display units (km/h, mph).
  • scene(): RaceScene — What to draw now (road-view-pseudo3d's RoadScene).
  • resume(seconds: number): boolean — Carry on after the clock ran out (a continue): from time-up or over, back to racing with seconds on the clock, where the car stands. Returns false in any other phase.
  • step(input: RaceInput = {}): void — One fixed step.
  • crashInto(other: DepthObject, what = "other", classes?: CrashClass[]): boolean — Crash into something the race does not own (rules layered on the race: an enemy car, a mine, a shell), by the same rules as a crash into scenery: the crash class by speed (classes, default crash.scenery), the crash sequence, the restart. Only while racing; returns whether a crash began.
  • addScore(points: number): void — Add points (rules layered on the race: a pursuit's hits and bonuses). Night Driver's bonus time and the wrap apply.
  • snapshot(): RaceSnapshot — A plain copy of the whole race.
  • restore(s: RaceSnapshot): void — Restore a snapshot taken from a race with the same config.

Types

ByDifficulty

type ByDifficulty<T> = T | { easy: T; normal: T; arcade: T }

A value, or one value per difficulty.

ClockDef

interface ClockDef

The clock.

  • start: ByDifficulty<number> — Seconds at the start.
  • max?: number — Cap. Default none.
  • countdown: number — Seconds of start signals before the clock runs.
  • lap?: ByDifficulty<number> — Seconds added per completed lap (circuits).
  • scoreBonus?: { at: number; seconds: number | "start" } | null — Night Driver: bonus seconds once the score reaches at. seconds: 'start' adds the starting time again.
  • timeUp: "stop" | "coast" — At zero: stop the car at once (Out Run sets the speed to 0) or coast to a stop.

CourseOptions

interface CourseOptions

Options for a course.

  • segmentLength?: number — route segment length (metres). Default 5.
  • drawDistance?: number — Segments drawn ahead. Default 240.
  • conditions?: string[] — Path conditions (switch on when surfaces, markers, scenery): Pole Position's race puddles.
  • entry?: string — A named entry of the road file (Night Driver's reverse track set).

CrashClass

interface CrashClass

One crash class, chosen by impact speed.

  • below?: number — Applies below this speed (m/s); the last class without below catches the rest.
  • kind: CrashKind — The kind of crash the presenter shows.
  • time: number — Seconds until the vehicle is back on the road.
  • restart: "keep" | "centre" — Where it restarts: where it stopped, or at the road centre.

CrashDef

interface CrashDef

Crash rules by what was hit.

  • scenery: CrashClass[] — Classes for hitting scenery, tried in order: the first whose below is above the impact speed applies.
  • traffic?: CrashClass[] — Traffic when onHit is crash. Default the scenery classes.
  • rival?: CrashClass[] — Rival race cars. Default the traffic classes.
  • minSpeed?: number — Below this speed a touch only stops you dead (no crash). Default 2 m/s.

CrashKind

type CrashKind = "bump" | "spin" | "flip" | "explode" | "fall" | "stop"

The kinds of crash, for the presenter.

CrashState

interface CrashState

A crash in progress.

  • kind: CrashKind — The kind of crash the presenter shows.
  • age: number — Seconds since impact.
  • time: number — Total seconds.
  • side: number — -1 left, 1 right: the side it went off to.
  • speed: number — Impact speed (m/s).
  • with: string — What was hit: scenery, traffic, rival.
  • restart: "keep" | "centre" — Where the vehicle restarts: keep where it stopped, or centre at the road centre.

Difficulty

type Difficulty = "easy" | "normal" | "arcade"

Difficulty levels: arcade is the original tables; normal (the gallery default) and easy are kinder.

HangOnOptions

interface HangOnOptions

Options for the bike presets.

  • difficulty?: Difficulty — The difficulty level. Default normal.
  • seed?: number — The config's seed. Default 1985 for Hang-On, 1987 for Super Hang-On.
  • road?: RoadDocument — Another road file; default road-data's hang-on (or super-hang-on).

NightDriverOptions

interface NightDriverOptions

Options for nightDriverPreset.

  • difficulty?: Difficulty — The difficulty level. Default normal.
  • track?: NightDriverTrack — Which track: novice (the default), pro or expert; harder tracks score faster.
  • reverse?: boolean — Drive the track in reverse. Default false.
  • time?: number — Playing time (s): 50, 75, 100 (factory) or 125. Default by difficulty.
  • seed?: number — The config's seed. Default 1976.
  • road?: RoadDocument — Another road file; default road-data's night-driver (entries <track>-1 and <track>-reverse).

NightDriverTrack

type NightDriverTrack = "novice" | "pro" | "expert"

Night Driver's three tracks.

OutRunOptions

interface OutRunOptions

Options for outRunPreset.

  • difficulty?: Difficulty — The difficulty level. Default normal.
  • seed?: number — The config's seed. Default 1986.
  • road?: RoadDocument — Another road file (a user-drawn route map); default road-data's out-run.

PolePositionOptions

interface PolePositionOptions

Options for polePositionPreset.

  • difficulty?: Difficulty — The difficulty level. Default normal.
  • seed?: number — The config's seed. Default 1982.
  • laps?: number — Race laps: 3 (upright) or 4 (sit-down); any count works.
  • rivals?: number — Rival cars on the grid. Default 7.
  • skipQualifying?: number | null — Skip the qualifying lap (start on the grid in this slot).
  • road?: RoadDocument — Another circuit (a road file whose start section leads back to itself); default road-data's pole-position-fuji.

QualifyDef

interface QualifyDef

The qualifying lap (Pole Position).

  • clock: ByDifficulty<number> — Clock for the qualifying lap (s).
  • limit: ByDifficulty<number> — Lap time limit to qualify (s): the slowest grid time.
  • grid: { time: number; bonus: number }[] — Grid positions by lap time: within time gives that slot (first is pole) and its bonus.

RaceBookkeeping

interface RaceBookkeeping

A race's private bookkeeping, as a snapshot holds it: timers, score accumulators, flags and the random stream. Read it only to store it; restore puts it back.

  • spawnTimer: number — Seconds since the last traffic car came; one comes every traffic.spawnEvery seconds.
  • scoreAcc: number — Seconds of driving towards the next speed award (scoring.speed.every).
  • distAcc: number — Distance driven (m) towards the next distance award (scoring.distance.every).
  • qualifyTime: number | null — The qualifying lap's time in seconds, or null while the car has not qualified.
  • passBonus: number — Points earned by passing rivals, paid with the end-of-race bonus.
  • smokeAcc: number — Seconds towards the next puff of tyre smoke or dust; one comes every 0.08 s while the car skids.
  • crashObjs: string[] — Ids of the depth-field objects a crash scattered, cleared when the car is set back on the road.
  • bonusDone: boolean — The end-of-race bonus has been paid.
  • overSaid: boolean — The game-over event has been sent.
  • goalDone: boolean — The car has reached the course's goal.
  • rng: number[] — The seeded stream's four 32-bit words (a kernel Rng snapshot); drawing advances them in place, so a snapshot carries the stream.
  • heading: number — Heading of the road under the player, integrated along the course, radians.
  • unwrapped: number — The score before scoring.wrap folds it: extends and the top score count from it.
  • pose: number — The player's drawn turn or lean frame (held until the input moves clearly past the next frame).
  • faces?: number — Course z up to which tunnel mouths have been given their solid faces.

RaceEvent

type RaceEvent = | { type: "start" } | { type: "signal"; n: number; of: number } | { type: "go" } | { type: "stage"; id: string; name: string; number: number } | { type: "checkpoint"; id: string; added: number } | { type: "extend"; seconds: number } | { type: "fork"; side: number; to: string } | { type: "overtake"; id: string; points: number } | { type: "passed"; id: string } | { type: "rebound"; id: string } | { type: "crash"; kind: CrashKind; with: string; speed: number; /** What was hit: its field id, kind, position and drawn width (`vw`), and where the car was when they met (`carX` across the road, `carS` along it), partway through the step if it was thrown sideways. */ cause: { id: string; kind: string; x: number; z: number; w: number; vw: number; carX: number; carS: number }; } | { type: "crash-end" } | { type: "hazard"; kind: string } | { type: "lap"; lap: number; time: number; best: number } | { type: "qualified"; grid: number; time: number; bonus: number } | { type: "not-qualified"; time: number | null } | { type: "race-start" } | { type: "time-up" } | { type: "goal"; id: string; letter: string; name: string } | { type: "bonus"; points: number } | { type: "finish"; position: number | null } | { type: "game-over" } | { type: "complete" } | { type: "vehicle"; event: string }

Events for the presenter and sound.

RaceInput

interface RaceInput

What the player does this step.

  • throttle?: number — 0..1.
  • brake?: number — 0..1.
  • steer?: number — -1 (left) .. 1 (right).
  • gear?: number | "up" | "down" — A gear index or a shift.
  • boost?: boolean — Turbo (Super Hang-On).

RacePhase

type RacePhase = "attract" | "countdown" | "racing" | "crashed" | "time-up" | "qualified" | "goal" | "over" | "complete"

Phases of a race.

RaceScene

interface RaceScene

What scene() returns: the data road-view-pseudo3d (or any presenter) draws. Structural, no view import.

  • road: PseudoRoad — The route road to draw: the current leg's PseudoRoad.
  • zBase: number — Course distance of the road's z 0, metres: the start of the current leg.
  • focus: { z: number; x: number } — What the camera follows: the player's vehicle (course z of its centre, lateral x).
  • field: DepthField — Everything standing on the road: scenery, traffic, rivals, the player's vehicle and effects.
  • branches: (segment: number) => readonly number[] | null — Strip offsets of a segment where the road has split, in route world units, or null for one centred road.
  • width: (segment: number) => number — The road's half-width at a segment as a factor of the base road width.
  • lanes: (segment: number) => number — Number of lanes on a segment.
  • surfaces: (segment: number) => readonly { from: number; to: number; surface: string }[] | null — Surface patches on a segment (puddles, oil) for the presenter to paint.
  • tunnel: (segment: number) => { ceiling: number; light: number; gap: number } | null — The tunnel over a segment (road-data tunnel features): clearance, light, the gap to its walls.
  • heading: number — Heading of the road under the camera, integrated, radians: horizon backdrops scroll with it.
  • style: string — The look of the road under the player, a presenter style name: its look key, else its region id, else the stage id.

RaceSnapshot

interface RaceSnapshot

A complete saved race: plain data.

  • state: RaceState — The state the presenter reads.
  • internal: RaceBookkeeping — The race's private bookkeeping: spawn timer, score and distance accumulators, crash objects, the random stream and the like.
  • vehicle: VehicleSnapshot — The player's vehicle.
  • field: DepthFieldSnapshot — The depth field holding the scenery, traffic, rivals and effects.
  • traffic: TrafficCar[] — The traffic cars.
  • rivals: RivalCar[] — The rival race cars.
  • events: RaceEvent[] — Events raised and not yet drained.
  • acc: number — Seconds of time carried towards the next fixed step.
  • path: PathSnapshot — The path along the road: where it has been laid and the forks decided.
  • conditions: string[] — The path conditions in force (Pole Position's race puddles).

RaceState

interface RaceState

The race state the presenter reads.

  • phase: RacePhase — Where the race is: attract before start, then countdown, racing, crashed, time-up, qualified (the qualifying lap is done), goal (the goal sequence), and at the end over (game over) or complete.
  • phaseTime: number — Seconds in this phase.
  • time: number — Seconds left on the clock.
  • score: number — Points so far.
  • topScore: number — Highest score seen by this race object (and any restored into it).
  • stage: string — Current stage id, name, 1-based number in the route (column), and the stages taken.
  • stageName: string — The display name of the current stage.
  • stageNumber: number — The current stage's number in the route: its 1-based column in the route map.
  • route: string[] — The ids of the stages taken so far, in order.
  • distance: number — Course distance of the player (metres).
  • lap: number — Laps completed (circuits) and the race length.
  • laps: number — The race length in laps; 0 on a route that is not a circuit.
  • lapTime: number — Current lap time and the last and best lap.
  • lastLap: number | null — Seconds the last completed lap took; null before the first.
  • bestLap: number | null — Seconds of the fastest lap so far; null before the first.
  • session: "qualify" | "race" | "route" — qualify or race on a circuit; route otherwise.
  • grid: number | null — Grid slot (1 = pole) after qualifying.
  • position: number | null — Race position among rivals (1 = leading).
  • passed: number — Cars passed (Pole Position's bonus counts them).
  • signal: number — Countdown signal index (0..n) while counting down.
  • crash: CrashState | null — The crash in progress, or null.
  • ending: { id: string; letter: string; name: string } | null — Ending reached (goal id) and its letter/name.
  • sinceExtend: number — Seconds since the last time extension (for the EXTEND TIME flash), Infinity if none.
  • extended: number — The last extension in seconds.
  • heading: number — Heading of the road under the camera, integrated (radians): horizon backdrops scroll with it.
  • fork: { progress: number; side: number; decided: number } | null — Fork in progress: 0..1 through the widen, the side it would pick now, decided side.

RivalCar

interface RivalCar

A rival race car.

  • id: string — The id of its field object.
  • kind: string — Its traffic kind's kind name, which is also the sprite kind of its field object.
  • z: number — Course distance, metres.
  • x: number — Lateral position, metres.
  • speed: number — Current speed, m/s.
  • top: number — Its top speed, m/s: it never aims above it.
  • target: number — The lateral position, metres, its racing line is steering to.
  • ahead: boolean — Was ahead of the player last step (pass detection).
  • practice: boolean — Practice car on the qualifying lap.

RivalDef

interface RivalDef

Rival race cars (Pole Position): a grid, a racing line, braking for corners.

  • count: number — Grid cars in the race (the player takes one more slot).
  • kinds: TrafficKind[] — The kinds of car on the grid, chosen by their weight.
  • spacing: number — Metres between grid rows.
  • stagger: number — Lateral stagger of grid columns (metres).
  • accel: number — Acceleration and braking (m/s^2).
  • brake: number — Braking deceleration (m/s^2).
  • grip: number — Lateral grip a rival uses for its corner speed (m/s^2): lower is more cautious.
  • pass: number — Points per car passed (Pole Position: 50, added at the end).
  • practice: number — Slow cars on the qualifying lap.
  • practiceSpeed: [number, number] — Their speed range on the qualifying lap (m/s).

RoadRaceConfig

interface RoadRaceConfig

A whole road race.

  • name: string — Shown in a panel.
  • difficulty: Difficulty — The difficulty level: picks the value of every ByDifficulty setting and sets the assist on the player's vehicle.
  • seed: number — Seed of the race's random stream (traffic spawns and lanes, rivals, crash scatter): the same seed gives the same race.
  • road: RoadDocument — The road: a road-data file (forks, merges, regions with scenery pools, surfaces, markers). The race reads checkpoint markers (data.time: seconds added, a number or one per difficulty), goal markers (data.ending), lap markers (circuits: a section whose successor is itself) and the file's kinds (collision widths).
  • entry?: string — A named entry of the road file to start from (Night Driver's tracks and reverse sets).
  • segmentLength?: number — route segment length (metres). Default 5.
  • drawDistance?: number — Segments drawn ahead. Default 240.
  • announce?: boolean — Announce entering a section (stage banner). Default true.
  • surfaceSpecs?: Record<string, SurfaceSpec> — Extra vehicle-handling surfaces the road file names (Pole Position's puddle).
  • vehicle: VehicleSpec — The player's handling (a vehicle-handling preset). Difficulty assist is applied by the race.
  • assist?: boolean — Apply vehicle-handling's assist for the difficulty. Default true.
  • surfaces?: { road?: string; off?: string; kerb?: number } — Override the road file's carriageway and off-road surfaces (vehicle-handling ids), and a kerb width.
  • bounds?: number — Lateral limit beyond each road edge (metres). Default the vehicle's road.bounds or 12.
  • player: { kind: string; w: number; h: number; d: number; hit?: number } — The player's object in the field: its sprite kind, drawn width w, and the box that collides (hit wide, default w; Out Run tests contact at the Ferrari's centre line, so its hit is narrow).
  • clock: ClockDef — The time limit: start time, extensions and what happens at zero.
  • traffic?: TrafficDef | null — Cars in lanes on the road. Default none.
  • rivals?: RivalDef | null — Rival race cars on a grid (a circuit race). Default none.
  • qualify?: QualifyDef | null — The qualifying lap before a circuit race. Default none: the race starts at once.
  • laps?: number — Race laps (circuits).
  • crash: CrashDef — What happens to the player's vehicle when it hits something, by what was hit.
  • scoring: ScoringDef — How points are scored.
  • kinds: Record<string, SceneryKind> — Kinds the race spawns itself (crash objects, smoke): sizes. Roadside kinds come from the road file.
  • endings?: Record<string, { letter: string; name: string }> — Endings by goal id.
  • goalTime?: number — Seconds of the goal sequence before the end bonus. Default 4.
  • steering?: { rampIn?: number; bendCut?: { above: number; kappa: number; cut: number } } — Steering rules outside the vehicle (Out Run, Cannonball set_ferrari_x): rampIn metres at the start of stage 1 over which steering grows from nothing; bendCut reduces steering by up to cut on bends of curvature kappa or tighter above speed above (m/s), scaled by how far above it the car is.

RoadUnder

interface RoadUnder

The road under the car this step.

  • curvature: number — Curvature of the road, 1/m; positive bends right.
  • grade: number — Slope of the road: rise over run.
  • halfWidth: number — Half the carriageway width, metres.
  • left: number — Outer tarmac edges of the road being driven (every strip before a fork decision).
  • right: number — Lateral position of the right outer tarmac edge, metres.
  • lanes: number — Number of lanes.
  • section: string — Section id (a connector's id inside a fork).
  • sample: RoadSample — The full sample.

SceneryKind

interface SceneryKind

A kind of object the race itself spawns (crash debris, thrown occupants, smoke): its size. Roadside scenery kinds live in the road file (road-data kinds, with their drawn and collision widths).

  • w: number — Drawn width (metres).
  • hit?: number — Collision width (metres). Default w.
  • h: number — Height (metres).
  • d?: number — Depth along the road (metres). Default min(w, h).
  • solid?: boolean — Touching it is a crash. Default true.
  • span?: boolean — Spans the road.
  • y?: number — Height of its base above the road (metres). Default 0.
  • data?: Record<string, number | string | boolean> — Plain values handed to the presenter (art hints).

ScoringDef

interface ScoringDef

Scoring.

  • speed?: { every: number; step: number; points: number[]; onRoadOnly?: boolean } | null — Out Run: every every s on the road, points[floor(speed / step)].
  • distance?: { every: number; points: number; anywhere?: boolean } | null — Points per distance: points every every metres (on the road only unless anywhere).
  • timeBonus?: { unit: number; points: number } | null — End bonus per unit of time left: points per unit seconds (Out Run 100,000 per 0.1 s; Pole Position 200 per s).
  • wrap?: number — The score wraps at this value (Night Driver: 1000).

SuperHangOnCourse

type SuperHangOnCourse = keyof typeof SUPER_HANG_ON_COURSES

A Super Hang-On course id.

SuperHangOnOptions

interface SuperHangOnOptions extends HangOnOptions

Options for superHangOnPreset.

  • course?: SuperHangOnCourse — Which continent to race: africa (the default), asia, america or europe.

TrafficCar

interface TrafficCar

A traffic car (rules state; its body is field object id).

  • id: string — The id of its field object.
  • kind: string — Its traffic kind's kind name, which is also the sprite kind of its field object.
  • z: number — Course z and lateral position in the current leg's frame.
  • x: number — Lateral position, metres, in the current leg's frame.
  • lane: number — Target lane and the lane position it is gliding through.
  • lanePos: number — The lane position it is gliding through (fractional between lanes; 0 is the leftmost lane).
  • speed: number — Current speed, m/s.
  • cruise: number — The speed it picked at spawn and returns to after slowing, m/s.
  • hit: boolean — Already rebounded off the player (one rebound per car).
  • ahead: boolean — Has been ahead of the player (a pass only counts then).
  • weaveIn?: number — Seconds until this car next weaves to another lane (TrafficDef.weave).

TrafficDef

interface TrafficDef

Traffic in lanes (Out Run's cars and trucks, Hang-On's rival riders), from Cannonball's OTraffic.

  • kinds: TrafficKind[] — The kinds of vehicle that spawn, chosen by their weight.
  • max: ByDifficulty<number[]> — Cap on live traffic by stage column (stage number - 1; the last entry repeats), by difficulty.
  • capScale?: number — Multiplier on max. A source table counts cars that live from the horizon to the player for as long as the source's projection keeps them; at true scale a car spawned spawnAhead metres away lives longer, so the same passing rate needs proportionally more cars on the road. Default 1.
  • spawnInSplit?: boolean — Spawn on a road that is splitting too (Out Run spawns throughout the split). Default true.
  • spawnEvery: number — Seconds between spawn attempts.
  • spawnAhead: number — Spawn distance ahead of the player (metres): "on the horizon".
  • despawnAhead: number — A car this far ahead (receding: it is faster than you) is removed.
  • near: number — A car with the player closer behind than this (metres) and within nearX laterally moves out of the way.
  • nearX: number — Lateral window for near (metres).
  • laneSpeed: number — Lateral speed of a lane change (m/s).
  • hemmed: number — Speed a hemmed-in car drops to at least (m/s): it matches the car beside it.
  • recover: number — How fast a car returns to its cruising speed (m/s^2).
  • overtake: number — Points when you pass a car.
  • quietStart?: number — No collisions in the first metres of the course (Out Run: the start grid). Default 0.
  • onHit: "rebound" | "crash" — What hitting one does: Out Run rebounds, Hang-On crashes.
  • rebound?: { drop: number; time: number; push: number } — Rebound: speed becomes the traffic's speed minus drop (m/s), a skid for time s pushing away at push m/s.
  • initial?: [number, number][] — Start traffic already on the road at the start: [z, lane] pairs (Out Run's stage 1 grid cars).
  • weave?: { every: [number, number] } | null — Cars that weave: each car changes to a free neighbouring lane at random, waiting a random every seconds (min, max) between changes (Chase H.Q.). Default none: cars keep their lane unless the player closes on them.

TrafficKind

interface TrafficKind

A kind of traffic vehicle or rival.

  • kind: string — Sprite kind of its field object (the presenter's art key), such as "truck".
  • w: number — Collision box (metres).
  • h: number — Collision box height (metres).
  • d: number — Collision box depth along the road (metres).
  • vw?: number — Drawn width (metres) when the art is drawn wider than the box (Chase H.Q. draws traffic about 1.4 times true scale). Default w.
  • weight?: number — Relative frequency. Default 1.
  • speed: [number, number] — Cruising speed range (m/s): each car picks one.