14 KiB
AGENTS.md — RTS Civilization Game Engine Architecture & Roadmap
This document serves as the primary technical specification, architecture reference, and development guide for AI agents and developers implementing an RTS Civilization game (Real-Time Strategy / 4X hybrid) on top of this hexagonal 3D terrain engine.
0. Mandatory Agent Rules
0.1 All Values Must Be Configurable via YAML
Important
Strict Agent Directive: All gameplay values, numeric parameters, costs, multipliers, initial statistics, thresholds, ratios, yields, and game limits mentioned by the user MUST be implemented as configurable parameters loaded from YAML files (in the
config/directory) rather than being hardcoded in C++ code.
- Whenever a new value, parameter, or mechanic is introduced, create or update a corresponding YAML configuration file and load it at startup.
- Default values in C++ must only serve as fallbacks if the YAML key is absent.
- Keep configurations modular (e.g.
config/city.yaml,config/terrain_yields.yaml,config/game.yaml,config/units/*.yaml).
0.2 English Language & Externalized UI Text (Localization)
Important
Strict Agent Directive: Everything in the application must be in English.
- Language Requirement: All source code, identifiers, variable and class names, comments, documentation, and user-facing text MUST be written in English.
- External UI String Catalog: Any text, label, prompt, message, tooltip, menu item, dialog, or UI notification displayed on the screen MUST NOT be hardcoded in C++ source files.
- File-based Translations: Screen texts must be loaded dynamically from a designated external string/localization file (e.g.
config/strings_en.yamlorconfig/localization/en.yaml) containing the English translations/texts.- Key-Based Lookup: Code must reference screen texts exclusively by localization keys (e.g.
localization.get("ui.button.found_city")or equivalent lookup) resolving to the external file.- Whenever new on-screen text is introduced, add its English translation entry to the external string file first before referencing its key in code.
1. Project Vision & Core Concept
Goal: Transform this 3D hexagonal terrain engine into a seamless Real-Time Strategy Civilization game.
Gameplay Formula:
- Civilization Depth (4X): Hex-based empire building, city founding, tile improvements (farms, mines, lumber mills), territory border expansion, technology tree, and resource economy (Food, Production, Gold, Science, Culture).
- RTS Dynamics: Continuous real-time simulation (with pause/speed controls) rather than strict turn-waiting. Units move, scout, build, and fight in real time with tactical unit control, responsive pathfinding, and dynamic skirmishes.
- Visual Realism: Modern OpenGL 4.0 rendering with realistic heightmaps, animated procedural water, smooth multi-biome blending (grassland, forest, desert, tundra, red rock canyon, snow-capped mountains), and hex-edge river networks.
2. Existing Codebase Architecture
The project is built on C++, Qt (Widgets & OpenGL), and OpenGL 4.0 Core Profile.
Key Source Files & Responsibilities:
terrain.h:- Map dimensions:
MAP_WIDTH = 300,MAP_HEIGHT = 125(total 37,500 hexagons). - Hex geometry constants:
LOD_0_SIZE = 1.0f,LOD_0_SIZE_Y = 0.4328799f. - Staggered column neighbor resolution:
getHexNeighbor(x, y, edge, &nx, &ny). - Edge midpoints:
getHexEdgeMidpoint(edge)for river routing. - Data structure
TerrainPoint: height, biome type, river flags.
- Map dimensions:
tile.h&tile.cpp:- Hexagon subdivision into triangles (LOD system: 6 base triangles subdivided
\times 4 \times 4 = 96triangles per hex). - Per-vertex elevation sampling from
heightmap.jpg(scaled to3.5\text{ km}peak height) with riverbed depression carving. - Smooth neighbor-aware normal generation across hex seams.
- Triplanar texture binding: grass, rock cliff, sand beach, animated water, snow, sahara, tundra, red sand, red rock canyon, and woodland forest.
- Hexagon subdivision into triangles (LOD system: 6 base triangles subdivided
qscenerenderer.h&qscenerenderer.cpp:QOpenGLWidgetsubclass managing camera view, rotation, and mouse interaction.- Interactive orthographic hex-tile minimap with camera viewport outline, drag-to-pan, and zoom controls.
shaders/simple.vert&shaders/simple.frag:- GLSL 400 shaders.
- Biome typemap sampling and altitude/latitude-based snowline (
2.5\text{ km}temperate, down to sea-level at polar caps). - Procedural dynamic dual-wave ocean and riverbed water rendering.
generate_rivers.py:- Python map preprocessor for strict hex-edge river connectivity and orthographic minimap generation.
Coordinate Systems:
- Grid Coordinates:
(tx, ty)with0 \le tx < 300and0 \le ty < 125. - World Coordinates:
\text{worldX} = tx \times 0.75\text{worldY} = ty \times (2.0 \times \text{LOD\_0\_SIZE\_Y}) + (tx \% 2 == 0 \; ? \; 0.0 : \text{LOD\_0\_SIZE\_Y}) - Elevation (Z):
0.0at sea level; land rises up to\approx 3.5\text{ km}.
3. Game Systems Architecture
To implement the RTS Civilization game, develop modular subsystems decoupled from the raw rendering loop:
+-------------------+
| GameManager |
+---------+---------+
|
+-----------------+--------+--------+-----------------+
| | | |
+----+----+ +-----+-----+ +-----+-----+ +-----+-----+
| Faction | | Unit | | City | | Economy & |
| Manager | | Manager | | Manager | | Tech Tree |
+----+----+ +-----+-----+ +-----+-----+ +-----+-----+
| | | |
| +-------+-------+ | |
| | Pathfinding | | |
| | (Hex A*) | | |
| +---------------+ | |
+-----------------+-----------------+ |
| |
+--------+--------+ |
| Fog of War / | |
| Visibility |<-------------------------+
+--------+--------+
|
+--------+--------+
| QSceneRenderer | (OpenGL Viewport + UI Overlays)
+-----------------+
4. Agents & Unit Specifications
Units are autonomous or player-directed entities traversing the hex map in real time.
4.1 Unit Types
-
Civilian Units:
- Settler: Consumed to found a new City Center on valid land tiles (cannot settle on water or mountains).
- Worker / Builder: Constructs tile improvements (Farms, Mines, Lumber Mills, Quarries, Roads) and repairs pillaged tiles. Can be automated via worker AI.
- Trader / Caravan: Establishes land or sea trade routes between cities, providing continuous Gold, Food, and Production.
-
Military Units (RTS Combat):
- Melee: Scout
\rightarrowWarrior\rightarrowSwordsman\rightarrowMusketman\rightarrowInfantry. - Ranged: Archer
\rightarrowCrossbowman\rightarrowField Cannon\rightarrowArtillery. - Cavalry: Horseman
\rightarrowKnight\rightarrowCavalry\rightarrowTank (high movement speed, flanking bonuses). - Siege: Catapult
\rightarrowTrebuchet\rightarrowBombard (high bonus damage against city walls). - Naval: Galley
\rightarrowCaravel\rightarrowFrigate\rightarrowBattleship (operates only on water hexes).
- Melee: Scout
4.2 Unit Data Model (Unit.h)
enum class UnitType { Settler, Worker, Warrior, Archer, Horseman, Galley };
enum class UnitState { Idle, Moving, Attacking, Harvesting, Building, Fortified };
class Unit {
public:
int id;
int factionId;
UnitType type;
UnitState state;
// Grid Position & Smooth Real-time World Position
int tileX, tileY;
QVector3D worldPosition;
QVector3D targetPosition;
float moveProgress; // 0.0 to 1.0 between hexes
// Attributes
float health, maxHealth;
float attackDamage;
float defense;
float movementSpeed; // hexes per second
float visionRange; // in hex radius
// Path & Target
std::vector<std::pair<int, int>> currentPath;
int targetEntityId; // target unit or city
void update(float deltaTime);
void commandMoveTo(int destX, int destY);
void commandAttack(int targetId);
void commandBuildImprovement(int improvementType);
};
4.3 Real-time Hex Pathfinding (Pathfinder.h)
- Implement A* over the hexagonal grid with cost functions:
- Flatland (Grassland/Plains): Base cost
1.0. - Forest / Jungle: Cost
2.0. - Hills: Cost
2.0. - River Crossing: Penalty
+1.5(unless road/bridge is present). - Mountain / Deep Water: Impassable for land units.
- Friendly vs Enemy Hexes: ZOC (Zone of Control) penalties near hostile military units.
- Flatland (Grassland/Plains): Base cost
5. Cities, Territory & Improvements
5.1 City Architecture
- City Founding: Consumes a Settler. Claims the center hex and immediate ring of 6 adjacent hexes.
- Borders: Expanding territory based on accumulated Culture.
- Hex Yields:
- Food: Drives city population growth (
Pop = 1, 2, 3 \dots). - Production (Hammers): Contributes to the active construction queue (units, buildings, wonders).
- Gold: Empire treasury for unit upkeep, tile purchasing, and rush production.
- Science: Advances active technology research in real time.
- Culture: Expands borders and advances civics/policies.
- Food: Drives city population growth (
5.2 Tile Improvements
- Farm: Built on Grassland/Plains/Floodplains (
+2\text{ Food}, river adjacency bonus). - Mine: Built on Hills (
+2\text{ Production}). - Lumber Mill: Built on Forest (
+1\text{ Production}, preserves forest defense). - Road: Built along hex edges/centers to reduce movement cost to
0.33.
6. AI Agent Behavior (Civilization Empire AI)
AI opponents must operate through a hierarchical decision architecture:
- Strategic Commander (Empire Level):
- Assesses empire needs: expansion, military defense, economic development, or technology rush.
- Queues city construction and manages empire-wide resource allocation.
- Operational Commander (Theater Level):
- Coordinates multi-unit formations (e.g. Settler with Warrior escort; army squads containing front-line melee and rear-line archers).
- Manages tactical skirmishes, city sieges, and territorial defense.
- Tactical Agent (Unit Level):
- Implements Utility AI or Behavior Trees:
- Worker AI: evaluates unworked tiles in city radius and constructs optimal improvements.
- Scout AI: moves toward unrevealed fog of war while avoiding hostile barbarians.
- Military AI: attacks vulnerable targets, retreats when health drops below
30\%, uses terrain defense bonuses.
- Implements Utility AI or Behavior Trees:
7. Fog of War & Vision System
- Three Visibility States:
- Unexplored (Black): Never seen. No terrain, no entities.
- Explored / Fog of War (Grayscale/Dimmed): Previously discovered terrain and static cities visible; enemy units hidden.
- Visible (Full Color): Currently within line-of-sight of any friendly unit or city.
- GPU Texture Mask:
- Maintain a
300 \times 125texture updated on the CPU / compute shader representing visibility(0 = \text{black}, 128 = \text{fog}, 255 = \text{visible}). - Sample this mask in
simple.fragto dim or mask terrain and hide out-of-vision units.
- Maintain a
8. Implementation Roadmap
Phase 1: Core Simulation Loop & Pathfinding
- Create
GameSimulationclass with fixed-tick update (e.g., 20 ticks/sec). - Implement hex A* pathfinding (
Pathfinder.h/.cpp) usinggetHexNeighbor. - Add basic
Unitclass with real-time waypoint interpolation across hex centers. - Implement mouse raycasting / hex picking from screen click to
(tx, ty).
Phase 2: Unit Rendering & RTS Controls
- Render 3D unit meshes / billboards on tile surfaces at correct elevation
Z. - Implement standard RTS controls: Left-click select, box-select, right-click move/attack.
- Add unit health bars, selection rings, and minimap unit dots.
Phase 3: Cities & Tile Improvements
- Implement
Cityclass, city founding with Settler, and territory border rendering. - Add Worker unit improvement actions (Farm, Mine, Road).
- Implement resource yield accumulation (Food, Production, Gold, Science).
Phase 4: Combat, Technology & Opponent AI
- Implement real-time combat calculation, ranged attack trajectories, and damage resolution.
- Add Technology Tree interface and research progression.
- Implement AI Factions and Barbarian encampments.
9. Coding Guidelines for Agents & Developers
- Language Standard: C++17 with Qt 5/6 framework.
- Rendering Thread Safety: Game logic and pathfinding must run synchronously or safely decoupled from
paintGL(). Never call OpenGL functions outside the OpenGL context thread. - Memory Management: Use RAII and smart pointers (
std::unique_ptr,std::shared_ptr) for entities. Avoid raw manual array allocations in game loop updates. - Performance:
- With 37,500 hexes, avoid iterating all hexes every frame. Use spatial partitioning or chunking for unit queries.
- Batch unit rendering using instanced OpenGL draw calls (
glDrawArraysInstancedorglDrawElementsInstanced).
- Math Consistency: Always use
terrain.hhelper functions (getHexNeighbor,getHexEdgeMidpoint,LOD_0_SIZE_Y) to maintain consistent geometry and alignment with the terrain mesh. - Language & Localization: English only across the entire codebase and UI. Never hardcode screen display text in C++; always retrieve English strings from the external localization file (
config/strings_en.yaml).