Friday Facts #70 - The smooth FPS

Posted by Kovarex on 2015-01-23, all posts


These weeks are quite quiet. We (Me and Kuba) are fighting the never ending wall of bugs, and Albert with Pavel (The graphics department) are doing the preparations of the 0.12 endgame graphics.

Say welcome to Robert

Robert, the new programming reinforcement arrived to Prague today. He is from Romania and he is making a big life step by moving to Prague to become part of the core Factorio team. He currently lives in our apartment until he finds his own rent.

Deterministic scripting

Kuba solved the problem, that mods that used scripts in a certain way (iterating over the values of a hash table), had non deterministic order. The result of this was desync related to various mods doing this quite common thing. The fix involved changing some very deep internals of the lua (the scripting language used in factorio) implementation, so let's hope we didn't break anything.

The struggle to achieve smooth fps - technical

Achieving smooth 60 fps is not as easy goal as one might think, especially in game that has to solve a lot of demanding tasks, like long distance path finding, real time map generation and big factory simulation while being viewed with far zoom levels, so tens of thousands of objects are visible at the same time.
In the beginning the Factorio frame loop was quite simple, it looked like this:

The main problem of this setup is, that there is no room for long time tasks, the game can't skip rendering to keep up with the speed, but mainly, there is very little time to do all the tasks needed. Whenever all the tasks took just a little bit longer than the 1/60 of a second (16.666 ms) the frame was skipped and the game was laggy.

The current update loop is more complicated, and in the ideal case it looks like this, note that each line is separate thread:

When there are lot of things on the screen, especially on far zoom levels, the render can take longer than, which can result in this situation:
The frame isn't prepared in time for the vertical synchronisation point, so the frame is skipped, the update isn't skipped, so the game isn't slowed down, but the render was skipped. This is happening when you have 40FPS/60UPS (frames per second/updates per second) or similar.

The other problem is when the update takes too long, this is the most typical problem of huge factories, as the computation of the logic of the factory takes simply too much time.
In this case the game is slowed down and fps is lowered as well, in this case you get less then 60 ups.

The main problem we are currently facing is, that the time of the game logic update might be not too high in average, but it spikes from time to time and it is enough to make the game feel laggy. This is never ending task, and we are usually trying to solve it by splitting any bigger calculations into a smaller parts and then computing just a little part of it every tick. I believe that we are starting to understand the meaning of the real time computing.

The regular comment thread at our forums is ready.