Twungeon · Devlog

Private operations arrive with graceful viewer disconnects

Twungeon gained a private, authenticated operator console and last-socket disconnect handling that sends absent viewers directly into AutoGuard instead of delaying every player phase.

Live multi-viewer testing revealed an awkward failure mode: when a viewer left the channel, their character remained in the dungeon with unspent action points. Keeping the character was intentional because a refresh or temporary network failure should not destroy a viewer's progress, but waiting for its action-point deadline made each later player phase appear stuck.

Twungeon now tracks authenticated WebSocket connections per Twitch user. A viewer is marked disconnected only after their final socket closes, so a second tab remains valid and closing one of several connections does not incorrectly end the turn. On the last close, unused action points immediately become Guard. Extension-bound characters that remain disconnected also enter AutoGuard as each later phase starts. Their characters stay on the board for a safe reconnection while connected viewers can complete the phase normally.

The same milestone adds a private operator console for live troubleshooting. It runs on a separate listener rather than the public Twungeon origin. The production listener binds specifically to 10.138.4.44:3001, and the application rejects source addresses outside 10.138.0.0/16. Basic authentication, a unique generated deployment password, per-process form tokens, no-store responses, a restrictive Content Security Policy, and frame denial provide additional boundaries. The port is not exposed through the public web listener or reverse proxy.

The server-rendered console shows the current run, floor, phase, players, Twitch readiness, OAuth authorization, uptime, and the latest 40 action-log entries. An operator can disconnect a viewer into AutoGuard, remove a character, end the active player phase, or reset the run. These operations call the same authoritative game core used by viewer commands and broadcast the resulting snapshot to connected clients.

Configuration remains opt-in. The admin listener will not start unless it is explicitly enabled with a 10.138.x.x bind address and a password of at least 16 characters. Operator documentation records the environment settings, network boundary, authentication flow, and the requirement not to publish or proxy the private port.

Validation covered linting, strict type checking, a production build, 28 domain tests, and 13 integration and end-to-end tests. Deployment checks confirmed that the public service and Twitch adapter were ready, authenticated admin health succeeded on the private address, unauthenticated access was rejected, and the admin port was not listening on loopback.

The private operations and graceful-disconnect implementation is recorded in commit 8b1d14dceac8f9645f70cab106a045ed64bcd71c.

View the complete Twungeon devlog →