How this section is organised

Pages are grouped the way the disc is layered, outermost first: the disc and its one big archive, then how the game unpacks and routes what it loads, then the individual asset types, the stat tables baked into the executable, the bundles a scene loads as a unit, and the archive entries that hold code. New here? Start with disc geometry and PROT.DAT - every other page assumes those two.

Each page carries a badge for how solid its decode is. The badge is a claim about evidence, not page length; a page's own confidence row is authoritative over the badge here.

  • Confirmed - verified end-to-end against real on-disc data, with passing tests.
  • Inferred - deduced from byte patterns; structurally consistent but not exhaustively validated.

Disc + container layer

The disc image before any in-game format is involved: the sector layout, the one archive that holds nearly everything, and the text file that names its contents.

Compression + dispatch

How archive bytes become usable assets: the compression scheme, the type-byte dispatcher, and the several near-identical "many assets in one file" pack layouts.

Legaia LZS Confirmed
The dictionary compression around most bulk assets - a custom LZSS variant with a 4096-byte zero-initialised ring buffer. Random input decodes without error, so always magic-check the output.
Asset type dispatcher Confirmed
How the game knows what a loaded blob is: an 8-bit type byte (0=TIM, 2=TMD, 4=MES, 6=ANM, 7=VDF, 8=SIN, 9=TMD2, B=MOVE2) routes it to a handler and decides LZS-vs-raw. The type names come from the developers' own error strings.
Asset descriptor format Confirmed
The (type_byte << 24) | size calling convention the dispatcher takes, and the descriptor-pair walker that only runtime overlays call.
Pack format Confirmed
The simplest multi-asset bundle: u32 count + u32 word_offsets[count], then assets back-to-back. Used inside DATA_FIELD streaming chunks.
Standalone TIM-pack Confirmed
A near-identical multi-texture bundle in some standalone PROT entries with different header math (byte_offset = word_index*4 + 4). Includes the boot-UI bundle at the head of the archive.
“Field-pack” Confirmed
Not a format: the 0x01059B84 word is a DATA_FIELD chunk header (type byte + payload length) wrapping an asset::pack of one scene's TIM atlases at raw-TOC +4 of its block. The page keeps the reading that made it look like a magic-prefixed bundle.
Player battle files Confirmed
The per-character battle-model files data\battle\PLAYER1..4 (extraction 0863..0866): header + LZS art records + equip-slot descriptor table + per-slot mesh and texture streams. Also the in-battle pose source for the assembled meshes.
Row-479 NPC CLUTs Confirmed
NPC colour palettes: plain PSX TIMs in scene PROT entries whose palette block targets framebuffer row 479. Uploaded with merge-zeros semantics so several scene TIMs share the row.

Per-asset formats

What a single texture, model, sound bank or dialog file looks like once unpacked.

PSX TIM Confirmed
The PlayStation's standard texture format. 4 / 8 / 15 bpp; palettes (CLUTs) scatter across PROT entries. crates/tim exports to PNG and encodes PNG back to TIM.
Legaia TMD Confirmed
The 3D mesh format - a custom variant of stock PSX TMD, magic 0x80000002: offset pointers, an 8-byte primitive group header, and a 6-row shape table that sets each record's layout. No mesh is lit from its normals.
VAB sound bank Confirmed
PSX-standard instrument bank (program / tone / SPU-ADPCM sample). crates/vab extracts and decodes to WAV. The vab_01 block (extraction 1070..1192) is wall-to-wall VAB.
PsyQ SEQ Confirmed
The music sequence format - PsyQ's MIDI-derived pQES container in Legaia's 15-byte-header variant: u32 BE version, PPQN 480, a placeholder tempo the first body event overrides, meta events without a length byte.
XA-ADPCM Confirmed
CD-XA Mode 2 Form 2 streaming audio (voice shouts, ambience). crates/xa demuxes per channel and emits one WAV per stream.
MES dialog Confirmed
The dialog-text container, in Compact and Records variants. Message bytes are font-tile indices with two-byte escapes that splice in the hero's name, item and art names at display time.
Dialog font Confirmed
The proportional Latin font the dialog renderer draws with: a 256-entry width table and a 38-entry escape table in the executable, 4bpp glyph bitmaps in VRAM at (896, 0).
ANM animation Confirmed
Skeletal animation container (asset type 6): count + byte offsets + per-(bone, frame) 8-byte records. Keyframe pose decoder in legaia_anm::AnimPlayer.
Player-character meshes Confirmed
Where Vahn, Noa and Gala's models live. Field form = PROT 0874 §0; battle form is assembled per character from the player battle files' equipment sections, with PROT 1204 as the Baka Fighter / default-equipment sibling pack.
Monster animation Confirmed
Enemy battle animation inside the monster archive (extraction 0867): per-action rigid-transform keyframes, one part per TMD object. Action 0 is the idle loop; the entry's first byte is an action tag, not an index.
MDT - move tables Confirmed
Tactical Arts move records - the fighting-combo system's data. The runtime MOVE base is sourced per scene from a CDNAME slot, not from one boot-time PROT entry.
Move-power table Confirmed
Per-move power + behaviour records (26-byte stride, PROT 0898): damage roll, homing, hit reaction, sound cue and spawned-effect lists, in the same id space as the spell table.
Art data - Tactical Arts records Inferred
Per-character art records (0xD0-stride, in each player battle file's record[0]): command sequence, power bytes at +0x24 (Confirmed), hit-cue timing, impact-effect class. The menu's arrows are a separate SCUS table.
Per-character save record Confirmed
The in-RAM record holding one party member's whole state: 0x414 bytes per slot. Cheat-database-pinned offsets for stats, level, magic rank, spells, summons and equipment.

Battle / stat tables

The game's numbers - item names, spell stats, equipment bonuses, steal chances - are static tables inside SCUS_942.54, the main executable, not in the asset archive. Each is byte-pinned against the executable.

Streaming + scene containers

The bundle formats a scene loads as a unit - room geometry, textures, scripts and audio together - plus the records that drive encounters and scene transitions.

DATA_FIELD streaming Confirmed
The typed-chunk multi-asset container parsed by crates/asset::parse_streaming; a sister detector catches the shape whose final chunk walks past EOF.
Scene bundles Confirmed
The family of per-scene container shapes, each read off its retail walker: battle backdrops, BGM streams, town asset tables, move-VM stager scripts.
scene_v12_table Confirmed
Per-scene .PCH walk-on trigger sidecar: a four-kind sub-table directory plus inline 4-byte trigger records, exactly one sector in all 97 scenes. The stager prescript is the next PROT entry.
Place names Confirmed
One place name, three carriers: the executable's quick-travel cells, the label table trailing every kingdom MAN, and each scene MAN's banner name. Parser legaia_asset::place_names.
World-map slot-4 records Confirmed
Slot 4 of each kingdom bundle is the world-map scene's ANM animation bank - the same clip container every field scene carries: 8-byte entries of three 12-bit translations and three 8-bit rotations, frame-major, read by the clip selector and the animated-mesh renderer. Not a mesh library, and not the bulk continent terrain.
Effect bundles Confirmed
The hit sparks and spell flashes of battle: the runtime efect.dat 2-pack (extraction 0873) - a sprite atlas, frame-animation batches and spawn scripts indexed by effect id.
Per-scene primitive scratch buffer Inferred
A negative finding: the RAM cluster once read as a navmesh is a per-scene scratch buffer the renderer fills with GPU primitive data on scene entry.
Encounter record Confirmed
Which monsters you can meet where: three header bytes, a count, and up to four monster ids, armed on a field actor and copied into the battle loader's formation cell.
MAN relocation Confirmed
How to safely resize a record inside a scene's script bundle: fix the partition tables, the section-0 offset, intra-record jump deltas and the external descriptor size. Powers the door randomizer and translation packs.
STR FMV table Confirmed
How the game finds its movies: a 23-slot dispatch table in the cutscene overlay, nine retail slots covering every movie on the disc; per-scene triggers are literal operands in the scene scripts.

Runtime overlay carriers

Archive entries that hold code, not assets: overlays are chunks of MIPS machine code the game loads into RAM on demand, and most of the game's logic lives in them.

Auxiliary