Benchmarking

Description

The benchmarking commands within AGK can be used to determine information about what's happening at runtime, such as the number of sprites being drawn or the amount of time that the physics simulation is using. This information is particularly useful if you are attempting to improve the performance of a game that may be running slowly on certain platforms, for example, these commands could be used to discover that the physics simulation is taking up a great deal of time, therefore you can act on this by doing something like reducing the number of active physics entities.

The benchmarking commands

Here's a quick overview of the benchmarking commands. All of these commands return values and have no parameters:

Getting started

This example examines the usage of several commands within the benchmarking section. It will create 500 sprites and scroll them across the screen and have a particle explosion being fired off on a continual basis. Within the main loop statistics about the drawing time etc. will get displayed on screen.

The code prior to the main loop takes the following steps:

Here's the code:

SetVirtualResolution ( 320, 480 )

CreateSprite ( LoadImage ( "background1.jpg" ) )
LoadImage ( 1, "shrapnel3.png" ) LoadImage ( 2, "ball1.png" )
CreateParticles ( 1, -100, -100 )
for i = 1 to 500 CreateSprite ( i, 2 ) SetSpritePosition ( i, Random ( 320, 2000 ), Random ( 60, 480 ) ) SetSpriteColor ( i, Random ( 0, 255 ), Random ( 0, 255 ), Random ( 0, 255 ), Random ( 50, 255 ) ) speed# [ i ] = Random ( 10, 40 ) / 10.0 move# [ i ] = 0.0 next i
fire = 1

Main loop

The first block of code within the main loop displays the drawing set up time, the amount of time it took to draw the scene, the number of sprites being drawn, the number of particles being displayed and the current frame rate:

Print ( "Drawing set up time = " + str ( GetDrawingSetupTime ( ) ) )
Print ( "Drawing time        = " + str ( GetDrawingTime ( ) ) )
Print ( "Sprites drawn       = " + str ( GetManagedSpriteDrawnCount ( ) ) )
Print ( "Particles drawn     = " + str ( GetParticleDrawnQuadCount ( ) ) )
Print ( "Frame rate          = " + str ( screenFPS ( ) ) )

The next section deals with the 500 sprites. They are all moved from left to right and a wavy effect is applied to their Y position, rotation is also applied. The final part checks whether the sprite has gone off screen and then repositions it over to the right.

for i = 1 to 500
    x# = GetSpriteX ( i )
    y# = GetSpriteY ( i )

y# = y# + cos ( move# [ i ] ) move# [ i ] = move# [ i ] + speed# [ i ]
SetSpritePosition ( i, x# - speed# [ i ], y# ) SetSpriteAngle ( i, GetSpriteAngle ( i ) + speed# [ i ] )
if x# < -100 SetSpritePosition ( i, Random ( 320, 2000 ), Random ( 60, 480 ) ) endif next i

The final block of code within the main loop is responsible for the particles. It begins by creating an explosion and when this explosions ends the particles are reset and restarted.

if ( fire = 1 )
    SetParticlesPosition ( 1, Random ( 100, 200 ), Random ( 100, 300 ) )

ResetParticleCount ( 1 ) SetParticlesFrequency ( 1, 250 ) SetParticlesLife ( 1, 3.0 ) SetParticlesSize ( 1, 64 ) SetParticlesStartZone ( 1, -10, 0, 10, 0 ) SetParticlesImage ( 1, 1 ) SetParticlesDirection ( 1, 30, 30 ) SetParticlesAngle ( 1, 360 ) SetParticlesVelocityRange ( 1, 0.8, 2.5 ) SetParticlesMax ( 1, 500 )
AddParticlesColorKeyFrame ( 1, 0.0, 0, 0, 0, 0 ) AddParticlesColorKeyFrame ( 1, 0.5, 255, 255, 0, 255 ) AddParticlesColorKeyFrame ( 1, 2.8, 255, 0, 0, 0 )
AddParticlesForce ( 1, 2.0, 2.8, 25, -25 )
fire = 0 endif
if ( GetParticlesMaxReached ( 1 ) = 1 ) fire = 1 endif

Full code listing

Everything is now ready to be presented as the final program:

dim speed# [ 500 ]
dim move#  [ 500 ]

SetVirtualResolution ( 320, 480 )
CreateSprite ( LoadImage ( "background1.jpg" ) )
LoadImage ( 1, "shrapnel3.png" ) LoadImage ( 2, "ball1.png" )
CreateParticles ( 1, -100, -100 )
for i = 1 to 500 CreateSprite ( i, 2 ) SetSpritePosition ( i, Random ( 320, 2000 ), Random ( 60, 480 ) ) SetSpriteColor ( i, Random ( 0, 255 ), Random ( 0, 255 ), Random ( 0, 255 ), Random ( 50, 255 ) ) speed# [ i ] = Random ( 10, 40 ) / 10.0 move# [ i ] = 0.0 next i
fire = 1
do Print ( "Drawing set up time = " + str ( GetDrawingSetupTime ( ) ) ) Print ( "Drawing time = " + str ( GetDrawingTime ( ) ) ) Print ( "Sprites drawn = " + str ( GetManagedSpriteDrawnCount ( ) ) ) Print ( "Particles drawn = " + str ( GetParticleDrawnQuadCount ( ) ) ) Print ( "Frame rate = " + str ( screenFPS ( ) ) )
for i = 1 to 500 x# = GetSpriteX ( i ) y# = GetSpriteY ( i )
y# = y# + cos ( move# [ i ] ) move# [ i ] = move# [ i ] + speed# [ i ]
SetSpritePosition ( i, x# - speed# [ i ], y# ) SetSpriteAngle ( i, GetSpriteAngle ( i ) + speed# [ i ] )
if x# < -100 SetSpritePosition ( i, Random ( 320, 2000 ), Random ( 60, 480 ) ) endif next i
if ( fire = 1 ) SetParticlesPosition ( 1, Random ( 100, 200 ), Random ( 100, 300 ) )
ResetParticleCount ( 1 ) SetParticlesFrequency ( 1, 250 ) SetParticlesLife ( 1, 3.0 ) SetParticlesSize ( 1, 64 ) SetParticlesStartZone ( 1, -10, 0, 10, 0 ) SetParticlesImage ( 1, 1 ) SetParticlesDirection ( 1, 30, 30 ) SetParticlesAngle ( 1, 360 ) SetParticlesVelocityRange ( 1, 0.8, 2.5 ) SetParticlesMax ( 1, 500 )
AddParticlesColorKeyFrame ( 1, 0.0, 0, 0, 0, 0 ) AddParticlesColorKeyFrame ( 1, 0.5, 255, 255, 0, 255 ) AddParticlesColorKeyFrame ( 1, 2.8, 255, 0, 0, 0 )
AddParticlesForce ( 1, 2.0, 2.8, 25, -25 )
fire = 0 endif
if ( GetParticlesMaxReached ( 1 ) = 1 ) fire = 1 endif
Sync ( ) loop

Conclusion

While only a small section within AGK, the benchmarking commands are incredibly helpful in attempting to understand performance issues within games and can play an important part in developing a game.