# Wizard online An online version of the card game Wizard (rules: `wizard_instructions/`). | Component | Path | Tech | |-----------|------|------| | Frontend | `wizard_website/` | React + TypeScript + Vite, CSS modules, served by nginx | | Game server | `wizard_server/` | Python, FastAPI, websockets | | Game logic | `wizard_server/game_logic/` | Pure Python package `wizard_game` (no dependencies) | | AI player | `wizard_ai/` | Python; RL training skeleton + websocket service | ``` browser ──wss /api/ws──▶ Caddy ──▶ wizard_server ◀──ws /internal/ai── wizard_ai ──https /──────▶ Caddy ──▶ wizard_website (network wizard_internal) ``` ## How it works 1. A player opens the website, enters a name and creates a lobby (and joins it). 2. The lobby shows a code (and an invite link, `?lobby=CODE`) others use to join. 3. The host can add AI players, toggle the *not equal* / *hidden bids* rules, and start the game (3–6 players). 4. The server runs the game with `wizard_game` and sends every player a personal view (`Observation`) after each move. Reloading the page reconnects to the same seat. A player who leaves a running game is replaced by an AI player. 5. When an AI seat has to act, the server sends its `Observation` to the AI service over the internal websocket and applies the answered action. If the AI service is unavailable or too slow, a random legal move is played so games never get stuck. The `Observation` / action JSON format is defined once in `wizard_game` and shared by the frontend, the server and the AI, so AI models see exactly the same data in training and in production. ## Deployment ```bash cp .env.example .env # set AI_SHARED_SECRET docker network create wizard_website # if they don't exist yet docker network create wizard_api docker compose up -d --build ``` - `wizard_website` joins the external network `wizard_website` (port 8082). - `wizard_server` joins the external network `wizard_api` (port 8083) and `wizard_internal`. - `wizard_ai` joins only `wizard_internal`, created by compose as an internal network. Add a site block like `Caddyfile.example` to the existing Caddy container: `/api/*` goes to `wizard_server:8083`, everything else to `wizard_website:8082`. Trained AI checkpoints go into `wizard_ai/models/latest/` (mounted read-only). Until one exists the AI service uses the built-in heuristic player. ## Development ```bash python -m venv .venv && . .venv/bin/activate pip install -r wizard_server/requirements-dev.txt -r wizard_ai/requirements-dev.txt (cd wizard_server && uvicorn app.main:app --reload) # :8000 (cd wizard_ai && python -m wizard_ai serve) # connects to :8000 (cd wizard_website && npm install && npm run dev) # :5173 (cd wizard_server && pytest) # game logic + server tests (cd wizard_ai && pytest) ```