Added chatterbox connections
This commit is contained in:
1 parent
41ef12f954
commit
e58ceeb192
58 files changed
+8931
-8
No files matched your search
@@ -0,0 +1,259 @@
|
||||
# Glitch whole-room simulation
|
||||
|
||||
This lab turns the supplied **Glitch: the Dark Machine** design into an interactive, deterministic room prototype. Rust owns room state; the Flutter screen sends revision-checked simulation intents through the local JSON gateway and NATS. No real cabinet, RFID reader, GPIO bridge, Teddy motor, or release output is contacted in this mode.
|
||||
|
||||
The supplied files are retained as `design/glitch_implementation_contract.json` and `design/GDD_reference.txt`. They are design references, not existing Odin wire definitions. The original files and Odin repository are unchanged.
|
||||
|
||||
|
||||
Current design additions are recorded in [Design updates](design/DESIGN_UPDATES.md), including the junction-box power opening, delayed alien reveal, and proposed cross-cabinet communication mechanic. Power restoration is now implemented; cross-cabinet control remains proposed.
|
||||
|
||||
## Start
|
||||
|
||||
From the repository root:
|
||||
|
||||
```powershell
|
||||
cd labs/glitch_odin
|
||||
py -3 lab.py build
|
||||
py -3 lab.py start-room
|
||||
```
|
||||
|
||||
Open **http://127.0.0.1:18777/?room=1**.
|
||||
|
||||
The original single-cabinet lab can continue using 18767. Whole-room mode has a separate broker on **14232**, room API on **18776**, and browser UI on **18777**; all bind to loopback by default. Ctrl+C stops the processes this launcher owns.
|
||||
|
||||
The default is local-only. Optional --lan mode exposes the simulation UI/gateway for a shared phone/tablet demonstration; see below. This is not a production room operator service.
|
||||
|
||||
## What is simulated
|
||||
|
||||
- Seven cabinets: six named token-gated arcade assignments plus the Dark Machine boss.
|
||||
- P01 claw repair, P02A/P02B claw rewards, P03 records, P04 service-panel symbols, P05 tickets and P06 poster discoveries.
|
||||
- Correct token identity and freshness, persistent retry authorization, attempt IDs and score/home targets.
|
||||
- Virtual cell charge, bay-open confirmation, identity/location observations, debounce and stable ship power.
|
||||
- Two tutorial practices, party-size-dependent calibration waves and profile-specific pass/hold/deadline requirements.
|
||||
- Sequential station arming, operator-group acknowledgements, navigator commit and a five-second launch countdown.
|
||||
- Teddy's authored transcripts, queued cues, simulated playback duration, hint requests, mute, failure/fallback and GM takeover.
|
||||
- Pause, technical holds, time extension, assisted rescue and confirmed reset.
|
||||
- Command deduplication, stale-run/revision/expiry checks and an exportable/replayable trace.
|
||||
|
||||
The server advances the clock continuously. The countdown starts after briefing; pause and technical holds freeze gameplay. Diagnostics provides manual fast-forward controls. Multiple browser tabs do not accelerate time. Clock events are included in the replay trace.
|
||||
|
||||
The room overview is a conceptual dependency layout, not a measured CAD plan.
|
||||
|
||||
## Walk through a full run
|
||||
|
||||
### 1. Prepare and brief
|
||||
|
||||
Select the profile and party size, then Apply profile. Guided uses one calibration pass; standard two; challenge three. Party size sets the number of concurrent operator stations independently of difficulty. One player is explicitly assisted.
|
||||
|
||||
Enable audio in Teddy, then return to Room Flow and click Start run. Hear the haunted-arcade introduction with cabinets OFF. After narration, click Briefing complete: the countdown begins and the room waits for the junction-box key and switch. Click Flip power switch up to simulate unlocking and raising the physical switch. All six token-gated stations boot for four seconds, then show attract mode awaiting their matching token. Scan a token and press Start in Cabinets. The boss retains its six-win gate. These are simulated startup states, not rendered Godot ROM-check animations or physical outputs.
|
||||
|
||||
### 2. Discover tokens
|
||||
|
||||
In Room flow:
|
||||
|
||||
1. Simulate solving P01.
|
||||
2. Solve P02A, then Observe delivery for T01.
|
||||
3. Solve P02B and confirm T02 delivery.
|
||||
4. Solve P03–P06 and confirm their corresponding token deliveries.
|
||||
|
||||
Solving and delivery are separate. ACK only / jam test acknowledges the output request without confirming a token arrived. P02B remains blocked until T01 is delivered. GM hand-delivery requires a staff name/reason and marks the run assisted.
|
||||
|
||||
The first demo deliberately accepts a correct fresh token even if delivery was not observed, as the GDD requests to avoid a sensor-created soft lock. The trace shows the scan; a dedicated delivery-discrepancy warning remains future work.
|
||||
|
||||
### 3. Play six cabinets
|
||||
|
||||
Open Cabinets. Each card shows its game, required token, objective, attempt, losses, charge, health and calibration progress.
|
||||
|
||||
For each cabinet: scan its correct logical token, Start attempt, then Simulate target reached. These are fake observations, not six Godot windows. Wrong token tests are available.
|
||||
|
||||
Charge starts on the first Start and needs 30 seconds of active virtual time. Advance +30 seconds while the run is active. A loss requires a three-second retry delay; authorization and charge remain. The game cannot count a second first-state win.
|
||||
|
||||
Only all six distinct wins make the boss available.
|
||||
|
||||
### 4. Defeat the boss and open the passage
|
||||
|
||||
In Room flow, Start boss and Simulate boss victory. A passage-release request appears in Diagnostics.
|
||||
|
||||
A simulated ACK does not open the passage. Click Observe passage open, then advance at least 300 ms (the +1 second button is sufficient). If five active seconds pass without an open observation, the room enters RECOVERY_HOLD. Observe opening, advance for debounce and Resume; the game clock does not run during the hold.
|
||||
|
||||
Boss gameplay/stages are a deliberate placeholder in this first whole-room test.
|
||||
|
||||
### 5. Move the six cells
|
||||
|
||||
In Ship & cells, for each cell:
|
||||
|
||||
1. Wait for 100 percent charge.
|
||||
2. Observe bay open.
|
||||
3. Remove from bay.
|
||||
4. Insert matching socket.
|
||||
|
||||
Advance +3 seconds after insertion. This allows 500 ms observation debounce plus two seconds of stable ship power.
|
||||
|
||||
Inserting a cell without removing it from its bay intentionally creates a duplicate-location fault. Fix the observations; the ship cannot power up just because six sockets appear occupied.
|
||||
|
||||
### 6. Practice and calibrate
|
||||
|
||||
Open Calibration & launch. The ship displays targets; choose the operator's corresponding selection and click Simulate held Ready for every active station, then Navigator Execute.
|
||||
|
||||
Complete two untimed tutorial practices first. Scored waves then use the selected profile's deadlines and pass count. The fixture Ready action supplies the configured stable-hold duration; actual physical selection stability is not being measured.
|
||||
|
||||
A wrong/incomplete Execute fails the active wave, preserves earlier passes, issues a fresh challenge and adds a three-second retry delay. A deadline at exact equality is closed. Advance time to test expiry.
|
||||
|
||||
With two players, one roaming operator handles stations sequentially. With six players, five stations can be active in a wave. With eight, six are active and extra helpers are not required by the guard.
|
||||
|
||||
### 7. Launch
|
||||
|
||||
Once all passes are complete:
|
||||
|
||||
1. Arm each of the six stations, in any order.
|
||||
2. Acknowledge each operator group.
|
||||
3. Click Navigator Commit.
|
||||
4. Advance five seconds.
|
||||
|
||||
The controller rechecks ship power/health before awarding exactly one launch. The normal outcome is WON. An explicit Finish assisted action produces ASSISTED_RESCUE instead and does not manufacture missing wins.
|
||||
|
||||
Removing a cell during calibration or countdown creates a hold, cancels current readiness/countdown and retains completed passes. Restore the cell, advance for stability, then Resume. A canceled countdown never restarts by itself.
|
||||
|
||||
### 8. Review and reset
|
||||
|
||||
Diagnostics shows output intent versus acknowledged/observed status. Refresh trace, then Copy trace JSON to retain a run. Reset simulation requires confirmation and produces a new run identity.
|
||||
|
||||
This reset only resets fake room state. It does not perform or certify a physical reset checklist.
|
||||
|
||||
## Teddy
|
||||
|
||||
Teddy acts like Odin's narrator/clue device but is not an authority for room progress. The simulated cues include welcome, station naming, readback, holding, readiness, boss, reveal, training, launch and ending. Requested/automatic hints are generic draft text, not final physical-puzzle answers.
|
||||
|
||||
Only one simulated cue plays at once. Queued cues expire or are discarded when their phase changes. Noncritical playback has an eight-second gap. The prototype uses a fixed six-second playback duration rather than real audio acknowledgements.
|
||||
|
||||
Use the Teddy tab to preview the transcript, request hints, stop, replay, mute, simulate failure, or take over/release narration. Offline/muted Teddy retains captions; gameplay can still finish.
|
||||
|
||||
Future work: per-puzzle inactivity/hint ladders, exact calibration-target hints, operator live voice, configurable cue lengths/priorities, playback acknowledgement/timeouts, authored audio and bounded motor control. Optional Teddy speech is available below; doll drivers remain unimplemented.
|
||||
|
||||
## Automated checks and evidence
|
||||
|
||||
Stop whole-room mode before running its network test. The single-cabinet lab uses separate ports and can remain running.
|
||||
|
||||
```powershell
|
||||
py -3 room_smoke.py
|
||||
.\target\debug\glitch-odin-lab.exe replay-room evidence\room-golden-trace.json
|
||||
cargo test
|
||||
cd gm
|
||||
flutter analyze
|
||||
flutter test
|
||||
```
|
||||
|
||||
The smoke test owns its temporary broker/controller and stops them afterward. It executes the full standard six-player run through HTTP and NATS, verifies six cells and two passes per station, commits one launch, exports the trace, and replays it offline.
|
||||
|
||||
Local generated evidence (git-ignored):
|
||||
- evidence/room-golden-trace.json — requests, receive timestamps, results and a state hash after each input.
|
||||
- evidence/room-result.json — transport, final outcome, pass counts and final SHA-256.
|
||||
- evidence/room-runtime.log — test runtime output.
|
||||
|
||||
Replay requires the exact imported contract hash. It reconstructs state and verifies every recorded hash without connecting to NATS or physical devices. It is deterministic regression evidence, **not durable crash recovery**.
|
||||
|
||||
## Acceptance coverage and deliberate gaps
|
||||
|
||||
| GDD cases | Current evidence |
|
||||
| --- | --- |
|
||||
| SIM01–04 | Full pure-reducer runs for standard six-player, guided two-player, assisted solo and challenge eight-player; exact trace replay. Standard path also passes over real NATS. |
|
||||
| SIM05–07 | Wrong/repeated/aged token rejection, retries without another token, and six-distinct-win guard. Production source/boot/assignment validation is not implemented by this fixture API. |
|
||||
| SIM08–09 | ACK versus delivery/open observation, recorded hand-delivery and passage hold. |
|
||||
| SIM10–13 | Cell conflicts, calibration/countdown cancellation, retained passes, challenge expiry and readiness-window retry. Real sensors, agent handshakes and clock synchronization remain untested. |
|
||||
| SIM14–16 | **Deferred:** durable transactional outbox/restart, device dedupe across restarts, message drop/reorder/snapshot reconciliation. In-memory command dedupe is not a substitute. |
|
||||
| SIM17 | Offline Teddy does not gate the full run; stale phase cues are discarded. Real playback-status failure detection and puzzle-specific stale hints are deferred. |
|
||||
| SIM18–20 | Paused active clock, wall-time expiry, calibration time expiry/extension, and rejection of old-run win/token/launch commands. |
|
||||
| UI | All panels checked at 390, 900 and 1400 px; disconnected controls disabled; mutations send authoritative run/revision. |
|
||||
|
||||
These are implementations of selected semantic assertions, not certification that the complete production contract is satisfied.
|
||||
|
||||
## Architecture boundary
|
||||
|
||||
The whole-room simulator has one serialized Rust reducer. It uses a separate experimental NATS subject, `escape_gallery.glitch.lab.v1.room.simulation.request`, and named-field MessagePack. Its fixture command API is **not** the supplied normalized event schema, generated Odin contract, or a production agent ingress.
|
||||
|
||||
The controller currently runs fake observations in one process; it does not launch seven Godot agents. The separately tested real Godot/Pac-Man mode remains available with start-godot. Bridging room assignments into those real agents is a subsequent step.
|
||||
|
||||
The following must be added before live room use: generated shared contracts; authenticated/authorized sources and room-scoped subjects; agent boot/sequence/assignment fencing and readiness handshakes; durable journal/outbox and device ledgers; production recovery tests SIM14–16; real cell/passage feedback; physical preflight/reset; and hardware-specific Teddy/I2C integration.
|
||||
|
||||
The existing Pi deployment, GPIO configuration, single-cabinet lab and Odin repository remain separate.
|
||||
|
||||
## Hear Teddy with Chatterbox
|
||||
|
||||
Chatterbox Turbo is now the default lab voice, using the actor's approved reference recording. On this development PC, the model runs in Ubuntu/WSL on the RTX 5070 and stays loaded between hints. WAV audio is cached and delivered through the existing browser audio controls.
|
||||
|
||||
From `labs/glitch_odin`:
|
||||
|
||||
```powershell
|
||||
py -3 lab.py start-room --speech --lan
|
||||
```
|
||||
|
||||
Wait for READY, then open Teddy and tap **Enable audio and test speaker** on each listening phone/tablet/PC. Use **Say now** on a saved hint, or start the room briefing. Audio requires the page to remain active; mobile browsers can suspend background or locked-screen playback.
|
||||
|
||||
The configured installation is `~/teddy-chatterbox` inside WSL Ubuntu. Runtime reference: `.speech/voices/teddy-chatterbox-reference.wav`. These local dependencies and voice assets are not included in Git. See [Teddy voice setup](TEDDY_TRAINING.md#chatterbox-live-lab-backend) before moving to a fresh machine. This GPU backend has not been deployed to a Raspberry Pi; a Pi can receive prepared audio from a GPU host in a future deployment integration.
|
||||
|
||||
The follower stops publishing audio on mute, stop, takeover, offline, reset, replacement, or connection loss. In-flight GPU computation may finish to fill the cache, but cancelled cues cannot begin playback. An unavailable voice engine leaves captions and room controls available; inspect `.speech/chatterbox.log` and restart the lab to retry. No automatic change to a different voice occurs.
|
||||
|
||||
For the PC's speakers instead of browsers:
|
||||
|
||||
```powershell
|
||||
py -3 lab.py start-room --speech --speech-output local
|
||||
```
|
||||
|
||||
Piper is retained as an explicitly selected fallback:
|
||||
|
||||
```powershell
|
||||
py -3 lab.py setup-speech
|
||||
py -3 lab.py start-room --speech --speech-backend piper --lan
|
||||
```
|
||||
|
||||
`setup-speech` installs the original stock Piper voice only. Chatterbox does not use Piper ONNX models. Audio completion still does not advance puzzle state, and different browsers are not sample-synchronized.
|
||||
|
||||
## Demonstrate from a phone on the same LAN
|
||||
|
||||
```powershell
|
||||
py -3 lab.py start-room --speech --lan
|
||||
```
|
||||
|
||||
On the phone, join the same normal Wi-Fi network as the PC and open:
|
||||
|
||||
`http://<PC-Wi-Fi-IPv4>:18777/?room=1`
|
||||
|
||||
For the development PC's current primary Wi-Fi address, that is **http://10.0.0.57:18777/?room=1**. Check `ipconfig` if the address changes. Use the Wi-Fi address, not a VPN adapter address. The PC also currently has another Wi-Fi adapter at 10.0.0.227.
|
||||
|
||||
The page and its room/audio requests use the same host/port, so a phone never tries to contact its own localhost. Only the UI/gateway binds to the LAN; NATS, the room API, and speech remain on loopback. This is a shared, unauthenticated **simulation demo**: anyone who can reach that port can change the simulated run. It does not connect to real cabinets or GPIO. Do not port-forward it onto the Internet.
|
||||
|
||||
If Windows Firewall blocks the page, allow the Python launcher on the trusted Private network. Alternatively, in administrator PowerShell create a narrowly scoped demo rule:
|
||||
|
||||
```powershell
|
||||
New-NetFirewallRule -DisplayName "Glitch lab demo 18777" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 18777 -RemoteAddress LocalSubnet -Profile Private
|
||||
```
|
||||
|
||||
Remove that optional rule after demonstrations with `Remove-NetFirewallRule -DisplayName "Glitch lab demo 18777"`. A guest Wi-Fi network, client isolation, or VPN LAN blocking may prevent a phone from reaching the PC.
|
||||
|
||||
Use Ctrl+C in the launching terminal to stop the demo. Start without `--lan` to return to localhost-only access.
|
||||
|
||||
## Speech checks
|
||||
|
||||
`py -3 -m unittest test_runner test_teddy_speech` checks startup handling and stale-cue cancellation, duplicate polls, mute/takeover/reset, synthesis failures and single playback. `py -3 speech_smoke.py` uses temporary loopback ports and real Piper to test non-silent WAV generation and local playback with room-state fixtures; it briefly plays a test line. It does not change any running room session.
|
||||
|
||||
## Saved hints and manual speech (October 18 update)
|
||||
|
||||
The Teddy tab now supports:
|
||||
- **New saved hint / Edit**: title, spoken text, multiple comma-separated categories, phase, puzzle/cabinet, target completion condition, and strength (1 subtle, 2 direct, 3 solution).
|
||||
- **Relevant now**: filters by the live room phase and target state. All eligible parallel branches are included. P02A requires P01 solved; P02B requires the first claw token delivery. Solved puzzles and won cabinets leave the incomplete-target suggestions. General room hints remain available.
|
||||
- **All hints**: turn off Relevant now; category and text search still apply. This is the escape hatch for non-linear play or situations the simulation does not model.
|
||||
- **Say now**: sends the selected text through the room controller to the speech backend immediately. It replaces the current cue and bypasses the virtual narration gap. It does not complete puzzles or advance the clock.
|
||||
- **Write a one-off hint**: say custom text without saving, or save it into the library.
|
||||
- **GM takeover**: pauses automatic narration only. Manual hints and Replay work during takeover. Muted/offline Teddy still suppresses speech.
|
||||
|
||||
The library is stored on the hosting computer at `labs/glitch_odin/.lab-data/hints.json`, with the previous save in `hints.bak`. Back up these files when moving to another PC. They are deliberately excluded from Git and persist independently of simulation resets. Reload library to retrieve edits from another device. Conflicting saves preserve your open draft and ask you to review it before saving again. Initial hints are editable draft suggestions, not final puzzle solutions.
|
||||
|
||||
### Audio troubleshooting
|
||||
|
||||
Refresh the updated page, open Teddy, and click **Enable audio and test speaker**. You should hear a one-second tone. The tone is generated in the browser and does not depend on the speech backend. If silent, check that device's media volume, output/Bluetooth routing and browser/tab mute.
|
||||
|
||||
Then click **Say now** on a hint. Speech should progress from generating to ready, and browser status should show playback. If automatic playback is blocked, tap **Play current hint here**; that directly starts the prepared WAV in a user gesture. The button is disabled until a valid current cue has finished generating. Stop/mute/takeover changes and phase/time jumps can cancel cues.
|
||||
|
||||
A server status of **ready** means the WAV is available, not that anybody heard it. Browser status tracks its own playback. The lab no longer reports a fake browser completion based on server elapsed time.
|
||||
|
||||
The previous silence reproduced with GM takeover enabled: manual hints and replay were queued behind the same gate as automatic narration. They now explicitly bypass that gate. Rebuilds also bypass stale bootstrap/JavaScript caches so refreshed browsers get the current controls.
|
||||
Reference in new issue
Block a user