F-Zero X decompilation port reaches Nintendo 3DS v1.0.0, directed by one person with a Claude session
A post-mortem on hypnotize.works covers the port of G-Diffuser, the F-Zero X decompilation, to the Nintendo 3DS, ending in a v1.0.0 release. The work ran in two phases. The first, a 24-day sprint (2026-08-11 to 09-03), put the game on a New 3DS at 60 fps in stereoscopic 3D. The second, 43 calendar days (2026-09-07 to 10-19) and not originally planned, added Old 3DS support, a native renderer and the 64DD Expansion Kit. One person directed throughout; one long-lived Claude session orchestrated; 147 subagents built the first phase and "many more" carried the second.
The release is three console builds from one source tree: the base game for Old 3DS / 2DS, the base game for New 3DS / New 2DS XL, and a New 3DS build with the 64DD Expansion Kit (course editor and machine creator, playable with a user-supplied disk image). They boot from the HOME menu (.cia) or the homebrew launcher (.3dsx). Every build reads prebaked asset archives from the SD card, and no ROM or disk image ships with the game. The builds cover Grand Prix, Time Trial, Practice, Death Race and the machine editor screens, with music and effects on the real DSP, stereoscopic 3D on the slider, a bottom-screen dashboard with three HUD layouts, and clean HOME suspend, resume, close, lid sleep and power-off.
The stack: the F-Zero X decompilation (inspectredc/fzerox), untouched upstream plus a patch stack; libultraship, the N64 runtime by Kenix3, untouched upstream apart from a 13-line newlib fix that lets it build on devkitARM, and still drawing every menu and non-race screen; port/3ds, 15,039 lines as of the first phase and since grown (a citro3d rendering backend, stereo, audio, input, menu, lifecycle, render thread, profilers, packaging); and, from the second phase, a native renderer, an owned interpreter that skips the per-frame display-list walk for race geometry. At v1.0.0 both consoles default to the native renderer. The New 3DS first-phase render-thread path is still built in and reachable with an explicit ini.
First phase, New 3DS. 08-11 to 08-14: a feasibility dossier, a plan for a team of agents, five parallel foundation streams and six boot bugs led to a first race at 12 to 20 fps in the emulator. 08-20 to 08-22: fog, HUD, livery, shadow and sky were fixed, and the "loadblock discovery" took menus from 27 to 60 fps. The first hardware run came on 08-21 ("wow it runs amazing"), with audio the same evening. 08-27 to 08-28: stereo, a touch menu and a release package; a GPU vertex-transform moonshot was built and shelved. 09-01 to 09-02: HOME crash and close-from-HOME hang fixed, a proposed bridge output cache proven a NO-GO and replaced by memoizing each sub-display-list's classification, and a LOCKED-60 campaign launched. 09-02 to 09-03: multi-core work with the render thread on core 2 and a one-frame-ahead mode, reaching a median of 59.6 fps with 53% of frames at the cap.
Second phase. From 09-07 to 09-29 the previously written-off Old 3DS milestone was restarted. Parallel agents fit the build into the console's 64 MB app region by halving the RDRAM arena, streaming audio instead of keeping it resident and capping texture uploads. In the first hardware session on a real Old 3DS (2026-09-29), the shipped New-3DS-era build with 16 MiB RDRAM died at boot, while the -DGDX_3DS_O3DS=ON profile booted and raced the same session at about 10 fps.
On 09-29 to 09-30, a narrowed audio lock cut the race-wall wait on the Old 3DS by about 20 ms a frame, frame skipping ended the game's accidental slow motion, and a first retained-mode renderer won big in the emulator but barely moved the number on hardware. From 09-30 to 10-01, hardware performance counters showed the real limit was instruction-cache misses, not instruction count. A pose-replay fallback worked but was set aside on the director's call: "we should go for a real 60! i still believe it has to be possible."
On 10-01 to 10-02 the native renderer was rebuilt around the cache: one small loop per race category, sized to fit the 16 KB instruction cache. Median frame time on a 2D Grand Prix race reached 16.5 ms. From 10-03 to 10-08, a per-eye resubmit with its own swap-pacing mode reached 59 to 60 fps in 3D on most Grand Prix courses on the Old 3DS. The heaviest courses (Silence, Sand Ocean) can still trip the frame-skip safety net to a steady 30 fps mid-race. From 10-08 to 10-19 the 64DD Expansion Kit was verified tick-for-tick identical under the native renderer and booted on the Old 3DS, which then proved too slow to release it there. The bottom-screen DASH shipped, and a standing adversarial review audited the merged result before v1.0.0.
The overview points to further pages: author's notes, a step-by-step chronology, the New 3DS performance campaign, the native fork, the Old 3DS campaign, comparisons, difficulties, the agentic workflow, and a cost page counting tokens, dollars and subagents.
Key facts
- G-Diffuser, the F-Zero X decompilation, now has a v1.0.0 Nintendo 3DS release in three builds: Old 3DS / 2DS, New 3DS / New 2DS XL, and a New 3DS build with the 64DD Expansion Kit.
- One person directed and one long-lived Claude session orchestrated; 147 subagents built the first phase (24 days) and "many more" the second (43 calendar days).
- On the New 3DS the first phase reached a median of 59.6 fps with 53% of frames at the cap; on the Old 3DS, a native renderer sized to the 16 KB instruction cache reached 59 to 60 fps in 3D on most Grand Prix courses.
- The turning point on the Old 3DS was a hardware-counter probe showing instruction-cache misses, not instruction count, were the real limit.
- No ROM or disk image ships; builds read prebaked asset archives from the SD card, and the Expansion Kit needs a user-supplied disk image.
Why it matters
This is a detailed account of a hardware-constrained port driven largely by agents: a decompiled N64 racer taken from a black screen to native 60 fps stereoscopic play on a handheld, then extended to the weaker Old 3DS after that goal had been written off. The post-mortem shows the kind of decision a human still made. When a fallback that worked was on the table, the director pushed for a real 60 instead, and a hardware performance probe then redirected the whole plan from instruction counts to cache behaviour.
Who it affects
Owners of Old 3DS / 2DS and New 3DS / New 2DS XL consoles who run homebrew are the direct audience, along with fans of F-Zero X and its 64DD expansion. Developers working on decompilation ports or on console performance work can read the account of the native renderer and the cache findings. Anyone studying agent-driven development gets a concrete case: one director, one long-lived Claude orchestrator and well over 147 subagents across two phases.
How to use it
The builds boot from the HOME menu (.cia) or the homebrew launcher (.3dsx). They read prebaked asset archives from the SD card, because no ROM or disk image ships with the game. The 64DD Expansion Kit build is for New 3DS only and is playable with a user-supplied disk image. This overview page gives no download link, license or release URL for v1.0.0. With no ini, both consoles default to the native renderer ([perf] preset = auto); the New 3DS first-phase render-thread path can be selected with an explicit ini.
How solid is it
This is the project's own post-mortem, so the numbers are the author's measurements and claims, and nothing here is independently confirmed. It is specific, though: dated phases, named fps and frame-time figures, and hardware-counter evidence for the cache diagnosis. The source also says a standing adversarial review audited the merged result before release. Dollar figures on the separate Cost page are estimates that apply published API list prices to exact token counts. The page does not name the human director.
Risks and caveats
Old 3DS performance is not a flat 60: the 59 to 60 fps 3D result covers most Grand Prix courses, and the heaviest (Silence, Sand Ocean) can drop to a steady 30 fps mid-race. The first Old 3DS race on real hardware ran at about 10 fps, so the final result came from heavy later work. The Expansion Kit booted on the Old 3DS but was judged too slow to release there. The 59.6 median is a New 3DS first-phase figure and the New 3DS default has since changed to the native renderer. The overview's clips and photos are from v0.9, before the DASH dashboard replaced the debug console on the bottom screen.
“we should go for a real 60! i still believe it has to be possible.”
— the user directing the project, as quoted in the post-mortem