Stack setup
Setting up GameBoyGhost is like building a server from a strict golden image. Every layer is pinned to a known version. Nothing gets upgraded casually, because the whole point is that a run today produces the same bytes as a run last month.
The hardware
Section titled “The hardware”One Apple Silicon desktop: Apple M3 Ultra class, 32 processor cores, 256 GB of memory. Plus an external drive for backups.
The machine is big, but the project does not lean on it. The default is just four game runs at a time. More are allowed only after checks show the results stay byte-for-byte identical.
The operating system
Section titled “The operating system”macOS on arm64, Apple’s chip architecture. The project’s setup notes record that Torch (a machine-learning library) can use the Mac’s graphics chip. Nothing in the pipeline requires it.
The pinned Python interpreter
Section titled “The pinned Python interpreter”All project code runs with exactly one Python interpreter: version 3.11.16. It lives in a virtual environment (venv), a private, self-contained Python install, inside the frozen repository. The rules for it are strict:
- Use only this interpreter. No other Python, ever.
- Never install packages into it.
- If something is missing, stop and report it.
- Run Python with
-B, which tells Python not to write cache files (.pyc). That keeps stray files out of the project folders.
Why pin it? For the same reason you pin a production server’s package versions. A different interpreter or library version could change behavior in tiny ways, and tiny changes break byte-for-byte reproducibility. Campaign job lists record the interpreter’s path, its version string and a fingerprint of the interpreter program itself. A run on a different interpreter cannot pass as the same run. The package versions themselves were adopted from upstream projects the code builds on.
notable packages in the pinned environment
From the environment’s installed-package metadata:
| Package | Version | Role |
|---|---|---|
| PyBoy | 2.0.0 | The Game Boy emulator |
| NumPy | 1.26.4 | Number arrays |
| PyArrow | 21.0.0 | Columnar data files |
| Torch | 2.2.2 | Machine-learning library |
| Stable-Baselines3 | 2.3.0 | Reinforcement-learning library from the older project |
| Gymnasium | 0.29.1 | Environment interface from the older project |
| pandas | 3.0.5 | Tables |
| Matplotlib | 3.11.1 | Plots |
The environment was created with uv, a Python package manager. It does not use any system-wide packages.
The emulator: PyBoy
Section titled “The emulator: PyBoy”PyBoy is an open-source Game Boy emulator written for Python. The project drives it only through button presses, one frame at a time. Every run loads the start point exactly once and then plays forward (rule R13).
You must supply your own legally obtained copy of the game. The project never distributes it, and this site never shows it.
The folder layout
Section titled “The folder layout”The editor and the AI agent
Section titled “The editor and the AI agent”Any code editor works. The project’s AI coding agent is Claude Code, which reads instructions from the repository:
AGENTS.mdis the standing rulebook. It covers the environment, git rules, pins, frozen files, game rules, test-case numbering, determinism, gates, STOP and repair rules, honesty, and report format.CLAUDE.mdis one line that importsAGENTS.md. Claude Code readsCLAUDE.mdautomatically. That one line means both names lead to the same rules..claude/settings.jsonholds deny rules that block certain commands and file edits. Shell and agent security explains what they are good for and where they fall short.
The backup drive
Section titled “The backup drive”An external drive receives a full copy of the repository after every commit, using rsync. It is the only second copy of the large files git ignores. Those files are all fingerprinted in committed lists, so the backup can be checked. An off-site copy is PLANNED.
Generic bootstrap, step by step
Section titled “Generic bootstrap, step by step”These steps follow the project’s own restore notes, written generically. They describe what to do; they are not a copy-paste script.
- Get the hardware ready. An Apple Silicon Mac with plenty of cores and memory, plus an external drive.
- Restore the frozen repository at its pinned commit, into a fresh folder.
- Add your private files from your own offline backup: your legally obtained game file, the start point, and any trained models. These never go into git.
- Fetch the reference code the older project depends on, at its pinned commit.
- Create a fresh Python 3.11.16 environment with uv and install the exact locked package list. Don’t reuse an old environment.
- Run the test suite and a full replay check. The project’s restore record shows 189 tests passing plus 1 protected skip, and an exact replay of the teacher’s reference run.
- Clone the main repository next to it, and confirm that
git statusis clean. - Set up the agent. Open your editor and Claude Code at the main repository’s root, so
CLAUDE.mdandAGENTS.mdload. - Set up the backup. Do one
rsyncto the external drive, and check that it completes.
Gameplay footage from The Legend of Zelda: Link’s Awakening DX, captured from the author’s own emulator runs for technical commentary. The game and its imagery are © Nintendo. This project is not affiliated with or endorsed by Nintendo. How the footage is made.