Linux, cloud and container environments
GameFrame runs on macOS and Linux, on a desktop or headless. This page lists what an agent needs to set up a Linux machine, a container or a cloud agent's workspace, and what to check before work starts.
Ask your agent
Set up a Linux environment. Copy this prompt into your coding agent:
Set up GameFrame in this Linux environment.
1. Clone https://github.com/tanepiper/game-frame (or update it) and read
docs/working/environments.md and the re-setup skill.
2. Run scripts/setup.sh and show me the table. Tell me what is missing and how large each
part is. Wait for my answer before installing anything.
3. Install what I agree to. Verify Ghidra's download against the SHA-256 on its release page.
4. If DOSBox-X is older than 2026.10, tell me, and build a current one with the debugger
only if I agree.
5. Run tests/run.sh --ghidra and report the count. Fix the setup until every check passes or
is skipped for a reason I accept.
6. Write a short report: the versions installed, the test result, and anything left to do.
Keep logs outside the repository.
Never put game files, extracted assets or decompiled code inside a git checkout.What the toolkit needs
| Tool | Version that works | Needed for |
|---|---|---|
| Python | 3.10 to 3.13, with .venv from requirements.txt (Unicorn 2.1, pefile, Capstone 5) | every tool |
| JDK | 21, the full JDK (with javac) | Ghidra |
| Ghidra | 11 or 12 (12.1.4 tested) | decompiling |
| objdump | GNU binutils or LLVM | reading instructions exactly |
| Node.js | 18 or later (24 tested) | VitePress and other Node tools |
| Node.js for REA | 22.23.4+, 24.22.1+, or 26.12.1+ | optional REA MCP provider |
| Zig | 0.14 | building the sample game in the tests |
| DOSBox-X | 2026.10 or later, with the heavy debugger | DOS games, the debugger tests |
| innoextract, 7-Zip | any recent | unpacking installers |
| REA | 6.7.0 | optional MCP server for agents; enable with ./gameframe mcp --enable rea |
scripts/setup.sh checks each one and prints a table. External MCP servers are off by default. Use ./gameframe mcp --list and ./gameframe mcp --enable NAME to add one to a project. --install installs with apt on Debian and Ubuntu. Ghidra is not in apt: download the release zip, check its SHA-256 against the release page, unzip it and set GHIDRA_INSTALL_DIR.
Steps on a Debian or Ubuntu machine
- Install the system packages:
python3-venv,openjdk-21-jdk,binutils,nodejs,innoextractandp7zip-full(or letscripts/setup.sh --installdo it). - Install Ghidra from its release zip, as above.
- Run
scripts/setup.sh --installto make.venvand write.envwith the tool paths. - Check the DOSBox-X row. Distribution packages are often older than 2026.10. Build a current one with the debugger as the re-setup skill describes, or leave DOS games out.
- Run
tests/run.sh --ghidra. Every check should pass, or skip with a reason.
Each session
Agents often start a new shell for each command. Source scripts/env.sh at the start of each one:
source ~/code/game-frame/scripts/env.shIt sets GAMEFRAME_ROOT and GAMEFRAME_HOME, loads the home's config.env and then .env, exports GHIDRA_INSTALL_DIR and JAVA_HOME, and puts gameframe and the .venv Python first on PATH. The scripts load .env themselves, so this matters for commands typed by hand and for agents.
The GameFrame home
GameFrame keeps one folder per machine outside every clone: ~/gameframe, or the folder in GAMEFRAME_HOME. ./gameframe home init makes it, and ./gameframe home doctor checks it.
| Folder | What |
|---|---|
config.env | Settings for every project: GAMEFRAME_ROOT, GHIDRA_INSTALL_DIR, JAVA_HOME, DOSBOX_X_BINARY, the LLM endpoints |
python/ | The shared Python environment for the toolkit |
tools/, emulators/, drivers/ | Programs, ROM sets and period drivers that every game shares |
machines/ | Virtual machines, one folder each. machines/os/ holds the operating system images |
games/ID/ | One game's files: media/ (the discs as they came), game/ (extracted or installed), saves/, analysis/, derived/, and game.json with each image's SHA-256 |
projects/ID/ | The game's git repository |
worktrees/ | GameFrame worktrees made by hand |
cache/ | Downloads and scratch files. Safe to delete |
data/ | What tools keep between runs |
Settings are read in this order: the home's config.env, then the project's .env. The later one wins, so a project's .env holds only what differs. Both replace a value inherited from the environment.
A project's game, media, saves, analysis and derived are links into games/ID/, and its .gitignore names them. ./gameframe game link ID . makes them, in a git worktree too. ./gameframe game add ID FILE adds a disc image or installer and extracts it into game/. An older project with real target/, game-data/, save-game/ or truth/ folders moves them with ./gameframe home adopt PROJECT --id ID. It leaves a link at each old name, so paths in the project's code and documents keep working, and it keeps any folder git tracks files in.
One GameFrame checkout
Keep one checkout of GameFrame on a machine: the clone of https://github.com/tanepiper/game-frame that you change, test and push. Every game project uses it. A project made by scripts/new-project.sh finds it through GAMEFRAME_ROOT in the home's config.env, or in its own .env (git-ignored):
GAMEFRAME_ROOT=~/code/game-frameThe project's ./gameframe reads that line, from the project and from its main checkout, so the project's git worktrees use the same checkout. Without the line it tries ~/code/game-frame, then ~/code/reverse-engineer-games, then the plugin's newest install. It never looks next to the project. It used to: projects side by side then shared whatever sat in ../game-frame, and one project ran a symlinked second clone that had fallen a day behind.
To change GameFrame from a game's session, work in a git worktree of that one checkout, test there, and merge into its main:
git -C "$(./gameframe root)" worktree add ~/gameframe/worktrees/NAME -b NAMEDo not make a second clone for a game. Its work and the main checkout drift apart, a project pinned to it runs old tools, and its lessons reach GitHub only when someone remembers to push them. ./gameframe root prints the checkout a project uses.
This rule is about where GameFrame lives. It does not limit what a game builds. Each game is different, and its own tools, crates, scripts and viewers belong in its own repository, next to GameFrame's. Pass back up only what would help any game: a tool fix, a format family, a pitfall, a know-how entry, each with a test against GameFrame's own samples.
One emulated PC per game
When a game runs in an emulated PC (tools/live/emupc.py), give each game its own: its own folder (derived/vm in the project, which git ignores), disk overlay, SSH key, port and name. The Debian cloud image underneath can be shared, because the VMs never write to it. emupc.py init names the VM after the project and refuses a port that another VM listens on. Never run one game in another game's VM: it ties the game to that project's machine, load and changes, and puts one game's files inside the other's.
No display
The tests and the tools need no display. dosbox-run.sh uses SDL's dummy video and audio drivers unless you pass --window. A DOSBox-X built without X11 or OpenGL support runs the tests. Ghidra runs headless.
REA in a cloud or container session
- MCP servers start with an agent session. After you register REA, start a new session to get its tools.
- REA's doctor may warn about a host it does not list, such as Debian 13. Test it on the sample game: open
examples/sample-game/build/game.exeand analyse a function. - Ghidra analysis can take minutes. Raise the client's tool timeout for REA.
Game material on someone else's machine
A cloud machine belongs to its provider. Before you put a game there, check that your licence and the provider's terms allow it.
- Keep the game's files, extracted assets, decompiled code and analysis output outside every git checkout.
scripts/new-project.sh DIR "Name"without a game path creates the project and copies no game files. Put the game's files in the project's ignoredgame/folder only where you are allowed to.- Each cloud task usually runs in its own copy, so a git worktree is rarely needed.
Keep the environment repeatable
- Save the versions you installed, and the output of
scripts/setup.shandtests/run.sh --ghidra, outside the repository. - Write a small refresh script for your environment that pulls GameFrame, reruns
scripts/setup.sh --installand registers REA again. - Report changes you had to make to GameFrame's own files upstream, so the next environment does not need them.
Back up a Codex Cloud environment
The persistent Codex Cloud environment for this repository has a local backup. Its settings are listed in docs/working/codex-cloud-environment-settings.md, its install script is in scripts/codex-cloud-environment-install.sh, and its start instructions are in docs/working/codex-cloud-start-skill.txt. The files were copied from the published game-frame environment on 2026-10-25.
Codex Cloud does not read these files automatically. When you change the environment's Install script or Start skill in Codex Settings, update the matching local file too. To restore the environment, paste the contents of each file into the corresponding setting. This backup is separate from generated files under .codex/.