Game Loop
A game loop is a continuous loop that runs an Update() method and a Draw() method. Below is the simplest example of a game loop:
void GameLoop()
{
while (true)
{
Update();
Draw();
}
}
In practice game loops may have a lot more code. They may wait a certain amount of time between passes, do less processing on certain passes than others, contain exit logic, etc.
Simple Game Loop
In the simplest example of a game loop, the game updates and draws at the same rate.
void GameLoop()
{
while (true)
{
Update();
Draw();
}
}
This was a common way to design video games when they were first made, and came with the following pros and cons:
- Pros
- Even when the game slows down, physics and game logic are still processed in a consistent manner.
- Cons
- If either the
Update()or theDraw()took too much time, the game would slow down. - Game may not run at full speed on weaker hardware.
- Different versions of the game must be made in order to run at different framerates.
- If either the
Timesteps
There are two main types of timesteps:
- Fixed Step - the game loop processes equal intervals of game time
- Variable Step - the game loop processes varying intervals of game time based on how much real time has passed
While simple game loops originally all used fixed timesteps, some began to use variable timesteps as a way to address known issues:
// time of last iteration through game loop
DateTime lastTime;
void GameLoop()
{
lastTime = GetRealTime();
while (true)
{
// calculate elapsed real time
var time = GetRealTime();
var dt = time - lastTime;
Update(dt);
Draw(dt);
lastTime = time;
}
}
This solved a few important issues but introduced new issues as well:
- Pros
- Game runs at full speed on weaker hardware.
- If either the
Update()or theDraw()took too much time, the game would keep running at full speed. - One version of the game can run at different framerates.
- Cons
- When the game slows down
- Physics and game logic are not processed in a consistent manner.
- Player inputs may be dropped.
- When the game slows down
Independent Update and Draw
It is clear that game logic should be fixed step for a consistent experience, but ideally game rendering should be able to run independently at the display's refresh rate. To achieve this the Update() must be able to run independently of Draw(), a separation many programmers are familiar with (back end / front end, model / view, etc.).