Inspiration

A raid is the biggest moment of arrival a Twitch community has: a whole audience lands in chat at once. Most of the time that moment is a handful of "welcome raiders" messages that scroll away in seconds. I wanted the welcome to be something the whole chat does together, and something the stream remembers.

What it does

When a raid arrives, chat gets 30 seconds to type !welcome.

  • Each chatter counts once. Spamming doesn't help. What counts is how many people show up.
  • The goal scales with the raid, so small streams and big streams can both win:

$$\text{goal} = \min\left(8,\ \max\left(1,\ \left\lceil \frac{\text{raiders}}{4} \right\rceil\right)\right)$$

  • As welcomes come in, the Welcome Wisp builds up on the stream overlay.
  • Hit the goal and the Wisp stays on stream as a keepsake of that raid. If time runs out, chat still keeps a partial Wisp, so small communities never walk away with nothing.

How I built it

I built the whole project in a single OpenAI Codex thread.

  • Server: Node.js, with routes, JSON endpoints and live updates to the overlay.
  • Twitch: OAuth with the user:read:chat scope, token refresh, and EventSub over WebSocket for channel.raid and channel.chat.message. The app only reads chat and never posts.
  • Game rules: the 30-second round, raid-size goal scaling, one welcome per chatter, and exact !welcome matching.
  • Overlay: an OBS browser source with live progress, a countdown and the Welcome Wisp.
  • Control page: the streamer's view, with a goal preview, a raid simulator and demo chat, so anyone can try it without a live stream.

Codex also handled the edge cases: a second raid arriving mid-round, clearing the old keepsake, reconnecting EventSub when Twitch moves the WebSocket session, and rejecting malformed requests.

What I learned

  • Count people, not messages. Counting distinct chatters changes the feel completely: it becomes a group effort instead of a typing race.
  • Fairness has to scale. A fixed goal punishes small streams, so the goal grows with the raid but is capped, so a big raid doesn't become impossible.
  • Twitch's EventSub over WebSocket is a clean way to build a local tool. There's no public server, and it just runs alongside OBS.

Challenges

  • You can't trigger a raid on demand. To build and test it, I added a raid simulator to the control page. Chat comes through Twitch live, and raids can be simulated for testing and demos.
  • Overlapping raids. A second raid can land while a round is still running, so the rules had to decide cleanly what happens to the round already in progress.
  • Keeping it safe. The control page has no login, so it's designed to run locally next to OBS, never exposed publicly.

What's next

A shelf of Wisps: one for every raid a community has welcomed, so a channel can look back at its own history of growing.

Built With

Share this project:

Updates

Submission history