DEV Community

Dennys A
Dennys A

Posted on

Marele — a ghost who can only speak through the family computer

Hacktoberfest Open-Source AI Challenge: Ghost in the Machine Submission 👻🌼

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine.

What I Built

Every family has that one old computer nobody is allowed to throw away. In Marele, yours still has someone inside it.

You are the ghost. The AI plays the person trying to repair your computer.

On Día de Muertos, Marycel opens an old family computer to recover a recording for the ofrenda. You are her aunt Elena, trapped inside it, reaching her through its screen, speakers and printer. Marycel decides what to investigate. Something else in the machine is listening.

One signal reaches three parallel versions of the same night. Switch between rooms to watch how each Marycel responds, and discover more ways to communicate as she repairs the equipment. Your signals and her decisions can lead each room toward a different ending.

Demo

Play it in your browser: marele.tech (also at marele.onrender.com). No install. If nobody has played for a while, the first load takes about a minute while the server wakes up.

Watch the Marele demo on YouTube.

Timing varies with the model and the route you take; give Marycel time to investigate. The three Marycels take turns in rounds, so you have time to watch and decide when to reach out. A room waiting for your answer sits out until you answer or its 45 seconds run out.

Code

GitHub logo antunishdPursuit / marele

A Día de Muertos pixel game where a fine-tuned open model plays the technician and you are the ghost in the machine.

Marele

You are the ghost. The AI plays the person trying to repair your computer.

On Día de Muertos, Marycel opens an old family computer to recover a recording for the ofrenda. Elena is trapped inside it. Reach Marycel through the screen, speakers and printer while something else in the machine listens.

Built for Hacktoberfest 2026 Week 4: Ghost in the Machine.

Play at marele.tech · Watch the demo

How to play

  • Watch one room and switch between three parallel versions of the same night.
  • Send a signal from the computer, speakers or printer. It reaches all three rooms; each Marycel notices only what she can see or hear.
  • Unlock more ways to communicate as she repairs the equipment.
  • Answer when she asks for permission. You influence her decisions; you do not control her movement.

The rooms can reach different endings. Their names and conditions are left for you…

MIT-licensed. It includes the game, the rules engine, the training-data generator, the Tinker training and scoring scripts, and the tools that bring the model to a local GPU.

How I Built It

The part I was most excited to build was Marycel herself. I wanted the AI to inhabit the room: choose a tool, investigate a strange signal, and decide what to do next. Tinker let me fine-tune an open model for that job, then measure what changed against the untrained baseline.

The model. Marycel is Qwen3-8B (Apache-2.0) with a LoRA adapter (rank 32) trained on Tinker. Each turn she receives only what she can perceive (the room, the screen, what she heard, her short memory of earlier steps) and answers with one JSON step from a fixed list of actions, plus a short line she says to herself.

The training data. I didn't have recordings of technicians meeting ghosts, so I wrote a rules engine for the three rooms and a generator that plays out whole nights: routine repair work, reactions to Elena's signals, fixes after a step fails, and what to do after each kind of answer Elena gives. The training pipeline replays generated steps through the rules engine. The saved training summary records 240 nights and 4,607 steps, with 0 policy problems at generation time.

Did fine-tuning help? I scored the base model and the fine-tuned model on held-out steps they never trained on, replayed against the game's final rules. 394 of the 419 held-out steps replay under the current rules. The other 25 have earlier events in their history that the current rules refuse, so both models are compared on the same 394 replayable steps.

Base Qwen3-8B Fine-tuned (v2)
Valid by the game's rules 64.2% 99.2%
Same action as a scripted reference 26.6% 75.6%
Attempts a transfer without her yes 23 0

These are checks of saved model predictions (tools/score_steps.py), not a guarantee of every live playthrough. They measure whether her steps follow the rules, not yet how well she responds to Elena: her reactions to Elena's signals match the reference only 59% of the time, and that is what the next version has to improve.

