CIS 3000: Introduction to Computer Game Design

C# and XNA Resources

If you are programmer, then you will find this page to be a useful collection of resources for programming in C# and XNA. If you find any additional resources that you feel should be included on this page, please contact the course staff.

[C#] [XNA] [Libraries] [Tips]


Learning C#

While professional game programming is often done in C++, we are using the XNA game engine for class and thus must program in C#. Fortunately, you will find that C# is very similar to Java, and thus it is a lot easier to program in coming from a Java background. You will find the following resources helpful in getting started.

Java and C# comparison
This is a side-by-side reference that shows you how to translate a Java program into a C# program, and vice-versa.
The C# Tutorial
A tutorial covering many of the basic features of C#. Most of it is straight-forward, though you may want to pay special attention to Lesson 10.
.NET Framework Class Library
This is the equivalent of the Java API for C#. It details all of the .NET classes with their methods.

These resource are just to get you started. You should always feel free to pester the course staff with questions about C#.


Learning XNA

Once you have mastered C#, XNA is pretty easy. XNA is just an additional set of APIs that extend the .NET framework. Because it is rapidly becoming a standard platform for teaching game design, there are an awful lot of resources out there.

XNA Framework Class Library
This is the equivalent of the Java API for XNA. It details all of the XNA classes with their methods.
XNA Tutorials
This is a good collection of tutorials for elementary stuff in XNA. In the past, you could find most of the answers to the first lab here. However, some things may have changed with XNA 4.0, so be careful. You may want to wait until we have updated our demo page.
How to draw text
Because of X-Box considerations, drawing text is actually one of the more difficult things to do in XNA. This tutorial explains how to do it.
Microsoft App Hub
This used to be the XNA Creator's Club. It has since been rebranded as a phone-centric page because Microsoft is trying to compete with Apple and Google. This unfortunately makes it a lot harder to find things. You will probably want to stick to the game development page.

XNA on your Home Machine

Often people want to design games on their home machines instead of having to do them in the lab. In turns out that it is very easy to get XNA up and running provided that you have a copy of Visual Studio. You will either need a copy of Visual Studio 2010 (which is what we use in the CSUG lab), or Visual C# Express. We recommend that you use Visual Studio 2010, as projects created in these two versions of Visual Studio often have compatibility issues.

While Visual C# Express is freely available, Cornell has a program by which you can get a copy of Visual Studio 2010 through MicroSoft Developer Network Academic Alliance (MSDNAA). You should have been given information about obtaining software from the MSDNAA when you received your CSUG account.

Once you have Visual Studio 2010 installed, XNA is a separate installation on top of that. However, the right version depends upon which version of Windows you have. If you are an XP hold-out (like many of the computing labs on campus), then you will need the XP version of XNA 4.0. On the other hand, if you are using Windows Vista or 7, you will need to download the Windows Phone Tools. And no, I do not understand why they had to bundle XNA 4.0 with the Phone Tools either.


Libraries for XNA

One of the advantages of using a platform like XNA is that there is a large enough developer community that there are lots of libraries out there to help you do cool and unique things with it. This way you can leverage these libraries to solve your technical problems, and focus more on making your game fun. In this section, we present several libraries that you may find useful. Over the course of the semester, we will add more as we discover them.

Physics Engines

One of the most difficult parts of a modern game is the physics engine. Even more than graphics, this is one of the advantages of having a 2D game, since 2D physics is simpler than 3D physics. It also means that there are likely to be a lot of free physics libraries out there (unlike the 3D engines, which want some serious money). The preferred library for this class will be Box2D X, a port of the famous Box2D physics engine; we will eventually have a lab covering its use. However, there are several other alternatives to choose from. Each has its advantages and disadvantages.

Box2D X
This is an XNA port of the Box 2D physics engine. Unlike the other engines, it is incredibly well-documented with an excellent manual. However, the port relies on DLLs, and so this engine will prevent you from distributed your game on the X-Box. If you want to have an X-Box distribution, you will need to use another engine.
Farseer Physics
This was a popular 2D physics engine for projects that want to target the X-Box. It is native and is getting better all the time. However, in the past the the documentation has been horrible. Looking at the latest documentation page still leaves much to be desired.
JigLibX
This is a popular 3D physics engine for XNA. It has all of the documentation problems of Farseer and more. This is if you really want a challenge. However, it may be best to forget about this library until CIS 4002.

Steering and Pathfinding

Several people have asked about the steering and pathfinding prototypes that I have shown in class. Unlike the Physics engines, these libraries are a bit sketchy. In the past, strong students have had better luck implementing their own pathfinding algorithms. Use this libraries at your own risk.

XNA Pathfinding
This is a simple library supporting A* search. I am not sure I would trust it, as the page is not very active. Given its age, it may not be XNA 4.0 compatible. Use this at your own risk.
OpenSteer.Net
The OpenSteer library supports steering, the physics-based approach to pathfinding shown in class. It is great for local pathfinding and pushing through crowds; it is not so great for long treks across the game world. Like Box2DX, this uses DLLs and is not X-Box compatible.

Programming for the Kinect

Wouldn't it be great if you could create a Kinect game in XNA? Microsoft has promised support "in the future". If we hear anything, we will add that information to this page.


Important Programming Tips

Performance is very important in game programming, and you will often find yourself optimizing your code. However, there is always a balance between performance and readability. The following tips should help make easy to maintain code while avoiding some of the more basic performance pitfalls.

Asserts

Asserts are a nice way to make sure that your program is behaving the way that you expect it to. Whenever you assume that something is true, you should call the method Debug.Assert() to make sure that it really is true. For example, suppose you assume that the player's health is greater than 0. Then you should add the line

Debug.Assert(health >= 0, "player health is negative");

Other good things to assert are 'target != self' and 'level != null'. Note that the assert has a text message which it displays if the assert is not actually true. Look at the documentation for Debug.Assert() for more information.

If you're not familiar with the concept of asserts, this might sound like unnecessary extra work. However, getting in the habit of using assert is one of the biggest timesavers possible. It basically corners bugs before they can even happen. As soon something you assert fails to be true, you'll be told when and where. On the other hand, if the assert hadn't been there, (unless you get lucky) your game will keep running, some completely unrelated code will screw up, and you will have no idea why.

Note that asserts do not even get compiled in optimized Release builds, so your game will not run any faster if you don't use them.

Caching

The primary performance problem is often doing unnecessary computation in the Update() or Draw() method. These two methods are the ones that are called every animation frame, so the less computation you do here, the faster your game is going to go.

The most common pitfall is to perform computation that never changes between animation frames. For example, suppose a space ship has size size, and every frame, you want to draw a target sqrt(2)*size away from the space ship (thus the target scales with the size of the ship). Computing this number is expensive every frame; the sqrt function is not cheap. It is much better to make an additional field targetPos and set it equal to sqrt(2)*size in the initialization method, which is not called every frame. In this case, you are caching the computation in a variable, so that you do not have to keep doing it every frame.

Floats vs. Doubles

No matter what you might hear, doubles are slower than floats even on current (circa 2011) systems, and they take up twice as much memory. You should use floats instead of double in your game, except where extremely high precision is absolutely necessary (which, in this course, is basically never).

When you type a decimal number in your code like 0.5, that automatically means it's a double. You should instead type these values like 0.5f (append an f to the number), to tell the compiler it's a float and not a double. In general, you should also always use functions that require floats instead of doubles if at all possible. Unfortunately, the Math functions in C# all use doubles, and there does not appear to be any float versions of these functions. Therefore, you should be very careful how you use these functions, as type casting between a float and a double can be very expensive. You should cache these computations whenever possible.

Another feature that you will find with floats is that you may be tempted to compare two floats with the "==" comparison. This is fine and valid if you know they can be exactly the same, but in many cases all you really want know is whether the floats are within a certain range of tolerance within each other. In order words, you often want to test

if (Math.abs(floatA - floatB) < 0.001f)

instead of

if (floatA == floatB)

If you are relying on super-high precision for your game to work (e.g. you absolute have to use '=='), you are doing something wrong anyway that high precision will not be enough to fix in all cases.

Magic Numbers

A "magic number" is any numeric value in your program that has some semantic meaning, such as the window size, or the player starting health. Magic numbers are very confusing and often hard to debug. And they appear a lot in graphics programming.

Whenever you find yourself using a magic number, you should use a constant instead. For example, we used a magic number in our discussion about comparing floats. We should have written

if (Math.abs(floatA - floatB) < EPSILON)

where EPSILON is some constant that we defined telling us the amount of tolerance we have between floats.


That is it for our tips right now. We may add more as the semester progresses.