home-server/services/observer-effect/README.md

67 lines
2.7 KiB
Markdown
Raw Normal View History

2026-06-15 21:22:41 -07:00
# Observer Effect — doomsday clock
A period-styled (1964) clock for running Delta Green: *Observer Effect* online.
- **Player screen** — `observer.ellie.town/` (`clock.html`): an Olympian Holobeam
Array master chronometer. Nixie tubes counting toward 22:03:37, warning lamps
that flash on each pulse, a red wash and dissonant flutes/drums as communion
nears. Read-only; safe to share with the players.
- **Handler panel** — `observer.ellie.town/control` (`control.html`): run/hold,
scrub the clock, jump to any scenario beat, set the iteration (which resets
reality to its wake point), and fire pulse / communion / text effects on the
players' screen.
## How it syncs
A tiny Rust WebSocket relay (`relay/`) holds the one authoritative clock. The
panel sends authenticated commands; every connected screen gets the new state
and free-runs the digits locally between actions. Late joiners get the current
state immediately. Served behind nginx with TLS; the relay only listens on
loopback.
## Deploy
1. DNS: point `observer.ellie.town` at the VPS (A/AAAA). ACME does the cert.
2. It's already wired into `flake.nix` (vps modules) as
`./services/observer-effect.nix`. Rebuild the VPS:
`nixos-rebuild switch --flake .#vps` (however you normally deploy).
## The control key
Commands are authenticated with a shared token in `services/secrets/observer_vps.yaml`
(sops). Enter it once in the panel's **CONTROL KEY** field (saved in that
browser). Rotate any time with `sops services/secrets/observer_vps.yaml` then
rebuild.
## Running a session
The clock starts paused at iteration I, 17:00:00 (the Agents' arrival). Drive it
by hand to match table pacing — **JUMP TO BEAT** for the scripted moments, or
**RATE ×N** + **RUN** to let it tick. Fire **PULSE** on the live shudders and
**COMMUNION** at 22:03:37; then hit **ITERATION II/III/IV** to reset reality
nearer the end as the loop tightens. **SHOW** broadcasts a line of text over the
players' screen (e.g. *"I see the throne of God."*).
## Sound effects
The player screen's pulse / communion / broadcast-text sounds are pre-rendered
mp3s in `site/sfx/`, synthesized from pure ffmpeg `lavfi` filtergraphs (no
samples). Regenerate with:
```sh
cd site/sfx && nix-shell -p ffmpeg --run ./generate.sh
```
If a file fails to load the screen falls back to an equivalent WebAudio synth.
The ambient dread drone is always synth (it's driven by the tension level).
## Local dev (no Nix)
```sh
cd relay
OBSERVER_TOKEN=test cargo run # relay on 127.0.0.1:8770
# serve ./site on :8080 and proxy /ws -> 127.0.0.1:8770, or just open
# site/clock.html and append ?, then point common.js' WS at ws://localhost:8770/ws
```
The pages connect to `wss?://<host>/ws`, so behind nginx everything is same-origin.