A headless GameBoy/GameBoy Color emulator written in Rust, designed for AI agents and automated testing. Targets both native (library) and WASM environments.
Test-First Development: This emulator is built with comprehensive testing infrastructure from day one, enabling rapid iteration and validation against known-good test ROMs.
Headless & Agent-Friendly: No GUI, no audio output. Just a programmatic API that provides:
- Frame buffer access (160×144 RGB pixels)
- Button input control
- Battery-backed RAM persistence (save games)
- Screenshot export for vision models
gb-core/- Core emulator library (CPU, GPU, MMU, etc.)gb-test-harness/- Testing infrastructure for ROM validationtest_roms/- Downloaded test ROMs (gitignored)scripts/- Automation scripts for ROM downloads and testing
make setup
# or manually:
./scripts/download_test_roms.sh# Run all passing tests
cargo test
# Run tests that are still failing (implementation in progress)
cargo test -- --ignored
# Run specific test suite
cargo test --test blargg_cpu_instrscargo build --target wasm32-unknown-unknown --release --package gb-coreSave game data is preserved across sessions using battery-backed RAM emulation. Supports:
- MBC1 + RAM + Battery - Early cartridges
- MBC3 + RAM + Battery - Mid-era cartridges with optional RTC
- MBC5 + RAM + Battery - Later cartridges
Usage:
// Native Rust
let mut gb = GameBoy::new();
gb.load_rom(&rom_bytes)?;
if gb.has_battery() {
// Save to file
if let Some(ram_data) = gb.save_battery_ram() {
std::fs::write("game.sav", ram_data)?;
}
// Load from file
let save_data = std::fs::read("game.sav")?;
gb.load_battery_ram(&save_data);
}// WASM / Browser
const gb = new WasmGameBoy();
await gb.load_rom(romBytes);
if (gb.has_battery()) {
// Save to LocalStorage
const ramData = gb.save_battery_ram();
localStorage.setItem('save', btoa(String.fromCharCode(...ramData)));
// Load from LocalStorage
const saved = localStorage.getItem('save');
const bytes = Uint8Array.from(atob(saved), c => c.charCodeAt(0));
gb.load_battery_ram(bytes);
}See docs/BATTERY_RAM.md for detailed documentation.
Examples:
examples/battery_ram_demo.rs- Native file I/O exampleexamples/battery_ram_example.html- Browser LocalStorage example
- Run tests to see current failures
- Implement CPU/GPU features to pass tests
- Re-run tests to validate
- Refactor with confidence
This project uses industry-standard test ROMs:
- Blargg's Test ROMs - CPU instruction accuracy
- Mooneye GB - Timing and hardware behavior
- dmg-acid2 - PPU rendering accuracy
All test ROMs are automatically downloaded via make setup.
- Native: >1000 FPS (headless, for RL training)
- WASM: ~60 FPS (real-time for web agents)
- Memory: <10MB heap usage
- Binary size (WASM): <500KB (after wasm-opt)
MIT OR Apache-2.0