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.
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:
service/mapgen)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: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
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