Skip to content

unityfs: Unity 6000.3 Shader and ComputeShader layouts for stripped player files - #791

Open
gnosticgeek wants to merge 1 commit into
seedds:mainfrom
gnosticgeek:contrib/unity-6000-3-shaders
Open

gnosticgeek wants to merge 1 commit into
seedds:mainfrom
gnosticgeek:contrib/unity-6000-3-shaders

Conversation

@gnosticgeek

Copy link
Copy Markdown
Contributor

Requested by Tom

What and why

Castlevania: Belmont's Curse (game 0100BA4026E94000, on the 01005F4027E94000 cartridge, Unity 6000.3) keeps all 97 Shaders and 11 ComputeShaders in player files without type trees. None of its 368 Addressables bundles holds a Shader, so the split stopped at the built-in resources with "no bundle has a Shader type tree of the same hash to borrow". Shader version 4 (6000.3.0f1 and later) adds m_AssetLocalIdentifierInFile after m_AssetGUID. Each ComputeShader resource gains a resType after its texture dimension. SHADER_6000_3 and COMPUTE_6000_3 match AssetRipper's 6000.3 release dumps node for node, alignment flags included, and both hashes are in KNOWN_TREES.

Checked

  • Tests: dm/gfx/tests/test_unity_*.py pass. test_unity_known_trees.py lists the two new hashes, and test_unity_compute.py reads a 6000.3 ComputeShader fixture through to shader_split. dm/tools/lint_python.py reports 0 new findings.
  • Games run: Castlevania: Belmont's Curse, built with these layouts in a downstream fork. Every stripped object reads to its exact end, and the split gives 2,165 stage shaders. Headless runs reach the title menu and the New Game intro at 30 fps with no RED lines. This branch was not rebuilt against the game.
  • Devices and OS: M4 Pro, macOS 27.0.1.

Docs

  • The finding is in its docs/reference/shaders.md entry (Unity stripped trees list); docs_symptoms.py was not needed, because no new entry heading was added
  • A chain tool changed: unityfs.py feeds the shader split, not the translation chain, so dmsh_chain.h is unchanged
  • No game files, keys or data extracted from a game in the change or the attachments

🤖 Generated with Claude Code

…layer files

Castlevania: Belmont's Curse (01005F4027E94000 cartridge, game 0100BA4026E94000,
Unity 6000.3) keeps all 97 Shaders and 11 ComputeShaders in player files without
type trees, and none of its 368 Addressables bundles holds a Shader. The split
stopped at the built-in resources with "no bundle has a Shader type tree of the
same hash to borrow". Shader version 4 (6000.3.0f1 and later) adds
m_AssetLocalIdentifierInFile after m_AssetGUID, and each ComputeShader resource
gains a resType after its texture dimension. Both layouts match AssetRipper's
6000.3 release dumps node for node, the alignment flags included. Every stripped
object reads to its exact end, and the split gives 2,165 stage shaders; headless runs
reach its title menu and the New Game intro on an M4 Pro Mac.

