PS2

How to Recomp PS2 Games: The Complete Walkthrough

This tutorial takes you from a fresh Linux (or Apple Silicon Mac) machine to a PS2 game running in your browser, using the open-source ps2-web-recomp toolchain. Budget around 30–60 minutes, most of it waiting on the first build.

Before you start — the honest version

  • Only two games have been brought up so far (Gran Turismo 4 and God of War II). Your game may stop at a system call or graphics feature nobody has implemented yet. That’s the current state of the project, not a bug in your setup.
  • You need a disc image of a game you own. No game data is included with the project, and none is downloaded by it.
  • You need a browser with WebGPU: Chrome or Edge on Windows/macOS. On Linux it’s off by default (see below).
  • Expect roughly 300 MB of disk space per game for the generated code and builds.

Step 1 — Install the toolchain

You need: git, CMake, Ninja, a C++20 compiler (clang is preferred and picked up automatically), Python 3, and 7-Zip if your disc image is inside a .7z archive.

On Debian/Ubuntu-based distributions:

sudo apt install git cmake ninja-build clang python3 p7zip-full

On macOS (Apple Silicon), the scripts need a newer bash than the system 3.2:

brew install bash cmake ninja sevenzip

The first run installs the Emscripten SDK into tools/emsdk (or uses the one the EMSDK environment variable points to) and downloads wgpu-native for the native runner. If you only want the native window, pass --native-only to skip the browser build entirely — that path needs the SDL2 development files instead.

Step 2 — Clone the repository

git clone https://github.com/snuri00/ps2-web-recomp.git
cd ps2-web-recomp

Step 3 — Recompile your game

scripts/port.sh mygame "My Game.iso"

port.sh takes an ISO (or a ZIP/7z archive containing one) and does the whole job end to end:

For reference, God of War II goes from ISO to page in about three and a half minutes on an 8-core laptop.

Customizing the discovery runs

By default the exploring runs press start and then cross every five seconds — enough to get most games through their title screens — and insert an empty memory card in slot 1, following the path a player would take.

scripts/port.sh mygame "My Game.iso" --press 900:cross --frames 2400

Frames from the last run land in games/mygame/shots — the quickest way to see how far a new game gets. To rebuild only the page after a change, use scripts/build_web.sh mygame.

Step 4 — Serve it and play

python3 scripts/serve.py build/web-mygame games/mygame/disc.iso

Then open http://localhost:8620/. The disc is read over HTTP Range requests, so only the executable is downloaded up front; everything else streams as the game asks for it.

Browser requirements (WebGPU)

Troubleshooting: if your game doesn’t boot

Set your expectations: two games have been brought up so far. Another game will most likely stop at a system call or an IOP library function nobody has implemented yet. The runner logs exactly that:

[sys] unhandled syscall

The game called an operating-system function the high-level emulation doesn’t answer yet.

[iop] missing <library> #<n>

An I/O processor library function the game needs hasn’t been reimplemented.

Graphics issues (missing or wrong geometry)

The game may use a Graphics Synthesizer feature the renderer doesn’t handle yet.

These aren’t signs you did something wrong — they’re the frontier of the project. Check the project’s GitHub issues to see if your game is being worked on, and share your findings if it isn’t.

What about performance?

The two verified games set the bar to expect:

You change the internal resolution from the page. On a discrete GPU, expect more headroom.

Next: what games run today?

See the full compatibility breakdown for the verified titles — and what’s known about the road ahead.

PS2 Web Recomp games list →