Equipment stat-bonus table Confirmed
The numbers behind every weapon, armor piece, helmet, and boot: a static table in
SCUS_942.54 (the game's main executable on the disc) giving each equippable item its stat
bonuses, the characters allowed to equip it, and which of the four equip slots it fills. Eight bytes per item
cover all of it - five bonus bytes, a character mask, and a slot/flag byte. It hangs off the shared item property table: an item whose kind byte is 1
(equipment) uses its +1 byte as the index into this table. One detail walkthroughs get wrong: the
two "defense numbers" listed for boots are actually a small attack bump plus lower-defense - and no equipment
in the game touches AGL at all (see superseded readings).
Indexing (Ghidra-traced)
The chain below is read out of the game's own code with Ghidra, the disassembler this project uses (FUN_80xxxxxx names are traced functions, DAT_80xxxxxx fixed RAM addresses - static data, so each maps straight back to file bytes in SCUS_942.54). From the equip-effect aggregator FUN_801CF650 (in the menu overlay - a chunk of code loaded into RAM on demand), which walks a character's five equipment slots and sums their bonuses into the equip-screen preview:
kind = item_table[id].byte(+0) ; DAT_80074368[id*0xC]; 1 = equipment
bonus_index = item_table[id].byte(+1) ; DAT_80074369[id*0xC]
record = (&DAT_80074F68)[bonus_index * 8] ; stride-8 record
; applied only when kind == 1; record[+0..+4] sum into five stat accumulators
Record layout (8 bytes, stride 0x8)
| Field | Value |
|---|---|
| Record base | DAT_80074F68 (file offset 0x64F68 in SCUS_942.54) |
| Stride | 0x8 bytes |
| Index | item property +1 byte (per equippable id) |
| Offset | Type | Field |
|---|---|---|
+0 | u8 | intelligence (INT) bonus - head gear sets it |
+1 | u8 | attack (ATK) bonus - weapons' only field; boots also add a small amount |
+2 | u8 | defense-up (UDF) bonus - body armor + head gear |
+3 | u8 | defense-down (LDF) bonus - body armor + boots |
+4 | u8 | speed (SPD) bonus - only footwear sets it |
+5 | u8 | passive-effect index slot - 0x40 (the no-passive sentinel) on every retail row; read by the kind == 1 arm of the passive aggregator FUN_80042558 |
+6 | u8 | equip character mask: bit 1 Vahn/Meta, 2 Noa/Terra, 4 Gala/Ozma; 7 = any |
+7 | u8 | slot type (& 0x60: 0x00 body, 0x20 head, 0x40 weapon, 0x60 footwear) + bit 0x01 = Ra-Seru |
Each byte's stat target is pinned by tracing the aggregator's five accumulators back to the live character-record stat block (AGL, ATK, UDF, LDF, SPD, INT at record +0x110..+0x11B): +0 → INT, +1 → ATK, +2 → UDF, +3 → LDF, +4 → SPD. Equipment never modifies AGL - the AGL accumulator takes no equipment add. The +1/+2/+3 magnitudes are additionally byte-exact against the curated gamedata; the +0/+4 magnitudes have no external cross-check, but the disc-gated test asserts the slot invariant (INT only on head gear, SPD only on footwear).
Slot model
The four +7 categories are Legaia's four armour/weapon equip slots - there is no missing "8-slot" disambiguation. Cross-referencing against the curated gamedata by item name pins it exactly:
+7 category | Slot | Count (disc = gamedata) | Examples |
|---|---|---|---|
0x40 | weapon | 50 (incl. Ra-Seru tiers) ≥ 27 curated | Survival Knife, Mace |
0x00 | body armor | 20 = 20 | every body armour |
0x20 | head | 15 = 15 | Warrior Seal, Royal Crown, Ra-Seru Helmet |
0x60 | footwear | 16 = 16 | every greave / shoe |
The disc "head" bucket is exactly the gamedata helmet set - no helmet-vs-ring-vs-accessory collision. None of the accessories ("Goods") appear in this table at all: accessories are kind == 2 items whose descriptor byte indexes the separate 64-slot passive-effect space (see legaia_asset::accessory_passive). Weapon is the only non-1:1 category because the disc enumerates the upgradeable Ra-Seru weapon as per-tier entries the curated table collapses.
Parser + engine consumption
legaia_asset::equip_stats::EquipStatTable::from_scus resolves the property + bonus tables from a SCUS_942.54 image (PSX-EXE t_addr → file-offset map). EquipBonus::equips_party_slot(party_slot) maps a party slot (0 Vahn, 1 Noa, 2 Gala) to the mask bit 1 << party_slot, matching the retail equip-screen gate. The disc-gated equip_stats_real test pins attack / defense bytes, equip masks, and slot types against the real executable and curated gamedata.
In the engine, legaia_engine_core::equipment::DiscEquipInfo lifts the +6 mask and +7 category keyed by real item ids; the equip session filters each character's per-slot item list on it, so a Vahn-only weapon never appears in Noa's weapon picker. The disc-gated equip_modifiers_disc test drives the whole chain on the real executable.
Superseded readings
Superseded readings
- The earlier "agility / speed pair" reading of
+0/+4is falsified:+0is the INT bonus (head gear),+4is the SPD bonus (footwear), and no equipment byte touches AGL. - Boots/shoes spread bonuses across
+1(small attack bump),+3(LDF), and+4(SPD) - a walkthrough listing only "two defense numbers" for a boot is reading+1and+3, not+2/+3.