Skip to content

tim1234ltp/Katanian

Repository files navigation

⚔️ Katanian

An API-first, headless strategy game inspired by Travian. Build villages, train armies, research technologies, forge alliances, and conquer the map — all through a REST API with a React frontend.

Architecture

┌──────────────────────────────────────────────────────────┐
│                      Frontend                            │
│              React + TypeScript + Vite                    │
│              (SPA served by Nginx)                        │
└─────────────────────┬────────────────────────────────────┘
                      │ HTTP / REST
┌─────────────────────▼────────────────────────────────────┐
│                    API Server                            │
│           Go (Echo) — cmd/api                            │
│   • Authentication (GitHub/Discord OAuth)                │
│   • REST endpoints for all game actions                  │
│   • OpenAPI spec + Swagger UI at /docs                   │
│   • Reads state directly from DB (CRUD)                  │
└──────┬──────────────────────────────────────┬────────────┘
       │                                      │
       │  pgx                          Redis (Asynq)
       │                                      │
┌──────▼──────────────────────────────────────▼────────────┐
│                   Game Server                            │
│           Go — cmd/server                                │
│   • Background tick loop (resource production)           │
│   • Task queue worker (building, training, combat)       │
│   • Map generation & seeding                             │
│   • Deterministic game simulation                        │
└──────┬──────────────────────────────────────┬────────────┘
       │                                      │
┌──────▼──────────┐                ┌──────────▼───────────┐
│  PostgreSQL 15  │                │     Redis 7          │
│  Source of truth │                │  Task queue (Asynq)  │
│  All game state  │                │  Rate limiting       │
└─────────────────┘                └──────────────────────┘

The game uses a hybrid active-ticking architecture:

  • The API Server handles HTTP requests and acts as a stateless CRUD gateway.
  • The Game Server runs a background loop that ticks every second, processing resource production, task completions, troop movements, and combat.
  • PostgreSQL is the single source of truth. All state mutations go through database transactions with SELECT ... FOR UPDATE to prevent race conditions.
  • Redis powers the async task queue (via Asynq) and rate limiting.

Tech Stack

Layer Technology
Backend Go 1.24, Echo web framework
Database PostgreSQL 15 (via pgx/v5 + sqlc)
Task Queue Redis 7 + Asynq
Frontend React 18, TypeScript, Vite, TailwindCSS
Auth GitHub + Discord OAuth (Goth)
API Spec OpenAPI 3.0 + oapi-codegen
Observability OpenTelemetry → Jaeger + Prometheus
Deployment Docker Compose, Nginx reverse proxy

Quick Start

The fastest way to run Katanian locally — one command, everything in Docker:

# Clone the repo
git clone https://github.com/tim1234ltp/Katanian.git
cd Katanian

# Start everything (PostgreSQL, Redis, API, Game Server, Jaeger, Prometheus)
docker compose -f docker-compose.localdev.yml up --build

The game will be available at:

Note: Auth is disabled by default in local dev (AUTH_DISABLED=true). You'll be logged in as the first user automatically.

Frontend (Development Mode)

To run the frontend with hot-reload:

cd web
npm install
npm run dev

The Vite dev server runs on http://localhost:5173 and proxies API calls to the backend.

Development Setup

Prerequisites

  • Go 1.24+
  • Node.js 20+ and npm
  • Docker and Docker Compose
  • sqlc (go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest)

Running Without Docker

If you prefer running services natively:

  1. Start PostgreSQL and Redis locally
  2. Initialize the database:
    psql -U postgres -d katanian -f sql/schema.sql
    # Optional: load demo data
    psql -U postgres -d katanian -f sql/demo.sql
  3. Copy and configure environment:
    cp .env.example .env
  4. Run the servers:
    # Terminal 1: API Server
    make run-api
    
    # Terminal 2: Game Server
    make run-server

Key Makefile Targets

Command Description
make build Build API and Game Server binaries
make unittest Run unit tests (excludes integration)
make integration Run integration tests (requires PostgreSQL)
make sqlc Regenerate Go code from SQL queries
make oapi Regenerate Go code from OpenAPI spec
make local-up Start local dev environment via Docker Compose
make local-down Stop local dev environment
make uat-up Start UAT environment (with AI bots)
make fmt Format all Go code

Project Structure

