Factorio - Klonan
Hello, most of the team is out of the office today attending the Game Developers Session here in Prague, if you're around you can look out for some people wearing Factorio t-shirts.

As we were thinking about what to write in this Friday Facts, kovarex suggested "In the next Friday Facts we should write about how hard it is to write Friday Facts". Sometimes it is really difficult to find something interesting to write about. Thankfully we found some short things that that we thought you would like.

Passenger seat for vehicles
Just a minor multiplayer feature.


Resource generation and game balance
I wanted to have a look at how we generate resources and try to balance and improve it so it's a bit more fun. When playing the game, I noticed that I always need more iron than copper and I also felt that there is more copper than iron on the map, so I first wanted to look at that.

When we balance out any part of the game it's usually something like "that seems a bit low, let's increase it by 0.2-ish and see how it goes". While this worked surprisingly well so far, I like to take a more scientific approach and look at hard numbers when possible.

First I looked at resource requirements. In order to complete all non-infinite research you need:
  • 60,445 Science pack 1
  • 59,885 Science pack 2
  • 48,600 Science pack 3
  • 20,800 Production science pack
  • 27,925 High-tech science pack
  • 32,445 Military science pack
To make all this you need:
  • 3.5 million copper and 5.2 million iron. Ratio: 0.67 (in normal mode)
  • 10.4million copper and 10.9 million iron. Ratio: 0.95 (in expensive recipes mode)
I would say it's safe to assume that these are close to the number of resources needed to finish the game. Since you wont research everything, which will compensate for the cost of infrastructure and combat.
Here I see that there is a different ratio of copper to iron, and the ratio is different in expensive mode.

Now going to the map generation, I generated some 2048x2048 maps and calculated the total number of resources on them. For some reason there was always more copper. This seemed very strange since the map generation settings had the same values for both copper and iron. It turns out that some resources are always on top of others. Coal was on top of copper that was on top of iron that was on top of stone that was on top of uranium (alphabetical order). This meant that there will be more copper on average. To be precise, the maps had 1.5 billion copper and 1.3 billion iron. That's a ratio of 1.15 caused by overlapping. I changed the order of resources around a bit so Iron is on top.

To balance all this out, the plan is to change some some recipes in expensive mode, so that the required copper to iron ratio is roughly the same in normal and expensive mode. Then the map generator settings will be tweaked so it also reflects that ratio (of course while keeping in mind the difference caused by overlapping resources).

Now some might argue that what's the point of all this. Making things balanced does not mean more fun, for example making the player and the tank overpowered and unbalanced in combat made them way more fun. But for resources I believe it's more fun to find value in almost every resource patch you find as you explore, instead of "oh, another copper patch, how useless", especially if the player assigns the same value to it and has some expectation that they are balanced. Balancing all this is not a big deal, but it's just a subtle attention to detail that might make the game 1% more fun, and polishing all these little things will happen more and more as we approach 1.0.

While I'm looking at the resource generation, there are more things that I plan to improve. For example:
  • Tweaking the resource density (average number of resources per tile).
  • Making resources much more spread apart.
  • Reworking how the staring area works so that it always contains a predictable amount of resources. This means that every new map is feasible.
  • Making sure the starting area is not covered by trees.

More optimizations
When we talk about game performance improvements it's almost always focused on the entity-update time as that is primarily what determines how fast the game can run. There is however one other important part and that's the "prepare" step that collects minimal information about the game to be rendered on screen. This step happens between the game being updated and the results being rendered on the screen which means the game has to be paused while it's run.

We haven't looked into improving this part of the game for quite some time because it runs in multiple threads and was always been "somewhat quick". Recently I decided to spend some time trying to improve it and found several easy optimizations. The end result being the prepare step now runs roughly 50% faster than it did before, leaving more time for the game logic and entity updates.

Lua API additions
With every major update we add keep improving the Lua mod API and 0.16 is no exception; between the larger tasks and bug fixing I've been working on requested Lua API additions. For those interested I've been keeping a public gist of the 0.16 changes and additions here.

I'm always reading the forums for new requests or changes to the API, so If you can make a valid argument for some new API feature (and provided it doesn't negatively impact the game performance when not used), please let us know on the Modding interface requests forum.

Let us know what you think by commenting in our usual topic at the forums.
Factorio - Klonan
Hello, most of the team is out of the office today attending the Game Developers Session here in Prague, if you're around you can look out for some people wearing Factorio t-shirts.

