wr64-decomp

Wave Race 64 turned back into C that compiles, with Nintendo’s own compiler, to the exact same ROM.

install
make toolchain && make init   # with your own US Rev 1 ROM as baserom.us.rev1.z64
wr64-decomp — lead screenshot
status
live 1,302 of 1,348 functions matched (96.6%)
stack
C / IDO 5.3 / splat / MIPS binutils / Python
source
github.com/nickallevato/wr64-decomp ↗
links
build steps ↗ · FORK.md, the milestones ↗ · upstream: LLONSIT/Wave-Race-64 ↗
since

What it is

Wave Race 64 shipped in 1996 as a compiled MIPS binary. This turns the binary back into C source, and that source, compiled with the same compiler Nintendo used (IDO 5.3), produces the same ROM down to the last byte. Every build ends with a SHA-1 check against the cartridge, so one wrong instruction fails it.

It’s a fork of LLONSIT/Wave-Race-64, which did the groundwork: the ROM split, the build system and the first nine hundred or so functions. This fork is written with Claude, and upstream doesn’t take AI-generated code, so it runs independently and nothing goes back.

Where it stands

AreaWhat’s in itMatched
libultraNintendo’s N64 OS library157 / 157
otherhandwritten assembly, loose segments55 / 55
audiosequence and sound playback227 / 228
overlayscourses and menu screens148 / 151
codesegHUD, menus, text, popups, fades210 / 219
sysboot, threads, memory35 / 37
gamerace logic, riders, camera, water470 / 501
total1,302 / 1,348

The functions that don’t match yet keep a readable C attempt beside the assembly, with a note on what still differs. make NON_MATCHING=1 builds with those, so most of the game can already be read and changed as C. The ROM differs then, which is expected.

What it’s for

A matching tree is the floor everything else stands on: how the water simulation really works, bug fixes, a native port, and mods well past what patching a binary allows. The one I want is in 64 riders in Wave Race 64, which stopped short of growing the game’s four-rider arrays from the inside because the decomp wasn’t far enough along.

After the bytes comes the half of the job the hash can’t judge: names, structs, documentation. The hash will say when the bytes are right. Nothing will say when the names are. That argument is the bytes don’t remember the names.

You need your own copy of the game, US Rev 1, .z64. It isn’t in the repo and never will be.

writing about it

2