The shape of the engine

Legaia is a fairly typical late-90s PSX RPG engine, but with a twist: most of the gameplay logic doesn't live in the main executable. SCUS_942.54 contains the boot path, low-level I/O, the asset dispatcher, the move-table VM, the motion VM, and the audio / renderer libraries - about half the runtime. The other half lives in RAM overlays that the disc loads on demand into one shared window. There are fewer of them than the subsystem list suggests: the slot-A family (field/town 0897, battle 0898, menu 0899, cutscene/STR 0970, and the minigames) all load at the same base and are mutually exclusive, while the world map, save, shop, level-up, and options are subsystems inside the field and menu overlays, not separate ones. Two of the runtime VMs (the field/event VM and the effect VM) live in these overlays.

Overlay residency in the 0x801C0000 window RAM overlay window - mutually exclusive at runtime 0x801C0000 0x80200000 ~256 KB window. The disc loads exactly one overlay here for the active game mode. Title (0971) Actor / sprite VM FUN_801D6628 Town (0897) Field/event script VM FUN_801DE840 (~190 KB) Battle (0898) Action SM + effect VM FUN_801E295C / E0088 Menu (0899) inventory / equip / status, + save, shop, level-up, options Cutscene (0970) STR / MDEC video game modes 26/27 Minigames fishing 0972 / slot 0975 / baka 0976 / dance 0980 Always resident in 0x80010000-0x800FFFFF SCUS_942.54: boot path, asset dispatcher, move VM, motion VM, libsnd / libspu / libcd / libapi
These overlays share one RAM window (the slot-A family loads at 0x801CE818): battle loads on top of town's slot, never coexisting. Several “subsystems” are not separate overlays - the world map is a mode of the field overlay (0897), and save / shop / level-up / options all live inside the menu overlay (0899). The randomizer injects a whole new vendor screen into 0899's dead space - see the overlay dead-region write-up for a zoom into that overlay.

The list below groups subsystems by what layer of the engine they sit at.

Bootstrap and asset plumbing

The five runtime VMs

Legaia's runtime is driven by five independent VMs that all talk to one shared actor model. Four are clean bytecode dispatchers (actor / move-table / motion / field-event); the fifth (effect) is a per-slot state machine - different shape, same architectural role. They serve different layers of the engine and were almost certainly written by different members of the dev team.

Per-domain runtime

World map
Overworld traversal mode. Controller FUN_801E76D4 handles the debug top-view toggle, top-view camera scroll/azimuth/zoom, and normal-walk per-frame update. Entity tick SM (FUN_801DA51C, 5 states) drives encounter and location-entry sequences.
Save screen
Save-slot selection and write flow. Lives in the menu overlay (not a separate overlay). Outer dispatcher FUN_801DC6B4: 9-state machine, entry-context pointer table at 0x801E4F40, slot-select via actor VM, save-block existence scan at DAT_80084140.
Shop
Buy / sell / quantity / confirm flow. Lives in the menu overlay. ShopSession tracks pending item, quantity, and buy/sell direction. Sell price = half buy price (min 1). Per-scene item tables pending overlay trace.
Inn
HP / MP restore flow. InnSession { cost } gates the stay on affordability, then restores all active party members to full HP/MP. Per-scene costs pending overlay trace.
Level-up
Post-battle XP distribution and stat gain. XP curve = static-SCUS table DAT_80076AF4 + formula, and per-character stat growth = DAT_800769CC / DAT_80076918, both applied by the overlay level-up function FUN_801E9504. LevelUpBanner renders for 180 frames via level_up_draws_for(). The engine extracts the real XP curve from the user’s SCUS at boot; the stat-growth tables are parsed but not yet applied.
Cutscene (STR mode)
PSX STR video decode + XA audio playback. Game modes 26/27 (StrInit / StrMode). MDEC decoder: VLC → IDCT → BT.601 YCbCr→RGBA. Clean-room port in crates/mdec.
Battle
Battle scene loader, the per-action state machine, character record layout, the per-frame stat aggregator, range / line-of-sight, the weapon-trail builder, status-effect ticker, AP / Spirit gauge, equipment-aware stat aggregator, and item-effect catalog.
Battle action FSM
The 47-state machine inside FUN_801E295C - the layer between “player picked Attack” and “HP has been deducted.” Two-level dispatch: action category (party byte) plus execution phase (ctx byte).
Battle formulas
Damage / MP-cost / accuracy / RNG arithmetic. Selector dispatch in FUN_800402F4; spirit damage is hard-coded; MP cost is ability-bit modified; engine-vm port lives in battle_formulas.rs.
Arts command gauge
The AP gauge the player spends inputting an arts combo, and the weapon-specialty arm width: the arm command's cost at DAT_801C9360[char][0x0C]+0x74 escalates over base for an off-class weapon (favored 0x1E / off-class 0x2A / Astral 0x36) - not a flat double.
Audio
Sound-driver path strings, three SCUS consumers, the SsAPI sequencer cluster (statically linked PsyQ libsnd), and the libspu DMA engine that moves bytes into SPU RAM.
Renderer
The Legaia TMD renderer (60 GTE ops with a per-mode descriptor table). The engine port emulates PSX VRAM in a compute-friendly format so multi-page meshes render correctly.

The clean-room port

The Rust port lives in its own page - phase plan, crate layering, architectural principles, and the legal posture.