Brotator Tracker

Brotator Tracker

A real-time stream overlay that tracks challenge progress and keeps every connected viewer synchronized.

> GenreStream Overlay
> EngineNode.js / WebSockets
> RoleFull-Stack Developer
> StatusFull Release

About the Project

Brotator Tracker is a browser-based progress overlay built for a complete character challenge in Brotato. It gives stream viewers an immediate view of the previous, current, and next character while displaying overall run progress in a compact 500-by-200-pixel layout.

The tracker is designed to run as a browser source in streaming software. Progress changes are persisted on the server and broadcast to every connected overlay without requiring a page refresh.

What I Built

  • A focused three-character overlay for previous, current, and next states
  • Real-time synchronization with WebSockets
  • Persistent character order and completion state in JSON
  • Authenticated actions for advancing, undoing, and clearing progress
  • Reordering endpoints for adjusting the active challenge sequence
  • Automatic WebSocket reconnection and server-side keepalive messages
  • A custom character dataset with more than 60 image assets
  • Node 20 and Docker packaging for repeatable deployment

Technical Structure

An Express application serves the static overlay and exposes the control endpoints. A shared HTTP server also hosts the WebSocket server, allowing API actions and live updates to operate on the same in-memory state.

function broadcastUpdate() {
  const message = JSON.stringify({
    type: "update",
    characters,
    progressIndex,
  });

  clients.forEach((client) => client.send(message));
}

The ordered character array and progressIndex define the complete tracker state. After a state-changing action, the server updates every character’s completion flag, writes the result to characters.json, and broadcasts a snapshot to connected clients.

Design Decision

The client renders only three characters instead of the entire challenge roster. This keeps the overlay readable at stream scale and makes the current goal visually dominant. Sending complete state snapshots over WebSockets also keeps the client simple and allows newly connected viewers to render immediately.

For this small dataset, synchronous JSON persistence is straightforward and dependable. A larger multi-user service would benefit from asynchronous storage, environment-based secrets, stricter input validation, and a database-backed state model.

What I Learned

The project connected several concerns that are often developed separately: HTTP controls, persistent state, real-time broadcasting, reconnecting clients, CORS restrictions, and container deployment. The main lesson was that a live overlay needs recovery behavior as much as rendering logic; clients must be able to reconnect and reconstruct the current state without manual intervention.

Development Notes

The devlog explores the real-time state flow and deployment decisions in more detail:

Read the Brotator Tracker devlog