- TypeScript 96.7%
- CSS 2.5%
- Just 0.4%
- JavaScript 0.2%
- Dockerfile 0.1%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
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
|
||
| deploy | ||
| docs | ||
| public | ||
| scripts | ||
| server | ||
| src | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| .oxlintrc.json | ||
| .prettierignore | ||
| .prettierrc.json | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| compose.traefik.yml | ||
| compose.yml | ||
| Dockerfile | ||
| index.html | ||
| justfile | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.app.json | ||
| tsconfig.json | ||
| tsconfig.node.json | ||
| tsconfig.scripts.json | ||
| tsconfig.server.json | ||
| vite.config.ts | ||
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.