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.