- Xamarin did offer a commercial license to Unity; Unity would not accept it
- MS began to release their own .NET implementation under the kinds of license terms that Unity wanted years ago, but Unity didn't budge
- In the meantime, MS then relicensed Mono itself—the .NET implementation that Unity actually wanted—under the kinds of terms that Unity wanted, but still Unity didn't show signs of moving until very recently
The whole it's Mono's fault that Unity sucks was essentially a successful PR attempt for Unity to disclaim responsibility for their shortcomings, with the (maybe not unintentional) side effect of directing public ire towards Mono for not doing enough free work (to benefit what was already one of the industry's most successful companies!)
The fees went away, they started moving.
Its more complicated than that, but ultimately they won: the people demanding license fees got flipped off and they got what they wanted for free.
...so, I know a lot of people have been angry about this, but by every metric what they did was a total business success.
If you want the guys from Unity to act differently, you have to actually tangibly affect them (eg. pick a different engine), not just complain.
I don't consider this to be anyone's fault, my point is that post-MS acquisition, it is easier to get access to the newest mono runtimes/compilers, which is why we are seeing them appear in Unity and in Godot.
>MS began to release their own .NET implementation under the kinds of license terms that Unity wanted years ago, but Unity didn't budge
That one wouldn't have targeted all of their platforms, right?
Workarounds exist. That's great. I don't care. Workarounds don't address the default experience of writing idiomatic C#.
I've considered switching to Unreal, but that has GC built into it a little too much. I know nothing about its characteristics, but it makes me wary. This thread makes me want to investigate Godot. Can anyone provide a one-sentence summary of the GC situation there?
Hopefully a more experienced Godot dev will jump in and correct me if I'm wrong here..
Godot uses reference counting, but additionally supports a function which you can call on an object which will cause it to become 'unmanaged' by the reference counter, allowing you to free its memory on your own terms (or leak the memory, if you're not careful).
Godot 3.0 added support for Mono, but I'm not sure how that works. I'm guessing that game objects in Godot are still reference counted, but now you also have memory allocated by the Mono runtime which will be garbage collected.
' Memory management
If a class inherits from Reference, then instances will be freed when no longer in use. No garbage collector exists, just simple reference counting. By default, all classes that don’t define inheritance extend Reference. If this is not desired, then a class must inherit Object manually and must call instance.free(). To avoid reference cycles that can’t be freed, a weakref function is provided for creating weak references. '
Lots of increments/decrements on the refcount interleaved in normal code can kill the gains over a traditional GC that has nearly free allocation, batched finalizations and doesn't pollute the instruction stream with increments/decrements.
Also with a traditional GC you pay nothing if you don't allocate memory; the collector will never run. You still pay the full price of reference counting no matter if you're done allocating or not.
I tried MonoGame once and the results were much better--garbage collection was fast when there wasn't much to do. However, I'd still choose a non-garbage-collected engine any day because I dislike lag spikes.
I know very little about it, but in general there's a lot more information in the docs about the Garbage Collector than there is about how to not use it.
A garbage collector is rarely the issue; poor development practices and not planning memory usage patterns in the architecture will cost you orders of magnitude of performance long before the GC itself is an issue.
Its not even hard to have zero GC allocations on ~99% of frames. This will give you better performance than the best GC implementations over bad allocation patterns ever could. This is also true of Unreal (UObjects are GC'd as you mentioned) and literally everything else using a GC; its not a free pass to forget about memory management.
Thats one of the primary reasons why I rarely use code assets from the Asset Store; most people don't know how to write performant C# whatsoever; they get killed by a thousand cuts but none of them show up in the profiler, effectively wasting 90% of the CPU without any warning signs. (This is true of almost every software ever released.)
I'm not one for premature micro-optimizations, but on the other hand I don't see how you can get any kind of performance without accounting for macro-optimizations from the very beginning.
Blaming the GC for poor performance is pretty much the same as doing unbuffered byte-by-byte I/O and then wondering why its 1000x slower than the competition even after weeks of micro-optimizations.
I blame Unity's GC for what it is bad at. It's both stop-the-world and non-generational. As I said down-thread, it's a lot of work to design for avoiding allocations. Even then, Unity will still GC from time to time, and whether it matters will depend on the characteristics of your game's managed heap as a whole. This is the major stumbling block most times people argue with me about how GC is fine. Your data is like your data, because your app is your app. It's not like my data. The next step is not to use the managed heap for anything that isn't a temporary. Again, quite a bit of work. And the beginners and intermediates who are most of Unity's users aren't going to do it. Hell, in general I consider GC a non-starter for games, but sometimes I want to work at a company that uses C#. So I repeat:
> Workarounds exist. That's great. I don't care. Workarounds don't address the default experience of writing idiomatic C#.
I still wouldn't call that a workaround but rather properly using memory in the first place; you'll get GC pressure even on a concurrent generational GC if you constantly push garbage down its throat. You'll get slowdowns even on reference counting if you naively assume it to be faster than a GC then blindly pass references all over the place causing tons of increments/decrements on the refcount; trashing caches in the process and causing tons of branch mispredictions.
I've worked on a LOT of radically different games; I don't believe the specific game, genre, engine or language changes how you manage memory, at all. I don't even believe its more work when you account for all the debugging and profiling time you save by the end of the project; a data-driven approach is almost always simpler. Heck Unity is even moving towards a new Entity-Component-System that explicitly relies on the user managing their memory (and in batches too!), with massive performance gains, same for the Job system currently in the 2018.1 beta. We're talking gains of orders of magnitude in performance, not the tiny ~10% gains you'd get profiling and micro-optimizing at the end of a project.
Beginners and intermediates don't manage memory on large scale Unity projects, and memory management isn't nearly as important on smaller ones; they can waste 80% of hardware resources and still hit 60FPS, computers are that fast. So I don't think that's a valid point. Also saying my data is different than your data may be true, but that has no impact on how memory management works whatsoever. Just like you don't stop using SQL because a different app has different relations.
Its almost impossible to get any kind of performance without accounting for memory allocations and layouts, no matter the engine/language you pick. You're bound to waste 90% of the hardware while being left profiling within the remaining 10% from the very second you stop thinking about memory. I really dont get this "again, quite a bit of work" you mention; idiomatic C# is literally more work than data-driven C# at a fraction of its performance and simplicity.
I've seen death by a thousand cuts "we enter crunch mode for months because the game is dog slow before shipping because nobody cared about architecture for 10+ months" kill many game projects; they all had fancy idiomatic code, everything looked good in the profiler yet the problems were systematic. Its pretty much being Agile without having any actual agility.
So I repeat: blaming the GC for poor memory performance isn't the issue. I'll bet I find tons of complexity issues long, long before I see GC issues in any codebase; that's the real issue. Its not that the GC is one huge slowdown, its that the codebase is littered with tiny slowdowns all over the place, so tiny they're effectively invisible to the profiler, yet their sum is still greater than that of the GC.
Why they have never hired a team to simply create a reference counting fork of their object system is beyond me. Their GC is the reason Unity games have a reputation for running with inconsistent choppy frame rates. You'd think fixing that would be top priority.
But they have never committed publicly to a timeline to fix it, and it is a glaring weakpoint in their runtime environment. Possibly worse than any other, besides the insane and broken way they designed their "prefab" concept. Those 2 flaws have led me to call Unity the "Javascript of Game Engines" in the past. It's not quite that bad, but it's close.
Say you design a car prefab and a wheel prefab. If you put 4 wheel prefabs in your car prefab, and then update the wheel prefab, it will not be reflected in the wheels to your car, because you can not have nested prefabs.
Neither will any other set of prefabs — say, the tires on your wheels, or the seats in your car — without going to ludicrous workarounds.
Think about it like a programming language. Imagine if you had a class, and you wanted to include an object of another class in it, but instead of including a reference to that object, your IDE just pasted the entire contents of its class implementation verbabitm into your class, once, and left it like that.
That is how they designed it and that is how it has been, to the frustration of all, for over 13 years. Everyone has to design around this bizarre limitation that isn't present in any other (even simple) game engine. They've promised to fix this before, but haven't.
Now do you understand?
Unity is filled with weird kludges like this, that aren't apparent when you are just starting, in basic systems and critical corners, which is why so many are frustrated with it, despite its strengths in platform ubiquity and market adoption.
> Unity's only achilles in this is the stupid nested prefabs handicap, but hopefully we won't have to live with that much longer
https://twitter.com/Doomlaser/status/550129905028300800
Fool me once. Let's see what they ship. :)
Soon™.
Something "looking" simple from a distance and actually being simple when you code it are two different things. Also its not like that was the only feature they had in the backlog to work on.
Its mind-boggling that people don't realize how much work actually goes in writing a game engine.
I remember when I first learned I couldn't nest prefabs, and I couldn't believe it. Here's hoping they actually fix it.
Besides that, I think the Unity prefab system is really nice, and Unity in general seems very nice.
But I may lack context! I'm coming up on two years using it, and it's my first time working with a game engine (or in games).
Still, it seems much nicer than interface builder or qt designer.
1. Rope in beginners with network effect, asset store, popular fear of C++.
2. Promote as many new features as possible, with only the most minimal discretion of whether the features actually work or help, anybody because once their demographic notices the ploy, they are too invested to leave. Ideally, they will build a few products for the asset store to make up for the dismal investment.
3. Throw enough dirt and some of it will stick. Mass promotion to beginners gives them enough sign-ups to keep going. Interesting how the pricing model means beginners can’t view the unpredictable performance issues until they start paying.
They consistently fail to prioritize the problems with memory management, lightmapping, and material standards that plague serious Unity devs. I have switched to using Unreal and it’s like night and day. I am super interested in Godot.