Skip to content

Mrcocacola21/FATE

Repository files navigation

FATE

TypeScript npm workspaces Node.js Fastify Vite React

Deterministic turn-based game stack in a TypeScript monorepo: authoritative rules engine, Fastify + WebSocket server, and Vite + React client.

Follow active progress and implementation notes in the Developer Log.

Contents

Packages

Package Path Purpose
rules packages/rules Deterministic game engine (authoritative state updates).
server packages/server Fastify + WebSocket game server.
web packages/web React client UI.

Getting Started

Install

npm install

Run Development Stack

npm run dev

This runs:

  • rules in TypeScript watch mode (emits dist/)
  • server on http://localhost:3000
  • web on http://localhost:5173

Note: the server waits for packages/rules/dist/index.js before starting to avoid intermittent Cannot find module ... rules/dist/index.js crashes during watch startup.

Optional local env file (not required for dev):

  • Copy .env.example to .env if you want to pin API/WS URLs.

Dev Flow: Two Tabs, Same Room

  • Open http://localhost:5173
  • Create a room in the Lobby and copy the room id
  • Join as P1 in the first tab
  • Open a second tab and join the same room as P2 (or spectator)

Build

npm run build

Tests

npm run test
npm run -w web typecheck

Environment Variables (Web)

The frontend reads these at build time. In production builds they are required and the build will fail fast if missing:

  • VITE_API_URL (example: https://your-render-app.onrender.com)
  • VITE_WS_URL (example: wss://your-render-app.onrender.com/ws)
  • VITE_ENABLE_TEST_ROOM=true - shows the Test Room creator when the server also allows it. Local Vite development enables the entry automatically.

Local defaults are provided in .env.example.

Environment Variables (Server)

  • WEB_ORIGIN - allowed browser origin for CORS and WebSocket Origin checks, for example https://your-app.vercel.app.
  • FATE_DEBUG_TOKEN - production-only token for debug REST game views/actions/logs. Send it as X-FATE-DEBUG-TOKEN: <token>.
  • ENABLE_TEST_ROOMS=true - enables authoritative Test/Sandbox rooms. Development enables them by default unless explicitly set to false; production requires this flag and a matching FATE_DEBUG_TOKEN when creating the room.
  • ROOM_TTL_MS - idle room TTL before cleanup. Default: 86400000 (24 hours).
  • MAX_ROOMS - maximum in-memory FATE rooms retained. Default: 100.
  • MAX_LOG_EVENTS - maximum action log entries retained per room. Default: 5000.
  • WS_MAX_PAYLOAD_BYTES, WS_RATE_LIMIT_WINDOW_MS, WS_RATE_LIMIT_MAX_MESSAGES, RECONNECT_GRACE_MS - WebSocket payload, rate, and reconnect controls.

Local development keeps debug REST endpoints open when NODE_ENV !== "production". In production, GET /api/games/:id, POST /api/games/:id/actions, and GET /api/games/:id/log require X-FATE-DEBUG-TOKEN to match FATE_DEBUG_TOKEN. Browser WebSocket connections must use an allowed Origin; missing Origin is accepted for non-browser clients.

Test Room / Sandbox

Test rooms are server-authoritative manual QA rooms. A single controller can spawn catalog units for either side, edit HP/statuses/charges, force turns and phases, run normal attacks and abilities, queue deterministic d6 results, place stakes/forest markers, inspect pending rolls/state, load deterministic presets, and export/import bounded JSON snapshots.

Enable locally:

VITE_ENABLE_TEST_ROOM=true
ENABLE_TEST_ROOMS=true

In production, ENABLE_TEST_ROOMS=true is required and room creation must include the configured FATE_DEBUG_TOKEN. Sandbox commands are rejected for normal rooms, disabled deployments, spectators, and non-controller connections. Imported snapshots are capped and validated before replacing test-room state.

Assets (Figure Arts + Tokens)

Recommended formats:

  • WEBP preferred (best size/quality)
  • PNG allowed (if transparency is needed)
  • Token transparency: use WEBP/PNG with alpha

Suggested sizes:

  • Full art: 1024x1536 (2:3) or 1200x1800
  • Token: 256x256 or 512x512 square

File naming rules (must match figureId):

  • packages/web/src/assets/figures/<figureId>.webp
  • packages/web/src/assets/tokens/<figureId>.webp

Tips:

  • Try to keep full art under ~300-600 KB if possible
  • Assets under src/assets are bundled by Vite; if user uploads are needed later, move them to /public or external storage

Server API

  • GET / - basic server info
  • GET /health - health check
  • GET /api/health - health check (legacy)
  • POST /api/games - create a game
    • body: { "seed"?: number, "arenaId"?: string }
  • GET /api/games/:id?playerId=P1|P2 - debug player-specific state view; production requires X-FATE-DEBUG-TOKEN
  • POST /api/games/:id/actions?playerId=P1|P2 - debug GameAction submit; production requires X-FATE-DEBUG-TOKEN
  • GET /api/games/:id/log - debug action log; production requires X-FATE-DEBUG-TOKEN
  • GET /rooms - list room summaries
  • POST /rooms - create a room (returns roomId)

WebSocket

  • GET /ws
    • client -> server:
      • { type: "joinRoom", roomId, requestedRole, name? }
      • { type: "leaveRoom" }
      • { type: "action", action }
      • { type: "requestMoveOptions", unitId }
    • server -> client:
      • { type: "joinAccepted", roomId, role, connId }
      • { type: "joinRejected", reason, message }
      • { type: "roomState", roomId, room }
      • { type: "actionResult", ok, events, error?, logIndex? }
      • { type: "moveOptions", unitId, roll, legalTo }
      • { type: "error", message }

Deployment

Deployment updates are also posted in the Developer Log.

Render Deploy (Server)

Render can build from the repo root.

  • Build command: npm install && npm run -w rules build && npm run -w server build
  • Start command: npm run -w server start

Environment variables:

  • PORT (Render sets this automatically)
  • WEB_ORIGIN (set to your Vercel URL for CORS and WebSocket Origin checks)
  • FATE_DEBUG_TOKEN (required only if using debug REST endpoints in production)
  • ROOM_TTL_MS, MAX_ROOMS, MAX_LOG_EVENTS (optional in-memory bounds)
  • NODE_VERSION=22 (optional)

Notes:

  • The server binds to 0.0.0.0 and uses PORT
  • WebSockets are available at wss://<render-host>/ws

Vercel Deploy (Web)

Recommended Vercel settings:

  • Framework preset: Vite
  • Root Directory: packages/web
  • Install Command: npm install --prefix ../..
  • Build Command: cd ../.. && npm run -w web build
  • Output Directory: dist

Environment variables (required for production builds):

  • VITE_API_URL=https://<render-server>.onrender.com
  • VITE_WS_URL=wss://<render-server>.onrender.com/ws

Common Pitfalls

  • Failed to fetch in production usually means VITE_API_URL points to localhost
  • WS connection failures usually mean VITE_WS_URL should be wss://.../ws in production
  • CORS errors usually mean WEB_ORIGIN is missing or incorrect on Render

Quick Verify

  • Open the Vercel site, check Network tab: /rooms should hit your Render domain
  • Confirm WebSocket connects successfully (wss://<render-host>/ws)
  • Visit https://<render-host>/health and see { ok: true }

Notes

  • The server is authoritative: the client only sends GameAction intents
  • Per-player visibility is enforced by makePlayerView (exported from rules)
  • Avoid running Vite with --host 0.0.0.0 unless you explicitly need LAN access

Developer Log

Track implementation updates, architecture notes, and release progress in the Telegram channel:

About

Web-based interactive project inspired by the Fate setting with custom mechanics, UI, and immersive presentation.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages