-
-
Chat knows. You don't. The Baited landing introduces the game with its animated secret-word round.
-
A real Twitch round: chat sees BANANA in the video Extension while Baity relays the streamer's unconfirmed guess.
-
Two views from the iPhone playtest: the secret BAIT card and the Twitch chat trying to make the streamer say it.
-
18 illustrations from the 100-card deck. Card words and clues are rendered separately so they stay readable.
-
Current Studio: round controls, automatic catch review and Speech Lab access. Local demo shown.
-
Speech Lab: the same recording compared in Whisper Tiny and Moonshine Tiny, entirely on the device.
-
Draw your own bait. Current pixel editor detail from our setup walkthrough, with a local demo drawing.
Inspiration
Every Twitch stream has moments when chat knows something the streamer doesn't, and everyone waits for the reaction. Baited turns that into a game. Chat's secret is one word. An innocent question about dinner might be a trap.
We wanted something that fits around a streamer's game, especially the stretches of waiting or travelling. Chat already supplies running jokes. What if everyone had a reason to work together on one?
Paolo studied Twitch creators, their slang and their relationships with their audiences. We kept coming back to the same thing: the interesting part is the conversation. The extension should give people something to talk about without asking the streamer to stop playing.
What it does
Viewers get an illustrated secret card. The streamer gets its back and a clock. Chat has to make the streamer say the word through ordinary Twitch chat. If the clock runs out, the streamer wins.
For BANANA, somebody might ask what belongs in a smoothie. Harder cards add off-limits clues, so chat has to get more inventive. Viewers can vote to skip, build a shared streak and earn a streamer-selected award for a good clue.
The streamer can fight back with Call the bait. Guess the word correctly and escape. Guess wrong and chat gets another 15 seconds. They can type privately in Studio or use a voice command such as “I am calling the bait, banana, lock in.”
Moonshine listens in the streamer's browser. When it detects the target, a 15-second review window gives the streamer time to reject a mistake before the catch is confirmed automatically. A confirmed catch can also be reversed.
Baity, our chat bot, announces rounds, reacts to results and answers commands for help, scores and the leaderboard. The game also has a 100-card illustrated deck, optional three-word missions, and a Card Maker with custom packs, image artwork and a pixel editor.
How we built it
We built the Studio and game views with TypeScript and React. The hosted backend runs on Cloudflare Workers and SQLite Durable Objects. Each channel has a room that owns its round, timer and score. A separate control object coordinates Twitch authorization, EventSub subscriptions and the bot's outgoing message budget.
Twitch chat reaches us through EventSub webhooks. Authenticated WebSockets carry game updates to clients. The server sends different views of the same round: the viewer receives the secret; Studio and OBS do not receive the active target.
That distinction matters. The OBS Browser source is a public round HUD recorded into the stream. The native Twitch Extension sits over the player or in its panel and mobile views. Twitch identifies the account, so viewers get the word while the broadcaster gets the card back until the round is decided.
Moonshine runs locally in a browser worker with WebAssembly. Raw microphone audio stays on the device. Final text and timing reach the server for matching; it does not retain a full speech transcript. Speech Lab compares the same recording with Moonshine and Whisper Tiny, independently of the game.
We used OpenAI Codex throughout development: exploring Twitch APIs, implementing the game, writing regression tests, comparing hosting costs, and fixing problems while people were actually streaming. We directed the visual design through repeated team reviews with Codex, generated pixel-art illustrations with ChatGPT image generation, and kept card text separate from the images so it remains readable and editable.
Challenges we ran into
Our most useful bug reports came from playing.
A streamer could say “I'm calling the bait,” pause, then say “banana.” Speech recognition delivered two separate phrases. The game needed to remember the command intent instead of treating the next phrase as an accidental catch. Fast commands, misheard wake phrases and “lock in” arriving separately created more cases. We turned those transcripts into tests and improved the parser. Recognition can still miss words, which is why review and reversal controls matter.
We also had to handle microphone interruptions, stale OBS connections and the difference between a working local preview and a working native Extension. On iOS, accepting Twitch's general extension notice was not enough: the viewer also had to accept the test Extension itself.
Live feedback changed the product. Manual confirmation became automatic confirmation with a rejection window. Skip voting became easier to understand. We made microphone state and recovery clearer, and brought the transcript where the streamer could inspect it.
What we're proud of
We have played real rounds with remote viewers, Twitch chat, physical microphones and OBS, including the native Twitch app on iOS. Chat landed clues, streamers called the bait, wrong guesses bought chat more time, and a few last-second catches produced exactly the reaction we wanted.
Speech runs on the streamer's device. The backend decides the game and protects the secret. We researched and modelled scaling and cost before choosing this structure; we have not benchmarked large-scale production traffic.
What we learned
We learned how Twitch's chat, authorization, Extensions and broadcasting surfaces fit together. Watching people play taught us where the interface interrupted the conversation. A streamer juggling a game and an audience needs useful defaults, clear recovery and very few extra clicks.
Codex was most useful when the loop was concrete: play a round, save the failing transcript or screenshot, reproduce it, fix it, and test again with the streamer.
What's next
We want more community-made decks, cards in multiple languages, and stronger voice-command testing across accents and devices. We also want to measure the hosted pilot before expanding it. The goal stays small and specific: give chat a shared joke worth setting up, and the streamer a chance to catch them doing it.
Try it
For a credential-free local test, use Node 24 and pnpm 10.34.3, then run from the repository root:
pnpm install --frozen-lockfile
pnpm --filter @baited/app build
pnpm preview:local
Open http://127.0.0.1:3318, choose Try the local demo, and open the viewer-room link in another tab. Demo controls simulate chat and speech; you can also enable your microphone for Moonshine. The repository's judge walkthrough covers the rules and native-view fixtures.
The native Extension has been tested in Twitch Hosted Test. It is not a public directory release. Another native session needs arranged tester access, an allowed broadcaster channel and the correct installed, activated version. Viewers must accept the test Extension in Twitch. Contact [email protected] to arrange access.
Links
Built With
- chatgpt
- cloudflare-durable-objects
- cloudflare-workers
- express.js
- javascript
- moonshine
- node.js
- obs-studio
- openai-codex
- react
- sqlite
- twitch
- twitch-eventsub
- twitch-extensions
- typescript
- vite
- web-audio-api
- web-workers
- webassembly
- websockets

Log in or sign up for Devpost to join the conversation.