├── api/
│   └── openapi.yaml          # OpenAPI 3.0 specification
├── cmd/
│   ├── api/                   # API Server entrypoint
│   ├── server/                # Game Server entrypoint
│   ├── bot/                   # AI bot player (for testing)
│   └── tools/                 # CLI utilities
├── config/
│   ├── config.go              # Application config (env vars)
│   ├── jaeger/                # Jaeger tracing config
│   ├── prometheus/            # Prometheus metrics config
│   └── redis/                 # Redis config
├── docker/
│   ├── Dockerfile.*           # Multi-stage Dockerfiles
│   ├── gateway/               # Nginx gateway config
│   └── docker-compose.gateway.yml
├── integration/               # Integration tests
├── internal/
│   ├── api/                   # Generated OpenAPI handlers
│   ├── auth/                  # OAuth (GitHub, Discord)
│   ├── db/                    # sqlc-generated DB layer
│   ├── game/                  # Core game engine
│   │   ├── engine.go          # Resource production, building, training
│   │   ├── combat.go          # Combat simulation
│   │   ├── missions.go        # Troop movement & mission logic
│   │   └── settlement.go      # Village settling
│   ├── gamedata/              # Static game data (YAML-driven)
│   │   └── data/              # buildings.yaml, units, etc.
│   ├── middleware/            # Auth guard, rate limiting, telemetry
│   ├── payment/               # Stripe integration (optional)
│   ├── queue/                 # Task queue (Outbox → Asynq)
│   ├── server/                # HTTP handlers + game server loop
│   ├── telemetry/             # OpenTelemetry setup
│   └── worker/                # Asynq worker handlers
├── sql/
│   ├── schema.sql             # Database schema (PostgreSQL DDL)
│   ├── queries/               # SQL queries (used by sqlc)
│   ├── demo.sql               # Demo data for local dev
│   └── prod.sql               # Production seed data
├── web/                       # React frontend (Vite + TypeScript)
├── docker-compose.localdev.yml   # Local development
├── docker-compose.uat.yml        # UAT with AI bots
├── docker-compose.prod.yml       # Production deployment
├── docker-compose.beta.yml       # Beta deployment
├── Makefile
├── sqlc.yaml
└── .env.example

Configuration

All configuration is done through environment variables. See .env.example for the full list.

Key variables:

Variable Default Description
DATABASE_URL postgres://postgres:password@localhost:5432/katanian?sslmode=disable PostgreSQL connection string
REDIS_ADDR localhost:6379 Redis address
PORT 8080 API server port
AUTH_DISABLED false Skip authentication (dev only)
TIME_MULTIPLIER 1.0 Game speed multiplier (e.g., 5.0 = 5x speed)
ALLOWED_ORIGINS http://localhost:5173,http://localhost:8080 CORS allowed origins (comma-separated)
BASE_URL http://localhost:8080 Public URL for OAuth callbacks

API Documentation

The full API is documented via OpenAPI 3.0. When the server is running:

Authentication

For local development with AUTH_DISABLED=true, pass any UUID as the session_token cookie or X-API-Key header.

For production, Katanian supports:

  • GitHub OAuth — set GH_OAUTH_KEY and GH_OAUTH_SECRET
  • Discord OAuth — set DISCORD_OAUTH_KEY and DISCORD_OAUTH_SECRET
  • API Keys — generated per-user via /v1/account/keys

Example: Create a Village Building

curl -X POST http://localhost:8080/v1/village/{village_id}/construct \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key" \
  -d '{"building_type": "barracks", "slot_id": 22}'

Game Features

  • 🏘️ Village Building — 20+ building types with upgrade trees and resource costs
  • ⚔️ Combat — Attack, raid, reinforce, and scout with detailed battle reports
  • 🔬 Research — Academy tech tree to unlock advanced units
  • 🗺️ World Map — Procedurally generated hex map with oases and wilderness
  • 🤝 Alliances — Create and manage player alliances
  • 🦸 Heroes — Hero system with adventures, items, and equipment
  • 🏛️ Celebrations — Small and large celebrations for culture points
  • 🏪 Marketplace — Trade resources between villages
  • 🤖 AI Bots — Built-in bot players for testing (Romans, Gauls, Teutons)
  • 📊 Observability — Full distributed tracing (Jaeger) and metrics (Prometheus)

Testing

# Unit tests only
make unittest

# Integration tests (requires PostgreSQL running)
make integration

# Full QA suite (spins up everything + runs integration tests)
make qa-up

Deployment

Docker Compose (Recommended)

  1. Copy and configure your environment:

    cp .env.example .env
    # Edit .env with your production values:
    #   POSTGRES_PASSWORD, BASE_URL, OAuth keys, etc.
  2. Bootstrap a VM (Ubuntu/Debian):

    chmod +x scripts/bootstrap-vm.sh
    ./scripts/bootstrap-vm.sh
  3. Start production services:

    make prod-up

With Cloudflare Tunnel

For HTTPS without port forwarding, set the TUNNEL_TOKEN env var. The production Docker Compose includes a Cloudflare Tunnel sidecar.

CI/CD

The repo includes GitHub Actions workflows:

  • go.yml — Builds, lints, and tests Go code on every push
  • web.yml — Lints and builds the frontend on every push
  • deploy.yml — Manual deployment to a VM via workflow_dispatch

Contributing

Contributions are welcome! Here's how to get started:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/my-change)
  3. Run tests (make unittest)
  4. Commit your changes
  5. Open a Pull Request

Please ensure:

  • Go code is formatted (go fmt ./...)
  • New game logic has unit tests
  • SQL changes include both schema updates and sqlc queries

License

This project is licensed under the MIT License — see the LICENSE file for details.

About

An API-first, headless strategy game inspired by Travian.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors