Factorio - Klonan
Read this article on our Website.

For a few frames more
Previously on Factorio Friday Facts (#264): "No wonder, scenes heavy on smoke or trees can tank FPS, especially in 4K. Maybe we should do something about that..."

Sometimes, it's just a bug
Writing technical Friday Facts helps me to summarize what I know, look at problems from a different perspective, and sometimes try to answer questions I haven't even thought of asking before.

For example, I made the overdraw visualization just for screenshot for FFF-264, and while writing the FFF I didn't analyzed them. Just after the blog post was released I looked at it and started thinking - why does smoke create such a huge overdraw blob when it is just barely noticeable in game view? Well, it turned out it was largely due to a bug. Some time ago we optimized smoke particles so that they are only updated once every 120 ticks (2 seconds), and its animation (movement, scale and opacity) is interpolated during drawing.

Thing is, particles are destroyed only during their update, if the lifetime of a particle ended somewhere in middle of the 120 tick window, the particle would be still drawn until destroyed. Because smoke fades away and scales up during its lifetime, it would be drawing itself fully transparent over a large area. Making the smoke particle not draw itself past its lifetime reduced number of particles being drawn by 15%, and reduced the number of pixels being rasterized even more. Additionally, particles below 2% opacity don't really seem to add anything to the final picture, so we can safely not draw those to get little extra boost.

Turret range visualization optimization
Probably only a very small number of our players actually run into this issue during normal play, but it is simple problem that we used to learn more about how to use GPUs more efficiently.

Turret ranges in the map view are rendered as opaque geometry (no sprites) to an offscreen buffer which is subsequently drawn semi-transparently to the game view. This makes the turret ranges blend into single solid shape of the same color. Every pixel is written for each turret in range, but if it is written once, subsequent writes are unnecessary.

We had two ideas how to optimize this. First, enable stencil test, so that pixels can be written just once. The second, pass a list of turrets to the GPU and test if each pixel is in range of any turret using a pixel shader. The stencil test idea yielded about 3x speed-up in our extreme test cases (20x20 turrets) which was not good enough - if your GPU had a problem with 3x3 grid, it would have problem again with 9x3 grid, which is not such a preposterous setup to have. The pixel shader idea turned out to be mixed bag - if the entire screen was in range, the shader would be lightning fast, but as soon as there were pixels outside of range, which meant shader had to iterate through entire list of turrets to figure out none covers it, performance started to drop off rapidly. In the worst case, it would be worse than without optimization.

Jiri came up with idea to do prepass, in which we would render the geometry into a much smaller buffer (let's say 16x smaller in both width and height) and then in turret range shader we would check if a pixel is definitely in range (pixel in prepass buffer is fully opaque), definitely out of range (pixel in prepass buffer is fully transparent) or we don't know (pixel in prepass buffer is semi-transparent due to linear filtering) and we need to the pixel against the turret list. He did that and performance improved slightly, but not as much as we hoped for. After further investigation we found out the GPU really doesn't like the early exit in the pixel shader. Jiri managed to remove it by rendering all the certain cases first, while marking uncertain pixels in stencil buffer, and in another pass he would run the turret range shader on just stenciled pixels. This solution ended up being up to 20x faster in cases that were too slow with the un-optimized solution, but as you would zoom out more and there were more turrets covering less pixels on screen, the orginal solution would become better. So we turn on the optimization only when you are zoomed in enough.

By the way, artillery ranges suffered from the same problem in early 0.16 versions, but they are so large it was good enough for us to test if entire screen is in range, and draw just single fullscreen rectangle in that case. Turrets were very likely to cause problems on low-end GPU even when not covering the entire screen.

GPU performance
As always, the root of all performance degradation is memory access. Since we mostly do just simple sprite drawing, the GPU has to read pixels from a texture, and blend it into a framebuffer. Which technically means reading pixels from another texture, doing some simple maths with the two values, and writing the result back. GPUs are designed to do this on a massively parallel scale and are optimized for high memory bandwidth while sacrificing memory latency. The assumption is you'll want to do at least a little bit of maths on the colors that you fetch from textures, to give the resulting image some dynamic detail. Every GPU core can then have many scheduled tasks and switch between them as the current task starts waiting on some memory operation to finish.

When you don't really do any math to add dynamic details, and all detail comes from drawing more layers of sprites, the GPU cores quickly reach their limit of maximum tasks and every one of them is stalled by a memory access. That is not to say we don't hit memory bandwidth limits on some hardware. For cases where we do hit memory bandwidth limits, we added an option to do rendering in 16-bit color depth (as opposed to the normal 32-bit). This option is intended for old GPUs and integrated GPUs.

An obvious way to improve this is to shade less pixels. This is something I mentioned before in FFF-227 by splitting tree shadows from tree trunks to remove large areas of completely transparent pixels. This can be improved further by drawing sprites not as rectangles but as generic polygons that envelope sprites such that most of the fully transparent areas won't be rasterized. This is something we will probably do for the most problematic sprites (trees and decoratives).

Another way to reduce the number of shaded pixels is to simply to render in lower resolution. We actually do this for lights for a long time already, but it could be used for other effects that don't have important high frequency detail - for example smoke. Ultimately, some GPUs are not cut for rendering the game in FullHD resolution no matter what (for example Intel HD Graphics 2500 or multimedia cards like GeForce GT 710 and Radeon HD 6450 come to mind), so they would benefit from an option to render the game view in lower resolution with native-resolution GUI overlay.

In FFF-227, I also mentioned mipmaps - downscaled copies of textures that are used when a texture is being scaled down. This helps to better utilize the caches on GPU, and therefore reduce the need to access main VRAM. We already used mipmaps for trees and decoratives in 0.16, but paradoxically some people had performance issues when they had mipmaps enabled. The problem is, in 0.16 we always use trilinear filtering for mipmapped textures. That means when you want to draw as sprite at 75% scale, the GPU will get a pixel from the 100% scale mipmap, and the 50% scale mipmap and average them to get the pixel for the 75% scale version. The access to two different mipmap levels would make things slower. In the new rendering code, we are able to control this, so for sprites that are likely to cause performance issues (for example smoke) we can just fetch pixels from the closest finer detailed mipmap.

Texture compression
GPUs natively support block compressed formats - the texture is divided into 4x4 pixels (or possibly different sizes in formats that are not commonly supported by desktop GPUs) and each block is compressed into a fixed number of bytes. Commonly supported formats on desktop GPUs are BC1-7. Most interesting to us, are:
  • BC1 (used to be DXT1) - Intended for RGB without alpha (or 1 bit alpha) with uses 4 bits per pixel (as opposed to the 32 bits raw RGBA uses).
  • BC3 (used to be DXT5) - Uses 8 bits per pixel - same format for color as BC1, but uses 4 extra bits for the alpha channel.
  • BC4 - Stores just a single color channel in the same format as the alpha channel in BC3 is stored (so 4 bits per pixel).

These formats work pretty well with normal textures, but not so well with 2D art that contains a lot of small detail. With our art it is not so bad as long as sprites are static, but as soon as we apply the compression on animations, even tiny changes in individual pixels results in larger changes in blocks that contain them, and the resulting animation ends up looking very noisy.

https://cdn.factorio.com/assets/img/blog/fff-281-player.webm
https://cdn.factorio.com/assets/img/blog/fff-281-player-compressed.webm
Uncompressed vs. BC3 compression

Awesomenouts developers described this in their blogpost on how compressed formats supported by GPUs work, what kind of artifacts it creates in their art, and what they do to improve quality. They store their sprites in a slightly higher resolution (for example 41% larger width and height) to spread the large frequency detail more apart. This makes compression less efficient but still worth it. The problem is, we can't really do this as it makes our sprites look pretty bad and blurry.

During our initial experiments with compression, we deemed the quality of compression to be too low. In addition to that it somewhat slowed down the game startup as we built sprite atlases in an uncompressed format first and compressed them at the end of the sprite loading process. I left the 'Texture compression' option in, for people who really needed to use it, and it would compress only the sprites that usually blend over some other graphics (like color masks, shadows and smoke).

The most commonly used image or video compression formats (like JPEG or H.264) exploit the fact that human vision is actually pretty bad at recognizing colors and is much more sensitive to changes in brightness. Instead of RGB color space they use of color space based on luma (brightness) and chrominance (color), and apply better quality compression to the luma component and lower quality to color components, resulting in a very high quality image to the human eye. Some smart people thought this technique could be used to improve the quality of GPU block compression formats.

One of the ideas is YCoCg-DXT compression which uses BC3 as an underlying format and stores luma in alpha channel for higher quality compression and chrominance in RGB channels. Pixel shaders that use these textures need to do just a little bit of math to convert colors from YCoCg color space to RGB. We tried to integrate this (using separate BC4 compressed texture for alpha channel) and were pleasantly surprised by the result. You probably won't notice artifacts unless you zoom-in a lot and look for them. In fact, two weeks ago I enabled texture compression by default (and didn't tell anyone), and whenever I ask somebody on the team if they disabled it, they say they didn't know it was turned on. So I am pretty happy about that. The small downside is the need to use two textures (BC3 + BC4) resulting in 12 bits per pixel, but the best thing is, despite the pixel shader having to fetch from 2 textures instead of just one, the GPU is able to render up to twice as fast due to caches being able to fit more pixels in compressed formats than in raw formats.

Luckily the paper contains the pixel shader code for compressing to this format on GPU, so we just had to adapt our sprite loading code to efficiently utilize GPU for compressing sprites as they are being loaded, so that the fact that we are compressing sprites during startup doesn't make the game load slower.

In 0.17, the texture compression graphics setting is changed to a drop down list containing 'None', 'High quality' and 'Low quality':
  • High quality will use the custom YCoCg-DXT compression and will be the default on most computers.
  • Low quality will use BC3 and is intended for use only on really weak GPUs.
There shouldn't be any reason for you to disable compression, the option to do so is there mainly just in case some technical issue appears. Compression is applied to all sprites except the GUI, which needs to be as crisp as possible. Also, regardless of the texture compression option, shadow sprites will be always compressed using the BC4 format.

https://cdn.factorio.com/assets/img/blog/fff-281-017-uncompressed.webm
https://cdn.factorio.com/assets/img/blog/fff-281-017-high-compression.webm
https://cdn.factorio.com/assets/img/blog/fff-281-017-low-compression.webm
Uncompressed vs. High quality compression vs. Low quality compression

After we added the high-res worms, biters, and spitters, VRAM usage rose up to 3.5GB (with high-res enabled, obviously) when no compression (even the shadow one) was applied. Compressing just shadows decreased VRAM usage to 0.16 levels of ~2.5GB. With high quality compression enabled, VRAM usage of sprite atlases currently is ~1GB (without mipmaps). This means, vanilla should be perfectly playable in high-res on GPUs with 2GB VRAM, and in combination with texture streaming these GPUs should be able to keep up in high-res even in cases when mods add a lot of new sprites. High-resolution sprites were originally intended for players with the most powerful computers, but in 0.17, they'll essentially become new standard. The goal is to eventually remove the 'low' and 'very-low' sprite resolution options, as 'low quality' texture compression on normal sprites + texture streaming should be able to run even on GPUs with very low VRAM sizes.

Side note: I mentioned there are 7 BC formats. BC7 is intended for RGB or RGBA textures, and has potentially much better quality than BC3 with the same compression ratio. The problem is, the format was introduced with DirectX 11, so it is not supported by DirectX 10 class hardware, and it is not available in OpenGL on macOS. The second problem is that it takes a very very long to compress something into this format, because the compressor has to try out a large number of configurations for each block to find the one that yields the best quality. Since Factorio is kind of outlier in that its art is distributed in bunch of PNG files instead of having everything neatly packaged so that graphical assets can be loaded directly to the GPU, without any transcoding to a different format or dynamically building sprite atlases, we require a real-time compression solution. We are not eager to change how the game is distributed too much, for one having everything in separate files makes updates reasonably small when we change some of them, and having vanilla data completely open makes it easier for people to mod the game.

Now look at these graphs
We took some benchmarks of extreme scenes. The first one is on save from public Clusterio event last year. Twinsen sent me the save, because he was getting framerate drops in the middle of large steam turbine array. The second one is save from a bug report. I choose the save because it has rails going though forest and because I could really get low FPS on it even in 0.16, I used map editor to carpet the ground with grass decoratives.

We tested on GPUs with 2GB or 1GB of VRAM, that we have in the office. Benchmarks on desktop GPUs ran on single PC (we just swapped GPUs between runs) - Intel Core i7-4790K, 16GB RAM, Windows 10. We measured the time a frame was being processed by GPU, for 1000 frames, and averaged out the results. We benchmarked against the 0.17 build from before GPU-side optimizations were implemented, unfortunately we don't have a way to capture GPU timings in 0.16. Tests ran in FullHD resolution (1920x1080) with high resolution sprites enabled, with a graphic configuration that I believe to be the best for rendering performance. For old build: Mipmaps, Atlas specialization, Separate lower object atlas, Texture compression options enabled, Video Memory Usage set to All. And equivalent configuration for the new build, except for using the new high quality compression option.

We also included a result from one high-performance GPU (GeForce GTX 980 4GB), but this was ran in 4K resolution (3840x2160) as opposed to FullHD.The benchmark of Intel HD Graphics 5500 was ran on a laptop with Intel Core i7-5600U and 16GB RAM, and used Low quality texture compression instead. We also included results with 16-bit color depth enabled.







Times were measured in milliseconds. Lower times are better, and for 60 FPS, a frame needs to take under 16.66ms.

If you are interested in how GPUs work more in-depth, Fabian Giesen wrote a nice series of articles on the topic.

As always, let us know what you think on our forum.
Factorio - Klonan
Hello,
as we learned countless time before: Visual feedback is the king!
Especially when the GUI is as complex as the Train GUI.

Train GUI part 2
The biggest missing feedback I could identify in the Train UI is not seeing the path the train is going to take, so it was the first thing we did:

https://cdn.factorio.com/assets/img/blog/fff-280-path-visualisation.webm

Adding a station by selecting it from the list of the stations is nice and all, but being able to interact with the minimap directly is an opportunity that would be a shame to miss, so we added the possibility to shift-click a station to add it to the schedule. Since visual feedback is the king, holding shift shows the path to the selected station, so you have an idea how is the train going to get there. The train can take a different path in the end, as there are multiple possible paths to the same destination, but in general this works well.

https://cdn.factorio.com/assets/img/blog/fff-280-station-path-visualisation.webm

The same goes for temporary stations, holding Control (the default modifier to add temporary stations) shows the path to that point. This can be also used to figure out problems in the rail network, as moving the mouse can help you to find out what section is blocked out because of bad signaling, missing rails etc.

https://cdn.factorio.com/assets/img/blog/fff-280-temporary-station-visualisation.webm

But once we allow any interaction with the map, the map needs be useful, so we allow to move and zoom the map the same way as the normal game map. The view is centered on the current locomotive by default, but once you start dragging, the link is cancelled, and you can move wherever you like. Pressing the button will center it again.

https://cdn.factorio.com/assets/img/blog/fff-280-drag-map.webm

As you might know, if the train has stations that are not available, the train skips them. But the reasons for it might be different, and it might not be that clear what is going on, so we decided to indicate the station state in the GUI, and give the player tooltip based info on why is the station is disabled.





When you have multiple stations with the same name, we show how many there are next to the name in the station selection window. It can happen, that a station is not available from the current train location. Reasons can vary. The stop could be in different train system, there might be a bad signal, rail problem somewhere etc. So we show the inaccessible train stops with a red color, and put them at the bottom of the list. We even have special feedback for stations being partially accessible, IE when not all of the stations with the given name are accessible.



It is a small thing, but an example of what we learned in the settings GUI. Hovering the button to remove a condition works normally, but hovering the button to remove the whole station also highlights the buttons to remove the related conditions, as they are removed along with them.

https://cdn.factorio.com/assets/img/blog/fff-280-remove-visualisation.webm

One of the most common ideas from last weeks discussion thread was some visualisation of the AND/OR condition precedence, which was quite easy to do. When you don't have a complex condition, such as a simple 'Time elapsed AND Inactivity', the visualisation won't show. Only when you have a combination of 'AND' and 'OR' conditions, will the precedence be shown.

https://cdn.factorio.com/assets/img/blog/fff-280-boolean-visualisation.webm

The last thing is not really GUI related, but rather a change of the train behaviour. We were asked many times, to support waypoints. A waypoint would be a stop in the schedule, where the train doesn't even stop, it just goes through it. Instead of having another checkbox settings on every stop for that, we just changed the rule, that no conditions on a stop means, that the train doesn't stop at all.

https://cdn.factorio.com/assets/img/blog/fff-280-train-loop.webm

If you want a Train to come to a full stop and then continue, you can add a 'Wait 0 seconds' condition.

Implementation wise, the implications of this for the train pathfinding logic weren't that straightforward. Previously, each train pathfinding is done from its current position, to the next stop where it stops. But now, since the train might want to continue through the next stop at full speed, it needs to plan the path ahead through the next stop once it gets to the point of no return (the point where it needs to start braking to stop in time).

This means, that the train pathing can be ahead of the current station target by many stops, and since the schedule works circularly, it can plan through the whole schedule 2 or more times.

The fact, that all these things are finished now means, that the Train GUI chapter is closed and we can move on. There are a few nice ideas of what could be done to make the train schedule way more powerful in the endgame (Train names, Train groups, conditional stations), but this will have to wait until some future time. I believe, that this was the most complex UI we have done for 0.17, so it should only get easier from here on out :).

