Eurekiel: Libra is a 2D top-down tank combat game built on a custom C++ engine (Eurekiel). Players pilot a tank through procedurally generated maps, switching between projectile and flamethrower weapons to engage four distinct enemy types, each with unique physics interactions, movement rules, and combat behaviors. The entire game is data-driven: enemy attributes, tile properties, map layouts, and spawn rules are all defined in XML, enabling rapid iteration without recompilation.
Game Trailer
Player Tank Mechanics
The player tank features independent body and turret rotation. The tank body follows WASD directional input while the turret tracks toward the mouse cursor. This decoupled control scheme allows strafing and retreating while maintaining aim on a target, which is essential for kiting enemies with different movement speeds.
The tank carries two weapon systems: a rapid-fire projectile cannon and a short-range flamethrower. The projectile uses fast voxel 2D raycasting for hit detection, while the flamethrower applies continuous area damage with particle effects. Players switch between weapons depending on enemy range and type.
Fast Voxel 2D Raycast
Both the player’s bullets and enemy laser attacks rely on a fast voxel traversal algorithm adapted for the 2D tile grid. The raycast steps through tiles at a configurable resolution (RAYCAST_STEPS_PER_UNIT = 50), checking for solid tile collisions and entity intersections along the way. This same system powers line-of-sight checks for AI targeting decisions.
Enemy Design & Physics Interactions
Each enemy type is defined entirely through GameConfig.xml. Drive speed, turn rate, shoot cooldown, health, and physics interaction rules are all designer-tunable without code changes. Every enemy has its own corrective physics state that determines whether it can be pushed or pulled by the player or by other enemy types, creating emergent tactical situations.
graph LR
subgraph Enemies
Leo["Leo - Infantry"]
Aries["Aries - Shield"]
Scorpio["Scorpio - Heavy"]
Capricorn["Capricorn - Aquatic"]
end
subgraph Properties
Push["Pushable by Player"]
Pull["Pullable by Player"]
Water["Can Cross Water"]
Special["Special Ability"]
end
Leo -->|Yes| Push
Leo -->|Yes| Pull
Leo -.->|No| Water
Leo -->|Standard AI| Special
Aries -.->|No| Push
Aries -.->|No| Pull
Aries -.->|No| Water
Aries -->|Reflective Shield| Special
Scorpio -.->|No| Push
Scorpio -.->|No| Pull
Scorpio -.->|No| Water
Scorpio -->|Immovable Body| Special
Capricorn -->|Yes| Push
Capricorn -->|Yes| Pull
Capricorn -->|Yes| Water
Capricorn -->|Tracking Missiles| Special
Leo: Pushable Infantry
Leo is the basic ground enemy. It patrols using distance-field navigation, chases the player on sight, and fires standard projectiles. Leo can be both pushed and pulled by the player’s tank, making it possible to shove Leos into hazards or use them as mobile cover against other enemies.
Aries: Reflective Shield Bearer
Aries carries a frontal energy shield that reflects incoming projectiles back at the player. Direct fire is ineffective. Players must flank Aries or use the flamethrower to bypass the shield. Aries cannot be pushed or pulled, forcing the player to reposition rather than brute-force the encounter.
Scorpio: Immovable Heavy Tank
Scorpio is the heaviest enemy type. It cannot be pushed or pulled by any force, player or other enemies. Scorpio acts as a static obstacle that blocks pathways and forces the player to engage on Scorpio’s terms. Its high health pool and steady fire rate make it a priority target.
Capricorn: Aquatic Missile Launcher
Capricorn is the only enemy that can traverse water tiles, giving it access to areas other enemies cannot reach. It fires tracking missiles that home in on the player’s position. Capricorn can be pushed and pulled, but its water-crossing ability means it often attacks from unexpected angles.
Procedural Map Generation
Maps are procedurally generated from XML-defined MapDefinition templates that specify dimensions, tile type distributions, worm counts, and worm lengths. The generator uses a worm algorithm to carve traversable paths through the tile grid, then runs a flood-fill reachability check to guarantee the player can always reach the exit. If the generated layout fails the reachability test, the generator retries (up to MAX_ATTEMPTS = 100) until a valid map is produced.
Each map theme (grass, tunnel, and water) uses different tile palettes and generation parameters, producing visually and mechanically distinct environments while sharing the same generation pipeline.
AI Navigation & Heat Map Debug
Enemy pathfinding is driven by distance-field heat maps computed over the tile grid. Each tile stores a heat value representing its distance to the target (player position). Enemies follow the gradient toward lower heat values, producing smooth, obstacle-aware navigation without explicit pathfinding graphs. The heat map is only recomputed when the player moves to a new tile, avoiding unnecessary recalculation.
The game ships with four heat map debug visualization modes, togglable at runtime, that overlay the distance field values directly on the tile grid. These modes visualize different aspects of the AI navigation data: raw distance values, directional flow, solid/non-solid classification, and entity-aware cost adjustments, making it straightforward to diagnose pathfinding issues during development.
Data-Driven Architecture
The entire game is configured through XML files under Run/Data/. No gameplay-relevant constant is hardcoded. Everything from player speed to enemy spawn counts to tile properties is externalized into data definitions.
graph TD
subgraph DataFiles["Run / Data"]
GC["GameConfig.xml"]
TD["TileDefinitions.xml"]
MD["MapDefinitions.xml"]
SD["SpriteSheetDefinitions.xml"]
end
subgraph Runtime
TDef["TileDefinition"]
MDef["MapDefinition"]
Map["Map - Tile Grid"]
Entity["Entity - Player and Enemy"]
end
GC --> Entity
TD --> TDef
MD --> MDef
TDef --> Map
MDef --> Map
SD --> Entity
Map --> Entity
GameConfig.xml controls all entity attributes. A designer can adjust leoDriveSpeed, scorpioShootCooldownSeconds, or capricornMissileSpeed and see the change on next launch. TileDefinitions.xml maps tile type names to solidity flags, sprite sheet references, and rendering properties. MapDefinitions.xml defines each map’s generation parameters: grid size, worm algorithm settings, tile type probability weights, and theme-specific overrides.
This separation means the game’s content (maps, enemies, tiles, animations) can be iterated entirely through data files, while the C++ engine code handles only systems and logic.
Design Philosophy
Data Over Code — Every tunable parameter lives in XML. Enemy stats, map generation rules, tile properties, and sprite definitions are all externalized. This enforces a clean boundary between engine systems (C++) and game content (data), enabling rapid iteration and reducing recompilation cycles to zero for balance changes.
Corrective Physics Per Entity — Rather than a one-size-fits-all physics model, each enemy type declares its own push/pull interaction rules. This creates a physics system where tactical depth emerges from entity composition — Leos can be shoved into Scorpios (who don’t budge), Capricorns can be pushed off water tiles, and Aries simply ignores all forces. The physics interactions become a core gameplay mechanic, not just collision resolution.
PCG with Guarantees — Procedural generation is only useful if it produces playable results. The worm-based map generator always validates reachability before accepting a layout, ensuring the player can never be softlocked. This “generate-then-validate” loop trades a small amount of generation time for absolute reliability.
Debug as a First-Class Feature — Four heat map visualization modes, entity state labels, collision bound rendering, and AI goal markers are all built into the game from the start — not bolted on after bugs appear. The debug draw system uses a clip mode that can isolate specific layers, making it practical to diagnose issues in complex multi-enemy scenarios.
Distance Fields Over Pathfinding Graphs — Instead of A* or navmesh, the AI uses distance-field heat maps computed over the tile grid. This approach naturally handles dynamic obstacles (breakable tiles, other entities), produces smooth movement without waypoint snapping, and scales linearly with map size. The heat map doubles as a debug visualization tool, closing the loop between runtime behavior and developer understanding.