d9c3ecb2521afa1a8e287ccf08d5e9154e906e1f
- Moved common/game.go → plugins/games/rules.go
- Contains GameRules interface, MovePayload, Player abstraction
- Centralizes all reusable game rule contract logic
- Added plugins/games/config.go
- Introduces GameConfiguration struct (players, board size, etc.)
- Added global GameConfig and RulesRegistry maps
- Each game (tictactoe, battleship, etc.) now registers its config + rules
- Updated generic_match.go to use:
- GameConfig for board/players initialization
- RulesRegistry for rule lookup during MatchInit
- Removed hardcoded TicTacToe behavior
- Clean error returns when game param missing or invalid
- Updated folder structure:
/plugins/
/games
rules.go (formerly common/game.go)
config.go
tictactoe.go
battleship.go
/structs
/modules
main.go
- Ensures GenericMatch pulls:
m.GameName, m.Mode, m.Config, m.Rules
directly from config/registry at MatchInit
- Removes old duplicated logic and simplifies how games are registered
tic-tac-toe — Authoritative Multiplayer Game Server (Nakama + Go)
A production-grade, server-authoritative multiplayer backend built using Nakama 3, Go plugins, and PostgreSQL, deployed via Drone CI/CD and exposed securely through Traefik.
🚀 Overview
This repository contains a fully authoritative Tic-Tac-Toe backend built on Nakama 3.21.0 ARM, using a custom Go plugin to implement game logic, matchmaking, validation, leaderboards, and session management.
The server ensures:
- Zero client trust
- Deterministic gameplay
- Secure matchmaking
- Validated moves
- Authoritative outcomes
Designed for scalability, extensibility, and cloud deployment (GCP, AWS, or ARM homelab environments).
⭐ Key Features
- Authoritative Go match handler (
tictactoe) - Device-ID authentication + JWT session
- Matchmaking queue support
- Deterministic game validation
- Match lifecycle handling
- Disconnect handling & forfeit detection
- Leaderboards creation + scoring
- Production-grade CI/CD with Drone
- Automated ARM Docker builds
- Full Traefik routing (HTTP + WebSocket)
- Compatible with x86/ARM/GCP
🧩 Architecture
High-Level System Diagram
flowchart LR
UI[(React + Vite)] --> Traefik
Traefik --> Nakama[Nakama Server]
Nakama --> Plugin[Go Plugin]
Nakama --> Postgres[(PostgreSQL)]
Drone[Drone CI/CD] --> Registry[Private Docker Registry]
Registry --> Nakama
🛠 Tech Stack
Backend
- Nakama 3.21.0 ARM
- Go 1.21.6 (plugin ABI compatible)
- PostgreSQL 16
- Docker / multi-stage builds
- Drone CI/CD
- Traefik reverse proxy
Cloud/Infra
- GCP-ready
- ARM homelab deployments
- Private registry support
📦 Repository Structure
tic-tac-toe/
│── plugins/
│ ├── main.go
│ ├── match.go
│ └── matchmaking.go
│
│── Dockerfile
│── go.mod
│── go.sum
│── README.md
🔌 Registered Server Components
📌 Match Handler
Name: tictactoe
Handles:
- Turn validation
- State updates
- Win/loss/draw
- Disconnect forfeit
- Broadcasting authoritative state
📌 RPCs
| RPC Name | Purpose |
|---|---|
leave_matchmaking |
Allows clients to exit matchmaking queue |
📌 Matchmaker Hook
| Hook | Purpose |
|---|---|
MatchmakerMatched |
Validates matchmaker tickets and instantiates a new match |
🎮 Gameplay Protocol
OpCodes
| OpCode | Direction | Meaning |
|---|---|---|
| 1 | Client → Server | Submit move {x, y} |
| 2 | Server → Client | Full authoritative game state |
🧠 Authoritative Flow Diagram
sequenceDiagram
participant C1 as Client 1
participant C2 as Client 2
participant S as Nakama + Go Plugin
C1->>S: Matchmaker Join
C2->>S: Matchmaker Join
S->>S: MatchmakerMatched()
S-->>C1: Matched
S-->>C2: Matched
C1->>S: OpCode 1 (Move)
S->>S: Validate Move
S-->>C1: OpCode 2 (Updated State)
S-->>C2: OpCode 2 (Updated State)
⚙️ Build & Development
Build Go Plugin
CGO_ENABLED=1 go build \
--trimpath \
--buildmode=plugin \
-o build/main.so \
./plugins
Run Nakama Locally
nakama migrate up --database.address "$DB_ADDR"
nakama \
--database.address "$DB_ADDR" \
--socket.server_key="$SERVER_KEY"
🐳 Docker Build (Multi-Stage)
FROM --platform=linux/arm64 golang:1.21.6 AS plugin_builder
RUN go mod download
COPY . .
RUN CGO_ENABLED=1 go build --buildmode=plugin -o build/main.so ./plugins
FROM heroiclabs/nakama:3.21.0-arm
COPY --from=plugin_builder /workspace/build/main.so /nakama/data/modules/main.so
ENTRYPOINT ...
🤖 CI/CD — Drone Pipeline
Drone performs:
- Fetch latest Git tag
- Check if Docker image already exists
- Build Nakama + plugin
- Push to private registry
- Stop old container
- Deploy new Nakama server automatically
Full pipeline included in repository (.drone.yml).
🌐 Traefik Routing
HTTPS
nakama.aetoskia.com
/ → HTTP API
/ws → WebSocket (real-time)
Includes:
- CORS rules
- WebSocket upgrade headers
- Certificate resolver
- Secure default middlewares
🔧 Environment Variables
| Variable | Description |
|---|---|
DB_ADDR |
PostgreSQL connection string |
SERVER_KEY |
Nakama server key |
REGISTRY_HOST |
Private registry |
📊 Leaderboards
- Created during server start
- Score:
+1on win - Metadata logged (mode, player IDs)
🧪 Testing
- Win/loss/draw simulation
- Invalid move rejection
- Disconnect → forfeit
- Load testing matchmaking
📈 Production Deployment
Supported on:
- ARM homelabs (Raspberry Pi)
- Google Cloud (Compute Engine + Cloud SQL)
- AWS EC2
- Kubernetes (optional)
🤝 Contributing
- Fork repo
- Create feature branch
- Write tests
- Submit PR
Coding style: Go fmt + idiomatic Go; follow Nakama plugin constraints.
Description
Languages
Go
63.9%
Python
33.4%
Dockerfile
2.7%