The 180° Turn: Why Turian is Coming Home to C#
When building ambitious projects, execution matters far more than stubbornness. About six months ago, I made a dramatic shift: I paused the C# stack for my engine initiative, dove headfirst into Zig, and rebuilt everything from the ground up. When I say "we" elsewhere in this post, I mean me: I'm a single developer for the time being.
The result of that experiment was Turian, which is now being renamed to TurianZ. It grew into a working native 3D engine in Zig, with 3D rendering, scene management, asset pipelines and a usable editor. Along the way, I contributed back to the ecosystem, creating libraries and tools including GUID, math-3d, GPU, KTX2, and liquidz.
I also owe a lot to the DVUI developers, whose Zig UI library gave the editor a strong foundation and whose support made a real difference. Zig's wider ecosystem is young but lively; awesome-zig is a good map of the projects and tools people have built.
TurianZ also became the first real consumer of its own tooling: building a functional Zig game meant handling the game's source code as part of the engine's build process. That exposed friction I could not see while developing the engine in isolation.
Yet, during those same six months of deep low-level Zig development, I kept using modern .NET / C# for every other side project I spun up. Eventually, I realized something undeniable: I was writing—and enjoying—significantly more C# code than Zig.
A weekend project updating Guinevere to the latest .NET features lit the spark. Revisiting the original C# Turian codebase sealed the deal. The code was cleaner, easier to parse, and felt remarkably natural.
After a full month of refactoring, updating, and aligning systems, I'm making it official: The entire stack is returning home to C#.
The Elephant in the Room: Naming & Legacy
I know what you're thinking: "Wait, Turian was C#, then it became a Zig engine, and now it’s C# again?"
Yes. The confusion is completely justified. Here is how I am handling the transition cleanly:
- Turian (C#): Reclaims its status as the core flagship engine and repository.
- TurianZ (Zig): The Zig incarnation is now officially preserved as a "legacy" repository.
TurianZ is too useful to simply delete. It has 3D rendering, scene management, asset systems and a functional editor. If you want to fork, maintain or evolve TurianZ, you have my full blessing and support (reach me on Matrix/Discord).
Zig vs. C#: The Engine Developer's Perspective
Spending six months in Zig while keeping a foot in modern .NET gave me a reasonably informed view of both ecosystems.
What I Loved About Zig
- Comptime:
comptimeis genuinely good. Generating structs, inspecting fields at compile time, and running logic without runtime overhead all work as advertised. - Predictability: No background garbage collector, no runtime surprises, and direct control over memory allocators.
- C interop: Consuming native C libraries without glue code or header bindings is still Zig's strongest feature.
Where Zig Struggled for This Use Case
- Editor metadata was harder to carry into a running game:
comptimecan inspect types and generate code, but Turian Studio needs to discover components, expose editable properties, and inspect objects while the game runs. Without the runtime reflection and attributes I use in C#, I had to design explicit metadata and registration paths for those workflows. Each new kind of editor interaction brought more glue code. - The game and engine were tightly coupled at build time: With no stable Zig ABI for linking my game against a precompiled Zig engine, the game compiled engine source as part of its own build. Changes to the engine or its dependencies flowed through the game's build, making the edit-build-try loop heavier than I wanted for game development.
- The engine had to understand game source: For TurianZ's approach to building a functional Zig game, the toolchain had to parse game code and inject engine-specific pieces. That pushed the engine toward behaving like a low-level language parser. Dogfooding this path at the highest level was valuable, but maintaining it alongside the renderer, editor, and game was not a great experience for one developer.
None of this cancels out what I like about Zig or the help I received from its community. It does explain the switch: I was spending too much of my time making the development loop work and too little time using the engine to make a game. In C#, the runtime metadata and the existing .NET tooling fit this particular editor-and-game workflow more naturally.
The New C# Horizon: Turian & Guinevere
Reclaiming C# hasn't meant starting from scratch; it meant upgrading everything to modern standards. The C# codebase has already swallowed and adapted the best features born during the Zig experiment:
- OAP (Open Asset Package): Re-engineered for C#, bringing an asset packaging system to the .NET ecosystem.
- Guinevere GUI: Considerably more capable than the version I started with, built on modern .NET throughout.
- Turian Studio & Gaya: Improved decoupling in the architecture to pave the way for the Gaya platform and editor layer.
- Engine parity: 3D rendering pipelines brought up to date, quality-of-life enhancements, and performance work.
If you want to see it go further, you can support the work on Patreon or Ko-fi.