# tic-tac-toe-ui โ€” Multiplayer Game Client (React + TypeScript + Vite) A fully functional multiplayer Tic-Tac-Toe game client built using **React + TypeScript**, powered by **Nakama WebSocket real-time networking**, and delivered as a tiny **production-optimized Vite build** (served via BusyBox/Docker). This UI communicates with the authoritative backend (`tic-tac-toe`) to deliver a secure, synced, cheat-proof multiplayer experience. --- ## ๐ŸŽฎ Overview This repository contains the front-end implementation of the Tic-Tac-Toe multiplayer platform. The client supports: * Device-based authentication * Full matchmaking lifecycle * Real-time gameplay with WebSockets * Authoritative state rendering * Leaderboard browsing * Game result screens * A Vite-powered environment system for dynamic host/SSL selection This UI is production-ready and deployable to any server or container environment. --- ## โญ Features * **React + TypeScript UI** * **WebSocket real-time gameplay** using Nakama JS * **Matchmaking flow:** queue โ†’ ticket โ†’ match โ†’ gameplay * **Authoritative state updates** (OpCode 2) * **Secure device authentication** (device UUID โ†’ session) * **Leaderboard view** over Nakama's leaderboard API * **Production Docker image:** Node โ†’ Vite โ†’ BusyBox * **Environment-based configuration** for host/SSL --- ## ๐Ÿงฉ Architecture ### Frontend System Diagram ```mermaid flowchart LR User[Browser] --> UI[React + TS + Vite] UI -->|WebSocket| Nakama UI -->|HTTP| Nakama UI --> Leaderboard[Leaderboard API] UI --> Matchmaking[Matchmaker API] ``` --- ## ๐Ÿ›  Tech Stack * **React 18** (TypeScript) * **Vite.js** (build system) * **Nakama JavaScript Client** * **Plain CSS** for styling * **WebSockets (SSL / non-SSL selectable)** * **Docker (multi-stage build)** --- ## ๐Ÿ”ง Environment Variables (Vite) These are injected at build time: ``` VITE_WS_HOST=nakama.aetoskia.com VITE_WS_PORT=443 VITE_WS_SKEY=secret VITE_WS_SSL=true ``` Meaning: * **VITE_WS_HOST** โ†’ Nakama host (domain or IP) * **VITE_WS_PORT** โ†’ Port for WebSocket/API * **VITE_WS_SKEY** โ†’ Nakama server key * **VITE_WS_SSL** โ†’ `true` for wss://, `false` for ws:// --- ## ๐Ÿ”Œ Runtime Flow ### Authentication * UI generates a device UUID * Calls `client.authenticateDevice()` * Stores session in React state ### Matchmaking 1. User selects mode (classic / blitz) 2. joins the matchmaking queue 3. Waits for matchmaker ticket 4. Auto-joins the match when assigned ### Gameplay * User sends moves via OpCode **1** * Server validates + broadcasts authoritative board via OpCode **2** * UI re-renders board state from server packets ### End of Game * Player sees win/lose/draw * Can return to home or matchmaking --- ## ๐ŸŽจ Styling Styling uses **plain CSS** via a single `styles.css` file. Simple, responsive layout using Flexbox. --- ## ๐Ÿณ Docker (Production Build) ### Dockerfile Overview ``` # Stage 1: Build FROM node:20-alpine AS builder # Set working directory WORKDIR /app # Copy package.json and package-lock.json (or yarn.lock) COPY package*.json ./ # Install dependencies RUN npm ci # Copy the rest of the app COPY . . # Build arguments ARG VITE_WS_HOST ARG VITE_WS_PORT ARG VITE_WS_SKEY ARG VITE_WS_SSL # Export them as actual environment variables (Vite needs ENV) ENV VITE_WS_HOST=${VITE_WS_HOST} ENV VITE_WS_PORT=${VITE_WS_PORT} ENV VITE_WS_SSL=${VITE_WS_SSL} # Build RUN npm run build # Stage 2: Static file server (BusyBox) FROM busybox:latest WORKDIR /app # Copy only build frontend files COPY --from=builder /app/dist /app # Expose port EXPOSE 3000 # Default command CMD ["busybox", "httpd", "-f", "-p", "3000"] ``` Produces an extremely lightweight production image. --- ## ๐Ÿงช Testing Manual testing validated: * Full matchmaking loop * Game state sync * Invalid move handling (server rejections) * Disconnect behaviour * Leaderboard retrieval Pending: * Stress tests * Mobile responsiveness * Reconnect logic --- ## ๐Ÿ“ˆ Deployment ### Supported: * Docker on any Linux host * Raspberry Pi (ARM) * Google Cloud Run / Compute Engine * Traefik reverse proxy via `games.aetoskia.com` ### Example Deployment via Docker ``` docker run -d \ -p 3003:3003 \ --restart always \ tic-tac-toe-ui:latest ``` Traefik HTTPS routes: * **games.aetoskia.com** โ†’ UI --- ## ๐Ÿ—บ๏ธ Roadmap * Rematch flow * Reconnect/resume after refresh * Improved animations * Mobile UI redesign * Centralized error handling ---