Ridge Racer
Namco's racing game, the PlayStation's launch-day port of its 1993 arcade game, read through kazuyette's decompilation of the Japanese release.
On this page
Ridge Racer is Namco’s 1993 arcade racing game, ported to the PlayStation for its Japanese launch on 3 December 1994. The atlas reads it through kazuyette’s rr-decomp, C for every game function that builds the Japanese release’s executable (SLPS-00001) byte for byte, so each claim names that release. Most functions are still named by address, and each file declares its own structs, so the claims cite a car’s fields by offset. The README says the work is heavily AI-assisted. Nothing has been measured in the game yet.
#The power slide
A car is in one of four states, and the slide is the second. In grip, the car moves only along its heading: the code drops the sideways part of its velocity each update1. A car gets in two ways. One is to lift off the accelerator and press it again: the updates spent off it, times the speed, must beat the car’s threshold. The other is to tap the brake with the accelerator off, while the car is moving sideways2. Whichever product started the slide becomes its budget.
The slide spends that budget. The heading turns at up to 54/4096 of a turn per update3, the steering feeding the turn, while the budget drains faster at wide angles, with the brake held, and at low speed. Once it’s gone, the turn dies away and the slide ends3. Ending it costs speed by the angle left between heading and travel: a slide that ends at 45° keeps 75% at 45°4 of its speed, and the speed taken off fades out along the old line over the next updates4. During the slide the engine pushes at an eighth of its grip strength, scaled down to nothing at 45° of slip, but the car keeps far more of its speed each update5. The exit code only lowers the speed, so the atlas has found no boost at the end of a slide4.
#The start
The player’s car starts the race in its fourth state, wheelspin. When the grid phase ends and the race starts, the game reads the tachometer: the further the revs are from 7500, the longer the wheelspin lasts, and revs above 7500 count six times as much. While it lasts the car covers a quarter of the ground its speed would carry it. With the accelerator held, it ends after 4 updates from 7500 and 61 from the rev counter’s top of 100006. That makes it a rocket-start with no boost, only a shorter penalty.
#The other cars
The computer car in slot 0 is rubber-banded by laps and by distance. On an earlier lap than the player, or behind by more than a margin, it aims at 1.01 times its field 0x10C; on a later lap, or more than 0x600 track units ahead, it aims at 80% of the lower of its usual target and its field 0xF8. On the last lap, unless a flag the atlas hasn’t identified is set, the cap holds it either way7.
#Laps and the clock
A lap is timed in race updates and shown in milliseconds as if 30 updates made a second. When a lap ends, the game adds a random 0 to 31 ms to it before comparing it with the course’s best, filling in digits the count can’t resolve. Backing over the line and crossing again doesn’t count8. The race clock counts down in the same updates. Each new lap adds time, as do one or two checkpoints when the course is run in its usual direction. Below 30 the pad is ignored, and below −59 the race is over9.
Mechanics
| Mechanic | Kind | How |
|---|---|---|
| Rocket start | Rev target | with the accelerator held, the start's wheelspin lasts 4 updates when the tachometer reads 7500 as the race starts, and 61 when it reads 10000 |
| Rubber-band AI | Speed step | behind the player, the car in slot 0 aims at 1.01 times its field 0x10C; well ahead, at 80% of the lower of its usual target and its field 0xF8 |
| Drift boost | None | the slide gives no boost: its end only takes speed off, more the wider the angle between heading and travel |
Every claim about this game, by concept (9)
References
- ^In Ridge Racer's Japanese release (SLPS-00001),
car_simulate(func_80019CF4) runs one of four handlers each update by the car's state at offset 0xB4: 0 func_80026E7C, 1 func_80027734, 2 func_80027F60, 3 func_80028294, which the atlas reads as grip, slide, slide recovery, and the start. In state 0 the heading turns a fifth of the way to the steering's target each update, and the car moves only along its heading: the code keeps the forward part of its velocity and drops the sideways part.Codekazuyette/rr-decompHow we know
204 if (D_801D9060 != 1) { 205 switch (q->type) { 206 case 0: func_80026E7C(car); break; 207 case 1: func_80027734(car); break; 208 case 2: func_80027F60(car); break; 209 case 3: func_80028294(car); break;
src/fn/func_80019CF4.c lines 204–211 at 3b42b36 · upstream ↗ 23 car->ang += func_80019CA8(car->ang, car->u.c.steer) / 5; ⋮ 29 v.vx = (c * car->u.c.vx - s * car->u.c.vz) / 4096; 30 v.vz = (s * car->u.c.vx + c * car->u.c.vz) / 4096; 31 car->u.c.vx = s * v.vz / 4096; 32 car->u.c.vz = c * v.vz / 4096;
src/fn/func_80026E7C.c lines 23–32 at 3b42b36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^In Ridge Racer's Japanese release (SLPS-00001), a car in grip (state 0, func_80026E7C) enters a slide (state 1) in two ways. Pressing the accelerator again after lifting off: the code counts the updates the accelerator stays below half (0x80) without a fresh brake press, and on the update the accelerator is pressed again it multiplies the count by the car's speed; a speed above 960 and a product above the car's threshold start the slide. Or a fresh brake press with the accelerator off: the car's sideways velocity times its speed over 64, above the threshold at a speed above 320. The threshold is 14 times a value from the car model's spec table. The product that started the slide becomes the slide's budget (
D_801732F0), and the car's yaw rate (D_8012CFE0) is set against its sideways velocity: at least twice it on the accelerator, once on the brake.Codekazuyette/rr-decompHow we know
33 if (car->u.c.c4 == 1) { 34 t = car->u.c.spd * D_8007B1F0; 35 D_8007B1F0 = 0; 36 D_801732F0 = t; 37 if (car->u.c.spd > 960 && car->u.c.lim < t) { 38 car->u.c.slide = 1; 39 r = 1000 - (car->u.c.x98 - 1000) * 8; 40 if (r < 1000) 41 r = 1000; 42 D_8012CFE0 = -v.vx * r / 1000 * 2; ⋮ 45 } else if (car->u.c.grip < 0x80) { 46 n = car->u.c.c6; ⋮
src/fn/func_80026E7C.c lines 33–61 at 3b42b36 · upstream ↗ 41 if (D_801D9060 != 4 && D_8012CD20 >= 30) { 42 if (D_801D35A8.id == 0x41) { 43 car->u.c.C8 = ((D_801D35A8.btn & D_801D7778[2]) != 0) << 8; 44 car->u.c.CA = ((D_801D35A8.btn & D_801D7778[3]) != 0) << 8;
src/fn/func_80019CF4.c lines 41–44 at 3b42b36 · upstream ↗ 91 if (q->h6C == 0) { 92 if (q->g70 >= 0x85) 93 q->h6C = 1; 94 } else if (q->h6C == 1) 95 q->h6C = 2; 96 else if (q->g70 < 0x7C) 97 q->h6C = 0;
src/fn/func_80019CF4.c lines 91–97 at 3b42b36 · upstream ↗ 162 if (D_801D9060 >= 2) { 163 if (q->h60 == 0) 164 s0 += q->rpm / 256; 165 s2 = x * q->g70 / 256; 166 s0 += q->g72 * q->rpm / 256 / 32;
src/fn/func_80019CF4.c lines 162–166 at 3b42b36 · upstream ↗ 91 q->x3C = sp->h4 * 14;src/fn/func_8001AA60.c line 91 at 3b42b36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^ abIn Ridge Racer's Japanese release (SLPS-00001), a car in a slide (state 1, func_80027734) turns its heading by its yaw rate over 256 each update, with the yaw rate held within ±0x3600, so at most 54 of the 4,096 units of a full turn (computed: about 4.7°). While the slide's budget is above 0, a term from Phys 0x54 (
w54), which the atlas reads as the steering target, adds to the yaw rate and the budget drains each update by 0x40, by the square of the slip angle (heading against direction of travel) over 65,536, by (0x3600 − |yaw rate|)/64, and by 4 times the brake value, with more drained below a speed of 400, below half the car's spec speed, or at a slip under 0x80 with a slow yaw. Once the budget is spent, the yaw rate falls to 15/16 each update, and the slide ends on the first update it starts below 0x1000.Codekazuyette/rr-decomprevisedHow we know
34 a = D_8012CFE0 < 0 ? -D_8012CFE0 : D_8012CFE0; ⋮ 40 if (d < 0x80 && a < 0x800) 41 D_801732F0 -= (0x800 - a) * 4000 / 256; 42 if (q->spd < 400) 43 D_801732F0 -= (400 - q->spd) * 100; 44 if (D_801732F0 > 0) { 45 d = func_80019CA8(car->ang, q->w54) * 98 / 100; 46 d = d * (D_80173358 + 0x800) / 2048; 47 D_8012CFE0 += d * 16; ⋮ 55 if (D_8012CFE0 > 0x3600) 56 D_8012CFE0 = 0x3600; 57 if (D_8012CFE0 < -0x3600) ⋮
src/fn/func_80027734.c lines 34–69 at 3b42b36 · upstream ↗ 8 temp_v1 = arg0 & 0xFFF; 9 temp_a0 = arg1 & 0xFFF; ⋮ 15 if (var_a0 >= 0x801) { 16 var_a0 = 0x1000 - var_a0; ⋮ 18 return var_a0;
src/fn/func_80019C6C.c lines 8–18 at 3b42b36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
- ^ abcIn Ridge Racer's Japanese release (SLPS-00001), when a slide ends (func_80027734) the car's direction of travel snaps to its heading and its speed is multiplied by 1 − w²/2²⁰, where w is the slip angle between them folded to at most a quarter turn: a slide that ends at 45° keeps 75% of its speed and one at 90° keeps none (computed). The part taken off keeps moving the car along its old direction in state 2 (func_80027F60), shrinking to 31/32 each update with the leftover angle, and the car returns to grip (state 0) when both reach 0.Codekazuyette/rr-decomp
How we know
71 D_801D7E30 = t = func_80019CA8(q->dir, car->ang); 72 D_80173438 = q->dir; 73 q->dir = car->ang; 74 w = t < 0 ? -t : t; 75 if (w > 0x400) 76 w = 0x800 - w; 77 w = w * w; 78 D_8007C4E8 = w * q->spd / 0x100000; 79 q->spd = (0x100000 - w) * q->spd / 0x100000; 80 q->w5C = 2;
src/fn/func_80027734.c lines 71–80 at 3b42b36 · upstream ↗ 26 car->u.c.vx = func_80044D0C(car->u.c.dir + D_801D7E30) * car->u.c.spd / 256; ⋮ 30 car->u.c.vx = func_80044D0C(D_80173438) * D_8007C4E8 / 256 + s * v.vz / 4096; ⋮ 38 D_8007C4E8 = D_8007C4E8 * 31 / 32; 39 D_801D7E30 = D_801D7E30 * 31 / 32; 40 if (D_8007C4E8 == 0 && D_801D7E30 == 0) 41 q->slide = 0;
src/fn/func_80027F60.c lines 26–41 at 3b42b36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^In Ridge Racer's Japanese release (SLPS-00001),
car_simulategives a car in a slide (state 1) an eighth of the engine drive it gets in the other states, and lets its speed fall by 0.4% an update instead of 6%. The slide handler (func_80027734) then scales that drive by (0x200 − w)/0x200 for a slip angle w up to a quarter turn: full drive with no slip, none at 45°, and a pull against the motion beyond (computed). func_80026CA8 adds the drive along the heading, but the slide handler saves the direction of travel before the call and restores it after, so in a slide the drive changes only the speed.Codekazuyette/rr-decomprevisedHow we know
191 q->w58 = q->rpm * e->a; 192 if (q->type == 1) { 193 q->w4C = q->w58 / 256 / 32 / 128; 194 q->spd = q->spd * 996 / 1000; 195 } else { 196 q->w4C = q->w58 / 256 / 32 / 16; 197 q->spd = q->spd * 94 / 100;
src/fn/func_80019CF4.c lines 191–198 at 3b42b36 · upstream ↗ 85 d = func_80019C6C(car->ang, q->dir); 86 if (d > 0x400) 87 q->w4C = q->w4C / 2 + (u = (0x3600 - a) * 4) * q->w4C * (d - 0x400) / 1024 / 0x3600; 88 else 89 q->w4C = (0x200 - d) * q->w4C / 512; 90 d = q->dir; 91 func_80026CA8(car);
src/fn/func_80027734.c lines 85–91 at 3b42b36 · upstream ↗ 12 v.vx = (func_80044D0C(p->b) * p->r) / 4 + func_80044D0C(p->a) * p->d; ⋮ 15 p->r = func_80040B54(p->r * p->r + p->d * p->d + (p->r * 2 * p->d * (t / 4096)) / 4096) >> 6; 16 p->b = 0x400 - func_800187A0(v.vx, v.vz);
src/fn/func_80026CA8.c lines 12–16 at 3b42b36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
- ^In Ridge Racer's Japanese release (SLPS-00001), the player's car starts a race in state 3 (func_80028294). When the grid phase ends at race update 211 and the race begins, func_8001B284 reads the rev counter shown on the tachometer (
D_801D7800, the car's revs smoothed and held between 500 and 10000) and sets a counter to 1000 plus its distance below 7500, or 1000 plus six times its distance above 7500, in which case it also halves the engine field at car offset 0xB0. In state 3 the car moves a quarter of what its speed would carry it, and the counter falls each update by the accelerator plus the brake plus 8; at 10 or below the car goes to grip (state 0). With the accelerator held on a digital pad (0x100), revs of 7500 give 4 updates of this, 5000 give 14, and 10000 give 61 (computed).Codekazuyette/rr-decompHow we know
65 q->x5C = 3;src/fn/func_8001AA60.c line 65 at 3b42b36 · upstream ↗ 130 case 1: 131 if (D_80173310 >= 211) { 132 func_8001B284(p); 133 D_801D9060 = 2;
src/fn/func_80014C2C.c lines 130–134 at 3b42b36 · upstream ↗ 10 temp_a1 = D_801D7800 - 0x1D4C; 11 if (temp_a1 < 0) { 12 var_a1 = -temp_a1; 13 } else { 14 var_a1 = temp_a1 * 6; 15 M2C_FIELD(arg0, s32 *, 0xB0) = (s32) ((s32) M2C_FIELD(arg0, s32 *, 0xB0) / 2); ⋮ 17 D_8012CFF0 = var_a1 + 0x3E8;
src/fn/func_8001B284.c lines 10–17 at 3b42b36 · upstream ↗ 31 D_801D7800 += (D_8007C2DC - D_801D7800) / 4; 32 if (D_801D7800 > 10000) 33 D_801D7800 = 10000; 34 if (D_801D7800 < 500) 35 D_801D7800 = 500;
src/fn/func_8001B0CC.c lines 31–35 at 3b42b36 · upstream ↗ 27 car->u.c.vx = func_80044D0C(car->u.c.dir) * car->u.c.spd / 256; ⋮ 31 car->u.c.vx = s * v.vz / 4096 / 4; 32 car->u.c.vz = c * v.vz / 4096 / 4; 33 if (D_8012CFF0 > 10) { 34 D_8012CFF0 -= car->u.c.wear; 35 w = car->u.c.grip + 8; 36 D_8012CFF0 -= w; 37 if (D_8012CFF0 <= 0) 38 car->u.c.slide = 0; ⋮ 40 } else { 41 car->u.c.slide = 0;
src/fn/func_80028294.c lines 27–41 at 3b42b36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^In Ridge Racer's Japanese release (SLPS-00001), the computer car in entity slot 0 takes its target speed from func_80022C40 during the race (when its field 0x60 is 0 and the game state isn't 0x1A). Unless its mode field 0xAA is 2: when it's on an earlier lap than the player, or on the same lap and behind the player by more than a margin, its target is 1.01 times its field 0x10C; when it's on a later lap, or more than 0x600 ahead on the same lap, its target is 80% of the lower of the usual target and its field 0xF8. The margin is 0x800, or 0x300 times the player's lap count when
D_801D35D0is 0. Between the two the target is left as it was. WhenD_801D35D0is 0 and the player is on the last lap, the target is held to field 0xF8.Codekazuyette/rr-decompHow we know
10 if (car->hAA != 2) { 11 lim = 0x800; 12 if (D_801D35D0 == 0) 13 lim = D_8007C32C * 3 * 256; 14 if ((car->lap == D_8007C32C && lim < car->dist) || car->lap < D_8007C32C) { 15 *spd = car->x10C / 100 + car->x10C; 16 *acc = car->FC; 17 } else if ((car->lap == D_8007C32C && car->dist < -0x600) || D_8007C32C < car->lap) { 18 v = *spd; 19 if (car->F8 < v) 20 v = car->F8; 21 *spd = v * 8 / 10; ⋮
src/fn/func_80022C40.c lines 10–27 at 3b42b36 · upstream ↗ 40 if (D_801D35D0 == 0) { 41 n = 3; 42 if (D_8007C210 == 1) 43 n = 2; 44 if (D_8007C32C == n) { 45 if (*spd > car->F8) { 46 if ((*spd = car->F8) < car->x88)
src/fn/func_80022C40.c lines 40–46 at 3b42b36 · upstream ↗ 101 if (D_801D34F8 != 0x1A && car == &D_801E9250[0]) { 102 acc = s->wA4; 103 if (s->w60 == 0) 104 func_80022C40(car, &spd, &acc);
src/fn/func_80022F88.c lines 101–104 at 3b42b36 · upstream ↗ 70 if (D_801D77B8 == 0) { 71 d = car->pos - D_8007C260; 72 if (d >= 0) 73 d = d >= half ? d - len : d; 74 else 75 d = half >= -d ? d : len + d; 76 car->E0 = d;
src/fn/func_800217F4.c lines 70–76 at 3b42b36 · upstream ↗ 47 if (D_801D77B8 == 0) { 48 if ((((D_801E90E0 << 16) + c->w8) % (D_801E90E0 << 8) & ~0xFF) == 0x2700 49 && (((D_801E90E0 << 16) + c->w84) % (D_801E90E0 << 8) & ~0xFF) == 0x2800) c->h9C++;
src/fn/func_80025268.c lines 47–49 at 3b42b36 · upstream ↗ 87 D_801D35A0 = 3; ⋮ 93 if (D_8007C210 == 1) 94 D_801D35A0--;
src/fn/func_8001384C.c lines 87–94 at 3b42b36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^In Ridge Racer's Japanese release (SLPS-00001), a lap's time is counted in race updates and converted to milliseconds as if 30 updates were a second: whole seconds times 1000, plus the remaining updates times 100/3. When the player crosses the line from the race direction, the finished lap gets a random 0 to 31 ms added (
rand() & 0x1F) before it's compared with the course's best lap. Backing over the line and crossing again doesn't count a lap: the code counts each backward crossing and spends one on the next forward one. The race time is the sum of the laps.Codekazuyette/rr-decompHow we know
3s32 func_8001FBC0(s32 arg0, s32 arg1) { 4 return ((arg0 / 30) * 0x3E8) + (((s32) ((arg0 % 30) * 0x64) / 3) + arg1);
src/fn/func_8001FBC0.c lines 3–4 at 3b42b36 · upstream ↗ 170 case 3: 171 D_8012CD20--; 172 f = p->lap; 173 if (f > 0) { 174 f--; 175 p->u[f] = func_8001FBC0(++p->t[f], 0);
src/fn/func_80014C2C.c lines 170–177 at 3b42b36 · upstream ↗ 20 if (SEC(c->pos) == D_8012CDA0 && SEC(c->prev) == dir + D_8012CDA0) { 21 if (c->back > 0) { 22 c->back--; 23 } else { ⋮ 25 if (c->lap > 0) { 26 c->laps[c->lap - 1] += rand() & 0x1F; 27 if (c->laps[c->lap - 1] < D_801D7628[D_8012D088][D_801733B8][D_8007C210 - 1]) { ⋮ 40 else ⋮ 44 } else if (SEC(c->pos) == dir + D_8012CDA0 && SEC(c->prev) == D_8012CDA0) { 45 c->back++;
src/fn/func_80013D40.c lines 20–45 at 3b42b36 · upstream ↗ 31 if (c->lap > D_801D35A0) { 32 t = 0; 33 for (i = 0; i < D_801D35A0; i++) 34 t += c->laps[i]; 35 D_801D77C8 = t; 36 if (t < D_8012CD38[D_8012D088][D_801733B8][D_8007C210 - 1]) 37 D_8012CD38[D_8012D088][D_801733B8][D_8007C210 - 1] = t;
src/fn/func_8001483C.c lines 31–37 at 3b42b36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^In Ridge Racer's Japanese release (SLPS-00001), the race clock (
D_8012CD20) starts at the course's row of a table (D_8005E90C) times 30 and falls by 1 each race update in phases 2 and 3. Each row also holds a lap bonus and two checkpoint bonuses. Crossing the line to start laps 2 up to the last adds the lap bonus times 30 (another field whenD_801733B8is set). On the course run in its usual direction (D_801733B8clear), crossing the first checkpoint adds the first checkpoint bonus times 30, and on courses 3 and up a second checkpoint adds the second bonus times 30; backing over a checkpoint and crossing again pays once. While the clock is below 30 the pad is ignored and the car gets no accelerator or brake. Below −59, before the results, the race ends as over.Codekazuyette/rr-decomprevisedHow we know
88 if (D_801733B8) 89 D_8012CD20 = D_8005E90C[D_8007C210 - 1].h8 * 30; 90 else 91 D_8012CD20 = D_8005E90C[D_8007C210 - 1].h0 * 30;
src/fn/func_8001384C.c lines 88–91 at 3b42b36 · upstream ↗ 35 c->lap++; 36 if (c->lap >= 2 && c->lap <= D_801D35A0) { 37 D_8012CF58 = 150; 38 if (D_801733B8) 39 D_8012CD20 += D_8005E90C[D_8007C210 - 1].b * 30; 40 else 41 D_8012CD20 += D_8005E90C[D_8007C210 - 1].a * 30;
src/fn/func_80013D40.c lines 35–41 at 3b42b36 · upstream ↗ 61 if (D_801733B8 == 0) { 62 func_800140A4(c); 63 if (D_8007C210 >= 3) 64 func_80014280(c);
src/fn/func_8001483C.c lines 61–65 at 3b42b36 · upstream ↗ 16 if (SEC(p->pos) == D_801734B8 && SEC(p->prev) == D_801734B8 + 0x100) { 17 if (p->cnt > 0) { 18 p->cnt--; 19 } else { 20 D_8012CF58 = 150; 21 D_8012CD20 += D_8005E910[D_8007C210 - 1].bonus * 30; ⋮ 23 } else if (SEC(p->pos) == D_801734B8 + 0x100 && SEC(p->prev) == D_801734B8) { 24 p->cnt++;
src/fn/func_800140A4.c lines 16–24 at 3b42b36 · upstream ↗ 16 if (SEC(p->pos) == D_801734C0 && SEC(p->prev) == D_801734C0 + 0x100) { ⋮ 21 D_8012CD20 += D_8005E910[D_8007C210 - 1].bonus * 30;
src/fn/func_80014280.c lines 16–21 at 3b42b36 · upstream ↗ 215 if (D_801D9060 < 5 && D_8012CD20 < -59) { ⋮ 220 D_801D9060 = D_801D9060 == 2 ? 6 : 5;
src/fn/func_80014C2C.c lines 215–220 at 3b42b36 · upstream ↗ 41 if (D_801D9060 != 4 && D_8012CD20 >= 30) { ⋮ 76 } else { 77 car->u.c.CA = 0; 78 car->u.c.C8 = 0; 79 D_8007B1F8 = 0x100; ⋮ 81 } else { 82 car->u.c.CA = 0; 83 car->u.c.C8 = 0; 84 D_8007B1F8 = 0x100;
src/fn/func_80019CF4.c lines 41–85 at 3b42b36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
Sources
Code
- kazuyette. 2026. “Ridge Racer decompilation (kazuyette/rr-decomp).” Commit 3b42b36. kazuyette/rr-decomp @ 3b42b36 · licence, all uses