Skip to content

RustyNES v2.9.8 — "Vanguard" (v3.0.0's breaks landed early, every staged game looked at, and the database's corrections on every platform)

Latest

Choose a tag to compare

@github-actions github-actions released this 03 Oct 14:57
d243130

RustyNES v2.9.8 — "Vanguard"

The preparation release for v3.0.0. It carries v3.0.0's planned breaking changes early, fixes the rendering defects found by booting every staged game, brings the game database's corrections to every platform, and adds menu options to the MiSTer core. Read the breaking changes before upgrading.

Breaking changes

v3.0.0's planned breaks landed here, so that v3.0.0 itself can be a tested milestone. v3.0.0's notes will list them again.

  • Older saves are not found for cartridge games. A game is now identified by the bytes after its header, so a corrected header never loses its saves again. Save states, battery .sav files, cheats and movies made with earlier versions are not picked up. FDS and NSF games are unchanged.
  • Save states from v2.9.7 and earlier are refused with a message saying so, and movies older than this release are refused with a message to re-record them.
  • A movie records the console it was made on. It records the console model, the chip revisions, the power-on state, the Four Score, the Vs. switches and the Game Genie codes. Playback uses them whatever your settings are, and puts your settings back afterwards. Raw RAM cheats are switched off while a movie records or plays, because a movie cannot carry them.
  • Netplay peers must match on these options, not only on the ROM. A mismatch is refused with the reason, so a session cannot silently drift apart.
  • For developers:
    • LockstepBus is renamed SystemBus.
    • The APIs deprecated since v2.7.5 are removed, and so is serialize_header.
    • Header and FrameInput are #[non_exhaustive].
    • Movies keep Four Score players 3 and 4.

Games that render correctly now

Every one of the 748 staged dumps was booted and its final frame looked at. The games that drew garbage or nothing led to these fixes:

  • The game database no longer overrides a correct NES 2.0 header. It was running ten games as the wrong board, among them Youkai Club, the Sachen Lightgun 2-in-1, Saint Seiya, the Magical Taruruuto-kun games and Don Doko Don 2.
  • PAL games in old-style headers run at PAL timing, using the database's region: Pin Bot (E) and Sidewinder.
  • Board fixes: Megami Tensei II (Namco 163), Skull & Crossbones (RAMBO-1), Magic Floor, the 76-in-1 multicart, Vs. Super Mario Bros. (work RAM), Nintendo World Championships 1990, Famicom Jump II's graphics, the mapper 191 translations, and Balloon Fight (J) translated to Russian (a header with junk bytes).
  • Vs. The Goonies draws in its own palette.
  • The Pulsewave demo shows its postcard: VRC6 CHR banks now power on in order. That value is a documented assumption.
  • 44 dumps for the newest mapper families are now pinned by a baseline and a screenshot each. Mislabelled dumps are recorded rather than forced.

On every platform

  • Android, iOS and the libretro core now apply the game database's header corrections, as the desktop and the web build always did.
  • Power Cycle keeps your settings. Before, it dropped OAM decay, a custom palette, the fast dot path and the audio filter until the next load.
  • A game's settings are applied before its first frame. On a game-to-game load, the emulator could run a frame first. A late power-on fill then rewrote RAM under the running game.
  • A movie that is refused leaves your game alone. One with an old start state, or a bad Game Genie code, used to change your machine's settings and RAM before it was refused.
  • Mapper corrections reach "DiskDude!" dumps. On a dump whose header has junk at the end, a game-database or header-editor correction to a mapper of 16 or more read back as the wrong mapper. It now sticks.
  • Netplay against an older version fails cleanly instead of leaving the older side waiting on a session that never starts.
  • Android netplay shows colour emphasis as everywhere else. It used its own copy of the old emphasis rule; it now uses the core's.

On iOS

  • The iOS app builds, launches and plays again. v2.9.7's Swift did not compile on a Mac. Once it did, it opened to a black screen, and it crashed at launch when built without the iCloud capability. All three are fixed (#578), and CI now compiles the app for every release.

On the desktop

  • A Famicom console model (Settings > Emulation > Accuracy), off by default. Its PPU leaves reset before the CPU, which the 999-in-1 multicart depends on.
  • Vs. DualSystem cabinets start as two consoles from the command line too, and Power Cycle resets the whole cabinet.
  • Toggling "Fast PPU dot path" mid-game no longer wipes work RAM.
  • Colour emphasis follows the documented NTSC hardware model, instead of a fixed dim per bit.

The MiSTer core

New menu options, compiled and timing-closed but not yet seen on hardware:

  • your two custom aspect ratios from MiSTer.ini;
  • integer scaling;
  • a 224-line vertical crop;
  • a choice of the FBX "Smooth" or the 2C03 RGB palette.

The core's colours now match the emulator's, entry for entry, and a new co-simulation gate checks this.

Both builds were re-swept on the new RTL, and fitter seed 2 stays pinned. On-die every seed closes. Off-die, three seeds fail, and seed 2 closes with 33 ps of setup margin, the thinnest this project has pinned.

The attached bitstreams were compiled on 2026-10-01 (build date 261001), at fitter seed 2, from hardware sources identical to the release commit. The build date is part of the design, so a compile on another day is a new placement. On release day the on-die build missed timing by 0.162 ns on the HDMI clock, so the 261001 pair ships instead, as v2.9.3 did. Two clean compiles of each were byte-identical:

  • on-die: md5 132ec5c00356a8502823d8fcee53f44f (timing +0.656 ns setup, +0.105 ns hold);
  • off-die: md5 995f82595902131f128e8f0e3d183f12 (+0.033 ns setup, +0.116 ns hold).

No hardware has run any bitstream.

Performance

  • Removing the dead /NMI edge detector made a frame 4.9% to 6.1% faster on three of the four benchmark workloads, and 1.4% faster on the fourth. Measured on its own, over two runs.
  • Three small hot-path changes were adopted from an 11-candidate re-measurement, together 1.8% to 4.3% faster. Their output is byte-identical, so the accuracy is unchanged.
  • Against v2.9.7 as a whole, the shipped nestest frame is about 5% to 9% faster in both runs. On the other workloads the end-to-end gain did not reproduce. Something else in this release appears to offset the two measured gains there, and it is being investigated for v2.9.9 rather than claimed.
  • Rejected after measurement, with the numbers recorded in docs/performance.md: a palette read-view cache and a struct-layout change.

Verification

  • The full suite, with the test ROMs and every local commercial suite, passes on the release tree: 3,367 tests, 0 failed, 19 ignored. AccuracyCoin is 144/144 and nestest is 0-diff.
  • Each fix has a test that failed before it, and reverting the fix makes that test fail again.
  • Every changed baseline was looked at and attributed to its cause.
  • Co-simulation: on-die 175 passed, 0 failed, 1 expected failure; off-die 176 / 0 / 1.

Install

  • Download the pre-built binaries for Linux, macOS, and Windows below.
  • The MiSTer core bitstreams are attached below. The on-die build is RustyNES_MiSTer-v2.9.8.rbf, also attached under its datecoded name RustyNES_20261001.rbf, and the off-die build is RustyNES_MiSTer-v2.9.8-offdie.rbf.
  • The WebAssembly build is live at doublegate.github.io/RustyNES.
  • Licensed under GPL-3.0-or-later.