← Blog

Why Turian 2.0.0 Is a MAJOR Release With Just 1 MINOR Change

Why Turian 2.0.0 Is a MAJOR Release With Just 1 MINOR Change

2026-07-18

Turian 2.0.0 is out. If a "2.0" makes you expect a keynote, a rebranded editor and a hundred bullet points, this is not that release—and that's exactly the point. This release contains one headline change, and it's a breaking one. That's the entire reason the number went from 1 to 2.

What triggered the bump

Until v1.17, Turian's glTF/GLB importer had a limitation: it cooked only the first primitive of the first mesh in a file and silently dropped the rest. Fine for a cube; not so for anything in real life, where a single model often carries dozens of meshes and materials.

Issue #45 fixed that. Imported models now cook every mesh and every primitive, each submesh bound to its own material. Getting there required three coordinated changes:

  • The TMSH (our internal mesh format) gained a submesh table — per-primitive index ranges and material slots in one shared vertex/index buffer.
  • MeshRendererComponent traded its single material field for a materials array.
  • Scene files also traded the single material_guid field for a material_guids array.

That last change affects what Turian writes into your project's scene files. A scene saved by 2.0.0 is no longer fully understood by 1.x. Under our release policy, that's a breaking change, and a breaking change means a major version. No waiting for an annual release. No collecting unrelated changes until there's enough material to justify a flashy announcement. The change landed, so the version changed.

Why we do majors this way

Many engines treat the major version as a brand. Unity 6, Unreal 5, Godot 4 — each number represents years of accumulated work, a long list of new features, and inevitably, a large pile of breaking changes.

Teams often lock their engine version at the beginning of production and avoid upgrading entirely because the cost of crossing one of those version boundaries is difficult to estimate. Those upgrade cliffs rarely appear overnight. They are usually the result of dozens of postponed breaking changes finally being bundled into a single "big" release.

Turian inverts that relationship. The version number is not a marketing event. It is a compatibility signal.

What you gain

Migrations arrive one at a time, while the change is still small and fresh. This guide for 2.0.0 fits on one page and takes minutes. The version number is honest: when the major changes, you know it's worth reading the migration guide. When it doesn't, you know your project remains source-compatible, even after dozens of releases. And because breaking changes ship as soon as they are ready, there's no pressure to hoard them for some future "allowed" release window — the very dynamic that eventually creates painful upgrade cliffs elsewhere.

There's another benefit that's easy to overlook: every breaking change stays local. The reasoning behind it is still fresh, the migration is narrowly focused, and discussions revolve around a single design decision instead of dozens of unrelated ones. Upgrading becomes a routine engineering task rather than a dedicated project with weeks of planning and risk assessment.

This also encourages better API design. Knowing that compatibility is important — but not absolute — allows us to improve APIs when the long-term benefit clearly outweighs the migration cost. The alternative is preserving accidental decisions forever simply because changing them would have to wait for the mythical "next big version."

What you give up

Version numbers stop being memorable. There will eventually be a Turian 7 and a Turian 12, and neither will mean much by itself. A "2.0" sounds dramatically bigger than it actually is — which is why this post exists. You'll also encounter migration moments more often, even if each one is intentionally small.

We think that's a worthwhile trade.

Today and tomorrow

It is also fair to point out that Turian is still in its infancy. There are very few users today, and no commercial productions depending on the engine yet, so naturally the immediate impact of this policy is limited.

That is not why we adopted it.

The goal is to establish predictable engineering habits before the ecosystem grows. As more projects—and eventually commercial productions—depend on Turian, every breaking change will naturally require more careful planning. We'll need to think more about timing, migration cost, community feedback, and whether the improvement genuinely justifies disrupting existing projects.

The philosophy remains the same. It is the bar for introducing a breaking change that becomes higher.

Turian also doesn't currently provide an LTS-like release or equivalent stability branch.

At this stage of the project's life, maintaining multiple supported versions would add complexity without providing much value. The project is evolving quickly, the user base is still small, and our development process should reflect that reality.

As the engine matures, the release process will mature with it. Long-term support, extended compatibility guarantees, or other stability mechanisms may become the right choice in the future. Today's workflow is designed for today's project, not because we believe it should remain this way forever.

Features don't wait for announcements

One consequence of this philosophy is that version numbers and communication become two separate concerns.

New features, improvements, and bug fixes continue to land in regular releases exactly as before. You might update because you want a importer enhancement, a new renderer, or a studio new tool. Or you might simply want bug fixes while ignoring entirely the new capabilities that were added. The release cadence doesn't change just because a major version happened.

However, curiously, the exact opposite idea applies to communication!

Rather than publishing a blog post for every individual feature, we prefer to periodically collect them into broader release roundups, like the 2026 June Release. Those posts tell the story of where the engine is going, connecting multiple improvements into a coherent narrative that's useful for users, curious bystanders, and media alike.

Meanwhile, the day-to-day development story already exists where developers naturally look for it: commits, merge requests, issues, release notes, and discussions. That keeps technical communication immediate while avoiding a constant stream of fragmented announcement posts.

Version numbers answer one question: "Will I need to think about compatibility?"

Roundup posts answer another: "What's new in Turian lately?"

Keeping those answers separate makes both clearer.

What you need to do

Very little:

  1. Update to 2.0.0. Cooked meshes will automatically recook the first time they're opened.
  2. Run turian-cli migrate <project>. This rewrites scene files that still use the old material_guid field. Existing scenes continue to load either way, but the old format now emits a warning.
  3. If your code accessed MeshRendererComponent.material, use materials[0] instead (along with material_count where appropriate).

The full walkthrough—including the one thing you should not do (save scenes with 2.0.0 and then reopen the project with 1.x)—is available in the v2.0.0 migration guide.

As a bonus, models that always contained multiple meshes and materials now import completely. If you've ever loaded a model that looked mysteriously incomplete, this release probably fixes it.

#release#announcement#engine