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 whensetConditionsstarts 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;conditionsfollowssetConditions.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 fromlegand 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 distancefrom.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'stunnelfeature with its clearance (default 6 m), light (default 0.4) and walls (default solid), standinggapmetres 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 boundsboundsmetres 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 bydtseconds 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): fromtime-uporover, back to racing withsecondson 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, defaultcrash.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 reachesat.seconds: 'start'adds the starting time again.timeUp: "stop" | "coast"— At zero:stopthe car at once (Out Run sets the speed to 0) orcoastto 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 onwhensurfaces, markers, scenery): Pole Position'sracepuddles.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 withoutbelowcatches 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 whosebelowis above the impact speed applies.traffic?: CrashClass[]— Traffic whenonHitiscrash. 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:keepwhere it stopped, orcentreat 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. Defaultnormal.seed?: number— The config's seed. Default 1985 for Hang-On, 1987 for Super Hang-On.road?: RoadDocument— Another road file; default road-data'shang-on(orsuper-hang-on).
NightDriverOptions
interface NightDriverOptions
Options for nightDriverPreset.
difficulty?: Difficulty— The difficulty level. Defaultnormal.track?: NightDriverTrack— Which track:novice(the default),proorexpert; 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'snight-driver(entries<track>-1and<track>-reverse).
NightDriverTrack
type NightDriverTrack = "novice" | "pro" | "expert"
Night Driver's three tracks.
OutRunOptions
interface OutRunOptions
Options for outRunPreset.
difficulty?: Difficulty— The difficulty level. Defaultnormal.seed?: number— The config's seed. Default 1986.road?: RoadDocument— Another road file (a user-drawn route map); default road-data'sout-run.
PolePositionOptions
interface PolePositionOptions
Options for polePositionPreset.
difficulty?: Difficulty— The difficulty level. Defaultnormal.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'spole-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: withintimegives 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 everytraffic.spawnEveryseconds.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 kernelRngsnapshot); 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 beforescoring.wrapfolds 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-datatunnelfeatures): 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'sracepuddles).
RaceState
interface RaceState
The race state the presenter reads.
phase: RacePhase— Where the race is:attractbeforestart, thencountdown,racing,crashed,time-up,qualified(the qualifying lap is done),goal(the goal sequence), and at the endover(game over) orcomplete.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"—qualifyorraceon a circuit;routeotherwise.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'skindname, 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 theirweight.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 everyByDifficultysetting 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 readscheckpointmarkers (data.time: seconds added, a number or one per difficulty),goalmarkers (data.ending),lapmarkers (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'spuddle).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 widthw, and the box that collides (hitwide, defaultw; Out Run tests contact at the Ferrari's centre line, so itshitis 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):rampInmetres at the start of stage 1 over which steering grows from nothing;bendCutreduces steering by up tocuton bends of curvaturekappaor tighter above speedabove(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). Defaultw.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: everyeverys on the road, points[floor(speed / step)].distance?: { every: number; points: number; anywhere?: boolean } | null— Points per distance:pointseveryeverymetres (on the road only unlessanywhere).timeBonus?: { unit: number; points: number } | null— End bonus per unit of time left:pointsperunitseconds (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,americaoreurope.
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'skindname, 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 theirweight.max: ByDifficulty<number[]>— Cap on live traffic by stage column (stage number - 1; the last entry repeats), by difficulty.capScale?: number— Multiplier onmax. 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 spawnedspawnAheadmetres 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 withinnearXlaterally moves out of the way.nearX: number— Lateral window fornear(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 minusdrop(m/s), a skid fortimes pushing away atpushm/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 randomeveryseconds (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). Defaultw.weight?: number— Relative frequency. Default 1.speed: [number, number]— Cruising speed range (m/s): each car picks one.


