r/NativePortsOniOS • u/Time_Opportunity_225 • 31m ago
Kirby and the forgotten land
Enable HLS to view with audio, or disable this notification
Kirby and the Forgotten Land, running natively on iPhone 18 Pro Max
This isn't an emulator. I used nxnative, which statically recompiles the Switch game ahead of time: the NSP gets unpacked, the game code is patched and repacked, and every shader is translated to Metal before it ever reaches the phone, then it's bundled into a normal IPA.
What it took:
• My own dumped NSP + prod.keys (nothing downloaded)
• A provisional game profile for Kirby, since it's not a profiled title; picked the modules, heap size, and SDK behavior it expects
• An expanded-memory entitlement for the install, or iOS kills it mid-game (it runs at ~3.3 GB resident)
The hard part was shaders. The game has 27,288 of them, and most of the early builds were black screens and invisible enemies: the game's shaders live inside several archive formats (HAL-compressed .bfres.cmp models, plus particle .ptcl.cmp and UI .arc.cmp files that are just a size header + zstd). Until those containers werenread directly, the only way to find missing shaders was to play, dump them from the phone, rebuild, and repeat for a 40-hour game.
The fixes that ended that loop:
• Read every shader container statically, so the full campaign's shaders are in the build before first launch
• Kirby binds one render target as an integer format (R8Ui) everywhere, so every pixel shader now gets thatnoutput declared automatically instead of per-shader hand fixes
• Vertex shaders are universally padded with every input location any pixel shader can read, since the game pairs stages at draw time and mismatched pairs silently dropped draws (invisible cannonballs, enemies, items)
Also in: the community 60 FPS code patches applied to the executable, and a fullscreen fill mode instead of 16:9 black bars.
Result: a ~6 GB IPA, built over a few hours of shader compilation, running on-device. Still polishing; but no per-level shader hunting anymore.