The pack
roadAssault
function roadAssault(): Pack<{ roadAssault: typeof api }>
Install the road assault API.
Helpers
ASSAULT_ROADS
const ASSAULT_ROADS: Record<string, RoadDocument>
The road files of this folder, by name.
createAssault
function createAssault(config: AssaultConfig): Assault
Create an assault.
mineLine
function mineLine(left: number, right: number, count: number, gap: number): number[]
Lateral positions for a minefield of count mines across [left, right], leaving a clear gap 3.2 m wide at gap (0..1).
NIGHT_STRIKE_CAMERA
const NIGHT_STRIKE_CAMERA: { readonly height: 2.7; readonly back: 5.4; readonly fov: 78; readonly horizon: 96; }
A lower chase camera with a narrower lens for the two-lane night road.
NIGHT_STRIKE_ENEMIES
const NIGHT_STRIKE_ENEMIES: readonly EnemyKind[]
Night Strike's enemies.
nightStrikePreset
function nightStrikePreset(o: NightStrikeOptions = {}): AssaultConfig
Night Strike as an assault configuration.
nightStrikeRace
function nightStrikeRace(o: NightStrikeOptions = {}): RoadRaceConfig
The race underneath Night Strike.
planRally
function planRally(r: RallyDef, o: { from: number; to: number; checkpoint: number; lanes: number; perRow: [number, number]; mines: [number, number]; scale: number; rng: () => number }): PlanItem[]
Lay a rally's furniture along [from, to], avoiding the checkpoint band; sorted by z.
ROAD_BLASTERS_CAMERA
const ROAD_BLASTERS_CAMERA: { readonly height: 3.93; readonly back: 5.79; readonly fov: 90; readonly horizon: 77; }
The arcade camera, measured on 336 x 240 frames (REFERENCES.md): the edge lines vanish on row 77 and the 1.9 m car
is 55 px wide with its tyres on row 191: 3.93 m up, 5.79 m behind, fov 90. For road-view-pseudo3d's camera.
ROAD_BLASTERS_DRIVE
const ROAD_BLASTERS_DRIVE: TargetDrive
Base enemy driving (road-pursuit's TargetDrive): they cruise and weave; nobody sprints away or matches you.
ROAD_BLASTERS_ENEMIES
const ROAD_BLASTERS_ENEMIES: readonly EnemyKind[]
The four enemy vehicles of the attract screen's THE ENEMY roster (points from it and the Genesis manual).
ROAD_BLASTERS_KINDS
const ROAD_BLASTERS_KINDS: Record<string, SceneryKind>
Kinds the race spawns itself: explosions, smoke, sparks, the missile's rings.
ROAD_BLASTERS_REGIONS
const ROAD_BLASTERS_REGIONS: readonly (readonly [string, number, number])[]
The Genesis manual's regions: [name, first rally, last rally].
ROAD_BLASTERS_STARTS
const ROAD_BLASTERS_STARTS: readonly StartDef[]
The start screen: ROOKIE 1, VETERAN 4 +50,000, EXPERT 11 +200,000 (paid at the end of rally 11).
ROAD_BLASTERS_SURFACES
const ROAD_BLASTERS_SURFACES: Record<string, SurfaceSpec>
Surfaces the road file names: the bands painted across the road, toxic spills, lava verges.
roadBlastersPreset
function roadBlastersPreset(o: RoadBlastersOptions = {}): AssaultConfig
RoadBlasters as an assault configuration.
roadBlastersRace
function roadBlastersRace(o: RoadBlastersOptions = {}): RoadRaceConfig
The race underneath RoadBlasters (road-racer configuration).
roadBlastersRally
function roadBlastersRally(n: number): RallyDef
Rally n (1..50): region, speed, fuel, roster and density. Gauge readings in REFERENCES.md; the rest authored.
stepEnemy
function stepEnemy(e: EnemyState, k: EnemyKind, base: TargetDrive, w: EnemyWorld): void
Move one enemy one step by its role.
Functions
reserveAward
function reserveAward(score: number, fuel: Pick<FuelDef, "rally">): number
Reserve fuel the rally point awards for a rally's score: max(0, floor(score / per) - less) x unit (RoadBlasters, fitted to four rally ends on the arcade's gauges), before the reserve tank's cap.
Classes
Assault
class Assault
An assault. Create with createAssault(config).
readonly config: AssaultConfig— The configuration it was created with.race: RoadRace— The road-racer race for the rally being played; replaced at the start of each rally.state: AssaultState— The assault state the presenter reads.enemies: EnemyState[]— The enemy vehicles on the road now.turrets: TurretState[]— The gun turrets beside the road now.constructor(config: AssaultConfig)get rally(): RallyDef— The rally being played.kind(id: string): EnemyKind | undefined— A kind of enemy by id.start(): void— From attract: the start screen (a single start skips it).begin(choice: number): void— Begin from startchoice(index intostarts), from attract or the select screen.tick(dt: number, input: AssaultInput = {}): void— Advance bydtseconds of wall time (fixed steps inside, at most 0.25 s per call). Presses are latched.drain(): AssaultEvent[]— Events since the last drain.get speedDisplay(): number— Speed in the vehicle's display units (mph).scene(): RaceScene— What to draw: the race's scene (road-view-pseudo3d's RoadScene).step(input: AssaultInput = {}): void— One fixed step.spawnEnemy(kind: string, z: number, x: number, o: { speed?: number; mode?: string } = {}): EnemyState— Put an enemy of kindkind(an id inenemies) on the road at course z and lateral x (scripted encounters, tests). It drives atspeed(default its cruise) in role modemode(cruise,passfor an overtaker,sidefor a jeep on the verge).equip(w: WeaponId): void— Take a weapon (as from a pod): it replaces the one held.snapshot(): AssaultSnapshot— A plain copy of the whole assault.restore(s: AssaultSnapshot): void— Restore a snapshot taken from an assault with the same config.
Types
AssaultConfig
interface AssaultConfig
A whole road assault game.
name: string— The game's name.difficulty: Difficulty— Which difficulty (easy, normal or arcade) everyByDifficultyvalue reads.seed: number— Seeds every random choice, a whole number: the same seed and inputs replay identically.race: RoadRaceConfig— The race underneath (road-racer): the road file (one entry per rally), the car (its gear's top is replaced by each rally's), crashes and the distance score. The assault sets the entry and the clock per rally and owns every enemy.rallies: RallyDef[]— The rallies in the order they are played; at least one.starts: StartDef[]— The starts offered on the select screen; at least one, each naming the rally it begins at.enemies: EnemyKind[]— Every kind of enemy vehicle; rallies name them by id.drive: TargetDrive— Base driving for every enemy (each kind overrides).pace: ByDifficulty<number>— Multiplier on enemy speeds, densities and fire rates by difficulty (arcade 1).turret: TurretDef— The gun turrets beside the road.hazards: HazardDefs— The indestructible hazards: mines, boulders and spikers.globes: GlobeDefs— The fuel globes.fuel: FuelDef— The tanks and how fuel flows.multiplier: MultiplierDef— The accuracy multiplier.cannon: CannonDef— The car's laser cannon.weapons: WeaponDefs— The special weapons.jet: JetDef— The support jet and its pod.scoring: AssaultScoring— Scoring beyond the race's distance points.continue: AssaultContinue— The continue after the tanks run dry.destroyed: CrashClass[]— What destroys the car: one crash class (RoadBlasters: it explodes and a new car drops in).statsTime: number— Seconds of the rally stats screen.hints: string[]— Hints shown on the stats screen, in turn.
AssaultContinue
interface AssaultContinue
The continue after the tanks run dry.
countdown: number— Seconds of the count.max: number— Continues per game (-1 unlimited, the factory setting).main: "start" | number— Fuel after a continue: the main tank (start: the rally's starting level) and the reserve.reserve: number— Reserve tank level after a continue, in main tanks (never aboveFuelDef.reserveMax).
AssaultEvent
type AssaultEvent = | { type: "select"; choice: number } | { type: "rally"; rally: number; region: string } | { type: "fire"; weapon: "cannon" | "uz" } | { type: "miss" } | { type: "hit"; id: string; kind: string; destroyed: boolean } | { type: "kill"; id: string; kind: string; points: number; multiplier: number; x: number; z: number } | { type: "immune"; id: string; kind: string } | { type: "globe"; colour: "green" | "red"; fuel: number } | { type: "checkpoint"; fuel: number } | { type: "low-fuel" } | { type: "reserve" } | { type: "jet" } | { type: "drop"; weapon: WeaponId } | { type: "catch"; weapon: WeaponId } | { type: "missed-pod" } | { type: "special"; weapon: WeaponId; left: number } | { type: "shield-end" } | { type: "turret-fire"; id: string } | { type: "spiker"; id: string } | { type: "mines" } | { type: "destroyed"; by: string } | { type: "spin" } | { type: "rally-point"; rally: number; score: number; reserve: number; bonus: number } | { type: "fuel-empty"; countdown: number } | { type: "continued" } | { type: "game-over" } | { type: "complete"; bonus: number } | { type: "race"; event: RaceEvent }
Events for the presenter and sound.
AssaultInput
interface AssaultInput extends RaceInput
What the player does this step.
fire?: boolean— The trigger (held: the cannon repeats; the U.Z. fires while held).special?: boolean— The thumb button: the special weapon (a press).start?: boolean— Start / continue / skip the stats (a press).select?: number— Move the start selection (a press: -1 left, 1 right).
AssaultPhase
type AssaultPhase = "attract" | "select" | "rally" | "stats" | "continue" | "over" | "complete"
Phases of an assault.
AssaultScoring
interface AssaultScoring
Scoring beyond the race's distance points.
finalBonus: number— Paid for finishing the last rally.
AssaultSnapshot
interface AssaultSnapshot
A saved assault: plain data.
state: AssaultState— The assault state the presenter reads.internal: Internal— Internal counters: spawn and fire timers, shots in flight, the rally's furniture plan, the jet and pod, and the random draw count.enemies: EnemyState[]— The enemy vehicles on the road.turrets: TurretState[]— The gun turrets beside the road.race: RaceSnapshot— The snapshot of the road-racer race underneath.events: AssaultEvent[]— Events emitted but not yet drained.acc: number— Seconds of time not yet spent in the fixed-step accumulator (under 0.25).
AssaultState
interface AssaultState
The assault state the presenter reads.
phase: AssaultPhase— The current phase.phaseTime: number— Seconds spent in the current phase.rally: number— Index intoralliesand the rally number shown.number: number— The rally number shown (1-based): the currentRallyDef.number.choice: number— The start chosen on the select screen (index intostarts).started: number— Index of the start the game began from (its bonus is paid at the end of that rally).score: number— The score this game, in points.topScore: number— The highest score reached by this assault, kept across restarts.rallyStart: number— Score at the start of this rally (the stats screen shows the difference).main: number— Tanks.reserve: number— The reserve tank's level, in main tanks (up toFuelDef.reserveMax).startFuel: number— The main tank's level at the start of this rally.multiplier: number— The scoring multiplier now, betweenMultiplierDef.minandmax.special: SpecialState | null— The special weapon held, or null when none.incoming: WeaponId | null— The weapon the jet is bringing (the panel's "CATCH ..."), null when none.shield: number— Seconds left of the shield; seconds since the missile went off (Infinity when none).missile: number— Seconds since the cruise missile went off; Infinity when none has.mines: boolean— Mines ahead (the MINE light).low: boolean— Low fuel light.progress: number— 0..1 through the rally.checkpoint: boolean— Whether the car has passed this rally's checkpoint.countdown: number— Seconds left of the continue count.continues: number— Continues used this game.banner: string— The last banner ("EXTRA FUEL AWARDED") and seconds since it.sinceBanner: number— Seconds since the banner was set; Infinity when none has.stats: { rally: number; score: number; reserve: number; bonus: number; bonusName: string; hint: string } | null— The last rally's tally (the stats screen).kills: number— Kills this rally, shots fired and hits.shots: number— Cannon and U.Z. rounds fired this rally.hits: number— Rounds that hit a target this rally.
CannonDef
interface CannonDef
The car's laser cannon.
every: number— Seconds between rounds while the trigger is held.speed: number— Round speed relative to the car (m/s), range (m) and box (m).range: number— Metres a round flies before it is spent as a miss.size: number— The round's box size, metres.aim?: number— Rounds fly the way the car points: radians per drawn yaw frame (the car'spose, -2..2). RoadBlasters aims by turning the car (TASVideos: the sprite rotates in steps "used for aiming"). 0 = straight down the road.
EnemyKind
interface EnemyKind
A kind of enemy vehicle.
id: string— Id used by rally rosters.kind: string— Sprite kind (the presenter's art key).name: string— Display name ("STINGER").w: number— Collision box (metres);vwthe drawn width when the art is wider than the box.h: number— Collision box height, metres.d: number— Collision box depth along the road, metres.vw?: number— The drawn width in metres when the art is wider than the box. Defaultw.points: number— Points for destroying it (times the multiplier).armour: number— Cannon or U.Z. rounds to destroy it; 0 = immune to gunfire (the Command car: only the missile or the shield).role: EnemyRole— How it behaves on the road.cruise: number— Cruise and top speeds as fractions of the rally's top speed (they rise with it).top: number— Top speed as a fraction of the rally's top speed (an overtaker comes up from behind at it).settle?: number— After overtaking you from behind it settles to this fraction of the rally's top speed and hangs ahead of you. Defaultcruise.drive?: Partial<TargetDrive>— Driving parameters overAssaultConfig.drive(road-pursuit's TargetDrive).from: "ahead" | "behind" | "both"— Where it appears:ahead(on the horizon),behind(overtakes you), or either (both, half each).pack?: [number, number]— How many arrive together (side by side), min..max. Default [1, 1].spikers?: { every: [number, number]; range: number } | null— It throws spikers back at you while it is ahead of you, everyeverys (min, max), withinrangem.fuel?: boolean— It gives up a red fuel globe when destroyed far enough ahead (AssaultConfig.fuel.red). Default true.
EnemyRole
type EnemyRole = "racer" | "blocker" | "jeep" | "weaver"
How an enemy vehicle behaves on top of road-pursuit's target driving (stepTarget: cruise, weave, swerve round
the others, block, sprint):
racer(RoadBlasters' Stinger): arrives ahead or overtakes from behind, then cruises ahead weaving.blocker(the Command car): cruises ahead and moves across in front of you.jeep(the Rat Jeep): rides the verge alongside you, then cuts across in front of you and brakes.weaver(the Cycle): darts from lane to lane.
EnemyState
interface EnemyState
An enemy on the road.
id: string— Unique id, also the id of its object in the race's field.kind: string— Kind id.role: EnemyRole— How it behaves; copied from its kind.z: number— road-pursuit target record (z, x, speed, line, weave ...).x: number— Lateral position across the road, metres; positive is right.speed: number— Forward speed, m/s.line: number— The lateral line (metres, asx) it is moving to.weaveIn: number— Seconds until it picks a new line.shaken: number— Seconds left of a hit's swerve and sprint.vx: number— Lateral shove from the last hit, m/s (decaying).vz: number— Forward shove from the last hit, m/s (decaying).stopping: boolean— Pulling over for an arrest: road-pursuit's flag, always false for an assault's enemies.armour: number— Hits left.mode: string— Role phase: a jeepside->cross->away; an overtaker from behindpass->ahead(where it settles tosettle); one that starts ahead is incruise.modeTime: number— Seconds spent in the currentmode.spikeIn: number— Seconds to its next spiker.
EnemyWorld
interface EnemyWorld
What an enemy sees this step.
dt: number— Seconds this step lasts.playerZ: number— The car's position along the course, metres.playerX: number— The car's lateral position across the road, metres; positive is right.playerSpeed: number— The car's forward speed, m/s.top: number— The rally's top speed (m/s): enemy speeds are fractions of it.road(z: number): { left: number; right: number }— Tarmac edges at z.others: readonly { z: number; x: number; speed: number }[]— The other enemies (they keep clear of each other).rng: () => number— A seeded random source returning numbers from 0 up to but not including 1.
FuelDef
interface FuelDef
The tanks. Amounts are fractions of the main tank.
burn: ByDifficulty<number>— Burned per second while driving (the car burns whether fast or slow: dawdling runs you dry), by difficulty.green: number— Fuel from a green and a red globe.red: number— Fuel from a red globe, in main tanks.reserveMax: number— Capacity of the reserve tank.checkpoint: "restore" | number | null— The checkpoint:restoreputs the main tank back to its level at the start of the rally (the less is left, the more you get: RoadBlasters); a number adds that much; null nothing.rally: { per: number; less: number; unit: number }— The rally point: reserve fuel by the rally's score: max(0, floor(score / per) - less) x unit, up to the cap.crash: number— Fuel lost when the car is destroyed.low: number— Warn (low fuel light) below this much in both tanks.
GlobeDefs
interface GlobeDefs
Fuel globes.
green: { kind: string; size: number; perRow: [number, number]; spacing: number }— Green globes: rows ofperRowalong a lane,spacingm apart.red: { kind: string; size: number; minRange: number }— Red globes: dropped by enemies destroyed at leastminRangem ahead of you.
HazardDefs
interface HazardDefs
Indestructible things on the road (only the cruise missile clears them; the shield runs through some).
mine: { kind: string; size: number; count: [number, number]; depth: number; warn: number }— Mines: fields ofcountlaid across the lanes leaving a gap; the MINE light shows withinwarnm.boulder: { kind: string; w: number; h: number }— Boulders on the road: big, solid, block your shots; the shield does not help.spiker: { kind: string; size: number; speed: number; drift: number; life: number }— Spikers: balls thrown back by enemies, floating, drifting at you,speedm/s slower than the thrower.
JetDef
interface JetDef
The support jet.
kind: string— Sprite kinds of the jet and the pod, and their sizes (metres: width, height).pod: string— Sprite kind of the pod.size: [number, number]— The jet's drawn size, metres: width, height.podSize: [number, number]— The pod's size, metres: width, height.swoop: number— Seconds the jet takes to swoop in, to hang ahead while the pod falls, and to climb away.hold: number— Seconds the jet hangs ahead while the pod falls.away: number— Seconds the jet takes to climb away before it is removed.ahead: number— Where it hangs (m ahead of you, m up), where the pod lands (m ahead), how fast it drifts back to you (m/s).height: number— Height at which the jet hangs and the pod is released, metres up.land: number— Metres ahead of the car where the pod lands.drift: number— Metres a second slower than the car that a landed pod drifts back.catch: number— Lateral reach within which the car catches the pod (m).
MultiplierDef
interface MultiplierDef
The scoring multiplier: accuracy.
start: number— At the start of each rally.min: number— The lowest the multiplier can fall.max: number— The highest the multiplier can rise.hit: number— Change when a cannon shot destroys a target, and when one misses (hits nothing it can destroy).miss: number— Amount taken off when a shot misses (a positive number; 0 never lowers it).uz: boolean— U.Z. Cannon rounds change it too. RoadBlasters: false (Lynx manual: they neither raise nor lower it).resetOnCrash?: boolean— Back tostartwhen the car is destroyed. Default false (no arcade source says it does).
NightStrikeOptions
interface NightStrikeOptions
Options for nightStrikePreset.
difficulty?: Difficulty— Which difficulty (easy, normal or arcade) the game'sByDifficultyvalues read. Defaultnormal.seed?: number— Seeds every random choice, a whole number. Default 2026.road?: RoadDocument— Another road file with the entriesrally-1..rally-8. Default the bundled Night Strike road.rallies?: number— Legs to play (1..8).
PlanItem
type PlanItem = | { type: "turret"; z: number; side: -1 | 1 } | { type: "minefield"; z: number; count: number; gap: number } | { type: "boulder"; z: number; lane: number } | { type: "globes"; z: number; lane: number; count: number }
A piece of a rally's furniture.
RallyDef
interface RallyDef
One rally.
number: number— Rally number shown (1-based).entry: string— A road-data entry of the road file.region: string— Region name shown on the start screen.top: number— Top speed (m/s) of the car this rally.fuel: number— Main tank at the start of the rally (and whatrestoreputs back at the checkpoint).fullTanks?: boolean— Fill both tanks at the start (RoadBlasters refills them for the last rally).enemies: { kind: string; weight: number }[]— Enemy kinds by id with weights.max: ByDifficulty<number>— Enemies on the road at once, and seconds between arrivals, by difficulty.every: ByDifficulty<number>— Seconds between arrivals, by difficulty (the pace scales it).turrets: number— Turrets per kilometre (both sides).minefields: number— Minefields and boulders per kilometre.boulders: number— Boulders per kilometre.globes: number— Rows of green globes per kilometre.spikers?: boolean— Enemies that throw spikers do so in this rally. Default true.drops: number[]— Fractions of the rally at which the support jet drops a pod, and the weapons in the order they come.weapons: WeaponId[]— The special weapons the jet brings, in the order they come: drop n bringsweapons[n % length].lastChance?: boolean— A rally with no continue (RoadBlasters' 50th).
RoadBlastersOptions
interface RoadBlastersOptions
Options for roadBlastersPreset.
difficulty?: Difficulty— Which difficulty (easy, normal or arcade) the game'sByDifficultyvalues read. Defaultnormal.seed?: number— Seeds every random choice, a whole number. Default 1987.road?: RoadDocument— Another road file with the entriesrally-1..rally-50.continues?: number— Continuations per game: -1 unlimited (the factory setting) or a number (the operator's 4).rallies?: number— Rallies to play (a shorter game for the gallery's panel): 1..50. Default 50.
SpecialState
interface SpecialState
The special weapon held.
id: WeaponId— Which weapon is held.left: number— Uses left (shield, nitro, missile) or rounds left (U.Z.).of: number— Of how many (for the panel's bar or icons).
StartDef
interface StartDef
A starting point offered on the select screen (ROOKIE 1, VETERAN 4 +50,000, EXPERT 11 +200,000).
name: string— Name shown on the select screen ('ROOKIE').rally: number— TheRallyDef.numberof the rally the game starts at (a rally number, not an index intorallies).bonus: number— Paid at the end of the starting rally.
TurretDef
interface TurretDef
A gun turret beside the road: it fires at you as you pass and can be destroyed.
kind: string— Sprite kind (the presenter's art key).w: number— Collision box width, metres.h: number— Collision box height, metres.d: number— Collision box depth along the road, metres.armour: number— Rounds to destroy it.points: number— Points for destroying it (times the multiplier).gap: number— Lateral gap from the tarmac edge to its centre (metres).range: [number, number]— It fires while you are betweenrange[0]andrange[1]metres from it (ahead of you), everyeverys.every: ByDifficulty<[number, number]>— Seconds between shells while you are in range, as [min, max], by difficulty (the pace scales it).shell: { speed: number; size: number }— Shell speed (m/s) and the shell's box; it leads you by your speed.
TurretState
interface TurretState
A turret beside the road.
id: string— Unique id, also the id of its object in the race's field.z: number— Course position along the road, metres.x: number— Lateral position across the road, metres; positive is right.armour: number— Rounds left to destroy it.fireIn: number— Seconds until its next shell.
WeaponDefs
interface WeaponDefs
The special weapons the support jet drops.
uz: { name: string; rounds: number; every: number } | null— U.Z. Cannon: rapid fire,roundsper pod.shield: { name: string; uses: number; time: number } | null— Electro Shield:usesactivations oftimes each; enemies driven into are destroyed.nitro: { name: string; uses: number } | null— Nitro Injector:usesbursts (the vehicle's timed boost).missile: { name: string; uses: number; range: number; time: number } | null— Cruise Missile:useslaunches, each destroying everything withinrangem ahead except red globes.loseOnCrash: boolean— A crash loses the special weapon (the Genesis manual).
WeaponId
type WeaponId = "uz" | "shield" | "nitro" | "missile"
Special weapon ids.