Tool bar
Related to the new quickbar, we had this idea of an easier way to access some game tools, especially blueprinting tools. This is how the Tool Bar came along.



The tool bar is a small section to the right of the quickbar that contains a customizable set of buttons for some commonly used actions or tools (or actions/tools that don't belong anywhere else). You can see the tools we have far in the image below.



The Tool bar has 2 sections: the main panel and the tool selection list. The list contains all the possible tools and allows you to pin them to the main panel, sort them, or use them directly. Pinned tools are visible on the main screen all the time for ease of use. The main panel will change its size to accommodate for the selected tools. If no tools are selected, the main panel minimizes itself into a small button that opens the tool selection list.

All the tools related to blueprints were removed from the blueprint library and moved to the toolbar. Also they work a bit differently: when pressing "new deconstruction planner" for example, you will get a deconstruction planner that you can use immediately, and pressing Q will not place it in the inventory, instead it will place it back "into the button". This allows you to quickly deconstruct something without having to carry a "default" deconstruction planner around. Also avoids the situation where you end up with a bunch of different deconstruction planners in the inventory. You can of course still keep the deconstruction planner by explicitly clicking it in the inventory, quickbar, blueprint library, or any other inventory, such as a chest. The same behavior applies to the upgrade planner and empty blueprints.

Some tools will display useful information in the tooltips, for example:
Paste will show a blueprint tooltip of the blueprint in the clipboard. Special shortcuts will allow you to navigate through the "clipboard history".
Undo will show a textual representation (possibly also a visual representation) of what will be undone. Such as "Undo construction of Transport Belt", "Undo construction of 35 entities and 250 tiles".

Each tool will have it's own keyboard shortcut, so the tool bar will also teach players about these shortcuts through tooltips, hopefully to the point where they no longer need the tool bar.

Mods will be able to add their own tools to the list, making it a nice place for players to access mod-created tools.

Let us know what other quick tools would you like to see added to that list, or any other thoughts on our forum.
Factorio - Klonan
Hello,
FFF motivation
This weeks Friday Facts are a good example of how they serve not only the obvious role ofinforming the community, but also helps us to divide the work into smaller chunks with individual deadlines. As this Friday Facts was scheduled to be about the Train GUI, we had to put special effort into finishing everything planned for the Train GUI, so it can be presented, and we can move to another task and 0.17 comes in reasonable time :).

The train GUI
We introduced the plan and mock-ups for the Train GUI quite some time ago in FFF-212. Many things changed since then, the final GUI style and rules are different now, and we also re-iterated the UX of it. But the main general idea of the layout remained.

The train schedule is one big list with stations and conditions all visible, so you don't have to click through the list-box of individual stations to see the conditions.



Drag and drop
Previously, stations and conditions were added after the currently selected station/condition. Since there is no selection now, you just always add to the end. Changing station/condition order is done by drag and drop. The drag and drop was possible in the list-box version as well, but it was quite a hidden feature, as it was the only list-box in the whole game that allowed that, and there was no visual indication of that functionality.

We also believe, that the visual feedback of re-arranging is now better than before.

https://cdn.factorio.com/assets/img/blog/fff-279-drag-drop-017.webm

Wait condition visualisation
One of the things I always missed in the Train GUI was an indication of how much longer the train going to wait in the station. After some discussions, we decided to give visual feedback to all reasonable conditions by gradually changing the style of the condition frame to green as if it was a progress bar.

The question is, how do we calculate the fraction of completeness for individual type of wait conditions?
  • Elapsed time - The most obvious one, as it is known how much time the train has spent in the station, and how much more is remaining.
  • Inactivity time - Also simple, similar to elapsed time.
  • Inventory full - We can calculate the fullness of individual cargo wagons and average it.
  • Inventory empty - Simply (1 - fraction of full) :)
  • Item count - Here it starts to be tricky. If the comparator is > (greater than) or ≥(greater or equal than), we just calculate the amount of that item and divide it by the goal. If the comparator is anything else, I can't show a progress. I know how far I'm from the goal, but I don't know what to compare it to, so in this case, we just show either not completed at all, or fully completed.
  • Fluid condition - Basically the same as Item count.
  • Circuit condition - Here we just show nothing or full, as we can't really know.

The result is quite nice for simple cases:

https://cdn.factorio.com/assets/img/blog/fff-279-full-empty-loop.webm

And in more complicated cases, it can be a great tool to quickly identify a problem:

https://cdn.factorio.com/assets/img/blog/fff-279-train-complex-conditions.webm

Temporary stations
The second most desired feature is temporary stations. The main motivation for them is the usage of trains for personal transportation. When I want to do that now, I have to:
  • Open the map and search where I want to go, and find the nearest station.
  • Remember the station name.
  • Enter the locomotive and add that station (by searching through the list) to the schedule.
  • Confirm some random wait condition.
  • Press the "go to the station" button.
  • When it gets there, delete the station from the schedule again.

With temporary station support, what I do is:
  • Enter the locomotive and find the place where I want to go directly in the map preview.
  • Ctrl+Click nearest rail/station.

Using the control click will select the nearest station or even just a rail, and set it as a target of temporary station. By this action, the temporary station is added in front of the current goal (if there is any) and is ordered to go there. Once the goal is reached, the station is automatically removed from the schedule and the train will continue to the goal it was headed to before adding the temporary station.

This means, that I can carelessly hijack any train passing by for my personal travel, as it will continue its schedule once I'm done with it. It also adds some possibilities for when I need to send train from dried out mines into smelting and depots etc.

The modern Spitter
In the animation below you can see the new high-res spitter walking in 3 levels. As you can see we took the chance to work a bit different the same concept as before but integrating some new details that in my opinion makes them more interesting.

https://cdn.factorio.com/assets/img/blog/fff-279-spitter-walk.gif
Note: the colors are not necessary final.

We keep the modular shell due the familiarity with the biters. Also for convenience with the color tint. The same way the modern Biter moves a bit closer to a spider concept, the Spitters are going more to a woodlouse or a small centipede. The point is it's flexibility at the time of shooting, also they shoot from far away from the target, so there's no need to look specially strong or agile.

https://cdn.factorio.com/assets/img/blog/fff-279-spitter-shoot.gif

The 'classic' design of the Spitters is based in the idea that they shoot from some height in order to bypass the walls of your factory with their acid spits. This is a nice concept, but at the time of walking it doesn't make much sense to keep standing up. That's why we took the chance of improving this feature, and we divided the modes of the Spitter in two: walking and shooting.
Now when shooting, they stand up as before, but for walking they use all the legs.

We also added this big mouth claws that open and close when spitting to give a better expression. The rest is pure fun. We have also been with Vaclav on the way they shoot...

Worm and Spitter stream attack <font size="2">(V453000)</font>
With the new high resolution Worms (and now also Spitters), their projectiles started to look even more out of place than before. On top of that, a homing acid projectile makes about as much sense as a homing laser beam. We were quite sure we want Worms and Spitters to spit acid, but closer to how the flamethrower 'stream attack' behaves, so we started with that.

https://cdn.factorio.com/assets/img/blog/fff-279-no-prediction.webm

While visually it makes much better sense and the acid looks much nicer thanks to the work of Dominik (from the GFX gang, not pipe programmer gang) and Ernestas, the acid stream has a downside - it can easily be dodged. In fact, as long as you keep moving, the stream never hits you. Therefore we added predictive targeting to streams - so Worms, Spitters and Flamethrower turrets can hit the target unless it changes direction.It is still possible for the player to dodge them if they try, but with higher numbers of Worms it becomes a lot harder.

https://cdn.factorio.com/assets/img/blog/fff-279-prediction.webm

When the target too fast and/or the predicted position is out of range, the prediction is turned off. We will probably tweak this so that the prediction tries to go as close to the border of its range as possible. At some point even the homing projectiles from 0.16 miss so this is not much difference, the threshold probably comes a little earlier though.

Where the acid stream hits, it creates an acid splash on the ground. The acid splash does damage to trespassers (currently not buildings), and applies a slow debuff. Enemies are not affected by the acid splash.

To make the effect less binary (slow/fast), we added a tapering slow - at first it applies a lot of slowdown, but the effect linearly decreases over a few seconds until it disappears completely.

All of the worms have a large enough stream attack that it damages more than one building if they are next to each other. Spitters smaller than behemoth do not possess this ability.

https://cdn.factorio.com/assets/img/blog/fff-279-super-trooper.webm

Some details and numbers are still being worked on, but with all of the changes combined, it should be more fun to attack biter bases. If you are not a fan of 'combat dancing', you can always just invest a bit more into military technologies and win with brute force.

As always, let us know what you think on our forum.
Factorio - Klonan
It's finally here
The proposal was first mentioned more than 1 and a half years ago, in FFF-191. Since then, we kept mentioning it in our blog posts and players kept asking about it.
After a lot of back and forth within the team on whether we should implement it or not, and how it should work, we finally have it almost ready for 0.17.

The quickbar


To refresh your memory: the quickbar is changed from being a separate inventory to simply a shortcut bar to the player's main inventory. It will mostly work like the current quickbar, except item slots can only be filters.

This means that when you place, for example, an Inserter in the new quickbar, it creates a shortcut telling you how many inserters of that type you have in your main inventory. Clicking the shortcut, will grab the first available stack from the inventory. That shortcut will stay there throughout the game, even if the inserters are depleted temporarily.

This solves quite a few annoyances:
  • No more random items appearing in the quickbar as you craft them.
  • No more items moving to different slots when they get depleted and re-crafted.
  • No more using the quickbar to carry things around.
  • No more "will this be crafted to inventory or to the quickbar?".
  • No more confusion when shift-clicking an item if it will go to the quickbar or the trash slots, or somewhere else.
  • Guides the player to make proper shortcuts. Players are much more likely to remember shortcuts they created themselves.
  • Player is in full control of the quickbar instead of the game trying to be 'smart'.
  • Managing 1 inventory is simpler than managing 2 inventories.
  • Relevant item counts.
The main inventory size was increased by 20 stacks to compensate for the inventory slots that now became shortcuts.

The quickbar pages
A suggestion that quickly gained traction was the ability to configure and switch between multiple pages of shortcuts, not just two.
So the new quickbar is actually 10 pages of shortcuts that you can configure as you like: e.g. a page for general factory building, a page for combat, a page for building trains, a page for building outposts, a page for oil processing, a page with utility blueprints. It's up to the player to configure these pages as they like.



When clicking on the button next to one of the selected pages, a page selector will open which shows all 10 pages of shortcuts. You can then easily select what page(s) you want to actively use and see on the main screen. The number of pages visible on the main screen is configurable.
The page selector also acts as an extended action bar, allowing you to quickly grab an item or blueprint that you don't commonly use, or allowing you to quickly configure your pages.

The default keyboard shortcuts changed a bit: keys 1 to 0 will pick the item in the slots of the top selected page. Shift + 1 to Shift + 0 will change the the top selected page. So an advanced player will be able to quickly swap pages to build what they want.

The ghost cursor
A feature for more advanced players is the ghost cursor: When selecting a 'buildable' item from the quickbar or when using the pipette tool, if you have no items of that type in your inventory, a ghost will be placed in the cursor instead.

It's a common situation where for example you build something and you run out of inserters. So instead of crafting more or running to the other side of the base to get more, you can place ghosts, continuing to focus on designing what you are building instead of being distracted.



To avoid confusion for new players, this feature is off by default and can be turned on in the interface settings menu.

Integration with blueprint library
This is still work in progress, since big changes are also coming to the blueprint library. The plan is that you will be able to create shortcuts for blueprints from the blueprint library. This means you can place your most commonly used blueprints and books in one of the shortcut pages and use them directly from the blueprint library without clogging your main inventory.

Non-GUI progress update
There was some talk following last weeks GUI progress update, as to why we don't release now, and finish the GUI's during the experimental phase. One major clarification I'd like to make, is that it is not only the GUI that is not yet finished. While GUI is currently the largest task remaining to be done for 0.17, there are still some other non-GUI features that are yet to be completed:

Finalization of new Fluid system
The new fluid system (FFF-274) is almost complete, but it is yet to be merged into master. After internal testing we have been making efforts to tune the new behavior, specifically how throughput over distance and flow with different fluids works.

High resolution enemies
The new Biters and Worms have been showcased already in previous blog posts (FFF-259, FFF-268), and the last puzzle piece is the new Spitters. Alongside a graphical update, we have also been experimenting with some functional changes to the enemies.

Further map generation tweaks
We presented our most recent developments on the map generation in FFF-258. Since that post, there have been some further planned changes and improvements, specifically to the placement of tiles, biomes, trees, doodads, cliffs.

Playtesting, bug fixing, and design balancing
It seems to always be the case, but $nextUpdate is going to be the biggest Factorio release so far. While some initial playtesting shows that most things are stable, we have yet to have our typical office-wide week/fortnight of playtesting and tweaking. Inevitably things that we need to solve will come up during this playtesting, so it would be unwise to release before it is complete. There are also over 50 unsorted bug reports in our forum, which we will need to sort through.

Looking over what is left to be done, It is clear to me that the release won't be ready in January.
When we are ready to release 0.17, its launch definitely won't be a surprise. We will announce the exact date in the FFF at least the week before.

As always, let us know what your think on our forum.
Factorio - Klonan
GUI progress update
This is a continuation of the last status report from FFF-269. As it might not be a surprise, the biggest bottleneck of the 0.17 release is the GUI. I like to believe, that we have learned a lot from the pitfalls of the collaborative creative process of GUI. This is the typical way we were redesigning the GUI:

  • Two to three people started discussing what could be cool to change in the particular GUI. Some people randomly joined and left the ongoing discussion. Arguments to discard certain ideas have to be repeated over and over. Then the discussion is ended because of something.
  • A week later people start talking again, most of them forgot most of the stuff, or were discussing it with different people, so they assume some details of the changes to be understood by everyone, while they aren't.
  • They come to an agreement how it should be done.
  • They have a random discussion about it a week later and figure out, they had completely different ideas about how it should be done, they just didn't articulate them precisely. Both are kind of angry to have to reopen and re-negotiate the subject again.
  • Someone starts to implement the GUI, but half-way through it is uncovered, that there was another layer of misunderstanding when specifying how should the work be done, and we need to go to step 1 again and repeat.

Since many GUIs are thought and worked on in parallel, these situations overlapped and amplified the problems of mixing things up in our heads about what we agreed on in which GUI.

Luckily, we eventually figured out, that it can't be done like this, and since there is a lot of work in the GUI, we need to make a process. It goes like this:
  • First, there is some general discussion about the GUI, all team members can share their ideas.
  • kovarex + Twinsen sit alone in the office, and discuss for some time (can be hours), all the pros and cons of how things should be done, and make some agreement.
  • Twinsen writes a detailed UX document about the GUI containing the structure, and more importantly the behaviour, in a detailed manner.
  • Twinsen + kovarex discuss the UX document and propose changes until they agree on the final version.
  • Albert + Aleš take the UX document and create a UI mockup based on it.
  • kovarex + Twinsen + Albert agree on the UI mockup or propose changes.
  • Someone is assigned to implement the GUI based on the UX document and UI mockup
  • kovarex reviews that the implementation is correct and points out some inconsistencies that he can see. Part of this step is making sure, that we share as many GUI styles and code as possible across different GUIs.
  • kovarex + Albert have a final look on the implementation and fix final details until they both agree that the screen is fully finished.
Having the UX documents/UI mockups always available proved to be a huge time saver. Not only it helps us to solve the communication problems, we also don't have to remember and re-articulate decisions from some time ago as we can just open the document and see what we agreed on and instantly continue where we left off.

A good part of this strict pipeline is that we now have better knowledge of the state of the work progress.
These are the GUI screens that we hope to deliver for 0.17:



You can see, that there is still a lot of to do, but the work tends to accelerate as more and more of the GUI layouts/tilesets/standards are being finalized and reused. The conclusion is that 0.17 experimental in January is possible, but it might be February as well :).

The little details
Also, one of the reasons the work progresses slower, is that since we are making final versions of everything, we want to make it feel polished before we consider it finished, since there won't be time to come back to it.

For example, in every settings screen, we have the 'reset to default' button now. The first logical step was to only enable the button, when some of the options are different from the defaults. But the next logical step was to somehow let the user know, what settings will be changed when he uses the reset button. So we simply highlight all the non-default settings when hovering the reset button, and it feels nice since suddenly you have instant feedback of what you can expect from the action.

https://cdn.factorio.com/assets/img/blog/fff-277-reset.webm
https://cdn.factorio.com/assets/img/blog/fff-277-reset.mp4

I understand, that spending too much time in settings GUI might not look like a good idea, since it is not used that much and the in-game screens are more important, but many of these principles we realize on the way will be useful when designing changes for the in-game GUI.
The scaling problem and solution <font size="2">(kovarex)</font>
One of the many goals of the GUI rewrite was to make sure that the GUI looks correct in all possible UI scale values. By correct, we mainly mean, that the proportions of everything stay the same, so it is just smaller, but not deformed in a weird way. This might look like a simple thing to do, but it isn't as all the GUI values (sizes, widget positions, paddings etc.) are integer values, as in the end, every element needs to be on some specific pixel as long as we want it to be crispy clear.

Imagine that you have a 1 pixel wide gap between two 20 pixel wide buttons and then you want it to show in 120%. The buttons are enlarged to 24 pixels, but the gap either stays 1 pixel or becomes 2, but the proportions of the layout changes.

To solve this (and other issues), we decided to use something we call "modules". 1 module is 4 pixels in standard scale (100%), and almost everything is a multiplication of modules (sizes, positions, paddings etc). On top of that, we limited the possible scale values to be multiples of 25% (from 75% to 200%). This means, that the size of one module can be different (from 3 pixels at 75% to 8 pixels at 200%) but the proportions of everything stay the same, so it looks correct.



This works quite well so far, but it brings another problem for 0.17. I don't know if anyone noticed, but the item slots (inventory/logistic filters, crafting slots etc.) were intentionally scaled less than other UI elements. The reason for this was that the 32✕32 icons we have for all the items/fluids/recipes don't look good if stretched too much.


32✕32 icons that are stretched to 200% don't work good.

But since we had to abolish this special rule for 0.17 we need to make sure that all the 32✕32 icons (285 items, 27 signals, fluids and more) will have to be provided in 64✕64 resolution, so all the supported UI scales will look nice. This is going to be quite a lot of work, but since we render the icons from 3D models anyway, it should be manageable. We will probably push the high-res icons to 0.17 during the experimental phase.

Procedural Wave defense
We have had the Wave defense scenario in the game for a few years now, and over that time I have collected a lot of feedback. One problem I have determined, is that the scenario really lacks replayability, due to the fixed map. Since the map doesn't change at all, once you have a set of blueprints and tactic that works, repeat plays are mostly boring.

With recent changes and the great work by TOGoS, the procedural map generation is working really well, and is very reliable for a given set of settings. This gave me the idea, that it might be possible to make the Wave defense use a new map every time. I have been experimenting with some preset values, and I believe it will work really well.

However I have some indecision within myself, and there are several advantages and disadvantages between a handmade custom maps and randomly generated worlds.

Advantages of a bespoke map
  • The map can be specifically designed and tweaked for a better experience, I can test and iterate the way biters move through the map, adjust the placement of trees, resources, tune the difficulty etc.
  • We don't have to worry about map generation engine changes breaking the scenario.
  • It is a reliable experience for all players, people can share specific tips, designs and tactics that are more specific for the map.
Advantages of procedural maps
  • The scenario has much greater replayability.
  • We don't have to worry about migrating map data, tiles, entities, etc. to newer versions.
  • Any improvements to the map generation will be reflected in the scenario.
  • People can't cheese the scenario using other peoples blueprints.
  • We can add some configuration options for people who want to tailor the experience.
  • It is easy to add support for servers to continue running after victory/defeat.

So I am making the changes now to test whether procedural can work,and it shouldn't take too long as most of the scenario script will remain the same. I wanted to ask for some community feedback and thoughts: Have many of you played the Wave defense? Do you think a random map would be more fun? Do you think you would play it more if the map was different each time?

As always, you are welcome to let us know what your think on our forum.
Factorio - Klonan
Hello, the office is slowly ramping back up after the Christmas and New year festivities.

Belt item spacing
Part of the final polishing and cleanup work of preparation for 1.0 is cleaning up and smoothing out some of the hiccups in the game. Many will remember FFF-266 where we talked about some of these upcoming changes and simplifications. One suggestion that came up was to adjust the belt throughput from its unfriendly 13.33 items/s.

