Adam Bandel


Galaxy Sim

Jan 2026
Type: game
Code: 8k lines
Files: 50
Active: May 2025 — Jan 2026
Stack:
PythonPygameCustom ECS
Tags:
aigame-devsimulation

Overview

Galaxy Sim is a 4X (eXplore, eXpand, eXploit, eXterminate) space strategy simulation where 10 AI-controlled factions compete for galactic dominance. Each faction operates autonomously through a sophisticated multi-layer AI system, managing colonization, fleet movements, combat, diplomacy, research, and economic development across a procedurally generated spiral galaxy.

The simulation runs in real-time with a Pygame visualization layer, rendering the galaxy map with faction territories, fleet movements, and combat encounters. What makes this project unique is its focus on emergent gameplay through complex AI decision-making rather than player input—it’s essentially a galaxy-scale civilization simulation that runs itself.

Screenshots

Galaxy Overview

Combat and Expansion

Late-Game Dominance

Problem

Traditional 4X strategy games rely on scripted AI behaviors that become predictable after a few playthroughs. I wanted to explore whether decomposing AI decision-making into specialized subsystems—each with its own domain expertise—could produce more emergent and interesting faction behaviors. The goal was to create a simulation where watching AI factions compete would be genuinely unpredictable and engaging.

Approach

The core architectural decision was separating strategic concerns into independent AI modules that communicate through a central orchestrator, rather than building a monolithic decision engine.

Stack

Architecture

The game uses an Entity Component System pattern where:

The AI architecture splits decision-making across five specialized modules:

┌─────────────────────────────────────────────────┐
│              AI Orchestrator                     │
│  (Merges proposals, applies resource constraints)│
└─────────────────────────────────────────────────┘
         ▲           ▲           ▲           ▲
         │           │           │           │
    ┌────┴────┐ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐
    │ Empire  │ │Military │ │Economic │ │Research │
    │   AI    │ │   AI    │ │   AI    │ │   AI    │
    └─────────┘ └─────────┘ └─────────┘ └─────────┘

Each sub-AI proposes actions within its domain. The orchestrator filters by affordability, resolves conflicts, and prioritizes execution.

Challenges

Outcomes

The multi-layer AI architecture produces genuinely emergent behavior. Factions form opportunistic alliances against dominant powers, recognize when they have overwhelming advantage and switch to aggressive elimination strategies, and adapt their expansion patterns based on border threats. The simulation rarely plays out the same way twice.

Key technical insights:

Implementation Notes

The ECS uses array-based storage for frequently accessed components to maximize cache efficiency:

class ECSManager:
    def __init__(self):
        self._positions: list[PositionComponent | None] = []
        self._fleets: list[FleetComponent | None] = []
        self._movements: list[MovementComponent | None] = []
        self._live_fleets: set[int] = set()  # O(n) iteration without scanning

Combat calculates damage through synergy bonuses and force ratio multipliers:

def calculate_synergy_bonus(attacker_fleet: dict) -> float:
    scouts = attacker_fleet.get("scout", 0)
    destroyers = attacker_fleet.get("destroyer", 0)
    if scouts > 0 and destroyers > 0:
        return 1.0 + min(scouts / destroyers, 0.3)  # Up to 30% bonus
    return 1.0

The galaxy is procedurally generated using spiral arm distribution:

for i in range(num_systems):
    arm_index = random.randint(0, spiral_arms - 1)
    base_angle = (2 * math.pi / spiral_arms) * arm_index
    t = random.random()
    radius = (t ** 0.8) * max_radius  # Denser toward center
    theta = base_angle + arm_spread * t * 2 * math.pi

View on GitHub →


Related Posts

No posts yet.