The Road Rash ledger
This game is a remake of the arcade half ("Thrash") of Road Rash, EA's 1994 3DO game in its 1996 Windows port — the version Chinese players know as 暴力摩托 and the one I played. Every mechanic of that game has a row here, sourced, with a decision against it. A mechanic that is not in this table has not been considered yet, and nothing gets built from memory: a new mechanic is researched and added here before any code is written for it.
spec/ledger.test.ts holds the table to its own rules:
- every row has a status of
built,plannedoromitted - a
plannedrow names the crit it is due by:C8,C9,C10orfinal - a
builtrow names the spec test that proves it, asfile › test name, and that test exists - an
omittedrow says why - every source tag resolves to a URL in Sources
Treatment is same when the row is copied as the original has it, or
adapted: followed by what changes and why. Where versions of the game disagree,
the PC version wins; the others are only used where the PC manual is silent,
and the row says so.
A row whose source is — is a rule the original never needed — matchmaking, for
one — and must be adapted:, saying what it answers instead.
The research behind this table is in road-rash-research.md, gathered on 30 Sep 2026 from the manuals and FAQs listed at the end. It has the numbers, the differences between versions and the conflicts between sources that the table only summarises.
Structure
| ID | Mechanic (PC 1996) | Source | Status | Treatment | Due / proof |
|---|---|---|---|---|---|
| S1 | Big Game career: money, a bike shop, repair bills and fines, game over when broke | PCM, SATM | omitted | omitted: I chose the arcade mode alone. A career is a single-player economy, and it would make a race you join for five minutes carry a debt into tomorrow | — |
| S2 | Thrash: pick a level (1–5) and a track, race on a preset bike for that level; no money, no shop | PCM, SATM, FADE | built | adapted: each person picks a road and a level, and a shared race runs the room's majority vote of both (N4); everyone in it rides that level's bike. No money and no shop | spec/lobby.test.ts › is run at the level most riders voted for |
| S3 | Thrash preset bikes per level: L1 Swallow, L2 Sport 450, L3 ZYX 750, L4 Raven N, L5 Assassino N | FADE | built | adapted: five bikes of my own naming, Wasp 400, Hornet 450, Ronin 750, Kestrel 600 and Bravo 900, with the originals' horsepower and weight. Their top speeds, 275–315 km/h, are read off the PC game's own dial in a recorded race (R5), not taken from the manual, whose figures held level 1 at 92 mph | spec/feel.test.ts › never goes past the bike's top speed on the throttle alone |
| S4 | Finishing 1st–3rd qualifies you on that track; all five tracks qualified completes the level | PCM, ZHWP | built | same; qualifications are kept against the rider and survive across days | spec/persistence.test.ts › keeps a rider and a qualification across a restart |
| S5 | In Thrash, being Wrecked or Busted revokes your qualifications on the current level | SATM | built | same: a person wrecked or busted loses every road they had qualified on at that level, the other levels kept, and the result screen names the roads it cost. Leaving, running out of time or a race the server stopped takes nothing. The points on the leaderboard (N12) stay: they are for finishes that happened | spec/persistence.test.ts › takes every qualification on the level from a rider wrecked or busted in it, and keeps the other levels (S5) |
| S6 | Five levels; each lengthens the courses, adds traffic and cops, toughens opponents | PCM, ZHWP | built | adapted: a level is how ready the field is to fight, not how long the road is (every race is about two minutes, T2). Level by level the AI riders are up to 3.2 times as aggressive, swing on a quicker beat, go after whoever hit them more readily, rest less between fights, take cheap shots at anyone in reach in the middle of one, start armed more often (25% to 65%) and race nearer the bike's top; and there is more traffic, more cops and a faster bike. All of it is blind to whether a rider is a person (O5) | spec/fights.test.ts › hits harder at level 5 than at level 1, a person alongside and each other alike |
| S7 | Higher levels extend the same road rather than replacing it | ARGURO | built | same: each level runs 300 m further down the same road, 8.5 km at level 1 to 9.7 km at level 5 (T2) | spec/ledger-rows.test.ts › runs a higher level further down the same road, never a different one (S7) |
| S8 | Street hub between races: sign-up board, shop, schmooze, restroom | PCM, 3DOM | built | adapted: one lobby page with the matchmaking buttons and the rider's qualification board, beside the Live page (N11) and the Leaderboard (N12). No shop, because there is no money | spec/lobby.test.ts › lists every race on the road with the people in it, and lets anyone watch one, and stop |
| S9 | Named save files through Load / Save / Save As | PCM | built | adapted: nothing to manage — the rider is remembered by the browser, and everything saves as it happens | spec/persistence.test.ts › keeps a rider and a qualification across a restart |
Multiplayer
| ID | Mechanic (PC 1996) | Source | Status | Treatment | Due / proof |
|---|---|---|---|---|---|
| N1 | Mano a Mano: up to 8 players over a network; the host picks the level and sets traffic on or off | PCM | built | adapted: no host. Matchmaking pools replace the host (N2, N3), and a room holds the original's eight people at most: a full pool goes at once and the ninth waits for the next room. Eight is also what lets every person in a room wear different leathers (N13) | spec/lobby.test.ts › holds at most eight people; the ninth waits for the next room |
| N2 | Host option LIMITED AI BIKERS | PCM | built | adapted: an AI pool. It gathers for 5 seconds and takes everyone who joins in that window. Each rider sets how many AI riders to race, 0 to 29, and the race takes the median of what the pool asked, so no one person can empty or flood the road; anyone who does not say gets the full grid of fifteen | spec/lobby.test.ts › takes the median of what the pool asked for, up to the most allowed |
| N3 | Host option HUMANS ONLY | PCM | built | adapted: a human pool. It gathers for 10 seconds and starts if two or more people are in it; alone, it keeps waiting, and each newcomer restarts the 10 seconds | spec/lobby.test.ts › restarts the ten seconds for each newcomer, then races only the humans |
| N4 | The track is chosen by majority vote of the players | PCM | built | same, and the level is voted the same way; a tie is broken at random. No balancing by level — a level-1 rider may race level 5 | spec/lobby.test.ts › is run at the level most riders voted for |
| N5 | Once a race starts, its riders leave matchmaking | — | built | adapted: added by me, since the original had no pool. People still waiting in a pool can watch a race in progress | spec/lobby.test.ts › lets someone who joins after the start watch the race instead |
| N6 | Upper-left indicator of every human's position, scrollable | PCM | built | same: under the leave button, every person in the race in order of place, the place counting the NPCs, each with their leathers; one's own row is lit, anyone wrecked, busted or gone is dimmed, and past six people it scrolls. A person racing NPCs alone has their place on the dash already, so it shows only with two or more. Spectating, it follows the rider watched | spec/people.test.ts › lists every person in the race and no NPC, best placed first, with their place counting the NPCs |
| N7 | Chat: canned messages on F1–F8, free typing on F9; status events (busted, wrecked, quit) posted to it | PCM | built | adapted: eight canned lines of my own on F1–F8, or a Say button with the same list for a phone, and the status events. Each goes to everyone racing or watching that race, top right, the newest four kept and each fading after eight seconds; a person wrecked, busted or leaving is posted, an NPC is not. One line every 1.5 s each, so the box cannot be flooded. Free text on F9 is left out: an open public site would need moderation this game has no one to do | spec/lobby.test.ts › sends a canned line to everyone racing and watching, from the bike that said it, one every second and a half |
| N8 | Every other rider is drawn where they are now and moving smoothly, however unevenly the network delivers them | — | built | adapted: the original raced on a LAN. Here snapshots are placed by the race time they carry, drawn by a clock that is eased and never stepped back, and carried forward to the present; measured against the live server's own arrival times, every bike is drawn within 0.11 m of how it really moved, frame after frame. How far in the past the others are interpolated follows how late snapshots are coming (N14): 0.1 s on a connection that delivers on time, longer as the 95th percentile of the last five seconds' lateness grows, up to 0.4 s; it rises at a quarter of real time and falls at a fiftieth. Through a 300 ms, 3%-loss connection the fixed 0.1 s drew 44-78% of frames past the newest snapshot, by guesswork; adapting, 4-6%. When the server takes one's own bike over from the prediction (knocked off, thrown, run into), it is drawn where the prediction had it and let go of 8% a step, not moved back by a round trip's riding in one frame; the rider itself is where the server says from the first step | spec/netview.test.ts › draws every bike moving as it really moved, frame after frame |
| N9 | A match is accepted before it starts | — | built | adapted: added by me, after the ready check of a modern matchmade game; the original's host simply started. When a pool fires, everyone in the room gets a full-screen Match Found with ten seconds to accept, and sees a box fill as each person does. All accept and it loads. Anyone who declines or lets the ten seconds run out leaves the queue; everyone else goes back to the front of the pool with their votes kept. It asks even one person alone in an NPC race. While still in the queue a bar across the top of the lobby shows the pool, a running clock and when the room forms, on a timer so it keeps counting in a background tab | spec/lobby.test.ts › asks everyone in a room to accept, and starts loading only once all have |
| N10 | Everyone starts the race together | — | built | adapted: added by me, since the original raced on a LAN. After the accept, everyone loads the race — road, scene, the riders' frames, the music — on a screen with one card per person showing their leathers, their ping and how far they are. The race starts when all are loaded, after at least 2 s so the screen is seen and at most 20 s so one slow browser cannot hold the room. Each person's start carries the countdown shortened by half their round trip, the shortest one seen while loading as NTP takes it: averaged, a page busy building its scene read 147 ms on the same machine. Two browsers showed GO 1 ms apart | spec/lobby.test.ts › shortens each person's countdown by half their round trip, so GO lands at the same moment for everyone |
| N11 | Races in progress can be found and watched | — | built | adapted: added by me; the original had no spectators. A Live page at /live lists every race on the road, once a second: road, level, mode, race clock, each person with their leathers (and whether they have left), how many NPCs and how many people are watching. Watch puts the race full screen behind any rider, ← → (or A D, or the arrows on screen) moves the camera between the people and the leading NPC with that rider's own dash, and Esc goes back to the list. Watching survives joining and leaving a queue; racing or being matched ends it. The small view of the newest race for people waiting in a queue stays (N5) | spec/lobby.test.ts › lists every race on the road with the people in it, and lets anyone watch one, and stop |
| N12 | A standing across races | — | built | adapted: added by me; the original kept a career for one player. A Leaderboard page at /leaderboard ranks every person who has raced: a finish scores by its place across the line, F1's 25-18-15-12-10-8-6-4-2-1, with NPCs counted in the place but never listed; wrecked, busted, leaving or running out of time scores nothing. Anyone who rode a race is listed however it went, with nothing for it if it did not score: until 7 Nov a practice race (G3) and a race the server stopped were not written at all, so a person whose only races were those never appeared. Ties go to wins, then podiums, then fewer races. Each name is followed by the rider's number, as the log writes Name#rider, because a browser is a rider and two people may choose one name. It is worked out from the results already kept for every race, so races run before it existed count too, and one's own row is marked. A rider made by a script (a network probe, the load test, the spec's two people) connects with ?probe=1, is marked for good, and is never listed; the riders scripts made before the mark existed were marked by hand where the database shows it: made in bursts seconds apart, or by the probes of 13–14 Oct |
spec/persistence.test.ts › ranks everyone who has raced by points for their finishes, wins and podiums, and lists no NPC (N12) |
| N13 | Each player's rider is told apart from the others | — | built | adapted: added by me, since the original's network riders were dealt a look by slot. Leathers are dealt when the room forms, a shuffle of eight pairs, one each, so no two people in a room look alike and everyone's entry list carries the same pair. A picker came first, and two people could pick the same; it was taken out. Black & acid and Orange & red were cut after all ten were worn by the rider on the road: the black legs and bike vanished into the asphalt, and the two warm colours smeared into one | spec/lobby.test.ts › are dealt by the room, never the same twice among its people, and the same in everyone's entry list |
| N14 | Everyone's connection is watched through the race, and shown | — | built | adapted: added by me; the original raced on a LAN and showed no ping. The round trip was measured only while loading (N10), its shortest kept to time GO, so a connection that went bad in the second minute was invisible, and the only other measurement was scripts/netprobe.ts from a test machine. Now the server asks everyone racing for a round trip every second and keeps all of them; each browser reports every five seconds how long a key took to come back acknowledged, the gaps between snapshots (past 250 ms is a stall), how often its own bike was put back where the server said, and how long its frames took; the server times its own ticks and steps. One net line per person when they finish or leave, a lag_spike line when a round trip runs past 150 ms and three times their usual or snapshots stall, at most one per ten seconds each, and a server_stall past 100 ms late. The last round trip sits in the race's top right corner, green under 80 ms, amber under 150, red past it, and each person's usual one is on the Live page. readlog.ts --ev net,lag_spike,server_stall,server,big_jump reads it back. One's own bike drawn more than 10 m from where the server had it is sent at once as a big_jump, with both positions and speeds, the phases either side, the frame and snapshot timing and the events that named the rider, at most five a race: a 22 m jump onto a tree was seen once at a 20 ms round trip and could not be made to happen again in 30-odd rides, so the next one is caught where it happens |
spec/net.test.ts › writes one line per person when the race ends, by name, with their round trip, jitter and what their browser saw |
| N15 | A race stopped by the server ends for everyone in it, and says so | — | built | adapted: added by me; the original had no server to restart. A restart or a deploy sends the process SIGINT; before it exits, every race on the road ends with each person's outcome "aborted", an end carrying why goes to everyone racing or watching, and the log writes a race_end with aborted. The page shows "Race stopped" instead of only "Connection lost", and reconnects by itself. An aborted race is not written to the leaderboard or the qualifications, since nobody finished it. Before this, a restart 5.1 s into a race left both pages with no ending and the log with a race_start and no race_end (docs/testing/multi-user-test-report.md, scenario h) |
spec/lobby.test.ts › ends every race as stopped when the server shuts down, tells everyone in it, and scores nobody |
| G1 | Someone who rides nowhere is taken out | — | built | adapted: added by me; the original raced on one machine, where a player who stopped only spoiled their own race. Here one tab left open on the grid held a room of people to the time limit. A person who gets no more than 5 m further down the road for 45 s after GO is taken out as "idle", told so, and named in the chat as having left; the race goes on for everyone else. Measured by progress down the road, not speed, so a rider lying in the road, running back or crawling past a roadblock is never taken out for it | spec/griefing.test.ts › is taken out after 45 s with no progress down the road, and the race goes on for everyone else |
| G2 | One connection cannot flood the server | — | built | adapted: added by me. Each connection gets a burst of 90 messages, refilled at 90 a second; past it, messages are dropped and the refusal logged once. The page sends keys only when they change and four times a second otherwise, so a person never reaches it; before, a script sending 2000 renames had every one of them answered | spec/realtime.test.ts › drops a flood of messages from one connection past the rate, and still serves everyone else (G2) |
| G3 | A race with nobody to beat scores nothing | — | built | adapted: added by me. The board lets a person race alone against no NPCs (N2), and a first place there took 25 points and a qualification with nobody beaten. One person against fewer than four on the grid now rides and is shown the result, says it was practice, and gives no points and no qualification; the race is kept unscored, so the person is still listed (N12). Two people racing each other always count | spec/griefing.test.ts › scores nothing with fewer than 4 on the grid, and says so |
Riding
| ID | Mechanic (PC 1996) | Source | Status | Treatment | Due / proof |
|---|---|---|---|---|---|
| R1 | Steer left / right; accelerate; brake | PCM | built | same, on W, S, A and D (R15) | spec/feel.test.ts › pulls from the grid to 250 km/h in about five and a half seconds |
| R2 | Separate lean input: turns more slowly but loses less speed | FADE, PCM | omitted | omitted: I played without ever touching a lean key, and the lean I remember came from the bike itself (R17). A second steering input would make the game I am remaking harder to recognise, not easier | — |
| R3 | Steer and lean together is a power slide: fastest turn, risks a crash | FADE, SATM | built | adapted: no lean key. The bike leans on its own only when it is steered hard at 0.92 of its cap or more, turns up to 80% faster leant right over, and lowsides (16 damage) if held at full lean for 0.6 s; below that a full steer tips it no further than 0.35 | spec/ledger-rows.test.ts › leans only when steered hard near the cap, turns sharper leant over, and lowsides held there (R3) |
| R4 | No gears; the rev counter is feedback only | FADE | built | same: the needle climbs with speed towards the bike's cap, and the build-up (R17) carries it the last part of the way | spec/ledger-rows.test.ts › has no gears: the rev counter climbs with speed alone, and the build-up takes it to the top (R4) |
| R5 | Races at 100+ mph; the fastest bikes reach about 180 | SATM, RRVID | built | adapted: speeds come from the PC game's own km/h dial in a recorded race, not the manual: grid to 250 km/h in about 5.5 s, a cruise of 280–290 once the speed has built up. The bikes top out at 275–315 km/h by level, the same bike for everyone in a race, and nothing carries a rider past it (R8). The manual's 109–158 mph had held level 1 at 92 mph | spec/feel.test.ts › cruises at 280-290 km/h once the speed has built up |
| R6 | Lighter riders are faster; heavier riders hit harder | 3DOM, SCDM | omitted | omitted: everyone in a race rides the same bike at the same weight, so no rider, person or AI, has a faster machine than another (R8) | — |
| R7 | A faster rider hitting you from behind pushes your speed up by as much as about 7 mph | ARGURO | built | adapted: a shunt is a collision of two bodies (K14) with momentum kept, so what the bike in front gains depends on how much faster the one behind was, and it can be far more than 7 mph. The 7 mph is one FAQ's observation of the AI, with no rule behind it in any manual | spec/touch.test.ts › run into from behind, however much faster, nobody comes off: momentum is kept, the two part to either side and the faster goes by (K14) |
| R8 | Nitrous on "N" bikes only: ten charges a race, one burst per press | PCM, SATM, RRVID | omitted | omitted: it was built on every bike, ten charges of 3.5 s and 35 km/h over the top, and the AI used it too. Ridden, it read as cheating: a rider just passed came straight back past on a straight, with nothing on screen to say why (47 of 77 times an AI rider passed a flat-out player, measured over 4 seeds and 5 roads). Every rider in a race is on an equally good bike and none can go faster than it | spec/feel.test.ts › never goes past the bike's top speed on the throttle alone |
| R9 | Oil, mud and ice patches make you skid | FADE | built | same: about a dozen patches a road, one every 450-850 m in one of the four lanes, fixed by the road's seed so each is where it was last time (R11): oil in town and on the coast, mud in the valley and the canyon, ice in the mountains. On one the bars hold 8% of their grip on oil, 5% on ice and 25% on mud, so the bike carries on sideways, and the back steps out the way it was already moving; the grip comes back over half a second after. Held lean drops it in half the time, and mud drags. At 95% of top speed over oil with the bars still the bike slides 2.3 m across, and steering back holds it to 1.2 m. The same patches for everyone, people and NPCs, and the browser predicting its own bike sees them too | spec/ledger-rows.test.ts › throws the bike sideways the way it was going, and steering only half wins it back |
| R10 | Hills throw the bike into the air | FADE | built | same: where the road falls away over a crest faster than gravity can pull the bike after it (1.3 g of it), the bike leaves the road at the climb it had and flies under gravity until it meets the road again. In the air the throttle, the brake and the bars do nothing, cars and bikes below pass underneath once it is higher than a roof, and the chase camera flies up with it, so the road drops out of the picture, as fade84's "you lose sight of the ground". Orchard Valley has two short humps made for it: flat out the bike is in the air for over a second and 4 m up; at 60% of top speed it stays down. Ridge Road's crests lift it a few centimetres for a few tenths at full speed | spec/ledger-rows.test.ts › throws a bike flat out into the air over a hump, lands it riding, and keeps a slower one on the road |
| R11 | Pedestrians and traffic cones act as ramps; each obstacle always does the same thing | FADE | built | same for the cones: a line of three to five across one lane every 900-1500 m, fixed by the road's seed, so each is where it was and does what it did last time. A cone ridden over throws the bike up at 1.5 m/s plus 0.035 per m/s of speed, 0.3 m high at a third of top speed and 0.8 m flat out, over the rest of the line, and it lands riding; the cone goes flat for four seconds with a plastic knock. A pedestrian is the same ramp (T6) | spec/ledger-rows.test.ts › throws a bike that rides over one into the air, higher the faster, and it lands riding |
| R12 | Leaving the asphalt slows you; off-road trees crash you | FADE, PCM, RRVID | built | same. The dirt shoulder is ridden at about 190 km/h, as in the recording; grass beyond it bogs the bike down to 108 | spec/feel.test.ts › is ridden at about 190 km/h on the dirt shoulder |
| R13 | Falling off an unfenced cliff into the ocean wrecks you instantly | FADE, ARGURO | omitted | omitted: the coast road has a rail along the sea, solid as a wall (K12), so a rider kicked there is thrown into the rail and down. A fall that ended the race at once would end it for whoever was kicked, in a race they cannot restart | — |
| R14 | Roads fork; the shorter branch is the harder one | FADE | omitted | omitted: a fork splits the people in a room onto two roads, out of reach of each other's fists for the length of the branch, and being alongside one another is what this remake is for (README, "the person in the next chair"). It would also need a second centreline under everything that now runs on one: the race's distance, the standings, the browser's prediction, traffic, the land and the camera. The shorter-but-harder choice it offered is kept in another form, the lane with the cones (R11) or the patch (R9) taken or ridden round | — |
| R15 | Default keys: arrows ride, Home/PgUp lean, N nitro, D dismount, Ins punch or grab, Space backhand, Enter kick | PCM | built | adapted: W throttle, S brake, A and D steer, and the arrows do the same; J is the hand (punch, weapon swing, grab), K the foot (kick); M turns the music off, Esc leaves the race. Backhand has no key of its own (C3), and nitro and lean are gone (R8, R2). The phone rides with a stick under the left thumb (across steers, up is the gas, down the brake) and fights with J, K and L under the right, so the gas never has to be let go to punch (spec/stick.test.ts, and scripts/rough.ts with touch events) |
spec/ledger-rows.test.ts › carries every action a player has, keys and touch alike, through the wire and back (R15) |
| R16 | Configure Input remaps every control | PCM | built | same: a Keys panel on the board gives each of the six actions a key of the rider's choosing, kept by the browser. A key another action had swaps with this one's old key, so no key does two things and none is left without one; Esc, M and F1-F12 are refused, since a race already uses them. The arrows keep working until one is given away, and the touch buttons show the chosen letters | spec/keys.test.ts › gives any action any key, swapping with whoever had it, so no key does two things and no action has none |
| R17 | Speed builds towards the bike's top speed the longer you ride without being hit, crashing or stopping | — | built | adapted: from the game as I played it, not from a manual. Without it the bike reaches 0.88 of its top; ten seconds of riding above 0.7 of it on the asphalt builds the rest. A hit takes away 0.35 of it, and a crash or a stop all of it. It is felt as the road getting faster rather than read from a meter | spec/feel.test.ts › cruises at 280-290 km/h once the speed has built up |
Combat
| ID | Mechanic (PC 1996) | Source | Status | Treatment | Due / proof |
|---|---|---|---|---|---|
| C1 | Attacks aim automatically at the nearest opponent, shown in the Closest Opponent box | PCM, RR1M | built | adapted: the nearest riding rider within 8 m along the road and 5 m across, with distance across counted half as much again; with no one that close the box is empty | spec/ledger-rows.test.ts › aims at the closest rider in reach, and at no one out of it (C1) |
| C2 | Punch drains the target's stamina; it takes several blows to put a rider down | PCM, SATM, RRVID | built | adapted: seven club blows from full, eight fists, a run of them close together. The recording's rival seemed to go from full to empty in about five club blows a second apart (353-357.5), and five and six (club 21, fist 17) were tried first; ridden, a rider went down too fast | spec/traffic.test.ts › seven club blows close together take a full rider to empty (C2, M1) |
| C3 | Backhand hits a rider behind or beside you, with or without a weapon | PCM, 3DOM | built | adapted: there is no backhand. J throws the same punch (or swings the same weapon) wherever the opponent is, mirrored only to their side, and it lands on whoever is within reach on that side when it arrives: up to 0.9 m ahead or behind for a fist, 0.8 m for a boot, 1.1 m for a club and 1.3 m for a chain. Measured off five hits in the recording (RRVID 92.46, 57.28, 247.64, 355.60, 413.82) by the two rear tyres, each about a third of a metre wide: no struck bike is further than 0.7 to 0.9 m from level. The first reach, 1.8 m for a fist, was set before anything was measured and hit a rider most of a bike length back. Built first as its own move, J turning into a backhand when the nearest opponent was more than 0.6 m behind, with poses of its own; those poses kept the old cranked chain in play after the forward swing had been fixed, and a move that changes with where the other rider is reads as the game choosing for you | spec/ledger-rows.test.ts › throws the same punch at a rider ahead, level or behind, and lands it on whoever is within reach (C3) |
| C4 | Kick shoves the target's bike sideways, into traffic or roadside objects | PCM, SATM, FADE, RRVID | built | same: no stamina, and the bike thrown 15 m/s sideways, fading at 2 a second, 7.5 m if nothing stops it, so its worth is what it is thrown into (a car, the rail, a cliff, a tree past the shoulder). In the recording a kicked rival is over the next frame and off the side of the picture 0.16 s later (57.24-57.44); RR2: "does no damage but pushes the bike". Built first as a weak punch with a nudge, 5 stamina and 1.75 m in all. AI riders kick when the foe has something on its far side, and punch otherwise | spec/fights.test.ts › throws a rider in the outer lane into the sea rail, and they go down |
| C5 | Two weapons, club and chain; one held at a time, swung with the punch key; some riders start with one | PCM | built | same | spec/traffic.test.ts › the chain reaches a rider a fist cannot, and a weapon hits harder than a fist (C5) |
| C6 | Snatching: press punch as an opponent winds up a weapon swing and it becomes yours | PCM, FADE, POSTER, FINNER | built | same. The PC manual gives no timing, so the window is taken from the Mega Drive sources: "a small pause as they bring their arm back. You have to punch them at this exact moment" (FINNER). The draw-back is 0.36 s against a fist's 0.22 s (the recording shows a club held overhead for 6 frames and lowered over 2 at 25 fps), and only its last 0.12 s, the weapon all the way back, is the moment: pressed earlier, J is a punch, and the blow still lands. At first the whole draw-back was the window, so mashing J in a fight took weapons by accident and AI riders took about one swing in two; an AI rider now grabs in that last instant at a rate set by its aggression. The 0.12 s still leaves room for the network: a draw-back reaches the screen up to 0.1 s plus one way after it starts, and the round trip to the Fly app is 16 ms. Pressed after the blow lands, J is only a punch | spec/traffic.test.ts › punching at the moment an opponent has a weapon all the way back takes it off them (C6) |
| C7 | Cops carry clubs and are the easiest place to get one | POSTER, SATM | built | same | spec/traffic.test.ts › a cop's club can be snatched the same way, and the cop rides on without it (C7) |
| C8 | Stamina at zero knocks the rider off; they run back to the bike | PCM, ZOL | built | same; and back on the bike, stamina is full again, from the tip that jumping off and back on refills it (ZOL). Refilled to half at first, a rider knocked off once went down again after about four blows | spec/traffic.test.ts › getting back on the bike, a rider's stamina is full again (C8) |
| C9 | A rider lying on the road can be run over | FADE, RRVID | built | same, as the recording shows it (317.6-318.8): a rider on foot, running back to the bike or lying where they landed, ridden into is flung up ahead of the bike and off to one side, carried on level with it through the air so they are seen, and lands beside it; the bike that hit them is off the road for about a quarter of a second with its shadow left below, then goes over hard and rocks back, and rides on a little slower. A fallen bike lying in the road is ridden over with a smaller jolt and a bang of metal. Felt on one's own bike as it happens, not a round trip later | spec/ram.test.ts › on foot, running back to the bike: run over, not ridden through (C9) |
| C10 | Whether a stolen weapon carries into the next race | RR1FAQ | built | adapted: the PC is undocumented here; I follow the Mega Drive rule that it does not | spec/traffic.test.ts › some AI riders start armed, and every human starts empty-handed (C5, C10) |
| C11 | Rivals come at you: one rides up beside the player, matches speed and stays there trading blows, swinging about once a second | RRVID | built | adapted: the recording shows a rival alongside the player for six seconds and more (351.5-357.5), swinging every 0.96 s. Each AI rider here picks a foe as O5 has it, a person no more readily than another AI rider, rides to its flank, holds level with it while its own race pace allows, swings on that beat and now and then rubs it over, and gives up after 5-15 s. It has no nitro to close with (R8). It no longer rides a fight with its build-up held full, which no player had | spec/fights.test.ts › swings at a player who never swings back, on every road |
Meters and crashes
| ID | Mechanic (PC 1996) | Source | Status | Treatment | Due / proof |
|---|---|---|---|---|---|
| M1 | Stamina meter drains with each blow and slowly recharges when you avoid more | PCM, SATM, RRVID | built | adapted: recharges fast, 20 a second after one second without a blow, so empty to full in five. The recording's player wedge, knocked to about half at 413, filled again after about two seconds clear and was near full by 421, and 12 a second after 2 s was taken from it first; but a duellist swings about once a second for 5-15 s, so the two seconds never came inside a fight (the player lost 221 a race and got back 49), and it rode harsh. Before that it was 4 a second after 2.5 s | spec/traffic.test.ts › stamina comes back fast once the blows stop: a second clear, then empty to full in five (M1) |
| M2 | A crash (car, obstacle, tree, knockdown) throws the rider; the bike lies where it fell; you steer the run back | PCM, SCDM | built | same. The throw is flown: from the seat's height, upwards at 2.5 m/s for a slide and at 0.2 of the closing speed into a car or a tree (4 to 9 m/s), under gravity, with the road's own climb or fall at that moment carried into the flight, and down only when the rider meets the road under them. They leave along the road as it sloped there, so an even slope flies as the flat does; off a crest the road falls away under them and they sail on higher and longer, and into a rise they come down on it early. It was first a fixed arc drawn over the road wherever the rider was, which followed every crest and dip | spec/touch.test.ts › thrown off over a crest a rider flies longer, and into a rise comes down sooner (M2) |
| M3 | D dismounts deliberately | PCM | built | adapted: D steers now (R15), so getting off is L, or a Get off button on a phone, and remappable (R16). Only under 20 km/h: the bike goes down beside the rider, 2.4 m to the middle of the road, they stand while the key is held, and let go they walk back on as after a fall, with stamina full (C8), which is what the ZOL tip used it for. Stopped beside a cop, that is Busted (P1). The first version put the bike 1.6 m away, inside the 1.2 m a rider climbs back on from after one step's walk, so a tap was off and on in 0.06 s and never seen | spec/ledger-rows.test.ts › lets a rider near a stop get off, the bike stood beside them, and walk back on with stamina full |
| M4 | Bike damage gauge drains with each crash, cannot be repaired in a race; empty means Wrecked and out of the race | PCM, SCDM | built | same: a tree costs 34, a head-on 40, running up the back of a car 30, a wall 28, a lowside 16; a knockdown by another rider costs nothing (K6) | spec/ledger-rows.test.ts › wrecks a bike whose damage runs out, and the race is over for its rider (M4) |
Police
| ID | Mechanic (PC 1996) | Source | Status | Treatment | Due / proof |
|---|---|---|---|---|---|
| P1 | Stopping near a cop, by crashing or being pulled over, gets you Busted; the race is over for you | SATM, SCDM, ZHWP | built | same | spec/traffic.test.ts › stopping beside a cop is Busted, and the race is over for that rider (P1) |
| P2 | Motorcycle cops appear at fixed mile markers on each track and try to club you off or pull you over | ARGURO, FADE | built | adapted: fewer of them, one on a level 1 road, two on 2 and 3, three on 4 and 5, where the City has three at level 1. Each starts from a fixed point and patrols slowly (70 km/h) down the right-hand edge of the asphalt, clear of the outer lane's cars, on the race's own bike; he goes after no one of his own accord (P7). The previous version held cops off the road and sent one in from behind at whichever human neared his post, flat out on a bike a level better and always at full build-up: he shot past, then held the player's speed and steered to the player's line plus 1.4 m, so he sat just ahead mirroring every move, and riding alongside he made 28 of 38 crashes with a cop out a bust in 30 races. Got 150 m away from, either way, a cop gives up and patrols again, and a crash after that is not a bust by him. There are no police cars | spec/traffic.test.ts › a cop patrols slowly down the right-hand edge of the road, and goes after no one who leaves him be (P2) |
| P3 | Cops are slow at the low levels | FADE | built | adapted: a cop patrols slowly at every level and chases on the race's own bike, no faster than anyone he is after (P2, P7) | spec/traffic.test.ts › a cop patrols slowly down the right-hand edge of the road, and goes after no one who leaves him be (P2) |
| P4 | AI riders are never Busted | FADE | built | same. Kept after weighing it against O6: the cops are the road's hazard for the people racing, and an AI rider pulled over would only thin the field they race against | spec/traffic.test.ts › never busts an AI rider (P4) |
| P5 | Police roadblocks from level 4, passed on the centre line or over the sand mounds | FADE | built | same: one roadblock on every road from level 4, on a straight about three fifths of the way down; barricades over all four lanes with a 1.1 m gap on the centre line and a sand mound at each edge that throws a bike at speed over the 1.1 m barrier. Traffic is kept out of 150 m either side; NPCs and cops line up on their own mound | spec/ledger-rows.test.ts › is passed exactly on the centre line or over a sand mound, and stops anything else at the barrier |
| P6 | Cheat codes (XYZZY, then weapon, speed and police cheats) | CHEAT | omitted | omitted: in a shared race a cheat is a thing done to other people | — |
| P7 | A cop goes after whoever hits him: a rider slows to a patrolling cop and picks the fight, and the chase is theirs until someone else lands a blow on him | — | built | adapted: my own design in place of the original's, where cops close in on whoever passes their mile marker. Every rider is over any limit there is, so a cop chasing for speeding would chase everyone; here the police are a fight a rider chooses (for the club, C7), and one that can be passed to whoever else hits him. AI riders pick it too, from up to 250 m back so they can brake down from racing speed to his, keener without a weapon of their own: in 30 races a cop was set on a chase 54 times, the chase passed to someone else mid-way 37 times, and his club was taken 26 times. Coming up from behind he rides flat out; once past the one he is after he comes off the throttle and lets them come back to him rather than hold his place ahead | spec/traffic.test.ts › an AI rider picks a fight with a patrolling cop: brakes down to him from racing speed and lands blows (P7) |
Tracks and traffic
| ID | Mechanic (PC 1996) | Source | Status | Treatment | Due / proof |
|---|---|---|---|---|---|
| T1 | Five real Northern California roads, each with its own character | PCM, RRVID | built | adapted: five fictional roads of my own (Ridge Road, Seawall Highway, Orchard Valley, Gold Town, Red Canyon), each passing through more than one kind of country, the way one recorded race runs coast, valley, town, farmland and canyon. The land is shaped around the road, never laid over it | spec/terrain.test.ts › drawn as a heightfield, never covers any part of the road surface |
| T2 | Course lengths per level, from about 5 miles at level 1 to about 17 at level 5 | JATIN | built | adapted: every race is about two minutes, 8.5 km at level 1 to 9.7 km at level 5 on its faster bike. The original's 17 miles was a six-minute race here, on roads written out only 3.7-5 km and repeated four times over. Each road is now written bend by bend for its longest race, and none comes round twice | spec/world.test.ts › never comes round the same bends twice in a race, at any level |
| T3 | No race timer and no progress bar: the course length is shown before the race and the odometer counts up | PCM | built | adapted: the road, level and length in km are shown at the start, and the odometer counts up in km, as the dial does. A race still closes for anyone left on the road at its length over 30 m/s plus 90 s, so a rider who stops cannot hold a room for ever; nothing on screen counts it down | spec/ledger-rows.test.ts › shows position, odometer, both names and the closest opponent's distance, and no race clock (H1, T3) |
| T4 | Oncoming and same-direction traffic; drivers change lanes | FADE, 3DOM | built | same | spec/traffic.test.ts › keeps every car in a lane of its own direction for a whole race (T4) |
| T5 | Cross traffic from side roads at intersections | CJH, PCM, FADE | built | same: side roads cross every 1200-2000 m through town, farmland and pine (never on the coast or in a canyon), each with a white stop bar and a green light, at the same places at every level. Following FADE ("in the later levels... learn where they appear"), a car waits at none of them at level 1, one in three at level 2, two in three at level 3 and every one from level 4. It is always the same side roads, and the car pulls out so it is in the near lanes as the first rider comes up. Broadside on at a crawl, it is a crash for whoever rides on into it, and a rider who brakes sees it go by | spec/ledger-rows.test.ts › pulls across as a rider comes up, and takes down one who rides on into it, but not one who brakes |
| T6 | Pedestrians on and beside the road, and a flagger at the start who can be run over | 3DOM, CJH | built | same: in town someone strolls the pavement every 120-200 m and someone crosses the street every 500-800 m, and two people cross at every side road (T5). Each keeps a timetable fixed by the road and the race clock, so the server and every browser have them in the same place without a word on the wire. A bike ridden into one throws them flying and goes up over them like a cone (R11), landing riding; they are back on their feet ten seconds later | spec/ledger-rows.test.ts › is a ramp: a bike that rides into someone throws them flying, goes up over them and lands riding (R11) |
| T7 | Host can turn traffic off | PCM | omitted | omitted: there is no host, and traffic is half of what the road does to you | — |
Opponents
| ID | Mechanic (PC 1996) | Source | Status | Treatment | Due / proof |
|---|---|---|---|---|---|
| O1 | Fifteen riders; you start at the back of the pack | PCM, SATM | built | adapted: humans and AI riders make up the fifteen in the AI pool (N2), and the grid order is drawn from the race's seed. Built first with every person behind the AI, as the original has its one player: with several people in a race the back row was all of theirs, up to 24 m behind the front, and the field was gone before anyone saw it | spec/start.test.ts › puts people anywhere on the grid, not always behind the AI riders |
| O2 | Eight named riders, each with a build, a starting bike and a blurb | JATIN, ARGURO | built | adapted: fourteen NPCs with names of my own, and no builds or blurbs. Everyone in a race is the same weight on the same bike, person or NPC (R6, R8), so a build would be a name and nothing more | spec/feel.test.ts › puts everyone in a race on an equally good bike, people and AI alike |
| O3 | Riders have friends and enemies; hit someone and they hold it against you | PCM, ARGURO | built | adapted: grudges are kept between real people, on /data, across races and days; an NPC's grudge lasts its race (O5). A blow that knocks a person off names who landed it, and the one knocked off holds it against them, counted. When two people meet again, the loading screen says so beside the other's card ("Knocked you off twice; you got them once"), the corner list (N6) carries the head-to-head score, theirs first, and being knocked off by a person says who. Only knockdowns count: a punch that does not put you down is the race, not a grudge |
spec/people.test.ts › remembers who knocked whom off in one race, and tells both of them when they meet in the next |
| O4 | The closest opponent's meter shows their mood: green won't start it, yellow neutral, red coming after you | SCDM | built | adapted: the closest opponent's stamina wedge is all red when they are after you and all yellow otherwise; the player's own stays graded. An NPC is after you while it is fighting you or once you have hit it this race (O5), a person once you have knocked them off, in this race or any before (O3); each snapshot carries whom every rider is after, and a screen reader is told by name. There is no green: the manual's "won't rumble unless you strike first" describes no rider here, since every rider fights for the place it is level with (O5), and nothing can promise a person won't. The PC manual is silent; the Sega CD manual is the source | spec/people.test.ts › reads red for an NPC you hit, carried to the browser in the snapshot, and yellow otherwise |
| O5 | Opponents start fights over position and take cheap shots when they hold a grudge | PCM, GSKY, FADE | built | same, for the AI riders, and blind to whether the other rider is a person: a rider level with one fights it for the place, and one that has been hit goes after whoever hit it for the rest of the race. Fights are ridden at the rider's own race pace; a foe that drops back is left. Grudges kept across races are O3 | spec/fights.test.ts › goes for a person no more readily than for an AI rider level with it |
| O6 | Rubber-banding: while you lead, the AI stays about 300 m behind; AI nitro is unlimited | FADE | omitted | omitted: rubber-banding was built for one human against fourteen machines, and with several people in a race there is no one person to hold the field behind. Each NPC rides at a pace set by the level, 0.90 to 0.98 of the bike's top, plus a skill of its own of up to 0.12; none speeds up or waits for anyone. No one has nitro (R8) | — |
| O7 | Schmooze: talk to riders between races for tips and gossip | PCM | built | adapted: while the race loads, three of its NPCs each let a tip slip, written by me and read off the road being loaded so every one is true: the tightest bend, the side road where a car waits (T5), how many cops there are, the roadblock (P5), where town starts and its pedestrians (T6), the first slippery patch (R9). As the manual says, "don't expect to schmooze a course tip out of a rasher you just spent 5.3 miles hammering": a person in the race who holds a grudge against you (O3) gives a cold word instead. The race's seed picks who says what, so it reads the same in every browser | spec/people.test.ts › lets tips slip that are true of this road, and gives a cold word, not a tip, from someone you knocked off |
HUD and presentation
| ID | Mechanic (PC 1996) | Source | Status | Treatment | Due / proof |
|---|---|---|---|---|---|
| H1 | Instrument panel: damage gauge, stamina, position, distance to the closest opponent, speedometer, rev counter, odometer, closest opponent's name and stamina | PCM | built | same; the speedometer reads km/h, as the Chinese release's dial does | spec/ledger-rows.test.ts › shows position, odometer, both names and the closest opponent's distance, and no race clock (H1, T3) |
| H2 | F10 toggles the dashboard | PCM | built | same, and a Dash button beside Say for a phone. Put away, the panel draws nothing and the camera stops aiming over it, so the road fills the screen; the choice is kept by the browser | spec/ledger-rows.test.ts › draws nothing at all once F10 has put it away, and leaves the camera nothing to look over |
| H3 | A flag girl starts the race | 3DOM | built | adapted: a flagger in a road crew's orange vest and hard hat stands on the centre line 7 m in front of the front row, swinging a chequered flag over the count. He drops it at the go and stands a second longer, so a bike off the front row at full throttle meets him, as CJH did "every start" | spec/ledger-rows.test.ts › puts a flagger in front of the grid who waves it off and can be run over, and pedestrians in town and at the side roads |
| H4 | Four ways a race ends — qualified, placed, Wrecked, Busted — each with its own FMV clip | 3DOM, WP-3DO | built | adapted: a result screen headed by the way the race ended for you, over the standings. As well as the four, a shared race can end in Out of time, Left or Race stopped (N15). There is no video; the screen opens on a drawn star with the outcome on it (V19) | spec/lobby.test.ts › lets a rider leave mid-race with the tab still open, races on for the rest, and lets them queue again (H8) |
| H5 | Licensed grunge soundtrack (14 A&M songs) in the menus, synthesised music during races | PCM, ZHWP, RRVID | built | adapted: the songs are licensed to EA and cannot be republished, and none of the recording's music is copied. Each road plays a recorded rock track of its own by Kevin MacLeod (CC BY 4.0, credited in the README and client/public/assets/ASSETS.md), looping, from the top at every start. The first version was one drop-D loop written in code for every road, sized to what the recording measures (105 BPM, over a minute before it repeats); next to a played band it sounded thin, and five roads sharing it made them blur together. The engine and most hits are still synthesised; a club on a helmet is a recorded crack (Kenney, CC0); M turns the music off | spec/audio.test.ts › gives every road a track of its own |
| H6 | Resolution and detail-level options | PCM | omitted | omitted: the road is drawn at one fixed low resolution and scaled up, so there is nothing to trade | — |
| H7 | The name Road Rash, the riders, bike brands and track names | PCM | omitted | omitted: they are EA's. Mechanics are copied; names are my own, and the README credits the original | — |
| H8 | Esc pauses the race; Esc twice quits it | PCM | built | adapted: a shared race cannot pause, so nothing stops. Esc, or a corner button for touch, asks; Esc again or Leave takes the rider out and back to the board while the tab stays open, and the bike still answers the keys while the question is up. The race goes on for everyone else and the standings say "left", as when a tab is closed | spec/lobby.test.ts › lets a rider leave mid-race with the tab still open, races on for the rest, and lets them queue again (H8) |
Contact
None of the research above asked what happens when a bike touches something, and riding the first build through other bikes was how that showed. These rows come from frame sheets of the PC playthroughs and the manuals and FAQs, in road-rash-collisions.md. Where the PC footage could not settle a question, the row says which source filled it.
| ID | Mechanic (PC 1996) | Source | Status | Treatment | Due / proof |
|---|---|---|---|---|---|
| K0 | Bikes are solid: no bike passes through another, on any screen | YT1 | built | same | spec/contact.test.ts › never leaves two bikes overlapping, at any step of a full-field race |
| K1 | Side contact between two riders shoves the other bike sideways without a crash, the same as a kick | RR3FAQ2, YT1 | built | same. Road Rash 3's FAQ states it; the PC footage agrees | spec/traffic.test.ts › a gentle side rub shoves the other bike over without a crash (K1) |
| K2 | A harder side rub, at a steeper angle or higher closing speed, puts the other rider down in a lean-and-slide knockdown, unlike the full throw off a car | YT1 | built | adapted: a rub only shoves, however hard, and costs no stamina; only blows put a rider down. It first put the rider rubbed down outright at 6.5 m/s across, as the footage shows: in ten AI races 68 of the 108 riders put down by another went that way, often a blow or two into a fight. Then it cost stamina, up to 18 a touch, which still drained the meter in a fight much faster than the blows did. Riding, a rub that ends a fight read as wrong both ways | spec/traffic.test.ts › a rub only shoves, however hard: it costs no stamina and puts no one down (K2) |
| K3 | Hitting a car or fixed obstacle head-on throws the rider clear of the bike in a spread-eagle tumble, with a flash on impact | YT1 | built | same | spec/traffic.test.ts › meeting an oncoming car is a head-on crash (K3) |
| K4 | After a crash the rider lies in the road while others ride past, then stands and jogs back to the bike | YT1, PCM | built | same: thrown for at least 1.1 s, lying 0.3 s after landing, then running back at 6.5 m/s, and back on within 1.2 m of the bike. Others can run them over while they are down (C9) | spec/ledger-rows.test.ts › leaves a thrown rider lying in the road, then has them run back and ride on (K4) |
| K5 | Knocked off by another rider, the bike coasts on riderless, so the run back is longer than after a crash of your own | RR3FAQ2 | built | adapted: the PC footage does not show it; taken from Road Rash 3 because it makes a knockdown cost something different from a crash | spec/traffic.test.ts › knocked off by another rider, the bike coasts on further than one its rider dropped (K5) |
| K6 | A knockdown by an opponent costs no bike damage; only crashes do | RR3FAQ2 | built | adapted: from Road Rash 3, for the same reason as K5 | spec/traffic.test.ts › knocked off by another rider's blows, the bike takes no damage (K6) |
| K7 | Running into the back of slow traffic in your lane is nearly as damaging as a head-on crash | PCM | built | same, with T4 | spec/traffic.test.ts › running into the back of a slower car is a crash, and costs about a head-on's damage (K7) |
| K8 | The kick is for knocking a rival sideways into oncoming traffic | PCM | built | same: a kick throws a rider 7.5 m sideways (C4), and an NPC kicks when the road ahead has something on the far side to throw them into, a car among them | spec/ledger-rows.test.ts › is worth a kick with a car in the far lane, and the kicked rider meets it (K8) |
| K9 | Each obstacle always does one of three things: nothing, a small jump, or a crash | RR3FAQ2, FADE | built | adapted: two of the three. Everything past the shoulder (trees, poles, signs, rocks, lamps) crashes a bike, and a fallen bike or a rider lying in the road is a jolt and a hop (K11, C9). No obstacle is ridden through untouched; a traffic cone and a pedestrian are the small jump (R11, T6) | spec/ram.test.ts › lying in the road where they landed: run over too (C9) |
| K10 | Contact with a motorcycle cop or a blocking cop car is an instant bust; a parked roadblock car is not | RR3FAQ2 | built | adapted: touching a cop is not a bust, whichever way it goes; coming off the bike beside one is (P1). The PC footage never shows a cop collision, and from my own play of the PC version contact alone never got anyone busted, only a crash beside a cop did, so Road Rash 3's rule is not followed | spec/traffic.test.ts › rubbing a cop is not a bust; coming off beside one is |
| K11 | A downed rider and the separated bike stay in the lane as hazards for several seconds | YT1 | built | same: the rider until they are back on, the bike where it fell or coasted to (K5). A rider is run over (C9); a fallen bike costs the bike riding over it a tenth of its speed and a bang of metal | spec/ledger-rows.test.ts › jolts a bike ridden over a fallen one, and says so (K11) |
| K12 | Cliffs, canyon walls, buildings and the sea rail are solid: the bike rides along them or crashes into them, never through | RRVID | built | same. Glanced along, a wall slows the bike; ridden into faster than 6 m/s sideways, it throws the rider | spec/feel.test.ts › scrapes a bike glancing along the coast's cliff, and crashes one ridden into it square |
| K13 | Every touch is felt: a struck bike tilts away on the very next frame, the striker's bike rocks for about four, and nothing shakes or flashes the screen | RRVID | built | adapted: the rub, the shunt, a car's flank brushed and a wall scraped each have a sound and a tilt of their own, synthesised as every sound here is (H5); the recording shows the tilts, and its sounds are not copied. A rider struck by a blow shows a frame of being knocked over away from the blow. Of the blows only a club on a helmet is heard, as a recording of a wooden crack and nothing laid over it; fists, kicks, the chain and a blow taken are silent. Each had a synthesised slap and sub-bass thump, which sounded like nothing real. Nothing flashes: a white flash on the struck rider, a spark where the blow landed and a red flash of the screen for one's own were tried and taken out, since the recording carries a blow in the sprites and the sound alone. One's own rub is felt as it is predicted, not a round trip later | spec/touch.test.ts › a struck bike is over on the next frame and settled within about four |
| K14 | Running into the back of another bike: a nudge shoves it on, a hard hit knocks its rider off | PCM | built | adapted: nobody comes off. The recording has no clean rear-end between two bikes, and the manual only says rear-ending slow traffic is nearly as bad as a head-on. A first version knocked the rider in front off at 50 km/h faster, a rule of my own with no source, and 35 of 108 riders put down in ten AI races went that way. Now it is a collision of two bodies: momentum along the road is kept (bike and rider weights), 0.3 of the knock bounces, and the push goes through the line between the two, read on a bike's own proportions, so they part to either side, up to 5 m/s, and the faster goes by. The touch is felt by both (K13). Bikes are never drawn inside each other: the player's own is kept off the others after they move each frame as well as at each step | spec/touch.test.ts › run into from behind, however much faster, nobody comes off: momentum is kept, the two part to either side and the faster goes by (K14) |
Look
The first renderer here was drawn from nothing: a dusk sky, red-and-white kerbs, hand-drawn pixel riders, a web-page HUD. None of it came from the game, because the research behind the rows above was text only. These rows come from 137 screenshots of the PC and 3DO versions, measured in road-rash-visuals.md. Fractions are of the screen.
| ID | Mechanic (PC 1996) | Source | Status | Treatment | Due / proof |
|---|---|---|---|---|---|
| V1 | Real 3D world: texture-mapped polygons for road, hills, buildings, cliffs and tunnels, drawn to the horizon with no fog | YT1, A2023 | built | adapted: WebGL, with three.js. Road, ground, rock and sky are CC0 photographs (ambientCG, Poly Haven): the textures generated in code that this row first called for looked nowhere near the original. A haze from 500 m thickens to the range's colour at 1.75 km, where the land meets the painted panorama. No tunnels | judged: 6d5022d |
| V2 | Low chase camera dead behind the rider; rider about 9% of screen width and 22% of height, centred; horizon at .33–.38; the camera never rolls | YT1 | built | adapted: 6 m behind and 1.95 m up, trailing the bike sideways by 0.2 s and never by more than 1.5 m, and never rolling. Measured on the deployed game on 21 Oct, the rider and bike fill 11% of the width and 27% of the height at 1920×1080, centred, against the original's 9% and 22%: the rider modelled in 6d5022d came out larger than the one judged in b2cd232, and nobody re-measured it until then. At 390×844 the rider is 25% of the width and 17% of the height | judged: b2cd232 |
| V3 | 640×480, 4:3 | A2023 | built | adapted: the window's own shape, since both marking viewports are 16:9 or taller; a wider lens in portrait keeps the road in view, and the instrument panel keeps a 4:3 frame of its own | judged: b2cd232 |
| V4 | Low-resolution textures that break into big square texels near the camera | YT1 | omitted | omitted: the riders were drawn with nearest-neighbour filtering at first, about three screen pixels a texel up close with a stepped outline, and it read as a low resolution put on for show rather than as the original. Their frames are now blended between texels with a smooth outline; the game remakes how Road Rash plays, not its 1996 resolution | — |
| V5 | Riders are pre-rendered 3D sprites in bright two-colour leathers and full-face helmets; the whole bike leans up to 30–40° | YT1, TE, RRVID | built | adapted: pre-rendered sprites as the original's were, but of a rider puppet of my own design, posed for each frame the recording shows (riding hunched over the tank, a fist drawn back by the helmet then straight out, a club over the head then down, a leg out at peg height, thrown spread-eagled, lying, running back) and rendered from eight directions into one atlas with big square texels. Each rider's leathers, helmet and paint are tinted in at draw time. The first version posed a generic CC0 character, whose only clip was for driving a car, by twisting its bones at run time, and a punch came out as an arm jammed backwards from a body lying on the tank. The second built every limb as a separate stick with a ball at each joint, which read as a hinged doll; the third blended those sticks into one surface, still tubes with no shoulder, chest or calf. The body is now a modelled human (the CC0 character in the repo) skinned onto the puppet's joints and dressed in a modelled coverall and boots, so the suit has a thickness of its own over the body (painting the leathers on the bare body, even smoothed, left every muscle showing, and the feet bare), each limb's thickness and the shoulders' breadth set to what the recording measures across both colours of its two-tone sleeves and trouser legs (spec/body-shape.test.ts), the suit in the first colour and a yoke over the shoulders and upper back in the second, each a whole piece between two joints so the edge between them is clean (the recording's back panel and two-tone sleeves, cut by lines through the mesh, came out ragged at the atlas's size). Each helmet repeats the suit's second colour or is white or black, as racing kit is matched, and its stripe is the main colour; it is never the suit's own colour (spec/liveries.test.ts) |
spec/sprites.test.ts › draws a punch back to the shoulder, drives it out, and is at full stretch the moment it lands, on the side it is thrown |
| V6 | Only the closest opponent is named, in the HUD; no names float over riders | YT1 | built | same, closest as C1 has it | spec/ledger-rows.test.ts › names no opponent when no one is in reach, and draws the same panel on a phone (V6) |
| V7 | A black glossy fairing arch over the bottom quarter: cream MPH and RPM dials, the position in a black box, the odometer beneath, a red-yellow-green bar, and both riders' names with curved stamina wedges; the closest opponent's distance in red ↑ or green ↓ | YT1, PCM | built | same, on the measured fractions of a 4:3 frame centred on a wider screen; the speedometer reads km/h to 360. The phone gets the same panel over its touch controls | spec/ledger-rows.test.ts › shows position, odometer, both names and the closest opponent's distance, and no race clock (H1, T3) |
| V8 | Tall condensed white type for every name and number in the HUD | YT1 | built | same, in Oswald (SIL Open Font Licence), self-hosted | judged: b2cd232 |
| V9 | Purple-grey asphalt (#56505e), a double solid yellow centre line, white dashed lane lines, solid white edges, no kerbs or rumble strips | YT1 | built | same: an asphalt photograph multiplied towards the measured purple-grey, with the original's double yellow (#c0b04c), dashed lanes and solid edges painted over it | judged: 6d5022d |
| V10 | Brown dirt shoulders on rural roads, grey pavement in towns | YT1 | built | same, and sand on the coast and in the canyon | judged: 9aa3259 |
| V11 | A flat periwinkle sky (#94aefa) with hard-edged white cartoon clouds, the same on every track | YT1 | built | adapted: a CC0 photograph of a bright sky with scattered cumulus, in place of the flat periwinkle and cartoon clouds, which looked like an unfinished backdrop beside photographic ground | judged: 6d5022d |
| V12 | One silhouette per track: city canyons, coastal cliff and sea, snow peaks and pines, hazy vineyard hills, green rolling hills | YT1, TE, RRVID | built | adapted: one skyline per road and the country along it changing within a race: pine and snow peaks, a cliff on the left with the sea behind a rail on the right, fields and broad trees, a western main street, red canyon walls. Cliffs, walls and shopfronts stand where the bike is stopped (K12) | spec/terrain.test.ts › is never above the shoulder within it, on any road |
| V13 | Crashes play in the game view: the bike tumbles free, the rider lands, stands and walks back to it | YT1, TE | built | same, except that the rider runs back (K4) | spec/ledger-rows.test.ts › leaves a thrown rider lying in the road, then has them run back and ride on (K4) |
| V14 | The winner crosses the line sitting up with both arms raised | YT1 | built | same: the rider placed first sits up with both fists high and wide in a V over the helmet from the line on, as in pc-race-city-finish-arms-up-01. The race runs 2.5 s past the last person done so it is seen, and the road runs 400 m past the line for the camera to follow | spec/sprites.test.ts › has the winner cross the line sitting up with both arms raised, and anyone placed after ride on as they were |
| V15 | A swing throws an arm straight out sideways; a chain is raised above the helmet | YT1, APOST, RRVID | built | adapted: the poses are measured off single full-resolution frames of the recording (road-rash-feel.md, "Poses"): the rider rides hunched and sits up to strike; a fist or chain goes out dead straight to 3.4 helmet widths at shoulder height; a club is held up by the helmet; a kick is chambered bent and out for 6 frames before it straightens to 4.2. Each frame of the sprite puppet is projected and held to those numbers. A weapon is drawn as the recording's arm travels (247.2-248.0): rest, raised, drawn back, two frames on the sweep, out, and back down. A kick is not: it goes straight out from the bar through one frame halfway and lands 0.07 s after the key. A fist goes straight out from the bar and straight back through one and the same frame halfway (ride, halfway, out, halfway), out 0.12 s after the key, held out 0.22 s, the next punch 11 frames on as in the recording (91.90-92.62). It was loaded first, drawn down beside the bike and driven out through a strike frame of its own; the elbow swung round through those three poses and the arm read as cranked | spec/sprites.test.ts › every pose against the recording |
| V16 | Start: the picture darkened, a big white countdown in the road ahead; the finish is a chequered band across the road | YT1, A3DO | built | same: 3 s on the grid with nothing moving and a held throttle going on the same step as the field's (spec/start.test.ts › counts down before anyone moves, then launches a held throttle with the field), big white figures over the road, the picture held at about 60% brightness through the count and lifted over 0.4 s at the go, a white start line and a chequered band across the road at the finish |
spec/start.test.ts › darkens the picture to about 60% through the count and lifts it within half a second of the go |
| V17 | Traffic and police are texture-mapped box models: grey sedans, a yellow taxi, a black-and-white patrol car, a white police bike | YT1, A2023 | built | adapted: sedans, a yellow taxi and a pickup, modelled in code from extruded panels, and the white police bike. No patrol car: the police are the motorcycle cops alone (P2) | spec/traffic.test.ts › drives cars at 100-150 km/h, and puts no police cars on the road (T4, P2) |
| V18 | Menus in claymation caricature and a corkboard with a pinned photo postcard per track; orange-red condensed titles (#f05030), a yellow arrow cursor | A2023, APOST | built | adapted: the race sign-up is a cork board with the road picked in orange-red condensed titles (#f05030, Oswald) over a line about it written by me, its length, and a postcard of it pinned at the top right with a red pushpin, as in pc-menu-bulletin-city-02. The five postcards are photographs of each road taken in this game while riding it (scripts/postcards.ts); drawn first as SVG colour fields, they showed nothing of what a road looks like. The road picked carries the yellow arrow and turns yellow. No claymation, which I cannot make |
spec/people.test.ts › pins a photograph of each road, taken in the game, and names its length |
| V19 | Race end: a spiked "WINNER" star, then a still with the finishing place | YT2 | built | adapted: with H4, drawn rather than filmed. The result screen opens on a spiked star, burst in from small and turned, with the race's word across a dark band: WINNER! for the one who won, otherwise Qualified, Placed, Wrecked or Busted, orange for a finish and steel blue for a wreck or a bust. The still's line follows under it, "Ana finished in First Place.", as in pc-end-winner-02. With reduced motion it simply appears | spec/people.test.ts › puts WINNER on the star for the one who won, the way the race ended for anyone else, and their place in words under it |