HAL keeps its assets in .cmp containers: a 4-byte little-endian uncompressed size, then a frame (zstd, or LZ4 in the ubin/ map data). The split decompressed a zstd file by its magic at offset 0, so a frame that starts at offset 4 was read raw, and the shaders inside the BFRES archives of those containers were never seen. On Kirby and the Forgotten Land this is the difference between 121 shaders found and 27,288, and between a game that plays and one that shows a black screen: the game asked for 900 shaders the map did not have, and the log filled with "[RED] shader ... is not in the shader map". The split now opens a size-prefixed frame (unzs_bytes for zstd, unlz4_bytes for LZ4). The size prefix is checked against the decompressed length, so a file that is not a container is left alone, and a container that does not open is reported instead of being passed over in silence. - Found on: Kirby and the Forgotten Land (01004D300C5AE000, in bring-up): 7,201 .cmp files, 5,121 zstd frames with 19,364 BNSH inside (11.2 GB decompressed) and 2,080 LZ4 frames (0.3 GB, no BNSH). The split now finds 27,288 shaders: 18,476 in gfx/, 8,313 in ptcl/, 383 in lyt/, 67 in the loose shader files, 54 in main. - No other game on hand has such a file: Super Mario Bros. Wonder (v0 and v65536) and Yoshi's Crafted World (v1.0.1) have none. - The chain version is unchanged: shader_split.py is not one of the chain's tools (dm/gfx/nvn/dmsh_chain.h needs no rewrite). - The docs entry is in docs/reference/shaders.md; the symptom index is regenerated. All 15 test files in dm/tools/tests pass. Co-Authored-By: Claude Code <noreply@anthropic.com>
Subsystem references
How the host meets each part of a Switch game, and every failure met so far, one entry per mechanism: symptom, cause, fix (file and function), the games it was found on (linked to their notes in dm/games/<id>/README.md). Start from the symptom index when you have a log line or a visible result; the workflows that lead here are in docs/agents.
| File | Covers |
|---|---|
| packing.md | NSP script, compressed inputs and build artifacts |
| rewriter.md | The NSO rewriter patch_nso.py: jump tables, exclusive windows, patch area reach, cuts and observation gates, functions without unwind entries, stack and system registers, relocations |
| memory.md | Guest layout, heap and application pool, virtual address memory and the alias region (the SDK's node area), engine allocators, mapping SVCs, running out of memory |
| threads.md | Thread creation and cores, address arbitration, yields and spin waits, events |
| services.md | SDK calls and system services: sm connections, names that changed between SDKs, file system and saves, add-on content, input, keyboard and applets, display and operation mode, accounts and network, settings and fonts, C library and time, modules |
| movies.md | The SDK's movie library: decoder lifecycle, output slots, native-texture output, demuxers and codecs, game movie players |
| audio.md | The audio renderer and its command lists by SDK, AudioOut and devices, codecs, timing |
| frame-rate.md | The host's frame step, engine frame limiters, present intervals and display rates, CPU cost |
| nvn-objects.md | NVN object sizes, memory pools, command memory, queues and syncs, CPU-written textures, NVN entry points |
| rendering.md | The replay on Metal: textures, passes and clears, blend / depth / stencil, vertex input, uniforms and ordering, conditional rendering; the Vulkan and OpenGL layers |
| shaders.md | Shader containers by engine, control sections and code, translation, bindings and handles, shaders compiled at run time, pipelines and caches |
| game-state.md | Saves, scripted state, and game behaviour that looks like a host bug but is not |
A new general finding goes into the file and section it belongs to, in the same form, with a line in the symptom index; a fact about one game goes into that game's note.