Hacker News new | past | comments | ask | show | jobs | submit login
Mono for Unreal Engine (mono-ue.github.io)
146 points by markatkinson on Aug 4, 2017 | hide | past | favorite | 95 comments



C# is Unity's main programming language, now there's this for Unreal, and Godot 3.0 will also have C# support.

Is C# becoming the lingua franca of modern game engines?


I would certainly hope not. C# implementations are terrible for lots of games on not-Windows. The version of Mono that has been included with Unity is particularly bad with respect to stop-the-world garbage collection pauses.


Pros:

1. The GC provides a huge time-saving net over a ton of possible memory errors. Not to mention the code is so much easier to read when you aren't having to deal with memory on every line.

2. The debugging experience is brilliant - because there is always metadata available, you can literally inspect everything.

3. Compilation time is super fast.

4. Code samples are available for pretty much everything. And when there aren't, you can always interop into C++ or whatever else.

Cons:

People unfamiliar with the language forget about the GC and let it do all their dirty work. They then get angry when it bites back because of all the allocations they are doing each frame. The answer is to use pooling, and structure your code in a way that works with the GC (not against it), and all these problems go away.


But that's not the issue - any other GC'd language has a much faster and better GC than this ancient mono version. That was the issue mentioned.


Yes, and that complaint is specific to Unity's current GC. They will update it eventually, and it will no longer suck.

Does the GC in Unreal-mono have the same problems? If not, it's a non-issue.


It should be significantly better, but can still pause. Beyond this, it really depends on how you are allocating/using/reusing objects... There are techniques you can use that aren't too painful to overcome some of the issues.


Unity has a specific situation with Mono that doesn't apply to anything else. It won't apply here, something like this can use the latest Mono.


The concurrent GC in the latest .Net still requires pausing (though the time is less), because the heap still requires compacting, and no code can run while that operation happens.

Invoking the GC constantly on a frame by frame basis can quickly lead to heap fragmentation, resulting in pausing, because that is considered 'working against' the GC (both stop the world and concurrent). This is where custom solutions, such as pooling, should be used to mitigate these issues.


Like every other language used for game development: you don't allocate objects in the render loop. All objects are re-used and go into pools. Malloc isn't free (heh): maintaining the free lists can kill FPS just as quickly as anything else.

As others have pointed out: the CLR has had a concurrent low-latency GC for a long time now and now that it's all open-source there is nothing preventing Unity from adopting it.


Yeah, I am also surprised by the fact that people are constantly nagging about GC. In real gamedev on Unity, memory management is very serious and everything gets pooled. If GC is a problem, you rewrite the code so that it isn't.


I hope so, although I particularly hope that more game designers build games such that the windows distribution can be directly run by mono on not-windows. That is the way the game is most likely to stay working for an long time and under multiple operating systems. I'm no fan of Microsoft, but compatibility over time is one thing they do better than anyone else and games are the one kind of application where that is particularly important. Plus Mono is excellent. There are other ways game designers could try to make their applications more likely to work for a long time, but in practice they don't do that.

I haven't noticed garbage collector related issues with mono, although I don't play the type of games where that would be most noticible. I have seen a number of games with memory leaks that require a restart after a while, but that is the case under windows as well. I've recently stopped buying Daedalic games because they can't manage to make a simple adventure game with almost no movement work on a system with 4GB memory, but they are by no means the only ones with this problem.

C# on top of C++ might not help that much other than encouraging more game designers to use C#.


Maybe I'm getting old, but you saying Microsoft is brilliant at compatibility made me smile ruefully


Unity 5.x only uses Mono for the editor. On non-Windows platforms they use their own AoT .Net implementation, IL2CPP.


The code generator is indeed different, the runtime is still Mono.

Mono today has two code generators: Mono's built it one, and an LLVM one. Both generate code after Mono loads and processes the assembly.

Unity developed a different front end to the runtime that does the compilation from IL to C++, the result still requires the Mono runtime to provide services at execution time.

They are currently upgrading their Runtime and are making a version with all the greatest features available coming.


Oh wow! Hey Miguel! Thanks for the info. Parenthetically: you're a pretty hep cat. Thanks for all your hard work on these projects :)


Do you know if this is still true with the newer "concurrent" garbage collector in more recent Mono versions? I work on an audio player app rather than games, but also have problems with the GC in Mono on IOS. We're hopeful that eventually they'll go away, but haven't tried again recently.


I am not certain. Theoretically, it should be better, because I think they implemented a GC algorithm similar to the one on Windows. But I have never actually run it.

It's hard to emphasize how bad the Unity Mono GC is. It's a Mark-and-Sweep garbage collector, which is like the simplest-yet-least performant approach to GC there is. Nearly every other GC in production use in other stacks is better.


I'm willing to bet that Mono GC has improved a lot, but I don't think that Unity frequently updates the runtime. It's kind of painful, from what I've been told.


We are collaborating with Unity to assist on upgrading not only their runtime but also to adopt the latest and greatest GC.

Additionally in C# 7, 7.1 and the upcoming 7.x series there are many improvements that reduce object allocation (like ref structs, value type tasks and others)


Unity is just now updating the runtime for the first time in seven years. I think only the 2017.x releases have the new Mono, and most platforms use their IL2CPP AoT compiler I believe


It is an experimental option for Xamarin. Though haven't played with it.


Shouldn't this stop being an issue under Microsoft's patronage? .NET definitely doesn't have a stop-the-world garbage collector and this should trickle to Mono, if it hasn't already.


I believe it has stopped, or it had stopped a little bit before the acquisition. Other commentors indicated it has not trickled to Unity yet.

I am not up to date on the state of this in the latest Unity releases, I just know games I play on PS4 and OSX made with Unity stutter in places where they don't stutter on Windows.


Here's Miguel's blog post from a couple years ago (before the Microsoft acquisition) when their cooperative mode GC first landed:

http://tirania.org/blog/archive/2015/Dec-22.html


That effort continues, we have an update in Mono's blog and we are about to share details on our next concurrent/parallel milestone soon.


The version of Mono that is shipped with Unity is bad specifically for licensing reasons, there is no technical cause.


What's wrong with the licensing? Not disagreeing with you; this is just the first I've heard of it.


The popular telling of the story is that the team behind Mono asked for too much money to allow the Unity3D team to have a commercial license exception to newer versions of Mono.

(This comes from the Unity team's explanation to the Unity community about why their runtime remains out of date. It's since become a meme to paint the Mono folks as a bunch of jerks over this. This endured for a few years. In the meantime, however, Microsoft has released .NET under permissive terms that would allow Unity to use Microsoft's own runtime royalty-free—no need for a commercial license exception. Despite the opportunity it presented, an upgraded runtime failed to materialize from Unity. Maybe the transition from Mono to .NET Core was too big of a leap? Fair point. Thing is, Mono itself is now also relicensed under MIT, by way of Microsoft's acquisition of Xamarin, so Unity is free to make commercial use of newer Mono versions on proprietary platforms, just like Unity always wanted. Still, no upgrade to the Unity runtime.)


Ola, Lucas from Unity here,

Xamarin and Unity never did a renewed licensing deal. That doesn't make the lovely xamarin people nor us jerks :)

Licensing issues aside, for an ecosystem like Unity to upgrade its runtime, c# language, and base class libraries is an enormous undertaking. While we are not perfect, we take backward compatibility very seriously. All of mono and coreclr has been available under MIT licensing for a very long time now. In Unity2017.1 we now ship an experimental option to use modern .net. this uses a new mono (not using sgen), new c# compiler (still mcs for now, so c#6, not c#7, and .net4.6 class libraries).

In a future unity version (won't burn my fingers on exactly which one) this new .net experience will become default. (depends on how many problems you find! :)

the xamarin (and microsoft .net) team are wonderful folks, and it's great to work closely with them to make .net in unity, and .net in general solid.

next up on the list is improving the garbage collection story, which is in the works, but we're first focussing on shipping a new runtime+c#+.net base class libraries.

While there are some very valid areas to point out that make c# challenging to be "the language of an entire game", we believe that c# is a great controlling language for Unity. We're working on some really interesting (imho) compilation pipeline for a restricted compute subset of c# that I think will completely turn around people's expectations and opinions of c# in gaming. stay tuned, this is one of the most interesting projects happnening inside of Unity today.


Just want to say, working with Unity and their team is a delight.

And they have given great feedback on the future of the language and framework that Microsoft is going to fully embrace to make Unity users happy.

Hugs and love Lucas!


That is awesome! Can't wait to see this stuff get released.


Keep up the great work!


Unity v2017.1 released for general access a few days ago has the possibility of .Net 4.6.

it is marked as experimental for now, but their release notes say it will become the new default soon

I am evaluating 4.6 support now and it works okay so far for my VR Game


It's just a really old version.


Implementations is the keyword here, it doesn't have anything to do with the language itself.

GCC was for almost twenty years quite bad versus other commercial compilers, yet it is worshipped nowadays for its performance.


This isn't Unity. Why does Unity's version of Mono matter here?


Tim Sweeney gave a good explanation why they went C++. Seems reasonable, but I'll be happy to see C# support.

https://forums.unrealengine.com/showthread.php?2574-Why-C-fo...

- As an engine and its community grows, there is increasing pressure to expose more of the its native C++ features to the scripting environment. What starts out as a sandbox full of toys eventually grows into a desert of complexity and duplication.

- As the script interface expands, there is a seemingly exponential increase in the cost and complexity of its interoperability or "interop" layer where C++ and script code communicate through a multi-language interface for calling functions and marshaling data. Interop becomes very tricky for advanced data types such as containers where standard scripting-language idioms differ greatly in representation and semantics from their templated C++ counterparts.

- Developers seeking to take advantage of the engine's native C++ features end up dividing their code unnaturally between the script world and the C++ world, with significant development time lost in this Interop Hell.

- Developers need to look at program behavior holistically, but quickly find that script debugging tools and C++ debugging tools are separate and incompatible. Seeing where script code had gone wrong is of little value if you can't trace the C++ that code led to it, and vice-versa.


I don't think so. If I remember it correctly, the Epic guys said something about switching back (for the Unreal Engine 4) from their own scripting language to C++, because multi language debugging was a nightmare, and working on a big Python/C++ project myself, I can comfirm this.


Arr, the inevitable defeat by the core languages performance boost- lets allow for pointers to arrays in the core language, to not loose speed. The locks and non-locks, the fun of value changes while some variable holds part of a array in local memory of the script languages maschine, the problem of external data corupption, without having everything under assert all the time aSSERT(Not NaN, Not Infinity). Plus, the script languages garbage collection, making a custom allocator necessary- allmost like the one you allready have written. On and on it goes. If it where not for the artists ease of use and fast iteration, nobody would use the script languages.


> If it where not for the artists ease of use and fast iteration, nobody would use the script languages.

Aren't those core tenets of game production? :)


Without the right tools, multi language debugging is a nightmare.

A mixed C/C++ callstack is so benign and common that it likely won't even register as being a "multi language" debugging experience. You get a single unified stack display, breakpoints, the works. There's a caveat or two around exceptions - that's about it. Everything just works.

C#/C++ isn't quite as solid, but it's still ahead of Python/C++ IME. Namely, Visual Studio will again show you a single unified callstack. There are more warts - again involving exceptions, as well as crash dumps and after the fact debugging. I've occasionally needed to break out WinDbg to deal with this.

Python/C++ is a bit harder. If you don't have a debug engine that can unify callstacks, however, there's still stuff you can do - dumping out both C++ and Python callstacks (and possibly locals) programmatically on assertions and in crash handlers, for example. I've done this for Java/C++, ActionScript/C++, Squirrel/C++, and probably more that I've forgotten.

"Own scripting language"/C++ is harder still: you must build your own everything. Debug engines are big projects - I haven't even completed my standalone one for brainfuck. If you dump your callstacks, you not only have to use the APIs that let you do so, but write them in the first place.


"C#/C++ isn't quite as solid" is a bit optimistic, in my experience.


If you download VR games, all the ones I have seen so far - that give credit - have been done with Unity. I know ones made with Unreal are out there, I have not download any with the Unreal logo yet though.

I dabbled with the Daydream Google VR NDK C++ sample app and did a demo app for myself of simple shapes moving around. While I could do simple things, I couldn't imagine doing the type of games others have done on the platform (or Oculus, or Vive) without Unity. For most people the question will be, why reinvent the wheel?

I don't know if C# will be the lingua franca of modern game engines, but for the foreseeable future, I think it will be the lingua franca of VR.


There's less Unreal based games for VR than Unity but some of the most graphically impressive titles are based on Unreal. Robo Recall for example.

Valve's The Lab plumped for Unity because of the state of Unreal's forward renderer at the time but they wrote their own renderer. This was fair while back and both engines have moved on since then.


I doubt it. C++ has been the standard for a long time now and what we're really talking about is scripting languages for higher-level stuff, not the actual game engine. On the one hand, yeah, C# is a good choice since Windows dominates the desktop market. But it's the sort of thing you can easily change and that users might have personal taste and preference for.

I went and looked up all the major game engines I could think of:

Blender: Python only

CryEngine: Lua and C#

Gamebryo: C++ only

Unity: C# and Java (Boo is no longer supported)

Unreal: C++ only (UnrealScript no longer supported)

Amazon Lumberyard: Lua (maybe C++ too?)

id Tech: C++

I was actually surprised at how common Lua was, but now that I think about it I have heard of it being used increasingly in games.


I remember the main language of CryEngine is c++. And Amazon Lumberyard is a fork of CryEngine (so also c++). Maybe I am wrong.


Oh sure, I was listing the languages it was scripted in. They're all C++ or C when it comes to what the engine is written in. Performance is super important in games, so you're just not going to see a high level language as the implementation language in a major engine.


Why not use Lua, Squirrel or JavaScript as game programming language? Many game engines use one of these languages, especially Lua is very very popular in this niche, and LuaJIT is sooo fast. Also Java is used in several game engines. C# (Mono) was only used in Unity as one of three languages (one being JavaScript/Actionscript). What other well known game engines that are used for triple-A games use C#? We all know the troubles of Mono that meant for Unity for many years, they had to fork an old version due to draconic license changes - Mono was a bad choice for Unity. As triple-A games are developed for Windows7+ and PlayStation4 (and less often also macOS, Linux, XboxOne, Switch) usually cross platform languages like Lua, Javs, JavaScript or Squirrel are used.

We are talking about the game scripting language, the game engine is always coded in C++ for triple-A games, with only a handful outliers. It's different for indies. We all know how the "Managed DirectX" and the incompatibile successor XNA turned out, the C# DirectX community is dead, end of life and last supported on the old XBox360, dead like Silverlight https://en.m.wikipedia.org/wiki/Microsoft_XNA .


It turned out that Monogame is one of the official Microsoft supported ways to develop indie games on XBox ONE.

http://news.xbox.com/2016/03/14/letter-chris-charla-idxbox-u...


Even outside the engines available to us plebs C# is becoming extremely popular in game dev. It's basically ergonomic C++ so it's very familiar to the kind of people who do games for a living, the VM is world-beatingly fast, and it's an easy language to hire for. Most games companies use Windows anyway so the MS lock-in isn't so much of a downside (obviously C# isn't Windows-only now but it's still controlled by MS).


C# has been in the gamedev toolkit since XNA, over a decade ago.


Yeah and MSFT showed their stink finger to the community twice, first with C# Managed DirectX, then with end of life for C# XNA. https://en.m.wikipedia.org/wiki/Microsoft_XNA

Who would be so stupid and learn-resistant to use C# a third time for games?? Well there are those sheeps, that believes and do everything for their PR department.


They have brought back support for XNA/Monogame when they released the new XBox games program.

http://news.xbox.com/2016/03/14/letter-chris-charla-idxbox-u...

XNA was a victim of the usual internal wars between Windows Dev and DevTools R&D units, about which way to build software (.NET vs C++).

Hence why they are so supportive of Unity nowadays, which is the main way to develop HoloLens applications.


> XNA was a victim of the usual internal wars between Windows Dev and DevTools R&D units, about which way to build software

the reasoning behind it doesn't change the years of my life I spent learning an obsolete tech stack.

which is fine: tech moves on. Except for the fact that MS told me it was the future.

and I don't blame them, but I'm also not going to take them at face value again.


and while XNA is technically dead, Monogame lives on top of the bones if you want to code from scratch in C#.


Nope. This project is using patched engine and easily could be in the same position as present Linux support (which is "Builds for, not working well").


> Is C# becoming the lingua franca of modern game engines?

Unfortunately. It's a decent language, but it just seems a bit too heavy to use as a scripting language, but not as good as C++ for heavy lifting.

I'm doing some stuff on Godot, and will probably just end up using GDScript for basic stuff, and GDNative for more intensive stuff (It's a C/C++ API for shared libraries that you can load up through the editor).


> but it just seems a bit too heavy to use as a scripting language, but not as good as Assembly for heavy lifting.

> but it just seems a bit too heavy to use as a scripting language, but not as good as C or Pascal for heavy lifting.

Are two variations of that statement I have heard among games developers since I am in computing.


Sounds suspiciously like Embrace, Extend...


Microsoft's sponsoring Mono now, and they've always been pretty benevolent towards game companies, especially with how seriously they take backwards compatibility. I wouldn't worry too much, at least not at this point.


The lead for this project[1] recently gave a great talk[2] at .NET Fringe on some of the interesting things coming up for Mono. Definitely worth a watch.

[1] https://github.com/mhutch

[2] https://www.youtube.com/watch?v=uxzS-grpN4c


A little bit unrelated, but serious question. Mono and .net core are not going to converge? I mean that would be awesome. Since most of game developers nagging about Mono's bad performance


They're not strictly converging, but there is ever increasing code reuse where it makes sense. Mono supports a lot more in the box than .Net Core currently does. I could see a point where .Net Core covers as much as Mono does within reason, and the rest of Mono eventually becomes separate packages in Nuget.

But wouldn't expect that in under 3-5 years. Just an observer from the sidelines.


Would be interesting if the author could comment on the memory footprint and performance of having an additional GC'ed language running alongside the engine. It seems like it could lead to complex hitching issues.


