# 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 ```