Mr. Phil Games’ Blog

Posts for Tag: Dual Engine Architecture

Stellar Throne Devlog #6 — Zig Parity and Production Deployment

Hey everyone, MrPhil here with another devlog update!

Today marks a critical production deployment milestone for Stellar Throne, my 4X strategy game set in a post-empire galaxy. For those new here, I’m building Stellar Throne with a dual-engine architecture — using Godot for the UI client and Zig for the high-performance simulation backend.

This week’s focus: validating that the Zig simulation engine isn’t just fast — but production-ready.


⚙️ Context: The Zig Engine Hits 52.7× Performance

After two weeks of development, the Zig simulation engine is complete — delivering a verified 52.7× speedup over the original Godot implementation. Every one of the 1,069 tests passes cleanly.

The question was no longer “Does it work?” but “Can I ship it?” And even more importantly: “Will it stay stable under real-world stress?”


🧪 Parity Testing and Stress Scenarios

To answer that, I built a comprehensive parity testing system — a harness that runs the exact same turn through both the Godot and Zig engines, then compares every field in the game state to ensure they produce identical results.

Test scenarios ranged from:

  • 10 empires with 10 systems each

  • Up to 100 empires with 250 star systems

That’s when things got interesting — and the bugs started surfacing.


🐛 Three Critical Bugs (and How I Fixed Them)

1. Negative Resource Spirals

Zig’s resource validation could create negative feedback loops if a colony’s food production went below zero — spiraling further negative each turn instead of clamping to zero.
Fix: Added strict validation to prevent negative resource values during calculations.

2. Fleet Upkeep Mismatch

The Godot version used a flat-rate upkeep (10 Energy + 5 Minerals per fleet), but Zig calculated per-ship upkeep — leading to wildly inconsistent costs.
Fix: Standardized both engines to use the flat-rate formula for base upkeep while keeping per-ship maintenance for hull and weapon costs.

3. Maintenance Persistence Loss

Maintenance costs were being overwritten during stat recalculation, resetting values to zero.
Fix: Preserved maintenance data during the recalculation phase.

After fixing these, I expanded the stress tests — pushing edge cases like 200+ fleets per empire, negative production chains, and zero-population planets. That led to 11 parity fixes across both engines — covering resources, fleets, population growth, and infrastructure costs.


🚀 Deployment Roadblocks and Race Conditions

With parity achieved, I turned to production deployment — enabling the Zig backend automatically during game initialization.

Two blockers emerged:

  1. Initialization Timing
    The Zig backend tried to serialize game state before empires existed — crashing when the empires array was still empty.
    Fix: Corrected property references (galaxy.galaxy_width → galaxy.width) and restructured initialization order.

  2. Async Signal Race Condition
    The system awaited a signal after it was emitted — a classic async race.
    Fix: Stored the signal reference before starting the turn, ensuring the listener was connected in time.

To prevent future issues, I implemented:

  • Helper functions in GameScreenCore and GameInitializer

  • Debug logging in TurnProcessor

  • 343-line deployment guide detailing rollback, monitoring, and troubleshooting procedures


🧩 Deployment Decision: Disabled by Default

After reviewing everything, I made the cautious call to keep the Zig backend disabled by default for now.
The timing between empire creation and backend initialization is delicate — and I’d rather avoid subtle production bugs.

That said, the system is fully integrated. Manual enablement is available for testers. The performance boost is real, and parity is 100% confirmed.


📈 Final Stats

  • 20 commits in one day

  • 4,243 new lines of parity infrastructure across 13 files

  • 343-line deployment guide completed

  • 11 parity bugs fixed

  • All 1,069 tests passing

  • 52.7× performance improvement validated

The Zig simulation backend is production-ready, complete with fallback to Godot if anything fails.


🧭 Next Steps

  1. Verify signal-timing fixes in live game sessions

  2. Test deployment in extended campaign scenarios

  3. Decide whether to enable Zig automatically or keep manual control

Either way, the hard part’s done — the Zig engine is live-ready and just one config flag away.


Thanks for following along — and as always, you can find more at MrPhilGames.com.

See you in the next devlog!