Play the port
Walk around inside Legend of Legaia, in this browser, on your own copy of the game.
Not a video, and not an emulator: this is the project's clean-room engine reimplementation, compiled to WebAssembly and actually running - the same field VM, movement controller, and NPC motion VMs the native build uses, with WebGL drawing what they simulate.
You supply the game. The site ships no game data. Pick a .bin
disc image of your own copy below; it is read locally in your browser and nothing is uploaded.
Run it
Have a VR headset? The VR button under the canvas presents the running scene
over WebXR - a diorama you look into, or first-person from Vahn's own eyes
(VR mode). It needs Chrome or Edge with SteamVR as the
active OpenXR runtime and a secure context (https or localhost); if it can't
start, the button says what is missing.
.bin Mode2/2352 image. If you have already loaded your disc on
another page here, it is cached in the browser and will be picked up automatically.
What actually works
This is a partial reimplementation; the honest map matters more than a demo reel. Running in the browser today:
- Field and town scenes. The map assembles from the same pieces the game uses - environment models, tile grid, floor heights, walkable ground - textured from the PSX video memory the engine builds up (renderer). Movement is the ported controller, with retail's 2-unit stepping and per-axis collision against the walkability grid (field locomotion).
- The player character. The lead's field model, re-posed every frame from the real animation clips - idle while you stand, walk cycle while you move (character meshes, ANM).
- NPCs. Every character the scene's placement script puts down, animated and moved by the motion VMs. Press Z at one and the field VM plays out their dialogue, branches and all.
- Doors. Walk into one and the engine loads the destination scene under you.
- The New Game flow, end to end. Title card, New Game, the prologue, and then Rim Elm's establishing sweep running into the "Select your name." grid - the real screen, opened by the scene's own script, which stays suspended until you confirm. The name you commit is written into the party record, so the status panel and your saves carry it (boot chain).
- The pause menu and every screen behind it. Press Enter for the real retail menu - chrome and glyphs off your disc, every rectangle placed by the ported window-descriptor code (field menu). Items, Magic, Equip, Status, Options, Load and Save each run their live engine sub-session.
- Saving to a real memory card. Insert a card image from your emulator and the in-game Load and Save screens read and write that card through retail's own save-select flow (save screen). Saving edits the block in place, so Export hands back a card your emulator still loads.
What does not run here yet:
- Battles. The battle state machine and formulas are ported and tested, but the battle render path lives in the native window; encounters are disarmed here rather than dropping you into a black screen.
- The pre-title FMV movies. The title card, the prologue cutscene chain, its narration crawl, and the sepia + depth-cue grade all render here off your disc; STR movie playback (MDEC video) runs only in the native window, so an FMV beat is skipped in the browser.
- The inn. Its runtime state is ported, but no scene opens an inn session in either the browser or the native window yet. Merchants do work here: walking into a shopkeeper opens the retail gold shop, priced from your disc's own item table.
- Audio. The sequencer and SPU are ported (audio) and the WebAudio backend exists, but the BGM director is not wired into this page.
- The overworld. World-map locomotion and camera are a different controller; see the world overview for the continents.
Some scenes frame better than others: retail hand-authors a camera per scene, while this page runs one generic camera plus line-of-sight hiding of whatever blocks the view. In caves the floor sampler can also disagree with the visible ground - an engine-level thread tracked with the open questions.
How this page is wired
The WebAssembly bundle is the engine crates themselves, compiled for
wasm32-unknown-unknown. The page only turns key state into a PSX pad word, calls
tick_frame() once per animation frame, and draws what the engine reports - the
engine decides where you are. Actors are assembled per frame as R·v + T
from the animation record's bone transforms, because character meshes ship object-local
vertices (character meshes,
ANM).
The menus are the same menus. Every screen's geometry - the pause menu, the save-card flow, the dialog box, the shop panel - is built by one renderer-agnostic crate that both this page and the native window call; the page supplies a different framebuffer, not a different UI. That is also how the two stay in step: because a host "has" a screen exactly when it calls that screen's builder, a repository check can derive the shared surface from the source and fail the build when a screen reaches one host and not the other. Anything genuinely single-host has to be written down with a reason, and the check re-validates those reasons against the code on every commit - so this list of what does not run here cannot quietly go out of date.