Files
tic-tac-toe-ui/README.md
2025-12-01 08:30:29 +00:00

4.4 KiB

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

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_SSLtrue 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