Skip navigation

Category Archives: xna

The first challenge that you will need to overcome when you begin programming a game is as the title suggests: how to think about the software you’re writing.

If you’ve done any kind of programming before it was probably some kind of LOB application, like a website or some winforms or maybe some scripts.  That kind of programming follows a specific kind of model that unfortunately is only partially applicable to game programming.  First, let’s talk about what you know.

In your typical web or winforms application, your software starts by running some kind of initialization code.  It sets up the UI, loads configuration, puts some things into memory.  If it’s a web application, your UI is scripted with HTML and rendered by the browser software.  If it’s a winforms application, your UI is still “scripted” with controls you’ve setup at design time and your operating system (or the runtime, or a combination thereof) renders them.  From that point forward, your application will generally only do things in response to interactions initiated by the user.  Your application responds to events.  You, the smart application developer, takes good care not to stall the UI with CPU-intensive things in the main UI thread – when you need to harness the CPU, you fire off another thread in the background.

The point is that application performance is practially an afterthought in most modern programming because frankly most tasks that a user wants software to automate just aren’t that hard to do for modern hardware.  As a result, most programmers – including me, I admit – have gotten lazy about it.  Thanks to my formal CS education I am aware of concepts like algorithmic complexity and I try to use linear (or logarithmic) algorithms over polynomial ones, but honestly, if I can write an n-squared in 10 minutes for an n in an hour, I’ll use the n-squared a lot of the time.

When you are writing a game, performance is the first consideration you need to make, all the time.

This is a big paradigm shift for most programmers because they’re used to getting so much for free – namely, the actual application display.  Web developers are by far the laziest in this respect because they don’t even need to worry about things like out-of-thread processing on event handlers because all of their processing is happening on the server  and is totally divorced from client display (scripts don’t count).

In the bad old days of C++ Windows applications, we programmers needed to write something called “the main loop” or sometimes called “the message pump.”  The message pump was basically an infinite loop that continually probed the operating system for kernel-level events related to the window created by the application – mostly things like “the user clicked the X widget”.  The details aren’t important but the fact that your program at its core was an infinite loop waws an important one, because nothing’s changed.  WinForms applications work this way too; .NET just hides it for you and does all the message pump handling automatically, at the CLR level.  And it’s really efficient.  The CPU overhead for all of the stuff .NET does for you, like actually draw your controls on the screen every time the screen refreshes, is tiny.

When you are doing game programming, you don’t get this for free.  Here’s what XNA gives you:

  • An Update method that executes essentially as fast as possible
  • A Draw method that executes as fast as your monitor’s vertical sync rate refreshes the screen
  • A handful of initialization methods that are executed at startup

I was a little bit surprised when I created a project from the XNA template and got a new subclass of Game and saw these methods, surprised because while they give the most possible freedom, they are also a bit overwhelming.  Without proper care, Update and Draw give you enough rope to hang yourself

Unlike typical app development where your application only really needs to do things in response to what the user tells you to do, when you’re programming a game, you have to be aware that your game is doing something all the time.  XNA is constantly calling these methods for you in the game’s main loop.

That’s important.  Web and forms UI developers don’t think about their presentation in terms of frames.  When you want to show something on the screen you create a dynamic control and add it to your layout; when you want to hide something, you remove it from your layout; your framework (browser/forms) takes care of it from there.

Game programmers have to remember that nothing appears on the screen unless you draw it every single frame.  This means that your Draw() method assumes the screen is empty because it is – you will be clearing the screen at the start of every frame.  This also means that every line of code that you write in Draw(), or in a method that is called in Draw(), will be executed (optimally) 60 or more times per second.  That’s a lot of times per second.  If your drawing code cannot finish in 1/60th of a second, your framerate starts to drop.

When you’re just starting out, your framerate, even on bad hardware, should never drop below your vsync rate, which is probably going to be 60 – so 60fps.  As your begin working with XNA, the first thing you should do is add a framerate counter to your application.  Use this one:

