Beetle Adventure Racing! Recomp
Beetle Adventure Racing! Recomp brings Beetle Adventure Racing! to PC.
- Type: PC port
- Game: Beetle Adventure Racing!
- Runs on Windows
- By danielgomesvieira2000
- Latest release v0.4.2-alpha, 2026-09-20
- Source: https://github.com/danielgomesvieira2000/beetle-adventure-racing-recomp
README
beetle-adventure-racing-recomp
A work-in-progress native PC port of Beetle Adventure Racing! (N64, USA) built by static recompilation with the [N64Recomp][N64Recomp] toolchain — the same approach behind Zelda 64: Recompiled.
Status (2026-09-07): playable. Boots through the intros and menus into races and renders at 60 fps, with keyboard + gamepad input and audio working. Ships the RecompFrontend launcher / settings / input binding / pause menu, widescreen with a HUD that expands with the aspect ratio, a selectable 1x / 2x / 4x draw distance, internal-resolution scaling (defaults to display-native), MSAA + a VI "divot" seam filter, and high-FPS interpolation (phase 1). A handful of polish items remain — see docs/TODO.md for the roadmap and docs/STATUS.md to resume. The reverse-engineering and porting reference is docs/technical/.
Current release: v0.4.1-alpha (Windows x64) — Mount Mayhem's fog restored and a Metro Madness view glitch fixed, on top of 0.4.0's multiplayer. Get it from the releases page. A Linux build is in progress (it compiles, but crashes during boot; see docs/KNOWN_ISSUES.md).
No game data is included. You must supply your own legally-dumped USA ROM (SHA-1
e5ab4d226c08d22f68a2edcc48870203e67454b8). No ROM, assets, or other copyrighted material may ever be committed to this repo.
Lineage, and how this is built
This repository continues an existing, in-progress port: the original recomp work is bryankruman/BeetleRecomp, which got the game booting, rendering, taking input and playing audio, along with the in-app launcher, settings and cheats menus. None of that groundwork is mine. This repo picks that up and carries it forward as a standalone project.
The continued work is vibe coded with Claude Code. That is a
plain description of the process rather than a disclaimer: the features added here — widescreen, the
HUD that anchors to the widened frame, the extended draw distance and the matching culling fix — were
designed, measured, written, tested and documented in conversation with Claude Code, driven by
in-game testing and by the diagnostics the port carries (BAR_DBG_*, headless scripted runs and
screenshots). The commits carry a Co-Authored-By: Claude trailer where that is the case.
Two consequences worth stating plainly, because they affect how you should read this repo:
- The documentation in
docs/is the real artefact. Findings, measurements and dead ends are written down as they are made — including the negative results, which are the expensive part. If you want to know why something is the way it is,docs/will usually tell you, in more detail than is normal for a hobby port. The curated reference distilled out of it is docs/technical/ — see below. - It is tested by playing it. Rendering changes are checked in a running game, not only in captured frames; several defects here were only ever visible in motion.
What this is
Static recompilation translates the N64's MIPS machine code into C automatically, then links it against a modern runtime (CPU via [librecomp], graphics via [RT64], OS/audio/input via [ultramodern]). It is not a manual rewrite and does not require a finished decompilation.
This port is a sibling to the BeetleDecomp decompilation. The decomp is not a prerequisite for the recomp, but it is the source of the symbol-rich ELF and the module/relocation metadata the recompiler consumes — which is what makes this port tractable.
Technical documentation
docs/technical/ is a published reverse-engineering and porting
reference for this game. It exists because the expensive part of a project like this is not the
code — it is knowing what the ROM contains, which of the game's mechanisms produce which pixels, and
which plausible-looking approaches quietly do nothing. All of that was measured here, and leaving it
in commit messages and scratch notes would waste it.
It is written for two audiences:
- People who want to decompile Beetle Adventure Racing — the ROM and memory layout, Paradigm's "UV" engine, the ~133 relocatable modules and how they are loaded, the toolchain (IDO 5.3, splat, WSL), and the three-phase matching strategy with the permuter economics behind it.
- People who want to build their own PC port — of this game or another N64 title. The static recompilation pipeline is documented end to end, including the parts that are in nobody's tutorial: overlay registration for a module-based game, codegen fixups and why they must verify themselves, hardware-register stubs that are not really stubs, cooperative scheduling and audio starvation, joybus-level Controller Pak emulation, and the renderer work needed to make a 320×240 overscan-inset game look right on a modern display.
| Chapter | Covers |
|---|---|
| 01 — The game and the ROM | Cartridge facts, memory map, entry point, save hardware, microcode, the frame clock, the screen-state globals |
| 02 — The UV engine and the module system | Export tables, the 133 relocatable modules, ModuleCommInfo, the loader, the two coordinate systems and two scissor paths |
| 03 — Decompiling BAR | Toolchain, the module build, the match/scribe/name strategy, permuter economics, exactly what the recomp takes from the decomp |
| 04 — Static recompilation | N64Recomp config, section/overlay tables, the overlay bridge, hardware stubs, the RSP audio ucode |
| 05 — The runtime host | librecomp/ultramodern/RT64 wiring, cooperative preemption, audio, the low-level SI/PIF input path, Controller Pak |
| 06 — Graphics | The gfx manager, the overscan inset, the frustum BAR culls against, widescreen, HUD anchoring |
| 07 — Codegen fixups and MIPS patches | Every fix-recompiled.sh rule and why it exists; the RECOMP_PATCH pipeline and the linker trap it hides |
| 08 — Diagnostics and methodology | The BAR_* diagnostic surface, headless scripted runs, screenshot capture, how measurements are taken |
| 09 — Porting playbook | Generalised: the order to do this in, the traps ranked by cost, what to build before you need it |
Three conventions run through all of it, and they are the point rather than a style choice: every number names the switch that produced it, negative results are kept (a refuted hypothesis that gets deleted is one someone pays for again), and inference from unmatched assembly is labelled as inference rather than stated as fact.
The reference is a living document: it is updated in the same change as the code it describes,
and docs/technical/README.md carries the mapping from each source area
to the chapter that owns it. The chronological working notes it distils — current state, roadmap and
live bug reports — remain in docs/ alongside it.
Relationship to the decomp
This repo carries a copy of the BeetleDecomp
project at lib/bar-decomp. Two things are worth knowing up front:
The recomp does not compile the decomp's C. Static recompilation translates the original ROM's MIPS machine code into C automatically; the decomp's hand-written C is never built into the port. What the port takes from the decomp is:
| From the decomp | What for |
|---|---|
| The symbol-rich ELF that rebuilds the ROM byte-for-byte | Input to N64Recomp (built in WSL, never committed) |
| Headers + symbol tables | Readable names + typed interfaces for generated code and patches |
| Segmentation / module + reloc layout | Overlay handling for BAR's ~130 relocatable modules |
Because the decomp is byte-matching, its matching progress doesn't change the port — recompiling a function yields identical output whether it started as hand-written C or raw asm. What flows downstream from decomp work is better names and types (readability of generated code and patches) and the module layout that makes the port tractable.
Changes never go in the decomp — keep it a faithful mirror of the original. Modifications live in two recomp-owned layers:
patches/— C cross-compiled to MIPS that overrides (RECOMP_PATCH) or hooks (RECOMP_HOOK) game functions by name. This is the game-logic layer: bug fixes, widescreen, new features. Patches link before the recompiled output, so they win.src/— the native C++ host: rendering (RT64), input, audio, saves, config, and the in-app UI.
See BUILDING.md for how the ELF is produced and how to pull decomp updates.
Technical profile
The properties that made BAR a good recomp candidate, and which shape the runtime:
| Aspect | Detail |
|---|---|
| Graphics microcode | Stock gspF3DEX2_fifo (decomp gfx_ucode: f3dex2) — not a custom Paradigm ucode. RT64 supports F3DEX2 directly. |
| Audio | Standard libultra (alAudioFrame/alSeqFileNew/ALSndPlayer) wrapped in Paradigm's "UV" middleware. |
| Saves | Controller Pak only (osPfs*); no EEPROM/SRAM/Flash. The port emulates a Controller Pak. |
| Memory | 4 MB; no Expansion Pak, no TLB-mapped code (flat KSEG0). |
| Entry point | 0x80000400 (ROM header offset 0x8 == splat entry segment vram). |
| Module layout | The ~130 relocatable code modules (ai, battle, race, …, uv*_rom) were the crux of the port; the uv module overlay bridge (src/main/overlay_bridge.cpp) registers them at load. |
The toolchain license analysis and research sources are in THIRD_PARTY_NOTICES.md.
How it fits together
your ROM ─┐
├─► BeetleDecomp (WSL) ──► symbol-rich ELF ──► N64Recomp ──► RecompiledFuncs/*.c ─┐
recomp.ld ┘ (per-module layout) (beetle-adventure-racing-recomp.toml) ├─► CMake ─► beetle-adventure-racing-recomp(.exe)
│
patches/*.c ─► clang -target mips ─► patches.elf ─► N64Recomp (patches.toml) ─► RecompiledPatches/*.c ┘
│
runtime: librecomp + ultramodern + RT64 ───────┘
Repository layout
beetle-adventure-racing-recomp/
├── beetle-adventure-racing-recomp.toml # main N64Recomp config (entrypoint 0x80000400, ELF, overlays)
├── patches.toml # config for the C patches (MIPS override/hook layer)
├── overlays.us.txt # relocatable module/overlay section list
├── CMakeLists.txt # host-app build (clang-cl + Ninja)
├── COPYING # AGPL-3.0 (inherited from the decomp)
├── THIRD_PARTY_NOTICES.md # dependency licenses + research sources
├── BUILDING.md # full build instructions (Windows + Linux/macOS)
├── docs/ # STATUS.md (resume guide), TODO.md (roadmap), investigation notes
│ └── technical/ # the published RE + porting reference (start at its README.md)
├── src/
│ ├── main/ # native host: RT64 render context, input, audio, overlay bridge, config
│ ├── game/ # game-facing config schema (graphics.json)
│ └── frontend/ # RecompFrontend glue: launcher menus, config tabs, input forwarding
├── patches/ # C compiled to MIPS that overrides/hooks game functions
├── include/ # port headers
├── rsp/ # RSP microcode glue
├── scripts/ # setup / fetch-elf / gen-overlays / fix-recompiled helpers
├── assets/ icons/ # bundled app assets
├── elf/ syms/ # decomp ELF + patch symbol TOMLs land here (git-ignored)
└── lib/ # vendored source — ordinary files, NOT submodules:
├── bar-decomp # BeetleDecomp — symbols, headers, module/reloc layout (source ref)
├── N64Recomp # the static recompiler (MIPS → C)
├── N64ModernRuntime # librecomp (CPU) + ultramodern (OS/audio/input)
├── rt64 # RT64 renderer (D3D12 / Vulkan / Metal)
└── RecompFrontend # launcher / settings / input UI (recompui + recompinput)
# -> carries RmlUi, lunasvg and freetype with it
Vendored, not submoduled
This repository is standalone. There is no .gitmodules, nothing to git submodule update, and
no dependency on any fork staying up: git clone gives you everything needed to build. Every library
above is committed here as ordinary source.
That is a deliberate trade, and the cost is worth stating. Pulling a fix from any of these upstreams
is now a manual copy rather than a pointer bump, and the local changes this port needs — the RT64
renderer's BAR-specific code, librecomp's Controller Pak support, RecompFrontend's automatic
controller assignment — live here rather than as patches on top of someone else's branch. What is
bought is that the project depends on nobody: no fork can disappear, go stale or diverge underneath
it.
Every one of them keeps its own licence and its own authors. See Credits below and THIRD_PARTY_NOTICES.md; vendoring changes where the code sits, not who wrote it.
Quickstart
Full details and prerequisites: BUILDING.md.
# 1. Fetch dependencies and build the recompiler (N64Recomp + RSPRecomp).
scripts/setup.sh # or scripts/setup.ps1 on Windows PowerShell
# 2. Build the decomp ELF (in WSL), then copy it in.
# (WSL) cd ~/projects/bar-decomp && source .venv/bin/activate && make recomp
scripts/fetch-elf.sh # or scripts/fetch-elf.ps1
# 3. Recompile the game to C.
./N64Recomp beetle-adventure-racing-recomp.toml # emits RecompiledFuncs/*.c
scripts/fix-recompiled.sh # REQUIRED codegen fixup — re-run after every regeneration
# 4. Configure + build the port (clang-cl on Windows, clang on Linux/macOS).
cmake -S . -B build-cmake -G Ninja -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_BUILD_TYPE=Release
cmake --build build-cmake -j
Status & roadmap
The bring-up milestones — the per-module recomp ELF, overlay wiring, first boot, F3DEX2 rendering, input, audio, and Controller Pak saves — are done, and the game is playable. Current work is polish and features:
- Rendering — internal-resolution scaling (defaults to display-native), MSAA + a VI "divot" seam filter, and high-FPS interpolation (phase 1 live; throughput/artifact phases pending).
- Known issues — skippable legal/logo screens, a one-frame menu-transition flash, choppy track-map preview, audio latency-vs-clip tuning.
- Features — controller rebind UI, mod-manager UI, an app icon, and more settings surfaced in the in-app menu.
The live checklist is docs/TODO.md; per-item status and resume detail is in docs/STATUS.md.
License
AGPL-3.0, inherited from the BeetleDecomp data this port derives from. See
THIRD_PARTY_NOTICES.md for the dependency-license analysis and why
AGPL is the correct umbrella. The vendored libraries in lib/ retain their own licences and their
own copyright holders — copying them into this repository changes neither.
Distribute no game assets.
Credits
Nothing here starts from scratch. A static-recompilation port is mostly other people's work, and the short version is: the recompiler, the runtime, the renderer, the decompilation and the original reverse engineering were all done by other people, and this repo is a thin layer on top of them.
Most of the code in this repository was written by the people below, not by this project. It is
committed here rather than pulled in as submodules (see
Vendored, not submoduled), which makes the clone self-contained and
changes nothing about who holds copyright in it or under what licence it is offered. Where this port
has modified one of them, the modification is described in docs/ and the original is credited here
all the same.
This port
- Bryan Kruman (@bryankruman) — the original BeetleRecomp: the static-recompilation port itself, the overlay/module bridge that makes BAR's ~130 relocatable modules work, the runtime fixes, the launcher and in-app menus, and the decomp fork the port consumes. The great majority of the foundation this repo builds on.
- Daniel Gomes Vieira (@danielgomesvieira2000) — continued work: Controller Pak saves, widescreen, HUD placement, draw distance and culling, and the testing that found the defects in them.
The decompilation and reverse engineering
- SynaMax (@synamaxmusic) — the original bar-decomp and bar-notes: the splat configuration, the module/overlay build system, the symbol map and the IDO setup that everything downstream depends on.
- LLONSIT — the module-system work and build-system documentation in that project.
- BeetleDecomp — the fork this port consumes for its symbol-rich ELF and module/relocation metadata.
The recompilation toolchain and runtime
- Wiseguy (@Mr-Wiseguy) and the [N64Recomp] contributors — [N64Recomp] (the static recompiler and RSPRecomp), [N64ModernRuntime] ([librecomp] and [ultramodern]) and Zelda 64: Recompiled, which is the project that showed this approach works at all.
- RecompFrontend — the launcher, settings, input and mod-menu frontend this port uses as-is.
- RT64 contributors — the N64 renderer (D3D12 / Vulkan / Metal) that does the actual drawing, and whose extended-GBI aspect handling the widescreen HUD is built on.
Libraries
- RmlUi (mikke89) — the UI toolkit behind the in-app menus.
- lunasvg (sammycage) — SVG rasterizer for the menu icons.
- SDL — windowing, input and platform layer.
- miniaudio (mackron) — audio backend.
- The libraries RT64 vendors in turn — Plume, plus Dear ImGui, hlslpp, spirv-cross, xxHash, zstd, stb and others; see THIRD_PARTY_NOTICES.md.
The wider N64 decompilation community
The shared toolchain that makes any of this possible: splat, ido-static-recomp, asm-differ, objdiff, m2c and decomp-permuter.
AI tooling
- Claude Code (Anthropic) — the continued work in this repo was written with it, as described in Lineage, and how this is built.
*If you contributed something that is credited wrongly or not at all, please open an issue — it is