Both hashes are in KNOWN_TREES and test_unity_known_trees.py, and
test_unity_compute.py reads a 6000.3 ComputeShader fixture through to
shader_split. The entry is in docs/reference/shaders.md.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
seedds added a commit that referenced this pull request Nov 2, 2026
…p GPU skinning (#857)

Hello Kitty Party Land (Unity 6000.3.11f1) drew its characters as huge stretched
triangles. Its ComputeShader objects (class 72, type hash 43a0948a...) have no
type tree from a bundle and no layout in unityfs.py, so the split left out their
kernels, Unity's built-in Internal-Skinning among them. The run then logged "the
dispatched program has no compute shader" and the characters drew from vertex
buffers nothing wrote.

COMPUTE_6000_3 is the 2022.3 layout with an int resType after each resource's
texDimension and threadGroupSize a staticvector again. It is keyed by type hash and
used only for stripped files no bundle lends a tree to.

All 159 nodes and alignment flags match AssetRipper's 6000.3.0b4, 6000.3.0f1,
6000.3.11f1 and 6000.3.20f1 dumps, compared here. PR #857 and PR #791 report the same
hash on different games; those game results were not repeated here, since no game
with this hash is available. The fixture from PR #791 reads to its exact end and into
the split, and fails with the 2022.3 layout. Silver Pines (6000.3.15f1) already has
these kernels in its table without this layout.

PR #791's Shader layout is left out: its hash is not confirmed.

Co-authored-by: James <12531452+capibawa@users.noreply.github.com>
Co-authored-by: Tom Ramsden <13732780+gnosticgeek@users.noreply.github.com>
@seedds

seedds commented Nov 2, 2026 •

Copy link
Copy Markdown
Owner

The compute half of this PR landed on main as ba366d2, consolidated with #857, with you credited as co-author. COMPUTE_6000_3 is the same in both PRs, and your fixture is in test_unity_compute.py (its comment no longer names the game).

I'm keeping this PR open for the rest: SHADER_6000_3, hash 57f0dd2d…, its test and the build_ipa_from_nsp.py line.

The layout looks right. All 2,306 nodes and alignment flags match the 6000.3.0f1, 6000.3.11f1 and 6000.3.20f1 dumps, and the 6000.3.0b4 dump matches SHADER_6000_0, as you say. What I can't confirm is the hash, and the game description doesn't match the copy here. Update 1.1.0 (v65536) of 0100BA4026E94000, now on main, is Unity 2022.3.62f2 with 3,051 bundles. Its loose files hold 145 Shaders and 12 ComputeShaders, all under hashes main already knows, so it needs neither 6000.3 layout.

Could you tell me:

  1. Which build did you test: title ID, display version and the main build ID? Is it the 01005F4027E94000 cartridge?
  2. Which Unity version does that build's Data/globalgamemanagers header name, and do its stripped Shader objects carry 57f0dd2d4ef24437b4655529a673a936?

If that checks out, please rebase this PR down to the Shader part and describe that build in the docs entry. Its failing sanitizer check isn't caused by your change: it was a host timing test that #779 has since removed, so a fresh run should clear it.

@gnosticgeek

Copy link
Copy Markdown
Contributor Author

Thanks for checking this, and for merging the compute half. You're right that the hash doesn't belong to the game. My commit message named the wrong application, sorry about that.

My cartridge is the Midnight Edition (base game only, no update). It holds two applications, and the 6000.3 files come from the second one, the Digital Sound & Art Gallery, not from the game:

0100BA4026E94000 (game) 01005F4027E94000 (Digital Sound & Art Gallery)
Version v0, NACP 1.0.0 v0, NACP 1.0.0
main build ID e7caa6ab07f133269a2705ec9340ac58 79efa8c369b16c2a8b7993675b1f6ee3
Unity (globalgamemanagers header) 2022.3.62f2 (unity default resources: 2022.3.54f1) 6000.3.6f1 (unity default resources: 6000.3.0b4)
Stripped Shader hash (class 48) ea424a5f… 57f0dd2d4ef24437b4655529a673a936
Stripped ComputeShader hash (class 72) bfdf63ab… 43a0948a3f403068c0b31bff90ba0c9a

There's no patch meta on the cartridge; its update partition is only the firmware bundle. I also scanned all 3,025 of the game's Addressables bundles. All 3,508 serialized files in them are 2022.3.62f2, they hold 459 Shaders that all use ea424a5f…, and none of them holds a ComputeShader.

So the game on my cartridge is older than your v1.1.0, but it's on the same Unity 2022.3.62f2 as your profile and needs neither 6000.3 layout. That's consistent with what you found. The 97 Shaders, 11 ComputeShaders, and 2,165 stage shaders in the PR all come from the Gallery. That's also how my first build ended up packing the Gallery: nx_extract picked the lower title ID, and the build_ipa_from_nsp.py line in this PR fixes that by taking the application with the largest program. The headless runs that reached the title menu and New Game intro were of the game after that fix, on the 2022.3 path, so they say nothing about SHADER_6000_3. The only evidence for the Shader layout is that all 97 of the Gallery's stripped Shader objects read to their exact ends. I haven't run the Gallery.

If you still want the Shader layout with the Gallery as its sample, I'll rebase this down to SHADER_6000_3, its test and the build_ipa_from_nsp.py line, and rewrite the docs entry to name the Gallery (01005F4027E94000, 6000.3.6f1, build ID above) in place of the game. If you'd rather wait for a 6000.3 game that actually ships it, I'm happy to split the cartridge fix into its own PR and close this one.

@github-actions github-actions Bot added nvn NVN on Metal and its tests (dm/gfx/nvn, dm/gfx/tests) packing Building an IPA or a Mac app: the NSP script, extraction, the shader split, the packers tools Tools and scripts (dm/tools, scripts) docs Documentation labels Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation nvn NVN on Metal and its tests (dm/gfx/nvn, dm/gfx/tests) packing Building an IPA or a Mac app: the NSP script, extraction, the shader split, the packers tools Tools and scripts (dm/tools, scripts)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants