Files
room_glitch/docs/three_cabinet_test.md
T
Jeff Luke c1b2195834 Expand Glitch operations hub, cabinet authoring, deployment, and RFID support
Operator hub
- Introduce Escape Gallery branding and Glitch: the Dark Machine room views
- Add cabinet illustrations, Pac-Man marquee/gameplay artwork, and waiting states
- Add device feedback panels with RFID readings, input/output states, and stale status
- Add logged operator hardware interventions with request deduplication

Room and cabinet authoring
- Add a visual custom-PCB connection editor with per-cabinet device inventory
- Support device IDs, bindings, wiring notes, input polarity, and validation
- Add physical-room label/dimension toggles and editable doorway annotations
- Preserve doorway changes through undo, save, and revert
- Expand cabinet profiles, room layout, and Glitch scenario resources

Scenarios and gameplay
- Add per-assignment game configuration and runtime feature validation
- Add timed test wins and Frogger individual-home objectives
- Add the three-cabinet timed/score/Frogger test scenario
- Add Cabinet 1 Pac-Man RFID credits, credit sound, and CREDIT 0/1 display
- Require physical Start after an accepted scan and prevent duplicate credits

Pi hardware and deployment
- Add GPIO feedback sampling and a separate multiplexed RFID helper
- Validate reader pin ownership and input/output conflicts
- Add SSH cabinet startup and Pi desktop-session service support
- Add master packaging, site setup, SSH enrollment, and staged cabinet releases
- Verify deployment manifests and support explicit activation/status/log commands

Documentation and verification
- Consolidate the root README around the current architecture and setup workflow
- Add the complete master/Pi/RFID export and deployment walkthrough
- Document network isolation, credentials, card identification, and rollback
- Add PCB, room-editor, feedback, credit, deployment, and controller tests
- Isolate protocol tests from designer-edited cabinet configurations

Known limitations
- RFID helper compilation and physical Pi commissioning remain unverified
- Fleet provisioning does not yet configure RFID-only installations completely
- Broader Pac-Man tests retain a ghost-capture assertion failure
- Staged exports must be rebuilt and checked before deploying runtime 2.3
2026-10-17 14:53:54 -07:00

93 lines
6.0 KiB
Markdown

# Three-cabinet objective test
Choose **3-Cabinet Test: 5 seconds / 500 points / 1 frog** in the browser operator.
| Cabinet | Game | Starts when | Win objective |
| --- | --- | --- | --- |
| `cabinet_01` | Pac-Man | Operator or physical Start after preparation | Automatic win five seconds after Start |
| `cabinet_02` | Galaga | Cabinet 1 reports a win | Score reaches **500 or more** |
| `cabinet_03` | Frogger | Cabinet 2 reports a win | **One frog** reaches a valid home |
Cabinets 2 and 3 remain unloaded while waiting. They load and automatically start after their predecessor wins. The five-second clock begins with Cabinet 1's game-start event, including its intro; it does not count time spent waiting in READY. Galaga keeps its normal brief victory transition before reporting completion. Frogger reports completion after the home-arrival pause.
## What was configured
The resource is [three_cabinet_objective_test.tres](../data/scenarios/three_cabinet_objective_test.tres), registered in [project_database.tres](../data/project_database.tres).
Each `ScenarioAssignment` now has a `game_config` Dictionary, in addition to its cabinet, game, variant, dependency, and event mappings. These values are exported to the controller catalog, included in the prepare command, and passed to the game's `configure()` method. The editor's working copy preserves these dictionaries independently.
The assignments are:
```text
Cabinet 1 / Pac-Man
activate_after_win: empty
game_config:
test_auto_win_seconds: 5.0
boards_to_win: 0
score_to_win: 0
Cabinet 2 / Galaga
activate_after_win: cabinet_01
game_config:
score_to_win: 500
stages_to_win: 0
Cabinet 3 / Frogger
activate_after_win: cabinet_02
game_config:
homes_to_win: 1
boards_to_win: 0
```
Setting board/stage targets to zero disables those alternate win conditions for this scenario. Galaga already supported score targets. Frogger now supports the individual-home target; its default remains a full board. The managed agent's test timer is enabled only by `test_auto_win_seconds`; ordinary scenarios and manual assignments do not inherit it. Reset/unload cancels the timer.
Cabinet 3's profile now includes `joystick_4way`, alongside its existing controls, so Frogger passes compatibility checks. Map its actual joystick using Control Setup. This test has no hardware event mappings, so no GPIO reward or additional wiring is required.
## How to change it in Godot
1. Open `data/scenarios/three_cabinet_objective_test.tres` in the Inspector.
2. Expand **Assignments**, then the assignment to edit.
3. Choose its Cabinet and Game references. Keep Variant as `standard`.
4. Set **Activate After Win** to the preceding cabinet's ID (blank for Cabinet 1).
5. Expand **Game Config** and set the objective keys and numeric values shown above.
6. Save the resource. The sample is already registered in the project database; register any newly created scenario there too.
7. Regenerate the controller catalog from the project root:
```sh
godot --headless --path . --script tools/room_controller/export_catalog.gd
```
Supported network objective keys currently include `test_auto_win_seconds`; Pac-Man board/score targets; Galaga stage/score targets; and Frogger board/home targets. Invalid values and unsupported keys are rejected before scenario dispatch. Chain execution belongs to the managed controller; the editor's local simulation does not run this network handoff.
## Build and deployment checklist
**This update needs fresh game exports on all three Pis.** Agents now advertise `arcade-cabinet-2.1` and the `assignment_config_v1` feature. The controller rejects this objective scenario on older agents so a cabinet cannot silently ignore the five-second or one-frog objective.
1. In Godot, build **Windows Desktop** for PC testing and **Linux** (ARM64) for the Pis. Use the configured engine version and matching export templates. The current presets write one directory above the project; check the output paths before exporting.
2. Copy the new ARM64 executable and any accompanying export files to all three Pis. The same build serves every cabinet; identity and tokens remain machine-specific.
3. Update the Windows controller's `server.py`, `catalog.json`, and `operator.html` together from `tools/room_controller/`.
4. Preserve each machine's local `launcher.ini`, Godot CFG, input mappings, controller database, and GPIO ledger. Confirm its unique ID/token using the [cabinet setup guide](cabinet_setup.md).
5. Restart Windows in **controller-only** mode and restart each Pi cabinet. Do not run an additional PC game with an ID already used by a Pi.
No builds or live controller restarts are performed by editing these resources. The exported binaries must be rebuilt and copied before the hardware test.
## Run the test
1. Confirm Cabinets 1, 2, and 3 are ONLINE with agent version `arcade-cabinet-2.1`.
2. Reset any active sessions. Select **3-Cabinet Test: 5 seconds / 500 points / 1 frog** and prepare it.
3. Confirm Cabinet 1 is READY and Cabinets 2/3 are WAITING.
4. Start Cabinet 1. After roughly five seconds plus the next network poll, Cabinet 2 loads and starts Galaga.
5. Play Galaga until the score reaches at least 500. Cabinet 3 then loads and starts Frogger.
6. Get one frog into an open home. Cabinet 3 becomes WON, completing the test.
7. To repeat, reset all three and prepare the scenario again. Resetting or restarting an upstream cabinet invalidates its dependent sessions. A lost game does not unlock the next cabinet.
## Verification
The automated integration test runs three actual headless Godot clients against a temporary controller, with no real GPIO. Cabinet 1 uses the real five-second timer. Test-only code adds Galaga points at 499 and 500, then places Frogger at a valid home; it exercises normal score/home completion paths rather than directly forcing their wins.
```sh
python3 -m unittest discover -s tests/room_network -v
python3 tests/room_network/check_objective_integration.py /path/to/godot
godot --headless --path . --script tests/room_network/check_objective_defaults.gd
```