An open-source, web-based clone of The Settlers II: 10th Anniversary Edition
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.
- Highlights
- Architecture Overview
- Tech Stack
- Implemented Game Mechanics
- Project Structure
- Getting Started
- Network API Reference
- Game Loop & Systems
- Docker
- License
- Procedural hex maps — Perlin noise elevation & humidity with Poisson-disk resource seeding
- 32 building types & ~20 resources — Full Settlers II production chains (wood → planks, ore → steel → weapons, wheat → flour → bread, brewing, livestock, and more)
- Road logistics — Flags, carriers, donkeys, Dijkstra pathfinding, and level-2 main roads
- Military system — Recruitment, garrisons, territory projection, 1v1 duels, building capture, catapult sieges, gold promotions
- Naval gameplay — Shipyards, coastal harbors, and maritime colonization expeditions
- AI opponents — Computer-controlled players with economy and offense automation
- Fog of war — Per-player visibility filtering on every state broadcast
- Save & Load — Full game state persistence to PostgreSQL
- Victory conditions — Player elimination when all warehouses are lost
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) │
└──────────────────────────────────┘
-
Server (Quarkus / Java 25) — The game engine runs a fixed-rate game loop at 10 TPS (ticks per second). Each tick, it dequeues player commands, executes an ordered sequence of simulation systems against a single
GameState, then broadcasts a fog-of-war-filtered JSON snapshot to each connected client. All state mutations happen on the loop thread — the simulation is single-threaded and lock-free. WebSocket handlers only enqueue commands. -
Client (Nuxt 3 + WebGL) — Manages the lobby, in-game HUD, and map rendering. It receives server snapshots, interpolates unit movement for smooth 60 FPS rendering, and transmits player intentions as commands.
| 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 |
The backend is a full-fledged game engine (fr.opensettlers.*) implementing the core Settlers II gameplay loop:
- Doubled-height hex coordinate system
- Perlin noise-based terrain generation (elevation + humidity biomes)
- Poisson-disk resource seeding (
service/mapgen) - Configurable map size (default 64×64)
- Flags, roads, and road networks with Dijkstra shortest-path routing
- Carriers autonomously transporting goods between flags
- Donkeys for heavy-traffic main roads
- Level-2 main roads for upgraded throughput
- Construction site lifecycle: material delivery → earthworks → masonry → commissioning
- Specialized worker assignment upon completion
- Graduated placement rules — building size (hut / house / castle) depends on terrain slope and spacing from neighbors
- Flags placed only on valid unoccupied tiles
- 32 building types and ~20 resource types replicating Settlers II economy:
- Woodcutter → Sawmill (logs → planks)
- Mines (granite, coal, iron, gold) — each requires the matching ore vein and consumes food
- Smelter → Armory / Metalworks (ore → steel → weapons / tools / gold coins)
- Farm → Windmill → Bakery (wheat → flour → bread)
- Pig Farm + Slaughterhouse (grain → pigs → meat)
- Brewery (wheat + water → beer for soldiers)
- Each building has its own production timer tuned to original Settlers II pacing
- Resource growth — planted trees mature into harvestable lumber; wheat fields are sown, grow, and are reaped
- Geologists prospect mountain tiles, placing mineral signs
- Scouts explore fog of war around a flag
- Recruitment requires sword + shield + beer
- Garrison sizes: Barracks (2) · Guardhouse (3) · Watchtower (6) · Fortress (9)
- Headquarters is also a defensible garrison
- Lookout Tower — provides visibility without claiming territory
- Territory projection based on military building placement
- Gold-coin promotions to upgrade soldier rank
- Adjustable attack force — choose how many soldiers to commit
- 1v1 sequential duels to resolve battles
- Building capture on successful attack
- Catapult sieges for ranged bombardment
- Per-player explored area tracking
- State broadcasts filtered to each player's visible area
- Shipyard buildings to construct vessels
- Coastal harbors as naval logistics nodes
- Maritime expeditions to colonize unexplored shorelines
- Computer-controlled players that autonomously:
- Develop their economy and production chains
- Connect buildings with roads
- Launch military attacks
- Player elimination when all warehouses/headquarters are destroyed
- Game over broadcast with winner designation
- Full game-state save/load to PostgreSQL database
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
| Requirement | Version | Notes |
|---|---|---|
| Java | 25+ | GraalVM recommended for native builds |
| Node.js | 20+ | With pnpm |
| Docker | Latest | Required for PostgreSQL via Quarkus Dev Services |
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:devThe 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
cd frontend
pnpm install
pnpm dev # → http://localhost:3000| 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. |
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 |
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.
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.
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