Tictactics

A notepad-playable browser game that combines Tic Tac Toe's line-making goal with a small capture mechanic.

Rules

  • Two players alternate placing X and O on empty cells.
  • The board is 5 x 5.
  • After placing a mark, enemy marks trapped in a straight line between the new mark and another friendly mark are captured and removed.
  • Captures can happen in any of the eight directions.
  • First player to make 4 in a row wins.
  • If the board fills with no winner, the game is a draw.

Run With Docker Compose

Optional: copy .env.example to .env and change APP_PORT.

docker compose up --build

Then open http://localhost:8787 in two browser windows. The first two connected players are paired automatically.

Set a different host port with:

$env:APP_PORT=9090; docker compose up --build

Stop it with:

docker compose down

Run Locally

npm start

Then open http://localhost:8787 in two browser windows.

Set a different port with:

$env:APP_PORT=9090; npm start

Notes

  • No authentication or user accounts are required.
  • The server keeps games in memory only.
  • If an opponent closes their window, the remaining player sees a disconnect error and waits for a new player.
  • No build step is required.

Hardening Knobs

The server is intentionally small, but it rejects common abuse cases:

  • static files are served from an allowlist only
  • HTTP responses include basic browser security headers
  • WebSocket upgrades are origin-checked
  • clients, clients per IP, message size, and message velocity are capped
  • moves are validated server-side before being relayed
  • the Compose container runs as non-root with a read-only filesystem and dropped capabilities

Optional .env settings:

APP_PORT=8787
ALLOWED_ORIGINS=https://tic.sketchferret.com
MAX_CLIENTS=200
MAX_CLIENTS_PER_IP=12
MAX_MESSAGES_PER_WINDOW=40
TRUST_PROXY=true

Use TRUST_PROXY=true only when the app is behind a reverse proxy that sets X-Forwarded-For.

Description
A notepad-playable capture tic tac toe browser game.
Readme 83 KiB
Languages
JavaScript 74%
CSS 18.4%
HTML 6.5%
Dockerfile 1.1%