Skip to content

BleTib/cartographers-game

Repository files navigation

Cartographers - Multiplayer Board Game

A real-time multiplayer web implementation of a map-drawing board game, built with FastAPI, React, and WebSockets.

Disclaimer: This is an unofficial fan project and is not affiliated with, endorsed by, or connected to Thunderworks Games. Cartographers is a board game designed by Jordy Adan and published by Thunderworks Games. No copyrighted artwork is included in this project — all visuals are rendered programmatically. This project was built for educational and portfolio purposes.

Features

  • Real-time Multiplayer: Play with friends via WebSocket connections
  • Canvas-based Game Board: Interactive board with keyboard and mouse controls
  • Shareable Join Links: Easy game joining via URL links
  • Admin Dashboard: Monitor active sessions, view game history, player statistics
  • Scoring System: Full implementation of scoring algorithms
  • Game Replay: Review every turn at the end of a game with a step-by-step replay viewer or any previous games in admin dashboard
  • Dark Mode: Toggle between light and dark themes

Game Controls

  • WASD: Move shape position
  • Q/R: Rotate counter-clockwise/clockwise
  • F: Flip shape horizontally
  • T: Switch terrain type (if multiple available)
  • E/Enter: Place shape
  • Mouse Click: Move to position

Game Board Result Screen

Architecture

cartographers/
├── server/                 # FastAPI backend (Python)
│   └── app/
│       ├── api/           # REST & WebSocket endpoints
│       ├── core/          # Config, auth (JWT)
│       ├── models/        # Pydantic schemas
│       └── services/      # Game logic, scoring, room management
├── web/                   # React + Vite frontend (TypeScript)
│   └── src/
│       ├── components/    # GameBoard, CardDisplay, PlayerList
│       ├── hooks/         # useGameWebSocket
│       ├── pages/         # Home, Game, Join, Admin
│       ├── services/      # API client
│       └── types/         # TypeScript types
└── deploy/                # Production deployment
    ├── Dockerfile         # Multi-stage build (Node + Python + Nginx)
    ├── docker-compose.yml
    ├── nginx.conf         # Reverse proxy config
    └── .env.example       # Production env template

Quick Start

Backend

uv sync
uv run uvicorn server.app.main:app --reload --port 8000

Frontend

cd web
npm install
npm run dev

Environment Variables

For local development no .env file is needed — sensible defaults are used automatically (debug=True, dev-only JWT signing key, default admin credentials).

Session Logging

  • One JSONL logfile is created per session under server/logs/sessions/<YYYY-MM-DD>/
  • Filename format is <UTC_TIMESTAMP>_<SESSION_ID>.jsonl
  • A turn_end entry is appended after each turn with full board state for all players
  • Files are ignored by git via .gitignore

Production Deployment (Docker)

The deploy/ folder contains everything needed to run the app in production. A single Docker container runs Nginx (serving the frontend, proxying API/WebSocket) and Uvicorn (FastAPI backend).

1. Generate secrets

# SECRET_KEY — signs JWT player tokens
python -c "import secrets; print(secrets.token_urlsafe(32))"

# ADMIN_PASSWORD — for the admin dashboard
python -c "import secrets; print(secrets.token_urlsafe(16))"

2. Create .env file

cd deploy
cp .env.example .env

Edit deploy/.env and fill in:

DEBUG=false
SECRET_KEY=<paste generated key>
ADMIN_USERNAME=admin
ADMIN_PASSWORD=<paste generated password>
FRONTEND_BASE_URL=https://your-domain.com

3. Build and run

cd deploy
docker compose up -d

The app is available at http://localhost:8080.

Production safety checks

When DEBUG=false, the server refuses to start if:

  • SECRET_KEY is not set
  • ADMIN_PASSWORD is still the default (admin123)

Swagger/ReDoc docs are disabled in production.

What runs in the container

  • Nginx (port 8080) — serves built React frontend, proxies /api/ and /ws/ to backend
  • Uvicorn (internal port 8000) — runs FastAPI backend
  • Security headers, rate limiting (30 req/s), WebSocket timeout (3h)
  • Runs as non-root user

API Endpoints

Sessions (invite key required)

  • GET /api/sessions/{code}?key=INVITE_KEY - Get session details
  • POST /api/sessions/{code}/join?key=INVITE_KEY - Join a session (returns JWT)

Admin (Basic Auth required)

  • POST /api/admin/sessions - Create new session
  • GET /api/admin/stats - Dashboard statistics
  • GET /api/admin/sessions/active - Active sessions
  • DELETE /api/admin/sessions/{code} - Delete a session

WebSocket

  • WS /ws/game/{session_code}?token=JWT - Game connection (token from /join)

License

This project is licensed under the MIT License — see LICENSE for details.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors