Inspiration

Stream Together and Shared Chat put two communities in one room, but most collab content still treats the second chat as an audience for the first. I wanted a game where neither chat can win alone, so the two communities and the two streamers actually have to talk to each other.

What it does

Twinclue is a cooperative puzzle show for Twitch collabs. Every round has one answer and two halves of a clue. Streamer A's overlay shows one half, streamer B's overlay shows the other, and neither half is enough on its own. For example, one chat sees "a country in Asia with red in its flag", which fits China, Türkiye and more. The other sees "a monarchy that has hosted the Summer Olympics", which fits Spain, Sweden and more. Only Japan fits both.

Viewers vote in their own chat with !g answer. Each community's votes build a live lock-in meter on its own overlay. Halfway through the round a swap banner tells the streamers to read their halves out loud to each other, which is where the best moments come from. A round is won only when both communities lock in the right answer, with at least two voters on each side.

Both overlays during one round: each side sees only its half, the streamers are told to swap clues, and both chats lock in Japan

Around that core:

  • A real Twitch integration. One bot account reads both chats over EventSub WebSocket, follows Shared Chat (so a message seen in both chats is counted once), and posts round results through Helix Send Chat Message within Twitch's rate limits.
  • Fair voting. One person votes for one community per round, rapid vote flipping is rejected, and a consensus lock (60 percent of at least three voters, held for five seconds) can end a round early.
  • A !hint vote. When enough of a community asks, its extra hint line unlocks on its own overlay only, at the cost of a point.
  • A control panel with keyboard shortcuts, a rehearsal mode for practising without a partner, an OBS dock, and a session recap page the bot links in chat at the end.
  • Audited puzzles. A Puzzle Forge builds clues from curated fact tables. A blind panel of solver models then checks that each half alone is not enough and both halves together are. A two-model fact check makes sure the facts are true. 35 puzzles passed and ship in the pack.
  • A hosted sandbox where anyone can play both chats in one browser tab, with no Twitch login.

How I built it

I wrote the product brief (SPEC.md) and the build rules (AGENTS.md) before any code, then gave Codex one vertical slice at a time in a single thread. AGENTS.md acted as its constitution:

  • strict TypeScript;
  • tests for every module;
  • Twitch and the models behind interfaces, so tests use fakes;
  • no secrets in logs;
  • every decision written into DECISIONS.md.

Codex built slices 1 to 5c in that session: the game core and referee, the Twitch OAuth, EventSub and chat layer, the blind puzzle audit, the first overlays and control panel, the demo mode, community lock-in voting and the Puzzle Forge. Across 4 h 28 min of work it ran 541 commands and 66 test runs, and every slice ended green before I committed it.

When my Codex plan reached its usage limit, another AI coding assistant continued under the same AGENTS.md rules. It built production hardening, the overlay redesign, the hint vote, the recap, the sandbox and this build replay. CODEX.md in the repo lists every commit and who built it.

So that nobody has to take this on trust, the project replays its own Codex session. Open /codex on the sandbox to see every Codex turn: the brief it was given, every message it wrote, every command with its exit code, and every test run. The replay is generated from the raw codex exec --json logs and sanitised, and a test fails the build if any secret slips into it.

Challenges I ran into

The hardest part was making clues that are really fair. My first approach let a model write free-text clues, and the audit kept finding halves that gave the answer away on their own. I switched to building clues from fact tables with a constraint search, so fairness is checked before a model ever words the clue.

Live Twitch had its own surprises. Shared Chat sends the same message to both channels, so votes are deduplicated on the source message ID. Chat sends are budgeted against both of Twitch's limits at once, and the overlay keeps working through EventSub reconnects.

Accomplishments I'm proud of

  • It runs live on two real Twitch channels streaming at the same time, and the video shows it. A vote typed in one channel's chat lands on that channel's overlay inside the Twitch player, a !hint ask moves the counter, and the bot posts the round start and result in both chats. Those runs used my own two accounts, one voter a side, so the rounds did not score; Twinclue needs at least two voters per community before a round counts, and both the overlay and the bot say so.
  • I benchmarked the pipeline with a local fake EventSub server: 100,000 distinct chatters at 2,000 messages a second, plus a 10,000 per second burst. Every planted vote was counted exactly once, and overlay latency was 99 ms at p99. This measures my code, not Twitch's delivery, and the benchmark page says so.
  • 168 tests, including fault injection and a log-safety test.

What I learned

Giving an AI agent one slice and a written constitution works far better than one big prompt. The DECISIONS.md log was what let a second session, or a second assistant, pick up the reasoning and not just the code.

What's next

  • Custom fact tables per community, so a cooking stream and a speedrun stream can play puzzles about their own world. The CSV format already works.
  • A Twitch Extension version for viewers who want the clue in a panel as well as on stream.
  • Collabs of three or more channels, each holding a third of the clue.

Try it

Built With

Share this project:

Updates

Submission history