Skip to content

Black Dice Engine

A tabletop RPG platform that runs on the host's machine: a Game Master dashboard, player screens on phones, campaign memory, dice and state services, and optional AI or locally generated media. The rules services, not the language model, control the game state. Solo project.

Brand banner. The prototype's dashboard and player screens are still bare shells, so they aren't shown yet.
My role
Solo product architect and gameplay-systems engineer
Built with
Node.js, TypeScript, local web clients, structured campaign storage, media adapters
Key rule
AI may suggest actions; deterministic services validate dice, permissions and campaign state
Status
Early prototype: game server, GM dashboard, player companion, session state and dice endpoints

What it solves

AI-assisted tabletop tools drift, forget canon, invent contradictory state, or send private material to remote services. Virtual tabletops also split narration, memory, media, rules bookkeeping and player sheets across too many apps.

Black Dice Engine puts those jobs in one local runtime: the GM gets narration support and deterministic state tools, players get light companion views, the campaign gets structured memory, and generated content passes through clear schemas, permissions and approvals.

  • GM Command Center

    A dashboard for scene framing, live narration support, party state, hidden notes, dice logs, memory review, and approvals for heavier media jobs.
  • Player Companion

    Phone/tablet views for character sheets, status, rolls, submitted actions, handouts, and player-visible scene updates over the local network.
  • Local-First Runtime

    Campaign databases, generated media, models, secrets, and private PDFs stay outside Git and on the host machine unless remote services are explicitly enabled.

Architecture

Deliberately not a tangled mesh: the GM dashboard and player phones talk to one local game server, which coordinates dice, state, memory, AI, media, runtime health and persistence.

GM dashboard / player phones
→ local game server
→ dice, state, memory, AI and media services
→ database and local asset folders
→ WebSocket updates back to clients
  • Game Server

    Single API boundary for the GM dashboard, player phones, WebSocket updates, permissions, and service orchestration.
  • Dice + State Services

    Dice parsing, roll history, explicit state events, inventory/resource updates, conditions, initiative, quest flags, and auditability.
  • Memory Service

    Campaign canon, summaries, unresolved threads, NPC facts, locations, faction state, and session history stay structured instead of becoming loose chat history.
  • AI + Media Adapters

    Local LLM adapters, optional director calls, ComfyUI scene generation routing, and local audio cues sit behind approvals and runtime health checks.

Engineering lessons

  • Do not make the LLM the source of truth

    The AI may propose narration, dice calls, memory updates, or state changes. The game server validates and applies mechanics through explicit services.
  • Keep player-visible and GM-only data separate

    A table tool has real privacy boundaries: hidden notes, future reveals, private character details, and imported material cannot leak into companion views.
  • Graceful degradation matters

    If image generation, audio, or a local model fails, the session should keep running. Runtime health, reconnect state, and backups are part of the design.

Where it stands

The repository has the first local prototype: a Node/TypeScript game server with health, runtime-status, session-snapshot and dice-roll endpoints, plus small GM dashboard and player companion shells.

Next: persistence, local model adapters, ComfyUI routing, campaign memory ingestion, permissions, imports and hardened runtime recovery.