Hallow Mud:Gemma 每局生成一名陌生幽靈的萬聖節文字 MUD
Hallow Mud: a Halloween MUD where Gemma invents the one ghost we didn't write
Tommy Bergstrand 製作了萬聖節文字 MUD Hallow Mud,讓 Gemma 每局生成一名作者未編寫的陌生幽靈。遊戲以 1870 年聖保羅的 Swede Hollow 為背景,NPC 由 Gemma 扮演,會以自然語言互動、記住玩家並彼此回應;房間描述則於伺服器啟動時生成一次,供所有玩家共用。
This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine
What I Built
Hallow Mud is a text MUD set on All Hallows' Eve, 1870, in Swede Hollow: the ravine in Saint Paul, Minnesota, where Swedish immigrants built shacks along Phalen Creek. The dead of the Hollow are back tonight:
- Mor Brita, a cholera ghost from 1854, drifting between the graves looking for her son's painted wooden horse
- Järn-Gustaf, a brewery worker crushed by ice blocks in 1866, who still thinks he's on shift guarding the cellar stairs
- Fru Sigrid, a vampire who sleeps in the cellars "because no one looks for the missing poor"
- Varg-Anders, a trapper bitten by something along the creek
- Näcken, the water spirit from Swedish folklore, who followed the immigrants across the ocean and fiddles at the water's edge
- Gamle Lars, the lamplighter: the last living soul who refused to flee
Every NPC is played by an open-weight model. You talk to them in plain language; they answer in character, remember you, react to each other, and some of them wander the Hollow on their own. The model rewrites every room description when the server starts, so each night's Hollow reads differently, and all players share it, so looking around never waits on the model.
And then there is the Stranger. We didn't write them. At the start of each game, Gemma gets the story context and one question: "Someone is here tonight who no one in the Hollow has ever seen before. Who are they?" Whoever it invents steps out of the fog, and the rest of the cast has to deal with them. In one test run Gemma created Astrid Nylund, a woman with a rifle, who walked straight up to the lamplighter and started questioning him about what had changed in the Hollow. Nobody scripted that.
That's my take on Ghost in the Machine: a ghost that literally comes from the machine.
Demo
Play it in two places. Pick a name, create a character, and you're in the Hollow with whoever else is online on that server.
- q-bert.bearded-panga.ts.net: the fast one. Gemma 3 12B runs on the laptop GPU in my home, and the game sits next to it, published with Tailscale Funnel. NPCs answer in seconds. It's a laptop, so it may be asleep.
- hallow-mud.onrender.com: always there. It runs on Render's free plan with Gemma on the Gemini API, so the first visit after a quiet spell takes about a minute to wake up, accounts reset whenever the server restarts, and NPCs take a while to think.
A minute in the Hollow on the local server: Brita and Näcken each answer within about fifteen seconds.
I think it's really fascinating to see the generated conversations, but don't take my word for it, try it out!
Code
Hallow Mud
A Halloween text MUD set on All Hallows' Eve, 1870, in Swede Hollow, the Swedish immigrant ravine in Saint Paul, Minnesota. The dead of the Hollow are back tonight, and every one of them is played by Gemma.
Built for the Hacktoberfest Open-Source AI Challenge, Week 4: Ghost in the Machine.
What's in the Hollow
- NPCs written by us, played by Gemma: Mor Brita, the cholera ghost searching for her son's wooden horse; Järn-Gustaf, the dead brewery worker still guarding the cellar stairs; Fru Sigrid, the vampire in the cellars; Varg-Anders, the trapper turning into something else; Näcken, the water spirit fiddling by the creek; and Gamle Lars, the frightened lamplighter. Talk to them in plain language; they answer in character, remember you and react to each other.
- The Stranger, written by no one: each game, Gemma gets only the story context and the question…
The game engine is a fork of LlamaTale by neph1, itself built on Tale by Irmen de Jong. Our changes live on the hallow-mud branch of tobese/LlamaTale.
How I Built It
Gemma, two ways.
-
Local:
gemma3:12bon Ollama, on a gaming laptop (RTX 4080, 12 GB VRAM), with the game server running right next to it. I benchmarked Gemma 3 12B, Gemma 4 12B and Gemma 4 26B-A4B; Gemma 3 12B with an 8k context fits fully on the GPU at about 40 tokens/s, which is fast enough that NPCs answer while the scene is still fresh. -
Hosted:
gemma-4-31b-itthrough Google's Gemini API (OpenAI-compatible endpoint). Slower, but noticeably better prose, and it needs no GPU, so it's the backend for the always-on server on Render.
Switching between them is one line in llm_config.yaml.
The engine. LlamaTale is a MUD engine where the LLM narrates, plays NPCs, and builds world content through JSON-schema structured output. The story itself (zone, NPCs, quests, Swedish 1800s items such as the lie scythe and the folkdräkt) is plain Python in story/.
The look. Each NPC has a portrait and each room a picture, in the style of hand-tinted 1870s tintypes. Gemini's image model painted them in advance, from the same descriptions Gemma plays the characters from (the script is in tools/paint_resources.py). The Stranger can't be painted in advance, so the game paints their portrait the moment Gemma invents them, before they step out of the fog. The web client is restyled in Hacktoberfest's colours and fonts.
What I had to fix along the way (all on the fork, each with tests):
-
say to <npc>never reached the NPC, and NPC names matched case-sensitively - Gemma 4 always "thinks", and its
<thought>blocks leaked into the game text; they're now stripped - When an NPC's dialogue couldn't be parsed, the player got
ERROR IN DRIVER MAINLOOP; now the NPC just stares, lips moving, and no words come - An option to show only the generated text, instead of the original description followed by its rewrite
- A save-path check that could be bypassed on macOS through
/private/etc, plus test fixes for Python 3.11+ - Every
lookasked the model to rewrite the room for that one player, so players queued behind each other for 20 to 30 seconds; now each room is rewritten once when the server starts and shared, and looking around is instant - In multiplayer, what you said reached the other players retold by the model; now they hear your words as you said them
- New players who took more than a minute to create a character were destroyed by the Grim Reaper in Limbo mid sign-up
- NPCs name each other when they talk, and every named NPC answered, so two of them could talk forever; now an NPC answers other NPCs once per player line
- Stories can now ship their own stylesheet, and their pictures are found wherever the game is started from
Two fixes went upstream as PRs: #145, which neph1 has merged, and #146.
Why Does Open Innovation Matter?
The whole stack is open, so I could fix it instead of working around it. Tale is a MUD framework from the 2010s, LlamaTale adds the LLM layer on top, and Hallow Mud is a fork of that. When the engine got something wrong, like NPCs never hearing say to, I fixed it in the engine, with tests, and sent the fixes back upstream. One has already been merged.
Open weights are faster here, not just cheaper. Gemma 3 12B runs on the laptop next to the game server, so an NPC answers in about ten seconds. The same conversation through a hosted API took close to a minute. For a game, that's the difference between talking to someone and waiting for a letter.
Open weights mean no bill per word. Running locally there is no per-token cost, so the NPCs can gossip with each other, rewrite the rooms and react to everything all night long without anyone watching a meter.
One model family, two places to run it. The same Gemma runs on my own GPU and on Google's API, so moving between them is a line in a config file, not a rewrite. The always-on server uses the API; the fast one uses the laptop.
Small stories get to exist. Swede Hollow was a ravine of Swedish immigrant shacks in Saint Paul, cleared in 1956 and a park today. No product team would build a game about it. Open tools let one hobbyist do it in a few days.
My Agent Session
The whole project started from this prompt to Claude Code:
Hallow Mud
My idea is to build a LLM Mud with Halloween Theme
The NPCs I think should be based on the inhabitants from there that now are ghosts, zombies, werewolfs, vampires or similar.
Weapons and armour could be based on Swedish 1800s things:
Folkdräkter
Lie, Sledgehammer
And other things along that line.
In the challenge there are a number of prize categories, if we can find a match that would be a bonus.
The one that caught my eye is gemma.
For the local llm, we have q-bert, if MACHINES.md isn't in the global dirs, check sibling project systema-naturae.
Lets dive into the MUD!
The Dungeon Master
Besides some python version issues, that basically made a running system.
From there the session kept going: the fixes to the engine listed above (two of them sent upstream as pull requests), the Stranger, the portraits, the theme, and the two public servers.
The Spirit of It
When the autumn is advancing, the wind is howling and Halloween is nigh, then the mood is set for a real adventure with terrifying encounters...
When attending Uni, my friends and I were playing MUDs a lot. Today, I mostly play FFXIV, with stunning graphics and really advanced fighting. But it is the spirit of the game that matters, and MUDs still have it!
Coding has been done in really advanced environments like Visual Studio or JetBrains' many tools. Visual Studio Code was sort of a step backwards to a text editor, of course with plugins and tools for almost anything.
Now, I am sitting with a command prompt again, but with agents it can do about anything!
And the terminal cursor really calls for an entry of hallow-mud.
I recently stumbled on a MUD with an LLM, and this challenge felt like a perfect fit!
And for a Swede, I thought that Swede Hollow would be a good setting.
Prize Categories
Best Use of Gemma: every NPC, every room description, and the Stranger are Gemma, run locally on Ollama or hosted via the Gemini API. (The pictures, including each night's portrait of the Stranger, come from Gemini's image model.)
Best Use of Render: Render is the game's AI runtime and hosts its front end. The multiplayer server runs there as a Docker web service, built from the repo and deployed on every push to main: it runs the game, calls Gemma through the Gemini API for every NPC, room and Stranger, paints each night's Stranger, and serves the web client players connect to. See the Dockerfile.
來源:DEV Community · dev.to
