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:

TokenVahn / GalaNoa
ArmsL = 1R = 2
Ra-SeruR = 2L = 1
HighU = 4U = 4
LowD = 3D = 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, and restrictions / allowed arrays capturing the equipment / item / magic gating. Master Course's reward_first_clear = "war_god_icon" requires Jette to have been defeated in Absolute Fortress. The flat enemies = [...] 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, plus wiki_path for 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's seru_level field 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_constant resolves through legaia_art::tables::art_name, and the canonical name matches modulo (Hyper) / (Miracle) / numeric suffix variants.
  • Every art's direction-byte sequence is in 1..=4 and equals the per-character mapping of its command token 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 element is 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 / steal key resolves.
  • Every armor slot ∈ {armor, helmet, shoes}; every equip ∈ {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 directions field cross-validates.