z2rs
z2rs is a clean-room-style reconstruction of Zelda II: The Adventure of Link (NES) in Rust. It runs as a desktop app, in the browser (WebAssembly) and on Android, and it is checked frame by frame against the original ROM running in a reference emulator.
- Type: PC port
- Game: Zelda II: The Adventure of Link
- Runs on Windows, Linux and macOS
- By troyedwardsjr
- Latest release v0.3.0, 2026-09-27
- Source: https://github.com/troyedwardsjr/z2rs
README
z2rs
z2rs is a clean-room-style reconstruction of Zelda II: The Adventure of Link (NES) in Rust. It runs as a desktop app, in the browser (WebAssembly) and on Android, and it is checked frame by frame against the original ROM running in a reference emulator.
You bring your own ROM. Nothing from the original game is distributed here. PROVENANCE.md records what reference material the project worked from and where every file in this repository came from, and LEGAL.md has the rules contributors follow.
On top of the original game, z2rs adds a few optional extras:
- widescreen, with real scenery in the margins instead of a stretched picture
- HD graphics packs, so you can repaint tiles and sprites at 2x to 8x
- two-player co-op with a second Link, on one machine or online
- save states, fast-forward, movie playback and gamepad support
Release announcement: Moddable Zelda 2 PC / Web port with Online Multiplayer Co-op and Widescreen Released. Chat is on Discord.
Play it
- Download the archive for your system from the releases page. There are builds for Linux, macOS (Intel and Apple Silicon) and Windows. Unpack it.
- Start the launcher:
z2rs-launcher.exeon Windows,z2rs.appon macOS,z2rs-launcheron Linux. - Pick your Zelda II (USA) ROM and press Play.
The launcher also sets the window size, fullscreen, widescreen (16:10, 16:9 or 21:9 ultrawide), an HD pack folder, and local or online co-op. Online co-op uses a public signalling server by default, so two players only need to agree on a room name.
The game remembers the last ROM it loaded, so after the first run you can start z2rs directly and it boots straight into the game. Dragging a ROM onto the game window still works. HOW-TO-PLAY.txt in the archive lists the controls and where settings and saves are kept.
For Android 8.0 and newer, the releases page also has z2rs-<version>-android.apk. Install it, pick your ROM in the app and press Play. It has an on-screen gamepad and works with Bluetooth and USB controllers. Online co-op is not available on Android yet. guide/android.md covers installing, the controls and the settings.
Only one dump passes the check, identified by the hash of the ROM body with the 16-byte iNES header stripped: CRC32 BA322865, SHA1 11333adb723a5975e0ecca3aee8f4747aa8d2d26 (No-Intro USA). The file is only ever read in place.
Nothing in the archive is code signed. On macOS, right-click z2rs.app and choose Open the first time, or use Open Anyway in System Settings > Privacy & Security on newer versions. Windows SmartScreen wants More info and Run anyway, and on Linux the files may need chmod +x.
From a terminal you can skip the launcher:
./z2rs --rom /path/to/zelda2.nes --scale 3
./z2rs --fullscreen
z2-signal, the third binary in the archive, is the signalling server for online co-op. You only need it to host your own instead of using the public one.
Build from source
You need Rust stable (cargo, rustc). The browser build also needs the wasm32-unknown-unknown target (rustup target add wasm32-unknown-unknown) and wasm-pack.
make build # cargo build --workspace (no ROM needed)
make test # cargo test --workspace (tests that need a ROM skip without Z2_ROM)
export Z2_ROM=/path/to/zelda2.nes
make run # play the optimized desktop build
make run-web # build the wasm bundle and serve it on :8080
The Android app is built with make android, which needs the Android SDK, NDK and cargo-ndk. guide/android.md lists the prerequisites and explains how to sign a release APK.
make help lists every target. A target that needs Z2_ROM prints what to set and exits with status 2 when it is missing.
Controls
| Action | Player 1 | Player 2 (co-op) |
|---|---|---|
| A | Z | G |
| B | X | F |
| Start | Enter | T |
| Select | Shift (either one) | R |
| D-pad | arrow keys | W A S D |
Tab fast-forward, F5 save state, F7 load state, F6 next save slot, P pause, . single-step while paused, F11 or Alt+Enter fullscreen, Esc leave fullscreen or quit. Gamepads work too.
Guides
| Guide | What is in it |
|---|---|
| guide/desktop.md | the launcher, every key, save-state slots, command-line flags, the config file, gamepads |
| guide/android.md | installing the APK, the on-screen gamepad, controllers, accessibility, building and signing the app |
| guide/browser.md | the web build, its URL parameters, optional features and bundle size |
| guide/co-op.md | two Links locally or online, widescreen, how both work and what they cannot do |
| guide/hd-packs.md | making a pack by painting over spritesheets of the game (make hd-sheets, make hd-pack) and playing with it |
| guide/development.md | repository layout, headless runs, and how the port is checked against the original |
Contributing and legal
CONTRIBUTING.md covers setup, the pre-commit hook and the rules for tests that need a ROM. LEGAL.md explains what may never be committed. Read it before you open a pull request.
License
The z2rs source code is released under the MIT license (LICENSE). The license does not cover the original game, which you must supply yourself.