Skip to content

Port UnityPy Asset Extraction Logic with Snapshot Validation #1

Description

@atniptw

Goal

Port UnityPy's core asset extraction logic to enable reading Unity bundle files (.hhh) and generating equivalent JSON snapshots. This will allow asset inspection and manipulation in other contexts.

Scope

The logic to extract:

  • Bundle file parsing and asset loading
  • Object hierarchy (GameObjects, Transforms, Components)
  • Mesh data (vertices, indices, UVs, normals)
  • Material definitions (colors, floats, textures, properties)
  • Texture data (PNG export from Texture2D objects)
  • Animation metadata (if applicable)

Validation Strategy

We have 10 reference bundles with known-correct snapshots that can validate the port:

Bundle Objects Textures Notes
SamusPlushie_body 25 2 Static body model
BambooCopter_head 13 0 Static head model
ClownNose_head 10 0 Static head model
FoxMask_head 11 1 Static head model
FrogHatSmile_head 11 1 Static head model
AmyBackpack_body 13 1 Static body model
Aku Aku_world 228 1 Animated (SkinnedMeshRenderer)
Cigar_neck 17 0 Particle system
Odradek_neck 55 0 Static neck model
Volleyball_world 22 0 Static world object

Correctness validation: The ported logic is correct if it generates identical JSON snapshots with matching:

  • Object counts per bundle
  • Mesh vertex/index/UV counts
  • Material property values
  • Texture extraction results
  • Path IDs (as strings to preserve 64-bit precision)

Reference snapshots are located in: snapshots/{bundle_name}/

Expected Output Format

Each bundle snapshot contains:

snapshots/{bundle_name}/
  ├── manifest.json          # Bundle metadata
  ├── summary.json           # Object type counts
  ├── textures_index.json    # (if textures present)
  ├── objects/
  │   ├── 000_Type_PathID.json
  │   ├── 001_Type_PathID.json
  │   └── ...
  └── textures/              # (if textures present)
      ├── tex_PathID.png
      └── ...

Key Implementation Details

  • Path IDs must be serialized as strings to preserve JavaScript 64-bit integer precision
  • Material TexEnvs are tuples: ('_MainTex', {'m_PathID': '12345', ...})
  • Some bundles have no textures (field may be absent from materials)
  • SkinnedMeshRenderers contain skeleton/bone data (AnimationClips for Aku Aku_world)
  • ParticleSystems have different structure than MeshRenderers (Cigar_neck)

Success Criteria

✅ Generated snapshots match reference snapshots for all 10 bundles
✅ Object counts match exactly
✅ Mesh geometry is byte-for-byte identical
✅ All property values match (colors, floats, textures)
✅ Texture PNGs match original extractions

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions