Start the Arcade stack
One launcher starts the needed processes, waits for services to respond, saves logs, and stops its children when you press Ctrl+C. It runs on Windows and Linux/Pi (and supports controller-only use on macOS).
| Mode | Starts |
|---|---|
controller |
Room controller; optionally opens the browser operator |
cabinet |
Managed game and, when enabled, its local Pi GPIO bridge |
all |
Controller plus cabinet; useful for Windows simulation or a Pi hosting everything |
For the usual installation, run controller on the PC/Mac and cabinet on each Pi. Keep the launcher terminal open. These scripts do not install boot services or software packages.
Files to deploy
Keep the following directory structure, either by copying the repository or creating this deployment folder:
ArcadeEscape/
Start-Arcade.ps1
start-arcade.sh
ArcadeEscape.exe # Windows, with any accompanying export files
ArcadeEscape.arm64 # Pi, with any accompanying export files
tools/
launch/ # launch.py, examples, your launcher.ini
room_controller/ # server.py, operator.html, catalog.json
pi_gpio/ # pi_gpio_bridge.py
Use the executable appropriate to that machine. You can instead point the INI at an executable elsewhere. All relative INI paths resolve from the INI's folder, regardless of where you launch the script. Review your existing export location: the project's presets may place builds one directory above the repository.
Windows controller
Install Python 3 first. From the project/deployment root:
Copy-Item tools/launch/controller.example.ini tools/launch/launcher.ini
notepad tools/launch/launcher.ini
Fill in operator_token and cabinet_tokens with the same credentials already used by your cabinets. INI values here are not surrounded by quotes, except the JSON strings inside cabinet_tokens:
operator_token = YOUR_EXISTING_OPERATOR_TOKEN
cabinet_tokens = {"cabinet_01":"YOUR_EXISTING_CABINET_TOKEN"}
Each token must be distinct and at least 16 characters. Existing ARCADE_OPERATOR_TOKEN, ARCADE_CABINET_TOKENS, and legacy ARCADE_CABINET_TOKEN environment variables take precedence. Reuse credentials; the launcher does not generate or rotate them.
Set database to your existing controller database when upgrading. The example defaults to a new tools/launch/state/arcade_room.sqlite3; that would start a fresh controller history instead of using a database at the project root. To use a root-level database from the default INI location, set database = ../../arcade_room.sqlite3.
Then validate and start:
.\Start-Arcade.ps1 -Mode controller -Check
.\Start-Arcade.ps1 -Mode controller -Browser
If PowerShell blocks script execution, the same launcher can be run directly without changing execution policy:
py -3 tools/launch/launch.py controller --check
py -3 tools/launch/launch.py controller --browser
Pi cabinet
Install the GPIO dependencies once, following the GPIO guide. Configure the game's physical controls using the normal launcher before starting managed mode.
sudo apt update
sudo apt install python3-gpiozero python3-lgpio
cp tools/launch/pi.example.ini tools/launch/launcher.ini
nano tools/launch/launcher.ini
chmod +x ArcadeEscape.arm64
Set the game executable path, cabinet ID, bridge controller ID, and BCM pin allowlist. GPIO is enabled in this Pi example. Leave url and token blank to reuse the game's existing user://arcade_network.cfg, or supply them here:
[cabinet]
executable = ../../ArcadeEscape.arm64
id = cabinet_01
url = http://CONTROLLER_IP:8766
token = YOUR_EXISTING_CABINET_TOKEN
gpio = true
Do not copy operator credentials to a cabinet-only Pi. URL/token environment variables still override these INI values. Unlike the launcher INI, Godot's own CFG file requires double quotes around string values.
bash start-arcade.sh cabinet --check
bash start-arcade.sh cabinet
This starts the GPIO bridge first, waits for its local heartbeat endpoint, then launches the managed game with real GPIO enabled. The bridge uses 8765 locally; the room URL uses 8766 on the controller. --check validates files, settings, dependencies, and service port availability; it does not drive GPIO or prove wiring/permissions/network credentials work.
For Pi gameplay/network testing without physical outputs, set gpio = false. For a Pi that also hosts the controller, add the [controller] settings from the controller example and use all mode; blank cabinet URL/token then use that local controller's values.
Windows all-in-one test
Copy windows-all.example.ini to launcher.ini, fill in the controller tokens, and set the Windows executable path. Keep gpio = false:
.\Start-Arcade.ps1 -Mode all -Check
.\Start-Arcade.ps1 -Mode all -Browser
The game connects to the local controller using its cabinet ID's token. GPIO runs in simulation; Windows does not start the physical Pi bridge. To connect a Windows game to a remote controller instead, configure the cabinet section and use -Mode cabinet.
Stopping, logs, and configuration
- Ctrl+C stops the stack started by this invocation. On the Pi, the bridge receives SIGTERM so its normal output cleanup runs.
- Escape/game exit also stops services started by that same invocation. A controller launched separately on another machine stays running.
- An unexpected child exit stops the other owned processes and returns an error; the launcher does not automatically restart a game or repeat hardware actions.
- An occupied service port causes startup to stop. Existing processes are never killed or silently adopted.
- Logs append to
tools/launch/logs/controller.log,gpio.log, andcabinet.logby default. Check them for application errors after startup. - Keep the database and GPIO request ledger across restarts. Do not delete them to replay a reward.
- Use
-Config C:\path\launcher.inion Windows or--config /path/launcher.inion the Pi for another configuration file. launcher.ini,*.local.ini, the default logs, and the default state folder are Git-ignored withintools/launch/. Keep other private configuration paths out of Git yourself.- Controller firewall rules, Godot exports, catalog generation, and GPIO wiring are still one-time deployment tasks; see the room controller guide.
For macOS controller use: bash start-arcade.sh controller --browser, with Python 3 and a configured controller INI.