Cowboy Programming Game Development and General Hacking by the Old West

February 26, 2008

Managed Code in Games

Filed under: Game Development,Inner Product — Mick West @ 11:13 am

This article originally appeared in Game Developer Magazine, January 2007.

MANAGED CODE IN GAMES

The term “Managed Code” was once considered little more than a buzzword by many game developers. Synonymous with poor performance, uncertain memory usage and the unfamiliar C# language, managed code had a bad rep that many established game programmers could not get beyond. Yet managed code is becoming increasingly relevant in the world of game development. This article explains what managed code is, how it can be used in games, and why it is important to game programmers.

WHAT IS MANAGED CODE?

Managed code can be best explained by comparing it to “native” code. Native code is the executable file that results from compiling, say, a C++ program into the .EXE file that contains actual machine code that runs “natively” on the target platform. Managed code, on the other hand, is code compiled into an intermediate language (IL) that is executed either on a virtual machine (like early Java), or semi-natively using “Just In Time” (JIT) compilation (like C#). At a more fundamental level, native code runs directly on the CPU and has direct access to system resources (particularly memory), whereas managed code has a layer insulating the code from the hardware, which “manages” the code operations and resource interactions.

Many games, especially big budget AAA games, already use some kind of home-grown managed code in the form of either an interpreted scripting language, or a language that compiles into a byte code that runs on a virtual machine. Commercial game engines often have their own scripting language, which is essentially managed code. The Unreal engine has a Java-like UnrealScript. The Quake engine has “Quake script”. But when people speak of managed code, they generally are not referring to these home-grown scripting languages, but rather to writing the actual game in managed code, which for the PC means using Managed DirectX.

Managed DirectX is not DirectX written using managed code. It’s simply an interface to DirectX that allows it to be used by managed code. This distinction is very important. The lower level DirectX layer is still just the same, and can still push polygons around just as fast as before. Just now you can call it from managed code.

Managed code does not always mean C# either. In Visual Studio, C++ can be compiled into IL simply by adding the /clr compile switch, which allows you to use managed DirectX.

WHY MANAGED CODE?

When asked what advantages you get from managed code, proponents will tell you the biggest advantage is productivity. Managed code, in theory, will allow you to write your programs faster. There are several reasons given for this.

Firstly, managed code is easier to write. Writing your code in C# generally results in shorter and more readable code. You don’t need to have header files. Compilation times are reduced. With managed DirectX using C#, the DirectX initialization code is greatly simplified. In addition the .NET framework supplies you with a lot of components you might otherwise have to write yourself.

Secondly, managed code removes the causes of many bugs. Variables are always initialized, so you can’t have bugs resulting from uninitialized memory. Memory management is automated with garbage collection so there should be no memory leaks and no dangling pointers.

Another advantage of managed code that is often touted is that of “interoperability”. This is the ability to mix and match languages, both managed and unmanaged, in developing an application. Regardless of which language a particular component is written in, it is theoretically quite easy to interface it with other components written in different languages. This is of limited application to game developers, except as it pertains to the interface between managed and unmanaged code.

A final advantage of managed code is security. Firstly, managed code removes (or makes impossible) the potential security loopholes that often exist in native code, such as buffer overruns. Secondly, “managing” code controls its access to system resources, such as the file system and memory, in such a way that even if some nefarious code was introduced into the application, it would be unable to do much damage.

WHY NOT MANAGED CODE

Managed code is obviously not without its problems, and those problems strike fear into the heart of any battle hardened game programmer. Namely: framerate and memory.

Performance is nearly always going to be worse with managed code than it is with native code. This is because JIT compilers are currently not very good at optimizing code, and because the managing of code and the facilitation of that safety and memory management introduces a significant amount of overhead that drags down the speed of your code.

As well as pure code speed, the unpredictable nature of garbage collection means it is difficult to predict CPU usage. If a lot of garbage collection happens at once, it might cause framerate to drop

Memory usage is another problem. Since the code is complied into IL, the executable file can actually be smaller which is a momentary advantage. But once the program is loaded into memory, and JITed, the lack of optimization means the native footprint will be larger. The additional overhead of storing the CLR, boxing, and memory management also add to the total memory usage.

As a practical example, I took my “Blob” example (See Game Developer June/July 2006), and recompiled it with in Visual C++ with the /clr option. Three effects were apparent:
The size of the executable dropped from 140K to 116K
The frame rate dropped from 160 frames/second to 60 frame/second
The memory usage jumped from 29MB to 34MB

Why so slow? Well the “Blob” example is highly CPU intensive, and involves a lot of iterating over arrays and STL vectors of atomic objects and performing fairly complex operations on them, like collision detection and Verlet integration. This is simply not something that the .NET CLR is very good at doing. The code that is generated, and then JITed, ends up not being at all optimal, and since the CPU time is the bottleneck this causes the precipitous drop in frame rate.

MANAGED CODE FOR GAMES

So, if by using managed code we get this dreadful drop in frame-rate, why would any game programmer use it?

The most obvious answer is that not all games need all the CPU power or all the memory. Consider the rapidly growing market for casual games such as Diner Dash or Luxor. These games require very little in the way of processor resources, and are necessarily small to facilitate quicker downloads. The faster development times are also a big plus, as casual games are generally low budget, with a schedule of just a few months. The robustness provided by the automated memory management is a win again here, contributing to faster development, and easing the process of debugging around release. C# has not been too popular with casual games, due to the possibility of having to download the .NET framework, but that’s increasing installed by default on PCs or deployed automatically via Windows Update, so that objection is less relevant.

But what about games such as Half Life 2 or Neverwinter Nights 2? Is it possible to do high end games like this using managed code? The simple answer is “no, unless you want the game only playable with 2 gigs of memory and at half the frame-rate”. The more complex answer is “yes, as long as you use managed code for the right things”.

DIVISION OF LABOR

The key to successfully utilizing the benefits of managed code is to divide your code up in such a way that the code that would contributed most to performance degradation under managed code remains as unmanaged (native) code.

It’s often said that 90% of the (processing) time is spent in 10% of the code. That 10% (measured in lines of code) is code that performs large numbers of iterations, looping over data structures, performing repeated operations. These operations are things that are performed many times per frame, every frame, things such as collision detection, physics simulations and skeletal animations.

The remaining 90% of the lines of code (which takes only 10% of the processor time), is code that either is not executed every frame, contains very few iterations, or is only executed in cases where frame-rate is not an issue. Code such as user interface display, network packet marshalling, or artificial intelligence.

Managed

Player Control
Camera Motion
Combat Systems
User Interface
Game flow
State Transition AI
Saving and Loading
Data marshalling
Compositing Effects
In-game editors

Unmanaged

Collision Detection
Physics
Pathfinding
Skeletal Animation
Video Processing
Vertex Processing
Particle Systems
Visibility Determination
Fluid Dynamics

This table shows which types of code are suitable for managed code, and which are not. You might notice one thing about all the code tasks listed in the “unmanaged” column: they are all tasks that are commonly performed by commercially available engine components, or by a generic in-house engine. They are also typically components that are “close to the metal”, in that they may be hardware dependent, utilizing target specific resources. They are not game specific.

The code in the “managed” column, on the other hand, is higher level code, and generally platform independent. This code is often highly game specific, and can account for a very large portion of the actual code written for a particular game project, especially one that is based on an existing game engine.

So it’s clear how the division of labor works, low level engine components that require speed and efficient memory usage can remain in unmanaged (native) code. Game specific components that generally use less of the system resources can be written in managed code to gain the productivity benefits. If a game specific component ends up being a bit too inefficient in managed code, it probably is something that can eventually be made into a core engine component down the road.

MANAGED CODE IN EDUCATION

Since managed code is simpler to develop in than unmanaged code, it is an ideal language platform to use to initially instruct students in the craft of game programming. In addition, the easy accessibility of DirectX and XNA makes managed DirectX an obvious choice of platform for students to use when implementing their first game. Hence the modern student’s first exposure to game programming may well be in a fully managed code environment. Certainly courses in game development that are not structured along the lines of a traditional CS degree will be more heavily oriented towards a managed environment.

This means that there is a whole generation of games programmers coming along who are not only experience in programming for managed code languages and environments, but may actually be more experience in writing managed code than in unmanaged code. The result of this is that more your engine utilizes (or allows for) managed code, the greater your talent pool of potential game programmer will be. It’s quite possible that managed code will grow in popularity in the educational and hobbyist front to such an extent that there will be shortages of programmers who can write and debug code effectively in unmanaged C++, much like you would be hard pressed to find many young programmer comfortable in programming games in ASM, or even straight old-fashioned C.

THE MICROSOFT EFFECT

Perhaps the biggest influence on the future of managed code in games will be Microsoft’s popularization of the XNA framework for game development. Microsoft is aggressively pursuing the hobbyist game developer market to the extend of giving away for free the Express versions of XNA game Studio, including C# and C++ Visual Studio, all of which are tools which are quite capable of being used to create professional games.

Microsoft is also teaming up with the educational establishments to promote the XNA framework, with several universities adding courses based on this technology. But perhaps the biggest driving factor in all this is Microsoft’s decision to allow independent game development for the Xbox 360 console, with one caveat – the games have to be written entirely in safe managed code.

Why only managed code on the 360? Two simple reasons: firstly to prevent viruses and malware, and secondly, and most importantly, to prevent the development environment being used to pirate games and other paid content.

The ramifications could huge. Potentially a whole generation of hobbyist and student programmers will get their first experience of console programming on the Xbox 360, using XNA and C#. One the one hand this could be a great competitive advantage for Microsoft in a few years, as perhaps the majority of programmers will enter the game development industry with experience in Microsoft products. But on the other hand it could also be viewed as a great push for managed code in general. Aside from the DirectX framework, the .NET framework is portable (via the Mono project), and C# is an open standard which runs on Linux as well as Windows.

SUMMARY

Managed code can offer significant productivity gains, yet those gains come with equally significant speed and memory performance hits. For smaller games it’s quite reasonable to write the entire game in a managed language. In larger games managed code is not appropriate for engine components, but can work very well on a significant portion of the higher level code.

The popularity of managed code in education, and the easy availability of development tools may mean that the next generation of game programmers may feel most comfortable and productive programming in a managed language, and game developers would be wise to recognize this and incorporate managed code into their programming environment.

RESOURCES

Gamasutra, Microsoft to Enable User-Created XBox 360 Game, August 14 2006
http://www.gamasutra.com/php-bin/news_index.php?story=10458

Kyle Wilson, Why C++, GameArchitecht.net, July 2006
http://gamearchitect.net/Articles/WhyC++.html

5 Comments »

  1. hooray! thanks ;)

    now if only c# was properly cross-platform..

    Comment by raigan — February 27, 2008 @ 1:26 pm

  2. Please do note a previous discussion on this article at: https://cowboyprogramming.com/2007/01/05/blob-physics/
    And some subsequent followups:
    http://scapecode.com/category/14.aspx

    As far as C# being cross platform: The mono project has demonstrated how it can easily be implemented on a plethora of platforms in the Open Source world. There’s also reference implementations available from Microsoft and even some efforts to build a micro one that works on the PSP: http://scientificninja.com/development/csharp-on-the-psp

    Comment by Washu — March 29, 2008 @ 12:12 pm

  3. It’s always nice to see managed code for games get a little more of the the spotlight.

    I think the main way this is happening right now – is Lua. It’s widely used in many projects. A low level engine is written in C++ and then the logic is handled in the scripting language itself.

    That said I do love C# because it’s so tightly bound to Visual studio. It’s extremely easy and fun to program in.

    Comment by dan — May 17, 2008 @ 12:42 pm

  4. You should also keep in mind that (most of the) C++ will probably compile to the C# equivalent of “unsafe” code, which ends up being slower then plain .Net code.
    If you would’ve converted your code to C# (which would be a scary undertaking, i wouldn’t recommend it) your fps would most likely have gone up (still not as fast as c++ obviously).

    Comment by Sander van Rossen — June 18, 2008 @ 1:45 am

  5. True, – this was discussed at some length in the links Washu provides, above in comment #2.

    Comment by Mick West — June 18, 2008 @ 6:53 am

RSS feed for comments on this post. TrackBack URL

Leave a comment

You must be logged in to post a comment.

Powered by WordPress