CLI tool
mvdnes/rboy avatar
mvdnes/rboy

rboy is a Gameboy Color emulator whose GUI sits behind a feature flag

A Gameboy Emulator in Rust

666 stars55 forksRustMIT

At a glance

What is it?
The mvdnes/rboy project is a Rust Gameboy and Gameboy Color emulator that keeps its window, audio and command line parsing behind a single cargo feature called gui. It implements the CPU, GPU, timers, memory mapping and several cartridge mappers, and it is useful as a reference as much as a playable emulator.
Who is it for?
Adopt rboy if you want a small Rust codebase to read for how a Gameboy is emulated, or you want to play your own dumps and want the mapper and printer support the README lists. Do not adopt it as a commercial emulator project or as a complete implementation, since the README does not claim complete cycle accuracy and the test mode for GBEmulatorShootout is still under development.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 89 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One cargo feature gates the whole user interface

The Cargo.toml is short and the design decision is visible in the first ten lines of it. The package is rboy at version 0.2.0, edition 2018, and its dependencies are blip_buf 0.2 for the audio channel, serde with the derive feature, serde_arrays, typetag and ciborium for serialization, and then four optional dependencies: clap 4 for argument parsing, cpal 0.16 for audio output, glium 0.34 for graphics and winit 0.29 for windowing. The features section defines gui = [ "clap", "cpal", "glium", "winit" ], so enabling one flag pulls in the entire presentation stack. That matters because the binary target is declared with required-features = [ "gui" ], which means cargo will not produce an rboy executable at all unless that feature is on. A dependency graph that splits cleanly into emulation core and interface layer is unusual in small emulator projects, and it is the reason the source can be read without wading through windowing code.

Building requires the gui feature, running does not need a Makefile

The README describes two build paths and one run path. You can clone the repository and build it with either the make command or cargo build --release --features=gui.

bash
release:
	$(CARGO) build --release --features=gui

Running it is done either with cargo run --release --features=gui, or by running the generated binary found in target/release. The README also notes that you can copy the executable named rboy, or rboy.exe on Windows, into a directory on your PATH such as ~/.local/bin/ on Linux. The Makefile offers the same two builds under different names: a release target that runs cargo build --release --features=gui, and a debug target without the release flag. The Makefile also handles a detail you would otherwise hit yourself, since it declares ROMS from a wildcard over roms/*.gb.gz and gunzips each one with a pattern rule before running cargo test, and the clean target removes both the cargo build output and the decompressed ROM files.

The command line surface is small and mostly about edge cases

The help output shows a single positional argument, the ROM file, and a short set of flags. One of them is the serial port dump, one emulates the Gameboy printer, one forces classic Gameboy mode instead of Color, one sets the interface scale with a default of 2, one enables audio, one skips verification of the cartridge checksum, and one starts a special test mode. The README then tells you to explore the emulator with rboy --help.

text
A Gameboy Colour emulator written in Rust

Options:
  -s, --serial         Prints the data from the serial port to stdout
  -p, --printer        Emulates a gameboy printer
  -c, --classic        Forces the emulator to run in classic Gameboy mode
  -x, --scale <scale>  Sets the scale of the interface. Default: 2
  -a, --audio          Enables audio
      --skip-checksum  Skips verification of the cartridge checksum
      --test-mode      Starts the emulator in a special test mode
  -h, --help           Print help
  -V, --version        Print version

The two flags worth understanding are --skip-checksum, which exists because a real cartridge has a header checksum and some dumps fail it, and --classic, which forces the original monochrome behaviour even on a Color unit. Everything else is presentation.

Keybindings cover gameplay and the interface separately

The README splits the key map into two tables, and the split is informative. Gameplay bindings are minimal and deliberately conventional: Z is the A button, X is the B button, the arrow keys are the d-pad, Space is Select and Return or Enter is Start. Interface bindings are where the emulator specific controls live. The number 1 switches to 1:1 scale, R restores the scale given on the command line, holding Left Shift puts the emulator into unrestricted speed mode, and T changes the pixel interpolation. That last group tells you something about the intended use. A program that emulates a Gameboy faithfully has a frame rate to hit, so the unrestricted speed mode is a debugging affordance, and scale and interpolation controls are there because the author wanted to look at the output on a modern display rather than on the original hardware. The unrestricted speed mode in particular is the kind of feature that suggests the emulator doubles as a development environment.

The implemented list is a claim about subsystems, not about accuracy

The README keeps a list of what is done, and it is worth reading precisely rather than generously. The CPU entry says all instructions correct and all timings correct, and mentions double speed mode. The GPU has normal mode and color mode. Then there is a shorter list of subsystems: keypad, timer, audio, MMU and printing. Under the MMU the mappers are enumerated: MBC-less, MBC1, MBC3 with RTC, and MBC5, plus save games. Printing is listed as implemented separately, which lines up with the --printer flag in the help output. What the list does not say is as informative as what it says. There is no claim of cycle accuracy, no mention of a sound channel implementation beyond the word audio, and no entry for a timer accuracy statement. A reader deciding whether this satisfies them has to work from that silence rather than from a promise.

Test mode targets GBEmulatorShootout and is still unfinished

One feature is explicitly labelled unfinished. The test mode, activated with the --test-mode flag, provides some functionality for running GBEmulatorShootout, a test suite for Gameboy emulators, and the README states plainly that this is still under development. That is the honest framing of the project's testing story. There is no unit test suite for the CPU in the repository listing, and the Makefile test target depends on gunzipping ROM files out of a roms/ directory before running cargo test, which suggests the tests are about the harness and the serialization round trip rather than about emulated hardware behaviour. If you want confidence that a given ROM runs correctly, the emulator reference test suite is the tool for that, and this project only partially plugs into it.

A different approach is a tested emulator with a scripting layer

The practical alternative to rboy is not another Rust emulator but a mature emulator with automated testing built in, or a headless reimplementation of the same hardware used as a test oracle. The difference in approach is where the effort goes. A project like rboy spends its complexity in the emulation core, which is why the source reads the way it does and why the feature list is about instructions, timings, modes and mappers. A scriptable emulator with save states, a debugger and a test harness spends its complexity in tooling, which is what you want if your goal is running a ROM library or verifying a game you own. rboy also gives you something the alternative does not: a codebase small enough to read end to end in Rust, which is why it appears in the acknowledgements of emulator documentation alongside the JavaScript CPU write-up at imrannazar.com, the BGB pandocs, the Rust branch of alexcrichton's jba, and the pandocs at gbdev.io.

Editorial conclusion

Adopt rboy if you want a small Rust codebase to read for how a Gameboy is emulated, or you want to play your own dumps and want the mapper and printer support the README lists. Do not adopt it as a commercial emulator project or as a complete implementation, since the README does not claim complete cycle accuracy and the test mode for GBEmulatorShootout is still under development. Verify first by cloning the repository and building with the gui feature, checking that the rboy binary produced in target/release runs with a ROM you own, and note that the crate version is 0.2.0, the last push was on 2026-07-26, and the repository publishes no GitHub releases.

Frequently asked questions

How do I build rboy from source?

Clone the repository and build it with either the make command or cargo build --release --features=gui. The gui feature is required because the binary target declares required-features = [ "gui" ], so cargo produces no executable without it.

Which cartridge mappers does rboy support?

The README lists MBC-less, MBC1, MBC3 with RTC and MBC5 under the MMU, together with save games. The implementation list also covers printing and a serial port, which correspond to the --printer and --serial flags in the help output.

How do I enable audio and change the interface scale in rboy?

Pass --audio to enable audio and --scale with a value to set the scale of the interface, where the default is 2. The number 1 key switches to 1:1 scale at runtime, R restores the scale given on the command line, and T changes the pixel interpolation.

What is the test mode in rboy for?

The test mode, activated with the --test-mode flag, provides some functionality for running GBEmulatorShootout. The README states that this is still under development.

How do I run a ROM in rboy?

Pass the ROM file as the single positional argument, for example rboy followed by the path to a .gb file. The --skip-checksum flag skips verification of the cartridge checksum if a dump fails it.

What licence is rboy released under?

The project is licensed under MIT, with the LICENSE file at the top level of the repository alongside Cargo.toml, Cargo.lock, the Makefile and the src/ directory.

Official sources

  1. Issues
  2. License: MIT
  3. mvdnes/rboy on GitHub
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/mvdnes-rboy.svg)](https://hysenlabs.com/projects/mvdnes-rboy)

Was this useful?