08 · Frontier
Why this is bold, and where it is new
The user asked on 08-23 how to explain to an unimpressed friend why this port matters. The short version: when it started, no libultraship game was known to run on a handheld this weak, and no N64 port on 3DS was known to hold a native 60 Hz without interpolating, let alone in stereoscopic 3D; this one did both in three and a half weeks, with a fleet of AI agents doing the typing. A second phase then replaced the interpreter for race frames and took the game to the Old 3DS, a console with a third of the clock, and a third added online multiplayer and one-submission stereo. Others have moved since; the items below say where each claim stands now.
The field before this project
Two deep-research passes (08-14, 09-01) and a targeted literature check (09-02) mapped the state of the art. The findings framed every architectural decision:
| Precedent | What it did | What it means here |
|---|---|---|
| sm64_3ds (the well-known Mario 64 3DS port) | Native decomp with a hand-written 3DS renderer, plain switch dispatch, audio on a second core. Its README describes a naive frame skip below 30 fps and lists a separate 60 FPS patch. | The proven fallback in this field is some form of 30 Hz, interpolated or not. This project refused that and targeted native 60. |
| libultraship ports (Ship of Harkinian, 2Ship, Starship, and this game's own PC port) | Desktop-only. x86-64 and ARM64 with OpenGL, Metal or DirectX. Never compiled for devkitARM. | The LUS carve-out spike (08-12) proved LUS builds on devkitARM with a 13-line newlib patch, the first such build the research knew of (two other libultraship 3DS projects had appeared by 10-08; item 1). |
| Every N64 port ever shipped | Walks the display list on the CPU every frame and re-emits it to the GPU. | The 09-01 research verdict: nobody has shipped beyond the per-frame walk. GPU vertex transform was the field's number-one untried idea, listed as a TODO by the sm64 port's author. |
| Cross-core render pipelining on 3DS | No precedent found in any homebrew title. Core 2 needs a Luma kernel grant; core 3 is the OS's. | The render thread (09-02 → 09-03) was, as far as that research could find, the first game-logic-ahead render pipeline on the console. The 10-08 field search later found Smash 64 for New 3DS rendering on another core too (item 5). |
Nine things this project did first, or did differently
Each item carries its journey: where it started, what changed, and where it stands in the v1.1.0 work. A first label is used only where a research pass looked for precedent and found none, and says when; everything else is labelled as a difference.
1. libultraship on a 3DS
first, as far as our research foundThe whole runtime, its Fast3D interpreter, resource manager and archive loader, compiled for the ARM11 under devkitARM. When this started, the research passes (08-14, 09-01) found libultraship only on desktops. By the 10-08 field search two other libultraship-based 3DS projects had appeared (a SpaghettiKart-based Mario Kart 64 and a Ship of Harkinian port); their start dates are not in our record, so the claim is dated: no libultraship 3DS build was known on 08-12.
preset = off.2. Native 60 on a software display-list interpreter
did differentlyThe first phase's position on the New 3DS, full Grand Prix, trace off: median 59.6 fps, tenth percentile 51.4, 53% of frames at the cap, without dropping the logic rate or interpolating. When it landed, the 09-01 research had found no N64 port on 3DS holding 60 this way. The 10-08 field search found others reaching 60 by interpolating over 30 Hz logic, and Smash 64 for New 3DS aiming at 60 without promising it, so this is listed as a difference, not a first.
preset = off.3. Exact stereoscopy, then both eyes in one GPU submission
did differentlyStereo is an asymmetric-frustum shift folded exactly into the projection, x′ = x ± k·(z − dc·w), so depth, fog and the combiner are bit-identical per eye and the 2D race markers can sit at their ship's depth. The second eye has been produced three ways. Other 3DS N64 ports also replay per eye (rt64-3ds, the SM64 lineage); what is different here is how little the right eye costs, and that the last step came from a suggestion by a 3DS homebrew developer.
4. GPU vertex transform: shelved, then shipped
did differentlyThe 08-28 moonshot moved the unlit vertex transform onto the PICA vertex shader: 220,000 draws with zero fallbacks, 62% less vertex time in the emulator, imperceptible on hardware, and broken on the venue floor because 24-bit floats cannot hold ±32000-unit coordinates. It was shelved on that evidence. The native fork brought it back for the meshes it retains, with the precision problem solved: the shader adds an integer eye offset first, which float24 represents exactly.
gpuxf for retained track and machine meshes, with lighting and texgen.5. A render thread inside the game's own frame protocol
did differentlyRather than a mailbox, the fork happens where the N64 would have started the RSP task (osSpTaskStartGo) and the join is the game's own DP-done wait: a true one-frame-ahead pipeline with two-deep backpressure. The 09-02 research found no precedent; the 10-08 field search found Smash 64 for New 3DS also rendering on another core, so this is a different design, not the only multi-core renderer.
6. Fixed-function combiner totality
did differentlyEvery N64 colour-combiner mode the game uses maps to three or fewer PICA TexEnv stages; fog is a per-vertex factor blended in a TexEnv stage because the PICA's depth LUT cannot resolve the game's depth range. Zero unsupported modes.
7. Skipping the display-list walk, on the hardest target
first, as far as our research foundFor what a race spends its frame on, the native renderer writes the GPU's own command words from recorded and baked data instead of walking the display list (see The road to 60, all over again). It shipped first on, and matters most for, the Old 3DS: a third of the clock, no L2 cache, no second application core. No other N64 decompilation, recompilation or emulator project the 10-08 search found claims a sustained 60 on an Old 3DS, and that was still the case at release.
8. Online lockstep multiplayer across Old and New 3DS
did differentlyTwo to four consoles race over the internet, the same Wi-Fi or local wireless, sending only inputs: about 130 bytes per tick per peer, every console simulating the same race in deterministic lockstep. A small rendezvous server (one standard-library Python file, UDP 27200) exchanges endpoints from a five-character room code, punches through NATs and relays when it cannot; agents deployed and operated it on AWS. Old and New 3DS can share a room. No precedent search was done, so this is not claimed as a first.
9. The 64DD Expansion Kit on a handheld
did differentlyThe course editor, machine creator and 64DD content run as their own New 3DS build, streaming the player's own retail Japanese disk image from the SD card instead of holding 62 MB in RAM. We did not search for earlier 64DD efforts on a handheld, so no first is claimed.
Why bold
The conservative plan was available from day one and was declined at every fork:
- Native 60 Hz instead of 30 Hz + interpolation. The deep-research report on 08-21 said the proven path was the sm64 way. The user's instruction on 08-14: "only list options that work towards this running acceptably in 3D at 60fps."
- Stereo before the frame budget was safe. The stereo foundation was merged flag-off on 08-20 and armed on 08-27 while crowd frames still dipped to 30 fps, on the argument that it costs CPU submit time, not GPU time, and had to be designed in.
- Multi-core on a console that hides its cores. Core 2 is only reachable with a kernel capability that Luma grants to homebrew; the choice to depend on it was made after the 09-02 research and a hardware confirmation that the grant holds for a .3dsx and a .cia.
- Patch stack, not a fork. Keeping upstream pristine cost real pain (every patch a pure delta, regenerated by three-way merge) and kept the door open to upstreaming. One leak fix in libultraship was identified as an upstream bug on 08-28. The decomp side still works this way; libultraship was later frozen into a vendored carve (item 1).
- Shelving on evidence, not on effort. GPU transform, the bridge output cache, the DSP batch-break fold, the double-height stereo target and the machine texture atlas were each built to the point of measurement and then declined. The project's default-off branches are its most expensive documents, and one of them came back: GPU transform now ships on by default, once the native renderer gave it meshes worth transforming (item 4).
Innovation in method
The technical results rest on a way of working that is itself new. Every performance change shipped with a killswitch and a receipt line, so hardware could A/B it without a rebuild. Every hypothesis got a probe before a fix (the magenta padding flood, the fog probe line, the CRC tripwires that pinned the HUD bug). Every hardware round had a test plan written for a human and a log format written for a machine. The agentic workflow page covers how that discipline was enforced across a fleet of agents that could not see the console.