While it’s easy to get in and make something (it’s got all the bells and whistles) it also suffers from the monolith problem (too many features, old code, tech debt).
The asset store is gold but their tech feels less refined. It’s leaps and bounds where it was when it started but it still has this empty feel to it without heavy script modifications.
There is the problem. The scripting ending designed around mono doesn’t translate as well to CoreCLR and using the same Behavior interface gets a little more complicated.
There are times (even with my own engine) that one must let go of the old and begin a new. Dx7->dx9, dx9->opengl, opengl->vulkan, vulkan->webgpu.
> In 2018, Unity engineers discussed that they are working on porting the engine to .NET CoreCLR
Hard task, no doubt. Unity needs to throw everything at this problem. C# in general has gotten insanely fast by default. It's very much worth taking the time to upgrade/update.
Whilst we don't compare in size and api surface, it took us a few months to get off 472 and onto dotnet6. But once we were on dotnet6, moving to the LTS after that was relatively painless; usually a few hours of work.
The article doesn't cover it but the GC being used by Unity also performs very poorly vs. .NET, and even vs. standalone Mono, because it is using the Boehm GC. Last I heard Unity has no plans to switch IL2CPP to a better GC [1].
It'll be interesting to see how the CoreCLR editor performs. With that big of a speed difference the it might be possible for games to run better in the editor than a standalone Mono/IL2CPP build.
Re. the editor speedup, it should outright eliminate the "domain reload" thingy that happens because all of the C# needs to be unloaded and reloaded in response to a change.
Pretty sure that will still be there? It'll be different because CoreCLR doesn't really have AppDomains but it will still need to unload old assemblies and reload them all again. That's the only reliable way to reset everything into a clean state.
Yes, SGen should be a lot better, but Unity cannot use it because they hold and pass raw pointers around everywhere. That's fine for Boehm but not possible with SGen. They're working on fixing this already but not sure why they aren't planning a move to a better GC.
Yeah I think Unity just doesn't have the technical skillset anymore to make the migration to coreclr. It keeps getting delayed and their tech leads keep dropping out.
Might I suggest https://github.com/stride3d/stride, which is already on .net 10 and doesn't have any cross-boundary overhead like Unity.
Maybe they are making progress. But given that they first started talking about this in 2018, and then in 2022 they announced that they were planning to release a version with CoreCLR in 2023, and then in 2024 they said it would be in beta in 2025, and now in 2025 they're planning to release it as a technical preview in 2026, but they're still talking about an "internal proof-of-concept" as though it's something coming in the future...
As an outsider, it certainly seems like there's reason for skepticism.
I've seen similar things from the inside in other companies. Even existential threats (like lack of Apple Silicon support for performance-critical software), getting heavily delayed because the feature treadmill won't stop and the "important thing" is a pet project of some engineer. It is basically death by a thousand papercuts, where nobody can say what the focus is.
People complain about web development but working with native apps can be depressing sometimes.
Well they made some business decisions in the middle of that timeline that cut their funds quite a bit, not to mention probably scared off some good talent.
Godot is the only real open source competitor, their C# support is spotty. If I can't build to Web it's useless for game jams as no one should be downloading and running random binaries.
A real sandbox solution with actual GPU support is needed.
Writing C# in godot is a bad choice. Use GDScript and directly write c++ as a module. Skip "HD extension" completely. Godots build system is easy enough to use. Just add new classes to the engine using c++ if you don't want to use GDScript. The GDScript workflow is honestly great. Using C# is like the worst of all worlds.
I've seen this issue before, they're making progress but theirs no firm release date.
Plus you then have to extensive testing to see what works in Web builds and what doesn't. I REALLY enjoy vibe coding in Godot, but it's still behind Unity in a lot of ways.
I recently started learning Godot and learning that they use .NET for the C# runtime is a nice touch. I write a lot of code that targets .NET in my day job, so having to learn the unity way of doing things would be frustrating.
That's interesting. I made measurements with Mono and CoreCLR some years ago, but only with a single thread, and I came to the conclusion that their performance was essentially the same (see https://rochus.hashnode.dev/is-the-mono-clr-really-slower-th...). Can someone explain what benchmarks were actually used? Was it just the "Simple benchmark code" in listing 1?
I think a lot of the devil is in the details, especially when we look at NET8/NET10 and the various other 'boosts' they have added to code.
But also, as far as this article, it's noting a noting a more specific use case that is fairly 'real world'; Reading a file (I/O), doing some form of deserialization (likely with a library unless format is proprietary) and whatever 'generating a map' means.
Again, this all feels pretty realistic for a use case so it's good food for thought.
> Can someone explain what benchmarks were actually used?
This honestly would be useful in the article itself, as well as, per above, some 'deep dives' into where the performance issues were. Was it in file I/O (possibly Interop related?) Was it due to some pattern in the serialization library? Was it the object allocation pattern (When I think of C# code friendly for Mono I think of Cysharp libraries which sometimes do curious things)? Not diving deeper into the profiling doesn't help anyone know where the focus needs to be (unless it's a more general thing, in which case I'd hope for a better deep dive on that aspect.)
Edited to add:
Reading your article again, I wonder whether your compiler is just not doing the right things to take advantage of the performance boosts available via CoreCLR?
E.x. can you do things like stackalloc temp buffers to avoid allocation, and does the stdlib do those things where it is advantageous?
Also, I know I vaguely hit on this above, but also wondering whether the IL being done is just 'not hitting the pattern'. where a lot of CoreCLR will do it's best magic if things are arranged a specific way in IL based on how Roslyn outputs, but even for the 'expected' C# case, deviations can lead to breaking the opt.
The goal of my compiler is not to get out maximum performance, neither of CoreCLR nor Mono. Just look at it as a random compiler which is not C#, especially not MS's C# which is highly in sync and optimized for specific features of the CoreCLR engine (which might appear in a future ECMA-335 standard). So the test essentially was to see what both, CoreCLR and Mono, do with non-optimized CIL generated by not their own compiler. This is a legal test case because ECMA-335 and its compatible CLR were exactly built for this use-case. Yes, the CIL output of my compiler could be much more improved, and I could even get more performance out of e.g. CoreCLR by using the specific knowledge of the engine (which you cannot find in the standard) which also the MS C# compiler uses. But that was not my goal. Both engine got the same CIL code and I just measured how fast it run on both engines on the same machine.
Good article but seems strange that author benchmarked debug builds first, that’s a huge “no-no” in any perf tweaking and it’s clear that authors knows this well
From my experience, performance gains seen in Debug builds in Unity/C#/Mono nearly always translate in gains in Release mode. I know that this is not always true, but in this context that's my experience.
Setting up release benchmarks is much more complex and we develop the game in Debug mode, so it is very natural to get the first results there, and if promising, validate them in Release.
Also, since our team works in Debug mode, even gains that only speed things up in Debug mode are valuable for us, but I haven't encountered a case where I would see 20%+ perf gain in Debug mode that would not translate to Release mode.
Will the move to CoreCLR give any speed ups in practice if the release build is complied with IL2CPP anyway? On all the games that I've worked on, IL2CPP is one of the first things that we've enabled, and the performance difference between the editor and release version is very noticeable.
While it’s easy to get in and make something (it’s got all the bells and whistles) it also suffers from the monolith problem (too many features, old code, tech debt).
The asset store is gold but their tech feels less refined. It’s leaps and bounds where it was when it started but it still has this empty feel to it without heavy script modifications.
There is the problem. The scripting ending designed around mono doesn’t translate as well to CoreCLR and using the same Behavior interface gets a little more complicated.
There are times (even with my own engine) that one must let go of the old and begin a new. Dx7->dx9, dx9->opengl, opengl->vulkan, vulkan->webgpu.
Hard task, no doubt. Unity needs to throw everything at this problem. C# in general has gotten insanely fast by default. It's very much worth taking the time to upgrade/update.
Whilst we don't compare in size and api surface, it took us a few months to get off 472 and onto dotnet6. But once we were on dotnet6, moving to the LTS after that was relatively painless; usually a few hours of work.
It'll be interesting to see how the CoreCLR editor performs. With that big of a speed difference the it might be possible for games to run better in the editor than a standalone Mono/IL2CPP build.
[1] https://discussions.unity.com/t/coreclr-and-net-modernizatio...
For what reason? Mono has a pretty good precise GC since many years.
Might I suggest https://github.com/stride3d/stride, which is already on .net 10 and doesn't have any cross-boundary overhead like Unity.
Unity updates on their plans and progress:
2022 - officially announced plans to switch to CoreCLR - https://unity.com/blog/engine-platform/unity-and-net-whats-n...
2023 - Tech update - https://unity.com/blog/engine-platform/porting-unity-to-core...
Unite 2025 - CoreCLR based player scheduled for Unity 6.7 in 2026 - https://digitalproduction.com/2025/11/26/unitys-2026-roadmap...
As an outsider, it certainly seems like there's reason for skepticism.
People complain about web development but working with native apps can be depressing sometimes.
Godot is the only real open source competitor, their C# support is spotty. If I can't build to Web it's useless for game jams as no one should be downloading and running random binaries.
A real sandbox solution with actual GPU support is needed.
I've seen this issue before, they're making progress but theirs no firm release date.
Plus you then have to extensive testing to see what works in Web builds and what doesn't. I REALLY enjoy vibe coding in Godot, but it's still behind Unity in a lot of ways.
But C# is what I've used for over a decade. C# has vastly better IDE support. It's a more complete language.
Plus a lot of C# assets/libraries don't really have GDScript counterparts.
But also, as far as this article, it's noting a noting a more specific use case that is fairly 'real world'; Reading a file (I/O), doing some form of deserialization (likely with a library unless format is proprietary) and whatever 'generating a map' means.
Again, this all feels pretty realistic for a use case so it's good food for thought.
> Can someone explain what benchmarks were actually used?
This honestly would be useful in the article itself, as well as, per above, some 'deep dives' into where the performance issues were. Was it in file I/O (possibly Interop related?) Was it due to some pattern in the serialization library? Was it the object allocation pattern (When I think of C# code friendly for Mono I think of Cysharp libraries which sometimes do curious things)? Not diving deeper into the profiling doesn't help anyone know where the focus needs to be (unless it's a more general thing, in which case I'd hope for a better deep dive on that aspect.)
Edited to add:
Reading your article again, I wonder whether your compiler is just not doing the right things to take advantage of the performance boosts available via CoreCLR?
E.x. can you do things like stackalloc temp buffers to avoid allocation, and does the stdlib do those things where it is advantageous?
Also, I know I vaguely hit on this above, but also wondering whether the IL being done is just 'not hitting the pattern'. where a lot of CoreCLR will do it's best magic if things are arranged a specific way in IL based on how Roslyn outputs, but even for the 'expected' C# case, deviations can lead to breaking the opt.
I don't beleive such a large regression from .NET framework to CoreCLR.
Setting up release benchmarks is much more complex and we develop the game in Debug mode, so it is very natural to get the first results there, and if promising, validate them in Release.
Also, since our team works in Debug mode, even gains that only speed things up in Debug mode are valuable for us, but I haven't encountered a case where I would see 20%+ perf gain in Debug mode that would not translate to Release mode.