An implementation of the Mythic GM system with a little PbtA sprinkled in.
  • TypeScript 96.7%
  • CSS 2.5%
  • Just 0.4%
  • JavaScript 0.2%
  • Dockerfile 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Adam Macumber a06f2d43c1 feat(speech): read each character's dialogue in a voice of their own
The GM tags NPC dialogue ({Old Tom/m}"..."), tags are hidden on screen, and
Read Aloud casts a consistent voice per character from their name and hint,
for browser voices, solo AI voices, and table audio. Setting defaults on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G7NFJVE84ZJ2pezqQrRXBq
2026-10-07 12:36:45 -04:00
deploy feat(tooling): just recipes for development and Docker compose 2026-09-26 10:06:10 -04:00
docs feat(speech): read each character's dialogue in a voice of their own 2026-10-07 12:36:45 -04:00
public feat(table): opt-in Web Push notifications when the story moves on while you're away 2026-10-07 10:03:30 -04:00
scripts refactor(game): multi-PC model, rounds, and a shared GameSession 2026-09-25 21:36:33 -04:00
server feat(speech): read each character's dialogue in a voice of their own 2026-10-07 12:36:45 -04:00
src feat(speech): read each character's dialogue in a voice of their own 2026-10-07 12:36:45 -04:00
.dockerignore feat(tooling): just recipes for development and Docker compose 2026-09-26 10:06:10 -04:00
.env.example feat(deploy): compose file for hosts running Traefik 2026-10-02 12:22:33 -04:00
.gitignore feat(tooling): just recipes for development and Docker compose 2026-09-26 10:06:10 -04:00
.oxlintrc.json chore: scaffold Vite + React + TypeScript app shell 2026-09-24 12:37:21 -04:00
.prettierignore chore: scaffold Vite + React + TypeScript app shell 2026-09-24 12:37:21 -04:00
.prettierrc.json chore: scaffold Vite + React + TypeScript app shell 2026-09-24 12:37:21 -04:00
AGENTS.md feat(speech): speakable text and prefix-stable sentence chunking 2026-10-03 15:14:27 -04:00
CLAUDE.md docs: add AGENTS.md (jj + docs conventions) and CLAUDE.md pointer 2026-09-24 12:37:21 -04:00
compose.traefik.yml feat(deploy): serve on port 8788 behind Traefik 2026-10-02 12:51:19 -04:00
compose.yml feat(tooling): just recipes for development and Docker compose 2026-09-26 10:06:10 -04:00
Dockerfile feat(deploy): serve on port 8788 behind Traefik 2026-10-02 12:51:19 -04:00
index.html feat(table): opt-in Web Push notifications when the story moves on while you're away 2026-10-07 10:03:30 -04:00
justfile feat(tooling): just recipes for development and Docker compose 2026-09-26 10:06:10 -04:00
package-lock.json feat(table): opt-in Web Push notifications when the story moves on while you're away 2026-10-07 10:03:30 -04:00
package.json feat(table): opt-in Web Push notifications when the story moves on while you're away 2026-10-07 10:03:30 -04:00
README.md feat(speech): Read Aloud polish for phones, Esc, and docs 2026-10-03 21:41:09 -04:00
tsconfig.app.json chore: scaffold Vite + React + TypeScript app shell 2026-09-24 12:37:21 -04:00
tsconfig.json feat(server): table server with accounts, access control, keys, and caps 2026-09-25 21:36:33 -04:00
tsconfig.node.json chore: scaffold Vite + React + TypeScript app shell 2026-09-24 12:37:21 -04:00
tsconfig.scripts.json chore(playtest): headless playtest harness with player bot and spend cap 2026-09-24 14:08:16 -04:00
tsconfig.server.json feat(server): table server with accounts, access control, keys, and caps 2026-09-25 21:36:33 -04:00
vite.config.ts chore(dev): allow the dev server through tailscale serve, for HTTPS on a phone 2026-10-07 10:14:01 -04:00

Mythic AI

A tabletop RPG: the Mythic GME oracle and PbtA moves, with an LLM Game Master via OpenRouter. Play solo in your browser with your own key, or run the table server and play online with friends.

Development tasks run through just (just lists them all):

just install     # npm install
just dev         # the app and the table server together (Ctrl-C stops both)
just dev-app     # the app alone; solo play works on its own
just test        # unit and server tests
just check       # typecheck, lint, and test
just build       # typecheck + production build

The dev app also listens on your network, so you can open the printed Network URL (e.g. http://192.168.1.102:5173) from a phone on the same Wi-Fi.

The first time the server starts with no accounts, it prints a setup link. Open it to create the site admin, then add the site's OpenRouter key under Admin.

Read Aloud speaks the GM's narration as it streams: switch it on with the speaker button in the header, or replay any passage with the button beside it (Esc stops). Choose the voice under Settings → Read aloud: this device's own voice (free, offline) or an AI voice from OpenRouter (paid with your key). At a table, the site admin or the owner (with their own key) can give the table an AI voice that the server makes once for everyone. See docs/READ-ALOUD.md.

Deploying the table server

The Dockerfile builds one image that serves the app, the API, and table WebSockets on port 8787, keeping its SQLite database in a volume. compose.yml runs it, reading settings from .env (see .env.example):

just up          # creates .env with a new SECRET_KEY if missing, then builds and starts
just setup-link  # the one-time setup link
just logs        # follow logs; also: just ps, just restart, just down, just backup

Keep .env: its SECRET_KEY decrypts stored API keys. Locally the app is at http://localhost:8787. On a public host, point DNS at it and set PUBLIC_URL=https://<domain>, TRUST_PROXY=true, and COMPOSE_PROFILES=https in .env; just up then also starts Caddy (deploy/Caddyfile), which gets the HTTPS certificate.

If the host already runs Traefik, use compose.traefik.yml instead: set COMPOSE_FILE=compose.traefik.yml and MYTHIC_HOST=<domain> in .env (plus TRAEFIK_NETWORK, TRAEFIK_ENTRYPOINT, or TRAEFIK_CERTRESOLVER if yours differ from traefik, websecure, and letsencrypt). The container joins Traefik's network and is routed by its labels; no host port is published.

See docs/PLAN.md for the design and roadmap, and docs/MULTIPLAYER.md for multiplayer.