C++ vs C#: has the time come to develop games in a managed language?
(level : easy)


In December 2006, Microsoft released the first version of the XNA framework and tools, designed to allow programmers of all levels to develop games for both Windows and the Xbox360. Initially, the only language supported is C#, and if others (like Visual Basic) are added in the next versions of XNA, they will all belong to the .NET family, meaning they will all be managed languages. This makes sense for Microsoft, since they need some way of controlling what is executed on the Xbox360 especially, to prevent people from creating viruses, cheating on Xbox Live, or running pirated games. But from a developer's point of view, how adequate is it to use C# to write games, what are the advantages and drawbacks of the managed language compared to the good old native C++? (in this article, "C++" always refers to "native C++", and not "managed C++" of course).


C++ is the language of choice to develop console games, isn't it?

Yes it is, if we're talking about game engines and middlewares only. But creating a game requires tools, lots of them, some you buy and some you develop yourself. A quick survey during a Tools Roundtable at GDC 2006 showed most game companies use C# and the Windows Forms to write new internal software, and sometimes even try to progressively migrate their old C++ / MFC applications to the .NET framework. They don't do it purely for fun of course, but because they found their teams work faster and can accomplish more when using .NET (and the programs eventually end up being more reliable - more on that later). At Alias' Maya API developer's conference in June 2006, people from Secret Level gave a talk about using C# to develop Maya plugins, despite the fact the SDK is 100% C++ based, and reported their productivity was multiplied by a factor of around 3.

What about the game code itself, responsible for everything happening in the universe presented to the players? Most of the time it is written in some scripting language, like Lua or UnrealScript. Initially, it used to be like that because technical designers were the ones creating behaviors for the different entities of the game world, and they needed something they could modify and test without recompiling / debugging the whole project in Visual Studio or something equivalent. Guess what: game programmers have the same problem now, at High Moon Studios [1] they don't implement features requested by the designers in C++ anymore, they use scripts, and the explanation for that is iteration time.

[1] The views and opinions expressed in this article are strictly mine, and don't necessarily reflect those of High Moon Studios (my current employer) or Vivendi Games.


Iteration time

As everybody knows, on average projects keep getting bigger in the game industry, with more programmers writing more code and using more middlewares (I'm not even talking about content). This results in tens of thousands of lines to compile, and even the best compilers are having a hard time dealing with that amount of C++ code. One problem here is header files: parsing them takes a lot of time, and if precompiled headers are helpful for external libraries such as the STL, they don't solve anything regarding code that is frequently modified. The issue is actually so big, that some people use the Single Compilation Unit method to work around it: the basic idea is to have a new .cpp file that includes all your original .cpp files (you read that correctly) and nothing else, and to compile this single unit instead of all the separate files. This technique has some drawbacks (no more incremental builds, potential naming conflicts, some definitions are now visible from everywhere, see this page for details), but I tried it for myself, and got a 4.6x speed improvement on some not so big (about 100k lines) code base!

C# doesn't have header files. When you think about it, this is pretty cool, since this basically divides by 2 the number of files in your solution, and you don't have to repeat prototypes of functions you're going to implement somewhere anyway. In addition to that, your code is only compiled to some platform independent intermediate language (MSIL), which simplifies the job of the compiler, and doesn't have to be linked since C# uses DLLs rather than static libraries. Of course this has some implications regarding performance when you launch your program, but the bottom line is: compiling is very fast.

To me, the biggest advantage of using C# (or another managed language) is not the huge number of classes provided by the .NET framework, or the fact that it handles the destruction of unused objects for us through garbage collection, or how much easier it is to do some things with Forms rather than MFC; it is iteration time, i.e. the time it takes to modify, compile, and test some piece of code. If this time is too long, and you have to wait a few minutes before you can see the effect of each little change you make to your program, your productivity drops dramatically as you end up spending more time waiting than typing. Like I mentioned before, the programmers working on gameplay features at High Moon Studios exclusively use scripting, because it allows them to try many more things very quickly, without having to go through the long C++ compiling and linking process. The idea is the same when using C#: compiling is fast, and you can get a lot more done than if you constantly have to wait for feedback.

Don't get me wrong though: I'm not saying it's impossible to have a C++ code base made of loosely coupled classes, where inter-dependencies are kept to a minimum, and concepts such as interfaces and the Pimpl idiom are put to good use to improve compilation speed. But the truth is: the C++ language doesn't do anything to help you in this area, getting things right requires constant attention, and we all know unnecessary headers always end up being included in other headers at some point (this is actually the most common mistake I find when reviewing code samples from job candidates).


Reliability

Iteration time is one thing, but the productivity of programmers is certainly also greatly affected by bugs: the more time we spend debugging, the less time we have left to implement new features or extend existing ones. Everybody makes mistakes, but some of the characteristics of C# help preventing very common ones:
I only listed a few things here that, in my opinion, make it a bit easier to avoid very common bugs when using C# rather than C++. This list is not exhaustive, I didn't talk about type safety and delegates for example (delegates is the C# way of having type safe function pointers basically). And this is not a summary of differences between C++ and C# either, there would be many more (C# has 'properties', 'generics', 'reflection', but C++ has 'templates', etc).


Performance

So far in this article, I've said that C++ is not the only language used in game development, that iteration time is critical and C# does very well in this area, and that managed code should also require less debugging. But if you want to go beyond tools programming, and develop a full game engine in C#, performance is a topic of utmost importance.

The first thing people seem to worry about is garbage collection (GC): is it not too time consuming, is the framerate going to drop if you do a GC each frame, or if you don't call it that often and let dead objects accumulate, then will the game stop for 1 or 2 seconds when the cleanup finally happens? I didn't do any big experimentation myself, but here are a few interesting facts:
Another issue is Just In Time (JIT) compilation, and the speed of the generated code. JIT compilation means a big part of your code is going to be translated from the Microsoft intermediate language (MSIL) into native code for the local machine at startup, when you launch your application. This works pretty fast, but some other assembly that is not needed immediately could also be compiled while your program is running, in the middle of the action, right before the code it contains gets executed. I haven't tried it on the xbox360, but on PC there is a tool called NGen that should take care of this potential problem, by allowing you to compile everything on the target computer once and for all, when installing the game for example.

In the January 2007 issue of the Game Developer magazine, Mick West described how he recompiled a blob simulation with the /clr option of Visual Studio, to compare the size and speed of a native application with a corresponding managed one. He found the framerate dropped from 160fps to 60fps, which sounds terrible even though he admitted this sample was more of a worst case than a best case scenario for the .NET framework. Still, what I don't like about this test (I like the article though, since it encourages people to try managed code) is it doesn't take the specifics of the target language into account: even if native and managed C++ look quite similar in a text editor, the way they operate and use resources is very different, and I'm not sure using the STL in managed code is a great idea for example. When I wrote my first C#/XNA application, I started manually converting some C++ code I had; but since it was full of pointers and unsafe casts, this was tricky, and I quickly ended up rewriting the same function in a different, C# friendly way. The point I'm trying to make here is: you can not count on the compiler to do everything for you, that would be too easy, like for any other language programmers interested in real time performance will have to learn the do's and dont's.

Fortunately, there are examples to prove writing games in C# is possible, and I mean fast 3D games, not just puzzles or that kind of thing. The German company exDream Entertainment has developed a racing game (see pictures here) that should become one of the starter kits of XNA, and a few PC games in C# before that . The blog of their lead programmer Benjamin Nitschke contains some very interesting information about game development using .NET, and so does the beginning of this interview (the rest is more XNA oriented). GarageGames also wrote a non optimized C# version of their xbox360 Live Arcade game Marble Blast Ultra, and were apparently quite pleased with the results! Sure, these games may not have tons of objects affected by the laws of physics, or a complex path finding, or any other CPU intensive algorithm you want to insert here; but it doesn't mean it's impossible, it's probably only a question of time before somebody does it.

Other performance pitfalls I've seen mentioned are related to 'boxing' (converting a value-type, for example an 'int', to a reference-type such as System.Object), and the Platform Invoke (P/Invoke) mechanism (that can be used to call functions of the Win32 API from managed code). The basic rule here is to avoid doing these things too frequently (i.e. in time critical loops), completely getting rid of them is most likely overkill (let's call it premature optimization).

There are certainly a few more problems that will show up every now and then, and performance is probably always going to be a bit worse with managed code than it is with native code anyway, after all nothing comes for free. Tim Sweeney wrote he would gladly sacrifice 10% of performance for a 10% higher productivity, personally I'm fine with losing even a bit more than that, if that allows me to take advantage of the huge productivity gain C# brings to the table. In a way, to me it's like using C++ instead of assembler: you can't beat the speed of the latter, but writing and debugging a reasonably big game in assembler would be time consuming to say the least, and I'd better spend more time adding features and tuning the game, rather than try to make the fastest piece of software ever, and have a hard time keeping it stable. The gap between C# and C++ is obviously not as big as the one between C++ and assembler, what I mean is this is the same kind of compromise we always have to make: performance versus productivity.


