Game timing in XNA Game Studio 2.0

Originally posted to Shawn Hargreaves Blog on MSDN, Friday, November 23, 2007

In a previous post I explained how the game timing system works when Game.IsFixedTimeStep is set to true:

This is still true in the 2.0 framework, but we changed our implementation of "whenever we feel like it".

In 1.0, things worked like this:

In 2.0, the Draw behavior has changed:

In other words, we no longer call Draw more than once without an Update in between. That was a pointless thing to do, as it would just render the exact same image a second time!

Here's why the new behavior is an improvement:

In practice the effects of this were very minor, because the next Update would quickly catch up to the correct time, but it caused some unnecessary jitter in the rate of calls to Update.

In 2.0, we call Update at more precisely controlled times:

Apart from noticing how things now run slightly smoother, how might your game be affected by this change?

The main impact is on games that measure their framerate, for instance using the technique I described here. To take accurate framerate measurements, you should disable vsync and select variable timestep mode. But with the 1.0 fixed timestep behavior, you could still get kind-of-almost-right framerate measurements just by counting the number of Draw calls. With the 2.0 behavior that will just return a steady 60 fps, even if your game is actually capable of running much faster.

Seems like a step backward, huh?

Not really. The thing is, trying to measure the framerate of a fixed timestep update is fundamentally bogus. We want to measure the framerate in order to know how much performance headroom is available. But consider a game where Update takes 15 milliseconds, and Draw 0.5 milliseconds. With the 1.0 behavior we would call Update once, then Draw 4 times, before our 16.7 millisecond timestep was used up. The game thus appears to be running at 240 frames per second. Awesome! That means you have lots of headroom to add new functionality, neh? Not so: your Update method is right on the verge of fitting, and everything will collapse if you make this even slightly slower.

In 2.0, you can't use fixed timestep mode to measure framerate. But you never really could in the first place! It sometimes seemed like this worked using the 1.0 behavior, but would return misleading information.

So how should you measure the framerate of a 2.0 game?

I recommend doing this exactly as before, but also adding a special configuration that will run in variable timestep mode for taking more precise measurements. Here's how you do that:

      #if PROFILE
          this.IsFixedTimeStep=false;
          graphics.SynchronizeWithVerticalRetrace = false;
      #endif

You can now quickly switch between the Debug, Release, and Profile configurations. Debug and Release will run nice and smoothly, with simple fixed timestep update logic. Your framerate counter will show if you are falling behind the desired framerate, but will not be able to detect how much headroom is available if you are running faster than the target speed. The Profile configuration will just run flat out as fast as possible, which isn't so good for actually playing the game, but provides more useful framerate data.

Blog index   -   Back to my homepage