As we were thinking about what to write in this Friday Facts, kovarex suggested "In the next Friday Facts we should write about how hard it is to write Friday Facts". Sometimes it is really difficult to find something interesting to write about. Thankfully we found some short things that that we thought you would like.

Passenger seat for vehicles
Just a minor multiplayer feature.


Resource generation and game balance
I wanted to have a look at how we generate resources and try to balance and improve it so it's a bit more fun. When playing the game, I noticed that I always need more iron than copper and I also felt that there is more copper than iron on the map, so I first wanted to look at that.

When we balance out any part of the game it's usually something like "that seems a bit low, let's increase it by 0.2-ish and see how it goes". While this worked surprisingly well so far, I like to take a more scientific approach and look at hard numbers when possible.

First I looked at resource requirements. In order to complete all non-infinite research you need:
  • 60,445 Science pack 1
  • 59,885 Science pack 2
  • 48,600 Science pack 3
  • 20,800 Production science pack
  • 27,925 High-tech science pack
  • 32,445 Military science pack
To make all this you need:
  • 3.5 million copper and 5.2 million iron. Ratio: 0.67 (in normal mode)
  • 10.4million copper and 10.9 million iron. Ratio: 0.95 (in expensive recipes mode)
I would say it's safe to assume that these are close to the number of resources needed to finish the game. Since you wont research everything, which will compensate for the cost of infrastructure and combat.
Here I see that there is a different ratio of copper to iron, and the ratio is different in expensive mode.

Now going to the map generation, I generated some 2048x2048 maps and calculated the total number of resources on them. For some reason there was always more copper. This seemed very strange since the map generation settings had the same values for both copper and iron. It turns out that some resources are always on top of others. Coal was on top of copper that was on top of iron that was on top of stone that was on top of uranium (alphabetical order). This meant that there will be more copper on average. To be precise, the maps had 1.5 billion copper and 1.3 billion iron. That's a ratio of 1.15 caused by overlapping. I changed the order of resources around a bit so Iron is on top.

To balance all this out, the plan is to change some some recipes in expensive mode, so that the required copper to iron ratio is roughly the same in normal and expensive mode. Then the map generator settings will be tweaked so it also reflects that ratio (of course while keeping in mind the difference caused by overlapping resources).

Now some might argue that what's the point of all this. Making things balanced does not mean more fun, for example making the player and the tank overpowered and unbalanced in combat made them way more fun. But for resources I believe it's more fun to find value in almost every resource patch you find as you explore, instead of "oh, another copper patch, how useless", especially if the player assigns the same value to it and has some expectation that they are balanced. Balancing all this is not a big deal, but it's just a subtle attention to detail that might make the game 1% more fun, and polishing all these little things will happen more and more as we approach 1.0.

While I'm looking at the resource generation, there are more things that I plan to improve. For example:
  • Tweaking the resource density (average number of resources per tile).
  • Making resources much more spread apart.
  • Reworking how the staring area works so that it always contains a predictable amount of resources. This means that every new map is feasible.
  • Making sure the starting area is not covered by trees.

More optimizations
When we talk about game performance improvements it's almost always focused on the entity-update time as that is primarily what determines how fast the game can run. There is however one other important part and that's the "prepare" step that collects minimal information about the game to be rendered on screen. This step happens between the game being updated and the results being rendered on the screen which means the game has to be paused while it's run.

We haven't looked into improving this part of the game for quite some time because it runs in multiple threads and was always been "somewhat quick". Recently I decided to spend some time trying to improve it and found several easy optimizations. The end result being the prepare step now runs roughly 50% faster than it did before, leaving more time for the game logic and entity updates.

Lua API additions
With every major update we add keep improving the Lua mod API and 0.16 is no exception; between the larger tasks and bug fixing I've been working on requested Lua API additions. For those interested I've been keeping a public gist of the 0.16 changes and additions here.

I'm always reading the forums for new requests or changes to the API, so If you can make a valid argument for some new API feature (and provided it doesn't negatively impact the game performance when not used), please let us know on the Modding interface requests forum.

Let us know what you think by commenting in our usual topic at the forums.
Factorio - Klonan
Hello,
I wanted to write about the things I'm improving in our GUI library, but I realized, that the important part is to explain what is the motivation to do so. So let me present the history of Factorio GUI.

Version 0.X
Back in the day when Factorio started, I was quite clueless. I needed some GUI library for allegro, and agui was the only one I could find, so I started using it. As in most of the story, I didn't really pay much attention to GUI, it was just the pesky part of the code which I needed to work in order for the game to function. There weren't much GUIs back then, and most of them were done by manually placing bunch of elements so it is possible to interact with it. The look and positioning was quite random.



