CIS 300: 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 programming TAs.

[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 extremely handy reference 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.
Beyond this, you should always feel free to pester the programming TAs with questions about C#. Finally, if you are still completely lost, there is a brief 4 week mini-course on C# begin offered this semester.

Learning XNA

Once you have mastered C#, XNA is pretty easy. XNA is just an additional set of API 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 C#. It details all of the XNA classes with their methods.
XNA Tutorials
A collection of good tutorials showing you how to do elementary stuff in XNA; most of the answers to this lab can be found in these files somewhere. Note, however, that these tutorials are for XNA 1.0, while we are currently using XNA 2.0. There are some subtle differences; for example, the project for The Road Not Taken will not compile without some minor modifications.
XNA Creators Club
This is Microsoft's website for all things XNA.

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 2005 (which is what we use in the CSUG lab), or Visual C# Express. We recommend that you use Visual Studio 2005, as projects created in these two versions of Visual Studio are not compatible with one another, and standardizing on Visual Studio 2005 will save you a lot of grief.

While Visual C# Express is freely available, Cornell has a program by which you can get a copy of Visual Studio 2005 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 2005 installed, you should go to the XNA Creators Club for the instructions on how to install XNA on your machine.


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. The advantage of this is that you can leverage these libraries to solve your technical, game engine problems, and hence 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.

2D Primitives Library

File: PrimitiveBatch.zip

Yi Xu, one of our programming TAs, has been kind enough to create us library for drawing 2D geometric shapes without the worry of 3D details like camera position and projection matrices. Currently, this library allows you to draw the following shapes:

  • Points
  • Lines
  • Triangles (supports Gouraud shading)
  • Rectangles (supports rotation, Gouraud shading, and non-solid drawing)
  • Circles (supports non-solid drawing)
  • Ellipses (supports rotation and non-solid drawing)

The library comes with a demo showing how to use the shading abilities to produce effects like a "fade-out". In the demo you will see a yellow triangle in the top left corner, opening up to the bottom right corner, that fades out gradually.

This library is still under development. Try it out, and see if there is anything else that you would like. Contact Yi with your requests for future features.

Text Support for XNA

One of the most frustrating things about XNA is the total lack of text support. This is because XNA is designed to develop both for the PC and the XBox 360, and integrating TrueType support into the XBox is a little much. So, no text support for you. Fortunately, however, this was a glaring enough hole that several third parties have stepped up to provide for this need. Here is a collection of them.

Nuclex Fonts
A program that takes TrueType fonts and coverts them to bitmaps for rendering to the screen. It has an extremely simply API for rendering text.
XNA Font Creator
Similar to Nuclex Fonts, except that you do not use the font directly. Instead, you make in intermediate file format which is used by the XNAFont class.
Stroke Based Fonts
The bad news is that this text rendering library does not allow you to choose your font; all characters are rendered in the same way. The good news is that it is resolution independent because it uses vector strokes.

Physics Engines XNA

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). Here are a few we have found.

Farseer Physics
This has already proved to be a popular 2D physics engine, and is the choice of some of the more advanced programmers in the class.
XNA Physics API
This is a more advanced 3D physics engine created by a Russian development team. However, because this is a website in Russia, the English documentation is a tad sparse.

Programming for the Wiimote in XNA

The Nintendo Wii is one of the more interesting game consoles to come out in a long time. A lot of the excitement has centered around the "Wiimote", a motion sensitive controller that uses acceleration and infrared sensors to determine its spatial position. This allows for highly innovative games, though designers are still struggling with how make games that effectively leverage the controller.

While XNA does not allow you to design games for the Wii, there are XNA libraries that allow you to use the Wiimote with a PC (even if you do not have an actual Wii). There are several resources available online to get you started with this.

Codeplex
This is the necessary library for working with the Wiimote in C#. You will need to download and install this.
Managed Library for Nintendo's Wiimote
This is a tutorial on getting you started with the Wiimote in C#.

Designing a game for a Wii is definitely one way to satisfy the "innovative" requirement for this class. However, in order for it to count as innovative, you have to use the unique features of the Wiimote. If you are using the Wiimote in a way that could be easily be emulated by a D-pad style controller, this is not particularly interesting.


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.

A note about doubles and floats

No matter what you might hear, doubles are slower than floats even on current (circa 2005) 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.