Why Songs of Syx?
My love for simulation games goes back to the 90s. In 2004, Songs of Syx was released — an isometric sim game about a living settlement where every agent has its own needs, skills, and behaviors. Citizens commute to farms, gather resources, construct buildings — all driven by simple rules that produce emergence.
The game was so good that its source code was never published. It’s haunted my mind ever since.
What I’m learning
SimSandbox is not a game in the traditional sense. It’s a simulation engine playground, built from scratch in .NET 8. Every decision is intentional:
- Build a custom ECS (Entity Component System) with zero dependencies
- Learn multithreaded simulation — decoupling simulation logic from rendering
- Experiment with determinism – fixed timestep, double-buffered snapshots
- Understand agent AI – FSM, A* pathfinding, resource gathering, economics
Tech Stack
- .NET 8 + MonoGame 3.8 – renders at 60-144 Hz
- MemoryPack – fast binary serialization via source generators
- Custom bitset ECS – ~200 lines, zero external libraries
- A* with
.NET 6+ PriorityQueue+ path caching in ECS components
How It Works
The core architecture: two threads.
┌──────┐ snapshot ┌──────────┐
│ Render│─────────────▶ │ Sim │
│60-144Hz│ │30 Hz tick│
└──────┘ └──────────┘
▲ │
│ reads ┌─┴────┐
└──── snapshot ────────────World│
│ECS + Map │
│+ AI │
└─────────┘
The sim ticks deterministically at 30 Hz on a background thread. The render reads from a double-buffered snapshot atomically under a lock — I never block the sim for rendering. Result? Smooth animation regardless of variable FPS.
What already works
Nearly a year of work and here’s what’s running:
ECS – entity create/destroy, queries with 1-4 components, generation counters for memory safety.
Map and pathfinding – procedurally generated world (4 tile types: grass, floor, wall, door). A* with corner-cutting prevention – agents don’t pass through walls. Path cache in ECS component = A* computes once, agent follows the cached path.
Agents – spawned in homes, with a basic hunger stat. Wander with 70% home bias / 30% map exploration. When starving → go to storage, eat, return home.
Economy – farmers automatically produce food (GoToWork → Working → DeliverToStorage). Storage has a capacity of 50/100.
Building – homes 4×4, storage 6×6 with blue doors, farms 4×4 with green interiors. Build ordering system with auto-place when the terrain is clear.
Save/Load – MemoryPack binary format, versioning from day 1 (now 5 file versions). Migration between versions — write it now because three months from now you’ll be grateful.
What doesn’t work yet
- Multiprocessor AI – the logic phase is still sequential. I plan
Parallel.Foron agent slices - Flow fields – for 1000+ agents going to the same destination, a single BFS > A* per agent (O(N) vs O(N·log·N))
- Utility AI – scoring needs (Hunger², Thirst, Sleep, Fun) with quadratic prioritization for emergent behavior
- Game Over – agent death by starvation. Currently agents just vanish when starving
- Pause, speed control, builder mode – UI planned for the next iteration
Why I’m doing this publicly
Because simulations are one of the hardest, but most fulfilling genres in game development. Songs of Syx proved that simple rules can generate extraordinary complexity. But to truly understand it — you have to build it.
SimSandbox is my way — a private lab where I learn simulation-engine architecture from the ground up.
Links
- 📄 Project page: /en/projects/sim-sandbox/
I’ll keep writing about progress. Let me know if you have questions or suggestions!