Pre-release quality. Built from
mainfor early testing and feedback. Expect rough
edges — crashes, audio glitches, and missing native translations are still the rule, not
the exception. Please open issues rather than running off the latest commit silently.
⚠️ You must supply your own ROM
This release contains no game assets or code from the original cartridge. It ships
only the recompiled executable. To play, you must obtain a legal copy of
Automobili Lamborghini (USA).z64 (the North American release is the only one
supported) and place it next to the executable before launching. See BUILDING.md
for the full instructions; in brief:
- Extract the archive for your platform into its own folder.
- Drop
Automobili Lamborghini (USA).z64into that folder. - Launch the binary.
Game saves go alongside the ROM (or under %LOCALAPPDATA%\LamborghiniRecomp on
Windows / ~/.config/LamborghiniRecomp elsewhere — see README.md).
What's working
Game is playable, with upscaled resolution, high FPS, and widescreen (including HUD)
support across all race modes, plus N64 Rumble Pak support. The headline of this release
is distance pop-in is gone: a four-PR series (#119 → #122 → #123 → #124) traced the
remaining world pop-in to two mechanisms the earlier audits missed — the per-circuit
N64 fill-rate radius cull (worst on the city track: a whole city block popping in at the
35000-unit edge) and a camera-segment visibility list that silently dropped entries
past the first -1 hole. New graphics.json knobs let you tune the radius (draw_distance,
default 1.5× authored; draw_distance_circuit[6] per-track multiplier), the per-track
synth (no_lod_circuit[6], with pro tracks shipping off by default to preserve the
N64-authored look), and fog density (fog_scale, fog_scale_circuit). There's still
glitches so please report issues you find.
Closed since v0.4.2:
Distance pop-in (no_lod series)
- #87 follow-up / PR #119 — The remaining city-track distance pop-in is fixed. The
scene builderfunc_8000A6C0was distance-culling every PVS entry against a
per-circuit radius table at0x80088FD0— the city track's 35000-unit budget was
authored shortest, so segment 31 sat ~51k units down a long street and popped in at
the edge. A per-frame[[patches.hook]]on0x8000CD3Crewrites the 30 radii to
1e9 (per-frame because savestate restore brings the ROM values back). Authored
visibility lists are untouched — segments the game already streamed just stop being
hidden. New offline audit:tools/pvs_distance_audit.py(replays the builder's exact
test arithmetic from aLAMBO_RACE_DL_DUMPsnapshot). - PR #122 — Even with the radii lifted, segments not in the camera's authored
10-slot visibility row never drew. Two data-model fixes: PVS rows are 10 fixed slots
with-1holes (not terminators), and the segment count is(header+0x8 − header+0x4) / 20— circuit 5 has 55 segments, not 42. Threepatches.hooks widen
the existing walk to synthesise an all-segments row (authored entries first). New
fog_scale/fog_scale_circuitride the existing #83 fog DL-walker to scale fog
alpha without moving its authored onset distance. - PR #123 —
draw_distancebecomes a dial, not a switch. Default is 1.5× the
authored per-circuit radii (the worst measured pop needs ≥1.46×);0reverts to
the old unlimited behaviour,1.0reproduces N64 distances. Per-circuit
draw_distance_circuit[6]multiplies with the global. Multiplier-not-absolute
preserves the authored per-mode budget ratios (1P radii stay longer than 2-4P).
LAMBO_DRAW_DISTANCEenv override for capture. - PR #124 — Ship-safe default:
no_lod_circuit[6]adds a per-circuit PVS-synth
gate. Pro tracks (3-5) ship with the synth off to preserve N64-authored back-
of-buildings / floating geometry the radius cull was hiding; basic tracks (0-2)
ship with the modern pop-in fix. Radius cull and 2P+ scenery sub-DL stay gated on
the globalno_lod()so distance culling and 2P scenery work on all 6 tracks.
Newdocs/TRACK_INDEX.mdis the authoritative 0-based / 1-based / F-key / basic-
pro map.
Stability
- PR #118 — Pit-stop flicker is fixed, and so is the related cold-load crash from
LAMBO_STATE_LOADstraight into a pit-stop savestate. The widescreen HUD bracket
reset hooks sat on recompiled branch labels that run on every incoming path;
the pit-stop screenbnes straight past the draw and its pin, so every pit frame
emitted an unpairedG_EX_POPSCISSOR(scissor-stack corruption) and ran the matrix
walker over a stale span (needle/arrow shift toggled shifted/unshifted per frame —
the flicker). Cold-load withbracket_start=0crashedpatch_load_mtx_dx8/8.
One module-wide bracket flag now arms on every pin and disarms on every reset; the
quad-text bracket pair (pin_left→quad_text_end) keeps its existing pairing.
Covered bytests/test_hud_bracket_pairing.c(cold-start reset no-op, paired
needle shift still exact, pit-path unpaired resets leave scene matrices untouched). - #116 / PR #117 — The Championship-standings "Done" button and the second
button of the pak/records confirm dialogs are no longer dead. The menu system
dispatches per-screen actions via function pointers in static per-screen element
tables (0x801EB320, handler at record+0x4); because they're neverjal'd, splat
truncations produced silent no-ops instead of build errors. Whole-ROM sweep for
data pointers landing on empty-bodied recompiled functions found exactly these
two — the class is now closed. StandardSPLIT_MERGES + UNSTUBfix (func_80041538
andfunc_8004EF0C); absorbed tails have zero independent jal/data callers. PR
also fixed a generator-sync drift: PATCH_BLOCKS and NATIVE_OVERRIDES now carry the
hand-edits tolamborghini.us.tomlso regeneration is byte-clean (the #78 quad-
HUD hooks + the PR #108 rumble ignored entries).
Developer tooling
- PR #120 — Default boot is silent. The same lines that used to print one per
VI heartbeat (and several on each transition) now only emit when the binary is
started with--lambo-debug. 99fprintfsites converted across 7 files behind
alambo_log_enabledbool insrc/lambo_log.h; the[rt64]and[gfx]
heartbeats wrap their wholeif-blocks so the VI-reg read +interpolatedMutex
lock also short-circuit on a default boot (not just the innerfprintf). Crash
dumps ([crash]tag) and the opt-in env-var features (LAMBO_PAK_TRACE,
LAMBO_DL_INSPECT, ...) are NOT routed through the gate — they were already
opt-in via env var or only fire on actual signal/SEH. In a 1800-VI headless run:
default boot = 2 lines,--lambo-debug= 69 lines.main.cppskips argv entries
starting with-when finding the ROM path solamborghini_modern --lambo-debug path/to/rom.z64works. - PR #115 — A new
/releaseslash command (.claude/skills/release/)
captures the tag → dispatch → wait → verify → ship-notes flow with five
deterministic bash scripts (list-changes, tag-and-dispatch, wait-for-build,
verify-release, update-notes) and three reference docs (gotchas, prior-release-
format, release-notes-template).disable-model-invocation: truekeeps the agent
from auto-triggering — releases stay deliberate.
CI / build
- PR #121 — Fresh CMake configures were failing during the
directx-headers
FetchContent step (git.exe: add_item failed, errno 1;Git_VERSION=''). Root
cause: devkitPro's MSYS2git.exesat ahead of Git for Windows on PATH and its
Cygwin heap can fatal outside its own shell.build.ps1's toolchain-PATH step
now auto-discovers native Git for Windows and prepends it; verifiesgit.exe
in the[tools]check and warns ifgitstill resolves to MSYS/Cygwin.
What's not done yet
This is still pre-1.0 — plenty of force_stub.txt still includes real game primitives
rather than no-ops. The tracker is the canonical "what's next" list.
Known follow-ups carried over from prior releases:
- #26 epic / Widescreen HUD residual gaps — quad-mode skybox / fog / minimap
pinning is solid in 2P-4P; a few residual cases (the needle/arrow scale keyed off
the effective rect-pin aspect can over-scale at extreme ultrawide) are tracked. - #88 / #91 — lights-match in 3P+ viewports still open from the no_lod audit;
pop-in is gone but 3P+ scene lighting doesn't always match the 1P baseline. - Texture tooling PRs (#99, #66) still open — xBRZ HD-pack batch tooling and
font upscale / vector re-render tools are staged but not yet merged.
If you find a crash, please open an issue with lamborghini_crash style notes:
- Output window text (or the
crash-*.txtdump if the native handler caught it) - Commit / build provenance (below)
- Approximate in-game location (title screen / car-select / race lap 2 / etc.)
How to run
Linux
unzip lamborghini-recomp-linux-x64.zip -d lamborghini-recomp
cp "Automobili Lamborghini (USA).z64" lamborghini-recomp/
./lamborghini-recomp/lamborghini_modernRequires libsdl2-2.0-0 and a Vulkan-capable GPU + driver at runtime. Most
desktop distros ship these already.
Windows
Extract lamborghini-recomp-windows-x64.zip anywhere, drop your ROM in the same
folder, and double-click lamborghini_modern.exe. The bundled SDL2.dll,
dxcompiler.dll, and dxil.dll must stay alongside the EXE.
F11 / Alt+Enter toggles fullscreen (and remembers the choice next launch).
For the new pop-in / fog knobs: edit graphics.json (created on first run) and look
for draw_distance, draw_distance_circuit, no_lod_circuit, fog_scale,
fog_scale_circuit. The shipped defaults match what this release was verified
against (1.5× authored radii, pro tracks off for no_lod_circuit, 1.0 fog).
Build provenance
- Commit:
2446cb3(main, 2026-07-23) - Workflow run: #30075475921 (Build & Release, dispatch from this SHA)
- Toolchain: Linux build on
ubuntu-latestwith gcc / cmake / ninja /
libsdl2-dev/libvulkan-dev. Windows build onwindows-latestwith
MinGW-w64 GCC + Ninja (PowerShell, not MSYS bash) per the project's toolchain
notes.
If you'd rather build it yourself from source instead of running a pre-built
binary, see BUILDING.md. For graphics settings, see README.md.