summon.dat / readef.DAT streaming slots Confirmed
When a character summons a Seru or performs an Art, the assets are not in memory - the game streams them off the CD while the cast animation plays. Two files feed that side-band stream: per-attack texture pages and palettes bound for video memory, the summon creature's mesh and animation, and the player art-animation archives, all in fixed 33-sector slots so any slot can be seeked directly.
At a glance
- In the game
- Every Seru summon and every Art's mid-cast textures; the seven big summons' bespoke creatures
- Where
summon.dat= extraction PROT 893 (raw TOC0x37F);readef.DAT= extraction PROT 894 (raw TOC0x380); CDNAME blockbat_back_dat- Size / stride
- Fixed
0x10800-byte slots: 103 in summon.dat, 78 in readef.DAT, both tiling their entry exactly. No magic; texture slots start with au32 mode, art archives with'M' 'E' - Parser
legaia_actor_formats::summon_readef(+summon_creatures,me_archive); CLIasset summon-readef- Confidence
- Confirmed - slot math read from the battle-action state machine; a mid-cast save state's stream buffer and VRAM byte-match the disc (how we know)
- Used by
- battle action SM, Seru magic & summons, Arts
How a cast reaches the disc
slot × 0x10800, reads one slot into the stream buffer.Both files live inside PROT.DAT like everything else. The dev path strings are ignored - the retail file-open shim is a stub, and the fourth argument goes straight to the PROT reader as a raw TOC index. The in-RAM TOC keeps PROT.DAT's 8-byte header while the extraction strips it, so raw index = extraction entry + 2 (CDNAME numbering).
Action id to slot
The cast sequence computes a base slot byte from the actor's action id. Bit 7 selects the file (set = summon.dat, clear = readef.DAT); base & 0x7F is the first slot of the group.
| Action id | Base slot byte (mod 256) |
|---|---|
id < 0x9A | 3 * (id - 1) |
id >= 0x9A | 4 * id + 0x63 |
| Action ids | File | Group shape | Slots |
|---|---|---|---|
0x01..=0x1A | readef.DAT | 3 slots [texture, aux, aux] | 26 × 3 = 78 |
0x81..=0x99 | summon.dat | 3 slots [texture, texture, actor record] | 25 × 3 = 75 |
0x9A..=0xA0 | summon.dat | 4 slots [texture, texture, raw pool, actor record] | 7 × 4 = 28 |
The bands tile both files exactly. Group 0 of summon.dat (spell id 0x81, Gimard) carries the "Burning Attack" record, matching the spell table's player Seru-magic block.
One summon group; every slot is 0x10800 bytes (33 sectors). VRAM targets are positional: the group's first and second texture slots always land on the same rows and pages. readef.DAT groups stop after base + 1.
Slot formats
Texture slot
mode is 0, 1 or 2. Mode 1 carries two CLUT rows (page at +0x404), modes 0 and 2 one (page at +0x204). Mode 0's page is 64 halfwords wide, modes 1 and 2 are 128.
A summon module's parts sample those pages, so the page in VRAM has to be the cast's own. PROT 0903's fire tunnel draws one of its two additive layers from a single texel of the (512, 0) page through CLUT row 488: with the cast's summon.dat page there the tunnel is orange, with the last monster turn's readef.DAT page left there it draws grey. The port streams a player cast's two texture slots when its stager arms (battle_sideband_textures::record_cast_sideband_textures), and the formation's monster groups at battle entry.
Actor-record slot
Consumed in place, slot-relative offsets. The TMD and texture pool route through the same installer the monster archive uses, and the creature is staged as a battle actor.
- The name is a NUL-terminated attack-name string; the TMD is a Legaia TMD; the texture pool is a monster-style CLUT region + page.
- The stat head uses the monster record's offsets:
+0x0C“HP” is the attack's power feeding the summon damage roll,+0x18INT, and so on. - The stat head is the summon body for every player cast. The installer copies it into actor slot 7 with
FUN_80054CB0(record, 4)(the monster record → actor copy, seat 4 = slot3 + 4), boosting four stats by the fight's profile exactly as for a monster seat, and slot 7 is the attacker every summon module names in its damage roll. Thebattle_datatwin is a mesh source only: its stats are the enemy's (Gimard the enemy is HP 99 / INT 16, the Burning Attack body HP 192 / INT 48), and the flutes and big summons have no twin at all. Parsersummon_readef::cast_record_stats; the engine seats these stats onDiscTables::summon_creaturesat scene entry (monster_catalog::apply_cast_record). +0x1Dis the element of the cast (0 earth, 1 water, 2 fire, 3 wind, 4 thunder, 5 light, 6 dark, 7 none). The installer parks the record at battle slot 7, every summon module calls the damage roll with a hard-coded attacker slot 7, and the element kernels readrecord + 0x1Dfor any slot>= 3- so a cast's element is this byte, never the caster's and never a spell-table field. The Evil Seru Magic record carries 7, which is why its damage matches no elemental guard.- Per-part offsets index animation entries; their base differs by band (below).
Every slot is read whole
The transfer always reads the full 0x10800 bytes, never “the content length”. A slot's content ends where its own format says - a page's width times 256 rows, an actor record's part pool, an ME archive's last entry - and the rest is fill that arrives in the buffer and is never read. Every slot in both files ends in such a run.
Big-summon raw slot
The third slot of the four-slot groups is headerless; three regions tile it exactly (0x1E0 + 0x8000 + 0x8620): a 240-entry CLUT to VRAM (0, 486), a 64×256-halfword page to (448, 256), and a part pool for the creature's animation. Those targets are monster battle slot 2's, so a big summon installs over slot 2 and the ordinary relocation reproduces its placement.
Creature meshes and animation
- Base and evolved-Seru summons (
0x81..=0x95) reuse an enemy: the actor-record TMD is byte-identical to a record in the monster archive (extraction 867), which recovers the spell → creature map (Gimard0x81→ archive id 10). Map inlegaia_actor_formats::summon_creatures. - Big summons (
0x9A..=0xA0) carry a bespoke mesh matching no archive record; their texture pool and animation entries live in the group's raw slot. - Each per-part entry is a monster-animation record: a packed keyframe stream at entry
+0x8C,[u8 parts][u8 frames]then nine-byte TRS records, playback rate at+0x78. No decoder of its own is needed. - Offsets are relative to the actor-record slot for three-slot groups and to the raw slot's part pool (
+0x81E0) for four-slot groups; in both cases the streams tile contiguously.
The seven big summons
Each id is pinned by two independent reads of its own record - the inline attack-name string and the element byte - both agreeing with the curated summon table.
| Spell id | Summon | Attack name | Element byte |
|---|---|---|---|
0x9A | Palma | Meteor Cluster | 0 earth |
0x9B | Mule | Deep Avalanche | 1 water |
0x9C | Horn | Resurrector | 5 light |
0x9D | Jedo | Deadly Promise | 6 dark |
0x9E | Meta | Inferno | 2 fire |
0x9F | Terra | Queen Twister | 3 wind |
0xA0 | Ozma | Voltagor | 4 thunder |
All seven play in the browser on the Seru magic & summons page, decoded from your own disc.
Art "ME" archives
The aux slots of readef.DAT groups 0..3 (slots 3×char + 1 / + 2 for Vahn / Noa / Gala / Terra) hold the player art-animation archives:
The low 15 bits of each size sum to the body offsets. Each decompresses through the channel-delta codec into the same packed TRS stream (see player battle files). Parser legaia_actor_formats::me_archive. The consumer is FUN_8002B28C, called once on the disc — from 0x8004BCA8 in FUN_8004AD80, which expands the selected entry into the scratch at gp[0xA24] and installs that pointer as the art entry’s +0x88 keyframe stream. The streamed buffer *0x8007BD74 has twelve references disc-wide and that is the only content read outside the applier, so the consumer set is closed. The read is gated to party seats 0..2, so a fourth character’s group is decoded only when that character sits in a seat below 3 - which happens (a Terra-in-party battle puts her at seat 1), so readef group 3 is not a dead lane.
Which slot is resident when
- The initiative scheduler seeds the acting entity's group base per turn: party
3 × (char - 1); enemy3 × monster_record[+0x1C]. The character's main ME archive stays resident for the turn. - Battle-end win-pose staging requests slot
3 × char + 2(the base archive) directly. The win-pose pick is re-rolled onto a living party member only when the acting actor is dead - the hole behind the enemy-ally charm softlock. - readef groups stop after
base + 1unless bit 7 is set orbase == 0x36, the one readef id with a four-slot group; the second texture upload is skipped forbase < 0x0Cand0x37..=0x41. - The aux slots of the higher readef groups carry no new kind. The applier's stage-4 gate (
base >= 0x42or0x0C <= base <= 0x36) is a base-byte test it makes before looking at the slot, and it partitions the file exactly: inside the gate thebase+1slot is the group's second texture page (CLUT row 490, page originx = 640); the three groups it excludes from above (base=0x39/0x3C/0x3F) hold an actor record there, byte-identical to theirbase+2slot; below it are the four characters' ME archives. The only installer of an actor record,FUN_801F19EC, is called from slot-B cast modules alone, so on a readef-band cast that record arrives in the streaming buffer and nothing reads it. - Nothing selects those three groups. Sweeping
+0x1Cacross every LZS-decoded record in the monster archive, the byte never leaves0..=25(the file's 26 groups) and never takes 19, 20 or 21 - nor 1, 2, 5, 12 or 23. Group 0 is the roster default (119 of 186 records); the rest are boss and creature-family banks. Two of the unreferenced groups still have a consumer: the AI spell picker reads the first enemy seat's+0x1Cdirectly and compares it against 23, an arm the shipped table never satisfies, and the group-19 / group-21 actor records are byte-identical copies of the ones sitting in groups 23 and 22.
How we know
Routines and the mid-cast capture
| Function | Address | What it proves | Dump |
|---|---|---|---|
Battle-action SM, case 0x32 | FUN_801E295C | Action id → base slot byte; bit 7 file select | funcs/overlay_battle_801e295c.txt |
| Transfer SM | FUN_801F17F8 | Opens by raw TOC index via FUN_800558FC / FUN_8003E8A8; seeks slot × 0x10800; reads into *0x8007BD74 | funcs/overlay_battle_801f17f8.txt |
| Applier SM | FUN_801F12D0, record consumer FUN_801F19EC | Slot classes, VRAM targets, actor-record offsets, readef stop rule | funcs/overlay_muscle_dome_801f12d0.txt, _801f19ec.txt |
| Initiative scheduler | FUN_801DABA4 | Per-turn group base; win-pose re-pick at 0x801E6690 | funcs/overlay_battle_action_801daba4.txt |
| Mesh / texture installer | FUN_80055468 | Shared with the monster archive | funcs/80055468.txt |
| Mid-cast save state | stream buffer + VRAM | 67 584-byte buffer equals extraction 894 at 1 × 0x10800; slot 0's CLUT row and page match VRAM | - |
CLI: asset summon-readef <entry.BIN> lists every slot's class and attack name; --texture-png-dir decodes pages to PNG; --action-id resolves an id to its stream target. Source of record: docs/formats/summon-readef.md.