A Procedural Geopolitical Simulation
Watch nations rise and fall in a living, breathing world of emergent geopolitics.
Features · Getting Started · Controls · Architecture · Roadmap · Contributing
- Massive maps — 2 000 × 2 000 tile worlds with per-tile data (elevation, temperature, humidity, biome, river, resource, ownership)
- Web Worker pipeline — entire terrain generation runs off the main thread with zero-copy
ArrayBuffertransfers - 26 biomes — from deep ocean and glaciers to tropical rainforests and volcanic peaks, with organic jittered boundaries
- Rivers — Minecraft-style noise zero-crossing algorithm producing primary and secondary waterways with shore tapering
- 8 resource types — Timber, Stone, Iron, Gold, Fertile Soil, Fish, Fur & Game — derived from biome, ore noise, elevation and river proximity
- Strategic locations — automatic detection of river crossings, mountain passes, straits and peninsulas scored 0–10
- Nation spawning — 12 nations placed on habitable land with procedural names, colours, flags, governments and personality traits
- Struct-of-arrays — 8 typed-array layers (Float32Array / Uint8Array) instead of 4M JS objects
- WorldMap.at(x, y) — ergonomic accessor returns a
TileInfosnapshot with biome, resource, owner, river, shore adjacency - Per-tile ownership — Uint8Array layer tracking which nation owns each tile (255 = unclaimed)
- Chunked ImageBitmap pipeline — tiles are rasterised once per view mode and cached as bitmaps
- Viewport culling — only visible chunks are drawn each frame
- Precomputed chunk layout — view switching swaps cached bitmaps into a fixed layout without recalculation
- Spatial-hash tooltip grid — O(1) strategic point lookups on hover
{ alpha: false }canvas context — lets the browser skip compositing
| Key | Mode | Visualises |
|---|---|---|
E |
Elevation | Height map (blue → green → brown → white) |
T |
Temperature | Heat map (blue → red) |
H |
Humidity | Moisture map (tan → teal) |
B |
Biome | Full 26-biome colour palette (default) |
G |
Strategic | Biome base + highlighted strategic points |
R |
Resource | Biome base + tinted resource deposits |
P |
Political | Territory colours + nation borders |
- Zustand store — single source of truth for phase routing, view mode, world data, nations
- Title screen — seed input + "New World" button with phase-based routing
- Save / Load — binary format in IndexedDB (~68 MB per 2000×2000 world)
- Tile inspector — hover tooltip showing biome · river · resource · strategic · nation (toggle:
I)
- Runs as a native Electron app (Windows, macOS, Linux)
- Also ships as a static web build deployed to GitHub Pages via CI
- Node.js 18+ and npm
- Git
git clone https://github.com/CodeByBryant/Sovereign.git
cd Sovereign
npm install# Electron (desktop)
npm run dev
# Web-only (Vite dev server)
npm run dev:web# Web build → dist/
npm run build:web
# Desktop build + package
npm run build
npm run package
# Platform-specific installers
npm run build:win
npm run build:mac
npm run build:linux| Input | Action |
|---|---|
| Click + drag | Pan the camera |
| Scroll wheel | Zoom in / out |
E |
Elevation overlay |
T |
Temperature overlay |
H |
Humidity overlay |
B |
Biome overlay |
G |
Strategic overlay |
R |
Resource overlay |
P |
Political overlay |
I |
Toggle tile inspector |
S |
Toggle toolbar |
sovereign/
├── electron/ # Electron main + preload
│ ├── main/
│ └── preload/
├── src/
│ ├── config/
│ │ └── Config.ts # Every tunable parameter in one place
│ ├── core/
│ │ ├── ai/ # (Phase 4+) AI decision systems
│ │ ├── camera/
│ │ │ └── Camera.ts # Pan / zoom state
│ │ ├── entities/
│ │ │ ├── Nation.ts # Nation class (provinces, stats, personality)
│ │ │ ├── NameGenerator.ts # Procedural nation names
│ │ │ ├── ColorGenerator.ts # Golden-angle colour spacing
│ │ │ └── FlagGenerator.ts # Procedural flag patterns
│ │ ├── rendering/
│ │ │ └── Renderer.ts # Chunked Canvas 2D draw loop
│ │ ├── simulation/
│ │ │ └── Simulation.ts
│ │ ├── state/
│ │ │ ├── GameStore.ts # Zustand global store
│ │ │ └── persistence.ts # IndexedDB save / load
│ │ ├── systems/
│ │ │ └── NationSpawner.ts # Greedy spawn + territory claiming
│ │ ├── terrain/
│ │ │ ├── biomes.ts # 26-biome classifier
│ │ │ ├── rivers.ts # Noise zero-crossing rivers
│ │ │ ├── resources.ts # 8 resource types generator
│ │ │ ├── strategic.ts # Strategic point detection
│ │ │ ├── terrain.worker.ts # Web Worker pipeline
│ │ │ └── TerrainGenerator.ts # Orchestrates all layers
│ │ └── world/
│ │ └── WorldMap.ts # Struct-of-arrays tile storage
│ ├── styles/ # SCSS w/ tokens, mixins, components
│ ├── types/
│ │ ├── resources.ts # ResourceType enum + metadata
│ │ └── tile.ts # TileInfo / TileData interfaces
│ └── ui/
│ ├── App.tsx # Phase router
│ ├── MapView.tsx # Canvas + toolbar + tooltip + worker
│ ├── TitleScreen.tsx # Seed input + New World
│ └── main.tsx # Entry point
├── public/ # Static assets
├── docs/ # Documentation
│ ├── architecture.md
│ ├── terrain.md
│ ├── nations.md
│ └── save-load.md
├── electron-builder.yml # Desktop packaging config
├── electron.vite.config.ts
└── vite.config.ts # Web-only Vite config
- Seeded simplex noise (elevation, temperature, humidity)
- 26-biome classification with organic jitter
- Chunked ImageBitmap rendering with viewport culling
- Camera pan & zoom
- River generation (primary + secondary waterways)
- Strategic point detection (river crossings, mountain passes, straits, peninsulas)
- Web Worker terrain pipeline with zero-copy transfers
- JSDoc documentation across all modules
- Struct-of-arrays tile data (WorldMap)
- 8 resource types derived from biome, ore noise, elevation & rivers
- Title screen with seed input
- Zustand state management + phase routing
- Save / Load via IndexedDB (binary format)
- Seven overlay modes (Elevation, Temperature, Humidity, Biome, Strategic, Resource, Political)
- Tile inspector tooltip
- Nation entity system with procedural names, colours, flags & personality
- Greedy spawn placement + 5 × 5 starting territories
- Political map overlay with territory colouring
- Organic expansion algorithm with terrain costs
- Border detection & rendering
- Natural borders (rivers, mountain ranges)
- Collision / conflict resolution
- Population, economy & technology growth
- Diplomacy & alliances
- Warfare (province-by-province conquest)
- Religion & culture spread
- AI decision-making (Top-K / Top-P sampling)
- God Mode (intervention tools)
- Historical timeline & statistics
See individual phase docs in
docs/for details.
Contributions are welcome! The project is in early development.
- Fork the repository
- Create a feature branch —
git checkout -b feature/your-feature - Commit your changes —
git commit -m 'Add your feature' - Push —
git push origin feature/your-feature - Open a Pull Request
- TypeScript strict mode
- ESLint + Prettier —
npm run lint:fix && npm run format - Meaningful commit messages
- Update docs when adding features
MIT — Copyright (c) 2026 Bryant Ejorh
Inspired by Ages of Conflict, WorldBox and grand strategy games
Built with Electron · React · TypeScript · simplex-noise