A failure that changed the design. My first fine-tune (v1) was good at the repair work but still attempted the transfer 17 times without Elena's yes in the consent evaluation. That dataset contains 178 steps; 149 replay under the current rules, and the comparison uses those same 149 for both versions. I fixed it in two layers:

  1. The game now refuses a transfer unless Elena has said yes. A warning, "more tests", a no or silence all block it.
  2. A second training round (v2) added many more examples of what to do after each answer. That brought it down from 17 to 2 on the same set, with application rules blocking attempts without consent.

The model still needs more work on character alignment. Consent is enforced by the game rules, so a model mistake cannot grant permission.

Building the world around her. The three rooms are separate states, not three copies of a conversation. Each has its own equipment, positions, observations and history. The room art is built from those object placements on a shared pixel grid: 960 × 224 rooms, a scrolling 640-pixel view, and a common 73-color palette. Marycel's movement and the objects she holds are drawn around the action the rules actually accepted.

Running it. The same checkpoint runs two ways:

  • Locally: I merged the adapter, converted it with llama.cpp, quantized it to a 5.6 GB file and loaded it in Ollama. The repository includes the local Ollama inference path; timing depends on the machine.
  • Hosted: the web version on Render asks the same checkpoint through Tinker's OpenAI-compatible API, prompted exactly as in training. Each visitor gets their own night, and a daily step budget limits the cost (the code supports persistent counting through Render Key Value, with an in-memory fallback).

Sound and voice. Each room has its own music, generated offline with ACE-Step 1.5 (MIT). Marycel's spoken lines are recorded ahead of time with Kokoro (Apache-2.0) using its built-in af_heart voice, so every line is the same voice, and nobody's voice was cloned. Lines without a recording stay as subtitles. Sound effects are synthesized in the browser.

Why Does Open Innovation Matter?

I could change how the AI behaves, not just what I ask it. Prompting alone did not give me the behavior I wanted. With open weights I trained that behavior in, measured it on held-out data, and fixed it when the first version failed.

A local path is included. After dependencies and model weights are installed, the game can use Ollama on a gaming PC instead of hosted inference: model, rules, music and voice. A story about keeping a family's voice safe shouldn't depend on a service that might disappear.

I can control where it runs. Render serves the browser game, Tinker supplies the hosted model, and a daily step budget limits usage. Local inference avoids hosted per-request charges, though hardware and electricity still cost money.

Every piece is reusable. The model base, music model, voice model, converter and fonts all allow commercial use. Anyone can fork the repo, retrain Marycel for their own story, or swap in a different open model.

The Spirit of It

Día de Muertos gave the story its reason for returning to this computer: a recording someone wants to hear again. The horror grows from a question the repairs cannot answer on their own: when a familiar voice returns, how do you know who is speaking?

What I Want to Improve Next

Marycel can't hold a conversation yet. Her training data was generated from templates: Elena's words came from a small fixed set, so Marycel learned to react to those words and to the four answers, not to whatever you type. The game says so and shows the words she knows. Next time I'll write varied, open-ended exchanges first, test them with real players, and measure whether her next step depends on what Elena actually said, not only whether it follows the rules. For now, play in one tab: opening another tab can reset the browser's night.

Prize Categories

  • Best Use of Tinker: Marycel's model is a LoRA fine-tune of Qwen3-8B trained on Tinker, compared with the base model on saved held-out predictions, re-scored on the final rules (394 steps: valid 64% → 99%, same action 27% → 76%, attempted transfers without consent 23 → 0). The hosted game samples the same checkpoint through Tinker.
  • Best Use of Render: Render hosts the game's front end and server, deployed from a Blueprint in the repo.
  • Best Use of a .tech Domain: the game has its own home at marele.tech, pointing to the Render deployment. I claimed marele.tech through the Hacktoberfest partner promotion so people could open the game and play in their browser. Giving this little haunted computer its own address was a satisfying part of the build.

Top comments (1)

Collapse
 
anubhabdaserrr profile image
Anubhab Das •

Woah, such a cool project bro!