LEFTEROS / PERSONAL ARCHIVE
ShadowRealms AI — a local AI Storyteller for World of Darkness
31 May 2026 / Lefteris Iliadis / SomniusX

This is the biggest public project I run as Somnius: a web app for World of Darkness chronicles with an AI Storyteller, which you host yourself. The app runs in Docker and the language models on your own computer, through LM Studio and Ollama, so your stories stay with you. Every chronicle is played either with the classic rules (Classic, oWoD Revised) or with V5, and both the interface and the Storyteller speak English and Greek.
The repository opened on 28 August 2025. On 4 October 2026 versions 0.9.0 to 0.10.0 came out together, the biggest update since the project began, along with a two-minute trailer in English and in Greek. On 15 and 16 October versions 0.11.0 to 0.14.1 followed, about V5 characters made by the book, and a new trailer two and a half minutes long. Later on the 16th came 0.15.0, with ghoul sheets for V5 and Classic, and overnight to the 17th 0.16.0 to 0.22.1, which give the chat a voice: you hear it read aloud and you can speak your lines. Later on the 17th came 0.23.0 to 0.28.0, with cloud voices (opt-in) and the chronicle so far: the local model writes every chronicle’s chat up as minutes, night by night. On 18 and 19 October came 0.29.0 to 0.31.0: the AI Storyteller now remembers the chronicle so far, and a fallen character gets its death written by the local model, from an admin page that kills, revives and keeps the deaths log. The app is open source, under the MIT licence.

“Athens by Night” (V5) in play: two dice cards, a Rouse check, the Storyteller’s reply, and on the right the character with their Hunger.
Beta testing
I'm looking for a few people to test the platform, not to run a real chronicle: sign up, Classic and V5 characters in the forge, a chronicle with rooms, dice, a chat with the AI Storyteller, voice from a phone, switching between Greek and English, the chronicle so far. It runs on a test copy on my own machine, with a local model, so replies can be slow and the server will be down at times. Whatever is written in the test chronicles is visible to me, as the admin.
For access send me a message (on Discord or through the contact page) and I'll give you the address and an invite code privately. Report what you find with the beta form on GitHub: it needs a free account, and issues are public, so no personal data and no server address.
The trailer
The new trailer, two and a half minutes long, shows what came after the first one: the Storyteller setting a chronicle’s character creation rules, Guided mode suggesting a clan from a few questions, the new forge with every power and its page in the book, a bestial failure with /ai explain on it, a botch in Classic, and the character sheet as a PDF.
Everything in it is real: recorded on a demo copy of the app, with real AI Storyteller replies (Llama-Krikri, running locally), real dice rolls from the server and an original score. For the bestial failure and the botch I just kept rolling until they landed. The videos play straight from GitHub, in 1080p at 60 fps; each is about 570 MB, so they need a good connection. For the best experience, watch them fullscreen.
In English
In Greek
If it doesn’t play in your browser, download the video: English · Greek · the trailer’s page on GitHub. The first trailer, from 0.10.0, is still on GitHub.
Voice (0.16 to 0.22)
From the evening of 16 October to the morning of the 17th, seven releases gave the chat a voice. All of it runs on the app’s own server, in an optional speech container. More in the post about the voice.

Listening in a room: the message being read is highlighted, and the bar shows the sentence being said.
- Listen (0.16, 0.17): an ear in the room header reads the chat aloud, with the phone’s voices or the server’s (Piper for English, Pocket TTS for Greek). A character speaks with a voice of its gender (female, male or neutral, set on its character sheet), the Storyteller with the chronicle’s narrator voice, in American or British English or Greek. The chronicle’s creator sets what is read by default; every player can turn things off, and set speed and volume.
- Speak (0.18): the mic in the message box records up to three minutes, with a large timer and a ring that pulses and changes colour as time passes. You listen back with a slider and speeds, pick the language you spoke with a flag, transcribe it with Whisper, fix the text, and send it in character, as a quote or out of character. Voice messages carry a mic everyone sees, and the recording plays from the chat for the chronicle’s lifetime.
- In your language (0.19): read and hear the chat in your own language, with the original one tap away; speak Greek and send English. The translator is Llama-Krikri, with the chronicle’s names kept out of the translation.
- Transcript check (0.21): Laya-words, my model from RecMeets, marks the probably misheard words and Llama-Krikri fixes only those, slang and swearing included.
- Read along (0.22): sentence by sentence, so a long reply starts in about three seconds; the message highlighted and followed; “Read this” and “Read from here” on a long press; the dice read as a sentence in your language. And in 0.22.1, English voices say Greek names the Greek way.
The chronicle so far (0.23 to 0.28)
On 17 October, six releases gave every chronicle its minutes. The local model writes the chat up as a story, the way minutes are written from a meeting’s recording. More in the post about the chronicle so far.
- The chronicle so far (0.24): a panel in Chronicle settings writes the chat one room and one night at a time, in Greek with Llama-Krikri, in English with the LM Studio model: in short, the story so far, the open threads, and every night with a title, paragraphs and what happened, each event pointing back to its messages. It is written from what the players could read; the Storyteller has a part of their own with what they didn’t see. Only the nights that changed are written again, with live progress and Cancel.
- Minutes on paper (0.25, 0.26): export as Markdown or PDF, for the whole chronicle, the last N nights or a date range; in the character sheet’s look or a horror look (stained paper, a blood-red frame with thorns, splatters and drips), in colour or black and white for print, A4 or Letter. Greek text can be selected and searched in the PDF.
- The Storyteller edits and translates (0.25): the whole story edited in one Markdown box, with the written text kept apart; translation into the other language by the chat’s translator, with the names protected. And “Session ended here” (0.26) from a message’s menu, which cuts the nights there.
- Previously on… (0.27): whoever opens a room after twelve hours away gets a card with the nights they missed and the story in short, built only from the players’ view and with no model call, with “Jump to the start” of each night and “Read it” aloud.
- For the admin (0.28): settings per chronicle (night gap, writer model, table talk), an optional nightly run, writer health, and archives: a deleted chronicle leaves its minutes and transcript behind, for admins and for its Storyteller for 30 days.
- Cloud voices (0.23): Google Gemini voices, free or paid tier, turned on by the admin and chosen by each chronicle for itself; off by default, and if Gemini doesn’t answer, the local voice speaks.
The Storyteller remembers (0.29 to 0.31)
On 18 and 19 October, three releases put the minutes to use. More in the post about the Storyteller’s memory.
- The Storyteller remembers (0.29): every AI Storyteller reply gets a short block from the chronicle so far (the story in short, the open threads, the last three nights of the room, one line per other room, the Storyteller-only paragraphs), at most a quarter of the prompt and never more than 1,500 tokens, with no model call and no waiting. It is the Storyteller’s private memory, never quoted to players; on for every chronicle, with a switch in Chronicle settings, and
/ai contextshows it to admins only. - A death in writing (0.30): when an admin kills a character, the chronicle writer writes two to four sentences of the death in the chronicle’s language, from the story so far and the character’s last nights, player view only; on any failure or timeout the fixed sentence is used, in Greek too. Also: the composer’s slash commands come from the server, in English and Greek, and a chronicle created through the API without a language takes its creator’s app language.
- The kill page (0.31): Admin → Characters lists every player character, alive or fallen; Kill picks the death (soft, sacrifice, horrible), shows the text and whether the AI wrote it; Revive undoes it and the kill stays in the deaths log, which also goes to the moderation log. The fallen show the death text on the owner’s profile card and on the sheet. The death prompt forbids invented names, clans, places and lore, and mixed scripts in Greek fall back to the fixed sentence. And on phones the whole sheet scrolls, with only the name bar staying on top.
- SPEC.md: a system specification in the repository, at 0.31.0: what the system is and must do, roles, data, scope.
What changed since 0.10
0.15.0 “Blood servants” (16 October 2026): ghouls get their own sheet, made from your vampire’s sheet with “Add a ghoul retainer”. A ghoul belongs to the same player, follows its domitor and has no chronicle of its own; the domitor’s Storyteller can read it, and the AI Storyteller sees up to two of a playing character’s ghouls. More in the post about 0.15.
- V5 ghouls: a retainer on the corebook’s mortal templates (Weak •, Average ••, Gifted •••, or Deadly; pp. 185, 194) or a player ghoul by the Players Guide (pp. 140–142), with one level 1 power of a Discipline its domitor has, the ghoul-only Merits and Flaws, and a Blood Bond. No blood pool: in V5 a ghoul has no vitae to spend, no Hunger and no Blood Potency (core p. 234). The server checks it like a vampire.
- Classic Revised ghouls, by Ghouls: Fatal Addiction: Attributes 6/4/3, Abilities 11/7/4, 21 freebies, Potence 1 and one more Discipline, a Blood Pool of up to 10 spent 1 per turn, the Domitor Background, and a PDF laid out like the old ghoul sheet.
- The sheet PDF has a print version with no form fields, which looks the same in every viewer, the fillable one keeps Turkish and other accented letters, and long backgrounds and notes continue on extra pages.

A Classic ghoul’s sheet in the PDF, with its Blood Pool.
On 15 and 16 October 2026 came versions 0.11.0 to 0.14.1 (0.11.0 on the 15th, the rest on the 16th). Almost all of it is Forge v2: V5 characters made by the book. More in the post about 0.14.
0.11.0 “By the book”:
- A V5 rules catalog. All 16 clans (the corebook’s seven, the Players Guide’s seven with the Hecata, plus Caitiff and thin-bloods), every Discipline power, Blood Sorcery ritual, Oblivion ceremony and thin-blood alchemy formula, and the 18 predator types, each with its book and page and a short description in English and Greek. A script built it from the official books, facts only, with no book text; the descriptions are in our own words.
- The V5 forge follows the corebook’s order, with powers and rituals picked from lists and the real choices of each predator type. At the Disciplines step you see what a predator type gives before you pick it, and its Flaws now count as extra: every character also takes 2 Flaw dots of its own, as the corebook says (p. 136). There’s also optional starting experience for neonates and ancillae.
- Export to PDF: a fillable two-page character sheet for V5 or Classic Revised, in black and white for ordinary printers, Greek included.
/ai explain: reply to a dice card, and the Storyteller explains how that roll was counted, step by step, with the corebook page. Hidden rolls stay hidden.- Character creation rules per chronicle: which clans, predator types and ages the forge offers, and house rules shown at the top of the forge.
- The rule books are imported by a script, not read by an AI, into separate collections for each edition, so a Vampire chronicle never gets Werewolf rules. Dice leniency is set per edition too.
0.12.0 “Merits and guides”:
- Guided mode: instead of the full forge, a player can answer scenario questions, one per screen, and get a suggested clan and predator type, with the Attributes and Skills filled in. Everything stays editable. The questions are a first set for now.
- Advantages from the catalog: Backgrounds, Merits, Flaws and loresheets are picked from lists, with the ratings the books print.
- The server checks V5 characters too, and refuses a sheet that breaks the rules, saying what’s wrong in English or Greek. The Storyteller can still approve a sheet outside the rules.
- The PDF gets a Reference page with the clan, the powers, the rituals and the advantages the character has, each with its book and page.
0.13.0 “Saved for later”: Advantage dots left unspent at creation are kept on the sheet and spent later, with the Storyteller’s approval. A chronicle can let the AI Storyteller approve the spends that pass the rule check; that is a fixed check, not the language model, and a person can reverse it.
0.14.0 “The library” and 0.14.1 “House rulings”: the Storyteller picks which books a chronicle allows, and the forge offers only what they contain. The catalog grows with the supplements: 24 books, with 157 loresheets, 210 Discipline powers, 109 rituals, 29 ceremonies, 48 formulae and 279 Merits, Backgrounds and Flaws. Plus three house rulings, where the book is silent or says otherwise: the Caitiff’s Suspect counts toward the 2 Flaw dots, a player can take more than one loresheet at creation, and a player can take an Enemy or Dark Secret of their own beside the one the predator type gives.
What changed since 0.8
0.9.0 “Into the Night” rebuilds most of the app:
- Two rules editions. Each chronicle picks Classic or V5 when it’s created and keeps it. A V5 dice engine (Hunger dice, pairs of 10s, messy criticals, bestial and total failures, Willpower rerolls, Rouse checks), and a separate character forge and sheet for each edition.
- A new app: real URLs for every page, one navigation, and a Discord-style chat with live updates, dice cards and slash commands.
- Greek everywhere: more than 1,080 strings in English and Greek, and the Storyteller answers in the player’s language (in Greek with Llama-Krikri).
- A gothic redesign: 97 original SVG glyphs and sigils, fog, candle glow, blood on botches, animated dice, and an atmosphere setting for anyone who wants it calmer.
- AI: local models first, multilingual long-term memory that finally works, and the Laya classifier for out-of-character chat.
- Security: rate limits, lockouts, token revocation, a password policy, a login audit and a strict Content-Security-Policy.
0.9.1 to 0.9.4 fill the gaps: pick the edition first and then the game line, Willpower rerolls cost Willpower, a Logins & lockouts tab for admins, tokens that refresh themselves, log lines that can’t be forged, and at the table:
- Dice pools from the sheet: when the Storyteller asks for a roll, the server works out the pool from your sheet (specialties, Hunger, impairment) and the chat shows a chip that fills in the dice dialog.
- Copy, reply with a quote and delete on messages, and older history as you scroll up.
0.10.0 “New foundations” replaces the foundations: the interface now builds with Vite instead of Create React App, in about a second, with a smaller bundle and zero findings in the production npm audit (down from 69). In came react-router 7, motion 14, i18next 26 and Jest 30, and the unused packages went. All 204 lint warnings were fixed, and CI now fails on any new one. On the back end: Python 3.12 and ChromaDB pinned to 1.5.9.
How it plays
The rules. In Classic the dice follow Revised: difficulty 2 to 10, 1s cancel successes, a botch only when nothing succeeded, specialties re-roll 10s, and Willpower adds one success that can’t be cancelled. V5 has Hunger dice, messy criticals, bestial failures, Willpower rerolls and Rouse checks. The Storyteller’s prompt and the rule-book search follow the chronicle’s edition.
At the table. The chat feels like Discord: grouped messages, unread counts, in-character and out-of-character rooms. Rolls are made and posted by the server, so a dice card in the chat is always a real roll. /roll, /me and /chat for everyone and /ai for admins, and one “Speaking as” control for your character, yourself out of character or, for staff, the Storyteller’s voice.
Voice. Turn on the ear in a room and the chat is read aloud: each character in a voice of its gender, the Storyteller in the chronicle’s narrator voice, the dice as one sentence. Tap the mic to speak instead of typing; you check the text before it goes, and everyone can play the recording.
The chronicle so far. The Storyteller presses Update and the local model writes the chat up as a story, night by night, with every event pointing to its messages; they edit it, translate it and export it as a PDF, in the character sheet’s look or a horror look. A player who comes back after half a day gets a “Previously on…” with what they missed, and only what they could have seen. And the AI Storyteller reads the same minutes before every reply, so it remembers what happened three nights ago.
Characters. A character forge per edition: Classic with the Revised budgets (7/5/3, 13/9/5, virtues, 15 freebies), V5 with its spreads, Predator type, disciplines, advantages and flaws. Sheets lock after creation; changes go through downtime requests the Storyteller approves. In V5 the forge follows the corebook’s order and takes its clans, powers and advantages from the rules catalog, or a Guided mode suggests a character for you, and every sheet exports to a fillable PDF. The Storyteller sets which clans, predator types, ages and books each chronicle allows.
The atmosphere. 97 original SVG glyphs, fog, candle glow and blood dripping on botches. Each account picks its atmosphere: full, subtle or off. A guided tour of the theme lives at the app’s /showcase address.
The AI Storyteller
Instead of one model there are roles, each with its own model, all set in the admin panel:
| Role | Model | Runs on |
|---|---|---|
| Storyteller (English) | whatever model LM Studio has loaded | LM Studio, graphics card |
| Storyteller (Greek) | llama-krikri-8b-instruct (Llama-Krikri by ILSP) |
LM Studio |
| Utility calls | llama3.2:3b |
Ollama |
| Memory and rules | bge-m3 embeddings (multilingual) |
LM Studio, with ChromaDB |
| Chat moderation | Laya, my own fine-tuned mmBERT | processor, ONNX Runtime |
| Translator | llama-krikri-8b-instruct, with a game-term glossary |
LM Studio |
| Voices | Piper (English) and Pocket TTS (Greek) | the speech container |
| Transcription | Whisper large-v3-turbo, checked by Laya-words | the speech container, graphics card |
| Chronicle writer | llama-krikri-8b-instruct for Greek, the loaded model for English (or one model per chronicle) |
LM Studio |
| Cloud voices (optional) | Google Gemini, free or paid tier, per chronicle | Google, with the local voices as fallback |
| Death text | the chronicle writer, in the chronicle’s language, with a fixed sentence as fallback | LM Studio |
- Llama-Krikri was chosen because it writes clean Greek; in tests, Gemma 4 E2B answered Greek prompts in English.
- Long-term memory and the rule-book search are RAG on ChromaDB, with bge-m3 understanding English, Greek and the mix of the two.
- The Laya classifier moderates the out-of-character rooms and reads the intent of each message, in about 230 ms on the processor. It was trained with the same process as RecMeets' Laya, on hand-written and synthetic messages in English, Greek and Greeklish.
- Optionally, an admin can add Anthropic or OpenAI keys, stored encrypted; they are off by default.
Screens

The voice on a phone: a message’s menu, recording, and reviewing before transcription.

A player’s voice settings · a chronicle’s narrator voices and read-out defaults.

From the new trailer: Guided mode suggests a clan and a predator type · the forge with every power and its page.

A chronicle’s creation rules, with its books and clans · the Reference page in the sheet PDF.

The chronicle hall, with a Classic and a V5 chronicle · the same chronicle with the interface and the Storyteller in Greek.

The V5 roll dialog · a Classic roll with a specialty and an exceptional success.

The V5 forge with live counters · the character sheet and its trackers.

The Classic forge with the Revised budgets · skills, disciplines and advantages on the sheet.

The grimoire of 97 glyphs · a Revised botch beside a V5 messy critical.

Sign-in with the animated sigil · language and atmosphere from the account menu.

A chronicle’s locations · models per role in the admin panel.

And on a phone: playing, chronicles and rooms, sign-in.
Tech stack
| AI | Llama-Krikri 8B and any model in LM Studio, Llama 3.2 3B on Ollama, bge-m3 embeddings, the Laya classifier on ONNX Runtime, optional Anthropic and OpenAI |
| Voice | Piper and Pocket TTS for speech, faster-whisper (large-v3-turbo) for transcription, Laya-words on ONNX for the transcript check, FastAPI, Opus recordings, optional Google Gemini voices |
| Memory and rules | RAG on ChromaDB 1.5.9 |
| Back end | Python 3.12, Flask 3.1 on gunicorn, PyMuPDF for the rule-book import, ReportLab for the sheet and chronicle PDFs, PostgreSQL 16, Redis 7, server-sent events, bcrypt and Fernet encryption, JWT |
| Interface | React 18, Vite 8, react-router 7, motion 14, i18next (English and Greek), DOMPurify, d3, Tailwind CSS and my own design system with 97 SVG glyphs |
| Infrastructure | Docker Compose (with an optional voice profile), nginx with a strict CSP, NVIDIA container runtime |
| Quality and security | GitHub Actions (pytest, Jest, ESLint, a database schema check), CodeQL, Dependabot, branch protection, more than 250 back-end and 360 interface tests |
Developed on Linux (Omarchy), with an AMD Ryzen 9 5950X and an NVIDIA RTX 4080 SUPER 16 GB. Llama-Krikri needs about 5 GB of graphics memory.
Quick start
You need Linux with Docker and Compose v2, LM Studio with its lms command, and Ollama. An NVIDIA graphics card is strongly recommended.
git clone https://github.com/Somnius/shadowrealms-ai.git
cd shadowrealms-ai
cp env.template .env
cp backend/invites.template.json backend/invites.json
python3 scripts/generate_secret_key.py
Put your own keys and PostgreSQL credentials in .env and your own invite codes in invites.json (registration needs an invite). Then:
lms server start
lms load llama-krikri-8b-instruct -y
lms load text-embedding-bge-m3 -y
ollama pull llama3.2:3b
./docker-up.sh
./scripts/build-frontend.sh
For the voice, also start the speech container: docker compose --profile voice up -d speech (it needs SPEECH_SECRET in .env; see docs/VOICE.md).
Open http://localhost, register with your admin code, create a chronicle and type /ai health in its chat. Every step in detail is on the wiki’s installation page.
Contributing
The project is big on purpose, and it needs contributors: code, RPG mechanics, hands-on testing, translations, or just clear issues with steps to reproduce. Everything runs inside Docker, and every change goes through CI before it lands.
Licence
MIT: LICENSE. White Wolf’s commercial books are not covered by the licence; they stay your own files in the data/ folder, and I don’t host them.
Posts
- ShadowRealms AI on Lefteros.com, 20 September 2026
- ShadowRealms AI 0.10: V5, Greek, new foundations and a trailer, 4 October 2026
- ShadowRealms AI 0.14: V5 characters by the book and a new trailer, 16 October 2026
- ShadowRealms AI 0.15: ghouls, in V5 and in Classic, 16 October 2026
- ShadowRealms AI 0.16 to 0.22: the chat gets a voice, 17 October 2026
- ShadowRealms AI 0.23 to 0.28: the chronicle so far, 18 October 2026
- ShadowRealms AI 0.29 to 0.31: the Storyteller remembers, 19 October 2026
Sources
- The repository on GitHub
- Changes by version (CHANGELOG)
- How the voice works (VOICE)
- How the chronicle so far is written (CHRONICLE)
- The tech stack in detail (TECH_STACK)
- The system specification (SPEC)
- The trailers: the new one, from 0.14.0 and the first, from 0.10.0
- The wiki
Updated on 19 October 2026, with version 0.31.0 and the Storyteller’s memory.



























