DEV Community

Cover image for Ghost in the Code: Offline Séance with Programming Language Spirits
Arjan kc
Arjan kc

Posted on

Ghost in the Code: Offline Séance with Programming Language Spirits

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

Ghost in the Code — Every language leaves a ghost behind.

It is a local-first educational game that feels like an abandoned computer coming back to life. You summon fictional spirits inspired by historical programming languages — COBOL, BASIC, and Assembly — inside a phosphor-green haunted terminal. They teach, tease, and help you Exorcise the Bug: curated debugging mysteries with deterministic scoring.

The defining constraint: after you install Ollama and pull the model, core play works without the internet. There is no cloud AI fallback. Prompts stay on your machine. Progress, XP, quests, relics, and chat history live in localStorage.

This is the challenge’s own idea made literal — “an offline séance chatbot that channels the spirit of a long-dead programming language” — turned into a playable RPG rather than a themed chatbot skin.

What you can do

  • Boot the CRT terminal, summon a ghost, and talk about programming / computing history
  • Solve six local debugging cases (loops, conditionals, state, recursion) with hint penalties
  • Earn XP, levels, titles, combos, daily streaks, ghost affinity, quests, and unlockable relic themes
  • Hear procedural Web Audio (no sound files, no CDN media)
  • Fail safely: model output is plain text; answers are never eval’d or shelled out

Default model: qwen2.5:1.5b (~986 MB, Apache-2.0) — chosen for a GTX 1050 Ti / 16 GB RAM class machine. Swap via .env.

Demo

This is intentionally not a hosted SaaS demo. Judges (and you) run it locally:

Repo: https://github.com/arjankc/ghost-in-the-code

git clone https://github.com/arjankc/ghost-in-the-code.git
cd ghost-in-the-code
copy .env.example .env
npm install
ollama pull qwen2.5:1.5b
npm run dev
Enter fullscreen mode Exit fullscreen mode

Open http://127.0.0.1:5173

Three-minute path:

  1. Finish the boot sequence (click / Enter) — audio unlocks on first gesture
  2. Confirm LOCAL AI READY, summon COBOL, ask why teams rewrite working systems
  3. Open Exorcise the Bug → The Off-By-One Lanterns → hint optional → submit day <= 10
  4. Watch score burst, XP pop, quest/achievement chatter in the Chronicle
  5. (Optional offline proof) disconnect Wi‑Fi and send another prompt — Ollama on 127.0.0.1:11434 still answers

No login. No API keys. If Ollama is missing, the setup screen explains the gap instead of silently calling a cloud model.

Code

GitHub logo arjankc / ghost-in-the-code

Every language leaves a ghost behind. Local-first AI haunted terminal for Hacktoberfest Week 4.

Ghost in the Code

Every language leaves a ghost behind.

A local-first AI educational game for the Hacktoberfest Open-Source AI Challenge (Week 4: Ghost in the Machine). Summon fictional spirits inspired by historical programming languages in a haunted terminal, learn concepts, and Exorcise the Bug — with inference running on your machine through Ollama.