Belt throughput is determined by 2 variables, how far the belt moves items each tick, and how much space there is between each item. There is a visual requirement that belts only move integer number of pixels every tick, so that is 1/2/3 pixels for transport belt, fast belt, express belt respectively. This means the only 'allowed' way to change transport belt throughput is by changing the spacing between the items.

The spacing currently is 9 pixels between items. The fact that each tile is 32 pixels, and that 9 is not a factor of 32, explains the odd throughput number. This spacing also leads to some undesirable behavior, such as when using the circuit network to read the belt contents sometimes the belt can fit 8 items, sometimes it can only fit 6, and the count will fluctuate between the two:



At this point it is quite obvious to reduce the spacing to 8 pixels, which is a factor of 32, and gives a nice even 15.00 items/second, which is what we have done for 0.17:



With a spacing of 8 pixels, belts now always fit exactly 8 items (4 on each side), so for instance, reading a fully compressed belt gives a reliable result:



The change overall gives a 12.5% buff to belts, provides nice round integers for calculating factory requirements, and removes a few oddities. A next step we are considering is tweaking the furnace recipes to match the belt speed, but that is a consideration for another day.

Script rendering
In the last few weeks I have been working on a system that allows mods to easily render geometric shapes, text and sprites in the game world. Like many modding features, the implementation of this rendering system was prompted by a modding interface request. When I first saw this request, I doubted the usefulness of adding a whole new API that needs to handle saving and rendering for just one mod author. A few months later, another mod author discovered a newly added method to create text that was only visible to one player and requested more features for it. Through further discussion with the mod author it became obvious that they were looking for a system to show some helper text and sprites to only one player. After other mod authors joined in to point out that the solutions implemented at the time were not sufficient, the idea of a script rendering system was dug out again and I picked up the task to implement it.

Of course, one does not simply invent a new system without first finding out what the system should be able to do. Here I want to thank the regulars in the #mod-making channel of the Factorio discord. They were a great help in suggesting features and always happy to answer questions about what they render in their mods. I also consulted old modding interface requests on the forums to find out what features were desired, amounting to a total of 12 requests that are now fulfilled by the new system. With this information I wrote a rough design document that listed the desired features without considering their implementation.

The current implementation of the script rendering boasts eight different object types. The basic geometric shapes being line, circle, rectangle, arc and polygon. Additionally, sprites, lights and text can be drawn. One of my main aims was to make the system as flexible as possible which I achieved by making every single property of the render objects changeable after creation. One example of this is that the size or orientation of a sprite can be changed without destroying and recreating it. This differs from the previous rendering that mods used. They would create many entity prototypes which had sprites with the desired orientation or size and then switch those out to change the orientation and size of the sprite. This frequent replacing of entities comes with a considerable performance cost which the script rendering completely eliminates.

Furthermore, the rendering objects are simply identified by numeric IDs which are much more performant to handle in Lua than LuaEntities. Another advantage of this dynamic system is that nothing in the rendering relies on the data stage. Unlike the mentioned technique of using entity prototypes, the script rendering does not need prototype data. This means that scenarios, the so called 'soft-mods', can also make full use of this new system.

https://cdn.factorio.com/assets/img/blog/fff-276-script-render.webm
https://cdn.factorio.com/assets/img/blog/fff-276-script-render.mp4

The first big point in the design document was to allow any target to be either an entity or a position. This point with, the addition of entity offsets, works beautifully in-game. Objects can be 'attached' to entities or placed at static positions. Even a combination of the two is possible if an object like a line has multiple targets. Due to the attachment to entities, the render objects are deleted when the entity is destroyed. This leads to some very useful behavior: If mods for example want to simply place some text above all their entities, they don't have to handle deleting the text when their entities are mined by the player or eaten by biters.

The second big point was conditional visibility, this means that it is possible to restrict the rendering of objects to certain forces and players. This will hopefully see use by the helper mods that prompted the implementation. This conditional visibility had also been requested in the past where it was handled as something that simply 'won't be implemented'. The main reasoning for this was the predicted performance impact of adding the player whitelist to many entities that the base game uses. This performance concern is irrelevant when using the script rendering because it is a completely separate system from the base game rendering. If you don't use mods you won't even notice that it's there and it won't impact game performance.

https://cdn.factorio.com/assets/img/blog/fff-276-script-render-2.webm
https://cdn.factorio.com/assets/img/blog/fff-276-script-render-2.mp4
In combination with other modding additions, the new render system opens a lot of interesting possibilities for mods to explore.

In general, this new system means that mods no longer have to abuse entities like beams, smoke or flying-text for rendering. This opens up a lot of possibilities of new rendering options that previously could not be considered, such as custom fonts for text or easily changeable scale and orientation of sprites. So, mods authors, please think about what rendering options would be useful for your mods and request them on the forum if they are not already implemented.

As always, let us know what you think on our forum.
Factorio - Klonan
It's the last Friday of 2018, and as such the last Friday Facts before the New year of 2019.

We all hope everyone has had a great 2018, and looking forward to a lot more automation fun to come in 2019. Albert has produced a postcard for you all to share to give the year a good send-off.



0.17 Science changes
Science in Factorio or more separately, technologies and science packs, are the main progression mechanisms in the game, and all entities are unlocked by it. This is great but it also means that when we change or add almost anything to the game, it will certainly have some impact on science. Over time we have changed the technologies and science packs multiple times because their context and design goals moved and evolved with the game.



Before 0.15 we had a fairly linear progression of getting from Science pack 1 to Science pack 3 with increasing complexity, plus the go-fight-your-neighbours Alien science pack which didn’t really require much factory/crafting.

In 0.15 Kovarex introduced a new design where the player should be able to make a choice between different tech paths and get different benefits from each. The amount and price of these science packs also made the game significantly better paced and longer, meaning you have enough time in the game to appreciate the intermediate steps between upgrades, like for example, not ignoring Modular armor or Power armor Mk1. In 0.15 we also added infinite technologies with Space science packs, which give more sense to the large factories that never have to stop.

During 0.15 we did some tweaks to Production science pack as we realized neither the Assembling machine 1 or Pumpjacks were the right ingredients... and it ended up a bit too simplified.

I really like Kovarex’ general idea of the 0.15 science packs, but I also feel like it’s possible to improve the implementation in order to really make more out of its potential...



Current state - 0.16
Over time we have gathered a lot of experience through playing the game ourselves and feedback from reading your posts and comments about the technologies and science packs. Here are some of the issues we noted:



Military science pack
  • Gun turret in Military science pack is really expensive and the rest of the ingredients seem too small in contrast, which makes them feel redundant.
  • In the crafting menu, Science pack 3 is sorted before Military science pack, but when playing it’s almost certain that players obtain the military science first (except in peaceful mode), and Science pack 3 later simply because of the oil processing barrier which is hard for many.



Science pack 3
  • Science pack 3 suddenly adds the most amount of complexity (mainly oil mining, oil processing, setting up chemical plants), and a lot of extra resource requirements (4.5 times more expensive than the first two science packs combined).
  • Electric mining drill recipe in Science pack 3 has boring ingredients (Iron plates, Iron gear wheel, Electronic circuits) we use in multiple other places, and the Inserter in Science pack 2 is one of them. It is also the miner that raises the price of the science pack a lot.
  • Electric mining drill in Science pack 3 was supposed to hint to the player to expand production because things are about to get wild and expensive, but this hint doesn’t seem to work well.



Production science pack
  • Production science pack has surprisingly few ingredients (two) for its expected higher tier.
  • The step from Science pack 3 to Production science pack is minimal in complexity - use the simplest oil processing result (Lubricant) to upgrade Engines from Science pack 3, and produce more of the same (Steel and Advanced circuits) for Electric furnaces. For the first time you need a steady supply of Stone bricks, unless you have their smelting automated for Walls or for the handful of Oil refineries you needed earlier.
  • There are not that many unlocks that the Production science pack alone would actually give you. The interesting ones require High-tech science pack as well so in the end there is little choice as you simply need both anyway. This in combination with the difference in complexity and price between Production and High-tech science packs, means that most players don’t even realize that the design is that they can choose between the two science packs. Therefore it’s common to think that the High-tech science pack is obviously superior to the Production science pack... in fact even the name of the science pack implies that it is.



High-tech science pack
  • High-tech science pack is very expensive compared to the Production science pack.
  • The step from Science pack 3 to High-tech science pack is moderate in complexity but huge in price (crazy amount of Electronic circuits, Advanced circuits and smelting to support them).
  • Processing units in High-tech science pack are very expensive and the rest of the ingredients seems irrelevant and low tier.
  • High-tech science pack needs Copper cables as a high-throughput ingredient, which feels out of place to many people as you can craft Copper cables from the beginning of the game, and they don’t feel very high-tech. But it’s cool that it’s a little different - makes you consider using direct insertion in the build or not etc.
  • Batteries feel quite low tier - if you want early laser turrets, robots or accumulators, it’s usually the first oil product you make.
  • High-tech science pack needs Speed modules which have a much less interesting impact on the game than Productivity or even Efficiency modules.

In short, Military pack could be nicer and cheaper, Science pack 3 is a huge difficulty spike, while Production vs. High-tech science pack balance doesn’t really work. Let’s have a look at what we can do about it.



0.17 science
While the design idea stays the same, the new science is trying to make the progression difficulty smoother and the places with choice more clear. We will try to achieve this in three steps - changing the names, recipes, and technology dependencies.

Step 1: Science pack names
The names will make more sense once you know the rest of the changes, but I think it’s important to set a dictionary first so the article is less confusing.

One of the other factors which may have made things further confusing is that the naming convention of science packs is a mix of old science-pack-1,2,3 from pre-0.15 and unique names (military, production, high-tech, space). The idea behind this was that the specialized science packs get unique names, while the mandatory early game progression keep numbers 1,2,3. With the upcoming changes it’s a great opportunity to make this more consistent and fitting.

It’s noteworthy that we considered multiple options - whether we should keep the naming, give them numbered names or just name them by colours.

Naming by numbers
Giving them numbered names (1-7) would mean that any choices would be out of the window, unless we would add sub-numbers like for example Science pack 3A and Science pack 3B. That’s completely abstract though - would you ever remember which one is A and which one is B?

Naming by colours
The other option would be to just call them by colours - so many people do that already regardless. However, a lot of us also say green/red/blue circuits or yellow/red/blue belts. And that’s completely fine, but the official name in the game should be representative about the differences. The main difference between a green and a red circuit is not the colour, but the recipe and complexity.

Furthermore, I believe it has some value to have official 'formal' names, even if we know that we will call all of the things with simplified 'informal' names anyway. I believe that creating this informal language, in your mind or in the whole community, is subconsciously really cool. You’re calling things by their colour, it’s easy to remember and everybody understands each other - but only because you all share the knowledge of what the colour in that context means.

To summarize; it would be best to have unique names which represent each science pack well, they should be a representation of its purpose, of the stage in the game and the recipe, be short and easy to pronounce, it would be nice if each science pack name would start with a different letter, and so on... The only slight problem would be that those names weren’t easy to find, but I believe now we have them at last:



Step 2: Science pack recipes
One of the most important aspects of the science pack is its recipe as it defines how many resources it costs, how complicated is it to produce, how much do you need to research before being able to produce it (because of prerequisites), and how much time it takes to craft it including all the ingredients.



We are happy with the first science pack, especially when it gets a nicer name that sets the tone for the whole game.



The second science pack is fine. Here the name was not very easy to find as 'green science' is used to unlock so many various things, but logistics are a big part of them (red belts, car, trains, stack inserters, robots). In general Automation + Logistics is the first, and mandatory, part of the game so they fit well together, and the ingredients (Inserter + Transport belt) are both related to moving items around.

Especially since Assembling machine 1 does not have the 2 ingredient limit (FFF-266), I’d say this option is not completely off the table yet so I’m especially interested in what you think about this.


  • Piercing rounds magazine stays as it’s one of the more vital things to have automated for your health and well being on this planet.
  • Grenade stays as it’s a very useful weapon against large groups of enemies, like biters or trees.
  • Replacement of Gun turret with 2x Wall. This means more price balance between the ingredients so all of them feel reasonable, a lower price of the science pack in total, and now it requires Stone which is nice for variety and makes you automate Stone brick smelting you will need to craft Oil refineries.
  • It shows before Science pack 3 in the crafting menu.


  • Engine units and Advanced circuits stay, as they are the first intermediate products with longer crafting times and decent complexity, but they are not too resource expensive. You also need Engines for pumps/trains/cars, and Advanced circuits are useful for a whole bunch of other things.
  • Electric mining drill replaced with Solid fuel, giving you a lot more buffer room to produce something before your refinery deadlocks when one of the three oils has no use. The player is also much more familiar with item storage compared to the newly learned fluids at this stage so it is much easier to handle the possible deadlock. In general it also means that you don't need to rush towards Advanced oil processing to unlock cracking as early, especially if you send some of your Solid fuel to burn in boilers.
  • Since in the crafting menu it now shows after Military science pack, it would look weird that you get 2x Military science pack per craft, but just 1x Science pack 3. Now a single craft of Science pack 3 returns 2x as well. The ingredient count and crafting time has been increased to compensate. It’s also more clear that both Military and Chemical science packs are in a different tier to the first two science packs.


  • Electric furnace stays. It has a nice recipe and motivates upgrading to Electric furnaces, which in turn motivates players to extend boiler-based power generation, or replace it with with either solar or nuclear. Maybe you’re also motivated to build an external smelting because the 3x3 furnaces aren’t compatible with the old 2x2 ones, and external will likely be more expandable and use trains.
  • The Productivity module is not only an obvious choice because of the names and theme of getting more stuff produced. Using Productivity modules motivates you to extend your power setup since it makes machines eat more power, and extend your factory because it makes machines run slower, all while making you spend less time building mining sites. On top of that, it’s a common mistake that people research Productivity module 3 and then try to produce those immediately - which gets quite grindy because of the long investment return period of Productivity module 3 - but if you use level 1 first and work your way towards the top tier in smaller steps by upgrading to level 2 as a middle point, it becomes a lot more feasible. Since it is included in the science pack recipe, you are more likely to use Productivity module 1 earlier.
  • Rails. One of the coolest recipes in the game which also uses Iron sticks and raw Stone. Rails are also produced quickly while being relatively cheap - this means they can be used in high quantities in the science pack recipe to achieve the same 'high throughput ingredient' as 0.16 High-tech science pack had with Copper cables - except rails do not feel out of place because it’s never too late in the game to start building trains. The point of 'do you use direct insertion' is here twice as you can direct insert Rails into Production science pack machines, and you can do the same for Iron sticks into Rails (the ratio is also very nice by the way). The idea of making it easier for people to try using trains is also good.
  • Production science pack now returns 3x packs in a single craft, making it clear that it is a tier above Chemical science pack.



  • Utility science pack now returns 3x packs per craft, making it clear that it is the same tier as Production science pack.
  • Processing units stay, but their number is reduced from 3 to 2, it was just too many.
  • Flying robot frame is basically an upgrade to Battery and the Electric engine so it feels much more appropriate for a high tier science pack than either of those two did. And you are just a small step from worker robots - getting specifically Construction robots is one of the biggest power spikes that you get in the game - everything suddenly becomes much less tedious and defenses can be automatically repaired, while Logistic robots have their own share of awesome progression feelings when you get them, even just for personal delivery.
  • Low density structure. As hinted in earlier FFF-257, Low density structure is much more useful earlier on now, and since it is one of the ingredients for multiple advanced personal equipment items, it makes perfect sense to use Low density structure in the Utility science pack as most of the top tier personal equipment is unlocked by Utility science.



This recipe does not exist as it kind of is the process of the Rocket silo, but the values are representative. Note that it returns 1,000x science packs.

The Space science pack is only influenced by Low density structures having a slightly different recipe (20x copper plate, 2x steel plate, 5x plastic bar), but other than that it is the same.

Renaming of the science packs gave me an opportunity to rethink if it really should not be called Rocket science as many people have half-jokingly suggested.In my mind 'Rocket science pack' would mean you are trying to research some technology which improves rockets, which is not what is happening in the game. Space science pack tells me that I am discovering space, which is what the rocket is doing if you assume that the Satellite is sending you scientific data and the Rocket silo turns them into a bottle of scientific data, like any of the other coloured scientific data in the game.

Also space is said to be infinite, and this is a science pack for infinite technologies.

The math
Numbers are definitely important when it comes to science packs as they are a significant portion of where your resources are spent. When iterating the different science pack recipes, it was immensely helpful to use a spreadsheet in combination with my favourite Factorio calculator (thank you very much for this useful tool Kirk McDonald). If you are interested you can find the full spreadsheet here.



The spreadsheet can be pretty confusing so let’s just summarize the most significant points:
  • Oil is hard to quantify in the same formula as ore resources so it’s calculated separately.
  • Chemical science pack ore price is less than half of 0.16 Science pack 3 - the main hurdle is the complexity of oil processing so the oil price is also more.
  • Military science pack is significantly cheaper making it more viable earlier.
  • Using Productivity modules affects Military science pack very little as it includes no intermediate items, making it relatively expensive in the late game if you use Productivity modules for everything else.
  • Ore price of Production and Utility science packs is exactly the same, the Utility science pack is more expensive on oil.
  • The oil difference between Production and Utility science pack drops significantly with the use of Productivity modules.
  • Space science pack is more copper heavy because of the Low density structure recipe change.
  • The late game total ratio of Iron:Copper consumption is significantly different (1 iron : 1.4 copper), but Copper consumption is reduced more by Productivity modules (1 Iron : 0.76 Copper).
  • Coal and Stone are more relevant than in 0.16.
  • The total cost of all science packs combined is roughly 10% lower in ore resources, and about 10% higher in oil.
  • Another interesting number is the total crafting time required, which is also taken into consideration, as it basically says how large factory you need in order to craft the recipe at a given rate.

Step 3: Technologies and science unlocks
As it’s been hinted in FFF-245 earlier, one of the issues was the distribution of which technologies were unlocked by Production and Utility science packs. The same FFF also stated that we are trying to improve this and showed the tech trees for it. At that point the new science packs were not in our master branch yet so it wouldn’t be wise to include them in that FFF. Now we have a newer version...
Production science pack alone now unlocks:
  • Logistics 3 - Express belts always make sense for more production.
  • Level 3 modules - pimp my base, more production with less mining.
  • Automation 3 - faster Assembling machines with more module slots mainly for better utilization of Productivity modules.
  • Effect transmission - using Productivity modules with the help of Speed modules in Beacons - the recipe for moar production.
  • Coal liquefaction - very useful when you have a lot of coal but not enough oil. The Coal liquefaction recipe is also changed so it’s more useful - now it produces much more Heavy oil that you can crack into whatever you need, but produces less Light oil and Petroleum gas. If we cracked everything to petroleum, the maximum gain is almost doubled compared to 0.16.
  • Kovarex enrichment process and Nuclear fuel reprocessing
  • Worker robot capacity 2 - Better throughput for your robots - since you don’t have the full Logistic system yet, this is just for de-Construction robots and less Logistic robots needed for each personal delivery.


Utility science pack alone now unlocks:
  • Worker robot speed 3 - More convenient personal delivery and personal construction goes very well with the theme of Utility science. Speed for Construction robots is also very helpful when you are in a Tank and a Construction robot is chasing you to repair it.
  • Logistic system - The ultimate factory utility tool. Without Production science you can’t get ridiculous throughput, but you get the ability to move items by air.
  • Personal roboport, Power armor Mk2, Fusion reactor - More utility/personal equipment for combat, construction and faster movement.
  • Military 4 with Uranium ammo, Destroyer robots, Atomic bomb, Artillery.
  • High tier damage/shooting speed/follower robot count upgrades for military things.
  • Rocket control units - the final Rocket ingredient and Atomic bomb prerequisite.



With that the only technologies which require both Production and Utility science packs are:
  • Rocket silo
  • Space science pack (unlock of Satellite)
  • Atomic bomb (it’s fine if it’s super late game)
  • Upgrades like Inserter capacity, Worker robot speed/capacity, Mining productivity

During several playthroughs of very different settings and styles I have tried how viable it is to prioritize one or the other science pack (Production vs. Utility) and I got results I was very happy with.

Military upgrade technologies
Separately from any science pack rework, we have realized that we have a few too many technologies for damage/shooting speed upgrades.



In general the combat rebalancing Twinsen did for 0.15 is very good and all weapons have their uses, but in order to make for example Shotgun useful you have to invest a lot of time and resources into upgrades for it. This is hard to justify when you could instead research upgrades which benefit both Gun turrets and your Submachine gun and get a comparable amount of offensive power. A similar case happens in multiple places.



Please note that the icons above are provisional, but the solution is that we are merging all military upgrade technologies except Artillery upgrades into 5, which should make a lot of technologies much less redundant. The new technologies are:
  • Physical projectile damage - Bullets, Gun turrets, Shotgun shells, Tank cannon shell
  • Energy weapons damage - Laser turret, Personal laser defense, Distractor robots, Destroyer robots
  • Stronger explosives - Grenades, Rockets, Land mines
  • Refined flammables - Flamethrower turret, Flamethrower (handheld)
  • Weapon shooting speed - Bullets, Shotgun shells, Tank cannon shells, Rockets
Artillery, Follower robot count, and Laser turret shooting speed upgrades remain as separate technologies.

The prices of these new upgrades are about double than what 0.16 individual upgrades used to be. However you almost always get more than two improvements in return and some of the science packs (Military, Chemical and Utility) are now significantly cheaper.



You don’t get all of the upgrades from level 1 though. For example Stronger explosives level 1 gives only Grenade damage bonus, on level 2 it gives both Grenade damage and Land mine damage, and from level 3 further it influences Grenades, Land mines and Rockets. That way we avoid that you would get an upgrade for something far before you could actually possibly unlock and craft it.

Also, it means for example Tank cannon shell upgrades do not have 7 tiers but just 2 (Physical projectile damage 5+ and Weapon shooting speed 5+), but instead they are expensive and very impactful.



All the weapons which have a shooting speed kind of make sense that they could be in a single technology, so we did just that. The Artillery shooting speed is separate mainly because it’s an infinite research unlike the Weapon shooting speed.



One of the reasons why for example Land mines didn’t have their own upgrade technology is because it would be just another research. With this kind of grouping it is so much easier to add it into one of the categories without adding more technologies which would feel like bloat.



Personal laser defense is now also influenced by Energy weapon damage upgrades (which also affect Laser turrets), but on the other hand we decreased the base damage it does, and also decreased its power consumption so it is fun to use even with Personal solar panels early on, and if you invest into the Energy weapon damage, it becomes quite good later.



Combat robot damage was quite hideous because it didn’t actually provide bonuses for all combat robots - just for the two later tiers. Defenders did still get upgrades, just from a different place - the damage and shooting speed upgrades for bullets. Now it’s much clearer as Defenders are kept the same way while the upgrade for Distractors and Destroyers are in Energy weapons damage which is clearly focused on laser and electric beams.



Both Personal laser defense and Distractor robots now have the same laser beams as the new high resolution laser turrets (FFF-228).

Rocket silo
With the military technology changes, Rocket shooting speed technologies no longer exist. This opens the question what do we put to the Rocket silo prerequisite instead of Rocket shooting 5... The answer is: Nothing.

Putting any arbitrary military upgrade there just makes that weapon type mandatory to upgrade even if you don’t want to use it. Not only that, but it was also the only reason why you would need to make Military science packs if your only intention is to launch the Rocket.



This makes it even more clear that the Military science pack is a separate branch of science. It depends on the progression of your factory, but its sole purpose is to deal with the distraction - the enemies - from your main goal.

Biters by themselves already give you a very good reason to invest into Military science regardless and it’s unnecessary to force the Military science pack on people who play without biters - just because of the few Rocket shooting speed (or any other) military technologies that you don’t even make use of. Or maybe you play with biters but are badass enough to just use more unupgraded Gun turrets and launch the Rocket without any Military science packs anyway, we’ll leave that decision to you.

Freeplay victory condition
It’s late at night, you have been playing for a while now (again), you built all the assembly lines to make the rocket parts, provided the gluttonous silo all the parts it demanded. You can finally see the counter of rocket components say 100%. You watch the great animation of the rocket preparing. All excited you hit the LAUNCH button written in capital letters because this stuff is lit. Your emotions are through the roof, your eyes are desperately trying to remain dry. In feelings of pride and accomplishment, thinking about all the effort it took to achieve this great technological feat, you observe your great creation flying upwards. The epicness of the moment couldn’t be much higher. At least until you see the following:



How many of you have seen this great message before and how many of you have seen it on your first rocket launch? It’s really easy to forget the satellite, especially as the GUI slot for it only shows after the rocket is ready to launch. Not to mention that a new player might not know at all that the satellite even exists and is required.

Mainly for these reasons, you now win the game by launching an empty rocket. The satellite is unlocked with the Space science pack technology and its only purpose is obtaining these science packs.

The idea of an escape pod has been abandoned but we will might try to somehow use it in the campaign.

Mods like SpaceX which redefine the victory conditions with a super-satellite can use a remote call to disable the default victory condition.

As always, let us know what you think on our forums.
Factorio - Klonan
New Fluid system 2
Hi Factorians,

Here is Dominik, with an update on the fluids. This time it is pretty much finished so I can tell you facts instead of just speculations. You will find how the new algorithm will work and some new handy usability features.

In FFF-260 I wrote about how it all started, why we are doing it and what the plan is. There was a huge response from you all and I want to thank everyone for their contributions. Let me apologise to redditors, as at the beginning I started responding on the forums and when I realized there is reddit too, there were too many comments for me to handle.

The forum users produced many ideas on how the system could work. About third of them was a fluid teleportation, many where known but many were entirely new and interesting. What intrigued me was the large variety of backgrounds they came from - differents kinds of engineers (mechanical, CS, electrical, ...), mathematicians, physicists, and even people with real pipes hands on experience. I won’t go through them here, you can find them on the forums or reddit. There were two proposals on the forum though that were so good that they made it into the game - from quinor and TheYeast.

Both of these proposals were very similar and kinda similar to the previous game logic. What it shares is that the mechanic still uses fluid physics simulation and volume in a pipe as a base for the movement calculation. As a result, not much changes on the first glance. What they add though is an emphasis on the fluid network update being independent on the current state (i.e. updating one pipe only depends on state from the last tick) and is therefore independent on evaluation order, which was one of the big pains of the old model that led to sometimes ridiculous junction behavior. Difference between these two was rather small - quinor’s version allowed perfect throughput with 3 passes over the fluidboxes (fluidbox is the thing managing fluids for entities, so I will talk about them), while Yeast’s one was 2 pass with ¼ throughput. What was outstanding though is that TheYeast, a physicist, supported the model with a nice theoretical background and what’s more, he made an amazing JS simulator to test and compare various modification of the model. Because that extra pass in quinor’s version was too high a price for the perfect throughput, I went with TheYeast’s two pass one.

Since the old algorithm only used a single pass run by entities for the update, I first needed to overhaul the whole system to allow accommodating the new one. Going from one pass to two passes necessarily means higher complexity, so we made a big effort to optimize everything we could to make sure we will still end up faster than 0.16. Kovarex wrote about it in FFF-271.

The new algorithm
The new algorithm follows realistic wave equations. It works with two variables.
  • The volume of a fluid in a fluidbox (FB) and the corresponding column height.
  • The flow speed in a connection between fluidboxes.
The exact behavior then depends on two constants:
  • C^2 - corresponds to the mass of the liquid. Affects how quickly changes (waves) propagate.
  • Friction - affects how quickly throughput drops with pipe length.
The first good news is that these variables can now be set for fluids separately so different behaviour can be achieved. E.g. crude oil pipeline will require some pumps while steam will be totally fine.



The two pass algorithm for one update (leaving out many details) is then as follows:
  • Update flow speeds on all connections
    A. d = difference of fluid column (input has always 0 and output has max)
    B. d *= c^2
    C. (mechanism for damping waves)
    D. Flow speed += d
    E. Clamp the flow to take max ¼ of contents (otherwise we could get below 0 - remember that we only use last tick information); fluid can go over max temporarily.
  • Move the fluids along all connections
    A. Just move 'speed' amount of fluid from one FB to another

This algorithm is so simple and works so well, and also requires only very small changes, that it was a clear winner. The main downside is that it can only move ¼ of FB content in one tick, so FBs are enlarged to compensate. Another is that the fluids may seem to travel quite slowly into an empty pipe, but that is actually quite realistic and looks nice. The third issue might be some waves and oscillations, which are a result of the realistic model, and are very small with the current dampening model. This could be limited even further by introducing continuous fluid production/consumption, but it does not seem necessary at the moment.

