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, 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. One detail walkthroughs get wrong: the two "defense numbers" listed for boots are really a small attack
bump plus lower-defense - and no equipment in the game touches AGL at all.
At a glance
- Magic
- none - static data in
SCUS_942.54 - Where
DAT_80074F68(file offset0x65768), 8-byte stride, indexed by the item property table's+1byte forkind == 1items- Parser
legaia_asset::equip_stats; engineengine-core::equipment::DiscEquipInfo; patcherlegaia_patcherequipment feature- Confidence
- Confirmed - stat targets pinned from the aggregator's five accumulators (how we know);
+1/+2/+3byte-exact against curated gamedata;+0/+4targets 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
+5 passive slot is 0x40 (no passive) on every retail row.| Offset | Type | Field | Meaning |
|---|---|---|---|
+0 | u8 | INT bonus | head gear sets it |
+1 | u8 | ATK bonus | weapons' only field; boots also add a small amount |
+2 | u8 | UDF (defense-up) bonus | body armor + head gear |
+3 | u8 | LDF (defense-down) bonus | body armor + boots |
+4 | u8 | SPD bonus | only footwear sets it |
+5 | u8 | passive-effect index | 0x40 (the no-passive sentinel) on every retail row (details) |
+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 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/+3magnitudes are byte-exact against the curated gamedata;+0/+4have 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.
- Accessories ("Goods") do not appear in this table at all: they are
kind == 2items 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
| Function | Address | What it proves | Dump |
|---|---|---|---|
| Equip-effect aggregator | FUN_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-loader | FUN_801CF5D0 | Loads 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_80042558 | The kind == 1 arm reads +5 as a passive index. | funcs/80042558.txt |
| Item-detail renderer | FUN_801D5AE8, reads at 0x801D5C90..A0 | Second +5 reader: row-keyed lookup, < 0x40 bound, passive name table at 0x8007625C. | funcs/overlay_menu_801d5ae8.txt |
| Disc-gated tests | equip_stats_real, equip_modifiers_disc, equip_slots_vs_disc | Bytes, 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/+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.