Three real-time multiplayer party games, one shared server, one URL
Node.js standard library only — no npm install, no build step, no dependencies
Google Cloud Run container, custom subdomain, in production today
Started as a corporate Family-Feud tournament for a 20-team Employee Appreciation Week; generalized into a public tri-game platform
The problem behind each game
Most party games ship with one assumption baked in: everybody's in the same room, watching the same screen, at the same time. Break any of those three assumptions and most of the genre stops working.
Chris's Questions is three games that each break one:
- Second Guess — a survey-style game with no crowdsourced survey data. You can't run a game show mechanic without an answer key, and you can't afford to poll 100 strangers for every question.
- Dial It In (host mode) — a party game that has to work over a livestream, where the audience is watching the video 5–30 seconds behind whatever the host just said. Speed-based scoring stops being a game and starts being a lag test.
- Dial It In · party — a party game with no host and no shared screen. Two to eight people, one phone each, and no one running the room.
Each game is a different design answer to a different failure mode. Below is how each one solves its own problem.
Second Guess — the AI-authored answer key
For a room with one shared screen. Everybody answers the same question at once from their phone, and you score what the answer was worth.
The constraint
Survey-based game shows work because a production company paid a research firm to ask 100 people what they think about something. That answer sheet is the game. Without it, there's no game — you can't judge whose answer was "worth more" if nobody agreed on what the right answers were.
Independent developers don't have a research budget. So a public version of the genre needs a different way to get an answer key.
The design answer
An AI writes the answer key. Every Second Guess question ships with a set of accepted answers and a weighted score for each one, all authored ahead of time by Claude — not scraped from a real survey, but built to look and feel like one. The game runs against that answer sheet, not against live players' votes.
This inverts the usual mechanic. Instead of asking "what did the crowd say?" the game asks "what did the AI think the popular answers would be?" — and the players are guessing what the AI guessed.
What that made possible
- Every player answers at once, from their own phone. No buzzer, no team turns, no waiting. The bottleneck of a physical buzz-in disappears once scoring is deterministic against a fixed answer sheet.
- The board is a shared screen with the question and a set of hidden answer slots. Answers only fill in as the host reveals them — the board's HTML never contains an unrevealed answer, so nothing can leak through Ctrl+U, screen-share resizing, or a resend of a state payload.
- Ambiguous responses route to the host for review before scoring, so a fuzzy match doesn't quietly award or reject points behind the game.
- The whole system works with no phones at all as a fallback — the host types responses on the board's behalf. Same game, same scoring, same answer key.
Dial It In — the game that works on a livestream
For any size crowd, including a stream. One clue, one hidden spot on the meter, and everybody guessing at once from their phone. Works with four people or four thousand.
The constraint
A livestream audience is watching the video 5 to 30 seconds behind whatever the host is doing. Any game mechanic that rewards being fast stops being a game and starts being an internet-latency test. The person on fiber wins; the person on cellular loses.
The design answer
Nothing in Dial It In is scored on speed. Scoring depends only on how close a guess lands to a hidden spot on a meter — a value between two opposites (overrated ↔ underrated, mild ↔ spicy, useful ↔ useless). The band is chosen by the host; the players guess after seeing the clue; the score is the distance, full stop.
Three deliberate architectural choices fall out of that:
- Polling, not push. The transport is long-polling instead of Server-Sent Events. It survives Cloud Run idle disconnects, corporate-proxy buffering, and wifi-to-cellular handoffs — none of which are edge cases for a live audience.
- Guesses are write-only from the crowd. The viewer's phone is the input device and the video is the only output. There's no client that has to render live state fast enough to match the host — because there's no state a player needs to see faster than everyone else.
- The crowd's mean scores as its own player. An arbitrarily large audience is one entrant on the board, sitting alongside up to a handful of named players. That's how "four thousand people" and "four people at the kitchen table" become the same game.
Dial It In · party — the game with no host
For two to eight people in a room. One phone each, no host and no screen needed. It hands the clue around by itself and stops once everybody has had a turn.
The constraint
Party games at the kitchen table normally need somebody running the room — reading the card out loud, deciding whose turn it is, tallying points. Somebody has to sit out playing to run the game.
The design goal here was: nobody sits out.
The design answer
Self-orchestrating turn rotation. There's no board, no host role, no timer server-side. Each player joins from their phone; the game hands the clue-writing seat around the group in order; when everyone has written one clue, the round ends on its own. All state advances via poll timestamps evaluated on request — no wall-clock timers, no host input required.
Same mechanic as broadcast Dial It In, same server, same answer-isolation architecture. Just a completely different physical setup around it.
What the three games share
All three games run out of one Node.js process, one deploy container, and one URL. Under that surface are a handful of design decisions the whole platform inherits.
Any screen that gets shared to the room (the game board, the group's shared display) receives payloads that literally do not contain unrevealed answers. What isn't in the payload can't leak — no client-side "hide until reveal" that a curious user could bypass.
One deploy hosts up to 20 concurrent games at once, each in its own room, each with its own PIN-gated join door.
Host PIN and editor PIN are separate credentials with separate endpoint allowlists. A small CLI rotates either one at runtime without restarting the server — a restart would clear every room's live game, which is why rotation had to be live.
Product name, wordmark stacking, and company-logo visibility are all driven by environment variables served through /api/config, and applied to the DOM at load time. Same static HTML ships to production regardless of which product name is on the container.
No npm install, no build step, no bundler. Node.js standard library only. Drops onto any Bitnami/Ubuntu box, ships in any minimal container.
Only owned or CC0/OFL assets in the public build — Kenney SFX, Anton and Bebas Neue for wordmarks, no show-branded material. Provenance is documented in the audio credits file, not just implied.
Same codebase, different product names
The three public games share their engine with a private corporate build I wrote earlier for a client's 20-team Family Feud–style tournament. That project ran during a live company event and had to carry the client's company branding.
Rather than fork the code, the product name, wordmark, and company logo all live behind a single small layer: the HTML ships with a default identity, then a client-side script fetches /api/config and overwrites the parts marked with a data-app-title attribute. If the server ever doesn't answer, the page just keeps its shipped copy — a safe direction to fail for a screen that gets projected at a live event.
That lets one repo produce two live deployments — the corporate tournament under one name, the public tri-game platform under another — with no branch and no build-time swap.
Why I'm putting this in the portfolio
Three reasons this belongs in the "custom software" case-study set, not just a projects list:
- Novel game design under real constraints. Second Guess isn't a clone — the AI-authored answer key is the mechanic that made the game legally and operationally possible outside a corporate context. Dial It In's polling transport and write-only crowd input are what let it work on a stream at all.
- Real-time multiplayer, correctly. Answer isolation is an architecture decision, not a client-side
display: none. Multi-room, hot-rotatable auth, and idle-disconnect-tolerant transport are the parts that make it survive being played by strangers at unpredictable times. - Ships publicly, works today. Not a demo, not a slide deck. Load questions.chrisabass.com on your phone right now and you can start a game with the people in the room.
Play it
Pick a room, grab your phone, no install.
Want the build story or the source structure? Get in touch.