
- Title ID
- 010089B00D09C000
- Tested build
- 1.0.1
- Nintendo SDK
- 6.4.2
- Engine
- Unity 2017.4.17f1 IL2CPP
- Graphics API
- NVN
Build this game
Keep [010089B00D09C000] in your file names, put the base game, update and DLC in one folder and run the script. Follow the build guide, then the sideloading guide. Needs an iPhone 15 Pro or newer, or an M1 iPad or later.
Technical notes
The project's own record of bringing this game up: what its profile needs and why, what was found and what is still open.
Update 1.0.1 (v65536) over the base game, SDK 6.4.2. Unity 2017.4.17f1 IL2CPP with FMOD, on NVN. Modules main, subsdk0 (the movie module) and sdk. Plays on the iPhone; 60 fps (present interval 1). The README lists its IPA at about 8.3 GB.
Brought up on the Mac: the Spike Chunsoft logo movie, the title (its background movies), a new game (language, auto save notice), the opening at the merry-go-round and the first investigation with its conversation tutorial, both sticks; loading the autosave from the title. About 2.27 GB resident, flat over 5 minutes; audio through FMOD's AudioOut.
What it needs
| Setting | Where | Why |
|---|---|---|
pad_layout full |
game.tsv |
the 3D gamepad layout: the investigation moves its cursor with the left stick and the view with the right one |
mem_used 0x6800000 (104 MB) |
game.tsv |
the rewritten modules take more than the default 64 MB of used memory: with 64 MB the heap request plus the modules exceeds the pool and SetHeapSize fails (as Cuphead, 0100A5C00D162000) |
sys_resource 0x0 |
game.tsv |
the NPDM declares no system resource, so the game has no virtual address memory |
4 GB layout: mem_reserve 0x100000000, mem_alias 0x10000000, mem_stack 0x10000000, app_pool 0xCD500000 |
game.tsv |
256 MB in front + 256 MB alias region + 256 MB stack region + 3.25 GB heap region; see Memory |
No patches.py, and dm/tools/sdk_patches.py has no cut for its sdk build (184751379007f9c50fc96ba4d26a5dca).
Memory
- No system resource: Unity sets a heap of the application pool − used memory (3.11 GB) in the 4 GB layout and allocates from it.
mem_usedis 104 MB for the rewritten modules. - On the Mac: 2.27 GB resident over 5 minutes from boot to the first investigation, flat.
Movies
subsdk0is the movie module. The 168 movies (StreamingAssets/Movie, H.264 and AAC in MP4) play through Unity's video player: NV12 frames into CPU buffers, copied to an R8 + RG8 texture pair each frame (nvnCommandBufferCopyBufferToTexture).- Resolved: the game never left a movie that had played to its end; the last picture stayed on screen. The 6 s Spike Chunsoft logo (
StreamingAssets/Movie/al_titel_cl_sc_1k_30.mp4, H.264 High) before the title held the game there.DM_MOVIE_TRACE=1showed the end-of-stream packet arriving with H.264 pictures still in the reorder queue: its output went out as a black picture without the end-of-stream flag, and the queued pictures were to follow one per free output slot (the drain). Unity held all 16 video slots by then, andReleaseOutputBufferIndexdecoded again only when packets were queued, so the drain never went on and the game waited for the movie's end for good. Fixed inhle_movie.c(a released slot goes on with the drain; see Found on this game). The audio decoder was never affected: AAC has no reorder queue.
Rendering
- Docked, the game draws 1280x720 by its own choice and crops the 1920x1080 window to it.
- Resolved: a draw with the vertex shader of another Shader object. Once on entering the first investigation:
[RED] failed to create render pipeline (vertex 790573a52b9c5053_b fragment f39fb42850f50ecd_b): Fragment input(s) user(locn0),user(locn1) … not written by vertex shader. The vertex shader wasLegacy Shaders/VertexLit's shadow caster, the pixel shaderPSYNC/BG_AlphaTest's, whose own pass pairs it with00b462fe0dec6e06. Unity binds the vertex and fragment programs apart, so every draw's pair is a composite ofbind_stages, one of a ring of 64. In a 280-draw submission the precompile prediction (pso_predict_rest) made more than 64 composites and reused the slot the savedS.prognamed, so the draws after the restore, up to the next bind, ran with that slot's new pair. Fixed byprog_resolve(logged ascombined program taken again after a state restore). Two runs each from one save with one key script, prewarm off: the old host loggedtexture type mismatch: shader declares a cube, texture is 2Dboth times (a pixel shader run with another pair's bindings), the fixed host no red line, with the slot taken again twice.
Files and shaders
- The shaders are Shader objects in the AssetBundles of
StreamingAssets(read byshader_split.pythroughunityfs.py, Cuphead's Unity 2017.4 layout) and inmain: 13,057 (6,572 vertex, 6,482 pixel, 3 geometry). All build for Mac and iOS. - The ComputeShader objects of
Data/resources.assetshave no type tree (a red line in the split, as in Cuphead); no dispatch has missed one so far. romfs_markerisData/StreamingAssets/AssetBundles/Switch/audio.
Geometry shaders
The three geometry shaders were the test case of the general geometry-shader compute path (geometry support and limits):
| GS key | Effect | Candidate VS |
|---|---|---|
1b378c5c014e3a32 |
Hidden/DepthOfField/BokehSplatting: expands input vertex 0 to a four-vertex triangle strip |
ba2512f7f6973541 |
d57cdb168fdf6927 |
Hidden/Dof/DX11Dof: the same expansion, input varying locations 0 and 1 exchanged |
771d597a6eb545aa |
2341c1be4fcbf690 |
UCLA Game Lab/Wireframe/Single-Sided: screen-space edge distances from all three positions, three vertices out |
ce9cbd7dca9fda74 |
- The candidate vertex keys come from adjacent entries of the same Unity shader, not a captured runtime binding. The bokeh shaders really expand geometry and fail the layer-only fold; wireframe cannot drop its GS, as its fragment inputs depend on the other two vertices.
- Current: they build through the native-VS-capture / GS-compute path.
t_geometry, built withGAME=010089B00D09C000and given the currentcache/b-<chain>as its first argument, also checks the capture entry and the three translated GS kernels against numeric expectations (498 checks passed on an M4 Pro with Metal API validation). A 90-second Mac run reached the title at 60 fps with no[RED]line (its finalCRASH sig=14is the harness's time limit). Artifacts:010089B00D09C000-work/geometry-build/andgeometry-probe/beside the game's NSPs. - None of them was drawn in the opening observed so far, so their in-game appearance and cost are not checked.
Input
- Controller only, docked, with the 3D pad layout: the investigation moves its cursor with the left stick and the view with the right one.
Mac routes
- The work folder's
run/ctl.shdrives a run started withDM_CTL. From a fresh save: 15 s, A (New Game), Down, Down, A (English), Left, A (Yes), then A every 3 s into the investigation (about 3 minutes). - With the autosave:
DM_KEYS="15:A,18:A,21:Left,22:A,30:A,40:A*45/3"loads it and plays the opening again.
Found on this game
General host changes first needed here; each applies to every game:
- H.264 drain on a released output slot (
ReleaseOutputBufferIndexgoes on with the drain; the end-of-stream output takes the first queued picture,jflush,hle_movie.c): H.264 drain at the end of a stream goes on with released slots. - Per-stage composite taken again after a replay state restore (
prog_resolveinnvn_mtl.m, afterpso_predict_rest, the fusion probe and the deferred-draw replay): Composite program taken again after a replay state restore. - Geometry shaders as compute (native VS capture, GS dispatch, output-reader vertex function;
t_geometry): geometry support and limits. - The spin-wait search's store rule takes one wider loop in its
main: development.md, Power.
Open
game.tsvstill says the 3 geometry shaders "do not build"; the development notes and the geometry research say all 13,057 build, including them.
These notes are republished from the nxnative repository under its MIT license (license and attribution). The original, which may be newer, is the game's notes on GitHub. This site hosts no game files.