Inspiration
An empty chat does not mean an empty room.
Small streamers can be talking to people who are listening, enjoying themselves, and choosing not to type. A viewer count tells the streamer how many people Twitch reports, but it cannot convey a simple human message: "I'm here."
Lamplight gives that message a shape. One emote lights a lamp. Returning viewers find the same lamp waiting for them the next time they visit.
What it does
Lamplight is an OBS browser source overlay that turns lightweight participation into a persistent windowsill of lamps.
A viewer posts one emote, one emoji, !lamp, or !lurk to light their lamp. Its appearance is generated deterministically from their Twitch user ID, so the same person gets the same lamp across streams. Returning lamps grow with lifetime attendance. Lamps from earlier streams remain dim: a visible memory of who has been there.
Everything else is optional:
- Threads. Viewers connect their lamps with !tie. A thread persists across streams and records how many streams both people have attended together.
- Promises. !back expresses an intention to return, with no penalty for missing a stream. A kept promise gives the next stream's constellation progress a small head start.
- A shared sky. Reaching an attendance threshold earns a constellation fragment. The threshold scales automatically with the channel. Together, the community gradually builds a sky.
- Private presence receipts. Each completed stream produces a local attendance record containing return visits, promises, threads, and Twitch viewer count samples alongside lamp participation. There is no leaderboard, no ranking, and no bot chatter. Feedback lives on the overlay.
How we built it
I'm a chartered accountant, not a developer, and I built Lamplight as a solo entrant with Codex. I made the product decisions, tested it on my own Twitch channel, and kept asking two questions: Does this help a quiet viewer feel present? Does it stay out of the stream's way?
Codex first wrote SPEC.md and DECISIONS.md from my plain-language brief, and I corrected them before any code existed. The first technical milestone was receiving a real chat message from my channel through Twitch EventSub. This proved the riskiest connection before we invested in the visuals.
After that, Codex built the product milestone by milestone, and I tested each one on my channel before work on the next began. Later in the project, Codex captured the overlay frame by frame with Playwright, reviewed the frames, and reported what looked wrong before I decided what to change. Every decision we made together is recorded in DECISIONS.md.
Lamplight uses Node.js, TypeScript, WebSockets, and a plain HTML, CSS, and Canvas 2D front end. Twitch login uses the authorization code flow with automatic token refresh, while a local control page manages settings, roll calls, and receipts.
The log is the ledger, and the snapshot is derived from it. Events form a SHA-256 hash chain, the state can be rebuilt from the ledger, and a verification command checks its integrity. Receipts remain on the streamer's machine.
All lamp and sky artwork and motion are generated in code. The only bundled assets are the Space Grotesk font under the OFL and constellation star positions from the d3-celestial dataset under its BSD licence, with the relevant licence texts included in the repository. There is no LLM at runtime. The narration in the demo video was generated with ElevenLabs.
Challenges we ran into
The hardest problems involved timing and trust.
A lamp must arrive in its final position without jumping when the row rearranges. A constellation animation must end in the state that the server actually recorded. A card cannot announce how many people have returned at the moment a stream starts, before anyone has had time to arrive.
Testing on a real channel exposed issues that isolated tests could not: a panel that looked readable in a browser disappeared against the stream content, and thread lines that existed in the state were too faint to see.
We added deterministic demo replays, regression tests, and browser captures to inspect these transitions. We also tested density, reduced motion, privacy, and state reconstruction after a restart.
Accomplishments that we're proud of
Lamplight works on the real Twitch platform, with real viewers lighting lamps and returning across streams.
The lamps have distinct procedural identities without relying on external artwork. The overlay preserves those identities while keeping participation within a narrow band and a corner panel.
I'm especially proud that the accounting-inspired foundation supports the emotional experience: the memory is backed by an inspectable event history. A receipt records participation rather than inventing a recap.
The current build passes 127 automated tests, along with the TypeScript build and a repository secret scan.
What we learned
Quiet participation deserves its own design.
Adding more interactions is easy; making the first interaction sufficient is harder. One emote has to feel complete on its own. Threads, promises, and the sky should add meaning without becoming obligations.
Automated tests and live testing answer different questions. Tests can prove that a thread exists. Watching a real stream tells you whether anyone can see it.
Working with Codex taught me how much a non-developer can contribute through precise requirements, explicit trade-offs, and careful testing. My job was to decide what the product should mean and to challenge anything that did not match that intention.
I do not yet know whether lightweight presence makes viewers return. No study demonstrates that outcome. Lamplight is a working experiment in making quiet participation visible, not a claim that viewer retention has been solved.
What's next for Lamplight
The next step is testing with more small streamers and their communities: determining whether the lamps feel welcoming, whether the overlay remains unobtrusive, and which optional interactions people actually want.
Future possibilities include a private viewer record accessed through Twitch login, a !me command, threads that reach across channels, Channel Points as an alternative trigger for affiliates, and a packaged, one-click installation.
The core remains simple: one emote lights your lamp. Everything else is optional.
Built With
- codex
Log in or sign up for Devpost to join the conversation.