DungeonCore
The first easy-to-use, fully local AI roleplay app. The story and the inline scene images are both generated on your own machine — no accounts, no API keys, no cloud, no GPU rig. Your stories never leave your computer.
Inspiration
Most AI roleplay apps lock you into their cloud, their moderation, and their pricing. We wanted a private space where you could run an entire story — text and images — on a laptop, with no sign-up, no telemetry, and no one looking over your shoulder. DungeonCore is that space.
What it does
- Local text generation via Ollama (Gemma 4 QAT), or Connect a server to any OpenAI-compatible backend — llama.cpp, LM Studio, vLLM, a remote Ollama, OpenRouter. Narration streams in real time as the model writes.
- Local image generation — the narrator calls a
generate_imagetool and scenes render inline: FLUX.2-klein on Apple Silicon / NVIDIA / supported AMD Radeons, or point the app at your own ComfyUI instance. - Full play controls — Do / Say / Story input, Continue, Retry, Erase, and inline Edit on any passage. Quick-start presets write a custom opening.
- Long-story memory — history fills the model's context window (128K–256K), and older passages compact into a rolling "story so far" summary instead of being forgotten.
- Characters with visual continuity — saved portraits feed both the narrator (vision context) and the image generator (reference images).
- Private by design — everything lives in a local SQLite database and folders on your disk. Play from your phone over Tailscale.
![]() |
![]() |
How i built it
- Next.js 16 app with React 19 and Tailwind v4 for the UI.
- better-sqlite3 for local story storage — no server, no migrations, just a file on disk.
- Ollama as the default text backend, with a streaming SSE proxy so the UI gets tokens as the model writes.
- Python worker for image generation (FLUX via diffusers / ComfyUI), launched as a background process and called via HTTP.
- Tool calling — the narrator can invoke
generate_imagemid-passage and the UI renders the result inline. - Rolling summary — when context gets long, a background summarization step compacts old turns into a "story so far" block the model can reference.
- Next.js API routes for health checks, settings defaults, and chat history; everything else is client-side.
Challenges i ran into
- Native module ABI drift —
better-sqlite3breaks every time Node is upgraded because it ships a compiled.nodebinary. We had to add rebuild steps and detect the mismatch early. - Streaming + tool calls — getting the UI to render narration tokens while also waiting for an inline image tool call was tricky. We ended up splitting the stream into a text phase and a tool phase.
- Long-context summarization — compressing 128K+ tokens without losing character voices and plot details required a few iterations on the prompt and chunk size.
- Cross-platform image backends — FLUX runs differently on Apple Silicon (MPS), NVIDIA (CUDA), and AMD (ROCm / DirectML). The Python worker needed device detection and fallback paths for each.
- Windows launcher — bundling Node, Python, Ollama, and the image worker into a double-clickable experience on Windows meant writing a PowerShell setup script that handles PATH, venvs, and GPU detection.
Accomplishments that i'm proud of
- Zero-config first run on Mac — download the DMG, drag to Applications, open, pick a model, start writing.
- Real inline images — the narrator decides when a scene needs an image, and it appears in the flow without breaking the read.
- True privacy — no analytics, no cloud sync, no accounts. The entire app runs from a SQLite file and a couple of folders.
- Cross-platform — Mac, Windows, and Linux all supported from the same codebase.
- Phone play over Tailscale — you can run the server on your desktop and read/continue stories from your phone on the same network.
What i learned
- Local-first changes everything — when the data never leaves the box, users trust the app more, but you also lose the safety net of cloud infrastructure. Error handling and offline states matter more.
- Tool calling is the future of UI — letting the model trigger actions (like image generation) mid-response feels way more natural than separate buttons and panels.
- Summarization beats retrieval for stories — for long fiction, a rolling summary the model can actually read is more useful than RAG over raw past turns.
- Native modules are a tax — every Node upgrade costs you time with
better-sqlite3and friends. Pin Node versions tightly in production builds.
What's next for DungeonCore
- Multi-model scenes — switch narrators or art styles mid-story.
- Character voice tuning — save and swap speaking styles per character.
- Export — EPUB, PDF, and plain-text exports of completed stories.
- Plugin system — let users add custom tools the narrator can call (dice rolls, stat tracking, world-state lookups).
- Mobile app — a proper iOS/Android build so Tailscale isn't required.
- Community prompts — share and discover opening scenarios and narrator presets.
Built With
- gemini
- image-generation
- local-llm
- nextjs
- ollama
- on-device-ai


Log in or sign up for Devpost to join the conversation.