At a glance

Magic
none - static data in SCUS_942.54
Where
DAT_80074F68 (file offset 0x65768), 8-byte stride, indexed by the item property table's +1 byte for kind == 1 items
Parser
legaia_asset::equip_stats; engine engine-core::equipment::DiscEquipInfo; patcher legaia_patcher equipment feature
Confidence
Confirmed - stat targets pinned from the aggregator's five accumulators (how we know); +1/+2/+3 byte-exact against curated gamedata; +0/+4 targets fixed, magnitudes not externally cross-checked
Used by
Battle formulas (half of one slot folds into ATK at swing time), Shops page, Characters page, ROM patcher

Record layout

An item whose kind byte in the item property table is 1 (equipment) uses its +1 byte as the index into this table:

kind        = item_table[id].byte(+0)            ; 1 = equipment
bonus_index = item_table[id].byte(+1)
record      = (&DAT_80074F68)[bonus_index * 8]   ; stride-8 record
INT ATK UDF LDF SPD passive who slot +0 +1 +2 +3 +4 +5 +6 +7 five bonus bytes - never AGL character mask + slot/Ra-Seru byte
One 8-byte record per equippable item. The +5 passive slot is 0x40 (no passive) on every retail row.
OffsetTypeFieldMeaning
+0u8INT bonushead gear sets it
+1u8ATK bonusweapons' only field; boots also add a small amount
+2u8UDF (defense-up) bonusbody armor + head gear
+3u8LDF (defense-down) bonusbody armor + boots
+4u8SPD bonusonly footwear sets it
+5u8passive-effect index0x40 (the no-passive sentinel) on every retail row (details)
+6u8equip character maskbit 1 Vahn/Meta, 2 Noa/Terra, 4 Gala/Ozma; 7 = any
+7u8slot type& 0x60: 0x00 body, 0x20 head, 0x40 weapon, 0x60 footwear; bit 0x01 = Ra-Seru
  • Each byte's stat target is pinned by tracing the equip-screen aggregator's five accumulators back to the live character-record stat block (how we know). Equipment never modifies AGL - the AGL accumulator takes no equipment add.
  • The +1/+2/+3 magnitudes are byte-exact against the curated gamedata; +0/+4 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 categorySlotCount (disc = gamedata)Examples
0x40weapon50 (incl. Ra-Seru tiers) ≥ 27 curatedSurvival Knife, Mace
0x00body armor20 = 20every body armour
0x20head15 = 15Warrior Seal, Royal Crown, Ra-Seru Helmet
0x60footwear16 = 16every greave / shoe
  • The disc "head" bucket is exactly the gamedata helmet set - no helmet-vs-ring-vs-accessory collision.
  • Accessories ("Goods") do not appear in this table at all: they are kind == 2 items whose descriptor byte indexes the separate 64-slot passive-effect space.
  • 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 maps a party slot (0 Vahn, 1 Noa, 2 Gala) to its mask bit, matching the retail equip-screen gate.

In the engine, 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 +5 byte: a passive slot nothing uses

Two retail readers reach the byte - the passive aggregator's equipment arm, and the shop sell-panel's item-detail renderer, which bounds it below 0x40 before indexing the passive name table. Because every retail row carries the 0x40 sentinel, that arm never produces a passive on an unmodified disc: a reader who finds the chain and not the data will go looking for equipment passives that are not missing. The byte is row-keyed, not item-id-keyed - several item ids resolve to one bonus row. Parser side: EquipBonus::passive_index / has_passive, mirrored at DiscEquipInfo::row_passive_index.

How we know

FunctionAddressWhat it provesDump
Equip-effect aggregatorFUN_801CF650 (menu overlay)The index chain (item +1 byte → stride-8 record, gated on kind == 1) and the five add-backs. The +0 add lands on the last accumulator, out of sequence with +1..+4 - the detail that pins INT and rules out an in-order guess. No store to the AGL accumulator exists in the function.funcs/overlay_menu_801cf650.txt
Accumulator pre-loaderFUN_801CF5D0Loads the five accumulators from the character record's live-stat block (+0x110..+0x11B: AGL, ATK, UDF, LDF, SPD, INT), fixing each equip byte's stat target.funcs/overlay_shop_save_801cf5d0.txt
Passive aggregator (equip arm)FUN_80042558The kind == 1 arm reads +5 as a passive index.funcs/80042558.txt
Item-detail rendererFUN_801D5AE8, reads at 0x801D5C90..A0Second +5 reader: row-keyed lookup, < 0x40 bound, passive name table at 0x8007625C.funcs/overlay_menu_801d5ae8.txt
Disc-gated testsequip_stats_real, equip_modifiers_disc, equip_slots_vs_discBytes, masks and slot types against the real executable + curated gamedata; the +5 sentinel across all rows; the engine equip-gate chain end to end.-

The per-instruction walkthrough of the five adds is in the source doc.

History: the "agility / speed pair" reading
  • An "agility / speed pair" reading of +0/+4 is falsified: +0 is the INT bonus (head gear), +4 is 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 +1 and +3, not +2/+3.

See also