236 lines
20 KiB
Markdown
236 lines
20 KiB
Markdown
# Escape Gallery — Glitch: the Dark Machine
|
|
|
|
**A Godot arcade escape-room framework with a browser-based operations hub.**
|
|
|
|
Design rooms, configure cabinets and their connected devices, assign arcade games to scenarios, and manage play from a staff computer or tablet. Raspberry Pi cabinets run exported games; a Python controller coordinates their sessions and serves the **Escape Gallery** operator webpage. The first room is **Glitch: the Dark Machine**.
|
|
|
|
The Arcade software is separate from Odin. Its RFID helper follows the tester PCB's selector arrangement and Odin's reader-library approach without requiring Odin's room services.
|
|
|
|
## Start here
|
|
|
|
**For a fresh installation, follow the [master walkthrough: Cabinet 1 Pac-Man RFID test](docs/pacman_rfid_first_setup.md).** It covers the entire process: PC exports, matching release packages, private cabinet LAN, Pi prerequisites, reader compilation, credentials, configuration, startup, and physical acceptance testing.
|
|
|
|
| Task | Guide |
|
|
| --- | --- |
|
|
| Plan integration with Rust/NATS, Odin autopilot, and Flutter | [Target architecture and next requirements](docs/odin_integration/README.md) |
|
|
| Export and package a matching release | [Master walkthrough, section 3](docs/pacman_rfid_first_setup.md#3-export-package-and-copy-one-complete-release) |
|
|
| Run Cabinet 1 with RFID credits | [Full master walkthrough](docs/pacman_rfid_first_setup.md) |
|
|
| Configure cabinet controls | [Launcher and control setup](games/launcher/README.md) |
|
|
| Author the custom PCB wiring inventory | [Visual PCB setup](docs/cabinet_pcb_setup.md) |
|
|
| Configure GPIO outputs and device feedback | [Pi GPIO guide](tools/pi_gpio/README.md) |
|
|
| Run controller/cabinet launch scripts | [Launch tools](tools/launch/README.md) |
|
|
| Start Pi services remotely over SSH | [Remote cabinet startup](docs/remote_pi_start.md) |
|
|
| Stage and activate fleet releases | [Deployment tools and current limitations](tools/deploy/README.md) |
|
|
| Configure the operator/controller | [Room controller guide](tools/room_controller/README.md) |
|
|
| Test sequential cabinet objectives | [5 seconds → 500 points → 1 frog](docs/three_cabinet_test.md) |
|
|
|
|
The fleet wizard is not yet a complete RFID installer: it does not generate the device/helper paths and rejects an empty output allowlist with real GPIO enabled. Use the master walkthrough's manual installation for the RFID-only test. Do not add an arbitrary output pin to bypass this limitation.
|
|
|
|
## Included games
|
|
|
|
| | Game | Controls |
|
|
| --- | --- | --- |
|
|
|  | **Pac-Man** | Four-way joystick + Start |
|
|
|  | **Galaga** | Horizontal movement + Fire + Start |
|
|
|  | **Tempest** | Joystick, spinner, or trackball + Fire + Superzapper + Start |
|
|
|  | **Missile Command** | Trackball + three battery buttons + Start |
|
|
|  | **Frogger** | Four-way joystick + Start |
|
|
|  | **Space Invaders** | Horizontal movement + Fire + Start |
|
|
|  | **Robotron 2084** | Two eight-way joysticks, or movement joystick + four directional fire buttons, plus Start |
|
|
|
|
These are playable recreations with title/attract screens, sound, and game-specific rendering. Arcade accuracy and mechanics continue to be refined. Pi 4 gameplay has been tested; verify controls, audio, performance, and hardware on each installation.
|
|
|
|
## System layout
|
|
|
|
```text
|
|
Development PC: Godot editor + saved resources
|
|
| ARM64 game/PCK + Python tools | matching catalog + operator assets
|
|
v v
|
|
Pi cabinets <--------------------> Master controller
|
|
| Python + SQLite
|
|
| / \
|
|
Local GPIO bridge Private LAN Venue LAN
|
|
| |
|
|
PCB inputs / RFID / outputs Staff browsers
|
|
```
|
|
|
|
The master can run on a Pi, PC, Mac mini, or another suitable Python host. For the isolated Pi arrangement, its Ethernet connects to the private cabinet switch and its Wi-Fi or second Ethernet interface connects to the venue LAN. It hosts the operator on both networks without forwarding cabinet traffic to the venue. Network isolation requires the configuration in the walkthrough; the application does not configure routing/firewalls automatically.
|
|
|
|
| Port | Service | Address |
|
|
| --- | --- | --- |
|
|
| **8766** | Controller API and operator webpage | Master private IP for cabinets; master venue IP for staff |
|
|
| **8765** | GPIO bridge | Cabinet-local `127.0.0.1` only |
|
|
|
|
## Develop and play locally
|
|
|
|
1. Import [project.godot](project.godot) into the project's Godot version, currently **4.7.2**, and let asset import complete. The project uses the Compatibility renderer.
|
|
2. Run the main project or [ArcadeLauncher.tscn](games/launcher/ArcadeLauncher.tscn).
|
|
3. Complete **Control Setup** and select a game. Review saved editor run arguments if the project starts in a test/managed mode instead.
|
|
4. Install matching Godot export templates before making Windows or Linux builds.
|
|
|
|
Standalone games do not require Python. The controller/launcher/bridge do. Pi hardware uses GPIO Zero/lgpio; the separate RFID helper is built with Rust on the Pi.
|
|
|
|
- **Start:** select or start; **Select:** return to the standalone launcher.
|
|
- **F1:** reopen Control Setup; **Escape:** quit the application.
|
|
- Map each machine independently: Windows and Pi USB button indices can differ.
|
|
- Saved mappings live in `user://arcade_controls.cfg` and survive game-export replacement.
|
|
|
|
## Author rooms, cabinets, and scenarios
|
|
|
|
Open the **Escape Room** main-screen editor tab. Its plugin is enabled in the project; check Project Settings > Plugins if the tab is missing.
|
|
|
|
| Resource | Purpose |
|
|
| --- | --- |
|
|
| [Project database](data/project_database.tres) | Register games, cabinets, scenarios |
|
|
| [Physical room](data/rooms/arcade_room.tres) | Boundary, walls, doorways, placements, devices |
|
|
| [Cabinet profiles](data/cabinets/) | Unique IDs, control capabilities, hardware actions, PCB connections |
|
|
| [Game definitions](data/games/) | Scenes, required controls, game events |
|
|
| [Scenarios](data/scenarios/) | Assignments, dependency gates, per-game objectives, event/output mappings |
|
|
|
|
Give each cabinet a unique ID, describe its actual controls, register it, and place it in the room. Assign compatible games to a scenario and map only intended events to configured hardware actions. Save all resources before exporting. **Capabilities** determine game compatibility; **input mappings** determine which physical controls activate game actions.
|
|
|
|
Assignments support `game_config` overrides, including score/board objectives, Frogger home counts, and a test-only timed win. These settings survive scenario working-copy/save operations. The controller validates settings and cabinet feature support before preparation. Older example scenarios may require updating action IDs and capabilities to match the current designer-authored cabinet resources.
|
|
|
|
### Physical room editor
|
|
|
|
The **Physical** view provides Labels and Dimensions toggles to reduce clutter. Hidden labels do not prevent selecting objects; these toggles are editor-session view settings.
|
|
|
|
Use **DRAW DOORWAY** and drag from hinge to opposite jamb. Align it with a wall to display an opening, threshold, leaf, and swing arc. Select the doorway to edit its endpoints, convert wall/doorway type, or reverse its swing; use DELETE WALL to remove it. Edits use the room undo/save/revert workflow. Designer dimensions are in feet; stored geometry is in meters.
|
|
|
|
Doorways are layout annotations. They do not change game collisions or act as live door sensors. Browser room-map doorway rendering remains future work.
|
|
|
|
### Visual PCB connections
|
|
|
|
Open a cabinet profile's **PCB Connections** editor and select a connector to assign a device type, name, unique ID, binding, and wiring notes. Digital inputs expose their pull-up setting. The editor validates duplicate assignments and relevant pin/action conflicts, supports Undo/Redo, and saves the configuration with the cabinet resource.
|
|
|
|
The board includes direct GPIO connectors, J16 I2C, and multiplexed J1–J8 reader connectors. See the [pin mapping guide](docs/cabinet_pcb_setup.md). Saving this inventory does not energize outputs or install drivers. Supported entries can be exported into the optional runtime feedback configuration; I2C and Other devices remain inventory-only.
|
|
|
|
## Operator hub and managed play
|
|
|
|
The browser hub provides an overview, **Glitch: the Dark Machine** room map, per-cabinet details, hardware controls, and activity history. It shows assigned games and reported cabinet phases. Pac-Man has a custom cabinet treatment with marquee and gameplay artwork; the screen says **Waiting for operator** before play. This artwork is an illustration, not live video.
|
|
|
|
Prepare a scenario after its participating cabinets report online. Independent assignments can start through the operator or physical Start; dependency-gated assignments activate after their predecessor wins. RFID-credit assignments require a scan and physical Start. Reset before reassigning an active cabinet.
|
|
|
|
Manual game assignments do not inherit scenario rewards. Operator hardware interventions require an online prepared cabinet, configured action, and a reason; requests are logged and deduplicated. An accepted output command is not proof of physical movement or delivery.
|
|
|
|
Optional device panels show RFID identifiers, digital input activity, electrical output state, errors, and stale feedback. Activity records device changes. Generic sensor-driven puzzle rules and detailed live puzzle-step diagrams are not yet implemented; the Pac-Man RFID credit flow is the first specific input-driven scenario.
|
|
|
|
### Pac-Man RFID credit scenario
|
|
|
|
Select **Cabinet 1: Pac-Man RFID credit** (`pacman_rfid_credit_test`):
|
|
|
|
1. Prepare Cabinet 1: Pac-Man displays **WAITING FOR POWER**.
|
|
2. Press **J20 / BCM23** (`cab1_btn_ylw`) or operator **Power on**. After the four-second ROM-check recreation, Pac-Man shows its Character / Nickname introduction.
|
|
3. A new accepted scan on **J1 / cab1_rfid1** grants **CREDIT 1** and plays the credit sound.
|
|
4. The player presses mapped Start, consumes the credit, and begins play.
|
|
5. Clear one board to win; reset/re-prepare for another session.
|
|
|
|
Credit is capped at one. Historical/stale samples, duplicate events, scans on J2, and scans during gameplay do not bank extra credits. The initial scenario accepts any compatible readable card; `rfid_allowed_uids` optionally restricts accepted identifiers. No card-writing step is required. No motor/relay reward is configured for this test.
|
|
|
|
This needs **arcade-cabinet-2.4**, real GPIO feedback, the updated bridge, and the compiled RFID helper. The helper follows Odin's 32-bit identifier representation and is not full-length UID support for every card type. Compilation and physical reader testing on the tester Pi remain to be verified.
|
|
|
|
## Configuration and credentials
|
|
|
|
Prefer the launcher INIs shown in the master walkthrough. They start the required services and provide the managed game with its connection settings.
|
|
|
|
| Role | Settings |
|
|
| --- | --- |
|
|
| Master controller | `[controller]` URL binding, catalog/database paths, operator token, cabinet-token map |
|
|
| Pi cabinet | `[cabinet]` own ID/token, master private URL, executable, real GPIO option |
|
|
| Local hardware bridge | `[gpio]` controller ID, output pin allowlist, device file, RFID helper path |
|
|
| Optional direct Godot client | `user://arcade_network.cfg`, `[network]`, role-specific token and controller URL |
|
|
|
|
Browser staff use the **operator token**. Each cabinet uses its **own cabinet token**. These are application tokens, not SSH keys. Generate distinct values, for example:
|
|
|
|
```sh
|
|
python3 -c "import secrets; print(secrets.token_urlsafe(12))"
|
|
```
|
|
|
|
This produces a 16-character URL-safe token; use `py -3` on Windows if appropriate. For existing installations, preserve their assigned credentials instead of silently generating replacements. The older installation-specific examples remain in [cabinet setup](docs/cabinet_setup.md); the clean-install walkthrough uses fresh placeholders.
|
|
|
|
INI scalar values are unquoted; JSON values such as `cabinet_tokens` retain JSON quotes. Godot CFG strings use double quotes. The CFG belongs in Godot's user-data directory, not beside the executable. On Linux that is normally `~/.local/share/godot/app_userdata/ArcadeEscape/`; on Windows, `%APPDATA%/Godot/app_userdata/ArcadeEscape/`.
|
|
|
|
Nonempty launcher URL/token values override the CFG; inherited `ARCADE_ROOM_URL` and `ARCADE_CABINET_TOKEN` override those launcher values. The configured cabinet ID is passed as a command-line argument. Clear stale environment overrides when troubleshooting.
|
|
|
|
The cabinet controller URL is `http://MASTER_PRIVATE_IP:8766`, not the cabinet's own IP or GPIO port. The default operator connection is plain HTTP for the internal network; do not expose it through public router port forwarding.
|
|
|
|
## Exports, startup, and deployment
|
|
|
|
Use the [master walkthrough's release workflow](docs/pacman_rfid_first_setup.md#3-export-package-and-copy-one-complete-release) as the source of truth:
|
|
|
|
1. Save resources and export `catalog.json` from the same project revision.
|
|
2. Build Linux ARM64 executable + PCK into a fresh release folder outside the repository; optionally build Windows separately.
|
|
3. Package the matching Python/controller assets with `master-package` and the cabinet files with `bundle`.
|
|
4. Configure site-specific files separately; compile the RFID helper on the cabinet.
|
|
5. Validate launcher settings, start the services, and run the physical acceptance test before enabling startup.
|
|
|
|
The existing `setup/pc` and `setup/pi` folders are manual staging areas, **not proof of a current build**. Their checked-in artifacts are not automatically rebuilt when source changes. Do not assume they contain the 2.4 power/RFID features until explicitly exported and verified. Exclude staged exports from the game PCK.
|
|
|
|
The deployment tools provide a terminal setup wizard, separate site credentials, SSH enrollment, per-cabinet preflight, versioned uploads with manifest hashes, explicit activation, and service/status/log commands. They do not install a private DHCP/firewall configuration or offer a browser provisioning wizard. RFID-only provisioning still needs the manual route described above.
|
|
|
|
The Pi user-service helper captures the desktop environment and refreshes it on login. It does not automatically enable cabinet boot startup; follow the walkthrough for desktop autologin/startup, or use the master remote-start workflow. No Godot editor is needed on a deployed cabinet or browser-only master.
|
|
|
|
Back up site configuration, controller state, input mappings, and the GPIO deduplication ledger. Keep previous release bundles for rollback. Do not mix old PCKs, new catalogs, and unrelated Python releases.
|
|
|
|
## Development checks
|
|
|
|
Run from the project root; replace `godot` with the project's console executable and `python3` with `py -3` on Windows as needed:
|
|
|
|
```sh
|
|
python3 -m unittest discover -s tests/room_network -v
|
|
python3 -m unittest discover -s tests/gpio -v
|
|
godot --headless --path . --script res://tests/pcb/check_pcb.gd
|
|
godot --headless --path . --script res://tests/pcb/check_rfid_credit.gd
|
|
godot --headless --path . --script res://tests/room_editor/check_room_view.gd
|
|
godot --headless --path . --script res://tests/launcher/check_controls.gd
|
|
```
|
|
|
|
Controller tests use a stable historical catalog fixture so designer changes do not alter protocol tests; the RFID scenario test also checks the actual exported catalog. Network/GPIO tests use temporary services and fake hardware, not physical reader/actuator validation.
|
|
|
|
Last recorded verification during this work: 66 controller tests and the RFID credit checks passed; the prior GPIO suite passed 10 tests. The broader `tests/test_pacman.gd` suite reported one ghost-capture assertion failure in unchanged model code. Godot test shutdown also reported resource-leak warnings. These are known validation limitations, not a claim that every project test passes. New Pi exports, RFID compilation, card compatibility, audio, and end-to-end physical operation still need installation testing.
|
|
|
|
## Troubleshooting
|
|
|
|
| Symptom | First checks |
|
|
| --- | --- |
|
|
| Controls differ on Pi | Run Control Setup locally; do not assume Windows button indices match. |
|
|
| Unauthorized | Correct role/token and cabinet ID; check inherited environment overrides. |
|
|
| Cabinet offline | Master URL/8766, network, running client, matching export version. |
|
|
| Game unavailable | Cabinet capabilities and matching exported catalog/resources. |
|
|
| RFID scenario rejected | Cabinet 2.4, real GPIO, matching reader ID in the exported PCB inventory. |
|
|
| RFID pin conflict | Explicit empty `pins =` for RFID-only testing. BCM17/27/22/20 and SPI0 are reserved for readers. |
|
|
| UID visible but no credit | Prepare the RFID scenario, then remove/re-present at J1; check the accepted-card list. |
|
|
| Output delivery unconfirmed | GPIO acknowledgement/electrical state does not confirm physical movement; use an appropriate sensor. |
|
|
| Reader stopped or stale | Helper process, SPI/GPIO permissions, wiring, and competing Odin/bridge processes. |
|
|
|
|
## Repository layout
|
|
|
|
```text
|
|
addons/escape_room/ Editor plugin and PCB inspector registration
|
|
core/ Runtime, networking, controls, room/cabinet/scenario resources
|
|
editor/ Authoring workspace, physical room and PCB editors
|
|
data/ Saved games, cabinets, room layouts and scenarios
|
|
games/ Seven games, assets, launcher and control setup
|
|
operator/ Optional Godot operator scenes
|
|
main/ Room runtime entry scene
|
|
tools/room_controller/ Python controller, browser hub, catalog exporter
|
|
tools/pi_gpio/ Local GPIO bridge, feedback sampler, Rust RFID helper source
|
|
tools/launch/ Supervised launchers, Pi service helper, remote SSH startup
|
|
tools/deploy/ Packaging, site setup, staged deployment and activation
|
|
setup/pc/, setup/pi/ Existing manually staged exports/configuration examples
|
|
docs/ Setup, deployment and designer walkthroughs
|
|
tests/ Godot/Python checks and isolated fixtures
|
|
```
|
|
|
|
## Remaining work
|
|
|
|
Physical RFID commissioning, complete RFID support in the fleet wizard, browser doorway rendering, additional cabinet artwork, general sensor-to-scenario rules, detailed puzzle-step views, coordinated finale variants, and room timers/hints remain future work. The hub can link to other services; it is not yet a full multi-room orchestration system.
|
|
|
|
Pac-Man power-button wiring, the `devices.json` input entry, and the complete power → boot → RFID → Start acceptance test are included in the [master walkthrough](docs/pacman_rfid_first_setup.md).
|
|
|
|
## Glitch / Odin integration lab
|
|
|
|
The isolated [Rust, NATS, and Flutter lab](labs/glitch_odin/README.md) provides an experimental GM screen and simulated Pac-Man cabinet for testing the power, boot, RFID credit, Start, and win flow. It leaves Odin and the current Pi deployment untouched. Begin with the lab prerequisite check; Rust/Flutter checks and the headless real-Godot integration test now pass; physical RFID testing remains pending.
|
|
|
|
The [whole-room simulation walkthrough](labs/glitch_odin/ROOM_SIMULATION.md) covers the seven-cabinet Glitch story, discovery puzzles, ship cells, party-scaled calibration, launch and Teddy narration. This is an isolated Rust/NATS/Flutter prototype with virtual time and replayable traces; production durable recovery and hardware integration remain separate gates.
|