The loop to run games is the main and most-important loop, as the game will not run without it. There are not many articles on Game Loops with the Desktop with Xojo. I will talk about four different types of game loops, and will provide the pros and cons of these game loops and will then provide the best one (in my humble opinion) to use. This article will involve a little of the math(s) topic, so let’s dig in shall we!

Four types of loops to run games are: 1) Timer, 2) Simple Game Loop, 3) Minimum Time Loop (Maximum FPS), and 4) Minimum Time and Interpolation (Best at the moment).

The loops will be measured in microseconds, which means that 1,000,000 microseconds is equal to 1 second. For the below examples, the chosen frame rate is 60 frames-per-second (FPS), which means that the loop should draw equally, and every time, at 16,666 microseconds (1,000,000 microseconds/60 FPS).

Xojo Game Loop


The above graph shows the minimum, maximum, and average frames-per-second for the various timers, and a perfect timer would have 60 frames-per-second for a max, min, and average value. Timer and Simple are quite poor for gaming since the minimum and maximum value ranges are quite large. The maximum FPS has a much tighter group tolerance and does have some low FPS. Interpolation with Maximum FPS is the closest to Perfect and is slightly lower than the Perfect value of 60 FPS.

A simple bouncing ball example has been created to show that the graphics work and you can/might be able to see the ball movement stuttering or not move smoothly across the screen due to variations in time. By using the System.DebugLog command, each program has been run on the same computer to show the time difference between algorithms.


Because the main focus of this article is the game loop, no real time is spent on the graphics portion other than a bouncing ball moving on the screen. Testing was performed in an ASUS computer with 24 GB ram, 2.40 GHz, 64-bit, Windows 10, and all data was from running in the Xojo 2019 r1.1 IDE.


Note: When using a time loop, ensure that the While-Wend loop ends before closing the program.


Simple Game Loop Timer
The simplest game loop is with a timer in Xojo. Although it is good to see if the game physics work, such as proper collisions, colours, and other aspects, it is a really poor method to use with a game because of the wide variation in time that the loop fires. When running this example, the optimal time to fire *should be* near 16,666 microseconds per loop. The timer performs background updates and has a variation in firing times from 4,015 to 18,141 on the test computer, which means that the time varies from 249 FPS (1,000,000/4,015 = 249) to 55 FPS (1,000,000/18,141 = 55.1). The closer the FPS is to 60 FPS, then the smoother graphics appears on the screen. The variance is between 55 and 249 FPS. That is a large difference that can be seen by the human eye and isn’t acceptable for gameplay.

The simple game loop can be downloaded here: TimerFPS.xojo_binary_project

The main timer loop is in the Timer1 Action event (16 millisecond firing time) and is shown below:

 Sub Action() Handles Action
FRAMES_PER_SECOND = 60
MicrosecondsPerFrame = 1000000/FRAMES_PER_SECOND
ElapsedTime = Microseconds-FRAMES_PER_SECONDStartTime

System.DebugLog "ElapsedTime: " + ElapsedTime.ToText + ", MicrosecondsPerFrame: " + MicrosecondsPerFrame.ToText
UpdateGame(Canvas1)

UpdateFPS(Canvas1, FPSStartTime)

DisplayGame(Canvas1)

FRAMES_PER_SECONDStartTime = Microseconds
ElapsedTime = Microseconds-FRAMES_PER_SECONDStartTime
End Sub


Microseconds per frame are calculated and are 16,666 microseconds for a 60 Frame-Per-Second refresh rate. Actual elapsed time is calculated from the current Microseconds to the FRAMES_PER_SECONDStartTime. The elapsed time is shown in the IDE messages screen. Most game routines are to update the mathematics of the game (UpdateGame), show the FPS if needed (UpdateFPS), and draw the graphics to the screen (DisplayGame).

Timer Pros
A timer works well to allow the user to press buttons and interact with the Window while graphics are being drawn. The timer is easy to setup to check collisions and performing preliminary testing of the program.

Timer Cons
A very large variation in time from 55 FPS to 249 FPS makes it difficult to consider a timer for any smooth game runtime on the computer. Lots of stuttering of graphics and the average time to fire is at 83 FPS (12,005 microseconds).

Simple Game Loop
The game loop is literally a loop that is inside a While-Wend loop. Similar to the above method, the loop gets input from the user, such as pressing mouse and keyboard buttons, and the data is handled through the game loop. There really are only two parts to the game loop: UpdateGame contains the updated mathematical calculations, and DisplayGame which performs drawing of the graphics. The rest of the variables are added to measure the speed at which the game loop occurs.

 

 Sub Action() Handles Action
//Simple game loop
FRAMES_PER_SECOND = 60
MicrosecondsPerFrame = 1000000/FRAMES_PER_SECOND
ElapsedTime = Microseconds-FRAMES_PER_SECONDStartTime

GameIsRunning = True
FPSCounter = 0
FpsStartTime = Microseconds

While GameIsRunning

app.DoEvents

UpdateGame(Canvas1)

UpdateFPS(Canvas1, FPSStartTime)

DisplayGame(Canvas1)

ElapsedTime = Microseconds-FRAMES_PER_SECONDStartTime
'System.DebugLog "ElapsedTime: " + ElapsedTime.ToText + ", MicrosecondsPerFrame: " + MicrosecondsPerFrame.ToText
FRAMES_PER_SECONDStartTime = Microseconds
Wend
End Sub

 

The While-Wend loop continues to update data until the Boolean GameIsRunning value becomes false by the user pressing the Stop button. Execution times per loop were a low FPS of 46 FPS (21,695 microseconds), to a high of 417 FPS (2,396 microseconds). There is no time measurement in this loop, and the game just runs, which means it will run slower on an older computer and faster on a newer computer.

This downloadable program is GameLoopSimple.xojo_binary_project

Simple Game Loop Pros

Easy to setup, and runs fast on most new computers.

Simple Game Loop Cons

Runs way to fast on a new computer, and will run slow on an old computer. Moving the mouse over the screen greatly changes the FPS. The bouncing ball stutters greatly. FPS range is from 46 FPS to 417 FPS, and an average of 240 FPS. This loop is not considered playable in the real world due to the high FPS variation.


Minimum Time Loop (Maximum FPS)
A minimum time loop causes the drawing to occur when a minimum amount of time has elapsed. In this case the Frames-Per-Second is set to 60, which means that redrawing should occur after 16,666 microseconds. Since time is being controlled, a fast computer will slow down redrawing times, but a slow computer may take even longer to draw. This is an improvement over the previous two methods since time is being controlled.

 Sub Action() Handles Action
//FPS Dependent on minimum Frames Per Second
GameIsRunning = True
FPSCounter = 0
FpsStartTime = Microseconds

Dim FRAMES_PER_SECOND as Integer = 60
Dim FRAMES_PER_SECONDStartTime as UInt64 = Microseconds
Dim DoEventCounter as Integer = 0

While GameIsRunning
Dim MicrosecondsPerFrame as Integer = 1000000/FRAMES_PER_SECOND
Dim ElapsedTime as Integer = Microseconds-FRAMES_PER_SECONDStartTime

If ((ElapsedTime) > (MicrosecondsPerFrame)) Then
App.DoEvents

UpdateGame(Canvas1)

UpdateFPS(Canvas1, FPSStartTime)

DisplayGame(Canvas1)

ElapsedTime = Microseconds-FRAMES_PER_SECONDStartTime
'System.DebugLog "ElapsedTime: " + ElapsedTime.ToText + ", MicrosecondsPerFrame: " + MicrosecondsPerFrame.ToText
FRAMES_PER_SECONDStartTime = Microseconds
End If
Wend
End Sub

 

The same While-Wend loop from the previous example is shown and the added code is an If-End conditional statement where the ElapsedTime is compared to the MicrosecondsPerFrame, which is 16,666 microseconds (1,000,000/16). The lowest FPS is 27.5 (36,315 microseconds), and the highest FPS is 50.1 (19,956 microseconds) with an average FPS of 48.7 (20,517 microseconds). Although not perfect, this game loop is the most playable so far in the comparison of previous loops.

Feel free to download the example program FPSDependentOnMaximumFPS

Pros
On faster and moderate hardware the FPS are well controlled and the gameplay is almost the same on both machines. Graphics stuttering is greatly decreased

Cons
The FPS is lower than the target 60 FPS. This game will run slow on older hardware.

Minimum Time and Interpolation
This is the best of both worlds in my humble opinion, where both the time is monitored and changes in time modify the position of the ball being drawn, so that the ball appears smoothly drawn on the screen while the Frames-Per-Second are controlled on a faster machine. The loop is more complicated than the other three methods.

 Sub Action() Handles Action
//FPS Dependent on minimum Frames Per Second
GameIsRunning = True
FPSCounter = 0
FpsStartTime = Microseconds

Dim FRAMES_PER_SECOND as Integer = 60
Dim FRAMES_PER_SECONDStartTime as UInt64 = Microseconds
Dim DoEventCounter as Integer = 0
Dim InterpolationFactor as Double

While GameIsRunning
Dim MicrosecondsPerFrame as Integer = 1000000/FRAMES_PER_SECOND
Dim ElapsedTime as Integer = Microseconds-FRAMES_PER_SECONDStartTime

If ((ElapsedTime) > (MicrosecondsPerFrame)) Then
App.DoEvents
UpdateGame(Canvas1,InterpolationFactor)

UpdateFPS(Canvas1, FPSStartTime)

DisplayGame(Canvas1)

ElapsedTime = Microseconds-FRAMES_PER_SECONDStartTime
InterpolationFactor = 1000000/FRAMES_PER_SECOND/ElapsedTime
'System.DebugLog "ElapsedTime: " + ElapsedTime.ToText + ", MicrosecondsPerFrame: " + MicrosecondsPerFrame.ToText + ", InterFact: " + InterpolationFactor.ToText
FRAMES_PER_SECONDStartTime = Microseconds
End If
Wend
End Sub

 

If the game requires more time to draw graphics or more time for calculations, then the time is provided and graphics are updated with the interpolation factor which averages movement of the ball over time, which is barely (not?) detectable by the user and appears to be running smooth. The InterpolationFactor is the time-equivalent of the target Frames Per Second divided by the actual elapsed time. With Xojo’s move to a Double data type instead of an integer, movement of the ball or other objects is cleaner and removes most stuttering.

The example program can be downloaded here: GameLoopInterpolation.xojo_binary_project

The UpdateGame method has an additional property to change the speed based on the Interpolation factor, or the difference in speed from drawing one frame to another frame.

When the FPS is set to 60, the minimum rate is 47.3 FPS with a maximum of 50.2 FPS, and an average of 49.3 FPS. The variation is considerably smaller and graphics appear smooth to the user.

Pros
On faster and moderate hardware the FPS are well controlled and the gameplay is almost the same on both machines. Interpolation provides a smoother graphic appearance without (or low?) stuttering.

Cons
The FPS is lower than the target 60 FPS. This game will run slow on older hardware, and is more complicated to implement.

There are many different types of game loops and all have pros and cons, with minimum time loop and interpolation to be the best of the previous ones tested.

 This example was created on Windows 10 with Xojo 2019 r1.1 on 4 August 2019