Learning Curve

I can hear some people thinking: "I have been programming in C++ for many years, I'm an expert, I don't want or don't have time to learn another language". There is no worry here: you don't even need to read a book, C# looks so similar to C++ that you can start coding immediately. Later on you may have to search for the exact syntax for properties or delegates, but basically that's it, everything is pretty straightforward (especially if you have done some Java as well).

The real problem is to avoid reinventing the wheel, by knowing what's available in the .NET framework, and where to find it. There are literally a few thousand classes, which might sound overwhelming; fortunately, they're grouped under namespaces corresponding to what they do (for example, System.Collections includes the different containers supported by the framework, and the generics introduced by .NET 2.0 are in System.Collections.Generic), you will end up always reusing the same ones, and the IntelliSense system of Visual Studio makes it easy to navigate the tree of namespaces and see what classes are in there. Otherwise, there is the internet and your favorite search engine, that works very well too :-)

If you have to create GUI applications, using the Windows Forms shouldn't be difficult. The controls are the same as usual, with the addition of the PropertyGrid (used in Visual Studio itself), which is a very powerful tool since it takes advantage of the reflection feature of C# to display the properties of one or several objects (yes, it supports multi-selection editing!). I would just recommend using VS 2005 and .NET 2.0 rather than VS 2003 and .NET 1.1 if you have the choice, a few missing events have been added to some controls, and the designer feels improved as well. If you have used MFC in the past, you should find the code generated by the designer is cleaner: for example, the horrible message maps are replaced by event handlers and delegates, and some tasks like creating nested splitters don't even require you to write code anymore, it can be done entirely in design mode. Same thing with resizing controls when the dimensions of the window containing them change: the new docking/anchor system is not perfect, but it can handle a lot of common situations with only a few properties to edit.

To sum it up, programming in C# is easy if you have coded in C++ for a long time, creating a GUI with the Windows Forms is not difficult either, discovering the content of the different namespaces of the framework takes a bit more time though; but you don't have to learn everything upfront, this is an incremental process, and these already implemented classes is one of the things that will help you save time and increase your productivity.


Has the time come to develop games in C#?

If C# is so great, why is not everybody in the game industry already using it? The first problem is: it's not really cross platform. Its primary target was the PC, it has only been available on xbox360 since the end of 2006 (with the release of XNA 1.0) and there are still a lot of limitations in this case (for example, it's impossible to write a tool running on PC that talks to the console while the game is running), and it's not supported at all on other consoles.

The second problem is middlewares: they are all written in native code, with a C++ API. It is totally possible to call such an API from C#, for example to write a managed program that uses OpenGL for rendering. There are several drawbacks to take into consideration though:
A third problem is executing the game: in addition to DirectX or OpenGL, a C# game needs the .NET framework in order to run. This issue is not too bad, PC games already contain a redistributable version of the DirectX runtime, they could also install the .NET framework if it's missing on the target computer. On xbox360, I suppose Microsoft could push the framework through Xbox Live if they wanted to, but it would also have to be included on the DVD anyway (for people not connected to Xbox Live).

So, do the first two problems mean the answer is "no" (the time has not come to develop games in C#)? I guess if you want to develop for other platforms than the Microsoft ones, you'll have to stick with the good old C++, probably for a very long time (I don't see any other language replacing it any time soon). You can (and should) still use C# to code some tools running on PC, but that's about it.

Now if you're mostly interested in the PC and Xbox, or if you can afford (lucky you!) to develop a game for only one platform (and eventually port it to other ones later when your title is successful, or have another company do the conversion), then it's a different story. There is still the issue of middlewares, and the limitations of XNA on the xbox360 (at least until XNA Game Studio Professional is released, supposedly next summer), but I believe it's time to begin experimenting, at least on PC. It's time to do some R&D work and learn the do's and dont's regarding performance, to start writing libraries that are too game specific to be in the framework, and perhaps to develop a prototype in managed code for a future game. Think about it: a prototype doesn't have to run on all existing platforms, and would be quite a learning experience! I think Microsoft realizes developing games is really becoming way too long and expensive, and I expect them to encourage developers to make the move to managed languages a lot more in the future, maybe with the successor of the xbox360, or even before. If that happens, we, game programmers, would better be ready for it! And let's face it: learning and trying new things is part of what makes our job so exciting, isn't it?



back to top