Mario Kart 8 Deluxe (0100152000022000)¶
State: v3.0.5 (update v1376256 + Booster Course Pass DLC) boots and races headless on the normal 64-bit path at 40-47 fps (title, menus, cup select, races). The base 1.0 build is AArch32 and runs through the lifted a32jit.dylib (written by napple build) at 52-60 fps in headless menus and the attract race; the runtime has no interpreter (2026-10-26, a32-full).
What it needs¶
--update-romfs in-placedata (268 MB instead of ~19 GB), see README.- Mii default CharInfo as UUID v4 (otherwise the AArch32 build faults at start), device and account saves mounted separately, display version from the NACP,
time:ucmd 300, the A32 main-stack reservation.
What is open¶
- The ~45 fps ceiling is gfx: guest blocked ~21 ms per present in SyncWait, per-submit commit to complete ~21 ms, present GPU <= 8 ms, replay CPU 0.7 ms (LAS runs 58 fps with the same code). Headless pacing as a timer reached 60 fps in one run (merge-sensitive).
- Resolved 2026-10-26 (gfx-correctness): stale command handles (lists now live as long as their command memory), the compressed render-target shadow is copied back, a vertex stream outside every pool binds zeros (and streams no attribute reads are ignored), Metal API validation is clean through title, menus and a race. Still open: conditional rendering always enabled;
TextureInitialize: storage out of rangewas not seen again in the 2026-10-26 routes (re-check with the golden harness). - iOS Simulator: the G-buffer pass needs 48 bytes of colour attachment, the Simulator allows 32 (base, AArch32); 3.0.5 now gets past
time:ucmd 300 and aborts at ~2.3 s on the same 48-byte limit (2026-10-26).romfs.mapholds host paths: it works only in the Simulator, a device bundle needs the real RomFS. - Binary archive load time (2026-10-26): a 59 MB
cache/pipelines-v8.metalarleft in the default save root by earlier runs took 65.5 s to load inmtl_shader_init; now a file over 16 MB loads in the background (draws compile meanwhile) and the file is capped atNAPPLE_GFX_ARCHIVE_MAX_MB(default 64). The Grand Prix menu's mode-preview panel is a black rectangle (a video preview; media, not gfx). - A32: 4,818,607 of 4,867,102 instructions are lifted inline (VFP and NEON included), 48,495 (mostly undecodable pool/table words) run as build-time decoded out-of-line operations, zero interpreter fallbacks and zero "no lifted code" stops in 150 s scripted runs and 112 headless runs. One run in 40 aborted inside
gfx_cmdrec_finalize_handle(heap corruption in the command recorder after "command recorded outside BeginRecording/EndRecording"; gfx owner); no wild pc. - Both the ios-sim and mk8d-64 branches add
time:ucmd 300 (conflict inservices/time.cat integration).
Build and test¶
napple build <MK8D folder> -k "/Users/neto/Documents/Napple/Testing Material/Keys 22.1.0/prod.keys" --firmware "/Users/neto/Documents/Napple/Testing Material/Firmware.22.1.0.zip" --updates latest --dlc all --data-only --update-romfs in-place -o <out>
napple-runtime <out>/0100152000022000/fe941ed5ba14be5d --headless --seconds 120
NAPPLE_INPUT_SCRIPT="15:A,19:A,...,140:A" reaches the races (title "Ver. 3.0.5"); expected exit 0, 5362 frames in 120 s. A32: napple build writes modules/a32jit.dylib; run the b5c39b5b7c62a88e dir with NAPPLE_A32_JITSTATS=1 (prints out-of-line operations and the unlifted-pc counter, which must stay 0). The interpreter only exists in the make -C runtime A32_INTERP=1 debug runtime.
Numbers¶
| Build | Scene | fps |
|---|---|---|
| v3.0.5 A64 | title, menus | 44.9-45.4 |
| v3.0.5 A64 | race | 40-47 |
| v1.0 A32 lifted | menus / race | 44-45 / 43-45 |
| v1.0 A32 interpreter (removed from the runtime 2026-10-26) | menus / race | 37-45 / 6-15 |
| v1.0 A32 lifted, VFP/NEON inline (2026-10-26) | menus / attract race | 50.7-52.0 |
| Frames in 90 s: lifted 3707-3799, interpreter 2340-2355. Data dir: 268 MB. Memory: not measured in a note. |
Timing (fps-unlock-timing, 2026-10-27)¶
Guest cadence 60 Hz (swap interval 1): trace at all fps modes: vsync 60.00 Hz, game clock 1.000, presents 60/s headless. The race simulation is frame-stepped, so extra real frames need a patch (later package). (How each title ties its logic to vsync is inferred from its cadence and engine class, not verified by patching; the per-title timestep package confirms it.)
Tie-up status (end-to-end, 2026-10-27)¶
From tools/e2e/run.sh (testing guide): built through Studio, launched through the launcher, 45 s headless.
- 32-bit (A32) title built through Studio's pipeline: the a32jit.dylib is produced at build time and embedded in the app; update (3.0.5) and the DLC pass are in the app (3 version directories, 1 DLC). Boots 45 s: exit 0, 2442 frames, audio and scripted input OK, 6 save files written and mounted again.
- Mii: opens mii:u and lists the shared database (wrote 2 after the Mii Maker created one: the same MiiDatabase.dat every game reads). amiibo: nfp never opened.
- Overlay Game/System renders. Camera/IR: not used. Online: NullProvider.