What you get over 0.16 is that the fluids now behave correctly and intuitively, performance is consistent (pipes to ground won’t help you with throughput anymore), different fluids actually move differently.



As a small but handy improvement, you can now see flow rate information in the entity info of each pipe.



My big thanks go to quinor and mainly TheYeast for coming up with the model and doing a lot of work with me on tuning it and finding improvements to make the behaviour as nice as it is now. In case you are interested in more detail, see TheYeast’s forum posts and simulator source code.
Efficiency
The overhauls and optimisations in FFF-271 cut the update time by some 50% and up to 10x on some high-end CPUs.

Introducing the new algorithm made it immediately 30% slower. Long story short, through various fixes, including a small change that made the algorithm 1 pass again, this increase was cut down to 15%. So the overall result is that the fluid update is still a lot faster than it was before. I am still debating the segment merging, as it is not that simple and it would cost the simulation some detail. It is a low priority at this point compared to other parts of the update time.

Fluid Mixing


That’s right. No more fluid mixing.
Once an empty fluid system (connected network of fluidboxes - pipes, crafting machines etc.) touches either a fluid or a fluid filter, the system is locked onto that fluid. It is then not possible to connect it to another system with a different fluid. There are quite a few actions which can result in merging systems, so each needed to be checked:
  • Building an entity with fluidboxes (Eg. pipes, pumps, storage tanks)
  • Setting a recipe with a fluid input/output
  • Rotating an entity



In order to use the system for a different fluid, the system must first be reset - by draining its fluid and removing all the filters.

Please note that old saves have to work with this so if your save currently contains some fluid mixing setup, it will be automatically fixed upon loading it. This will be done during migration either by removing some fluids, unsetting recipes, or destroying entities if need be.

macOS developer needed
At the start of this week our long time macOS maintainer and web admin HanziQ let us know he was leaving the team and moving on to other projects. He has been part of the Factorio team for nearly 4 years, and in that time has contributed a lot to the game and community. We all wish him the best in his future endeavours.

HanziQ leaving, along with the departure of our other macOS developer Jiří, means we currently have nobody on the team to work with and maintain the macOS version of the game. This is a pretty significant issue, as we have the largely untested GFX engine rewrite due to be released with 0.17. If you know anybody who may be able to help us fill this position, please direct them to our macOS developer job listing.

Steam keys direct from us
We have long sold the game through our own website, which involves receiving a code and then registering an account etc. I have received quite some community feedback, and from this feedback we have decided to start selling Steam keys directly through our site. On the buy page you will be given the choice of a Website key or Steam key.



We hope this will be more convenient for a lot of people, especially for those wanting to gift a copy of the game this holiday season.

Steam awards 2018
The Steam awards 2018 voting has begun, and Factorio is nominated for 'Most fun with a machine'. There are also 2 other Czech games nominated for the same category, so the country is quite well represented.

Animal named after the game
A new species of scorpion Neobuthus Factorio was just identified and classified. My father has a hobby of going (not only) to dangerous places and identifying undiscovered species of scorpions and spiders. He offered to name one of his classifications after the game for fun. You can find the full publication here.

As always, let us know what you think on our forum.
Factorio - Klonan
Hello, we recieved a lovely holiday gift from Steam this week:


The note reads: Happy Holidays! From the Steam Team

The chocolates are delicious and do not seem to be lasting long...

Cutscene Controller
One of the things planned for the 1.0 release is a proper campaign and a tutorial-like “New Player Experience”. Both of these try to guide the player, and for that we sometimes need to divert the player's attention to a particular place in the virtual world.

In other words, we need cutscenes. Basic cutscenes are relatively simple things:We need to take the control away from the player, move the camera around to show the things we need to show, and maybe display some messages on screen. Cutscenes are meant to be triggered and controlled by scenarios, so there needs to be a generic way for scripts to describe a cutscene.

Inside the engine, player inputs pass through a layer called, unimaginatively,"controller". The 0.16 version of the game knows three controllers:
  • Character controller, where player inputs control the engineer entity in the centre of the screen.
  • God controller which is not tied to an in-world entity but rather allows the camera to fly around the world freely and interact with anything.
  • Ghost controller which does not allow the player to control the game at all.

The controller layer is the ideal place to take control away from the player in a cutscene. It is also a convenient place to move the camera automatically. Even better, Lua scripts can already change the current controller for any given player. Adding a new controller type to facilitate cutscenes was the obvious choice here.

The new cutscene controller is created with a list of map positions to pan the camera to, along with how long each pan should take, and how long the camera should stay in that position. The controller figures out on its own how to move the camera between the specified points – for that, it uses Cubic Hermite splines to make the camera movement nice and smooth. Once the controller reaches the last specified camera positions, it smoothly pans back to the starting position and restores the previous controller, giving control back to the player.

Here is a short video of the cutscene controller in action:

https://cdn.factorio.com/img/blog/fff-273-cutscene.mp4

Since this is all accessible from Lua, modders and scenario creators will be able to make a use of this new functionality in 0.17 from day one.

Rail clock
While working on the campaign, I ended up needing to do some work on cutscenes too. Inspired by a Youtube video I ran across by the venerable "arrow in my gluteus maximus", I decided that a great test case for cutscenes would be a static camera for a rail clock in the office, which could display the actual time.



Because of some technical issues, this needs to run as a multiplayer game, and it actually ended up exposing a few bugs in the cutscene implementation that only manifested in a multiplayer game, so that was a nice side effect.

Here's a video of it in action:

https://cdn.factorio.com/img/blog/fff-273-rail-clock.mp4

If you're a reasonably technical user, and would like to run one yourself, you can check out my rail clock repo. Unfortunately, as it does use various 0.17 features, you can't actually run this today, but once 0.17 is released publicly, it should work just fine.

You will also need to use either Linux or macOS. Windows might work, but there is a python component involved which has never been tested on Windows.

Localisation plan for 1.0
For a long time we have been using Crowdin for all the non-English translations of the game. Over the course of the early access period this has served us really well, the majority of the contributions were of a high quality, and since we automated the fetching and packaging of the translations, it was a mostly hands-off system.

As we approach 1.0 next year, we want to make sure that all parts of the game are as polished as they can be, so we are planning to have a 3rd party proofread and finalize the game localisation. While most of the current translations are really great, some of the languages we support have less than 50% of the strings translated and approved, so contracting another company to help fill out the rest is a reasonable course of action for us.

However we need to know where we should prioritize our efforts, so that the languages we target and focus on are the most significant ones and will help as many players as possible enjoy the game. To gather some preliminary data, we have created a simple Google form with some questions for our community. If you could help us by spending a few minutes filling it out, we will be able to make a more accurate decision on which languages are most important.

You can find the survey here.

Furthermore, if you have any other suggestions or feedback on the localisation of Factorio, any companies which you would recommend, etc. please let us know. As always, the place to share these helpful thoughts is our forum.
Factorio - Klonan
Hello,
a large part of the team is attending GDS, if you are in Prague and interested in Games, you are welcome to come as well.

New Manage/Install/Update mods GUI
As we were going through the main menu, improving the looks and sometimes the interaction of most of the GUIs, it was obvious the mod management needed some attention. Most of the interaction was quite unintuitive and limited, making most players prefer using the web version and managing the files manually.

Mods will be managed, installed and updated from the same GUI, the 3 operations being shown as 3 tabs. The interaction, arrangement and intuitiveness of the GUI should be vastly improved. It still won't have all the features of the online mod portal (such as discussions) but provides a very quick hassle-free way of installing and updating mods without having to deal with files.







Note these are just mockups, the in-game integration will be starting soon, and it should be done for 0.17.

The most notable changes are:
  • Only mods compatible with your game version are shown.
  • The list of visible mods can be additionally filtered by their category.
  • Mods will have a picture when browsing the mods list.
  • When updating mods, you can clearly see version numbers, browse the changelog, and choose what updates, if any, you want to skip.
As usual I wrote an internal document to be used as a reference. It's quite boring and contains the same information, just more verbose. If you really want, you can see it here.

Invariants are required
In a version of Factorio long ago we had this recurring problem with items and inventories. When an item was added or removed from some inventory it's meant to generate an event about what changed. These events are used for a multitude of different things and allow for many code simplifications and optimizations such as "turn off the inserter until a new item shows up in the chest it's taking from". It used to work like this:
  • Code to remove/add some item in some inventory
  • Some logic with those items
  • Send the event about what changed in the inventory
However as with most things - things changed. Someone would add in new logic or just forget and not send the changed event. After all - programmers are human and we make mistakes. The issue kept recurring and was incredibly hard to test for because you can't write a test for some logic which doesn't exist yet: you can't test something is correct until you've written it and if you forgot to sent the changed event you can forget to write a test that checks you didn't forget it.

The only solution I could think of to the "human problem" is to remove the human part of the problem. If we no longer needed to remember to write the code to send the event and it "just happened automatically" any time we changed items around then the problem would just go away. That invariant - that changing any item sends an event - solved the problem. However, it also taught me something: if some invariant is ever allowed to vary (aside from the obvious "an invariant that varies isn't an invariant") it's completely useless.

Invariants are amazing tools. We can write tests to enforce an invariant. Programmers don't need to think about handling things outside of the invariant because they can always say: "it should work as the invariant describes so I just don't need to handle the other cases". If the invariant is ever broken it's clearly a bug and has a clear solution.

As always, let us know what you think on our forum.
...