At a glance

In the game
every item use from the field menu or the battle Item command; which items are greyed out where
Magic / marker
none - a fixed table in SCUS_942.54
Lives in
SCUS VA DAT_800752C0 (file 0x65AC0), 130 × 4-byte records, ending where the spell table begins; heal amounts at 0x8007655C
Retail readers
menu-usability gate, field list builder, apply handler (how we know)
Parser
legaia_asset::item_effect::ItemEffectTable (from_scus, heal_amounts, restore_amount, stat_effect)
Confidence
Confirmed - Ghidra-traced readers; disc-gated item_effect_real pins the bytes and cross-checks each against its on-disc description

What it is and is not

The amounts are not here

This table holds class + tier + flags. "Healing Leaf restores 200 HP" is split in two: this table says (class = heal-HP, tier = 0), and the tier → 200 mapping is the separate, also-static heal-amount table. Stat-up and buff magnitudes (classes 5/6/7) are inline immediates in the apply handler.

It is the sibling of the item-name table and the spell table: the three are contiguous static data. The lookup is double-indirected - an item id resolves to a subtype byte in its name-table record, and the subtype picks a descriptor here - so many items share one descriptor, and "key items are unusable" is not a special case at all: a key item simply resolves to a descriptor with neither usability bit set.

1
item id
item_name_table[id].byte(+1) - the subtype
item_table
2
descriptor
DAT_800752C0[subtype * 4] - class, tier, flags, passive index
item_effect
3
amount
HP / MP classes read the tier tables; stat classes use handler immediates
heal_amounts

Record layout (4 bytes, 130 records)

OffsetSizeFieldMeaning
+01classeffect class - the action-validator arm (table below)
+11tierper-class sub-case; heal-HP 0/1/2 = 200 / 800 / full, stat-up = which stat, book = level
+21flagspopulated / info-panel / all-party / battle-usable / field-usable bits (below)
+31passive-effect index0x00..=0x3F for accessory / quest-item rows (the accessory-passive table); 0x41 = no-passive sentinel on consumable rows

Flag byte (+2)

BitMeaning
0x80populated - set on every descriptor that has an effect
0x40draws its own info-panel body instead of the passive block - exactly five subtypes: the Point Card and the two summon-flute pairs (the Point Card arm prints the live points bank; see shop)
0x20whole-party target (all-targets validator)
0x04usable from the battle item menu
0x02usable from the field item menu

Healers carry 0x04 | 0x02; permanent stat-ups and field-utility items carry 0x02 only; status-cures and revive carry 0x04 only. Key items resolve to a descriptor with neither usability bit (e.g. flag 0x89), which is how the menu greys them out. The class byte is meaningful only together with the usability flags - many key items funnel to class 0 with no usability bit, so "class 0" alone is not "an HP potion".

Class byte (+0)

Class labels are validated against the on-disc item description strings:

ClassEffectExample item
0 / 1heal HP, one ally / whole partyHealing Leaf / Healing Bloom
2restore MPMagic Leaf
3 / 8cure all status / cure single statusMedicine / Antidote
4revivePhoenix
5extend action gauge (one battle)Fury Boost
6permanent stat-up (tier = which stat)Miracle Water, the Water line
7temporary stat buff (one battle, ×6/5)Power Elixir
11/12/13arts book (Fire/Wind/Thunder; tier = book level)Fire Book I
14Point Card strike - reachable code, no item on the disc reaches it-
126/127summon fluteLippian Flute
128 / 129field escape (dungeon) / field warp (city)Door of Light / Door of Wind
130reduce encounter rateIncense
Class 14: the Point Card strike nothing sells

The class-14 arm of the apply handler takes min(points_bank, 9999) off the Point Card bank and applies it as battle damage - a strike scaling with how much the player has shopped. Decoding all 256 item records finds no item carrying class 14, so retail never opens the arm; the LEGAIA_POINT_CARD_MAX probe knob reaches it only by forcing the bank. Unused content, not a missing item.

Heal-amount table

The literal restore amounts the apply handler reads: two contiguous u16[4] sub-tables indexed by the descriptor tier (base + tier*2); only tiers 0..=2 are read flat.

VASub-tableTier 0Tier 1Tier 2Read by
0x8007655C (file 0x66D5C)HP restore cap2008009999classes 0 / 1
0x80076564MP restore cap5020020class 2
  • Each restore is deficit-clamped (applied = min(max - current, table[tier])), so tier 2's 9999 is an effective full restore.
  • Tier 3+ HP heals do not read this table - they are character-relative, scaled off the per-character Seru-heal tables.
  • Revive (class 4) is not a flat amount: tier 0 restores max_hp×0.4 + rand()%(max_hp/8), higher tiers a full revive.
