#2 Lina Engine: Core Loop
Hi folks, so we had successfully implemented our core loop, and today I do want to walk you guys through it. In order to do that, let's first look at what a core loop is.
A core loop in a game engine is basically, in simplest turns, a while loop. That runs until the game is exited, or terminated. This loop runs through the lowest level system in the engine, and is responsible for updating other systems. Basically, in a really simple scheme, a core loop looks something like this:
However, the core loop system is more complex than this of course. But do not get too scared about it, cause it's not some very hard logic to do. Basically, if we provide some atomic tasks for the loop, the core system's job is to:
Calculate time-frame mechanics
Run inner loops based on a frame focused time interval
Update other systems in this inner loop
Update game logic in this inner loop
Render game in this inner loop
The important thing here is the time management. All games out there have a main loop, that runs based on the frames. Every single calculation is done part by part, with small intervals, each frame, to provide a smooth result. So we have to implement some sort of a frame control into our loop, otherwise it would run as fast as the hardware can bear. Well sounds cool, but it will result in different behaviour in different hardware. We don't want that. We have to make sure that our game must be frame-independent, meaning that if we are moving a player by X amount per frame, in every computer it should move by the same totalX per second. Let me explain this a little bit better. Let's assume we move player by 2 units, each frame, since our loop will be updating the game each single frame that is runs. A fast computer, with 0.06 ms cycle time, meaning that it would run 60 frames per second, will move the player by 60x2 = 120 units per single second. While a computer with 20 FPS will only move the player by 40 units, in the same single second. Thus, with different hardware, we will get different gameplay behaviour. The most common way to avoid that, is to use time independency, a.k.a deltaTime.
Delta time is the time that it took the last frame to complete itself, in order words, the time between the initialization of the current frame and the initialization of the last frame. So, a fast device with 60 frames per second, will have less time between it's frames than a slow device with 20 frames per second. So instead of moving the player by 2 units each frame, if we move it by 2 * deltaTime units, each frame that took so long to process, will make the player go move than the frames that took faster to process. Meaning that different devices with different frames per second, will have the same delta position change at the end of time t. Basically, this simple logic, is the backbone of the core game loop, and the first thing we did was to implement it. If you want to take a look at how that is implemented, here is the code snippet of our core class, that also can be found in our Github repository.
So as you can see, we basically keep track of couple of values and do a little time processing. So little it takes, we would have ourselves a frame independent running main loop. Now we can start implementing our update methods for other systems, with ease.
Hope that helped, see you on the next post!