Features

  • Phosphor-green haunted terminal UI (CRT-inspired, local assets only)
  • Boot sequence, floating ghost portraits, particle FX, and score bursts
  • Procedural Web Audio SFX + ambient hum (no audio files / CDNs)
  • Three characters: COBOL, BASIC, and Assembly
  • Local open-weight chat (no cloud AI fallback)
  • Six curated debugging mysteries with deterministic scoring
  • Full local RPG layer: XP, levels, titles, combos, daily streaks
  • Ghost affinity meters, quest board, unlockable relic themes
  • Chronicle + stats, level-gated advanced cases, achievements
  • Typewriter replies, boot sequence, procedural audio, ? help
  • All progress in localStorage (no accounts / cloud…

Worth a look:

  • server/ollamaAdapter.ts — localhost-only runtime/model status + chat
  • src/characters/ — COBOL / BASIC / Assembly as data (prompts, greetings, accents)
  • src/puzzles/ — curated cases + deterministic validators (AI never scores)
  • src/game/ — XP, quests, relics, combo / streak engine
  • src/services/audio.ts — procedural SFX + ambient hum
flowchart LR
  ui[ReactHauntedTerminal] -->|proxy /api| api[ExpressLocalhost]
  api --> adapter[OllamaAdapter]
  adapter --> ollama[Ollama_qwen25_15b]
  ui --> storage[localStorageRPG]
  ui --> puzzles[DeterministicPuzzles]

How I Built It

Week 4’s theme is thin places between past and present. Programming languages are that: COBOL still runs ledgers; BASIC taught a generation; Assembly still lurks under everything polite. I wanted players to feel that history without pretending the model has real memories — every generated reply is labeled as fiction.

Local AI as the product, not a badge

Hardware was the design brief: NVIDIA GTX 1050 Ti (4 GB) and 16 GB RAM. That ruled out “just pull a 7B and hope.” Defaulting to qwen2.5:1.5b kept CPU/partial-GPU inference realistic. The app never auto-downloads multi‑GB weights; the README and setup screen ask the human to run ollama pull.

Architecture stays boring on purpose:

  • Vite + React UI on localhost
  • Tiny Express API bound to 127.0.0.1
  • Ollama only at a configured local URL — clients cannot inject a remote endpoint

That pattern matches what local-AI builders keep rediscovering: a thin Node bridge to Ollama is enough for private, offline chat without renting a cloud brain (privacy-first local assistant writeups on DEV; offline AI stacks that actually run today).

Game first, model second for fairness

Small models are wonderful séance partners and terrible judges. So Exorcise the Bug uses version-controlled puzzles and string-normalized validators. Hints can be narrated by the ghost; score is always deterministic (100 / 75 / 50 / 25). That keeps the educational loop honest when the spirit rambles.

Then I leaned into gamification — still 100% local:

  • XP, levels, titles, combos, daily streaks
  • Ghost affinity meters
  • Quest board + achievements
  • Unlockable relic themes (cosmetic CRT palettes)
  • Chronicle / stats HUD
  • Boot sequence, typewriter replies, procedural audio (no asset licensing rabbit hole — same idea as Web Audio–only game SFX)

Safety rails

  • No eval, no shelling model output, no arbitrary code execution
  • Plain-text rendering of AI replies
  • Clear distinction between curated history-inspired fiction and verified facts in character prompts
  • App code MIT; model weights documented separately (1.5B Apache-2.0; optional qwen2.5:3b is a different research license)

Why Open Innovation Matters

It works when the network doesn’t. Classrooms, travel, flaky ISP nights — once Ollama and the weights are on disk, the séance continues. A closed chat API simply goes dark.

Prompts stay on the laptop. Students asking “dumb” debugging questions shouldn’t have to ship that insecurity to a vendor. Local inference keeps the conversation co-located with the shame and the learning.

No per-token bill for the core loop. Electricity and disk still cost something — local is not free — but there is no surprise invoice for every COBOL monologue.

The brain is swappable. Change OLLAMA_MODEL and restart. The game, puzzles, and UI do not care which compatible open-weight instruction model you prefer. That is the opposite of rebuilding around one commercial assistant’s deprecation calendar.

Inspectable pedagogy. Characters, prompts, scoring, and quests are ordinary TypeScript/JSON in the repo. Teachers and curious students can fork a ghost or add a case without asking permission from an API product manager.

Closed tools are fine for many jobs. For a haunted classroom terminal that must keep working offline, open weights + open code were not a branding choice — they were the only architecture that matched the fantasy.

Prize Categories

None claimed for partner tracks this week — the project’s open core is local Ollama + Qwen2.5, not a featured partner runtime. Happy to compete on the overall Ghost in the Machine criteria: theme fit, local open-weight inference, and a write-up that shows the work.


If you try it, summon Assembly and ask something vague on purpose. It will make you be precise. The ledger prefers that.

Top comments (0)