2026-10-04 11:31:17 -07:00

Arcade Escape

An arcade-powered escape room framework built with Godot.

Arcade Escape brings seven classic arcade recreations together with room-design tools, configurable cabinet controls, scenario-driven hardware outputs, and a browser operator dashboard. Designers define the room and its scenarios; Raspberry Pi cabinets run the games; staff prepare and monitor sessions from a computer or tablet.

The Arcade Escape controller is separate from Odin and does not require its code or services.

Included games

Game Cabinet controls
Pac-Man Pac-Man Four-way joystick + Start
Galaga Galaga Horizontal movement + Fire + Start
Tempest Tempest Joystick, spinner, or trackball + Fire + Superzapper + Start
Missile Command Missile Command Trackball + three battery buttons + Start
Frogger Frogger Four-way joystick + Start
Space Invaders Space Invaders Horizontal movement + Fire + Start
Robotron Robotron 2084 Two eight-way joysticks, or one joystick + four directional fire buttons, plus Start

The games include attract/title screens, sound, and game-specific visual treatments. They are playable recreations under active development; arcade accuracy and individual mechanics continue to be refined.

Start here

How it fits together

Godot development computer
  Escape Room editor + game/cabinet/scenario resources
       |                         |
       | game export             | exported catalog.json
       v                         v
Raspberry Pi cabinets ------> Room controller on Mac mini / PC
  games + saved controls         Python + persistent SQLite state
       |                         ^
       v                         |
Local GPIO bridge          Browser operator on Mac / PC / iPad
       |
Physical outputs
Component Purpose Runs on
Godot project and Escape Room editor Build games, place cabinets, and author scenarios Development computer
Arcade Launcher Select games and configure physical controls Desktop or Pi cabinet
Managed cabinet client Load assigned games and report session events Each Pi cabinet
Room controller Validate assignments, track cabinet state, and queue commands Mac mini, PC, or suitable server
Browser operator View the room, prepare scenarios, and start/reset cabinets Staff computer or iPad
GPIO bridge Drive configured local Pi outputs Each Pi that controls hardware

1. Run the project locally

  1. Clone this repository and import project.godot into Godot.
  2. Use the project's configured Godot 4.7 version and Compatibility renderer. Allow the initial asset import to finish.
  3. Run the project with F5, or open ArcadeLauncher.tscn and use F6.
  4. Complete Control Setup if prompted, then select a game and press Start.

Godot's matching export templates are needed to create builds. Python 3 is needed for the room controller and GPIO bridge, but not for standalone desktop gameplay.

The launcher is the configured main scene. The project also has saved editor run arguments for a test scenario/cabinet; review Project Settings → Editor → Run → Main Run Args before testing another assignment.

Controls

  • Joystick: navigate the launcher and move in games.
  • Start: select an entry or begin play.
  • Select: return to the launcher in standalone mode.
  • F1: reopen Control Setup from the launcher.
  • Escape: quit the application entirely.

Configure each machine independently. USB encoders can report different button numbers on Windows and Raspberry Pi OS. The setup wizard saves local mappings, including separate Robotron firing controls; a trackball should report as a mouse.

Mappings live in user://arcade_controls.cfg and survive replacing the game export. See the control guide for keyboard defaults, multiple-controller behavior, and reconnect handling.

2. Author a room and its scenarios

The Escape Room editor plugin is enabled in this project. Open its main-screen tab in Godot; if it is missing, check Project Settings → Plugins.

The existing resources provide a starting point:

Resource What to configure
Project database Register cabinets, games, and scenarios
Room layout Boundary, walls, cabinet placements, and room devices
Cabinet profiles Unique cabinet IDs, available controls, and hardware configurations
Game definitions Game scenes, control requirements, and exposed events
Scenarios Cabinet/game assignments and event-to-hardware mappings

A typical authoring workflow:

  1. Create or duplicate a cabinet profile and give it a unique cabinet_id.
  2. Describe its actual controls in capabilities, and configure its hardware actions with the correct controller ID and BCM pins.
  3. Register the cabinet in the project database and place it in the room layout.
  4. Create a scenario with one assignment per participating cabinet. Choose a compatible game and the standard variant.
  5. Map game events to the cabinet's hardware action IDs. For example, game_won → coin_release.
  6. Register and save the scenario. Use the editor's simulation tools before deploying real outputs.

Designer-facing physical dimensions and positioning use feet; internal room geometry remains in meters.

Capabilities and input mappings are separate. Capabilities determine which games a cabinet can support; Control Setup determines which physical inputs activate their actions. The sample cabinet profiles describe limited controls, so update them to match your hardware before expecting every game to be available.

Export the operator catalog

From the project root, with your Godot executable available as godot:

godot --headless --path . --script tools/room_controller/export_catalog.gd

This generates catalog.json from the saved designer resources. The controller uses it for room positions, scenarios, and game compatibility. Regenerate it after authoring changes, restart the controller after copying it, and redeploy the game export when its packaged resources change.

3. Export and run a Pi cabinet

  1. Install matching Godot export templates on the development computer.
  2. Use the Linux export preset, configured for ARM64, for a 64-bit Raspberry Pi OS installation. The Windows Desktop preset is available for PC testing.
  3. Copy the executable and any accompanying export files to the Pi.
  4. Make the Linux executable runnable, then launch it normally to configure the controls:
chmod +x ArcadeEscape.arm64
./ArcadeEscape.arm64

Use your actual exported filename if different. The Pi runs the exported game; it does not need the Godot editor. The project has been tested on a Pi 4; verify the target hardware, display resolution, and controls for each installation.

For gameplay-only testing, no controller service or GPIO bridge is required. Real GPIO remains opt-in through --gpio=real.

4. Start the room controller and browser operator

Copy these three files together to the controller machine:

The controller uses Python's standard library; it has no pip dependencies. Generate distinct random tokens of at least 16 characters for the operator and each cabinet. Replace the placeholders below with those values.

macOS / Linux, from that controller folder:

export ARCADE_OPERATOR_TOKEN='your-generated-operator-token'
export ARCADE_CABINET_TOKENS='{"cabinet_01":"your-generated-cabinet-one-token","cabinet_02":"your-generated-cabinet-two-token"}'
python3 server.py --bind 0.0.0.0 --database arcade_room.sqlite3

Windows PowerShell, from the repository root:

$env:ARCADE_OPERATOR_TOKEN = 'your-generated-operator-token'
$env:ARCADE_CABINET_TOKENS = '{"cabinet_01":"your-generated-cabinet-one-token","cabinet_02":"your-generated-cabinet-two-token"}'
py -3 tools/room_controller/server.py --bind 0.0.0.0 --database arcade_room.sqlite3

Keep the database at a stable location and back it up. Allow TCP 8766 through the controller machine's firewall for the room LAN. Keep real tokens and deployment databases out of source control.

Open http://CONTROLLER_IP:8766/ on the staff computer or iPad and enter the operator token. The iPad needs only a browser. Use a trusted isolated LAN; the default HTTP connection is not encrypted. See the deployment guide for network and credential details.

5. Connect cabinets to the controller

On each cabinet, create arcade_network.cfg in the application's Godot user-data directory:

[network]
url="http://CONTROLLER_IP:8766"
cabinet_id="cabinet_01"
cabinet_token="your-generated-cabinet-one-token"

Use that cabinet's own ID and token. CFG strings use double quotes.

Machine Typical configuration directory
Raspberry Pi / Linux ~/.local/share/godot/app_userdata/ArcadeEscape/
Windows %APPDATA%/Godot/app_userdata/ArcadeEscape/

This file goes in the user-data directory, not beside the executable. ARCADE_ROOM_URL and ARCADE_CABINET_TOKEN environment variables override their file values; --cabinet=... overrides the cabinet ID.

Start the managed client:

./ArcadeEscape.arm64 -- --managed-cabinet --cabinet=cabinet_01

This bypasses the game list and waits for the operator. It uses the controls previously saved through the launcher. Deploy the current export: the fleet controller requires protocol 2 (arcade-cabinet-2).

Enable physical GPIO outputs

Follow the GPIO guide to install Pi dependencies and verify the wiring with an LED first. GPIO action pins use BCM numbering, not physical header positions.

For the Cabinet 01 GPIO17 example, run the helper and game in separate terminals:

# Terminal 1: local GPIO helper
GPIOZERO_PIN_FACTORY=lgpio python3 pi_gpio_bridge.py --controller cabinet_01_gpio --pins 17
# Terminal 2: managed game with real outputs enabled
./ArcadeEscape.arm64 -- --managed-cabinet --cabinet=cabinet_01 --gpio=real

Copy the bridge script from tools/pi_gpio/ to the Pi. Match its controller ID and allowed pins to that cabinet's hardware resources.

Port Service Address used
8766 Room controller and browser operator Controller machine's LAN address
8765 GPIO bridge 127.0.0.1 on the cabinet Pi

Keep the room URL on 8766 even when the GPIO bridge reports 8765. An accepted GPIO command confirms the software call; without sensor feedback it does not confirm physical coin delivery.

6. Run a room session

  1. Confirm each required cabinet is ONLINE in the browser operator.
  2. Select a scenario and choose Prepare assigned cabinets.
  3. Wait for each cabinet to acknowledge READY, then start it remotely or with its physical Start button.
  4. Monitor game state, event history, and hardware command acknowledgements.
  5. Use Reset cabinet… to end its session before changing assignments.

Scenario preparation validates the complete assignment list before dispatch, including connectivity and game compatibility. Cabinets acknowledge independently. Manual game assignments intentionally run without inherited scenario rewards.

The sample proof_of_concept connects a Pac-Man win on Cabinet 01 to its coin_release action. The two_cabinet_test demonstrates separate cabinet assignments and event mappings.

The older -- --operator Godot mode remains available for Cabinet 01 quick controls. Use the browser interface for multiple cabinets and the room map.

Troubleshooting

Symptom Check
Controls differ between Windows and Pi Run Control Setup on the Pi; do not copy Windows mappings blindly.
Room connection token is not configured Check the user-data CFG location, double quotes, role-specific token, and environment overrides.
Unauthorized The service is reachable; check the token and cabinet ID against the controller configuration.
Cabinet stays offline Check the controller IP, port 8766, firewall, running client, and export protocol version.
A game is missing from the compatible list Update the cabinet's capabilities, regenerate the catalog, and redeploy the cabinet resources.
GPIO command fails or LED stays off Check real mode, local helper, controller ID, pin allowlist, and the wiring test in the GPIO guide.
Delivery is unconfirmed Software acknowledgement is available, but physical feedback is not; inspect the output.

Repository layout

addons/escape_room/      Godot editor plugin
core/                   Game contracts, resources, runtime, controls, networking
editor/                 Room-authoring workspace and simulation tools
data/                   Saved games, cabinets, rooms, scenarios, and mappings
games/                  Seven games, art/audio, launcher, and control setup
operator/               Godot operator scenes
main/                   Room runtime entry scene
tools/room_controller/  Python controller, browser dashboard, catalog exporter
tools/pi_gpio/          Local Raspberry Pi GPIO bridge
tests/                  Godot and Python verification scripts

Development checks

Run commands from the repository root, replacing godot with your executable as needed:

python3 -m unittest discover -s tests/room_network -v
python3 -m unittest discover -s tests/gpio -v
godot --headless --path . --script tests/room_network/check_capabilities.gd
godot --headless --path . --script tests/launcher/check_launcher.gd
godot --headless --path . --script tests/launcher/check_controls.gd
python3 tests/room_network/check_integration.py /path/to/godot

On Windows, py -3 can replace python3. The network integration test launches two headless Godot clients and temporary services on ports 8765/8766, forces test-only wins, and checks a fake GPIO output. Stop any real services using those ports before running it. These tests do not replace physical Pi, wiring, or iPad checks.

Current scope

The project supports standalone arcade play, room authoring and simulation, multiple managed cabinets, scenario assignments, a browser room map, and real GPIO outputs. External sensor inputs, detailed live puzzle-step diagrams, coordinated finale variants, and room timers/hints remain future work. Device locations on the map currently provide layout context rather than live physical sensor state.

S
Description
Glitch in the Code - Escape Room game and controller/operator source
Readme
95 MiB
0 Stars 1 Watchers 0 Forks
Languages
PLSQL 89.8%
GDScript 4%
HTML 3%
Python 2.3%
Rust 0.5%
Other 0.4%