Curated game-data tables
Arts, magic, items, weapons, armor, accessories, enemies, shops, casino, and fishing tables mined from two public walkthroughs and exposed as typed Rust accessors. Acts as ground-truth labels for the binary records being reverse-engineered.
Why this exists
The binary reverse-engineering work has the raw record bytes (PROT entry 0x05C4 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
Two 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).
Only the factual columns are committed (item names, prices, art command sequences, MP costs, monster locations, drop tables). Prose passages from either guide are NOT reproduced - prices and stats are not independently copyrightable, but the prose is. Walkthrough 2 is the primary source; walkthrough 1 fills in gaps and contributes the boss-HP estimates from its Master Course commentary. Sony-owned bytes (asset data, executable, raw ROM bytes) remain out of the repo entirely.
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
Implementation: crates/gamedata.
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}.
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.