YAGB is a GameBoy / GameBoy Color emulator that runs in your browser. It started as a fun project at a company hackathon and evolved into a full-fledged emulator in about one month. It is written in TypeScript, and you can either run the build on github.io or build and run it from scratch.
In its current form YAGB gives you a CLI-like interface that allows you to load, run and debug ROM images. The most important commands are
load
: Load a ROM image (.gb, .gbc
)run
: Run or resume the current ROMstop
: Pause the current ROMreset
: Reset the current ROMhelp
: Show available commands and keybindings
The emulator is controlled with the following key bindings:
- Enter: Start
- Space: Select
- a/y/z: B
- s/x: A
- Arrow Keys: Joypad
- Shift-Enter: Pause / Resume
- Shift-Space: Reset
- +/-: Volume up / down
- Page up / down: Change emulation speed
IMPORTANT: You need to click the canvas (screen image) to give it focus in order for the key bindings to work!
The emulator stores the last ROM in IndexedDB and loads it automatically on load. In
addition, the current state is saved automatically every second and restored when the
page loads, so you can continue the current ROM where you left off. Additional
snapshots can be saved and loaded at any later point, check help
for details.
Games with battery buffered RAM have their RAM persisted, so you can load up save games and continue playing the next time you start the corresponding ROM.
The interface is not yet suitable to run the emulator on mobile phones (as there is no way to control it), but we plan to add a more full-fleged web app with touch support eventually.
YAGB can emulate both the classic GameBoy (DMG) and the GameBoy Color (CGB).
By default, games that support or require a CGB are run in CGB mode, and games
withough CGB support are run on a DMG. This behavior can be switched by setting
prefer-model
to either
auto
: the defaultcgb
: run all games in CGB modedmg
: run all games that do not require a CGB in DMG mode
DMG games running on a CGB will be colored with the respective compatibility palettes.
YAGB does not emulate the boot ROM, so palette selection cannot be done during
boot. Instead, pallettes can be swtiched with the palette
CLI command, or by
holding shift while performing the corresponding d-pad - A/B combos. Contrary to
a real GameBoy Color, palettes can be switched at any point while the game is running.
YAGB was designed to be suitable for usage on smartphones without excessive battery drain, so it has been built with performance in mind. On my M1 Macbook Chrome and Safari can run most games at about 20x their original speed, which amounts to about 1200 FPS. Firefox runs slower but still reaches between 5x and 10x native speed. My iPhone 7 reaches about 4x native speed.
As a tradeoff for performance, YAGB does not try to be a fully cycle exact emulator. Instead, its components try to batch and process as many cycles as possible in one step, and the PPU is not emulating the pixel fetchers, but uses a simpler line-based renderer instead. Within these constraints, the emulator tries to be as accurate as possible.
Audio is not strictly cycle exact either, but instead synchronizes at a rate that corresponds to the host sample rate. Almost all games sound fine (including those that abuse the hardware to play PCM samples), but there is no sophisticated resampling, so high pitched sounds may exhibit slight ringing due to aliasing artifacts.
That said, YAGB passes the CPU tests in the Blargg suite, displays mattcurrie's ACID2 test correctly and passes parts of the Mooneye suite. Almost all games that we tried run flawlessly, including notrious oddballs like the Addams Family, Hook and Road Rash though.
Simple. Make sure that you have yarn installed, then do
$ yarn install
to install the dependencies and
$ yarn start:cli
or
$ yarn build:cli
to start the development server (on port 9000) or do a release build. The build
will end up in yagb-cli/dist
.
The following resources were used to create YAGB
- The Pan Docs
- Marc Rawer's Gameboy Hardware Manual
- Pastraisers opcode table
- The gbdev wiki and nightshade256's excellent breakdown of the APU documentation
- Martin Korth's notes on the stat interrupt
- Ocassional glances on the excellent Sameboy source for clarifying edge cases with conflicting or missing information
- Random flotsam and jetsam on Reddit and StackOverflow
Parts of YAGB were developed during slacktime provided by the awesome folks at Mayflower GmbH.