The candle: Spooky experience with Gemma 4
This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine
What I Built
The Candle is a small haunted room in your browser. There's one candle on the floor of an old mansion's drawing room. Blow into your microphone (or hold the mouse near the flame) and it goes out. In the dark, something answers.
Five restless ghosts live in the house. Each one has its own voice, its own backstory, and a secret it won't give up easily. You talk to them by choosing replies written on scraps of old paper, and the scrap you pick burns as you say it. Relight the candle and the ghost is gone, and the next time it goes out, someone else may be waiting.
The ghosts know each other. Every conversation gives you a piece of what happened in this house, and you only get the whole story by asking the right questions, to the right ghost.
For the "Ghost in the Machine" theme, I took it literally: the voice in the dark is an open-weight model.
Demo
Try it live (use headphones, and let it have your mic if you want to blow the candle out for real):
Code
dumnicki
/
the-candle
A spooky virtual experience made for Hacktoberfest Open-Source AI Challenge: Week 4
Ghost in the Candle
A dark room, a candle, and a ghost that answers in its own voice. This is a DEV Hacktoberfest Open-Source AI Challenge week 4 project ("Ghost in the Machine"). The plan, including the Gemma 4 and Backboard notes, is PLAN.md.
Gemma 4 writes the ghost's line and both replies. Backboard is the default client and is pinned to the open-weight model google/gemma-4-26b-a4b-it through OpenRouter. Ollama (gemma4:e4b) and any local OpenAI-compatible server can take that place. ElevenLabs is the default voice, behind the same kind of swap, with a Piper stub for the open fallback.
The files in ghosts/ contain each ghost's secret. Reading them spoils the story.
The page is a quiet room with a candle. Blow into the microphone, or hold the left mouse button and bring the cursor close, and the flame goes out. A ghost is chosen at random. You…
MIT licensed. Fair warning: the files in ghosts/ contain every ghost's secret, so reading them spoils the story.
How I Built It
- Gemma 4 writes the ghosts. Every line and both reply options come from Gemma 4 (google/gemma-4-26b-a4b-it), called through Backboard, which also keeps each conversation's thread so the ghost remembers what you've said. The model never sees more than one ghost's profile: its personality, its ties to the others, and how much of its secret it's allowed to reveal at this point in the conversation.
- ElevenLabs gives them a voice. Each ghost has its own library voice and room effect, from a small room to a long tunnel, and the lines carry emotion tags like [whispers] or [sighs] that the voice actually performs.
- *The room is plain TypeScript. A Vite front end with no framework: a painted background, a candle whose flame bends with your breath or the cursor, a flickering glow, and random creaks and footsteps over a quiet room-tone loop. The server is a small Hono API.
- It's hosted on Render as a single web service that serves both the API and the room. The hardest part was the moment the candle goes out. The first spoken line can take a while to generate, so instead of showing a spinner, the game uses the wait: the room goes fully dark, you hear something arrive, and a line like "You feel shivers down your spine" fades in. By the time you're unsettled, the ghost speaks.
The game also degrades gracefully. With no voice key it plays with subtitles only.
Why Does Open Innovation Matter?
Because the ghost doesn't have to live in someone else's cloud. Gemma 4 is open-weight, so the same house can run on Ollama on my own machine with the network turned off, and the ghosts still answer. The model is swappable behind one small interface, and so is the voice. Piper is wired in as the open speech fallback, though it's still a stub.
Open models made this project possible to build in a week, by one person, for free, and I could see and change every piece of it.
The Spirit of It
The best moment is the second right after the flame dies. The room is black, the voice hasn't arrived yet, and you're not sure if anything will. Then someone speaks, and they remember things. I wanted that feeling of a house that's been waiting a long time for someone to sit down and listen.
Prize Categories
- Best Use of Gemma
- Best Use of Backboard
- Best Use of ElevenLabs
- Best Use of Render