The previous strategy stopped being possible quite soon, and we realized that we can't just manually place widgets in a window, so we started to use the layout functionality to build the GUI, so it doesn't break immediately once it contains just a little bit of different data. At that time, it was good.



Version 0.5
It is hard to believe now, but at that time, I was insisting, that the GUI is OK, and we don't need to improve it, but luckily, I was persuaded by Albert and Tomas that we need to give the GUI a better look. That was how was the look similar to the current one created. We needed to add hierarchical graphical style system to be able to control the looks and positioning of individual elements, so we did it. We also needed to add several additional functions to the layout mechanism as the need to make these two windows have the same height automatically and similar things. So we made specialised features for that by bending some of the original GUI library code. It usually worked, and when it didn't we made little hacks here and there to make it work. It also created new problems, like the random margins of elements that were supposed to be aligned with something. As all of this was made by unique specific numbers of widths/heights of elements, it could never work right, as all the style values were scaled depending on the resolution.



Here for example, the progress bar style was specified to have a somewhat correct width, and we didn't even care or understand how bad it is.



Version 0.6
It was identified at this time, that we need some mechanism to solve these kind of problems, so I created the stretchable functionality. As I was clueless about the library internals, I was afraid to break anything, the usage of it was quite awkward, it had to be used together with the functionality of mechanism from 0.5 to stretch windows to have the same width/height. You needed to set correctly some of the style values and some of the C++ object values to make it work properly. You had to set the stretchable not only the element but all of the parent elements etc. But it worked ...



Current day
Small hacks here and there accumulated.
When you use stretch layout and set align to right doesn't work? Well just set the layout to go from right to left and put things in opposite order.
Isn't the layout doing what you need? Just calculate the needed dimensions manually and force them in the style.
And much more ...

New people started joining our team and they didn't know the subtle things you needed to push to make it work and lot of new code was created with even more hacks. The GUI started to be a crazy complex beast. At that time, one of the new programmers wanted to fix some of the hacks. The result was, that he wanted to fix everything, and after 9 months of repeated inability to show anything, he was fired. After that time, GUI was considered even more scary.
Things like this started to appear all over the place in the desparate hopes of making it work:



Some people have even shown their disgust by naming their variables:



GUI refactoring
Now we are facing the need to make the GUI update (first part was presented in one of the recent fffs). At this point, you have some idea of how painful would it be to just glue the needed additions to our current GUI. It would be painful complexity squared.

This is why I decided to roll up my sleeves and just dive into it. I started rewriting and clean-up the core parts of how the layout works. At this is point, I have a branch that has 52k lines of changes compared to master, and the internal workings of the GUI have been revised a lot. A lot of the mechanisms that had to be hacked painfully work automatically and there is much less code and knowledge needed to write the GUI in the new branch. But this also means, that we have to go through every single GUI and remove the previous hacks by the new functionality, which is a lot of work.

To aid in the GUI simplification work, we created a simple GUI debug view, to let us quickly see how are the layouts stacked. I will leave it in the game, as it could be also useful for modders when they need to debug their GUI structures.




On top of that, I started to write GUI tests, as GUI layout is the great example of piece of software, where fixing one thing breaks some other without you knowing. These changes will also change the way modders specify GUI structures (mainly related to the align and stretching), but it wouldn't be us if we didn't break mod compatibility in a new release.

As always, let us know what you think on our forums.
Factorio - Klonan
Hello,
I wanted to write about the things I'm improving in our GUI library, but I realized, that the important part is to explain what is the motivation to do so. So let me present the history of Factorio GUI.

Version 0.X
Back in the day when Factorio started, I was quite clueless. I needed some GUI library for allegro, and agui was the only one I could find, so I started using it. As in most of the story, I didn't really pay much attention to GUI, it was just the pesky part of the code which I needed to work in order for the game to function. There weren't much GUIs back then, and most of them were done by manually placing bunch of elements so it is possible to interact with it. The look and positioning was quite random.



The previous strategy stopped being possible quite soon, and we realized that we can't just manually place widgets in a window, so we started to use the layout functionality to build the GUI, so it doesn't break immediately once it contains just a little bit of different data. At that time, it was good.



Version 0.5
It is hard to believe now, but at that time, I was insisting, that the GUI is OK, and we don't need to improve it, but luckily, I was persuaded by Albert and Tomas that we need to give the GUI a better look. That was how was the look similar to the current one created. We needed to add hierarchical graphical style system to be able to control the looks and positioning of individual elements, so we did it. We also needed to add several additional functions to the layout mechanism as the need to make these two windows have the same height automatically and similar things. So we made specialised features for that by bending some of the original GUI library code. It usually worked, and when it didn't we made little hacks here and there to make it work. It also created new problems, like the random margins of elements that were supposed to be aligned with something. As all of this was made by unique specific numbers of widths/heights of elements, it could never work right, as all the style values were scaled depending on the resolution.



Here for example, the progress bar style was specified to have a somewhat correct width, and we didn't even care or understand how bad it is.



Version 0.6
It was identified at this time, that we need some mechanism to solve these kind of problems, so I created the stretchable functionality. As I was clueless about the library internals, I was afraid to break anything, the usage of it was quite awkward, it had to be used together with the functionality of mechanism from 0.5 to stretch windows to have the same width/height. You needed to set correctly some of the style values and some of the C++ object values to make it work properly. You had to set the stretchable not only the element but all of the parent elements etc. But it worked ...



Current day
Small hacks here and there accumulated.
When you use stretch layout and set align to right doesn't work? Well just set the layout to go from right to left and put things in opposite order.
Isn't the layout doing what you need? Just calculate the needed dimensions manually and force them in the style.
And much more ...

New people started joining our team and they didn't know the subtle things you needed to push to make it work and lot of new code was created with even more hacks. The GUI started to be a crazy complex beast. At that time, one of the new programmers wanted to fix some of the hacks. The result was, that he wanted to fix everything, and after 9 months of repeated inability to show anything, he was fired. After that time, GUI was considered even more scary.
Things like this started to appear all over the place in the desparate hopes of making it work:



Some people have even shown their disgust by naming their variables:



GUI refactoring
Now we are facing the need to make the GUI update (first part was presented in one of the recent fffs). At this point, you have some idea of how painful would it be to just glue the needed additions to our current GUI. It would be painful complexity squared.

This is why I decided to roll up my sleeves and just dive into it. I started rewriting and clean-up the core parts of how the layout works. At this is point, I have a branch that has 52k lines of changes compared to master, and the internal workings of the GUI have been revised a lot. A lot of the mechanisms that had to be hacked painfully work automatically and there is much less code and knowledge needed to write the GUI in the new branch. But this also means, that we have to go through every single GUI and remove the previous hacks by the new functionality, which is a lot of work.

To aid in the GUI simplification work, we created a simple GUI debug view, to let us quickly see how are the layouts stacked. I will leave it in the game, as it could be also useful for modders when they need to debug their GUI structures.




On top of that, I started to write GUI tests, as GUI layout is the great example of piece of software, where fixing one thing breaks some other without you knowing. These changes will also change the way modders specify GUI structures (mainly related to the align and stretching), but it wouldn't be us if we didn't break mod compatibility in a new release.

As always, let us know what you think on our forums.
Factorio - Klonan
Hello, it is Friday once again.

Multiple starting areas
To make PvP fun, and fair, it is pretty important that all the teams have a fair start. We do this for the normal game by using some special logic to generate a specific starting area. While the map generation didn't support this, I worked around the issue by copy-pasting all the starting area chunks to new starting areas for all players. This looked very odd though, and since it was done in the Lua script, was very slow.



So the solution is to fix the map generator to create multiple starting points, which with all the refactoring work by TOGoS, was not so hard to do. Whereas before all the logic calculated its own 'distance from the start' from (0,0), now it looks for the closest starting area, and calculates the distance from that. This actually fixes and simplifies a lot of the PvP script, as I also don't have to worry about clearing away huge biters nests from each teams front door.



This is a much cleaner solution, as the new starting areas are seamlessly integrated into the map.

Multithreading issues
We were always saying, that we keep the full update multithreading as the last ace in the sleeve to be used after the normal optimisations become too difficult. Apart from the plan to split update into chunks and update them separately, there are also smaller and simpler things we can do.
We have for example this part of the update step, where we update trains, electric network and belts, and we update it one after another like this:



But these tasks are almost independent as neither trains or belts use electricity and belts don't interact with trains. There would be some details that would have to be solved, like Lua API calls and inserter activation order, but other than that it would be pretty straightforward. So I tried to run these things in parallel and measured how fast it would be:



