Tooling
Two kinds of tools live here. The first are for you: point them at your own Legend of Legaia disc and they extract every asset, re-roll the game from a seed, or translate its text. The rest are the project's reverse-engineering instruments - the Ghidra, emulator-capture and measurement tools the format docs and engine port are built with. Pick a task below and follow the card.
Pick a task
Every tool takes a disc image you supply (the project ships no game data); most read the extracted/ tree the extraction pipeline produces. The groups are in arrival order: get the assets off the disc, then either patch the game or dig into how it works.
- Extract assets - turn the disc into PNGs, meshes and audio; the starting point for everything else.
- Patch a disc - randomizer, ROM patcher, language packs. Shipped deliverables, not side effects.
- Dig in Ghidra - the static path: disassemble the executable, recover the RAM overlays, answer "who calls this?".
- Capture the emulator - the dynamic path: watch the retail game run and record what the code actually does.
- Measure the port - how much of the game is understood, how much is ported, and whether the port matches retail.
- More tooling docs - CI gates and triage ledgers, on GitHub only.
Extract assets
Almost everything on the disc lives inside one archive, PROT.DAT, as containers within containers. One command unpacks the whole chain.
./legaia-extract "/path/to/Legend of Legaia (USA).bin" --out extractedextracted/ and where to look next.Patch a disc
The patcher edits a copy of your disc in place - same-size edits, sector checksums re-encoded - so the result boots on real hardware and every emulator. Nothing Sony-owned is ever committed; you bring the disc.
legaia-patcher translate exports a disc's text as an editable YAML pack and applies a filled pack back as a same-size patch. Built for community translations.Dig in Ghidra
The static path. Ghidra runs headlessly in Docker, driven by scripts; every FUN_80xxxxxx on this site is a function it labelled. One fact shapes all four pages: most of Legaia's game logic lives in overlays - code the game pages into RAM on demand - not in the executable, so "no static caller" is a question, not an answer.
exec workflow, the script catalogue, the LUI+ADDIU workaround, and the decompiler artifacts that have produced false claims.PROT.DAT at its recovered load address, so an overlay's identity comes from the disc rather than a guess. Reproducible from any copy of the disc.Capture the emulator
The dynamic path: load a save state, arm a watch or breakpoint, run a few frames, read back what happened. PCSX-Redux brings a scriptable breakpoint debugger; mednafen brings cheap save states whose RAM can be diffed.
Measure the port
Four questions, four instruments: how much of the game is understood and reimplemented (port catalog, disc coverage), how much of one entry's bytes a parser really consumes (byte accounting), whether the port matches retail frame for frame (differential oracle), and whether it matches itself run twice (determinism).
// PORT: tags in the crates, with feature views and a regenerable open-work dashboard.trace_diff.py reports the first frame each channel diverges.legaia-engine record / replay: capture your inputs to a small text file and play them back frame-perfectly. Same input twice → bit-identical state trace.More tooling docs (on GitHub)
These live in docs/tooling/ only: the CI gates that keep a measurement honest and the per-row triage ledgers behind the port catalog.
REAL / INTERIOR / SHARED_TAIL / DUPLICATE / VA_ALIASED / ...), so the worklist reads as work rather than addresses.NOT WIRED that the audit finds live, and the three call-graph shapes that put them there.jal target is a property of the bytes, not the load base - and the one dump window whose targets are therefore untrustworthy.// PORT: address can name the wrong routine and no gate catches it; the ranked worklist for checking that by hand.0x801C**** / 0x801D**** band: which image and VA a printed address's bytes really occupy, and whether that VA is a function entry.pkill -f matching itself, grep's no-match exit 1 read as failure.#anchors that must resolve.v* tag builds the workspace binaries and attaches per-target archives + SHA256SUMS to the GitHub release. Binaries and licenses only - never game data.Disc-gated tests
Tests that touch a real .bin run only when LEGAIA_DISC_BIN is set; without it they skip and pass, which is how CI runs. Source builds put the binaries under target/release/.
LEGAIA_DISC_BIN="/path/to/Legend of Legaia (USA).bin" cargo test --workspace