Curated game-data tables
Arts, magic, items, weapons, armor, accessories, enemies, shops, casino, and fishing tables mined from three public walkthroughs and exposed as typed Rust accessors. When a record comes off the disc as anonymous bytes, these tables are the ground-truth labels it gets checked against: the walkthroughs say what the numbers should be, the disc says what they are, and the tests below hold the two together.
Why this exists
The binary reverse-engineering work has the raw record bytes (PROT entry 0x05C4 - the arts records' slot in the disc's main archive - for arts, RAM 0x80160EFC+ for Vahn's runtime art table, 0x80085958+ for inventory, etc.) but no human-readable labels for any of them, and no public reference to cross-validate the parsed numeric fields against. The curated tables close that gap so:
- Art records parsed from the binary can be sanity-checked against retail AP costs and command sequences.
- Inventory item IDs that appear as cheat-modifier values can be resolved to display names.
- Spell records can be linked to their MP / element / target type.
- Monster encounter records can be linked to known retail names, locations, and drop tables.
- Boss HP estimates ground the damage-formula reverse engineering: predicted hits-to-kill should fall inside the walkthrough's HP bracket.
Source attribution
Three GameFAQs walkthroughs supply the raw values:
- Tan Yong Hua, Legend of Legaia Walkthrough v6.6 (1999).
- Psycho Penguin (mcfaddendaman), Legend of Legaia Walkthrough (2001) - the more complete table dump (PSM Magazine attribution for the enemy drop / steal table).
- Meth962, Legend of Legaia 100% Walkthrough v1.11 (2015, FAQ 53721) - the per-enemy stat columns, the per-fight boss moveset / rewards layer, the Seru-magic absorb fields, and the magic-leveling tables.
The music-track table is contributed directly by Stann0x rather than mined from a guide; see Music-track disambiguation.
Only the factual columns are committed (item names, prices, art command sequences, MP costs, monster locations, drop tables). Prose passages from the guides are NOT reproduced - prices and stats are not independently copyrightable, but the prose is. Sony-owned bytes (asset data, executable, raw ROM bytes) remain out of the repo entirely.
Psycho Penguin's guide is the primary source for the item / art / shop columns, and Tan Yong Hua fills gaps and contributes the boss-HP estimates from its Master Course commentary. Meth962's stat columns outrank both where they overlap: they were extracted from in-RAM memory dumps rather than estimated from play, which is why they are what the binary records get cross-validated against.
Where the data lives
data/gamedata/
README.md - source attribution + cross-validation rules
arts.toml - per-character arts (regular/hyper/super/miracle)
magic.toml - 21 Seru spells + 8 Ra-Seru summons
items.toml - consumables, key items, art books, fishing tackle
weapons.toml - 27 weapons
armor.toml - 49 armor / helmet / shoes entries
accessories.toml - 70+ accessories with structured effect classes
enemies.toml - 130+ enemies with location + drop / steal table
bosses.toml - boss HP estimates (sanity-check data)
shops.toml - per-town shop inventories with item-key references
casino.toml - Sol/Vidna slot prizes + Muscle Dome courses + Baka Fighter
sol_tower.toml - Sol Tower floor map + side-quest chains
fishing.toml - Vidna/Buma fishing pond prizes
characters.toml - Vahn / Noa / Gala affinities and weapon classes
music.toml - 81-track BGM disambiguation (Stann0x)
Implementation: crates/gamedata. The music table has its own page: music-track disambiguation.
Schema highlights · Arts
Each art carries a command (player-facing input tokens: Arms, Ra-Seru, High, Low) and a directions array of raw direction bytes (1=L, 2=R, 3=D, 4=U) - exactly the prefix that ends up in the on-disc Art Record. The mapping is per-character because Noa is left-handed:
| Token | Vahn / Gala | Noa |
|---|---|---|
Arms | L = 1 | R = 2 |
Ra-Seru | R = 2 | L = 1 |
High | U = 4 | U = 4 |
Low | D = 3 | D = 3 |
The action_constant field (0x1B..=0x32) cross-references the per-character art name table in crates/art/src/tables.rs. The arts_action_constants_match_legaia_art_tables integration test pins the relationship.
Schema highlights · Magic
21 Seru spells + 8 Ra-Seru summons. element is lowercase (fire, water, earth, wind, thunder, light, dark, evil). target is one of single_enemy, all_enemies, single_ally, all_allies, self.
Schema highlights · Items / weapons / armor / accessories
Each row carries a stable snake_case key that shops.toml, casino.toml, fishing.toml, and enemies.toml reference; the shop_inventory_keys_resolve test asserts every reference resolves.
accessories.toml carries an informal effect_class taxonomy (hp_max_pct, ap_accrual_pct, mp_cost_pct, attack_pct, speed_pct, revive_once, protect_status, elemental_def, summon_seru, …). This is not retail data - it's a structured re-encoding of the walkthrough effect text designed for the engine to dispatch on. As individual cheats and battle-formula reverse-engineering pin exact retail mechanics, effect_class rows can be promoted to retail-confirmed data.
Schema highlights · Enemies
Per enemy: name, location, an optional element (for elemental Seru enemies), an optional boss = true, and optional drop / steal item keys. The enemy_drop_and_steal_keys_resolve test asserts every drop/steal target exists in the item tables.
Schema highlights · Shops
One [[shop]] per merchant. Inventories reference item keys; the gamedata-tool shop <town> CLI joins those keys against the four item tables and prints a fully-priced inventory.
Schema highlights · Casino + Muscle Dome
casino.toml carries several concept families:
[[slot_prize]]rows for the Vidna casino counter and the Sol Tower Muscle Dome prize-exchange counter (location = "Sol"is the F4 counter, not the slot machine itself - slot machines only pay coins).[[muscle_dome_course]]rows (Beginner / Expert / Master) with entry fee, clear reward, andrestrictions/allowedarrays capturing the equipment / item / magic gating. Master Course'sreward_first_clear = "war_god_icon"requires Jette to have been defeated in Absolute Fortress. The flatenemies = [...]field is the encounter-order roster as plain strings.[[muscle_dome_round]]rows pin the round-by-round assignment for each course as a normalised(course_key, round, boss_key, seru_level)table. Beginner and Expert have 8 rows each; Master has 13 rows (the longest progression).[[muscle_dome_boss]]rows hold the full per-enemy stat block (HP / MP / ATK / UDF / LDF /intelligence/ SPD / AGL / XP /gold), drop and steal items with chance percentages, attack list, immunity tags, element + weakness/strength arrays, pluswiki_pathfor provenance back to the Fandom source. Seru enemies (kind = "seru") carry their Lv1 / Lv2 / Lv3 stats as nested[[muscle_dome_boss.seru_level]]blocks; the round table'sseru_levelfield selects which block applies.[baka_fighter_meta]records the all-rounds-clear reward (reward_coins = 460) and the rule sketch. Per-round button sequences live as[[baka_fighter]]rows.[[muscle_paradise_secret]]records the Chicken King easter egg ("run from the first battle in all three difficulties").
Schema highlights · Sol Tower
sol_tower.toml is location-scoped data that doesn't fit any of the type-scoped tables: a per-floor map ([[floor]] rows with named sections) and the side-quest chains ([[side_quest]] rows with ordered step lists and reward pointers). The scene_label = "town0d" ties the data back to the CDNAME map in site/_gen.py and the field-VM bundle.
Cross-validation invariants
Run with cargo test -p legaia-gamedata. Enforced rules:
- Every art's
action_constantresolves throughlegaia_art::tables::art_name, and the canonical name matches modulo(Hyper)/(Miracle)/ numeric suffix variants. - Every art's direction-byte sequence is in
1..=4and equals the per-character mapping of itscommandtoken list. - AP costs align with kind: regulars ≤ 36, hypers 30..=70, supers 48..=72, miracles = 99.
- Each character has exactly one Miracle Art.
- Magic table contains exactly 21 Seru + 8 Ra-Seru entries; every
elementis one of the eight canonical values. - Every shop / slot / fishing / muscle-dome reference resolves to a row in
items.toml/weapons.toml/armor.toml/accessories.toml. - Every enemy
drop/stealkey resolves. - Every armor
slot∈ {armor,helmet,shoes}; everyequip∈ {Vahn,Noa,Gala,None}. - Every item
category∈ {consumable,permanent_stat,key,art_book,fishing_lure}.
Disc-gated cross-checks (skip when extracted/SCUS_942.54 is absent)
These validate the curated tables against the real executable, so the disc is the tie-breaker when the two disagree:
item_prices_vs_disc- every priced weapon / armor / accessory whose name resolves to a disc item id has a curatedpriceequal to the authoritativeSCUSshop-price field (theu16at+2of the item-property record). 119+ cross-checks, zero mismatches.equip_slots_vs_disc- the disc equip-stat table's four+7slot categories map name-exactly to the four gamedata armour/weapon slots (body 20, head 15, footwear 16), and none of the 77 accessories appear in that table (they are the separate passive-effect system below).accessory_passives_vs_disc- joinsaccessories.tomlto the disc's 64-slot accessory passive-effect index space (the descriptor+3byte, parsed bylegaia_asset::accessory_passive; the index becomes a bit in the per-character ability bitfieldchar+0xF4viaFUN_80042558). Every curated accessory with a structuredeffect_classthat name-joins a disc item (72 of 73; the gap is the curated “Light Ra-Seru Egg” vs disc “Light Egg” spelling) decodes to exactly the index its class + value/status/element predicts - zero mismatches across HP/MP/stat boosts, status guards, elemental guards, AP/encounter/loot/escape modifiers.enemy_stats_vs_disc- joinsenemies.tomlto the monster-stat archive (PROT 0867) by name (unambiguous names only; multi-form bosses like Gaza are skipped). The curated bestiary stats are scaled derivations of the raw disc record:hp/spd×1,udf/ldf×2,atk×5/4,exp×3/4,gold×5/16. Two curated labels are disc stats in disguise: curatedaglis the disc AGL action gauge (+0x0E), and curatedintelis the disc INT stat (+0x18) ×9/8. The disc is the raw ground truth; the test pins all nine fields across 120+ enemies.magic_vs_disc- joinsmagic.tomlto the static spell table inSCUS_942.54by spell name. All 21 Seru spells (ids0x81..=0x95) and 7 of the 8 Ra-Seru summons (0x9a..=0xa0; the hidden Juggernaut isn't in the contiguous named region) name-join, and every one's MP cost is byte-exact against the disc record. Target shape (the+2byte) agrees for all joins except the revive Ra-Seru Horn / “Resurrector”, whose byte is enemy-side though the effect revives all allies (checked explicitly).shop_inventory_vs_disc- scans every PROT entry for the gold-shop stock records embedded inline in each scene MAN (legaia_asset::shop_stock, op0x49sub-op0) and joins disc shops to curated shops by the item-name set (order-independent; the item set is far more distinctive than the shop title, which repeats as “Arms Shop” / “Items Shop” across towns). Every located disc shop's stock matches a curated inventory as an exact set, with one documented disc-only exception - Soru's Bakery, which sells only the novelty “Soru Bread” and has no curated counterpart.casino_prizes_vs_disc- joinscasino.tomlto the coin prize-exchange table in the menu/save/shop overlay's data segment (PROT entry 0899, stored raw; canonical readerlegaia_patcher::casino::CasinoExchange). Each prize is an 8-byte record[u16 item_id][u16 story_gate][u32 coin_price]in0x60-byte blocks - block 1 the Vidna casino counter, block 0 the Sol Tower Muscle Dome counter (high-value prizes story-gated via the+2word), blocks 2/3 short pre-progression states. Every curated prize joins a disc record byte-exact on (item name, coin price) across both full lists, and every disc record is a curated prize, with one documented exception - Earth Egg @ 100000 coins (the Muscle Paradise “Chicken King” easter egg), a separate hidden exchange not in the four-block table (asserted explicitly).
Where the disc overrides the walkthroughs
The curated tables carry the disc values wherever a public walkthrough disagrees; these oracles enforce that. Known divergences: the Forest / Magic Amulet price is 2000 (walkthrough 4000) and the Evil Medallion 9999 (walkthrough 9998); Mushura's “Crazy Driver” targets a single enemy (walkthrough all-enemies); the Gala helmet is spelled “Power Earring”, singular, as the disc names it.
Library API
use legaia_gamedata::{Database, Character, ArtKind, SpellFamily};
let db = Database::load();
// Per-character arts
for art in db.arts_for(Character::Vahn) {
println!("{:?} {:>3} AP {}", art.kind, art.ap, art.name);
}
// Look up an art by direction-byte sequence
let art = db.find_art_by_directions(Character::Vahn, &[1, 2, 4]).unwrap();
assert_eq!(art.name, "Hyper Elbow");
// Map an action constant to AP cost (for runtime damage tooling)
let ap = db.ap_cost_for_action(Character::Gala, 0x1B).unwrap();
assert_eq!(ap, 99); // Biron Rage
// Resolve a shop entry against the unified item lookup
for entry in db.shop_inventory("Rim Elm", "Variety Shop").unwrap() {
println!(" {:>20} {:>5}G", entry.name, entry.price.unwrap_or(0));
}
CLI
cargo run -p legaia-gamedata --bin gamedata-tool -- list arts --character Noa
cargo run -p legaia-gamedata --bin gamedata-tool -- list magic --element light
cargo run -p legaia-gamedata --bin gamedata-tool -- find "Tornado Flame"
cargo run -p legaia-gamedata --bin gamedata-tool -- arts-by-command Vahn "Arms,Ra-Seru,High"
cargo run -p legaia-gamedata --bin gamedata-tool -- shop "Sol"
cargo run -p legaia-gamedata --bin gamedata-tool -- dump-json arts > arts.json
See also
- Cheat databases - the GameShark / Mednafen pipeline that already pins many RAM offsets.
- Per-character save record - the
0x414-byte runtime record that cheats and gamedata both anchor on. - Art data format - the on-disc Art Record layout that gamedata's
directionsfield cross-validates.