Files

1601 lines
55 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Glitch The Dark Machine
Game Design Document and Room Control Specification
Escape Gallery • Version 1.0 • October 17, 2026
Purpose
Build one complete, deterministic escape-room run before committing to final physical puzzle mechanics. This specification connects the player experience to authoritative state, device signals, operator actions and acceptance tests. It targets Rust room orchestration, NATS messaging, Godot arcade clients and a Flutter game-master interface.
Players investigate an abandoned arcade whose games appear alive. Six recovered tokens awaken six cabinets. Their victories wake a seventh machine, whose defeat exposes a crashed alien spacecraft. Players retrieve six charged power cells, restore the craft and repurpose the arcade controls to calibrate its flight. The final launch succeeds through communication, practiced earlier and adapted to the number of players.
Design status
Confirmed requirements: six uniquely token-gated cabinets, a seventh boss cabinet, hidden spacecraft, six removable power cells, second-state calibration games, a coordinated launch, computer-controlled Teddy Ruxpin, variable difficulty and small-party support. Rust/NATS and Flutter are the confirmed final approach.
Proposed defaults: a 60-minute game; support for 2–8 players, plus an assisted solo test mode; the cabinet assignments, puzzle placeholders, character dialogue, tuning values and event contracts below. These are implementation candidates to validate through simulation and playtesting, not claims of completed room features.
How to use this document
Implement the rules and state contracts first. Use fake props, accelerated virtual time and scripted game outcomes to execute every act. Then replace each fake adapter with hardware or a Godot game without changing room rules. Sections 2–9 define play; 10–17 specify controls and operations; 18–21 provide implementation and test appendices.
Companion file: glitch_implementation_contract.json contains proposed profile values, entity mappings, an event envelope schema, a room-state example and machine-readable test cases. It is a design interchange format requiring an importer, not a drop-in Escape Gallery catalog or existing Odin wire schema.
1 Project alignment and implementation boundary
The final system has one room sequencing authority: the Glitch Rust controller. Godot owns local game execution and input feedback; Flutter requests actions and displays authoritative state; NATS carries commands, observations and snapshots. Neither the UI nor an individual cabinet decides that the room has advanced.
Area
Observed project baseline
Required Glitch extension
Arcade runtime
Seven Godot games and configurable objectives
Six first-state assignments, boss treatment and six calibration variants
Control path
Python controller and browser hub; experimental Rust/NATS/Flutter lab
Production Rust room reducer, durable recovery and Flutter run controls
Tokens
Pac-Man RFID credit admission and Start gating
Per-token allowlists for all six cabinets; persistent authorization for retries
Sequencing
Single predecessor win dependencies
All-six join, ship power join, communication rounds and launch barrier
Props and hints
Device feedback and configured output actions
Generic puzzle facts, cell inventory, passage sensing and Teddy scheduler
Migration constraints
Retain the existing Godot games and their tested lifecycle where possible. Select exactly one controlling backend per cabinet session. Do not let Python scenario sequencing and Rust autopilot both drive the same run. Use the legacy controller only for comparison, rollback or isolated development.
The Glitch lab is experimental: named-field MessagePack, a loopback JSON gateway and an in-memory replay cache. The Odin audit describes generated ordered-field prop messages. They are not wire-compatible. Generate agreed Glitch types for Rust and Dart; version the adapter explicitly and do not publish experimental payloads on Odin subjects.
Hardware facts that affect this design
The integration guide corrects older configuration: BCM23/J20 is an LED, not the power button; physical buttons use an unidentified I2C board. Keep that input mapping disabled until identified. The current catalog has only four cabinet profiles. Cabinets 5–7, cell bays, spacecraft sockets, Teddy and passage sensing need authored definitions. Cabinet 3 lacks Tempest’s second-button capability and Cabinet 4 lists roller where Missile Command requires trackball; reconcile capabilities before assignment.
All proposed device names in this GDD are logical identities. Bind them to verified inventory later. Qualify reused local IDs with cabinet identity, for example cabinet_01/cab1_rfid1.
2 Narrative and act structure
Act
Player experience
Exit condition
Target minutes
Arrival
Teddy wakes; investigators learn that tokens belong to particular machines.
Briefing acknowledged and run started
0–4
I The arcade
Parallel physical discoveries unlock six playable cabinets. Games teach naming, responding and holding a setting.
All six first-state wins committed
4–27
II The dark machine
Cabinet 7 boots and combines familiar controls into a short boss challenge.
Boss won; passage physically confirmed open
27–33
III The passenger
Alien reveal; six charged cells are retrieved and installed.
All six correct cells present and power stable
33–40
IV Flight school
Ship-side navigator gives instructions to arcade-side operators.
All calibration checkpoints complete
40–53
V Launch
Crew arms stations, confirms readiness and performs a synchronized commit.
Launch committed and finale completed
53–60
The story behind the machines
Proposed story: the alien’s emergency system has borrowed the arcade’s electrical network. Its damaged translation process makes the games appear mischievous and threatening. Teddy is an imperfect local voice for this system. The boss is a protective firewall, not the alien itself. Defeating it restores enough trust to reveal the passenger and its rescue request.
Avoid an abrupt tonal reversal by planting three clues: a repeating distress rhythm after the first win, a star-like pattern after the third, and Teddy briefly saying “help” before correcting himself. The reveal reframes the strange energy as a stranded being trying to survive. The final launch is theatrical; no moving craft is required.
Pacing rules
Act budgets are targets, not gates or independent countdowns. Early teams progress immediately. At 35 elapsed minutes without the boss completed, suggest assistance; at 45 without ship power, surface a GM pacing alert; at 53 without calibration complete, offer guided calibration. No automatic solve occurs without the configured assistance policy or a logged GM decision.
At zero remaining time, enter TIME_EXPIRED and suspend puzzle timers. The GM may extend time or choose a distinct assisted rescue/debrief ending. Only the normal launch guard produces a normal win. Keep achieved checkpoints for extensions; never restart the room merely because time expired.
3 Dependency graph and physical placeholders
Run start unlocks five independent discovery branches. Physical mechanics can change while their input/output contracts remain stable. All six tokens must remain obtainable without completing a game that requires one of those same tokens.
Puzzle ID
Placeholder interaction
Prerequisite
Reward
P01
Restore claw controls using a simple arcade maintenance clue
Run active
Claw stage A enabled
P02A
Claw retrieval from a designated prize zone
P01 solved
T01 for Cabinet 1
P02B
Second claw retrieval or alternate prize zone
P02A reward delivered
T02 for Cabinet 2
P03
Match a record excerpt to an album sleeve
Run active
T03 for Cabinet 3
P04
Reconstruct a service-panel symbol pattern
Run active
T04 for Cabinet 4
P05
Match ticket values to a cabinet maintenance label
Run active
T05 for Cabinet 5
P06
Read a poster overlay or aligned light pattern
Run active
T06 for Cabinet 6
P02A and P02B are separate reward facts even if they share one physical claw machine. Simulation uses explicit solve and delivery observations. A solution does not prove a token was physically delivered. Jam detection holds reward delivery pending and offers a GM hand-delivery action with a reason.
Room dependencies
P02A → T01 → A01; P02B → T02 → A02; P03 → T03 → A03; P04 → T04 → A04; P05 → T05 → A05; P06 → T06 → A06.
ALL A01–A06 won → B07 available → B07 won → passage release → passage open observation → spacecraft reveal.
Reveal → request all six cell bays open. Each cell also requires charge complete before its bay may release.
ALL six correct cell installations stable → second-state mode ready on all six cabinets → communication tutorial → calibration waves → final arm → synchronized launch.
Token policy
Each token has a configured UID or supported identifier mapped to exactly one cabinet. Reject an incorrect token with a short in-world response; do not consume or confiscate it. Admit only a fresh scan in the current run and boot session. The successful scan grants persistent run authorization for that cabinet, not unlimited banked credits. Each failed attempt can restart without finding the token again. Re-scans cannot create additional rewards or wins.
The first bench test accepted any card. Production admission must use explicit allowlists and test identifier collisions/reader limitations. A physically discovered token can be accepted even when its delivery sensor was missed; record the discrepancy for the GM rather than create a hidden soft lock.
4 Six arcade assignments and first state
Use the first four catalog assignments as the starting point. Cabinets 5–7 are proposals. The branded games below are project assets; public presentation and final naming remain a production decision. A win is a short configured objective, not an expectation that visitors master a full arcade game.
ID and game
First-state objective prototype
Teaches
Cell
A01 Pac-Man
Collect a configured score or clear a shortened board
Identify a station and report completion
CELL01
A02 Galaga
Reach a configured hit/score target
Hear a target, repeat it, then act
CELL02
A03 Tempest
Clear selected lanes or reach score threshold
Use named sectors instead of vague directions
CELL03
A04 Missile Command
Protect a small target set for a short wave
Wait for a cue; avoid premature firing
CELL04
A05 Frogger
Bring a configured number of frogs home
Report ready and hold a successful state
CELL05
A06 Space Invaders
Clear a marked formation or reach score threshold
Coordinate a countdown and confirm success
CELL06
Objective tuning
Proposed baseline: 60–120 seconds of successful play per cabinet, with a 180-second assistance threshold. Begin with the project’s supported score/board/home objectives; bespoke lane or marked-target objectives require game changes. The simulator models progress from 0 to objective_target and emits a validated win; it does not need arcade physics.
Default standard fixtures: Pac-Man 500 points, Galaga 500 points, Tempest 500 points, Missile Command 500 points, Frogger 1 home, Space Invaders 500 points. These are simulation seeds, not balanced production goals. Guided uses 60 percent of score targets; challenge uses 140 percent. Integer count objectives use explicit profile values, never rounding to zero. Validate each game adapter’s supported fields at preflight.
Teaching without blocking parallel play
The first completed cabinet triggers Teddy’s station-name lesson. The next completion triggers an echo/readback example. The third and fifth completions introduce “hold” and “ready.” These beats depend on completion count, not a specific cabinet order. A game win never waits for a voice line to finish. Missed lessons are summarized in the ship tutorial.
On loss, show the objective and allow Start again after a three-second reset. Preserve room wins, token authorization and cell charge. Offer reduced target or guidance after two failed attempts; apply a changed target only at the next attempt boundary. No automatic win timer is permitted in a production profile.
5 The boss and spacecraft reveal
Cabinet 7 The Dark Machine
B07 remains dark and rejects player Start until all six distinct first-state wins are committed. Its boot animation follows a confirmed prepare/ready handshake. Proposed base: a Robotron-inspired protection challenge, subject to cabinet controls, with an alternative bespoke single-joystick variant. Do not require dual joysticks on an unverified cabinet.
A three-part boss teaches the later protocol: identify a marked sector, protect the indicated signal, then hold a stable selection through a spoken countdown. Standard target duration is 90–150 seconds with retained stage checkpoints. Loss returns to the current stage after three seconds; repeated failures offer simpler targets. Boss victory is accepted only for its active assignment and attempt.
Reveal sequence
Step
Command or observation
Required behavior
1
boss.won committed
Latch victory once; queue reveal sound and passage release
2
passage.release requested
Only configured action; record command ID and delivery status
3
passage.open observed
Fresh sensor stable for 300 ms; begin reveal and cell retrieval
4
ship.reveal complete
Show passenger distress, six socket labels and cell instructions
5
cell bay releases
Release only charged bays; display pending charge for others
Do not equate an acknowledged relay command with an open passage. If no open observation arrives within five seconds, enter a reveal hold, alert the GM and stop the active game clock. The operator can inspect, retry a safe configured action or attest physical opening. Record attestation as an override, not as a sensor reading.
Audience and access
Use light, sound and the alien’s breathing or movement to carry the reveal; provide readable text alongside speech. No strobe is needed. Keep the passage’s show function separate from emergency egress. A hardware safety layer and venue procedure govern people and moving parts; the narrative controller must never be the only way to leave.
Teddy’s reveal line: “That was never an invasion. It was a call for help. The machines have been keeping our visitor alive. Bring the six light cores to the ship. Match every symbol, then come back to the controls.”
6 Power cells and the second state
Each cabinet contains one identifiable prop cell. “Charging” is a game abstraction unless engineering later specifies a real electrical function. Start its virtual charge on that cabinet’s first accepted game start. Charge takes 30 seconds of active room time and continues through local game losses. A powered-off or disconnected cabinet pauses only its own charge accumulation. A room hold pauses all charge timers.
Cell state
Entry or exit rule
DOCKED_IDLE
Preflight confirms cell identity and bay presence; charge 0
CHARGING
First valid game start; accrue verified active time
CHARGED_LOCKED
Charge reaches 100 percent; cell remains inaccessible until reveal
RELEASE_PENDING
Reveal reached and charge full; issue bay release once
AVAILABLE
Bay open confirmed; removal now expected
CARRIED
Bay absence stable; no ship socket currently contains this identity
INSTALLED
Matching ship socket reports identity and presence stable for 500 ms
UNKNOWN
Conflicting or stale observations; hold dependent transition
Each cell is mapped one-to-one to its socket, CELL01→SOCKET01 through CELL06→SOCKET06. Reject a wrong socket without penalizing progress. The controller retains both location and charge; a bay sensor going absent alone does not prove the cell reached the ship. Duplicate identity in two places is a fault, not two installed cells.
Ship power barrier
Require all six correct identities present, charged and healthy continuously for two seconds. Commit ship.power_ready, then prepare all six second-state assignments with new assignment IDs. Every required client must report calibration-ready before issuing tutorial challenges. Token scans are no longer required in this state.
Removing any cell before launch commit cancels the current challenge and launch arm, suspends calibration and starts a technical hold. Retain completed calibration checkpoints. Reinsert the correct cell, verify two-second stability and reconcile device readiness; the GM resumes with a fresh challenge ID. Never resume an old countdown automatically.
Practical recovery
A missing cell may be replaced by a registered spare identity through a logged GM substitution. A failed bay sensor may be attested after inspection. Both actions mark the run assisted. Neither action can make a physically unsafe actuator move. After launch commit, cell removal changes diagnostics only; it does not reverse an already completed story ending.
7 Communication and calibration games
Use a consistent spoken grammar: “Station, target, action.” The arcade operator repeats “Station, target, ready.” The navigator answers “Execute.” The game then reports “Locked.” Voice recognition is not required: explicit player buttons and game-state checks record readiness and execution. Teddy models the words, while the actual target remains on the ship display.
Station
Second-state task
Ship-only information
Completion check
01 Route
Move to one of four route symbols
Required symbol
Selection equals target at Execute
02 Vector
Move a horizontal pointer to a numbered zone
Zone number
Pointer inside zone for hold duration
03 Heading
Rotate to one of eight named sectors
Sector label
Correct sector stable through commit
04 Shield
Select one of three shield banks
Bank identifier
Correct bank selected on cue
05 Corridor
Choose a safe lane or home
Lane identifier
Correct lane confirmed
06 Thrust
Set a discrete thrust level
Level 1–4
Correct level held through cue
Teaching sequence
Round T1 is untimed: one navigator and one arcade operator practice a single station target. The navigator presses Dispatch on the ship console; the operator selects and presses Ready; the ship displays the readback target; the navigator presses Execute. This electronic readback allows the crew to correct mistakes before scoring. Require one successful practice, then one hold-and-countdown practice. Both are repeatable and narrated.
Scored calibration contains one or two waves covering all six stations, scheduled at the concurrency supported by the party. Standard has two passes per station with different targets; guided has one; challenge has three. Each completed station-pass is a durable checkpoint. Idle cabinets display their names and wait, avoiding six competing audio tracks.
Retry semantics
A wrong target, early Execute or expired response window fails only the active wave. Show which station needs correction without erasing earlier passes. Generate a fresh challenge ID and permit replay after three seconds; after two failures, offer slower timing. Late Ready or Execute messages for an old challenge are rejected. Targets are generated from a stored seed, with different consecutive values per station.
No calibration step requires an arcade expert. These tasks use familiar controls but assess precise communication. Provide large text, symbols and optional spoken targets; never encode information in color alone.
8 Party size and difficulty profiles
Party size determines simultaneous staffing; difficulty determines precision, repetition and hint timing. Store both at run preparation. Do not silently make a larger party harder or force a smaller party to skip story content.
Players
Navigator and operators
Calibration concurrency
Final human acknowledgements
1 assisted
Ship terminal repeats targets at active cabinet; walk between stations
1; all results latch
1 arcade acknowledgement then ship commit
2
1 ship navigator and 1 roaming arcade operator
1; six stations in sequence
1 arcade acknowledgement then ship commit
3
1 navigator and 2 operators
2 stations per wave
2 arcade acknowledgements then ship commit
4
1 navigator and 3 operators
3 stations per wave
3 arcade acknowledgements then ship commit
5–8
1 navigator; 4–6 operators; extra players scout/check
min(players minus 1, 6)
One per assigned operator group, up to 6
An operator group owns one or more stations. For two players, one operator sequentially arms all six stations; each station latches and displays armed. That operator acknowledges at the last assigned station, then the navigator commits from the ship. There is no simultaneous six-button requirement. Solo is an assisted simulation/access mode pending approval for sale.
Parameter
Guided
Standard
Challenge
Passes per station
1
2
3
Response window per wave
60 s
40 s
25 s
Stable target hold
1 s
2 s
3 s
Final acknowledgement window
30 s
20 s
12 s
Inactivity before hint 1
90 s
120 s
180 s
Next hint eligibility
60 s later
90 s later
120 s later
Boss stage checkpoint
Retained
Retained
Retained
Assistance and changes during play
Allow GM changes at an attempt or wave boundary; save the previous and new profile with reason. If staffing decreases mid-wave, cancel that wave, repartition unfinished work and preserve completed passes. Changing difficulty cannot retroactively invalidate a win. Accessibility options independently enable captions, longer holds, lower audio, alternative control mappings and a proxy narrator.
The timer is 60 minutes for all launch profiles initially. A small-party run reduces concurrent work and repetition through the guided profile if selected; assess physical walking time in playtests. Any extension is visible to staff and logged. Production party limits and timing are pending venue approval.
Assisted solo overrides the final acknowledgement window to 90 seconds to allow travel back to the ship. It still uses a five-second synchronized presentation countdown. Store assisted=true throughout; a valid normal launch may set outcome=WON while retaining that assistance marker, distinct from the GM-forced ASSISTED_RESCUE ending.
9 Synchronized launch protocol
The synchronization is a barrier of verified readiness followed by one scheduled commit. It must feel simultaneous without depending on every cabinet being physically occupied. Previously calibrated stations remain locked; automatic holding is presented as the ship’s stabilization system.
Phase
Guard and action
Failure or retry
ARM
All passes complete and ship power stable. Sequentially arm all six stations for a new launch_epoch.
Missing/offline station holds launch; GM may configure a proxy explicitly
CREW_READY
Every assigned operator group acknowledges once at its designated station. Open the profile’s readiness window on the first acknowledgement.
Window expiry clears group acknowledgements only; station calibration remains
COMMIT_REQUEST
Navigator presses ship Commit within the readiness window; all six stations armed and group acknowledgements current.
Reject with specific missing prerequisite; never partially commit
COUNTDOWN
Controller persists start and commit deadlines; five-second audiovisual countdown. Freeze new inputs except cancel.
Power loss, offline required agent or GM cancel disarms launch and pauses
COMMITTED
At deadline, atomically recheck guards and append launch.committed once. Dispatch finale using stable effect IDs.
After commit, presentation failures recover without undoing victory
DEBRIEF
Finale completion reported or GM confirms ending shown.
If playback fails, offer alternate ending narration; record fault
Timing contract
The controller owns the countdown clock and accepts readiness using its receive time, not player-device timestamps. Final presentation commands carry a future presentation time and launch_epoch; clients acknowledge readiness before countdown. A proposed clock-offset tolerance of 100 ms and audiovisual skew target of 250 ms need installation testing. If timing quality is inadequate, centralize the countdown audio and let clients follow state.
If a command arrives exactly at a deadline, accept only if received_at_ms < deadline_ms. Persist the ordering chosen by the reducer. A technical hold cancels an in-progress countdown; resumption always creates a new launch_epoch. Crew acknowledgements never survive a new epoch or staffing change.
Win and assisted ending
Normal outcome is WON when launch.committed is durable. Continue the ending even if a decorative cabinet animation fails. GM Finish assisted uses a separate outcome ASSISTED_RESCUE and reason; it does not forge six wins or cell readings. Abort and time-expired states lead to their own debrief paths.
10 Room and component state machines
Separate lifecycle from story phase. Lifecycle is IDLE, PREFLIGHT, READY, RUNNING, PAUSED, RECOVERY_HOLD, TIME_EXPIRED, WON, ASSISTED_RESCUE, ABORTED or RESETTING. Story phase is BRIEFING, ARCADE, BOSS, REVEAL, CELLS, CALIBRATION_TUTORIAL, CALIBRATION, LAUNCH_ARM, COUNTDOWN or DEBRIEF. A hold preserves the current phase and checkpoints.
From
Event and guard
To and effects
IDLE
prepare; configuration valid
PREFLIGHT; poll inventory and versions
PREFLIGHT
all required checks pass
READY; no room timer running
READY
start_run authorized
RUNNING/BRIEFING; start active clock
BRIEFING
briefing done or GM skip
ARCADE; enable discovery branches
ARCADE
all A01–A06 won
BOSS; prepare B07
BOSS
valid B07 win
REVEAL; request passage release
REVEAL
passage open confirmed
CELLS; reveal and eligible bay releases
CELLS
all cells stable and clients ready
CALIBRATION_TUTORIAL
TUTORIAL
two practices complete
CALIBRATION; generate first wave
CALIBRATION
all station passes complete
LAUNCH_ARM
LAUNCH_ARM
valid navigator commit
COUNTDOWN; persist deadline
COUNTDOWN
deadline and all guards true
WON/DEBRIEF; launch commit once
PAUSED is GM-controlled; RECOVERY_HOLD is fault-controlled. Both freeze active elapsed time and gameplay deadlines, while health probes and command expiry continue on wall time. TIME_EXPIRED can return to the saved phase only through a logged time extension. Terminal outcomes accept diagnostics and debrief controls, not gameplay progression.
Cabinet states
OFF → BOOTING → TOKEN_WAIT → READY → PLAYING → WON or RETRY_READY. A valid token authorization enables READY; Start consumes one attempt credit. Loss enters RETRY_READY and regenerates one credit after three seconds. First-state WON latches permanently for this run. Second-state assignment replaces local play state with CAL_READY → CHALLENGE → LOCKED; it never erases first-state completion. Health ONLINE, STALE or OFFLINE is a separate dimension.
Puzzle state is LOCKED, AVAILABLE, SOLVED or REWARD_PENDING/DELIVERED. SOLVED is durable; a delivery failure does not unsolve the puzzle. Device faults are overlays, not invented puzzle states. Any operator rewind requires an explicit dependency cascade preview; prefer local retry over rewinding a room checkpoint.
11 Authoritative state and event contract
Use a single serialized reducer per room. Validate an observation, deduplicate it, apply guards, append accepted domain events and update the snapshot in one transaction. Commit outgoing commands to an outbox in that same transaction. Publish after commit. The room state is reconstructed from the journal plus a verified snapshot; UI state is never the source of truth.
State group
Required fields
Run
room_id, run_id, schema_version, config_hash, lifecycle, phase, revision, outcome
Timing
active_elapsed_ms, time_limit_ms, hold_reason, remaining local durations, wall timestamps
Configuration
difficulty, party_size, operator_groups, seed, controller_epoch
Cabinets
entity_id, boot_id, assignment_id, attempt_id, mode, first_win, token_authorized, progress, health
Props
puzzle solved/delivery facts; cell identity/charge/location; socket observations; passage state
Calibration
challenge_id, wave_index, targets, station passes, ready set, deadlines
Launch
launch_epoch, armed stations, acknowledged groups, countdown deadline, committed flag
Teddy
mode, current cue, queue, played semantic keys, hint levels and cooldowns
Audit
event revision, actor, reason, overrides, command status, observation freshness
Envelope shared by normalized events
Required: schema_version, event_id, type, room_id, run_id, entity_id, source_id, boot_id, source_seq, assignment_id, occurred_at_ms, received_at_ms and payload. assignment_id is null for non-assignment events. Optional fields include correlation_id, causation_id, actor_id and reason. Controller events use controller identity and epoch. The gateway supplies received_at_ms; a client cannot choose it.
event_id is globally unique; source_seq is monotonic within source_id plus boot_id. Reject a wrong room/run, unknown schema, untrusted source or stale assignment before mutation. A duplicate event returns its earlier result without rerunning effects. Gaps trigger a full-state request; do not guess missed progress. Out-of-order lower sequence reports cannot regress state.
Important invariants
Exactly six distinct first-state wins unlock B07. Seven repeated wins from one cabinet do not.
One cell identity occupies at most one known location. Six occupied sockets without identity validation do not power the ship.
Only the current challenge or launch epoch can accept readiness. A win occurs once per run.
A command acknowledgement is not proof of motion, token delivery, sound playback or passage opening.
12 Signals commands and guard behavior
Normalized signal
Required payload
Acceptance guard
puzzle.solved
puzzle_id, evidence
Puzzle available; trusted adapter or explicit GM override
reward.delivered
reward_id, evidence
Reward pending; identity matches expected token
token.observed
reader_id, token_id
Fresh current-boot scan; correct cabinet; token-wait phase
game.started
attempt_id
Current assignment; credit admitted; cabinet ready
game.progress
attempt_id, value
Current attempt; valid monotonic objective progress
game.won / game.lost
attempt_id, objective result
Current playing attempt; win validated against objective
cell.observed
cell_id, location, present
Known identity/location; debounce and no conflict
passage.observed
open, sensor_id
Trusted current sensor; stable 300 ms
calibration.ready
challenge_id, selection
Expected station; matching current challenge
calibration.execute
challenge_id
Ship navigator; required ready set; deadline open
launch.group_ready
launch_epoch, group_id
Assigned group station; all its stations armed
launch.commit_requested
launch_epoch
Ship terminal; all groups ready; power and health valid
teddy.playback_status
cue_id, status
Current cue; accepted/started/completed/failed distinct
Server-generated events include charge.completed, phase.changed, calibration.passed, launch.committed, hint.eligible, timer.expired and recovery.required. Raw observations do not directly trigger outputs: adapters normalize them; the reducer decides the domain transition.
Normalize selections to discrete integers: Route 0–3, Vector 1–5, Heading 0–7, Shield 1–3, Corridor 1–4 and Thrust 1–4. Godot reports selection plus stable_for_ms with Ready. The room checks target equality and the profile hold threshold; readback alone cannot award a pass. A station must retain its selection until Execute or revoke readiness if it moves.
Commands and acknowledgements
Commands include prepare_assignment, power_on, start_attempt, reset_attempt, set_mode, issue_challenge, arm_station, play_cue, cancel_cue, request_snapshot and invoke_configured_action. Each carries command_id, room/run, target boot/session, controller_epoch, expected state revision, expires_at_ms and typed payload. Return ACCEPTED, REJECTED, COMPLETED, FAILED or DELIVERY_UNKNOWN with a reason code and snapshot revision.
Default acceptance deadline is two seconds and expiry five seconds; boot completion has a separate ten-second deadline. A pure state-setting command may be retried with the same command_id while unexpired. A pulse, release or other physical action with uncertain delivery is never blindly retried; reconcile feedback or ask the GM to inspect. Keep a durable device dedupe ledger across process restarts.
13 Rust NATS and Flutter target architecture
Implement a Rust Glitch domain crate containing a pure reducer, validation and profile resolution. A runtime crate supplies clocks, durable storage and a NATS adapter. Godot communicates through an agreed Rust integration boundary; the current sidecar can prototype it, while GDExtension remains a deployment choice. Each physical driver has one owner.
Component
Authority and responsibilities
Rust room service
Room journal/snapshots, dependency joins, timers, hints, recovery, operator audit and output outbox
Cabinet agent
Assignment validation, game lifecycle, RFID admission, local input, health, durable command dedupe
Prop agents
Claw and token delivery, cell/socket sensing, passage feedback, Teddy playback and configured outputs
NATS
Scoped delivery of observations, commands and state; authenticated clients and explicit permissions
Flutter GM and gateway
Authenticated actions, room map, diagnostic views, subscriptions and revision-aware snapshots
Proposed subjects and persistence
Use a versioned room namespace such as escape_gallery.glitch.v1. Publish observations to obs.<entity>, commands to cmd.<entity>, results to result.<entity> and authoritative snapshots to state.room. The gateway exposes room intent actions rather than arbitrary NATS publishing to browsers. Escape Gallery/Odin subjects and identities remain distinct.
Recommended baseline: a transactional room journal and outbox in durable local storage, plus JetStream-backed observation delivery. Consumers acknowledge only after durable acceptance/rejection recording. Commands use request/reply plus the durable outbox; an expired command is discarded even if delivered later. State snapshots and reconnect reconciliation remain mandatory. Final storage engine and JetStream policy require engineering sign-off; Core NATS alone must not be treated as a replayable journal.
Ordering and leadership
Only one active controller owns the room; cabinets accept its fenced controller_epoch. During restart, enter RECOVERY_HOLD, load committed state, acquire authority and reconcile all agents before accepting play. Do not use two active services writing the same run. Any future failover design must define an exclusive lease and fencing before deployment.
Generate versioned Rust/Dart contracts from the agreed message source; confirm field ordering for MessagePack and enum encodings. The JSON companion is semantic guidance, not the generated protocol. Flutter must show stale state if its subscription drops, fetch a full snapshot on reconnect and use expected_revision on mutations. Reject conflicting operator edits rather than silently overwrite them.
14 Teddy modes scheduling and overrides
Teddy is a character and a control-system output, never an authority that advances game state by speaking. Use authored cues with matching text transcripts. A deterministic cue scheduler selects lines from room facts; generative speech is unnecessary for the initial simulator.
Mode
Behavior and entry
DORMANT
Before run; silent, motors in resting pose
GUIDE
Arrival and discovery; warm, slightly unreliable arcade host
GLITCH
Brief authored interruptions at major wins; no continuous random chatter
REVEAL
Boss victory and ship discovery; voice becomes clear and empathetic
COACH
Calibration tutorial, readback reminders and retry encouragement
LAUNCH
Priority readiness and countdown coordination
HINT
Temporary targeted clue, then return to prior narrative mode
OPERATOR
GM-selected cue or live voice; autopilot narration suspended
FAULT or MUTED
No motor commands; text/room-speaker fallback available
Scheduling rules
Priority order: operational stop message, operator voice, launch cue, reveal beat, requested hint, tutorial, automatic hint, ambient line. Only one voice cue plays at a time. Duck cabinet ambience while speaking; never suppress necessary game feedback. Default minimum gap is eight seconds between noncritical lines; ambient frequency at most one per three minutes.
Each cue has cue_id, semantic_key, required_phase, precondition, priority, max_duration_ms, interruptible, expires_after_ms and transcript. Before playback, recheck the precondition; discard a queued token hint if that cabinet has already started. Deduplicate story beats by semantic_key per run. Playback completion is recorded separately from scheduling.
Override and failure
Flutter offers Preview transcript, Play, Stop, Mute, Set mode, Replay last, Choose hint and Take over voice. Takeover cancels pending automatic speech and uses an explicit release back to autopilot. A stopped cue is not automatically replayed; the scheduler reevaluates whether its information is still needed. A GM skip of the briefing is logged and never skips puzzle prerequisites.
If playback fails to start within two seconds or exceeds declared duration plus two seconds, stop motion, flag FAULT and show the transcript on the ship/arcade display or room speaker. Story progression does not wait for Teddy. If a mandatory tutorial cue fails, provide its text and require the same player practice, not a playback success flag. Motor limits, pose timing and audio interface require bench validation.
15 Teddy script and escalating hints
Cue
Trigger and once-only key
Proposed line
T00 Welcome
Run started; welcome
“I remember this place full of people. The machines remember too. Find their tokens. Each one belongs to only one machine.”
T10 Naming
First first-state win; lesson.name
“One signal restored. Use the name on the cabinet when you call out. Then we all know who you mean.”
T20 Echo
Second win; lesson.echo
“Say the instruction back before you act. These wires do not always hear us correctly.”
T30 Hold
Third win; lesson.hold
“That pattern looks like stars. Keep a good setting steady until someone says to change it.”
T50 Ready
Fifth win; lesson.ready
“Ready means you are waiting for the same moment. It does not mean go.”
T60 Boss
All six won; boss.awake
“The dark machine is listening now. Break through, and we may finally hear who is calling.”
T70 Reveal
Passage open; ship.reveal
“It was a call for help. Bring the six light cores to the ship. Match their symbols.”
T80 Training
Calibration ready; coach.begin
“Navigator, name a station and its target. Operator, repeat it and press Ready. Navigator, check it, then Execute.”
T90 Launch
Countdown entered; launch epoch
“Every station is holding. Crew ready. Five, four, three, two, one.”
T99 Ending
Launch committed; ending
“A signal has become a journey. You gave our visitor a way home.”
Hint policy
Maintain a hint level per active puzzle or challenge: 0 none, 1 orientation, 2 concrete direction, 3 explicit next action. Inactivity means no meaningful progress in that branch; button spam and repeated bad scans do not reset it. Automatic level 1 becomes eligible after the profile threshold. Subsequent levels require another threshold interval or a player/GM request. Default automatic maximum is level 2; level 3 is requested or GM-approved. A hint never marks a puzzle solved.
Example P03: H1 “The music and the sleeves belong together.” H2 “Listen to the short excerpt and compare it with the marked album choices.” H3 “Choose the sleeve whose symbol matches the displayed excerpt cue, then confirm.” Replace H3 with the actual answer after the record puzzle is finalized; do not claim a nonexistent solution.
Example calibration: H1 “Call the station name first.” H2 “The ship has the target; the arcade operator must repeat it.” H3 “Station 3, select NORTH, press Ready, then let the navigator press Execute.” Inject the current target, never a cached one. Suppress hints during reveal/countdown and expire them when the phase changes.
16 Operator dashboard and run operations
Flutter’s primary screen should answer: Where is the team, what can happen next, what is blocking it, and what action is safe for staff to take? Show both the narrative phase and technical lifecycle, active time remaining, party/profile, assistance status and the current next-transition guard.
Panel
Required contents and actions
Run header
Prepare, Start, Pause, Resume, Extend time, Abort, Finish assisted; show reason and audit outcome
Dependency view
Puzzles, tokens, six wins, boss, passage, cells and calibration; each blocked item explains its missing prerequisite
Cabinet tiles
Mode, game, objective, token authorization, attempt, progress, connectivity and latest fault
Ship and cells
Six identities, bay/socket location, charge percentage, sensor freshness and conflicts
Communication
Navigator and operator groups, current targets, ready set, wave deadline and completed passes
Teddy
Current mode/cue, transcript, upcoming cue, hint eligibility, mute and takeover
Diagnostics
Command lifecycle, delivery unknown, agent boot IDs, version/config mismatch and event history
Intervention semantics
Separate Retry current attempt, Restart cabinet process, Override puzzle solved, Confirm delivery, Substitute cell, Proxy failed station and Finish assisted. Each button explains its effects before application. Record staff identity, reason, affected entities and before/after revision. Physical actions show configured device and feedback status. Do not offer a generic “force next” that silently skips unknown dependencies.
Routine play controls may be immediate. Reset room, abort and dependency rewinds require an explicit confirmation displaying what is lost. A hardware action requires an allowed action binding and valid target session. A stale browser may view history but cannot issue state-changing actions until refreshed. Two simultaneous GM actions use optimistic revision checks; the second receives a conflict with current state.
Operational sequence
Before guests: validate inventory and capabilities, confirm cells home, test passage and Teddy, reset all game clients, load a matching release/config hash, then Prepare. At briefing: select party size, difficulty and access options; Start begins the game clock. During play: investigate faults before substituting outcomes. After play: complete debrief, export run summary, then enter RESETTING and follow the physical checklist.
Run summary records elapsed active time, final outcome, hint use, retries, assistance, technical hold duration, per-act duration and unresolved faults. Keep token identifiers out of guest-facing reports; staff diagnostics can use stable logical token names.
17 Reset recovery and degraded operation
Reset transaction
Enter RESETTING and inhibit new gameplay. Cancel cues/countdowns; set outputs to their configured resting states. Archive the old run and create a new run_id only after reset checks pass. Clear token authorization, wins, charge, calibration, hints and launch acknowledgements for the new run. Persist device dedupe history and old-run audit records; clearing them can re-enable repeated physical actions.
Return T01–T06 to their starting locations, reset claw prizes and placeholder puzzle mechanisms, and verify availability.
Return each cell to its own cabinet bay; confirm socket absence and bay identity. Close and latch bays; verify passage show reset independently of egress.
Confirm all seven clients in their initial states, boss dark, ship dormant, Teddy resting, and no pending command or delivery-unknown action.
Run preflight and have the GM acknowledge the physical checklist. A reset button alone does not prove the room is ready.
Fault policy
Fault
Response
Recovery
Cabinet disconnect
Mark STALE after 3 s, OFFLINE after 8 s; hold if active or required by current barrier
Request snapshot; reconcile assignment/attempt and preserve room checkpoints
Agent restart
New boot_id invalidates old targeted commands
Hold; reassign from authoritative room state; never replay an old pulse
Controller restart
RECOVERY_HOLD, recover journal/outbox
Reconcile every required agent and physical state; GM resumes
NATS interruption
Agents retain current visual state; stop accepting new timed work
Reconnect, snapshot, dedupe replay; fresh challenge after resume
Unknown delivery
No automatic repeat of physical action
Inspect sensor/device; confirm or deliberately reissue with reason
Teddy unavailable
Caption or speaker fallback; no room soft lock
Repair independently; resume autopilot only on explicit release
Cell removed
Cancel current wave/countdown; preserve passes
Correct identity reinstalled and stable; fresh challenge/epoch
During any hold, health checks and wall-clock command expiry continue. Physical input observations are recorded but gameplay wins/ready inputs are not accepted. On resume, reissue current intent with fresh IDs where necessary. A completed cabinet can be visually reconstructed as won without granting another reward. A failed station proxy is a logged assisted mode; never hide it as healthy hardware.
18 Simulation harness and reference run
The simulator uses the same reducer and typed contracts as production. Replace NATS/clock/device adapters with a virtual clock and deterministic fake agents for seven cabinets, physical puzzles, claw delivery, six cell bays, six sockets, passage, ship console and Teddy. Fixtures must not open network connections to real props. Simulation mode is prominently shown and cannot be enabled by a production game profile.
Harness controls
Provide advance_time(ms), inject_observation, set_agent_online, restart_agent, delay/drop/duplicate/reorder_message, fail_output, confirm_sensor, snapshot and assert_invariant. Seed objective outcomes and calibration targets. Retain a trace of accepted/rejected inputs, state revisions and outgoing commands. Replay the trace to the same final hash without re-emitting physical effects.
Virtual minute
Stimulus
Expected checkpoint
0
Prepare, preflight success, Start, briefing complete
RUNNING/ARCADE; five independent branches available
2–12
Solve placeholders and confirm T01–T06 delivery
Six rewards recorded; no game is automatically won
4–25
Correct scans, Start and validated wins in arbitrary order
Each first win latches once; charge completes after active time
25
Sixth unique win
BOSS; B07 boot/ready
28
Boss win; release ACK then passage open sensor
REVEAL then CELLS; bay releases requested once
30–36
Confirm bays open, remove cells, insert matching sockets
Ship power stable after 2 s; calibration assignments ready
37–39
Complete two practice interactions
CALIBRATION
40–51
All required waves pass with current targets
LAUNCH_ARM; all station passes retained
52–55
Arm six, acknowledge groups, navigator commit, advance 5 s
launch.committed once; WON and debrief
After
Reset plus physical observations
New run ready; no old event can change it
Minute values illustrate pacing, not a scheduled autopilot script. The golden-path fixture should also run accelerated without waiting 60 real minutes. No assertion depends on speech completing. Test both player-driven Start and permitted GM start controls, while retaining token admission.
Acceptance evidence
For every scenario record fixture version, config hash, seed, initial state, exact input trace, expected events, rejected events and final state hash. The tests below are specified acceptance cases; this GDD does not claim that the room implementation or those tests already exist or pass.
19 End to end acceptance scenarios
ID
Scenario and stimulus
Required assertion
SIM01
Golden path with 6 players, standard
All acts, six cells and two calibration passes; one launch commit
SIM02
2 players, guided; one roaming operator
All six stations completed; no simultaneous multi-station human input required
SIM03
1 assisted player; sequential ship and arcade interactions
No deadlock; clearly assisted outcome/metadata
SIM04
8 players, challenge; six stations active
Unused helper never required for a guard; three passes per station
SIM05
Wrong token, repeated scan, stale historical scan
No credit for wrong/stale; only one authorization for correct scan
SIM06
Lose A03 twice then retry
No extra token needed; other wins and charge retained
SIM07
Duplicate A01 win and missing A06 win
Boss remains dark; unique set count stays 5
SIM08
Claw reward ACK but token delivery jam
Reward pending; GM hand-delivery logged; no duplicate dispense
SIM09
Boss won; passage ACK without open sensor
Reveal hold after 5 s; no assumed opening
SIM10
Wrong socket, duplicate cell identity, missing cell
Ship power guard false; explicit diagnostic per conflict
SIM11
Cell removed during calibration and countdown
Current wave/countdown canceled; completed passes retained; fresh IDs
SIM12
Late Ready for old challenge; Execute exactly at deadline
Both rejected; current wave remains consistent
SIM13
One final group late, then retry
Acknowledgements clear; calibration retained; launch once on valid retry
SIM14
Restart controller after durable boss win before output publish
Recovered outbox sends same command ID; no repeated physical release
SIM15
Agent restarts after uncertain bay release
No blind pulse replay; reconcile or GM inspect
SIM16
Network drop, duplicate and reordered events
No regression/double reward; snapshot reconciliation reaches same state
SIM17
Teddy unavailable or stale queued hint
Fallback text; stale hint discarded; gameplay can finish
SIM18
Pause 5 min; expire action while paused
Active timer frozen; expired wall-time command rejected
SIM19
Time expires in calibration; extend 5 min
TIME_EXPIRED then preserved phase; no automatic normal win
SIM20
Reset and inject old-run win/scan/launch
All rejected; fresh run remains pristine
20 Implementation plan and decision register
Build order and release gates
Milestone 1: agreed generated contracts, Rust reducer, durable run state and a complete fake-prop golden path. Gate: SIM01–13 and SIM17–20 pass.
Milestone 2: NATS adapter, durable command dedupe, recovery and Flutter operator view. Gate: SIM14–16 plus conflicting-GM-action and unauthorized-source tests pass.
Milestone 3: one real Godot cabinet reproduces power, fresh token, Start, retry and win through the final transport. Gate: reconnect/restart produces no old credit or physical action.
Milestone 4: all seven cabinets, calibration variants, cell/socket agents and Teddy. Gate: full run with fake outputs, then each real device accepted independently.
Milestone 5: venue rehearsals for 2, 3, 4, 6 and 8 players. Gate: reset, degraded operation, timing, audibility and physical access verified before public operation.
Decision
Proposed default
Owner and validation
Party limits and duration
2–8 players, 60 min; solo assisted
Room designer; timed small-party walk-through
Cabinets 5–7 and controls
Frogger, Space Invaders, Robotron-style boss
Game/hardware leads; capability validation
Physical puzzle mechanics
Contracts P01–P06 retained
Puzzle designer; confirm token availability and H3 hints
Cell charging and sensing
Virtual 30 s; identity plus presence
Hardware lead; choose sensors and spare procedure
Finale timing
Latched stations; crew barrier; 5 s countdown
Designer/controls lead; test travel and latency
Persistence and transport
Durable journal/outbox plus JetStream observations
Framework owner; retention, schema and recovery review
Godot integration
Rust boundary; sidecar or GDExtension
Framework/game leads; platform lifecycle tests
Teddy interfaces
Authored audio, captions, bounded motion
AV/hardware leads; playback and motor limits
Physical release and reset
Sensor-confirmed actions; inspection fallback
Venue/hardware leads; hardware acceptance
Difficulty balance
Profile defaults in section 8
Playtest lead; completion and hint metrics
Open production decisions do not block the first software simulation. Keep them as explicit configuration values with proposed defaults. Do not encode draft cabinet names, physical pin numbers or one-off test UIDs into the room reducer.
21 Source notes and companion contract guide
Design authority
The user’s Glitch concept and follow-up requirements establish the room premise, six token gates, seventh cabinet, spacecraft rescue, six cells, second-state coordination and Teddy. The user’s October 17 direction makes Rust/NATS and Flutter the final approach. The timing, task names, thresholds, state contracts and scripts in this document are proposed design decisions.
Project material consulted
Project root: D:/Projects/escape-gallery/room_glitch. These local files informed compatibility and migration decisions; they were read, not modified:
README.md — current arcade framework, games, authoring model and known missing room features.
tools/room_controller/README.md and catalog.json — current cabinet assignments, capabilities, scenario structure, operator semantics and reward acknowledgement limitations.
docs/odin_integration/README.md — intended Rust/NATS/Flutter responsibilities, single-controller ownership and corrected BCM23/I2C wiring facts.
labs/glitch_odin/README.md — simulator and Godot-sidecar scope, experimental contract, replay limits and absent durable room orchestration.
labs/glitch_odin/ODIN_MESSAGES.md — generated Odin schema candidates, ordered-field MessagePack distinction and required Glitch-specific messages.
Where the older overview and integration notes differ, use the explicit wiring correction in the integration notes. A documentation statement that a bench test passed is historical project evidence, not a new physical verification performed for this GDD.
Companion file usage
glitch_implementation_contract.json includes design_version, target_architecture, profiles, entity maps, event and command schemas, typed observation payload schemas, an example event, a partial room-state example and simulation_cases. Validate the envelope and its type-selected payload, then apply the semantic guards in sections 11–12. Controller-internal events and complete persistent state types still require generated definitions. No generated Rust/Dart models or existing API compatibility are implied.
All durations use integer milliseconds in the companion. Profile resolution happens once at prepare, then any change is logged at a safe attempt/wave boundary. In simulation, physical puzzle solutions and game outcomes are deliberate fixture inputs; in production, adapters must provide their real evidence. Simulation events must never be accepted from production agent credentials.
Definition of ready for implementation
The first deliverable from engineering should be a full simulated run with visible state transitions and a replayable event trace. Then implement the listed failure scenarios before energizing rewards. The design is successful when a two-person team can finish the full narrative, a restart cannot duplicate an effect, a GM can explain any blocked transition, and a reset reliably produces a clean next run.