Install and hosting
Running it#
You need Node.js 22.5 or newer (24 recommended) and
pnpm. With Nix, nix develop provides both.
git clone https://github.com/dntAtMe/dnd-table.git
cd dnd-table
pnpm install
pnpm build
pnpm start
The server prints the addresses to open:
dnd-table server listening on 0.0.0.0:3000 (data: …/dnd-table/data)
Open on this computer: http://localhost:3000
Open on your network: http://192.168.0.12:3000
Players on the same Wi-Fi open the network address on their phones. Create an account, start a campaign (you become its GM) and share the invite code from the sidebar. The user guide covers the rest.
Configuration#
Set these as environment variables, e.g. SIGNUP_CODE=dragons pnpm start.
| Variable | Default | Meaning |
|---|---|---|
PORT |
3000 |
HTTP port |
HOST |
0.0.0.0 |
Interface to listen on (127.0.0.1 keeps it off the network) |
DATA_DIR |
data |
Where the database and uploads live (relative to the repository) |
SIGNUP_CODE |
(none) | If set, creating an account needs this code. Set it on any public server |
COOKIE_SECURE |
false |
Set to true when served over HTTPS |
LOG_REQUESTS |
false |
Log every HTTP request |
Your data#
Everything is in data/: one SQLite database (dnd-table.db) and uploaded images and audio
(uploads/). To back up, copy the folder while the server is stopped. To upgrade, pull the new
version, then run pnpm install, pnpm build and pnpm start again; the database is migrated
automatically on start.
Hosting it online#
For remote players, run it on a server behind an HTTPS reverse proxy that passes WebSockets through. With Caddy, which fetches certificates by itself:
table.example.com {
reverse_proxy 127.0.0.1:3000
}
HOST=127.0.0.1 COOKIE_SECURE=true SIGNUP_CODE=your-secret pnpm start
Uploads are limited to 30 MB per image and 50 MB per audio file, so allow request bodies that large if your proxy limits them.
Development#
pnpm install
pnpm dev # Vite on :5173 (open this) + API server on :3000, both reloading on change
pnpm test # rules engine and server integration tests (vitest)
pnpm typecheck
pnpm screenshots # regenerate docs/screenshots from a seeded demo campaign
pnpm site # build the website (site/ and the docs) into _site/
pnpm screenshots builds the client, starts a throwaway server with a demo campaign and drives
headless Chromium through it. It needs Playwright's browser once:
pnpm exec playwright install --only-shell chromium.
apps/server Fastify + WebSockets + SQLite (node:sqlite): accounts, campaigns, the live game
apps/web React + Vite client: GM, player and table display views
packages/rules The 2024 rules shared by client and server: dice, grid and fog, walls and movement,
vision, area templates, characters, combat, monsters, the knowledge base index
packages/protocol REST bodies and WebSocket messages (zod schemas and types)
scripts SRD import and screenshot tooling
The server is the source of truth. Clients send intents ("roll 2d20kh1+3, GM only", "move this token
here"); the server checks them, resolves them and sends each connection only what its role may see.
The database migrates itself on start-up (PRAGMA user_version).
Something unclear or out of date? Edit this page on GitHub.