BeamNG.Earth
BeamNG.drive용 1:1 비율 실시간 지구, 실제 고도·위성 이미지·부동 원점·보조 서버에서 LOD 스트리밍
Legend of Legaia Reverse Engineering PSX 1998년작 레전드 오브 레가이아 완전 리버스 엔지니어링
Legend of Legaia (PSX, 1998) reverse engineered end to end: play the from-scratch engine port in your browser via WebAssembly, browse every asset, patch your disc with the randomizer, and read byte-le
게임Rust · HTMLGitHub @AndrewAltimit온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
Reverse-engineering Legend of Legaia (PSX, 1999): Ghidra-traced format documentation, Rust extractors for every asset on the disc, and a clean-room engine reimplementation targeting wgpu/SDL3 with optional WASM. BYO-disc model, no assets distributed.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A playable port and modding hub for the PSX game Legend of Legaia (1998, Sony, NA SCUS-94254), standing on Ghidra-traced reverse engineering of the retail disc. The disc's formats are documented byte-by-byte with provenance back to traced retail functions, Rust parsers extract every asset, and a from-scratch engine runs the game's own scenes, scripts and menus - natively on wgpu, and in your browser via WebAssembly. On top of that sit a disc randomizer, a translation toolchain, and a project site full of interactive viewers that run entirely off your own disc image.README 전문 보기 ↗Legend of Legaia (PlayStation, 1998, NA SCUS-94254), running as a from-scratch Rust port you can play today - in a native window or in your browser - from your own disc image. Around the port sit a full asset extractor, a disc patcher (randomizer, translation packs, content mods), interactive viewers, and byte-level documentation of every format on the disc.
Project site: andrewaltimit.github.io/legend-of-legaia-re - play, browse and patch in the browser, nothing to install.
This repository is code and documentation only. You bring the disc: nothing Sony owns is committed or distributed, and everything browser-side reads your image locally in the tab - it is never uploaded. See You bring the disc.
| You want to | What ships | Where |
|---|---|---|
| Play the game | The port: title screen, New Game, towns, dungeons, world map, battles, menus, saves | Browser play page, or legaia-engine natively |
| Play the minigames on their own | Slot machine, Noa's dance, Baka Fighter, fishing, Muscle Dome | Minigames page |
| Get the assets out | Textures, models, music, sound banks, dialog, FMVs, data tables | legaia-extract and a CLI per format; the asset viewer and media browser in the browser |
| Randomize or mod your disc | Shuffles, tuning sliders, MIPS code hooks, custom models and textures | legaia-patcher, or the ROM patcher page |
| Translate the game | Export all text to YAML, edit, reimport in place | legaia-patcher translate, or the translation workbench |
| Look things up | Enemies, characters, NPCs, magic, arts, shops, every town and kingdom in 3D | The site's data pages, starting at enemies and the world |
| Export to Blender / Unity / VRChat | Scenes, NPCs, props, equipment and the party as .glb | legaia-engine export-glb (guide) |
| Understand how the game works | Format specs, subsystem docs, traced functions, RAM map | docs/ |
A port, in the ScummVM / OpenRCT2 / OpenMW / OpenLara sense: fresh Rust written from the project's own reverse-engineering record (Ghidra-traced function dumps and live emulator probes), reading the original game data at runtime. It is not a decompilation, not a byte-matching rebuild, and not a static recompilation of the executable. The -re in the name is both reverse-engineering and re-implementation.
Retail is the ground truth, not a cage. The traced disassembly and the parity oracles pin the original's arithmetic, RNG, script pacing and save layout, and a retail-faithful mode stays testable. On top of it the port adds things the original never had - enhanced lighting, volumetric ground fog, see-through walls around the player, free-angle movement, an orbit camera, VR - as toggles, on by default where they are clearly better, with retail one switch away. Per-knob defaults: docs/subsystems/engine.md.
One engine runs behind every host. The simulation crates carry no GPU, windowing or audio-device dependency, so the same code ticks in a native window and as WebAssembly in the browser; How it fits together draws the whole stack.
The whole game plays, New Game to the ending credits:
Known gaps:
SCUS-94254.Open the play page, pick your disc image, play - flat, or in VR over WebXR.
Download the archive for your platform from the Releases page and double-click Legend of Legaia in the unpacked folder (Legend of Legaia.exe on Windows, Legend of Legaia.app on macOS). The launcher opens: choose your disc image once (it is checked and remembered), set the display options, and press Play for the title screen.
| Platform | Archive |
|---|---|
| Linux x86_64 (glibc 2.28+) | legaia-tools-<version>-x86_64-unknown-linux-gnu.tar.gz |
| Linux arm64 | legaia-tools-<version>-aarch64-unknown-linux-gnu.tar.gz |
| Windows x86_64 | legaia-tools-<version>-x86_64-pc-windows-gnu.zip |
| macOS 11+ (Apple silicon + Intel) | legaia-tools-<version>-universal-apple-darwin.tar.gz |
sha256sum -c SHA256SUMS --ignore-missing # optional: verify the download
tar -xzf legaia-tools-<version>-x86_64-unknown-linux-gnu.tar.gz
cd legaia-tools-<version>-x86_64-unknown-linux-gnu
./"Legend of Legaia" # launcher, then the title screen
The archive's top folder holds only the two programs to double-click - the game and Legaia Explorer - plus README-PLAY.txt and the licenses; every command-line program, the engine legaia-engine among them, is in its command-line-tools/ folder. README-PLAY.txt covers first launch, including the macOS Gatekeeper prompt; docs/tooling/releases.md covers what is in an archive and how it is built. The engine and asset-viewer want a GPU and, on Linux, ALSA.
Every archive also carries Legaia Explorer, a desktop app for the asset side: open your disc image, browse the archive by scene, preview textures, models, characters, monsters, audio, dialog and movies, and export them, or run the full extraction with a progress bar (crates/explorer). The site's desktop apps guide walks through downloading, the first start on each system, Explorer and the native port, with screenshots.
Needs a Rust toolchain (edition 2024).
cargo build --release # every binary lands in target/release/
Paths below are for a source build; from a release archive run them in its command-line-tools folder, without the target/release/ prefix.
DISC="/path/to/Legend of Legaia (USA).bin" # a .cue works anywhere a .bin does
# Check the dump against the known fingerprint.
./target/release/disc-extract verify "$DISC"
# Play: the launcher, straight into a scene, or from the title screen.
./target/release/legaia-engine
./target/release/legaia-engine play-window --disc "$DISC" --scene town01
./target/release/legaia-engine play-window --disc "$DISC" --boot-ui
./target/release/legaia-engine list-scenes --disc "$DISC"
# Watch an FMV with its audio.
./target/release/legaia-engine play-str MOV/MV1.STR --disc "$DISC"
# Extract everything: disc files, PROT entries, sub-assets, PNGs, XA WAVs, font.
./target/release/legaia-extract "$DISC" --out extracted
# Browse what was extracted.
./target/release/asset-viewer prot extracted/PROT.DAT --cdname extracted/CDNAME.TXT
# Bake a scene (world, NPCs, animated props) to .glb.
./target/release/legaia-engine export-glb --scene town01 --out glb-export
# Randomizer and translation: each lists its feature flags under --help.
./target/release/legaia-patcher randomize --help
./target/release/legaia-patcher translate --help
Every binary answers --help, and legaia-engine --help groups its subcommands into playing, exploring and development diagnostics. The guides take each task end to end:
This project ships no Sony-owned bytes, ever. There is no game executable, no asset data, and no ROM content in this repository or in any release archive. Everything here is code and documentation that operates on a disc image you already own and supply yourself.
Concretely, and non-negotiably:
.bin. Nothing is bundled and nothing is downloaded for you.extracted/ and ghidra/projects/ are gitignored. Extraction output is Sony-derived, so it stays on your machine. The same applies to per-function Ghidra dumps under ghidra/scripts/funcs/ and to exported translation packs.LEGAIA_DISC_BIN is unset. Tests that need real disc bytes skip and pass without it, so CI runs green with no disc data present. This gating is deliberate - don't remove it.If you are adding code here, treat "no Sony bytes get committed" as the one hard constraint that outranks everything else - including decompiled C that carries literal asset data or text strings.
The reference dump:
| Disc | SHA-256 (Mode2/2352 .bin) |
|---|---|
| Legend of Legaia (USA), SCUS-94254 | e6120a5d70716dd2f026a2da32d0171d52651971b52c4347a68541299f75258c |
This hash is a sanity check against the project author's dump; different dumping tools can produce a different whole-image hash for the same disc. For canonical per-track verification, cross-check against Redump.
Start at docs/overview.md: how the layers stack from disc to sub-asset, and where to read next for any task.
| Section | Holds |
|---|---|
docs/guides/ | Task-oriented walkthroughs for the shipped tools. |
docs/formats/ | Byte-level specs for every format on the disc, each with a confidence level and Ghidra provenance. |
docs/subsystems/ | How the runtime works - the VMs, battle, renderer, audio, field, menus, minigames - and the port's own architecture. |
docs/tooling/ | Extraction CLIs, the randomizer, translation, Ghidra and emulator automation, and the parity instruments. |
docs/reference/ | Traced functions, the RAM map, builds, curated game data, and the open / settled / falsified research threads. |
The repository is one Cargo workspace of small crates, each with a one-page README.md. They stack in bands: a crate depends only on crates in its own band or a band below it, so the stack reads from the programs people run at the top down to the disc parsers at the bottom. Colour marks the track a crate belongs to.
Explore it interactively on the crate map: hover a crate to light what it uses and what uses it, open its scope, binaries and modules, filter by track, and follow a scene from the disc to the screen. The page, this diagram and the layer list below are generated from the workspace itself (every Cargo.toml, the crate tables in CLAUDE.md and the layering table) by scripts/ci/gen-crate-map.py, and a gate fails a commit that leaves them stale.
| Track | What it is | Start at |
|---|---|---|
| Preservation | Reading the disc: the sector reader, the PROT archive, one parser per format, the Legaia-specific format families over them, and the tools that extract and document every asset. | legaia-extract, asset, docs/formats/ |
| Engine | The from-scratch port: the ported script VMs and rules engines as World-free kernels, the simulation in engine-core, the session both play hosts tick, the wgpu renderer and the from-scratch SPU. | docs/subsystems/engine.md |
| Patcher | Writing the disc: same-size PROT edits with EDC/ECC re-encode, MAN relocation, translation packs, MIPS code hooks, model and texture replacement - all behind legaia-patcher. | docs/tooling/randomizer.md |
| Research tooling | Measuring the port against retail: emulator save-state readers, the parity oracles and retail comparison corpus, and the curated reference labels. | docs/tooling/retail-compare.md |
Top of the stack first. Every crate name links its README.
engine-shell, web-viewer, web-play, web-minigames, web-patcher,
asset-viewer, explorer, patcher, extract, assetengine-session, engine-screens, , , ,
, | Host | Crate | Draws through |
|---|---|---|
Native play-window | engine-shell (the legaia-engine binary) | winit + wgpu (engine-render) + cpal (engine-audio) |
| Browser play page | web-play, compiled to WebAssembly in web-viewer's bundle | WebGL + WebAudio, from site/js/play-app.js |
| Browser minigames page | the same web-play crate and bundle | one JS module per minigame |
Both play hosts tick the same engine-session BootSession over the same World; the minigames page drives the World-free minigame rules engines directly. What differs is only the shell. Host drift covers the gates that keep a feature from reaching one host only.
A scene takes one path through the stack on every host: iso reads the sectors, prot finds the entry, lzs decompresses it, container-formats and scene-formats split the bundle, engine-scene loads its resources, engine-core's World ticks the ported VMs over it, engine-scene-host and engine-session order the frame, render-kernels and engine-ui build the draws, and wgpu or WebGL puts them on screen.
| Path | Holds |
|---|---|
docs/ | The technical reference: formats, subsystems, tooling, reference tables (start here). |
site/ | The project site's sources: page fragments, the browser hosts' JS, the generator site/_gen.py. |
data/ | Curated, non-Sony reference tables (game data mined from public walkthroughs, music and scene names). |
ghidra/, scripts/ | Analysis scripts (dumps are gitignored), CI gates, capture automation (map). |
extracted/ | Your disc's assets. Sony bytes, gitignored, never committed. |
CLAUDE.md is the full map of the repository - every doc page and every crate, one line each - and crate layering explains the rules the stack keeps and the gate that holds the engine's kernel ranks.
Part of the stack describes the PlayStation rather than Legaia, and works on another game's disc. Take a crate as a git dependency with default-features = false (the default cli feature adds the command-line binary and its dependencies). Reusing this repo for other PS1 games has the per-crate detail, every Legaia assumption by name, and the transferable method (the retail-compare oracle, evidence grading, the falsified-hypotheses register, disc-denominated coverage, determinism replay), which the retail-oracle method writes up engine-neutral. A worked example runs the generic crates on a made-up game built in code: cargo run -p legaia-pcsx-redux --example bring_your_own_game.
| Crate | What it does | Generic? | Entry point |
|---|---|---|---|
iso | Mode 2/2352 reader, ISO9660 walk, EDC/ECC re-encode, in-place file patch | Generic | RawDisc::open, iso9660::walk_files, write::patch_file_logical |
xa | CD-XA ADPCM demux and decode to WAV | Generic | demux::demux_raw_sectors, decode |
tim | TIM parse, PNG export, PNG-to-TIM encode, software VRAM | Quirk: Vram::upload_tim lands CLUTs as Legaia's loader does | parse, decode_rgba8, encode::encode_replacement |
vab | VAB bank parse and VAG decode | Standalone VABs via parse; Legaia's two-chunk carriage has its own helpers | parse, decode_vag |
seq | libsnd SEQ parser | u32 version header, meta events with no length byte | Seq::parse |
lzs | LZSS (4 KB ring at 0xFEE) decode and re-pack | Zero-filled ring, no size header, Legaia container | decompress, compress |
CONTRIBUTING.md has the rules of engagement and the gates. The short form:
cargo fmt --all -- --check
cargo clippy --all-targets --workspace -- -D warnings
cargo test --workspace --profile release-test
LEGAIA_DISC_BIN="/path/to/Legend of Legaia (USA).bin" cargo test --workspace --profile release-test
The last line turns on the disc-gated tests; without the variable they skip and pass. Reverse-engineering work additionally wants Docker for headless Ghidra (setup) and, for runtime capture, mednafen or PCSX-Redux.
Status: playable from New Game to the credits, natively and in the browser; What works lists the known gaps. Prebuilt releases are on the Releases page.
License: dual-licensed at your option under either the Unlicense (public-domain dedication) or the MIT License. Apache-2.0 is intentionally not offered - this project is meant to be as close to public domain as the law in your jurisdiction allows, with no patent-retaliation strings attached: copy it, fork it, sell it, patent improvements on it, just don't stop anyone else from doing the same.
These licenses apply only to the code and documentation in this repository. Sony's IP - game executable, asset data, ROM contents - is not redistributed here and is not covered by them. See You bring the disc above.
legaia-art MiracleMatcher / SuperMatcher tables (crates/art/src/miracle.rs, super_art.rs) cross-reference and validate against it. His damage-formula analysis - the Offense Value / Defense Value shape, the per-command equipment selection and halving, and the Vahn vs Evil Fly worked example - organises docs/subsystems/battle-formulas.md, where each claim is checked against the disassembly.This project does not redistribute Sony's IP. You bring your own disc image. Tooling co-authored with AI agents under human direction.
engine-scene-host, engine-menu-runtime, engine-battle-hud, engine-world-views, engine-cheats,
engine-save-stateengine-coreengine-battle-loop, engine-minigame-scenes engine-battle-menus, engine-menus engine-fishing, engine-minigames, engine-scene engine-battle, engine-cast, engine-effects, engine-field, engine-ui engine-battle-vm, render-kernels engine-camera, engine-dev-menu, engine-mode, engine-motion-vm, engine-title engine-dialog, engine-system, engine-vmdisc-patch, translate, code-hooks, arts-patch, texture-replace,
party-swap, delilas-party, delilas-challenge, ram-image, mednafen,
pcsx-reduxcontainer-formats, scene-formats, actor-formats, minigame-formats, ui-formats,
game-tables, overlay-images, disc-auditiso, prot, lzs, bytes, tim,
tmd, vab, seq, xa, mdec,
mes, anm, mdt, art, font,
save, gamedata, cheats, app-thememdec| STR sector assembly, A/V demux, MDEC decode |
| Decoder is the Iki bitstream; STRv2 needs Legaia's VLC table |
str_av::demux_str_av, MdecDecoder |
mednafen | Mednafen state: RAM, VRAM, SPU | Library generic; several CLI subcommands are Legaia's | SaveState::from_path |
pcsx-redux | PCSX-Redux state: VRAM, scratchpad, RAM | Generic (all located structurally); the scene / mode accessors are Legaia's | SaveState::from_path_structural, gpu::PcsxGpu |
ram-image | RAM diff, write bisection, GPU primitive-pool decode | Generic; game knowledge is a GameProfile parameter | diff::diff_ram, prim_pool::decode, GameProfile |
engine-audio | From-scratch SPU and libsnd-shaped sequencer | No pitch modulation / noise / FM; Legaia battle-audio modules beside it | spu::Spu, Sequencer::new |
render-kernels | gte: register-level GTE with every command and the UNR divide | Module generic, crate Legaia-bound: vendor src/gte/ | gte::Gte |
tmd | Legaia's TMD variant | Legaia-only: rejects stock 0x41 TMDs | parse |
legaia-gamedataenemies.toml carries Meth's per-enemy HP / MP / EXP / Gold / ATK / SPD / UDF / LDF / INT / AGL / element columns for every entry (extracted from in-RAM memory, so fan-recorded values rather than retail-binary-extracted constants - useful as labels for the binary monster records crates/actor-formats/src/monster_archive.rs decodes from PROT 0867).bosses.toml is rewritten around the per-fight layer (named attacks + MP cost, XP / gold / item rewards, recommended party level) for all 18 main-story B-code bosses plus the Lapis superboss.magic.toml grows absorb_lv1 / absorb_lv2 / absorb_lv3 integer-percent fields per Seru spell (Gimard 55/60/80, Gilium 1/1/1, the full 21-spell table); the per-cast XP curve and damage-scaling multipliers live in legaia_gamedata::magic_leveling.--super-arts-pack (crates/patcher/data, randomizer.md). Same author as the "Legaia Arts Data" spreadsheet above.docs/reference/music-tracks.md - the human-readable label layer for the extracted SEQ/BGM tracks, in the same curated-reference spirit as the game-data tables above.
TMD TEST crashes on a retail console (its draw buffers are hard-coded at 0x80400040 / 0x80419040, which only the 8 MB development console has), that TEST hangs and READ jumps into an overlay that is no longer loaded (boot.md), and where unused RAM sits above the overlay slots, under the interrupt stack and in uncalled code (memory map).+8 every character gains at the end of its own action (Spirit's +32 replacing it), the AP a party member gains when an enemy's hit lands on them, the 9 AP a Miracle Art leaves, and that a level-9 Vera / Orb / Spoon heal doubles the target's AP. Checked against the disassembly in battle-formulas.md, which also led the port to apply the doubling.