Game Timing 

How fast your game runs dependeds on many factors - how 'much' it's doing, what's sort of PC it's running on and more.

If you want your game to run at a consistent speed on a wide range of PCs, you must take game timing into account.

If you're using double buffering and the 'Flip' command, your game will automatically run as fast as your screen's refresh rate, typically this is in the range 50...85 frames per second. So, a loop like this...

While game_on
     Cls
     DrawStuff()
     Flip
Wend

...will run at the same rate as your screen's refresh rate.

This is because the 'Flip' command automatically waits until the screen has been refreshed before flipping.

Of course, if your game is doing a lot of processing it may run slower than the refresh rate - but it will never run faster as long as you are using 'Flip'.

This method of game timing is known as frame-syncing, and it's a cool technique that gives very smooth results. Most games you see in the arcade are frame-synced.

Unfortunately, most PC games aren't! This is mainly because there is such a wide variety of graphics cards and screens in the PC world, that refresh rates vary wildly and frame-syncing does not provide consistent game speeds on different PC's.

Blitz addresses this problem by providing game timers. To use a timer, you must first decide how many times per second you want your game to update, a common choice here is 30.

Here's an example...

timer=CreateTimer(30) ;create a game timer
While game_on ;while game is in progress...
     frames=WaitTimer(timer) ;how many times should we update?
     For k=1 To frames ;do the updates...
          UpdateGame()
     Next
     Cls ;standard double buffered drawing...
     RenderGame()
     Flip
Wend

So, what does this do and how does it work!?

First, it's important to note that the game logic has been broken down into 2 pieces - 'UpdateGame' and 'RenderGame'. The update logic takes care of moving all your game elements, checking for user input and so on - all the 'intelligent' stuff. The render logic simply does all the drawing, and doesn't affect the state of the game - it is simply 'showing' the state of the game.

The line 'timer=CreateTimer(30)' is used to set up a game timer, this only needs to be done once. The '30' parameter specifies how many times per second we want the game to be updated.

The line 'frames=WaitTimer(timer)' checks the timer to see how many frames have gone by since the last call to 'WaitTimer', this will always return a value of at least 1.

The 'For...Next' loop calls your 'UpdateGame' for every frame that has gone by, this is the bit that actually updates the game.

Finally, once we've updated the game as many times as necessary we call 'RenderGame' to draw everything.

It's probably a good idea to try out this code on some imaginary machines.

First, let's imagine it running on a fast PC. In this case, the PC will be well capable of executing 'UpdateGame' and 'RenderGame' 30 times per second, therefore, the 'WaitTimer' will always return 1. So, our game will be updated as often as it is rendered.

Now let's imagine it running on a slow PC. In this case, the PC will not be up to executing both 'UpdateGame' and 'RenderGame' 30 times per second, therefore, 'WaitTimer' will return 2 or maybe even more. So the game will be updated multiple times before it is rendered - in effect, sort of 'catching-up' to where it should be in time!

Using this technique, we ensure that the game is updated exactly 30 times a second - regardless of how fast the user's PC is, what their screen refresh rate is and so on.

The downside to this technique is that game will not run as smoothly as it would have using frame-syncing.

This is perhaps the simplest(!) way of making sure your game runs at a consistent speed on all PC's, but it is not the only way.

Some other methods include: