Skip to content
nopromptPublic

About

Native PC port of Vagrant Story on the rood-reverse decompilation: Vulkan ray tracing, path-traced GI, live editor. Bring your own disc.

Resources

Stars

27 stars

Watchers

2 watching

Forks

Repository files navigation

rood-boi

rood-boi is a native PC port of Vagrant Story for Linux (and Windows, built from Linux or WSL). It is built on the rood-reverse decompilation: the game's original logic is the decompiled C, compiled for x86-64 and run directly (there is no emulator and no MIPS interpreter), with a host layer that stands in for the PlayStation's GPU, GTE, SPU, CD drive, memory cards and pad. On top of that sits a modern renderer: the world is drawn from native meshes on Vulkan (or OpenGL), lit with hardware ray-traced shadows, path-traced or probe-based global illumination denoised with NVIDIA NRD, and volumetric haze, while the PS1 look (nearest-filtered textures, original geometry and 2D) is kept. A live, Unreal-style editor lets you fly a free camera and place and tune lights while the game runs.

Disclaimer. This is an unofficial fan project. It is not affiliated with, endorsed by or sponsored by Square Enix or Sony Interactive Entertainment. It ships no game data (no disc image, game executables, models, textures, audio or movies); you must own Vagrant Story and supply your own disc image. (The menu string tables under assets/ come from the upstream rood-reverse decompilation, which needs them to rebuild the original files.) Vagrant Story, PlayStation and all other trademarks belong to their respective owners.

Contents

  1. Features
  2. Status
  3. Requirements
  4. Getting the game data
  5. Build
  6. Run
  7. Tests
  8. Platform support
  9. Licence and credits
  10. The decompilation (upstream rood-reverse)

The detailed reference for the port (renderer, editor, settings keys, developer RPC, test suites, architecture) is pc/README.md, with design notes in pc/docs/.

Features

  • The original game code, natively. Main executable, title, battle/field engine, menus and effects are the decompiled C (plus translations of the remaining hand-written assembly) built for the host. The PS1 build of the same sources still matches the original binaries byte for byte.
  • Renderers. Vulkan 1.3 with ray queries (64-bit build) or OpenGL 4.6/3.3. Rooms, characters, weapons, drop shadows and particles are drawn from native meshes with real depth, at up to 8x internal resolution, with perspective-correct texturing, FXAA, and frame interpolation for smooth motion above the game's 30/15 fps.
  • Lighting. Ray-traced soft shadows, per-pixel path-traced indirect light (Ultra, denoised with NVIDIA NRD), DDGI probe GI (Medium/High), shadow maps where there is no ray tracing, ambient occlusion and volumetric haze. Quality presets from Original (exactly the PS1's baked lighting) to Ultra, picked automatically on first run.
  • PS1 look preserved. Nearest-filtered textures, the original 2D, menus, fonts and 4:3 framing by default; post effects (depth of field, tilt-shift, fog) and 16:9 are opt-in.
  • Live editor (Escape): free camera, an Outliner of the room's lights and glows, light actors from JSON prefabs (candles, torches, lanterns...), one-click lighting of the room's fixtures, Houdini-style point/edge/surface snapping, undo/redo, and a Room Browser that warps to any room of the game for lighting work (saves are blocked while warped).
  • Lighting as data. Room lighting lives in layered, diff-friendly text packs under lighting/ (generated, hand-authored, personal), so lighting can be reviewed and contributed as pull requests. A fixture catalog classifies every candle, torch, lantern and brazier type in the game once (hashes and numbers, no game data), and a generator lights every instance from it; tuning a type updates all of its instances.
  • Optional weapon slots. A quick weapon and shield swap on L2 + R2, ported from eremtsov's QoL mod; off by default, memory cards stay compatible with the mod and the unmodded game.
  • Camera and view options. The right stick turns and zooms the game's own follow camera; optional smart cutaway walls hide only the walls actually between the camera and Ashley; optional MMPX upscaling for 2D/UI.
  • Room texture animations (scrolling sigils and the like) run as GPU material effects driven by the game's own animation state.
  • Audio and video. The original sound driver on a software SPU (music, effects, reverb), the intro movie (MDEC video and XA audio), memory cards as standard .mcd images that emulators also read.
  • Input. Keyboard and SDL 3 gamepads (Xbox, PlayStation, Switch and others), hot-plugged.
  • Options in the game's own menu. Gameplay, Display, Graphics, Audio, Interface and Controls pages sit below the original rows of the Option screen, drawn in the game's style: window mode, display, fullscreen mode (asks "Keep these settings?"), vsync, frame rate cap, render quality, key and pad bindings. Plugins can add pages of their own.
  • Lua plugins. Look, feel and quality-of-life changes live in Lua with hot reload (pc/docs/Extensions.md). Shipped: rood.options (the Option pages), rood.hud (the HUD with the modern menus) and rood.classic (the classic HUD: timing words, chain count, HP/MP/RISK gauges, each checked packet for packet against the game's own drawing, which stays the fallback).
  • Save state slots (optional, off by default): System > Gameplay > Save states, then F5 saves, F9 loads, F6/F7 pick the slot (bindable).
  • Cutscene player (developer tool, Window > Cutscene): reach a cutscene (New Game's opening, 39 room events by warp, the ending), pause, step, go back to any earlier frame and replay it exactly, slow motion, clean PNG captures and repro files; the optional instant replay keeps the last 30 s and F8 freezes it (pc/docs/Cutscene_Player.md).
  • Developer tooling. A JSON-RPC control socket and Python client (pc/tools/rood_rpc.py) for scripted play, screenshots and memory inspection; a Lua REPL into the running game (pc/tools/rood_repl.py); the engine as a library reloaded in place (pc/run-game.sh --reload, below); save-state resume across rebuilds (--resume); headless GPU and CPU-only test suites.
  • Game logic moving to Zig (in progress). Battle functions are being ported to Zig one at a time (game/), each checked against the original C: shadow mode runs both and compares every call, a differential checker compares them on generated inputs with branch coverage, and Zig edits hot-swap into the running game. See pc/docs/porting/.

Status

The port is playable but unfinished. It boots, plays the intro movie, and runs New Game (the opening cutscenes, then control of Ashley) and Continue from a memory card; exploration, battles, menus, saving and loading work in the areas played so far. The automated suites cover the boot, the opening, the first rooms, a save room and long unattended soak runs. It has not been played through to the end. Known gaps:

  • The ending is ported but only reached by a jump. ENDING.PRG runs natively (credits, the MISSION COMPLETE score and rank screen, the return to the title and its clear-data save; ending_smoke, from RPC ending), but no one has yet reached it by playing the final events.
  • Code paths that have not been translated yet stop the game with a named [UNIMPLEMENTED] message (and a stack trace) rather than misbehaving. Rarely reached branches (some spells, effects and enemy AI routines) are less tested than the rooms the tests visit.
  • The game sees a digital PS1 pad: a gamepad's left stick works as a D-pad (the right stick drives the camera); there is no analog movement, button pressure or rumble.
  • Widescreen (16:9) is experimental and off by default; some classic menu screens still show artifacts in 16:9 (being fixed). HDR output is not implemented.
  • 32-bit Vulkan drivers have no ray tracing: the Vulkan renderer and the Ultra preset need the 64-bit build.
  • Linux, and Windows through a build made on Linux or WSL (see Platform support).

Requirements

  • OS: Linux on x86-64. Developed and tested on Ubuntu 24.04 LTS (X11 and Wayland/XWayland sessions). Other current distributions should work with the equivalent packages but are untested. Windows 10/11 x64 runs a build made on Linux or WSL2 (see Windows); macOS is not supported.
  • GPU and driver (64-bit build, recommended):
    • Vulkan 1.3 with dynamic rendering, synchronization2 and geometry shaders for the Vulkan renderer. With VK_KHR_ray_query (NVIDIA RTX, AMD RDNA2 and later, Intel Arc, on current drivers) you get ray-traced shadows and the Ultra/High presets; tested on NVIDIA (proprietary driver) and Intel integrated graphics (Mesa).
    • Without ray queries Vulkan still runs, with shadow maps and the Low / Medium presets. Without usable Vulkan the game falls back to OpenGL: 4.3+ (compute shaders) for the OpenGL path tracer and probe GI, down to 3.3 core for the basic renderer.
  • CPU/RAM: any recent x86-64 CPU; 8 GB RAM is plenty for playing (building uses about 1-2 GB per compiler job).
  • Disk: about 2.5 GB for a checkout with your disc image, the extracted data and both builds, plus about 2 GB free temporarily during the first 64-bit build (the NRD shader compiler is unpacked and then deleted).
  • Network for the first build: the decompilation's make downloads its toolchain (old GCC builds, mkpsxiso, Python packages for splat; tens of MB). The first 64-bit build downloads NVIDIA NRD with its dependencies, including the DirectX Shader Compiler: about 500 MB, which is deleted again after NRD is built (about 40 MB stays in pc/build/nrd). Later builds work offline.

Packages (Ubuntu 24.04)

Build tools, the SDL 3 platform headers (SDL is vendored and built from source; its backends load their libraries at run time), Vulkan and the test helpers:

sudo apt install git build-essential ninja-build pkg-config python3 python3-venv \
    gdb libvulkan-dev mesa-vulkan-drivers vulkan-tools \
    libx11-dev libxext-dev libxi-dev libxcursor-dev libxfixes-dev libxrandr-dev \
    libxrender-dev libxss-dev libxtst-dev libwayland-dev libxkbcommon-dev \
    libdecor-0-dev libpipewire-0.3-dev libpulse-dev libasound2-dev \
    libdbus-1-dev libudev-dev python3-numpy python3-pil xvfb
  • CMake 3.30 or newer. NRD's dependencies require it, and Ubuntu 24.04's cmake package is 3.28: install a current CMake, for example sudo snap install cmake --classic (or Kitware's APT repository, or pipx install cmake), and make sure cmake --version reports it. With an older CMake the build still succeeds, but without NRD (it warns once and the Vulkan path tracer uses its own denoiser).
  • The decompilation's toolchain, for step 3 of the build. Either Docker (sudo apt install docker.io, then add yourself to the docker group; the snap package works too), which is what this README was verified with, or install the upstream prerequisites on the host: sudo apt install binutils-mipsel-linux-gnu clang-format unzip wget (upstream lists newer minimum versions than Ubuntu 24.04 ships; see Setup). The port's own build also needs mipsel-linux-gnu-ld, and runs it from the same Docker image when it is not installed.
  • A graphics driver. On NVIDIA, the proprietary driver (nvidia-driver-*, which includes Vulkan); on AMD and Intel, Mesa (mesa-vulkan-drivers, above). vulkaninfo --summary (from vulkan-tools) should list your GPU with apiVersion 1.3 or later.
  • Sound goes through SDL to PipeWire, PulseAudio or ALSA, whichever is running (Ubuntu's desktop has PipeWire).

The 32-bit build (optional, see Build) additionally needs gcc-multilib g++-multilib and, after sudo dpkg --add-architecture i386 && sudo apt update, the 32-bit runtime libraries of the backends you use: libx11-6:i386 libxext6:i386 libxi6:i386 libxcursor1:i386 libxfixes3:i386 libxrandr2:i386 libxss1:i386 libxrender1:i386 libpulse0:i386 libasound2t64:i386 libudev1:i386 libdbus-1-3:i386 libgl1:i386 libegl1:i386, plus the 32-bit OpenGL driver (libgl1-mesa-dri:i386, or your NVIDIA driver's libnvidia-gl-*:i386). Multiarch packages must match the versions of their 64-bit counterparts; check apt's list before confirming anything it wants to remove.

Getting the game data

You need your own copy of Vagrant Story (USA), SLUS-01040 and a dump of it made from your own disc: a raw (2352 bytes per sector) single-track BIN image, as made by a disc-ripping tool's BIN/CUE mode. Other releases (Europe, Japan) and other formats (ISO, CHD, PBP, ECM) are not supported.

  1. Place the image at disks/SLUS-01040.bin in the repository (create disks/; it is git-ignored, as is everything extracted from it). A symbolic link to an image stored elsewhere also works for the host build (Docker only sees files inside the repository, so use a copy or a hard link there).
  2. The decompilation's make (build step 3) extracts the disc's files into data/ with mkpsxiso's dumpsxiso, splits the executables with splat, rebuilds them from the decompiled sources, and compares every rebuilt binary with the one from your disc. All files match at the end is the check that your image is the right one: a bad or different dump fails there (no separate checksum is published upstream).

Never commit anything from disks/, data/, build/ or pc/build/.

Build

The build has two parts: the upstream decompilation's make, which extracts your disc and builds the original PS1 files (the port uses its extracted data, symbol tables and linker maps), then the port itself (pc/tools/build_boot.py, driven by pc/run-game.sh).

1. Clone with submodules (into your home directory if you use the Docker snap, which cannot see /tmp):

git clone --recursive https://github.com/noprompt/rood-boi.git
cd rood-boi

2. Add your disc image as disks/SLUS-01040.bin (see above).

3. Extract and build the original files (once, and again only when src/ or the disc changes). With Docker, build the toolchain image once and run make in it as yourself:

# The upstream Dockerfile also copies the disc into the image for CI;
# building it without that line keeps your disc out of the image.
sed '/^COPY disks/d' Dockerfile | docker build -t rood-reverse-dev:local -
docker run --rm -u "$(id -u):$(id -g)" -e HOME=/tmp -v "$PWD:/work" -w /work \
    rood-reverse-dev:local make -j8

(Or, with the toolchain installed on the host, just make -j8.) It ends with ✔ All files match. The image name rood-reverse-dev:local matters: the port's build uses it to run mipsel-linux-gnu-ld when that is not installed.

4. Build and play (recommended: the 64-bit build with Vulkan):

pc/run-game.sh --vulkan

pc/run-game.sh builds the port (unless --no-build), then starts the game in a window from the repository root, with settings in pc/user/settings.cfg. On a hybrid-graphics NVIDIA machine it renders on the NVIDIA GPU (PRIME offload; ROOD_GPU=integrated keeps the default GPU).

Option Effect
--vulkan 64-bit build, Vulkan renderer (ROOD_RENDERER=vulkan). Recommended. Falls back to OpenGL if Vulkan 1.3 is not available.
(none) or --64 64-bit build with the OpenGL renderer
--32 32-bit build (build_boot.py --battle) with OpenGL: the original port configuration, no longer tested; needs the multilib/i386 packages above and has no Vulkan or NRD
--reload 64-bit development split: the engine is a library the running game reloads in place (below)
--no-build skip the build step and run the existing binary
--skip-movies (passed to the game) skip the intro movie

To start at the title every time (no publisher and developer logos, no intro movie), turn on System > Gameplay > Skip intro, or put skip_intro 1 in pc/user/settings.cfg. It is off by default: the original start.

To shorten the wind-up before spells, items and Break Arts take effect in battle, set System > Gameplay > Battle charging to Fast (4x) or Skip (full speed), or put qol_skip_charging 1 (or 2) in pc/user/settings.cfg. Off by default; the battle itself plays exactly the same, only faster to watch.

The builds go to pc/build/boot64/rood_battle_probe (64-bit) and pc/build/boot/rood_battle_probe (32-bit). To build without running: python3 pc/tools/build_boot.py --arch 64 (add --nrd off to skip NRD and its download) or python3 pc/tools/build_boot.py --battle for 32-bit.

Build times (measured on a 20-thread desktop with a fast connection): building the Docker image takes a minute or two and step 3 under a minute; the first 64-bit build about 3 minutes (building the vendored SDL 3 and glslang, and fetching and compiling NRD); the first 32-bit build about 2 minutes. A later build with nothing changed does nothing (well under a second: pc/build/<tree>/build-stamp.json records every input of the last complete build), and after a change only the units it touches recompile (a few seconds; pc/tools/build_cache.py). build_boot.py --check says whether a build would do anything. --no-build skips even the check.

Engine edits without a restart (Linux, 64-bit). pc/run-game.sh --reload (with --vulkan for Vulkan) builds pc/build/dev64: rood_host, the game and its state, and librood_engine.so, the rest of pc/ (renderers, UI, editor, Lua, RPC). While it runs, pc/tools/dev_loop.sh --watch rebuilds only the library after each save under pc/src or pc/shaders and the game swaps it at its next vsync: no restart, the window, audio, settings and game state stay (about 2.5 s from the save to the new engine on screen for a renderer edit; dev_loop.sh --reload does it once). A change to the game itself or to what the host is built from falls back to a rebuild and an RPC restart at the same moment. See pc/docs/plans/2026-10-19-engine-reload.md.

Run

pc/run-game.sh --vulkan --no-build starts the game without rebuilding. The intro movie plays first (Start skips it), then the title: New Game, or Continue to load from the memory card.

Keyboard

Key PS1 button
Arrow keys D-pad
Z Circle (confirm, attack)
X Cross (cancel)
A Square
S Triangle
Q / W L1 / R1
1 / 2 L2 / R2
Enter Start
Tab Select
J / L, I / K, O camera: turn, zoom, reset (the right stick and R3 on a gamepad)
Escape or F1 open/close the editor
F2 free camera (opens the editor)
` (backtick) fast-forward while held (both stick clicks, L3 + R3, on a gamepad)

Gamepads are SDL 3 gamepads (SDL's controller database; extra mappings from SDL_GAMECONTROLLERCONFIG or a gamecontrollerdb.txt in pc/user/). Buttons map by position, so the east face button is Circle (confirm) and the south one Cross (cancel) on any pad; D-pad or left stick moves; shoulders, triggers, Start/Select (Back) and the left stick click map to their PS1 equivalents. The right stick turns the camera around Ashley (left/right, faster the further it is pushed) and zooms (up/down); R3 turns it back to the game's 45-degree view and distance. L1/R1 still turn in 45-degree steps; Start (or R3 with the reset turned off) is the first-person view. Settings: the editor's Graphics > Controls (speed, dead zone, curve, invert, zoom range, idle reset; see pc/README.md, "Right-stick camera"). PlayStation controllers, including the DualSense and DualShock 4 over USB or Bluetooth, work as ordinary gamepads; their touchpad, motion sensors, lightbar, rumble and adaptive triggers are not used. Gamepads can be plugged in at any time; ROOD_CONTROLLER=none disables them. While the editor is open the keyboard and mouse belong to the editor, but a gamepad still plays.

Saves are standard 128 KiB memory card images: slot 1 is pc/save/card1.mcd (created on the first save), slot 2 pc/save/card2.mcd (inserted only if the file exists). Save at a save point and load with Continue on the title screen. The images are compatible with PS1 emulators.

Settings. Graphics and lighting settings are changed in the editor and saved with File > Save settings (Ctrl+Shift+S) to pc/user/settings.cfg, a plain text file (edits made outside the game apply live). Per-room lights and lighting overrides are saved with Ctrl+S to pc/lights/. pc/save, pc/user and pc/lights are yours and git-ignored.

Lighting quality. The editor toolbar's Lighting dropdown picks a preset:

Preset Shadows Indirect light Needs
Original none: the PS1's own baked lighting baked anything
Low shadow maps baked integrated GPUs
Medium soft shadow maps probe GI no ray tracing needed
High ray-traced soft shadows probe GI ray queries (entry RT)
Ultra ray-traced (2 rays) path tracing + NVIDIA NRD discrete RT GPU, Vulkan

On first run, before any settings are saved, the preset is detected: Ultra on a discrete GPU with Vulkan ray queries, High on an integrated one with them; without ray queries Medium on a discrete GPU, Low otherwise. ROOD_LIGHTING_PRESET=low (any preset name, or auto) overrides it. Choices a backend cannot run fall back to the next one (the editor shows why). ROOD_GI=0 turns the dynamic lighting off entirely.

The editor (Escape or F1) is laid out like Unreal's: a toolbar, an Outliner of the room's lights and glows, a Details panel (lighting, atmosphere, post effects, graphics, diagnostics), Place Actors for light prefabs, and Help > Keyboard shortcuts. Right-drag in the view flies a free camera (WASD/QE); Play returns to the game camera. See pc/README.md ("Renderer and developer overlay") for everything it does.

Useful environment variables (more in pc/README.md): ROOD_WINDOW=WxH (window size), ROOD_SCALE=1..8 (internal resolution, default 4), ROOD_WIDESCREEN=1, ROOD_AUDIO=none, SDL_VIDEO_DRIVER=x11|wayland.

If something goes wrong, the terminal shows the log. A crash prints [crash] and [stack] lines (pc/tools/where.sh resolve turns them into function names); [UNIMPLEMENTED] name means the game reached code that is not ported yet. Please include those lines, your GPU and driver, and what you were doing when you report a problem.

Tests

The test runner starts the game headless (on the GPU through EGL, no X server, or on a private Xvfb display with software rendering) with scratch memory cards and settings, so your saves and settings are never touched:

cmake -S pc -B pc/build -G Ninja && cmake --build pc/build   # CMake probes, once
python3 pc/tests/run.py --list                               # the suites
python3 pc/tests/run.py --arch 64 --renderer vulkan          # everything, 64-bit Vulkan
python3 pc/tests/run.py --arch 64 --renderer vulkan rpc      # suites matching "rpc"
python3 pc/tests/run.py                                      # everything, 64-bit OpenGL
python3 pc/tests/run.py --arch 32                            # the 32-bit build (no longer kept up)

The runner prefers rendering on the GPU through EGL (python3 pc/tools/rood_rpc.py headless shows which mode and GPU it gets) and falls back to Xvfb with software rendering, which is several times slower. It prints one table with each suite's result and log (pc/build/tests/<suite>/), and exits non-zero if any failed. It does not build the game: build first. Some suites need a save on pc/save/card1.mcd and are skipped without one; golden-frame references are generated locally (pc/tests/golden_frames.py --update) and never committed. A quick boot check without the runner:

pc/build/boot64/rood_battle_probe --skip-movies --title-checkpoint

exits with status 0 once the original title code reaches its input loop.

Platform support

Platform Status
Linux x86-64 Supported (Ubuntu 24.04 tested; X11, Wayland via XWayland or natively)
Windows 10/11 x64 Native 64-bit build, cross-compiled from Linux or WSL with MinGW-w64 (Windows 11, NVIDIA RTX 4070 tested; Vulkan with ray queries and NRD)
macOS Not supported, not tested
Linux on ARM Not supported (the build and the guest memory layout assume x86)

Windows

The 64-bit build runs natively on Windows as rood.exe (Vulkan or OpenGL, ray-traced lighting and NRD, WASAPI audio, XInput/HID gamepads). It is built on Linux, or in WSL2 on the Windows machine itself, since the decompilation's make and the port's symbol analysis need Linux tools: the build compiles every unit twice, for Linux (the analysis) and with MinGW-w64 (the executable). How it works and its limits are in pc/docs/Platform_Support.md.

  1. In Linux or WSL2 (Ubuntu), follow Build steps 1-3 (in WSL, keep the checkout in the Linux file system, e.g. ~/rood-boi, not under /mnt/c), and install MinGW-w64: sudo apt install mingw-w64.
  2. Build: python3 pc/tools/build_boot.py --target windows (it also builds the Linux 64-bit objects it analyses; NRD's Windows library is compiled from the Linux NRD build's sources and shaders).
  3. Make a folder to play from (on WSL, a Windows drive): python3 pc/tools/windows_dist.py /mnt/c/Games/rood-boi --disc.
  4. On Windows, run play.bat in that folder. The log is rood.log; saves and settings stay in the folder's pc\save and pc\user across updates.

The developer RPC takes ROOD_RPC=tcp:PORT on Windows (a loopback TCP port: Windows' Python has no Unix sockets); pc/tools/rood_rpc.py connects to it from Windows or WSL. Every TCP connection must authenticate first, including Lua eval/grant requests. Supply ROOD_RPC=tcp:PORT:TOKEN, or let the server generate a secret in $ROOD_OUT/rpc.token (default pc/build/boot/rpc.token, next to the default Unix socket). ROOD_RPC_TOKEN_FILE overrides this path; rood_rpc.py reads it when the address has no token. The file is mode 0600 on Unix and owner-only on Windows; Windows refuses existing token files, so remove the old file before restarting. Only ROOD_RPC_PRINT_TOKEN=1 prints the generated secret to stdout. Generation/storage failure disables TCP RPC; Unix socket behavior is unchanged. The Linux-only test harness (pc/tests, Xvfb/EGL headless runs) does not run on Windows.

macOS

Not supported. Besides needing a Mach-O equivalent of the Windows work (pc/docs/Platform_Support.md), macOS has no native Vulkan (MoltenVK lacks the geometry shaders and ray queries the Vulkan renderer uses) and caps OpenGL at 4.1 without compute shaders, and its ARM machines would need the guest memory layout reworked.

Licence and credits

The project's own code (the decompilation inherited from rood-reverse and the port under pc/) is dedicated to the public domain under CC0 1.0 (see LICENSE). Vendored third-party code under pc/third_party/ (SDL 3, Dear ImGui, ImGuizmo, glslang, PsyCross) keeps its own licence, and NVIDIA NRD and its dependencies are downloaded at build time under their own terms and never committed; see THIRD_PARTY.md.

Thank you

rood-boi exists because of the rood-reverse decompilation.

  • ser-pounce started rood-reverse and has done the overwhelming majority of the work on it. Turning Vagrant Story back into readable C that rebuilds the original game byte for byte is what made a native port like this possible at all. None of this would exist without it.
  • Lil' Sassy is one of the decompilation's most prolific contributors; their work is part of the game code this port compiles and runs.
  • eremtsov made the Vagrant Story QoL mod (CC0); its optional weapon slots quick swap (L2 + R2) is ported from it (pc/README.md).
  • Kenney made the Input Prompts icons (CC0) that the button prompts draw for keyboards and PlayStation, Xbox and Nintendo controllers (pc/README.md).
  • Andrew Kuhar designed the Vagrant Story UI Remaster (Figma prototype), the inspiration for the optional modern menus and HUD (pc/docs/Modern_Menus.md). Our layouts are our own implementation; no assets from the prototype are used.
  • Thanks also to every other rood-reverse contributor, and to the projects and people credited in the upstream section below.

The decompilation (upstream rood-reverse)

The rest of this README is the upstream project's, lightly adapted. rood-reverse is a decompilation project for Vagrant Story for PlayStation 1, with a goal of enabling interoperability with modern hardware and fixing bugs in the original game. It does not contain any of the original files from the game disk; you must own a copy of the game. The PS1 build in this repository still matches the original binaries (make reports All files match).

Many thanks to the Chrono Cross Decompilation for much of the sound library code.

Heavily inspired by and indebted to the incredible work of the sotn-decomp team and the PS1/PS2 decompilation Discord server.

Grateful to the authors of Data Crystal’s Vagrant Story page for their excellent work and insights.

Thanks also to the following amazing projects (and their dependencies):

Decompilation progress (upstream)

These badges track the upstream repository (ser-pounce/rood-reverse), not this fork's additions.

Overall progress

Core libraries

SLUS_010.40 progress

Main game engine

BATTLE.PRG progress INITBTL.PRG progress SCREFF2.PRG progress

Effects

Total effects progress

Per file

EFFPURGE.BIN progress PLG005.BIN progress PLG044.BIN progress PLG045.BIN progress PLG047.BIN progress PLG049.BIN progress PLG050.BIN progress PLG051.BIN progress PLG053.BIN progress PLG057.BIN progress PLG061.BIN progress PLG065.BIN progress PLG065.BIN progress PLG073.BIN progress PLG077.BIN progress PLG081.BIN progress PLG082.BIN progress PLG085.BIN progress PLG086.BIN progress PLG087.BIN progress PLG114.BIN progress PLG128.BIN progress PLG129.BIN progress PLG134.BIN progress PLG135.BIN progress PLG137.BIN progress PLG138.BIN progress PLG139.BIN progress PLG141.BIN progress PLG142.BIN progress PLG143.BIN progress PLG146.BIN progress PLG147.BIN progress PLG148.BIN progress PLG149.BIN progress PLG150.BIN progress PLG152.BIN progress PLG153.BIN progress PLG154.BIN progress PLG156.BIN progress PLG158.BIN progress PLG160.BIN progress PLG161.BIN progress PLG162.BIN progress PLG165.BIN progress PLG166.BIN progress PLG167.BIN progress PLG168.BIN progress PLG169.BIN progress PLG198.BIN progress PLG224.BIN progress PLG232.BIN progress PLG232.BIN progress PLG242.BIN progress PLG246.BIN progress PLG250.BIN progress PLG255.BIN progress PLG260.BIN progress PLG263.BIN progress PLG265.BIN progress PLG265.BIN progress PLG272.BIN progress PLG273.BIN progress PLG291.BIN progress PLG297.BIN progress PLG300.BIN progress PLG300.BIN progress

Menus

Total menu progress

Per file

MAINMENU.PRG progress MENU0.PRG progress MENU1.PRG progress MENU2.PRG progress MENU3.PRG progress MENU4.PRG progress MENU5.PRG progress MENU7.PRG progress MENU8.PRG progress MENU9.PRG progress MENUB.PRG progress MENUC.PRG progress MENUD.PRG progress MENUE.PRG progress MENUF.PRG progress

Title and Ending Sequence

TITLE.PRG progress ENDING.PRG progress

Editable content

The entirety of the game's menu code and data is decompiled, including all files in MENU and SMALL, with the exceptions of MENU/MCDATA.BIN, MENU/OPMCIMG1.BIN and MENU/OPMCIMG2.BIN.

Much of the menu code has been refactored and is readable, and the menu executables are completely relocatable. It should be possible to rewrite the menu code arbitrarily, the method and data addresses in other modules will be relinked appropriately.

Due to the presence of a large number of empty sectors at the start of each directory on the disk, it should also be possible to rebuild the disk without affecting sector-based data loading in BATTLE.PRG, as long as the number of dummy sectors is adjusted accordingly.

(Naive) Quickstart

For decompilation work, which is best contributed upstream to rood-reverse:

  1. n.b.: You may want to consider limiting the jobs spawned by make to something sensible like -j8.
  2. Fork the project
  3. Install system dependencies and copy disk image (see "Setup" below)
  4. Run make -j to perform an initial split & build
  5. Pick a function to decompile, use make decompme to create a scratch on decomp.me
  6. Claim and decompile the scratch
  7. Copy the decompiled code where it belongs
  8. Optionally use make permute if needed
  9. Run make remake -j, and finally make format if the code compiles successfully
  10. Open a PR

Setup

The project is mostly self-configuring but requires a minimal amount of setup.

  • Make sure the following packages are installed, older versions may also work but this is not tested. This configuration works as-is on Ubuntu 26.04 on WSL; depending on your distro you may need additional packages.
Package Minimum Version
clang-format 21.1.8
g++ 15.2.0
binutils-mipsel-linux-gnu 2.45.90
make 4.4.
python3 3.14.4
python3-venv 3.14.4
unzip 6.00
wget 1.25.0

Take a look at ./Dockerfile for a minimal setup on Ubuntu

  • Dump your original disk to disks/SLUS-01040.bin
  • Run make -j to finish installation and perform an initial build

Build targets

  • make -j should be all that is needed most of the time. The first execution will configure the remaining dependencies in the tools directory and extract the files from the disk; from then on it will perform a minimal rebuild.
  • make decompme TARGET=path/to/nonmatchings/source.s uploads the target function to a new decomp.me scratch.
  • make permute TARGET=path/to/nonmatchings/source.s invokes the permuter for the target assembly file.
  • make remake -j will delete and re-split the targets; this can be necessary if the dependency management has failed to identify everything that needs rebuilding (in which case a bug report is appreciated!), or if the configuration has changed enough to be no longer valid (e.g. orphaned .d files). It's good practice to run this before submitting a pull request to make sure everything still works.
  • make format formats the source files and symbol addresses for consistency. Please run this before submitting a PR.
  • make clean simply deletes the build and nonmatchings directories
  • make clean-all will completely reset the project, including dropping any source changes and data files (but not the disk image). Use with caution.

About

Native PC port of Vagrant Story on the rood-reverse decompilation: Vulkan ray tracing, path-traced GI, live editor. Bring your own disc.

Resources

Stars

27 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages