- Add a four-second arcade-style boot sequence followed by the Character / Nickname introduction. - Separate cabinet power-on from RFID credit and player Start. - Add operator Power on control and cabinet power-state reporting. - Prevent repeated power commands from restarting boot or gameplay. - Ignore RFID scans received before the cabinet is ready. - Add power-state, RFID, controller, and GPIO feedback regression tests. - Expand the master walkthrough with export, packaging, file transfer, fresh-Pi setup, RFID compilation, and end-to-end testing instructions. - Correct tester hardware documentation: BCM23/J20 drives an LED; physical buttons connect through a separate I2C1 input board. - Document operator-triggered power-on as the current test workflow and retain the temporary 2.4 configuration compatibility notes. - Record successful physical testing of power-on, RFID credit, and player Start. - Add an Odin integration README describing the proposed Rust/NATS bridge, shared messages, Flutter GM interface, autopilot sequencing, hardware ownership, and Starfish SSH-management role. - Define migration milestones and information needed from the framework owner; link the integration guide from the root README. Validation: 69 controller tests, 10 GPIO tests, Pac-Man power/RFID checks, managed-cabinet lifecycle checks, and visual screen inspection.
Escape Gallery: Arcade Cabinet Integration
Purpose and status
The target architecture combines the existing Godot arcade cabinet framework with the Rust room-control framework developed for Odin. Rust owns room sequencing, NATS carries control and state messages, and Flutter provides the game-master interface. Starfish is the proposed tool for managing Raspberry Pi SSH access.
This document describes the intended integration, not a completed deployment. The current arcade installation uses a Python room controller and browser operator interface. A physical Pac-Man test has successfully demonstrated operator power-on, the boot sequence, RFID credit, and player Start on a Raspberry Pi. The NATS bridge, Flutter cabinet controls, and shared autopilot integration remain to be implemented.
Glitch: the Dark Machine and Odin's Dilemma remain separate room implementations. Shared infrastructure, drivers, and messaging can be reused without mixing their puzzle rules, assets, device identities, or deployment configuration.
Target system
Staff laptops / tablets
|
v
Flutter GM interface
|
v
Rust room controller / autopilot
|
v
NATS messaging
|
v
Cabinet Rust integration (Godot GDExtension)
|
v
Godot cabinet application
| Game, graphics, sound, controls, credits and objectives
| Cabinet hardware interface
v
RFID / I2C inputs / LEDs / configured outputs
This diagram shows the logical control flow. The Flutter-to-controller transport and browser connection path must be confirmed against the owner's current framework. Hardware may run in a local service rather than inside the Godot process; each device must have one owner.
Starfish sits alongside this runtime architecture for SSH access management. It is not the game-message transport. Release packaging, service installation, update activation, and rollback need an agreed deployment workflow; SSH-key management alone does not provide those functions.
Responsibilities
| Component | Intended responsibility |
|---|---|
| Godot cabinet application | Game selection, rendering, game audio, joystick/trackball/button mappings, boot presentation, credits, objectives, and game lifecycle. |
| Cabinet hardware layer | RFID and I2C drivers, input interpretation, configured output actions, and hardware status. |
| Rust Godot extension | NATS connectivity, generated message serialization, command validation and translation, state publication, and connection reporting. |
| Rust room controller / autopilot | Room sessions, puzzle sequencing, timed actions, dependencies between cabinets, room-wide effects, and GM overrides. |
| Flutter GM interface | Room layout, cabinet/device views, progress, diagnostics, and operator commands. |
| Shared message definitions and generator | Compatible command and state types for Rust, Dart, and any additional required languages. |
| Starfish | Proposed management of Pi SSH identities and access, subject to confirming its workflow. |
Room sequencing has one authoritative owner: the Rust controller. A cabinet owns execution of its assigned game and local interactions. For example, an accepted RFID scan can grant a local credit under the current assignment, while a completed game is reported to autopilot to determine which room puzzle activates next.
Fit with the existing cabinet framework
The existing games remain in GDScript. The Rust extension provides methods and signals that GDScript can call or observe; it does not require rewriting gameplay in Rust or C#.
The current framework already supplies:
- Arcade games with configurable objectives and mapped player controls.
- Cabinet profiles, compatible-game assignments, and a visual PCB/device inventory.
- Pac-Man software power, boot, credit, Start, and completion behavior.
- A local Python GPIO bridge and Rust RFID helper.
- A managed-cabinet command/state integration point.
- An operator interface, room-layout authoring, and deployment tools useful during migration.
The existing HTTP integration can remain available for development and rollback while a NATS backend is introduced. Each deployed cabinet session must select one controlling backend; the Python controller and Rust autopilot must not independently issue competing assignments or advance the same room sequence.
The Godot editor remains useful for designing cabinets, defining devices, and authoring game objectives. An agreed export format should carry those definitions into the Rust/Flutter system so staff do not maintain conflicting copies manually. Existing room and cabinet visuals can inform the Flutter implementation, but the current HTML interface is not automatically reusable as Flutter widgets.
Rust, NATS, and shared messages
A godot-rust GDExtension is the proposed integration mechanism. It can use the existing Rust message types and NATS libraries while exposing a small cabinet API to Godot. If message serialization stays inside Rust, C# or GDScript message generation is not required for the initial integration.
The local Odin repository already contains:
msgs/*.genomessage definitions.- Generator commands producing Rust types and Dart JSON models.
- Rust prop agents and puzzle controllers.
- An autopilot that observes puzzle state and schedules actions.
- Flutter services and controls for room operation.
The inspected version uses MessagePack on prop-facing connections and JSON on game/UI-facing connections. The current upstream schemas and wire formats must be confirmed before implementation. Sharing the name MessagePack is not enough: field order, optional values, enum encoding, and schema compatibility must match the generated implementation.
Networking and hardware operations must not block Godot's rendering/input loop. The extension should queue incoming work and deliver game-facing actions on the appropriate Godot thread. Build and export checks must cover the project's actual Godot version, Windows development builds, and Linux ARM64 cabinet builds.
Proposed cabinet contract
The following are capabilities to agree on, not existing Odin message names:
| Direction | Capability examples |
|---|---|
| Controller to cabinet | Assign a compatible game, configure its objective/credit policy, power on, reset, request full state, invoke a configured hardware action. |
| Cabinet to controller | Identity/version, assignment, power/boot/play state, credit count, objective progress, win/loss, input changes, RFID observations, device faults. |
| Command result | Accepted, rejected, completed, or failed, with a command identifier and explanation. |
Commands and events should identify the room, cabinet, and active session. Define command IDs, expiry, duplicate handling, acknowledgement meaning, reconnect behavior, and state resynchronization before enabling sequencing or physical outputs.
Core NATS does not retain messages for offline subscribers. A one-time win event alone must not be the only record of completion. Agree on authoritative state snapshots, acknowledgement/retry behavior, and whether JetStream persistence is needed. Retries must not repeat credit grants or physical pulses.
Hardware integration
The cabinet can present one hardware interface to gameplay even when the underlying drivers are split across services. Initially, the working Python bridge and Rust RFID helper can remain behind that interface. Individual drivers can then move to shared Rust components without changing each game's logic.
For the tester:
- J1 and J2 are the RFID reader connections; J1 currently grants Pac-Man credit.
- BCM23 / J20 is connected to an LED, not the power button.
- The physical buttons connect through a separate board on I2C1.
- Operator power-on is the current tested method until that input board is integrated.
The I2C board needs its model, address, channel mapping, polarity, and matching driver identified. Existing I2C support elsewhere in Odin does not establish compatibility with this particular board. The previously authored J20 button mapping is obsolete and must be corrected during configuration migration; BCM23 must not be configured as a button input.
Only one process may own each GPIO line, shared reader selector/reset arrangement, or hardware interface. Output commands should refer to configured device actions rather than allow arbitrary network pin writes. Define startup, disconnect, shutdown, and process-failure behavior for connected outputs.
GM access and network layout
The required staff experience is a GM interface accessible from laptops and tablets on the building's local network. Flutter Web is the proposed browser target, subject to checking the current UI and its dependencies. A working Flutter desktop application does not by itself establish browser compatibility.
The master can host the Rust controller, NATS, and web-serving components while connecting to both the venue network and a private cabinet network. Staff devices access the GM interface; cabinets use the private network. The exact browser transport, authentication, NATS permissions, and required listening ports must be defined without opening general routing between those networks.
Keep these credentials distinct:
- SSH identities for installation and maintenance.
- NATS credentials and permissions for runtime messaging.
- GM authentication for staff operations.
First integration milestone
Reproduce the already tested Pac-Man experience through the shared system:
- Flutter assigns Pac-Man to Cabinet 1 and displays Waiting for power.
- A GM Power on command reaches the cabinet through Rust/NATS.
- Godot runs its four-second boot sequence and reports Ready.
- A fresh accepted RFID scan grants one credit and plays the credit sound.
- The player presses Start; the cabinet consumes the credit and reports Playing.
- The player completes the configured objective; the cabinet reports completion.
- Glitch autopilot activates the next configured puzzle or cabinet.
Acceptance includes reconnecting the network, restarting a cabinet, repeating commands, resetting a session, and verifying that no old scan, win, or output action is applied to a new session. Add the physical I2C button after its driver and mapping are confirmed.
What is needed next
| Needed from the framework owner | Purpose |
|---|---|
| Current Odin/shared-framework repository, revision, and build instructions | Establish the actual integration baseline and private dependencies. |
| Message-generator source or installation instructions, plus current schemas | Generate compatible types and agree on cabinet command/state definitions. |
| NATS subject conventions, connection configuration, credentials/permissions, and persistence policy | Integrate cabinets with the existing messaging architecture. |
| Proposed Rust/Godot bridge API and implementation ownership | Decide who builds the extension, what GDScript calls, and how releases are maintained. |
| Hardware schematics, I2C board identity/address/channel mapping, and driver source | Integrate the tester's buttons and LED correctly. |
| Current Flutter build targets and browser-access expectations | Confirm laptop/iPad access and the required web transport. |
| Starfish enrollment/key-management workflow | Align Pi maintenance access with the owner's tooling. |
| Deployment conventions and ownership of room definitions | Agree on service names, release packaging, configuration generation, updates, and rollback. |
Migration approach
- Agree on the cabinet contract and hardware ownership with the framework owner.
- Implement and test the Rust/Godot bridge using one Pac-Man cabinet.
- Add matching Glitch controller logic and Flutter cabinet controls.
- Transfer sequencing authority to autopilot for the test scenario.
- Integrate the confirmed I2C driver and remaining cabinet devices.
- Expand to additional games/cabinets, then port room-map and diagnostic views.
- Adopt the agreed Starfish and release workflow while retaining a tested rollback path.
The existing working installation remains the reference until the new path passes the same physical tests. No deployment or runtime migration is performed by this document.
References
- godot-rust / GDExtension
- NATS and Core NATS delivery behavior
- MessagePack
- Starfish repository supplied by the owner — implementation not reviewed here.
- Current arcade master setup walkthrough — updated for operator power-on, RFID-only live inventory, and the corrected BCM23 LED / I2C button arrangement.