Skip to content

File Formats

xAstroBoy edited this page Jul 2, 2026 · 2 revisions

File Formats

All of these were reverse-engineered from libshell.so (V79 and V205.2 databases). This page is the quick reference; the code in src/loaders/ and src/cook/ is the authority.

V79 side — OPA container (OPAA)

A V79 official home is an APK whose assets/scene.zip holds content/ descriptors + cache/android/ cooked .opa blobs. Common blob types:

File Contents
<fbx>.opa Model geometry: node hierarchy, per-material submeshes, positions/UVs/indices.
<name>.skin.opa Skinned mesh: SkinnedPos (pos f32×3 + weights f16×4 + bone idx u8×4), StdData (uv f16×2), indices, joint-name list, per-bone inverse-bind.
<name>.skel.opa Skeleton: jointIds (u64), joint names, parent indices, per-joint local bind TRS (T3, quat wxyz, S3).
<name>.anim.opa Clip: joint-name list, Transform track = per-frame per-joint parent-local 4×4.
<fbx>.sanim.opa Node/material animation: per-node Translation(3)/Rotation(4 quat)/Scale(3) and UVTransform(6 = 2×3) tracks.
<name>.mat.sanim.opa Per-material UV/tint sub-animation (UVTransform, MaterialTint RGBA).

Track record layout (shared): a name marker (0xFFFF len string) then a 12-byte header (flag, nKeys, nVals) then nVals floats. Derive frames = nVals / comps (comps = 3/4/6) — never from nKeys (flag=1 tracks pad key-time data). Strings are length-prefixed with no char filter (joint names can contain : from Maya/FBX namespaces).

V205 side — HSL APK

The cook emits a modern HSL environment. Key file-ids (FlatBuffer-wrapped):

File-id Contents
RENDMESH Cooked geometry (vertex streams by semantic, submeshes, skin block for skinned meshes).
MATL Material: shader ref (FlatBuffer field 7 via vtable, not a fixed offset), blend/depth/cull, texture slots, matParams constant block.
HSTF Scene: entities + components (Transform, Mesh, Skybox, Collider, Animator, Audio, …).
HZAN / ASMH Animation: HZAN:SKEL skeleton + ACL-compressed HZAN:ANIM (magic 0xA34912B6) clip.
RENDTXTR (TXTR) Texture: ASTC (or R16G16B16A16 for VAT), width/height, mip count, byte blob.

matParams binding

Cooked material constants bind to the shader UBO by MurmurHash3("matParams." + name) — match by name, not slot order.

VAT texture (encodeVatTexture)

f2 = 5R16G16B16A16_SFLOAT (libshell TextureFormat 97), width = vertexCount, height = frameCount, each texel = that vertex's local-space offset (x,y,z) + w=1 for that frame. Cooked with a full half-float mip chain (the device GPU-uploads it like ASTC and expects the chain — do not strip it). The vatunlitbasecolor shader samples by (vertexIndex, time) and does pos += offset.

Coordinate / transform notes

  • V79 skinned SkinnedPos verts are model-local; world placement is in the skeleton bind.
  • HSTF localRotation is euler radians (no w); clipFromWorld = P·V (model is a push-constant).
  • Depth is reversed-Z on D32_SFLOAT.

Related: Architecture · Animation System · Developer Guide.

Clone this wiki locally