Skip to content

AtlasRedux/LearnfunPlayfunGameBoy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LearnfunPlayfun for Game Boy

An AI that learns to play Game Boy / Game Boy Color games by watching human gameplay, then plays autonomously using brute-force search over discovered objective functions.

Ported from LearnfunPlayfunAtari2600 to the Game Boy via the gambatte-libretro core — a TAS-grade, deterministic Game Boy emulator.

Based on Tom Murphy VII's original learnfun & playfun — the paper is a great read if you want to understand the theory.

How it works

  1. Record a human playing a Game Boy game (recordfun)
  2. Learn objective functions from the recording by finding lexicographic orderings on RAM bytes that correlate with "progress" (learnfun)
  3. Play the game autonomously by searching over possible input sequences and scoring them against the learned objectives (playfun)
  4. Replay the AI's best run visually with sound (replayfun)

The approach is entirely game-agnostic — it knows nothing about any specific game. It discovers what "progress" means by observing which RAM values tend to increase when a human plays well.

Tools

Executable Purpose
recordfun Play the game with keyboard and save inputs as .gbinp
learnfun Analyze a recording to discover objective functions
playfun AI plays the game using learned objectives (master/helper distributed search)
replayfun Watch a .gbinp replay with video and audio
scopefun Visualize RAM activity during a replay
pinviz Visualize input pin activity
tasbot_gui.pyw Python/tkinter GUI for the full workflow

Building

Prerequisites

  • Visual Studio 2022 (MSVC v143 toolset)
  • CMake 3.20+
  • vcpkg (with VCPKG_ROOT environment variable set, or installed at C:\vcpkg)
  • SDL2 (via vcpkg: vcpkg install sdl2:x64-windows)
  • Other deps installed automatically via vcpkg: protobuf, zlib, libpng, lz4

Clone with gambatte-libretro

git clone https://github.com/AtlasRedux/LearnfunPlayfunGameBoy.git
cd LearnfunPlayfunGameBoy
git submodule update --init --recursive

Build

cd tasbot
cmake --preset default
cmake --build --preset release

Or use the included build.bat from the project root.

Binaries are output to tasbot/build/Release/.

Usage

The fastest way is the included GUI:

cd tasbot\build\Release
pythonw tasbot_gui.pyw

Drop a .gb or .gbc file into that folder (or use the Browse… button), then click through the four buttons in order:

  1. 🎮 Record (play game) — opens an SDL window; play the game with the keyboard, ESC saves the input log as <game>.gbinp.
  2. ▶ Pretrain (learnfun) — analyses the recording and writes <game>.objectives and <game>.motifs.
  3. ▶ Run (playfun) — spawns one helper process per CPU core (configurable) plus a master. The AI plays the game and saves its best run so far to <game>-playfun-futures-progress.gbinp periodically. The Resume checkbox continues from an existing progress file.
  4. 🎬 Watch Replay — opens replayfun.exe on the latest progress file, with audio and per-frame controls.

The GUI auto-detects ROMs and input logs in its directory, manages the helper/master lifecycle, and streams the master's coloured progress bars to its log pane.

Keyboard controls in recordfun:

  • Arrow keys: D-pad
  • Z: A button
  • X: B button
  • Enter: Start
  • Right Shift (or Tab): Select
  • ESC: quit and save

Manual command-line workflow

If you'd rather skip the GUI, all tools read a config.txt file in the working directory:

game mario
rom mario.gb
movie mario.gbinp

game is the base name (used for output filenames). rom is optional — if omitted, the tools look for <game>.gb, then <game>.gbc.

recordfun.exe       # Step 1 — record human play, writes <game>.gbinp
learnfun.exe        # Step 2 — write <game>.objectives and <game>.motifs

# Step 3 — start one helper per core, then the master:
playfun.exe --helper 29000
playfun.exe --helper 29001
playfun.exe --master 29000 29001 ...

replayfun.exe       # Step 4 — watch the latest progress file

replayfun.exe controls: Space (pause), Right (step), Up/Down (speed), R (restart), M (mute), ESC (quit).

Architecture

  • Emulator wrapper (emulator.cc): Abstracts the gambatte libretro core behind a clean C++ API — initialize, step, save/load state, read RAM, get video/audio.
  • Objective discovery (objective.cc, weighted-objectives.cc): Finds lexicographic orderings on RAM that correlate with human gameplay progress. Works on arbitrary byte arrays — fully generic.
  • MARIONET protocol (marionet.proto, netutil.cc): Protobuf-based TCP protocol for distributed master/helper search. Sends opaque byte blobs (emulator states, input sequences).
  • Input format (.gbinp): Simple text format — one line per frame, 8 characters RLDUTSBA where . means not pressed. Human-readable and diffable.

Game Boy vs Atari 2600

Atari 2600 (previous port) Game Boy (this port)
Emulator stella2023 (libretro) gambatte (libretro)
Resolution 160 × 210 (variable) 160 × 144
RAM exposed 128 bytes 8 KB (DMG) / 32 KB (CGB)
Inputs 5 (UDLRF) + 2 console 8 (RLDUTSBA)
State size ~1.2 KB varies (~10–60 KB depending on cart)
Input format .a26inp .gbinp
Refresh rate ~60 Hz NTSC ~59.7 Hz

The larger RAM gives learnfun more candidates to find meaningful progress signals — most Game Boy games keep position, score, lives, and timers in WRAM where the algorithm can latch onto them.

Credits

  • Tom Murphy VII — original learnfun/playfun concept, NES implementation, and the brilliant paper
  • AtlasRedux — NES revival, Atari 2600 port, and Game Boy port
  • gambatte — accuracy-focused Game Boy / Game Boy Color emulator by Sindre Aamås and contributors
  • cc-lib — Tom Murphy VII's utility library

License

Same terms as the original learnfun/playfun. Gambatte is GPL v2 — see gambatte-libretro/COPYING. See individual source files for details.

About

Conversion of Learnfun/Playfun to support Nintendo Game Boy

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors