09 · 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, still true at v1.0.0: nobody had run a libultraship game on a handheld this weak, nobody had pushed a software N64 display-list interpreter to a native 60 Hz on an ARM11, and nobody had done it with stereoscopic 3D, in three and a half weeks, with a fleet of AI agents doing the typing. A second phase then took the same approach to the Old 3DS — a console roughly a third the New 3DS's clock speed, with no second core — and shipped a 64DD expansion alongside it.

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:

PrecedentWhat it didWhat 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. First time.
Every N64 port ever shippedWalks 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 3DSNo 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) is, as far as the research could find, the first game-logic-ahead render pipeline on the console.
An earlier draft of this table described the sm64_3ds port as 30 Hz logic interpolated to 60; that was not accurate. See Pushing the boundaries for the correction.

Seven things this project did first, or did differently

1. libultraship on a 3DS

The whole runtime, including its Fast3D interpreter, resource manager and archive loader, compiled and running on ARM11 under devkitARM. The port lives as a stack of pure-delta patches (48 files as of the first phase; 93 files at v1.0.0 — 52 decomp patches plus 41 lus patches, the set tools/ci-3ds.sh applies and vendors) over two untouched upstream submodules, so the upstream projects could take any of it.

2. Native 60 on a software display-list interpreter

The measured position at the end of the project on a full Grand Prix, trace off: median 59.6 fps, tenth percentile 51.4, 53% of frames at the 60 cap. Menus at 60. Achieved without dropping the logic rate or interpolating.

3. Exact stereoscopy inside the projection fixup

Stereo 3D is implemented as an asymmetric-frustum shift folded into the projection fixup uniform, in exact clip-space form: shift(d) = ±sep·(d−dc)/(1−dc). The right eye is a replay of the packed vertex buffers with a different matrix, no second interpreter walk. The user's hardware verdict on 08-27: "3D works great, doesnt seem to affect performance much at all." The final touch (09-03) anchors the race position markers, which are 2D rectangles, at the depth of the ship they label by reading the game's own prim-depth register.

4. GPU vertex transform, working, then shelved on evidence

The "moonshot" of 08-28 moved the unlit vertex transform onto the PICA vertex shader: 220,000 draws with zero fallbacks, 62% less vertex time in the emulator. On hardware it was imperceptible (the unlit slice was too small) and it broke texture mapping on the venue floor because the PICA's 24-bit uniforms cannot hold ±32000-unit coordinates. It was preserved on its branch, documented, and shelved. Nobody in the lineage had built it before.

5. A render thread inside the game's own frame protocol

Rather 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. Mode 2 acknowledges DP-done when the game parks, giving a true one-frame-ahead pipeline with two-deep backpressure. The bridge pre-pass moved to the main core to balance the load. Hardware round 4: median 59.6 fps.

6. Fixed-function combiner totality

Every N64 colour-combiner mode the game uses maps to three or fewer 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; the decal-clamp, environment-colour-flush and CCMUX-11 fixes made the translation total with zero unsupported modes.

7. Skipping the display-list walk, for real, on the hardest target

Item 4 of this list shelved a GPU vertex-transform shader because it could not fix what actually limited the frame. A second phase (2026-09-07 to 10-19) found a different way to the same goal: for the geometry a race actually spends its frame on — the track, the machines, the sky, the HUD, the effects — an owned interpreter precomputes and writes the GPU's own command words directly, skipping the per-frame CPU walk entirely for those categories, with menus and the long tail of one-off screens left on the original interpreter. It shipped first on, and matters most for, the Old 3DS. No other N64 decompilation, recompilation or emulator project this project found claims a sustained 60 fps on an Old 3DS: a third of the New 3DS's clock, no second core, and a cache the original interpreter's code did not fit in. See Pushing the boundaries for the comparison, on our own New 3DS build and against the field.

Why bold

The conservative plan was available from day one and was declined at every fork:

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.