Underground 2 Revived
Play Need for Speed: Underground 2 (2004) in Chrome and Firefox with WebGPU graphics, Web Audio, up to 120 fps widescreen, controller support, free roam and Online races with friends. Fan project, not
RustyNES, 순수 Rust로 만든 사이클 정확도 NES 에뮬레이터
[RustyNES] Cycle-accurate Nintendo Entertainment System NES emulator built in pure Rust — 208+ mappers, WebAssembly-ready, GGPO netplay, TAS tools, and RetroAchievements integration for game preservat
게임Rust · PythonGitHub @doublegate온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
[RustyNES] Cycle-accurate Nintendo Entertainment System NES emulator built in pure Rust — 208+ mappers, WebAssembly-ready, GGPO netplay, TAS tools, and RetroAchievements integration for game preservation. "Precise. Pure. Powerful."
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Precise. Pure. Powerful.
RustyNES is a cycle-accurate Nintendo Entertainment System emulator written in
pure Rust. It aims at the Mesen2 / higan / ares accuracy bar: one master clock,
every CPU cycle a real bus access, and the PPU caught up to each half of it, so a
sprite-zero hit, a mid-scanline scroll write or an MMC3 IRQ lands on the exact dot
without a per-game patch. It passes AccuracyCoin 146/146 and matches the
Nintendulator nestest log with zero diff.
Around that core sits a complete, modern platform: 208 mapper families, the Famicom Disk System, Vs. System and PlayChoice-10 arcade boards, rollback netplay, RetroAchievements, a TAStudio piano-roll editor, a Mesen2-class debugger, HD packs, a shader stack, and native apps for desktop, the browser, Android, iOS and RetroArch, all on one bit-deterministic core.
Play it in your browser, no install required.
Upgrading from v2.x? v3.0.0 "Cornerstone" is a major release. Save states and movies made by earlier versions are refused, netplay needs both sides on the same emulation epoch, and saves are keyed to the ROM without its header. The v3.0.0 release notes list every change by audience: players, RetroArch, mobile and the Rust crates.
Development note: AI-assisted. RustyNES is built with LLM tooling under a human-directed, test-driven workflow, with public test ROMs as the oracle. See
docs/originality-and-provenance.mdfor what that means for originality and licensing. The accuracy claims are meant to be checked by running the public suites, not taken on faith. A comparison to another emulator is a comparison, not a claim of being better.
| Cycle-accurate | CPU, PPU and APU on one master clock: AccuracyCoin 146/146, nestest 0-diff, blargg's CPU, APU and PAL suites |
| 208 mapper families | NROM through MMC5, the whole VRC line, Sunsoft FME-7, Namco 163, Taito, J.Y. Company, the MMC3 and MMC1 multicarts, Waixing and Nanjing boards, homebrew flash boards with working saves, and a UNIF (.unf) loader. Each is classified Core, Curated or BestEffort by the evidence behind it |
| Famicom Disk System | Real-BIOS boot, writable disks, side swapping, a timed disk-head model and 2C33 wavetable audio |
| Vs. / PlayChoice-10 | Arcade boards in true 2C03 / 2C04 / 2C05 RGB, per-game DIP presets, and Vs. DualSystem two-screen cabinets |
| Rollback netplay | GGPO-style, up to four players over UDP or browser WebRTC, with room codes, TURN traversal and spectators; peers must match on ROM, emulation options and emulation epoch, so a session cannot silently diverge, and a mismatch is refused with its reason |
| RetroAchievements | Achievements, leaderboards, rich presence and hardcore mode through the rcheevos library |
| TAStudio | A piano-roll TAS editor with a greenzone, branches and markers, plus .fm2 / .bk2 / .fcm / .fmv / .vmv import |
| Debugger | Conditional breakpoints, watchpoints, a hex editor, RAM search, a callstack, .dbg source maps, and editable palette, nametable, CHR and OAM |
| Video and audio | NTSC composite filtering, a CRT shader stack, HD packs with OGG audio, .pal palettes, a generated NTSC palette, and an NSF / NSFe player |
| Save states, rewind, run-ahead | All on the deterministic snapshot path. A movie records the options it was made with (console model, chip revisions, power-on state and more) and the emulation epoch, so a replay is bit-identical whatever the player's settings, and a movie from a version that emulates differently is refused rather than replayed wrong |
| Lua scripting | A sandboxed Lua 5.4 engine with memory access, callbacks, an HUD and a TAStudio API |
Pre-built binaries for every release are on the
Releases page: Linux x86_64,
macOS (Apple silicon) and Windows x86_64. From v2.9.7 they are the full
native build: RetroAchievements, Lua scripting, HD packs, A/V recording (with
ffmpeg on your PATH) and the debugger telemetry are all included.
# Linux / macOS
tar xf rustynes-<tag>-<target>.tar.gz && ./rustynes path/to/rom.nes
# Windows (PowerShell)
Expand-Archive rustynes-<tag>-x86_64-pc-windows-msvc.zip; .\rustynes.exe path\to\rom.nes
Launch it without a ROM and use F12, the File menu, or drag and drop a
.nes / .fds onto the window.
You need Rust 1.99 (pinned in rust-toolchain.toml; rustup
installs it) and Git.
git clone https://github.com/doublegate/RustyNES.git
cd RustyNES
cargo run --release -p rustynes-frontend -- path/to/rom.nes
# Everything native at once: RetroAchievements, Lua, host IPC, HD packs,
# debugger telemetry and A/V recording.
cargo full-run path/to/rom.nes
On Linux, the window, GPU and audio stack need a few system libraries:
# Ubuntu / Debian
sudo apt-get install -y libxkbcommon-dev libwayland-dev libxkbcommon-x11-dev libasound2-dev libudev-dev
# Arch / CachyOS
sudo pacman -S --needed libxkbcommon wayland alsa-lib systemd-libs
macOS and Windows need nothing extra; the optional retroachievements feature
needs a C compiler on every platform.
rustynes --help lists the command-line options, and rustynes help opens an
interactive guide to the controls, hotkeys, mappers, configuration, scripting and
netplay.
The hosted build is at doublegate.github.io/RustyNES.
To build it yourself, install trunk and run trunk serve
in crates/rustynes-frontend/web.
$2007 behaviour.docs/mappers.md
lists every family, its tier and its evidence.IndexedDB, from v2.9.7).disksys.rom, and UNIF boards
mapped to their iNES numbers.deploy/..rnm format 7).docs/memory-export-interface.md), and
rustynes dump-check to tell whether a ROM file is the dump it claims to be.rustynes-mcp, serving the headless core to a Model
Context Protocol client, with reproducible fork-and-diff experiments
(docs/mcp-server.md).ca65 / cc65 source maps. The inspectors become editors on request.docs/scripting.md..mp4 / .mkv through ffmpeg..slangp importer..pal palettes, a generated NTSC palette, and a choice of analog filter
models.docs/android.md.docs/ios.md.Both apps run the same core as desktop, and both are free: RustyNES is permanently non-commercial (ADR 0035).
Every binding can be changed in Settings or in the TOML config; the controls guide has the full list. USB gamepads bind to player 1 automatically.
| Action | Player 1 | Player 2 |
|---|---|---|
| D-pad | Arrow keys | W / A / S / D |
| A / B | Z / X | Q / E |
| Start / Select | Enter / Right Shift | P / R |
| Action | Key | Action | Key |
|---|---|---|---|
| Pause | Space | Save / load state | F1 / F4 |
| Fast-forward (hold) | Tab | Rewind (hold) | F5 |
| Frame advance | \ | Reset / power cycle | F2 / F3 |
| Speed up / down / reset | = / - / 0 | Open ROM | F12 |
| TAS record / play / branch | F6 / F7 / F8 | FDS disk side | F9 |
| Menu bar | M | Vs. coin | F10 |
| Debugger | ` | Fullscreen | F11 |
| Quit | Esc | Famicom microphone | N (hold) |
| Suite | Result |
|---|---|
| AccuracyCoin | 146/146 (100.00%) at upstream f5f41dc2, read from RAM rather than the screen. The 144/144 reported before v3.1.0 was overstated: the older ROM's Misaligned OAM behavior fail path fell through to a pass, hiding a real failure the re-sync found and fixed |
nestest | 0-diff against the Nintendulator log |
blargg cpu_interrupts_v2 | 5/5, and the unstable-store tests 6/6 |
| blargg APU (NTSC and PAL) | 11/11 and 10/10 |
blargg apu_test frame-counter probes | 10/10 |
blargg MMC3 (mmc3_test_2) | 5/6 strict, including 4-scanline_timing (all 13 sub-tests) since v3.0.0; 6-MMC3_alt tests the NEC revision, which the Sharp default is not, by design |
region_timing | 4/4, including PAL's 3.2:1 ratio |
| Holy Mapperel | every committed variant reports detail code 0000 |
| Commercial-ROM oracle | 99 titles, SHA-256-pinned, byte-identical frames |
The last MMC3 interrupt-timing residual, mmc3_test_2/4-scanline_timing, closed
in v3.0.0 (T-MMC3-BG-A12): every sub-test of the battery's MMC3 suite now passes
except the deliberate other-revision case. Every remaining known approximation is
listed, with its evidence, in docs/accuracy-ledger.md,
and the per-suite detail is in docs/STATUS.md.
When a document and a passing test ROM disagree, the ROM wins: that is this project's definition of cycle-accurate.
Mapper tiers. Of the 208 families, 181 are accuracy-gated: 51 Core and 130 Curated, each backed by a test ROM, a commercial dump, or a precise register description with a synthetic fixture. The other 27 are BestEffort: their documentation is thin, and a CI gate keeps them out of every accuracy claim.
| Platform | Status |
|---|---|
Linux x86_64, Windows x86_64, macOS (Apple silicon) | Release binaries |
| macOS (Intel), Linux ARM64 | Build from source |
| WebAssembly | Hosted and buildable |
| Android (arm64) | GitHub Releases (sideload) |
| iOS / iPadOS | TestFlight |
| RetroArch | rustynes_libretro core, published by the libretro buildbot |
A GPU with a wgpu backend is required: Vulkan, Metal, DX12, or WebGPU / WebGL2 in
the browser. The headless core runs a frame in about 4 ms on an Intel i9-10850K,
about four times faster than real time; docs/performance.md
has the measurements.
RustyNES is a Cargo workspace of focused crates. Three decisions carry the design,
detailed in docs/architecture.md and
docs/scheduler.md:
no_std and do not
depend on each other, so each can be fuzzed and benchmarked alone.| Crate | Role |
|---|---|
rustynes-cpu, rustynes-ppu, rustynes-apu | The 6502, 2C02 and 2A03 |
rustynes-mappers | 208 mapper families, expansion audio, the UNIF loader |
rustynes-core | The bus, scheduler, console and save states |
rustynes-frontend | The winit + wgpu + cpal + egui application (rustynes) |
rustynes-netplay | Rollback netcode over UDP and WebRTC |
rustynes-script | Sandboxed Lua 5.4 |
rustynes-cheevos, rustynes-ra | RetroAchievements |
rustynes-hdpack, rustynes-gfx-shaders | HD packs and the shared WGSL shaders |
rustynes-mobile, rustynes-android, rustynes-ios | The mobile bridge and platform glue |
rustynes-libretro | The RetroArch core |
rustynes-mcp | A Model Context Protocol server over the headless core (rustynes-mcp) |
rustynes-test-harness | Integration tests and the accuracy oracles |
| User guide | Installing, controls, save states, the debugger, configuration, FAQ |
| Documentation handbook | The subsystem specs and user guide as a website |
| API documentation | Rustdoc for the whole workspace |
| Status | Current state: per-suite results, the mapper matrix, feature flags |
| Changelog | Every release, newest first |
| Hardware specs | CPU, PPU, APU, mappers, testing, netplay |
| Decisions | Architecture Decision Records |
| Libretro core |
RustyNES's current release is v3.5.0 "Chorus" (2026-10-22) — creator tools: movies record every input the core takes (.rnm format 7), Lua gains WebSockets and real shared memory, an MCP server, speedrun auto-timing and dump checks arrive, the MMC5 scanline IRQ is fixed (epoch 6), and the MiSTer core adds the MMC5, VRC6, Namco 163, VRC7 (silent) and Bandai FCG boards, off the die only. Built on v3.4.2 "Countersign" (2026-10-20) — the RetroArch core loads on Apple Silicon Macs again. Built on v3.4.1 "Beacon" (2026-10-19) — the hosted netplay lobby live with the browser and mobile builds pointing at it (the TURN relay deployed but held off: Cloudflare kept honouring expired and revoked credentials), the browser RetroAchievements build fixed (web RA held until RetroAchievements answers the integration request), version-named MiSTer release assets, and the MiSTer save engine's cartridge-change defects and v3.4.0's two build findings fixed. Built on v3.4.0 "Waypoint" (2026-10-18) — netplay authenticated and three and four players on the desktop, RetroAchievements hardcore held to RA's full block list, the hosted services shipped as code (deployed in v3.4.1), the window thread's CPU halved, and the MiSTer core's headline build made the off-die one, with save states, rewind and Phase F3a's boards. Built on v3.3.0 "Plumbline" (2026-10-16) — v3.2.0's leftovers settled and its claims re-measured: CHR-RAM writes go through the bank registers on seven boards, mapper 71 decodes its bank select as documented, v3.1.x Bandai states load again, a v3.2.0 performance figure is withdrawn, the IRQ trace goldens became a test, and, in simulation, the MiSTer core's off-die build reads CHR-RAM back and loads CHR correctly. Built on v3.2.0 "Confluence" (2026-10-15) — every v3.2.0 branch in both repositories brought into one release: 17 mapper families (208 in all), the VRC4 IRQ fix, an AI remediation branch audited change by change, netplay protocol 8, slim libretro states, and sixteen more boards on the MiSTer core. Built on v3.1.0 "Bellwether" (2026-10-08) — the AccuracyCoin re-sync and an honest 146/146, the CPU overclock and the sprite-limit option in movies and netplay, PAL emphasis, the alternate MMC3, rewind and run-ahead on the Vs. cabinet, and the MiSTer core matched to all of it. Built on v3.0.1 "Mortar" (2026-10-07) — a maintenance release: one game's graphics fixed, the MiSTer core's last MMC3 rule exception tested, Rust 1.99 everywhere, every unanswered bot review answered, and the plan to v4.0.0. Built on v3.0.0 "Cornerstone" (2026-10-06) — the API major: every break since v2.x in one place, a core timing epoch for movies and netplay, the last MMC3 timing gap closed in both cores, and a release-candidate MiSTer core. Built on v2.9.9 "Ballast" (2026-10-04) — the release candidate for v3.0.0: the audits re-run, MMC3 and MMC5 by their documentation, audio exact across save states, and the MiSTer core moved onto it. Built on (2026-10-02) — the preparation release for v3.0.0: v3.0.0's breaking changes landed early (a save identity that ignores the header, old states and movies refused, movies and netplay that record the machine, the API removals), every staged game was booted and the defects found were fixed, and the game database's corrections reach every platform. Built on (2026-09-30) — the desktop's features on the web and on phones, the release binaries built with every native feature, and a PPU A12 fix found by real games: Acclaim's MC-ACC games, the J.Y. ASIC and mapper 91 now count at their documented rates. Built on (2026-09-30) — seventeen mapper families written from their NESdev pages (174 → 191), GTROM promoted to Curated with a modelled flash chip whose saves persist, mapper 4's NES 2.0 submappers corrected (MMC6, NEC, MC-ACC, T9552), and the local commercial suites re-baselined after drifting unread since about v2.0.0.
v3.0.0 is the API major (ADR 0043).
It gathers every breaking change since v2.x, most of them made early in v2.9.8 and
v2.9.9, and adds the last: movies and netplay carry an emulation epoch
(ADR 0045), and
four more public structs became #[non_exhaustive]. Its
release notes restate every break by audience.
The per-release detail, back to v0.1.0, is in CHANGELOG.md and
on the Releases page.
v3.0.0 has shipped: the API major with a release-candidate MiSTer core
(ADR 0043).
Next is v3.x, hardware verification: the MiSTer core on a SuperStation One,
the mobile apps on real devices, and the fixes each produces
(v3.x-hardware-verification-plan.md).
A change that alters what the emulator produces raises the emulation epoch, so
v3.x releases that emulate identically still share movies and netplay.
The full plan is to-dos/ROADMAP.md, with one plan per
release in to-dos/plans/. A free mobile store listing
may follow later, with no monetization of any kind.
A sibling project writes a new NES core in SystemVerilog for the MiSTer FPGA
platform, from public hardware documentation, and uses this emulator as its
verification oracle through crates/rustynes-cosim. RustyNES itself is not being
ported to an FPGA: what can be built is a new implementation checked against this
one, cycle by cycle.
Its co-simulation ladder covers the 6502, the bus and interrupts, the 2C02, the
2A03, AccuracyCoin parity and twenty-one iNES mappers. Each release attaches a
timing-closed bitstream pair; v3.3.0's (on-die and off-die, both at fitter seed 7,
each compiled twice to the same bytes) is a release candidate, not
hardware-verified. Its co-simulation ladder reads 260 passed, 0 failed, 3
expected failures on-die and 263 / 0 / 3 off-die. No hardware has run any
bitstream yet, so a booting core, a synced display, audible sound and a working
pad are not claimed. The details, and what
each rung can and cannot verify, are in docs/mister.md.
Contributions of every kind are welcome. CONTRIBUTING.md
explains the quality gates, the Conventional Commit format, and the rule that a
change to chip behaviour updates its docs/<subsystem>.md in the same pull request.
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
Questions are welcome in GitHub Discussions.
RustyNES is licensed GPL-3.0-or-later.
It is a derivative work of GPL-licensed NES emulators: it incorporates code
derived from Mesen2 (GPL-3.0-or-later) and, for a few subsystems, from
puNES, FCEUX and Nestopia UE (GPL-2.0-or-later). An earlier version
described that code as "oracle cross-checks" and licensed it MIT/Apache-2.0,
which was wrong; after a NESdev community review the project was relicensed and
every derivation credited in
docs/originality-and-provenance.md and
NOTICE (ADR 0036).
How that happened, and the rules that keep it from recurring, are public:
docs/provenance-failure-postmortem.md
and docs/ai-emulator-provenance-guardrails.md.
Reference emulators are black-box oracles: their output may be compared, and their
source is never read.
Permissive components (emu2413, TriCNES, rcheevos, blip_buf and the bundled
fonts) are credited in NOTICE. The test ROMs under tests/roms/ are CC0, MIT or
zlib. No commercial ROMs are included: dumps for the commercial-ROM oracle must
come from cartridges you own.
rcheevos.Full attribution is in NOTICE.
@software{rustynes2026,
author = {RustyNES Contributors},
title = {RustyNES: A Cycle-Accurate NES Emulator in Rust},
year = {2026},
url = {https://github.com/doublegate/RustyNES},
note = {Cycle-accurate NES emulator; AccuracyCoin 146/146, nestest 0-diff}
}
| Linux, macOS and Windows binaries, a WebAssembly build, Android and iOS apps, and a libretro core for RetroArch |
| The RetroArch core and how to set it up |
| Accuracy ledger | Every known approximation, with its evidence |
| Privacy policy | What the optional online services (netplay lobby, TURN relay, browser RetroAchievements proxy) receive and keep; also on the web |