History: "the amounts are overlay-resident immediates"

An earlier reading placed the restore amounts in a switch of immediates inside an overlay-resident handler outside the dumped corpus. The HP / MP amounts are static tier tables read by the static apply handler; only the class 5/6/7 magnitudes are immediates. Recorded on settled threads.

Stat-up / buff items (classes 5/6/7)

These classes read no data table - their magnitudes are inline immediates in the apply handler's case 5/6/7, so the (class, tier) → effect mapping is pinned to the disassembly while each item's (class, tier) is parsed from the descriptor. In brief: the Water line adds a flat permanent increment to one stat (tier selects which), the Elixirs multiply a battle-actor stat by 6/5 for the rest of the battle, and Fury Boost widens the action gauge. Parser: stat_effect(id)ActionGauge / Permanent / BuffOneBattle.

Full magnitude tables (Waters, Elixirs, Fury Boost)

Class 6 - permanent stat-up (field-use, flag 0x82)

Adds a flat increment to the character record, tier selecting the stat:

TierStatRecord offsetDeltaCapItem
0Max HP+0x11C+169999Life Water (0x82)
1ATK+0x124+4999Power Water (0x83)
2DEF (both facets)+0x126 / +0x128+4999Guardian Water (0x84)
3SPD+0x12A+4999Swift Water (0x85)
4INT+0x12C+4999Wisdom Water (0x86)
5Max MP+0x11E+8999Magic Water (0x87)
6all (AGL/HP/ATK/SPD/INT/MP/DEF)-+4 eachAGL 280, HP 9999, else 999Honey (0x65), Miracle Water (0x6D)

Class 7 - one-battle buff (battle-use, flag 0x84)

Multiplies the battle-actor stat halfwords by 6/5 (the handler's uVar + uVar/5), clamped to 0xFFFF, for the rest of the battle:

TierStat(s)Item
1SPD (+0x164/+0x166)Speed Elixir (0x8D)
2DEF, both facets (+0x15C/+0x15E, +0x160/+0x162)Shield Elixir (0x8C)
3ATK (+0x158/+0x15A)Power Elixir (0x8B)
4all - SPD + DEF + ATK + AGL (+0x168/+0x16A)Wonder Elixir (0x8E)

Class 5 - Fury Boost (0x81) sets the actor +0x1F9 gauge flag; the action-SM gauge-build phase then sizes the gauge as gauge_stat * 7 / 5 + 8 (clamped to 0x120). See the buff-selector table on the battle-formulas page.

How we know

FunctionAddressWhat it provesDump
Menu-usability gateFUN_8003043CThe subtype → descriptor index chain; the & 0x20 all-party test selecting the all-targets validator call; an item is offered only when at least one eligible target would benefit (walks the live party calling FUN_8003fb10(class, tier, target) per member).funcs/8003043c.txt
Field list builderFUN_80030628Reads the 0x02 / 0x04 usability bits - the grey-out logic.funcs/80030628.txt
Apply handlerFUN_800402F4; HP arm 0x800404B8, MP arm 0x80040DC0, revive arm 0x80040F58The tier-table reads, deficit clamp, revive formula, and the class 5/6/7 immediates. One handler serves field menu and battle (branching on game_mode == 0x15).funcs/800402f4.txt
Jump-table callerstable at 0x80014FA0 (132 entries); callers 0x801D84B4, 0x801D9280, 0x801E40DCWhat indexes the handler depends on the caller: descriptor class (field item use), the item record's own kind byte, or the battle actor's +0x1E8.overlay dumps
Target-panel previewFUN_801D6A54Gates on kind == 2 and class == 6 before mapping tier to a preview mode - the sibling kind-byte selector.funcs/overlay_menu_801d6a54.txt
Disc-gated testitem_effect_realPins Leaf 200, Flower 800, Berry full, Magic Leaf 50 MP, Magic Fruit 200 MP, Healing Shroom 200; cross-checks each class against its on-disc description string.-

Parser + engine consumption

ItemEffectTable::from_scus resolves both tables from a SCUS_942.54 image (PSX-EXE t_addr → file-offset map). The engine installs the flags over its curated catalog via ItemCatalog::apply_effect_flags (usability gates + is_all_party: Healing Bloom / Fruit skip target-select and fan across every living ally), seeds the Water line via apply_stat_items, the Elixirs via apply_buff_items, and Fury Boost via apply_action_gauge_items. The engine mirror of the usability gate (inventory_use::item_has_valid_target) greys a heal at full HP, a cure with no matching status, a revive with nobody fallen. Source of record: docs/formats/item-effect-table.md.

See also