Files
Dungeons-Ground/README.md
perfect_python500 e3b4ea7e5e
Some checks failed
CI / validate (push) Failing after 6m30s
Add widget to README.md
2026-08-15 13:20:04 +00:00

5.4 KiB

Dungeons & Ground

Made with Supabase

An English-first private web alpha for asynchronous text TTRPG campaigns. Players create private worlds with an AI coauthor, submit actions into shared rounds, and play alongside persistent AI companions. The rules engine—not the language model—owns dice and mechanical state.

Local start

cp .env.example .env
pnpm install
pnpm dev:all

Open http://localhost:3000. pnpm dev:all starts the Nuxt site and the AI worker in one terminal. To run them separately, use pnpm dev in the first terminal and pnpm dev:worker in the second.

To verify the complete hosted-Supabase multiplayer path (two temporary guests, invite, shared readiness, AI resolution, and the next round), keep dev:all running and execute pnpm smoke:multiplayer in another terminal.

Before starting either process, the root commands check the Supabase schema. If it is missing and SUPABASE_DB_URL is configured, they transactionally create all D&G tables, functions, triggers, indexes, and policies from supabase/bootstrap.sql. Copy the Session pooler URI from the Supabase Dashboard Connect panel into the root .env and replace the password placeholder with the URL-encoded database password. The database URL is server-only and must never use a NUXT_PUBLIC_ prefix.

The web and worker commands both load this root .env file explicitly. Environment variables supplied by Railway or CI take precedence over values in the file.

The UI can be built without credentials. A running Nitro server and every worker process require SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, NUXT_PUBLIC_SUPABASE_URL, and NUXT_PUBLIC_SUPABASE_ANON_KEY; startup fails with a clear error when required server credentials are missing. Redis is optional: when REDIS_URL is absent, the worker safely claims jobs from the Supabase ai_jobs outbox using short database leases and retries failed jobs up to three times.

Select OpenRouter or the official DeepSeek API with AI_PROVIDER=openrouter|deepseek and provide the matching API key. OpenRouter retains JSON Schema structured output; DeepSeek uses its official JSON mode, followed by the same Zod validation.

Use Node.js 18.20.5 or newer. The lockfile pins the web toolchain to the Node 18-compatible Nuxt 3.15, Nitro 2.10, and Vite 6 line; CI verifies the project on Node 18.20.8.

Workspace

  • apps/web — Nuxt SSR UI and Nitro API
  • apps/worker — BullMQ worker for AI world and round jobs
  • packages/shared — shared Zod contracts and domain types
  • packages/game-engine — deterministic d20 rules and state transition guards
  • supabase/migrations — PostgreSQL schema, indexes, triggers, and RLS policies

Alpha safety

  • Worlds are private by default.
  • Content is limited to 13+; explicit sexual content and sexual content involving minors are rejected.
  • AI responses are parsed against strict schemas.
  • AI can propose checks and events, but cannot directly set dice outcomes or mechanical values.
  • SRD-derived work must retain the attribution in LEGAL.md.

Production services

  1. Copy the Supabase Session pooler connection URI from Connect into SUPABASE_DB_URL. pnpm dev:all now detects an empty project and creates the complete schema automatically. pnpm db:ensure runs the same guarded bootstrap without starting the app. Manual SQL Editor installation remains available through supabase/bootstrap.sql.
  2. In Supabase Auth settings, enable Allow anonymous sign-ins. In Auth URL Configuration, set the Site URL to http://localhost:3000 and add http://localhost:3000/auth/callback as a Redirect URL. Email magic-link accounts remain optional and must be added to public.allowlist. Before external testing, enable CAPTCHA and review Supabase's anonymous sign-in rate limits so disposable guests cannot be used to evade AI quotas.
  3. Run pnpm dev:worker alongside the web process. Provision Redis only when BullMQ delivery is desired; otherwise the worker polls the Supabase outbox.
  4. Configure either OPENROUTER_API_KEY (default model deepseek/deepseek-v4-flash) or set AI_PROVIDER=deepseek with DEEPSEEK_API_KEY (default model deepseek-v4-flash, endpoint https://api.deepseek.com/chat/completions).

If the worker reports POST /rest/v1/rpc/claim_ai_job 404 and /rest/v1/profiles also returns 404, the base schema was never installed. Run the generated supabase/bootstrap.sql in the SQL Editor and restart pnpm dev:all. Do not run only 0002: it depends on the tables created by 0001.

Stage two flow

  1. Click Enter the Alpha to create a persistent guest session without email. Do not sign out or clear site storage unless you are prepared to lose that guest account. An allowlisted email magic link is still available as an alternative.
  2. Create a world in the coauthor chat, review the editable result, and confirm it.
  3. Create human characters and optional AI companions in the campaign lobby.
  4. The owner creates an expiring private invite link. Guest or allowlisted-email users join through /join/:token.
  5. Players save actions and mark them ready. The final ready action queues the round automatically; the owner can also continue without waiting.
  6. The worker resolves server-owned rolls and state, publishes narration, and opens the next round. Visible campaign tabs synchronize every two seconds and immediately when the tab regains focus.