ccboy
Play Game Boy games in Minecraft with ComputerCraft: a Lua client streams frames from an external emulator to in-game monitors.
Play Game Boy in Minecraft with ComputerCraft. Lua client streams PyBoy frames from a Python WebSocket server and relays inputs; Docker-ready. See the README below for details.
README
On GitHubccboy
Play a Game Boy inside Minecraft using ComputerCraft. This project streams frames from a Python WebSocket server running a Game Boy emulator (PyBoy) to a ComputerCraft/CC:Tweaked client written in Lua. The client renders frames on a monitor and sends button presses back to the emulator.
Works either locally or via Docker for the server. The ComputerCraft client can be hosted on Pastebin for easy installation in‑game.
How It Works
- Server: Python app runs PyBoy on a ROM, converts each screen frame to an NFP palette, compresses it with zlib, and streams it over WebSocket.
- Entry:
main.py - WebSocket:
websocket_server.py(default0.0.0.0:8081in Docker) - Frame conversion:
screen_converter.py(palette inconfig.py:20) - Input handling:
button_handler.pyviaACTION_MAPinconfig.py:36
- Entry:
- Client:
gameboy.luaconnects viahttp.websocket, decompresses frames usingLibDeflate.lua, loads NFP viasurface.lua, draws to the main monitor, and sends touch‑based button events from a second “controller” monitor.
Prerequisites
- Server (if not using Docker):
- Python 3.9+
- Packages:
pyboy,websockets,numpy
- Docker (optional): Docker installed
- Minecraft side:
- ComputerCraft or CC:Tweaked with HTTP and WebSocket enabled in the mod config
- One computer with two attached monitors:
- Main screen: on the
topside - Controller screen: on
front,back,left, orright
- Main screen: on the
- Internet access from the CC computer to fetch Pastebin raws (or pre‑bundle the libs)
Quick Start (Docker)
- Prepare a ROM folder and copy your ROM file (example
pokemon.gbc):- Create and place under
roms/next to this repo
- Create and place under
- Build the image:
docker build -t ccboy .
- Run the server, mounting your ROMs and exposing the port:
docker run --rm -p 8081:8081 -e ROM_FILE=pokemon.gbc -v $(pwd)/roms:/app/roms ccboy
- Note the WebSocket endpoint for the client:
ws://:8081
Environment defaults are defined in config.py and the Dockerfile sets sane defaults for container use.
Run Locally (no Docker)
- Install dependencies in a venv:
python -m venv .venv && source .venv/bin/activatepip install pyboy websockets numpy
- Put your ROM in
roms/and set env vars as needed, then start:export ROM_FILE=pokemon.gbcexport ROM_PATH=$(pwd)/romsexport WEBSOCKET_HOST=0.0.0.0export WEBSOCKET_PORT=8081python main.py
On start you should see “WebSocket server started on …” in the console.
ComputerCraft Client
- Script:
gameboy.lua - Libraries auto‑downloaded by the client (Pastebin IDs embedded in the script):
LibDeflate.lua(zlib decompression):fN3HFQ9fsurface.lua(rendering):QiaQ2KBr
Two recommended ways to install the client on a CC computer:
- Pastebin one‑liner (host
gameboy.luayourself):- Upload the contents of
gameboy.luato Pastebin and note the ID, then on the CC computer run: pastebin get startup- Reboot the computer so it auto‑starts the client.
- Upload the contents of
- Manual copy (if you can paste directly):
- Create a file named
startupon the CC computer and paste the contents ofgameboy.lua.
- Create a file named
Before first run, edit the script endpoint if your server isn’t on the CC computer:
- Open
gameboy.lua:6and setbase_urlto your server, for example:local base_url = "ws://192.168.1.50:8081"
Attach monitors:
- Main display monitor on
topof the computer - Controller monitor on one of:
front,back,left,right
Start the CC computer. The client will:
- Connect to the WebSocket, receive compressed frames, and render to the main monitor.
- Draw a simple controller layout on the second monitor. Touching zones sends:
up,down,left,right,a,b,select,start.
Controls
- Touch the controller monitor zones to send inputs.
- The client lowercases inputs internally; mapping is defined in
config.py:36.
Configuration (Server)
Environment variables read in config.py:
ROM_FILE: ROM filename insideROM_PATH(defaultdefault.gbc)ROM_PATH: folder where ROMs are stored (default/app/roms)WEBSOCKET_HOST: bind host (Docker default0.0.0.0; local defaultlocalhost)WEBSOCKET_PORT: bind port (default8081)EMULATION_FPS: PyBoy tick rate (default60)SCREEN_UPDATE_RATE: frames pushed per second (default15)COMPRESSION_ENABLED: zlib compression toggle (always used by current server build)
Color palette and nearest‑color logic used for NFP conversion live in config.py:20 and screen_converter.py.
Notes and Tips
- The server uses PyBoy headless mode (
window="null") so no GUI is shown on the host. - The Game Boy screen is centered on the CC monitor. Large monitors improve readability.
- If the CC modpack blocks HTTP/WebSocket, enable them in the CC/CC:Tweaked config or whitelist Pastebin/raw URLs.
- If connection fails on CC, verify
base_urlpoints to the server and that port8081is reachable from Minecraft. - Dockerfile references
requirements.txt. If absent, create one with at least:pyboywebsocketsnumpy
Project Layout
main.py: Starts emulator + WebSocket serverwebsocket_server.py: Client handler and frame streamingemulator.py: PyBoy wrapper and button queuingscreen_converter.py: RGB frame to NFP charactersbutton_handler.py: Maps commands to emulator inputsconfig.py: All tunables and mappingsgameboy.lua: ComputerCraft clientlib/LibDeflate.lua,lib/surface.lua: Lua dependencies for the clientDockerfile: Container image for the server
License
- This repository is under the GNU AGPL v3 License (
LICENSE).
From the project's repository, fetched . Images load from GitHub.
Releases
FeedNo releases yet. Follow the project to hear when the first one comes out.
Works for me
Did it work on your PC? A quick report tells other players which versions are safe to try.
Discussion
No posts yet. Ask a question, share your setup or post a clip.
Sign in to post