The reason that I recommend this is because the only way you’re going to wind up with something playable in the end is if you remain vigilant on drawing performance.  Any time you add anything to your game, whether it’s a new drawing technique or a new game logic function, if doing so causes your framerate to drop below 60, you’re doing it wrong.  I say this because it’s 2010.  You’re not doing real-time ray tracing.  You’re not doing Doom 3 ultra quality.  You’re not a Final Fantasy intro video.  You’re doing a hobby game for fun.  If you can’t render it in 60 frames per second, it means you’re making a systemic error in something you’re doing in code.  It doesn’t mean that the GPU can’t handle it.  (Unless, of course, you choose to load your screen with thousands and thousands of polgyons.  If you want to tank hardware, you can tank hardware).

Next tim XNA rookie mistakes

I’ve been working with XNA for a couple of weeks in a hobbyist capacity as a break in the monotony of business programming.  I like talking and writing about programming so I though I would start a series detailing the challenges that I’ve faced (and hopefully how I overcame them).

First, before we begin, I want to state that I am a professional software engineer with abou 10 years of software development experience behind me.  When I got my degree in CS, they were still teaching students C++.   For the last 4 years I’ve done almost nothing but C# .NET development.  I work for an ISV doing product development.  I also took a lot of math in college (linear algebra, a course called “math for computer graphics”, and the CS department’s CG course).  I’ve played with Direct3D and OpenGL before, but not to much extent.

I feel that’s important to mention because as I stated in my discussion of the obstacles the amateur game programmer faces, game programming doesn’t necessarily lend itself to amateur programmers because even professionals like me find it challenging.  That isn’t to say “if I can’t do it, nobody can!”  More like, don’t be discouraged.  If you find this hard, well, you’re not alone.

So, let’s begin!

First off  – why XNA?

I got interested again in finally churning out an amateur video game when XNA 4.0 came out mostly because the idea of a (mostly) singular code base that could produce a game that is playable on a PC or console hardware was highly intriguing.  Managed Direct3D has been around for a while so graphics programming .NET is not a revolutionary step – but a managed API is.  Managed D3D struck me as lipstick on a pig.

I work on a product that got its start in the mid-90’s as a C++ core with an MFC UI.  Around 2000, we launched an ASP.NET front-end.  To do it, we had to write a lot of .NET 1.1 code.  To expedite the process we did a lot of copy and paste and a lot of syntax find-and-replace.  Because C# is a successor to C++ we got away with it, and to be fair, .NET 1.1 was barely better than C++.  It gave us garbage collection and a non-generic STL – remember, generics were introduced to .NET in C# 2.0 – so a syntax port was about as good as we could do.

These days, there’s a stark difference between C++ and C#.  I’ve gotten so used to the features of modern C# – specifically LINQ – that writing C++ is like building a house without power tools.  Whereas with .NET 1.1 code you could pretty much cross-port C++ into C# and C# back into C++ with barely more than syntax touchups, modern .NET code is a different beast.

The reason that I share this campfire story is because that is essentially what managed DirectX/3D feels like.  I’m not going to talk about what it actually is or isn’t because I barely went further than the guided tour before I got tired of writing C++ code in C#.

It seems like Microsoft agreed with me because XNA is what managed DX should have been – a modern .NET API for graphics programming that exploits (some) of .NET’s platform evolution over the C++ dinosaur. 

Finally, 4.0 grabs me where 3.0 didn’t, mostly because after my experience with .NET 1/1 vs. .NET 2.0, and my own experience with developing APIs (which I’ve been doing for the last 2 years since I write mostly platform code), I figured that Microsoft’s first stab at XNA would need work.  As an aside, one of the challenges of product development – probably the biggest challenge – is getting customers to bite on version 1.0.  There are always brave souls and sysadmins who will install betas and initial releases, but the guys with the money usually wait for a second release so the vendor has time to fix all the bugs first.  Microsoft may be one of the world’s biggest software vendors but their code is still written by people and nobody on the planet is immune to the 1.0 rule.

So, the journey begins…

Next: First steps