What pitfalls did you encounter when writing games for the PC with a managed Language like C# and how did you solve them?
I don't know much about Java, so this is from the point of view of a .net developer.
The biggest one by far is garbage. The .NET garbage collector on Windows does a fantastic job, and you can get away without baby sitting it for the most part. On the Xbox/Windows Phone 7 that's a different matter. If you get stalls every few frames, garbage collection might be causing you problems. At the moment it triggers after every 1MB allocation.
Here are some tips for dealing with garbage. You shouldn't have to worry about most of these in reality, but they may come in handy one day.
- Draw the contents of
GC.GetTotalMemory()to the screen. This gives you an approximation of the amount of allocated bytes your game uses. If it hardly moves, you're doing OK. If it's going up fast, you have issues.
- Try to allocate all your heap objects up front. If you don't allocate everything before the game starts, every time you hit a meg of allocations, your going to stall. No allocations, no collections. As simple as that.
- After loading, call
GC.Collect(). If you know most of your big allocations are out the way, it's only nice to let the system know.
- DO NOT CALL
GC.Collect()every frame. It might seem like a good idea, keeping on top of your garbage and all that, but remember the only with worse than a garbage collection is over garbage collection.
- Look for where your garbage is coming from. There are some common causes like concatenating strings instead of using
StringBuilderisn't a magic bullet, and can still cause allocations!. This means simple operations like adding a number to the end of a string can create surprising amounts of garbage) or using
foreachloops over collections that use the
IEnumerableinterface can also create garbage without you knowing (for example,
foreach (EffectPass pass in effect.CurrentTechnique.Passes)is a common one)
- Use tools like the CLR memory profiler to figure out where memory is being allocated. There are loads of tutorials out there on how to use this tool.
- When you know where your allocating during gameplay, see if you can use tricks like pooling objects to lower that allocation count.
- If all else fails, make your collections run faster! The GC on the compact framework follows every reference in your code to figure out what objects are not in use anymore. Refactor your code use less references!
- Remember to use
IDisposableon classes that contain unmanaged resources. You can use these to clean up memory the GC cannot free up itself.
The other thing to think about is floating point performance. While the .NET JITer does a fair amount of processor-specific optimizations, it cannot use SSE or any other SIMD instruction sets to speed up your floating point maths. This can cause quite a big speed difference between C++ and C# for games. If your using mono, they have some special SIMD maths libraries you can take advantage of.
A tipical performance pitfall is not considering the garbage collector in the design/development of the game. Producing too much garbage can lead to "hiccups" in the game, which happen when the GC runs for a considerable long time.
For C#, using value objects and the "using" statement can alleviate pressure from the GC.
I'd say the biggest problems I've encountered writing games in C# has been the lack of decent libraries. Most I've found are either direct ports, but incomplete, or wrappers over a C++ library that incur a heavy performance penalty for marshaling. (I'm speaking specifically about MOgre and Axiom for the OGRE library, and BulletSharp for the Bullet physics library)
Managed languages (as distinct from Interpreted - neither Java nor C# are actually interpreted anymore) can be just as fast as native languages if you have a good understanding of what actually makes them slow (marshaling, garbage collection). The real problem, I think, is that library developers haven't realized that yet.
Like others have said, GC collection pauses are the biggest issue. Using object pools is one typical solution.
Neither Java nor C# are interpreted. Both of them get compiled into native machine code.
The biggest problem with both of them and games is having to code in such a way that they never garbage collect during game play. The number of hoops you have to jump through to accomplish that nearly outweighs the benefits of using them in the first place. Most of the features that make those language fun to use for application or server programming have to be avoided for game programming otherwise you'll get long pauses during game play as they go off and garbage collect.
C# and Java are not interpreted. They're compiled to an intermediate bytecode which, after JIT, becomes just as fast as native code (or near enough to be insignificant)
The biggest pitfall I've found is in freeing resources that directly affect user experience. These languages do not automatically support deterministic finalization like C++ does, which if you're not expecting it can lead to things like meshes floating about the scene after you thought they were destroyed. (C# accomplishes deterministic finalization through IDisposable, I'm not sure what Java does.)
Other than that, managed languages are really quite a lot more capable of handling the kind of performance that games require than they get credit for. Well written managed code is much faster than poorly written native code.
One large pitfall I see from making games with languages like these (or using tools like XNA, TorqueX engine, etc.) is that you will be hard pressed to find a team of good people with the expertise needed to create an equivalent game to what would be fairly easy to find people for in C++ and OpenGL/DirectX.
The game dev industry is still very heavily steeped in C++ as most of the tools and pipelines that are used to push out big or just well polished small games were written in C++, and as far as I know ALL of the official dev kits you can get for XBox, PS3, and Wii are released only with compatibility for C++ (XBox toolset may be more managed nowadays, anyone know more?)
If you want to develop games for consoles right now you pretty much get XNA and C# on the XBox and then only in a side part of the games library called XBox Live Indie Games. Some who win contests etc. get picked to port their game to the real XBox Live Arcade. Other than that plan on making a game for PC.