To my surprise, the parallel version didn't speed things up, it was actually even slower. First I thought that it is caused by the fact, that the threads steal each others cache or the task is too short to be parallelized etc., but then I realized, that we already do the "prepare logic" in parallel. The prepare logic gathers all the data (sprite draw orders) for rendering and it is doing in parallel up to 8 threads. The task is iterating through the game world, and it is also quite short. Yet still the parallelization works pretty well there. After a few days (and many cppcon videos about multithreading later), I got the answer to my question. The answer is the same as many other answers related to performance, it is caused by cache invalidation.

There is some shared cache for all the threads (L3 I believe), and some smaller caches specific for each of the cores (L2 and L1 I believe). The cache is divided into some kind of pages. The problem is that as long as I don't control the memory allocation, the data of 3 objects that might be completely independent can end up in the same page of memory cache. So lets imagine this situation:



Even if two different cores work with the same part of memory, they don't slow each other down as long as they only read the memory (Which is the case of our prepare logic as it is read only operation) as each core has its own copy of the memory page. The problem arises when the operation is not read only:



Each thread has its own copy of the page, but whenever something is changed, the other copies of the same page need to be invalidated and updated. This means that the threads are invalidating each others cache all the time, which slows the whole process so much that it is slower than the non-parallel solution.

How do we solve it? The solution would probably be to organize the memory allocation in such a way, that everything that is on the same chunk, or related to some specific task would have to use its own memory allocator that keeps things in one place together in the memory. Every chunk would have its own piece of memory dedicated to entities in the chunk, trains would have all its data in one piece of memory together etc. This way, it shouldn't happen that two tasks would work on one piece of memory at the same time so the multithreading would actually speed things up.

The problem with this is, that it requires big changes in the code as not only the entities itself but all their dynamically allocated data would have to be always allocated depending on the entity position. Whenever the entity moves between chunks, all its data structures would have to be re-allocated in the new chunk. All pointers to any data structures in entity would have to be properly updated as they move around etc. This means, that once (if) we decide to do this step, it would probably be one big update related only to this and this is not something we have time to do before 1.0.

As always, let us know what you think on our forums.
Factorio - Klonan
Hello, it is Friday once again.

Multiple starting areas
To make PvP fun, and fair, it is pretty important that all the teams have a fair start. We do this for the normal game by using some special logic to generate a specific starting area. While the map generation didn't support this, I worked around the issue by copy-pasting all the starting area chunks to new starting areas for all players. This looked very odd though, and since it was done in the Lua script, was very slow.



So the solution is to fix the map generator to create multiple starting points, which with all the refactoring work by TOGoS, was not so hard to do. Whereas before all the logic calculated its own 'distance from the start' from (0,0), now it looks for the closest starting area, and calculates the distance from that. This actually fixes and simplifies a lot of the PvP script, as I also don't have to worry about clearing away huge biters nests from each teams front door.



This is a much cleaner solution, as the new starting areas are seamlessly integrated into the map.

Multithreading issues
We were always saying, that we keep the full update multithreading as the last ace in the sleeve to be used after the normal optimisations become too difficult. Apart from the plan to split update into chunks and update them separately, there are also smaller and simpler things we can do.
We have for example this part of the update step, where we update trains, electric network and belts, and we update it one after another like this:



But these tasks are almost independent as neither trains or belts use electricity and belts don't interact with trains. There would be some details that would have to be solved, like Lua API calls and inserter activation order, but other than that it would be pretty straightforward. So I tried to run these things in parallel and measured how fast it would be:



To my surprise, the parallel version didn't speed things up, it was actually even slower. First I thought that it is caused by the fact, that the threads steal each others cache or the task is too short to be parallelized etc., but then I realized, that we already do the "prepare logic" in parallel. The prepare logic gathers all the data (sprite draw orders) for rendering and it is doing in parallel up to 8 threads. The task is iterating through the game world, and it is also quite short. Yet still the parallelization works pretty well there. After a few days (and many cppcon videos about multithreading later), I got the answer to my question. The answer is the same as many other answers related to performance, it is caused by cache invalidation.

There is some shared cache for all the threads (L3 I believe), and some smaller caches specific for each of the cores (L2 and L1 I believe). The cache is divided into some kind of pages. The problem is that as long as I don't control the memory allocation, the data of 3 objects that might be completely independent can end up in the same page of memory cache. So lets imagine this situation:



Even if two different cores work with the same part of memory, they don't slow each other down as long as they only read the memory (Which is the case of our prepare logic as it is read only operation) as each core has its own copy of the memory page. The problem arises when the operation is not read only:



Each thread has its own copy of the page, but whenever something is changed, the other copies of the same page need to be invalidated and updated. This means that the threads are invalidating each others cache all the time, which slows the whole process so much that it is slower than the non-parallel solution.

How do we solve it? The solution would probably be to organize the memory allocation in such a way, that everything that is on the same chunk, or related to some specific task would have to use its own memory allocator that keeps things in one place together in the memory. Every chunk would have its own piece of memory dedicated to entities in the chunk, trains would have all its data in one piece of memory together etc. This way, it shouldn't happen that two tasks would work on one piece of memory at the same time so the multithreading would actually speed things up.

The problem with this is, that it requires big changes in the code as not only the entities itself but all their dynamically allocated data would have to be always allocated depending on the entity position. Whenever the entity moves between chunks, all its data structures would have to be re-allocated in the new chunk. All pointers to any data structures in entity would have to be properly updated as they move around etc. This means, that once (if) we decide to do this step, it would probably be one big update related only to this and this is not something we have time to do before 1.0.

As always, let us know what you think on our forums.
Factorio - Klonan
Hello, there has been an illness running around the office this week, so productivity has been down. Regardless, it is still friday, so here are the Factorio Facts.

High-resolution concrete
It seems concrete became the main ground texture of most megabases, which is something we didn’t expect when we added the stone and concrete 'paths' a few updates back. Since we are remastering all sprites into high resolution, we decided to redesign concrete to fix some issues we have with it:
  • It has a visible grid that doesn’t match the tilted projection of the game.
  • It doesn’t seem to have any height.
  • Hazard concrete transition to concrete is very sharp which makes it look too artificial.
When drawing terrain, we try to hide the fact it is composed of repeated square tiles. For this reason we use various tile sizes, where bigger tiles can have some larger features that wouldn’t fit onto a smaller one. This solution was not good enough for concrete rendering any more.

We were inspired by an article about detail textures, and decided to try to draw concrete in two layers - material and detail. The idea was that we would create a larger material texture that would be laid out in a regular grid under the whole world, and we would cut out the shape of the concrete placed over it. Then on top of the material, we would add some detail defined in our regular 1x1, 2x2 and 4x4 tile sprites.

We experimented with this and liked the freedom from having to create 32 by 32 pixel sprites that need to tile with each other. For other terrain types we use prerendered transition sprites on border between two terrains, but because of the material layer, we needed to render transitions at run-time. To finish this up, we needed to add alpha masking to our rendering capabilities. The alpha mask is a greyscale or single channel image which is multiplied with the actual texture, so that a pixel in the texture becomes more transparent the darker the corresponding pixel in the mask is. Now that we have this capability we can replace the prerendered transitions with masks, that are shared by multiple terrains, so we will save some video memory. This will be big deal when we do transition from any tile type to water.



In 0.15 we made a change that merged concrete and hazard concrete transitions to other terrains. Initially hazard concrete had its own graphic for the transitions, but the algorithm that was drawing them produced flawed results in some edge cases, so we decided to use the same transition graphic as normal concrete does.

To fix the flaws of the original drawing algorithm, we render transitions in two passes. First we resolve transitions as if all hazard concrete was regular concrete, then we render transitions just for the hazard concrete. This also allows us to create irregular edges between hazard and normal concrete. In the end we didn’t use normal tile sprites to add any additional detail, but we used normal (non-masked) transition sprites to add a border from the concrete bricks. The following GIF illustrates how individual layers are added together.



In some way it's a pity that we decided to tackle the concrete last, as we could of used this functionality for all the other terrains. The final result is a much better and easier system to work with, and will allow the artists to create the best art without worrying about the technical considerations too much.



These improvements lead to other ideas to improve our graphics rendering, and a lot of difficult issues are still left to be resolved, so let us know what you think on our forum.
Factorio - Klonan
Hello, there has been an illness running around the office this week, so productivity has been down. Regardless, it is still friday, so here are the Factorio Facts.

High-resolution concrete
It seems concrete became the main ground texture of most megabases, which is something we didn’t expect when we added the stone and concrete 'paths' a few updates back. Since we are remastering all sprites into high resolution, we decided to redesign concrete to fix some issues we have with it:
  • It has a visible grid that doesn’t match the tilted projection of the game.
  • It doesn’t seem to have any height.
  • Hazard concrete transition to concrete is very sharp which makes it look too artificial.
When drawing terrain, we try to hide the fact it is composed of repeated square tiles. For this reason we use various tile sizes, where bigger tiles can have some larger features that wouldn’t fit onto a smaller one. This solution was not good enough for concrete rendering any more.

We were inspired by an article about detail textures, and decided to try to draw concrete in two layers - material and detail. The idea was that we would create a larger material texture that would be laid out in a regular grid under the whole world, and we would cut out the shape of the concrete placed over it. Then on top of the material, we would add some detail defined in our regular 1x1, 2x2 and 4x4 tile sprites.

We experimented with this and liked the freedom from having to create 32 by 32 pixel sprites that need to tile with each other. For other terrain types we use prerendered transition sprites on border between two terrains, but because of the material layer, we needed to render transitions at run-time. To finish this up, we needed to add alpha masking to our rendering capabilities. The alpha mask is a greyscale or single channel image which is multiplied with the actual texture, so that a pixel in the texture becomes more transparent the darker the corresponding pixel in the mask is. Now that we have this capability we can replace the prerendered transitions with masks, that are shared by multiple terrains, so we will save some video memory. This will be big deal when we do transition from any tile type to water.



In 0.15 we made a change that merged concrete and hazard concrete transitions to other terrains. Initially hazard concrete had its own graphic for the transitions, but the algorithm that was drawing them produced flawed results in some edge cases, so we decided to use the same transition graphic as normal concrete does.

To fix the flaws of the original drawing algorithm, we render transitions in two passes. First we resolve transitions as if all hazard concrete was regular concrete, then we render transitions just for the hazard concrete. This also allows us to create irregular edges between hazard and normal concrete. In the end we didn’t use normal tile sprites to add any additional detail, but we used normal (non-masked) transition sprites to add a border from the concrete bricks. The following GIF illustrates how individual layers are added together.



In some way it's a pity that we decided to tackle the concrete last, as we could of used this functionality for all the other terrains. The final result is a much better and easier system to work with, and will allow the artists to create the best art without worrying about the technical considerations too much.



These improvements lead to other ideas to improve our graphics rendering, and a lot of difficult issues are still left to be resolved, so let us know what you think on our forum.
Factorio - Klonan
Hello, we are still here, working on the game.

Tutorial dependencies
As we were going through and polishing some of the mini-tutorials, we hit a bit of a problem. We wanted to introduce a new concept to the player, but we don't enforce or encourage any order to the tutorials. This means a player might start the ghost rail tutorial before he knows what ghosts are, or play the rail signal tutorial before he knows how to use the trains.

The solution is to add dependencies to the tutorials, so we recommend to the player, "You should play this tutorial before another".



Another advantage of this is that it sorts the tutorials better. Now suggested or unplayed tutorials will show at the top of the list, tutorials with missing dependencies will show in the middle, and complete tutorials will be at the bottom. From a tutorial design standpoint it makes things a lot easier. I can make safe assumptions about what skills the player has, and not have to worry about re-teaching the basics in every tutorial 'just in case'.

Logistic request pasting
Logistic chest pasting is a great quality of life feature when setting up 'shopping malls' with logistic bots. Drop a assembling machine and requester chest, set the recipe, then copy-paste from the assembler to the requester chest. The design question is how much should the logistic chest request? Quick recipes like electronic circuits need a lot of materials to avoid idle time, while items that are slow to craft, like modules, can result in a lot of materials sitting idle in the chest. This creates a lot cases where the pasted amounts needed to be adjusted manually.

One of our community contributors, Mylon, designed a new system, which is now integrated into 0.16. The system scales the count of requested items to the crafting time of the recipe, and to the speed of the specific assembling machine. It aims to keep the chest supplied with 30 seconds of crafting ingredients. So notice in this example how the amounts varying between the machines being pasted from:



Adding modules and beacons to a design and then repeating the copy paste will recalculate the requested amounts, whereas before the amounts would need to be modified by hand. We still have a prototype defined recipe paste multiplier for very expensive items, like Nuclear reactors and Satellites, but overall this new system will be much more flexible, and deal with most of the annoying cases.

Buildability checks
"Is the thing in the cursor buildable where it is behind held?". It sounds simple at first, but as the game has advanced it has quickly become anything but. Not all entities have the same buildability rules:
  • Gates can be built on rails - but not all rails.
  • Mining drills can only be built on the correct ore type.
  • Rail signals can only be built next to rails.
  • Offshore pumps can only be built at the edge of water and land.
To complicate things even more the rules change when building ghosts:
  • Other entities are ignored if they're marked for deconstruction.
  • Signals can be built anywhere instead of only next to rails.
  • Ghosts ignore ghosts of other forces.
  • Tile ghosts can't be built on tiles of the same type (it wouldn't do anything).
When shift clicking blueprints:
  • Trees and rocks are ignored - since they will be marked for deconstruction if they are in the way.
  • Anything that can't be built is just ignored in the blueprint.
There are so many special cases and so many combinations of when things can and can't be built (or can be ignored when building) that I've probably missed a few of them here. Something that has been missing for some time now has been making all of these variations render correctly in the preview you see before you build something.

A simple example is when holding a blueprint over a patch of ore with shift held down. Any trees and rocks in the way will be marked for deconstruction, and the ghosts will be placed. In 0.15 the preview would not be updated, so the drills would show as red. Now in 0.16 they rendered correctly:



It's a very small thing, but one more thing that when it 'just works', it makes the overall experience that much better, after all, perfection is just doing a lot of little things right.

As always, if you have any suggestions or ideas, please let us know on our forums.
Factorio - Klonan
Hello, we are still here, working on the game.

Tutorial dependencies
As we were going through and polishing some of the mini-tutorials, we hit a bit of a problem. We wanted to introduce a new concept to the player, but we don't enforce or encourage any order to the tutorials. This means a player might start the ghost rail tutorial before he knows what ghosts are, or play the rail signal tutorial before he knows how to use the trains.

The solution is to add dependencies to the tutorials, so we recommend to the player, "You should play this tutorial before another".



Another advantage of this is that it sorts the tutorials better. Now suggested or unplayed tutorials will show at the top of the list, tutorials with missing dependencies will show in the middle, and complete tutorials will be at the bottom. From a tutorial design standpoint it makes things a lot easier. I can make safe assumptions about what skills the player has, and not have to worry about re-teaching the basics in every tutorial 'just in case'.

Logistic request pasting
Logistic chest pasting is a great quality of life feature when setting up 'shopping malls' with logistic bots. Drop a assembling machine and requester chest, set the recipe, then copy-paste from the assembler to the requester chest. The design question is how much should the logistic chest request? Quick recipes like electronic circuits need a lot of materials to avoid idle time, while items that are slow to craft, like modules, can result in a lot of materials sitting idle in the chest. This creates a lot cases where the pasted amounts needed to be adjusted manually.

One of our community contributors, Mylon, designed a new system, which is now integrated into 0.16. The system scales the count of requested items to the crafting time of the recipe, and to the speed of the specific assembling machine. It aims to keep the chest supplied with 30 seconds of crafting ingredients. So notice in this example how the amounts varying between the machines being pasted from:



Adding modules and beacons to a design and then repeating the copy paste will recalculate the requested amounts, whereas before the amounts would need to be modified by hand. We still have a prototype defined recipe paste multiplier for very expensive items, like Nuclear reactors and Satellites, but overall this new system will be much more flexible, and deal with most of the annoying cases.

Buildability checks
"Is the thing in the cursor buildable where it is behind held?". It sounds simple at first, but as the game has advanced it has quickly become anything but. Not all entities have the same buildability rules:
  • Gates can be built on rails - but not all rails.
  • Mining drills can only be built on the correct ore type.
  • Rail signals can only be built next to rails.
  • Offshore pumps can only be built at the edge of water and land.
To complicate things even more the rules change when building ghosts:
  • Other entities are ignored if they're marked for deconstruction.
  • Signals can be built anywhere instead of only next to rails.
  • Ghosts ignore ghosts of other forces.
  • Tile ghosts can't be built on tiles of the same type (it wouldn't do anything).
When shift clicking blueprints:
  • Trees and rocks are ignored - since they will be marked for deconstruction if they are in the way.
  • Anything that can't be built is just ignored in the blueprint.
There are so many special cases and so many combinations of when things can and can't be built (or can be ignored when building) that I've probably missed a few of them here. Something that has been missing for some time now has been making all of these variations render correctly in the preview you see before you build something.

A simple example is when holding a blueprint over a patch of ore with shift held down. Any trees and rocks in the way will be marked for deconstruction, and the ghosts will be placed. In 0.15 the preview would not be updated, so the drills would show as red. Now in 0.16 they rendered correctly:



It's a very small thing, but one more thing that when it 'just works', it makes the overall experience that much better, after all, perfection is just doing a lot of little things right.

As always, if you have any suggestions or ideas, please let us know on our forums.
...