MMOthello is a browser-playable experiment: Othello, but on one persistent 1000x1000 shared board. Everyone joins anonymously as Black or White, places server-validated stones, and watches the map evolve in real time.
The goal of this repo is to show a complete realtime systems project in a small, inspectable package: authoritative game rules, binary WebSocket protocol, local persistence, canvas rendering, responsive UI, and bot-driven demo traffic.
- Server-authoritative strict Othello flips on a
1000x1000board. - Anonymous two-team play balanced by players active in the last minute.
- Persistent local state using full-board snapshots plus WAL replay.
- Binary WebSocket protocol with chunk snapshots, deltas, score updates, chat, and global play activity.
- Canvas paper-map UI with pan/zoom, minimap, cooldown state, score, ping, hover preview, optimistic placement, chat, activity, and touch support.
- State-aware Node bots that subscribe to board chunks and choose legal moves, useful for demos and load checks.
- Browser smoke script for the local demo path.
- Go server: board state, rule validation, sessions, cooldowns, persistence, and WebSocket fanout.
- TypeScript client: Vite app, DOM controls, binary protocol client, and Canvas renderer.
- Node scripts: bot runner, smoke test, and inspection helpers.
# Terminal 1 - server, listens on :8080
make server-run
# Terminal 2 - client dev server
make client-install
make client-devOpen the Vite URL, usually http://127.0.0.1:5173/. If that port is busy, Vite will print another URL such as http://127.0.0.1:5174/.
For a livelier portfolio demo, run the same server with local-only limits and a shorter cooldown:
# Terminal 1 - demo server with 1s placement cooldown
( cd server && \
MMOTHELLO_COOLDOWN_MS=1000 \
MMOTHELLO_CONN_CAP=300 \
MMOTHELLO_PLACE_RATE=400 \
MMOTHELLO_PLACE_BURST=400 \
go run ./cmd/mmothello )
# Terminal 2 - client
make client-dev
# Terminal 3 - 200 legal-move bots for one hour
./scripts/loadtest/run.sh --base http://localhost:8080 --clients 200 --duration 3600 --cooldown-ms 1000Use the default 5000ms cooldown for normal play. Stop bots with Ctrl-C.
make server-test
make server-race
make client-test
( cd client && npm run build )With the server and client running, smoke-test the browser flow:
make smoke
# or:
./scripts/smoke/run.sh --url http://127.0.0.1:5173/The smoke script verifies session creation, WebSocket connection, first snapshot, score display, help toggle, placement feedback, and mobile HUD overlap.
GET /healthz- process health.GET /session- anonymous browser session bootstrap; returnssessionID,team, andcooldownMs, and setsmmothello_token.GET /stats- operational/debug JSON with board counts, connected clients, and live players by team.GET /ws- binary WebSocket traffic; browsers authenticate via cookie, bots may use?token=<hex>.
# Bot runner
./scripts/loadtest/run.sh --base http://localhost:8080 --clients 100 --duration 60
# Inspect persisted files
./scripts/inspect/run.sh --file ./server/data/meta.json
./scripts/inspect/run.sh --file ./server/data/wal.log --kind wal
./scripts/inspect/run.sh --file ./server/data/snapshot-1700000000.bin --kind snapshot