Wouldn't it be roughly like when games embed Lua?


I think the difference would be that UE is used more in AAA games that have high performance requirements, which can be non-trival.

You can see an example of troubleshooting lock hitches using a 3rd party tool to get an idea of the complexity. https://www.youtube.com/watch?v=RE04LQffZfs


Crysis & CryEngine used LUA so I don't think the AAA argument makes sense.


UE didn't go that route as you'll notice though, that was one of the reasons if I'm remembering correctly.


I can guess: Too many cooks, spoil the broth! :)


A good thing. The C# bindings for Unity are great for scripting - the language is surprisingly suited to lightweight logic. This should be a nice gift to developers not yet familiar with C++.


For 'lightweight logic' maybe, but using GCed language for almost all logic executing every frame is bad idea.


Just because it's GC'd doesn't mean it's constantly allocating memory. Optimizing the most common heap allocation sources isn't very difficult (especially compared to the nightmare of manual memory management).

I recommend running the Roslyn Clr Heap Allocation Analyzer extension for VS for a few days - it helps to learn which language features and APIs implicitly allocate objects (or box value type objects).

Plus, modern GC implementations are super clever and efficient (as opposed to the implementation used by Unity, which unfortunately rather sucks, but I hear they're working on swapping it out).


I wrote games and engines in C++ for 15 years, and Unity for about 5. I strongly prefer manual mem management, hands down. Optimizing for Unity's GC, in pathological situations, is the nightmare.

If the game is relatively simple, and the heap relatively small, it's not a big problem. But if you're trying to make a large, complex simulation that's actually pushing boundaries, the GC becomes a constant adversary. People always talk about allocations, but not allocating during a frame is just the minimum price of admission. The real trouble is the static characteristics of the heap, like size and graph complexity. With manual alloc, at least the problem is straightforward: don't leak, and don't dangle. With a black-box GC, where you can't even hint to it about the lifetimes of objects, you have to be much, much more aware of memory management, then go through a lot of different non-idiomatic contortions regarding every single thing you put on the heap.


Unity GC is a bad example, because it is widely known that their implementation is pretty crappy, frozen in 2007 implementation.

The majority of GC implementations out there are generations ahead of what Unity's GC is capable of.


C# has value types, it takes some careful coding to avoid GC stutters, but imo not nearly as careful as C++


Uh, what? C++ doesn’t have garbage collection. Did I misread this comment?


I read that as "[C#] takes some careful coding (to avoid GC stutters) but not nearly as careful as C++ [requires in general]".


That would make more sense. I can see that now.

Whether that tradeoff is the one to make probably depends a lot on what kind of game you are making.


Still possible to have huge deallocations in C++. On top of that, C++ makes it possible to fragment memory, whereas .NET's GC can compact references.

In both languages you have to be conscientious of types of allocations.


I've had to deal with "huge" deallocations causing stuttering before - by e.g. deferring deallocation over several frames. Deferred deallocation is also occasionally important for working around use-after-free bugs in middleware or system APIs that you don't have the source code to.

Building and using the tools to track down and break up circular references, dangling pointers, leaks, visualize memory fragmentation, etc. has eaten up a lot of my time.

I've considered attempting to write what would amount to a compacting GC in a C++ codebase to deal with memory fragmentation issues before - but retrofitting such a beast into an existing codebase was a huge enough undertaking, that we went for other simpler half measures instead. Being unable to control some middleware and system allocations meant any such GC would involve half measures and hacks as well anyways.



The engine makes uses of shared pointers to do ref counting, and will deallocate unrefed objs for you. Additionally there is a built in asset GC system.


Actually C++11 has a GC API and Unreal does make use of a C++ GC.


Hmm...looks like the repo is not available?[1]

[1] https://github.com/mono-ue/UnrealEngine


It's forked from EpicGames/UnrealEngine, you have to be logged in and have access. https://www.unrealengine.com/ue4-on-github


Been waiting a long while for this. Super keen to get stuck in. Huge thanks to the whole team.


Is there something wrong since it seems to be missing and a lot of the links don't work?


You will need source access to Unreal Engine on GitHub to get access to the MonoUE fork.


Why is this interesting.?


Why wouldn't it be? There are tons of entries on HN on [insert random project]. If enough people upvote in short enough time it hits the FP and is considered interesting. Not sure what else there is you want to see answered?

The question: "Why is this interesting to me." Is entirely different and we cannot possibly start to answer that for you.

We can give you the executive summary though. This brings access to UE4 to people without c++ knowledge. You can compare it to any managed wrapper around an unmanaged library. Some will curse it, others love it.


Previously you could only write code for the Unreal Engine with C++ or the visual scripting system, Blueprints. This allows people to use C# for everything that they would normally need C++ to add to their games - which will particularly help with people who are trying to transition from Unity to Unreal.


UE3 had UnrealScript, a VM based scripting language, similar to Java or C#. It is odd, that Epic removed it in UE4, and now someone makes it as plugin.


There was one good podcast (that sadly not in English with) Nick Atamas (senior engine programmer in Epic).

They had serious reason to not provide any official scripting support in UE4. Basically there no single language and runtime that would work well across all platforms: between Python, Node.js, Mono none of them work on every platform Epic target. Some don't have good support for consoles and other for mobile platforms and maintaining fork is hard even for Epic. So instead they try to extend blueprints instead since for them there are no such problems with C++.



What's wrong with the comment? I think you're assuming that it is disparaging when the person is simply asking why this is interesting.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: