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 TOC 0x37F); readef.DAT = extraction PROT 894 (raw TOC 0x380); CDNAME block bat_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 a u32 mode, art archives with 'M' 'E'
Parser
legaia_actor_formats::summon_readef (+ summon_creatures, me_archive); CLI asset 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

1
Cast begins
The battle-action state machine turns the action id into a base slot byte; bit 7 picks the file.
battle overlay
2
Transfer
Opens the file by raw PROT TOC index, seeks slot × 0x10800, reads one slot into the stream buffer.
transfer SM
3
Apply
Each arriving slot is consumed: palette rows and texture pages go to VRAM, the actor record becomes a battle actor.
applier SM
4
Draw
The summon animates through the ordinary rigid-transform battle draw from its per-part keyframe streams.
monster animation decoder

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 (actor +0x1DF)or turn group base bytectx+0x277 summon.datextraction 893 readef.DATextraction 894 bit 7 set bit 7 clear slot = base & 0x7F0x10800 bytes each stream buffer*0x8007BD74 texture slotVRAM CLUT row + page actor recordFUN_801F19EC → slot-7 actor big-summon raw slotVRAM + part pool ME archiveart entry +0x88 stream
One byte picks both the file and the slot; whatever the slot holds, it lands in the same stream buffer, and its kind decides where it goes next.
Action idBase slot byte (mod 256)
id < 0x9A3 * (id - 1)
id >= 0x9A4 * id + 0x63
Action idsFileGroup shapeSlots
0x01..=0x1Areadef.DAT3 slots [texture, aux, aux]26 × 3 = 78
0x81..=0x99summon.dat3 slots [texture, texture, actor record]25 × 3 = 75
0x9A..=0xA0summon.dat4 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.

base + 0texture slotCLUT (0,488), page (512,0)
base + 1texture slotCLUT (0,490), page (640,0)
base + 2raw pool slotbig summons only
last slotactor recordname, TMD, textures, clips

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

+0x000modeu32
+0x004CLUT row(s), 256 × BGR5550x200 per row
+0x204 / +0x4044bpp texture page, 256 rows0x8000 / 0x10000

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.

+0x00name offsetu32
+0x04TMD offsetu32
+0x08texture-pool offsetu32
+0x0Cmonster-shaped stat head…
+0x1Delementu8
…  
+0x4Apart countu8
+0x4Cper-part offsetsu32[parts]
  • 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, +0x18 INT, 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 = slot 3 + 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. The battle_data twin 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. Parser summon_readef::cast_record_stats; the engine seats these stats on DiscTables::summon_creatures at scene entry (monster_catalog::apply_cast_record).
  • +0x1D is 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 read record + 0x1D for 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 (Gimard 0x81 → archive id 10). Map in legaia_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 idSummonAttack nameElement byte
0x9APalmaMeteor Cluster0 earth
0x9BMuleDeep Avalanche1 water
0x9CHornResurrector5 light
0x9DJedoDeadly Promise6 dark
0x9EMetaInferno2 fire
0x9FTerraQueen Twister3 wind
0xA0OzmaVoltagor4 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:

+0'M' 'E'magic
+2countu8
+3entry_sizes[count]u16, bit 15 = compressed
…bodies back to back 

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); enemy 3 × 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 + 1 unless bit 7 is set or base == 0x36, the one readef id with a four-slot group; the second texture upload is skipped for base < 0x0C and 0x37..=0x41.
  • The aux slots of the higher readef groups carry no new kind. The applier's stage-4 gate (base >= 0x42 or 0x0C <= base <= 0x36) is a base-byte test it makes before looking at the slot, and it partitions the file exactly: inside the gate the base+1 slot is the group's second texture page (CLUT row 490, page origin x = 640); the three groups it excludes from above (base = 0x39 / 0x3C / 0x3F) hold an actor record there, byte-identical to their base+2 slot; 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 +0x1C across every LZS-decoded record in the monster archive, the byte never leaves 0..=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 +0x1C directly 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
FunctionAddressWhat it provesDump
Battle-action SM, case 0x32FUN_801E295CAction id → base slot byte; bit 7 file selectfuncs/overlay_battle_801e295c.txt
Transfer SMFUN_801F17F8Opens by raw TOC index via FUN_800558FC / FUN_8003E8A8; seeks slot × 0x10800; reads into *0x8007BD74funcs/overlay_battle_801f17f8.txt
Applier SMFUN_801F12D0, record consumer FUN_801F19ECSlot classes, VRAM targets, actor-record offsets, readef stop rulefuncs/overlay_muscle_dome_801f12d0.txt, _801f19ec.txt
Initiative schedulerFUN_801DABA4Per-turn group base; win-pose re-pick at 0x801E6690funcs/overlay_battle_action_801daba4.txt
Mesh / texture installerFUN_80055468Shared with the monster archivefuncs/80055468.txt
Mid-cast save statestream buffer + VRAM67 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.

See also