OpenSettlers

OpenSettlers

An open-source, web-based clone of The Settlers II: 10th Anniversary Edition

Get Started License: GPL-3.0 Java 25 Quarkus Nuxt 3


OpenSettlers faithfully recreates the classic Settlers II: 10th Anniversary experience as a modern web application. The project features procedural map generation, complete production chains, road logistics, military expansion, naval expeditions, and AI opponents — all powered by a real-time, authoritative-server architecture.

Note: This is a fan-made, non-commercial project. It is not affiliated with or endorsed by Ubisoft or Blue Byte.


Table of Contents

  1. Highlights
  2. Architecture Overview
  3. Tech Stack
  4. Implemented Game Mechanics
  5. Project Structure
  6. Getting Started
  7. Network API Reference
  8. Game Loop & Systems
  9. Docker
  10. License

Highlights


Architecture Overview

OpenSettlers follows a strict client-server model where the server is the single source of truth:

┌──────────────────────────────────┐     WebSocket (JSON)     ┌───────────────────────────┐
│         Backend (Quarkus)        │◄────────────────────────►│    Frontend (Nuxt 3)      │
│                                  │                           │                           │
│  ┌────────────────────────────┐  │   REST (Lobby, Saves)    │  ┌───────────────────────┐ │
│  │  Game Engine (10 TPS)      │  │◄────────────────────────►│  │  WebGL Map Renderer   │ │
│  │  ┌──────────────────────┐  │  │                           │  │  Vue 3 HUD & Lobby    │ │
│  │  │ Ordered Systems      │  │  │                           │  │  Composable State     │ │
│  │  │ (AI → Combat → ...   │  │  │                           │  └───────────────────────┘ │
│  │  │  → Victory)          │  │  │                           │                           │
│  │  └──────────────────────┘  │  │                           └───────────────────────────┘
│  │  Single-threaded, lockless │  │
│  └────────────────────────────┘  │
│                                  │
│  PostgreSQL (Hibernate Panache)  │
└──────────────────────────────────┘

Tech Stack

Layer Technology Role
Backend Quarkus 3.37 (Java 25) Game engine, dependency injection (ArC), scheduler
Persistence PostgreSQL + Hibernate Panache Game save/load via Active Record pattern
Real-time Quarkus WebSockets Next Non-blocking reactive WebSocket for state broadcasting
Serialization Jackson JSON serialization for messages and snapshots
Frontend Nuxt 4 (Vue 3) Reactive UI, HUD, shared client state via composables
UI Components shadcn-nuxt + Radix Vue Accessible, composable UI primitives
Styling Tailwind CSS 4 Utility-first styling
Code Gen Lombok Boilerplate reduction (@Data, @Builder, etc.)
Build Tools Maven (backend) · pnpm (frontend) Build and dependency management
CI/CD GitHub Actions Automated frontend deployment to GitHub Pages

Implemented Game Mechanics

The backend is a full-fledged game engine (fr.opensettlers.*) implementing the core Settlers II gameplay loop:

Procedural Hex Map

Logistics & Transport

Construction & Building

Production Chains

Geologists & Scouts

Military

Fog of War

AI Opponents

Victory & Persistence


Project Structure

OpenSettlers/
├── backend/                          # Quarkus server (Java 25)
│   ├── src/main/java/fr/opensettlers/
│   │   ├── utils/                    # Coordinates, GameConfig (all tuning constants)
│   │   │   └── enums/                #   Terrain, resource, building & unit enums
│   │   ├── entities/                 # Game model, grouped by domain
│   │   │   ├── building/             #   Building hierarchy + BuildingFactory
│   │   │   │                         #     (production, military, storage, shipyard, catapult…)
│   │   │   ├── unit/                 #   Carrier, Donkey, Worker, Soldier, Ship
│   │   │   ├── world/                #   MapTile, Flag, Road, NaturalResourceNode
│   │   │   └── resource/             #   ResourceStack, ResourceSlot, Recipe
│   │   ├── state/                    # GameState, GameSession, RoadNetwork,
│   │   │                             #   TerritoryManager, FogOfWarManager
│   │   ├── systems/                  # Simulation systems (one per mechanic)
│   │   │   ├── ISystem.java          #   Common system interface
│   │   │   ├── AiSystem.java         #   AI decision-making
│   │   │   ├── VictorySystem.java    #   Elimination & win detection
│   │   │   ├── economy/              #   Production, Economy, Worker, Construction
│   │   │   ├── transport/            #   Transport & Donkey (road logistics)
│   │   │   ├── military/             #   Military, Combat, Catapult, Movement
│   │   │   ├── exploration/          #   Geologist, Scout, Naval
│   │   │   └── world/                #   Growth, Vision
│   │   ├── service/                  # Game orchestration
│   │   │   ├── GameEngine.java       #   Fixed-rate game loop
│   │   │   ├── GameActions.java      #   Player command handlers
│   │   │   ├── commands/             #   Command model
│   │   │   └── mapgen/               #   Perlin noise, Poisson-disk, map gen
│   │   ├── controller/               # REST endpoints + WebSocket + DTOs
│   │   └── persistence/              # Panache entities, snapshots, save service
│   ├── src/test/java/                # JUnit 5 test suite
│   ├── src/main/resources/           # application.properties (Dev Services PostgreSQL)
│   └── pom.xml
│
├── frontend/                         # Nuxt 4 client
│   ├── app/
│   │   ├── components/
│   │   │   ├── game/                 # In-game UI components
│   │   │   │   ├── GameCanvas.vue    #   WebGL hex map renderer
│   │   │   │   ├── GameHud.vue       #   Heads-up display overlay
│   │   │   │   ├── BuildPalette.vue  #   Building selection panel
│   │   │   │   ├── Minimap.vue       #   Overview minimap
│   │   │   │   ├── SelectionPanel.vue#   Selected entity details
│   │   │   │   └── ...              #   Military, inventory, distribution dialogs
│   │   │   ├── menu/                 #   Main menu & lobby
│   │   │   └── ui/                   #   Reusable UI primitives (shadcn)
│   │   ├── composables/              # Vue composables
│   │   │   ├── useGameSession.ts     #   WebSocket connection & state sync
│   │   │   ├── useGameApi.ts         #   REST API client
│   │   │   ├── useCamera.ts          #   Map camera controls
│   │   │   └── useHotkeys.ts         #   Keyboard shortcuts
│   │   ├── pages/                    # Nuxt file-based routing
│   │   └── types/                    # TypeScript type definitions
│   ├── nuxt.config.ts
│   └── package.json
│
├── .github/workflows/deploy.yml      # GitHub Actions: frontend → GitHub Pages
└── LICENSE                           # GNU GPLv3

Getting Started

Prerequisites

Requirement Version Notes
Java 25+ GraalVM recommended for native builds
Node.js 20+ With pnpm
Docker Latest Required for PostgreSQL via Quarkus Dev Services

Backend

cd backend

# Set JAVA_HOME to a JDK 21+ (macOS example)
export JAVA_HOME=$(brew --prefix openjdk)

# Start in dev mode (auto-provisions PostgreSQL via Docker)
./mvnw quarkus:dev

The backend will be available at:

Endpoint URL
Quarkus Dev UI http://localhost:8080/q/dev/
REST API (Lobby) http://localhost:8080/games
WebSocket (Game) ws://localhost:8080/game/{gameId}

Unit tests do not require Docker: ./mvnw test

Frontend

cd frontend
pnpm install
pnpm dev        # → http://localhost:3000

Network API Reference

REST — Lobby & Saves

Method Endpoint Description
POST /games Create a new game. Body: {"playerCount": 2, "aiPlayers": 1}. Returns gameId.
GET /games List all active games.
DELETE /games/{gameId} Stop and remove a game.
POST /games/{gameId}/save Save a running game. Body: {"name": "..."}.
GET /saves List all saved games.
POST /saves/{saveId}/load Restore a saved game as a new active game.

WebSocket — Real-time Game State

Connect to ws://localhost:8080/game/{gameId}?playerId=N (omit playerId to join as spectator).

Server → Client messages:

Type When Payload
MAP On connect Terrain tiles, elevation, natural resources
STATE Every tick Buildings, flags, roads, carriers, workers, soldiers, ships, territory (fog-filtered)
GAME_OVER Game ends Winner designation

Client → Server commands:

Command Description
BUILD_BUILDING Place a building at a hex coordinate
DESTROY_BUILDING Demolish a building
PLACE_FLAG Place a flag on a valid tile
LINK_FLAGS Build a road between two flags
ATTACK_BUILDING Attack an enemy building (optional attackerCount)
SEND_GEOLOGIST Dispatch a geologist to prospect from a flag
SEND_SCOUT Dispatch a scout to explore from a flag
SET_PRODUCTION Toggle production on/off for a building
SET_COIN_DELIVERY Enable/disable gold coin delivery to a military building
SET_DISTRIBUTION Configure resource distribution priorities
SET_MILITARY Adjust garrison occupation settings

Game Loop & Systems

At each tick, the GameEngine dequeues all pending player commands, then executes simulation systems in strict order:

AI → Military → Combat → Catapults → Movement → Geologists → Scouts
→ Workers → Growth → Economy → Construction → Production → Transport
→ Donkeys → Naval → Vision → Victory

Each system implements the ISystem interface and operates exclusively on the shared GameState. After all systems execute, a fog-of-war-filtered state snapshot is broadcast to each connected player.

All game balance constants — tick rate, distances, garrison sizes, production timers, AI parameters, naval settings — are centralized in GameConfig.java for easy tuning.


Docker

The backend ships with multiple Dockerfiles in backend/src/main/docker/:

Dockerfile Description
Dockerfile.jvm Standard JVM-based image
Dockerfile.legacy-jar Legacy JAR packaging
Dockerfile.native GraalVM native image
Dockerfile.native-micro Minimal native image (micro base)

In dev mode, PostgreSQL is auto-launched via Quarkus Dev Services — no manual Docker setup needed.


License

This project is licensed under the GNU General Public License v3.0 — see the LICENSE file for details.


Built as a tribute to The Settlers II: 10th Anniversary Edition by Blue Byte