A few days ago I was investigating a rather minor bug report related to "Rotational Asymmetry in Belt/Inserter interactions" (aka Inserter was not behaving identically when rotated). This was a classic case of floating point equality comparison.
The Inserter would move it's arm and then it would pick up the item if the current arm orientation is equal to the desired arm orientation. Because of some chain of calculations related to rotation, some precision was lost and the equality check would fail for 1 tick, delaying the item pickup for 1 tick in some Inserter rotations. So I fixed that by finishing the inserter movement if it's close enough. Now the inserters should be a tiny bit faster in some rotations, plus all rotations should again be symmetrical and identical.
While analyzing the code and Inserter behavior for that bug, I also noticed that inserters with stack bonus would do nothing for 1 tick after picking up an item from a belt. I changed it so inserters will start moving to a new target immediately after they pick up something. This also sped up the Stack Inserter by a tiny bit.
Both the speedups were enough to fix another bug that was often regarded by the other devs as "not a bug": A Stack Inserter was not fast enough to pick up all the items placed on a belt by another Stack Inserter. Furthermore, because of different timings, the amount of items a Stack Inserter would pick up would depend on how far that Stack Inserter was from the item source:
As someone from Twitch chat noted "Inserters are so fast now, they even don't care about the side of belt". Remember that I fixed the rotation problem by finishing the Inserter movement if it's close enough. Well, what ended up happening was what now the Inserter would stop 0.0001 degrees short of perfectly vertical. That was of course closer to the other belt lane so the item would be dropped there. Previously it was always dropped perfectly vertical, and the lane decision algorithm would choose the right lane. The fix was easy and it's probably released by the time you are reading this.
So with everything fixed, inserters are now more consistent, predictable and intuitive, things that I think are important for a precise game like Factorio. Some situation might end up being slightly slower or will consume a bit more electricity, but generally inserters are now faster.
New resource icons
In FFF-179 we presented new resource graphics for Factorio 0.15. When the resource graphics were finished, we tried to cut pieces from them and compose these into new item icons - but the results were not better than what we already had and we needed to do many more things for 0.15, so we kept the resource icons as they were for the time being.
Recently we have started work on higher resolution for icons, and the resource icons are one of the first families to get a revisit.
As mentioned in FFF-179, to save time when creating the resource graphics we used various randomization methods to get a new batch of re-randomized resource pieces easily. This method has one big drawback for icons - it’s very hard to preview and control in Blender.
However the random generation allows us to generate many random pieces of resources very quickly...
...and combine them in Photoshop into icons with perfect control over every pixel.
However when we put these icons in the game, on belts they seem to suffer a lot from repetitiveness just like the older versions did.
There was one more thing regarding resource icons that we tried to do for 0.15 but did not have enough time for - resources would get randomized variations of icons when drawn on belts.
Rendering more variations and assembling new icons was relatively easy at this point, so we made some more versions.
With randomized variations the resources look much more natural and unrefined, which makes a lot of sense as The Factory has not processed them into perfect uniform products yet.
The resource frequency slider in the map generator settings has a smaller influence over the amount of ore in the starting area patches. more
Inserters with stack bonus are now smarter when picking up items, and thus slightly faster. more
Bugfixes
Fixed that researching the appropriate technology would re-add shortcut buttons to the shortcut toolbar even if the player explicitly removed them earlier. more
Fixed that some saves that contained multiple surfaces would cause the game to crash on load. more
Fixed that auto-barreling opt-out didn't work if the fluid has icons defined. more
Fixed that auto-barreling recipes would use the wrong fluid name if the fluid had a custom localised name defined. more
Fixed that the entity damaged event original_damage value wouldn't be accurate if the entity had shields or resistances. more
Fixed a performance problem related to the undo logic and large blueprints. more
Fixed that trying to join Steam networking enabled games with Steam networking disabled didn't work correctly. more
Fixed that trains built part of a blueprint was snapping to train stop which could prevent some specific blueprints from being built.
Fixed smoke for generators without animation. more
Fixed train circuit conditions not working properly sometimes when arriving at disabled station. more
This really is a tiny feature, the car and tank will now save the color of the passengers when they exit the vehicle.
So now you won't forget which vehicle you were driving, and can warn everyone else on the server: "Pink tank is mine".
All kinds of bugs
As uninteresting as it is; most bugs are boring and typically involve missing code. Someone forgot to implement part of a new feature, forgot that some situation could happen, forgot to check for null. Rarely interesting things show up where everything is working but not how we want it to.
Performance: It's never what you think it is
Recently we had a bug report where a modded game would freeze for a minute for seemingly no reason and then continue like nothing went wrong. It being a heavily modded game my first reaction was to blame it on the mods doing something in a very unoptimized way. But I had to test it to figure out which mod was causing the problem. After reproducing it... I was reminded (again) that it's (almost) never what you think it is.
When a train is driven by a player the game has no idea what direction the player will drive (straight, left, or right). So, as the train is moving the game goes over the potential rails in front of the train and asks every gate it finds to open in case the train ends up driving over them. This logic was very simple: get the rail distance it would take the train to stop at its current speed and "walk" down the rails until it exceeded that distance. As it walked, tell any gates on any of those rails to open.
That logic is "correct" in that it does what it was supposed to do: open any gates that the train could drive over. What it wasn't accounting for was a rail system where everything looped back onto itself 5-10 times per junction.The time complexity for the algorithm it was using was O(N^2). That's "fine" when N is small. However, in this save file, with this rail network, and with these modded trains (with 2,500% speed bonus from modded fuel no less) it meant N ended up somewhere around 75,865. That - as it turns out - was slow.
Interestingly even though the algorithm was recursive it didn't stack overflow. The old algorithm was executing the "open gates on this rail" 5,755,573,057 times. Many of those requests to open gates where duplicates but the algorithm didn't care. In total it took 57 seconds for it to run all of the logic - still incredibly fast for what it was doing (1.6 million rails per game tick).
After some thinking about it; I was able to re-implement the algorithm in worse-case O(N) time which ended up executing the "open gates on this rail" logic 42,913 times and took 0.009 seconds.
Crashing on dereferencing null? Add a null check
I love this phrase. It's both correct and incorrect at the same time. I put it right next to "Crashing from an exception? Just try-catch". It's such an easy trap to fall into: fixing a symptom instead of the cause.
Earlier this week we got a bug report about the game freezing, consuming all of the available RAM, and then crashing when it ran out of RAM. It was again a modded save file so my first instinct was to blame it on a mod. Again, I had to test it. And again... it's never what you think it is.
The crash was correct: it was running out of RAM and when that happens the game crashes and exits. But why?
The game failed to allocate memory when it tried to create a furnace smoke
Because it was trying to make 4'294'967'000~ (4 billion) smokes
Because a small negative signed integer was being converted to unsigned
Clearly the game wasn't supposed to be making 4 billion smokes. So, seeing the problem my first fix was "Casting a small negative signed integer to unsigned makes it 4 billion? If it's negative, I'll just return 0 since a negative amount of smoke makes no sense". I was about to commit this fix when the smarter part of my brain said "that makes no sense, why would this code ever say to make a negative amount of smoke?" So I kept going ... why?
... Because the logic to make those signed integers was "(cycle progress ...) - (last cycle progress ...)" (cycle was < last cycle ... that should never be possible)
Because the furnace burner had made a negative amount of progress in burning the fuel (negative progress should not be possible)
Because the "remaining amount of fuel from this item to burn" was negative (negative fuel values are invalid and the game won't even reach the main menu if some mod tries to set one)
Because the mod API didn't prevent mods from doing: entity.burner.remaining_burning_fuel = -1 AND the game didn't properly clear "remaining amount of fuel from this item to burn" when the item being burnt was removed due to mod migration/removal.
So, I still repeat the phrase: "Crashing on dereferencing null? Just add a null check!" as a reminder to myself and others to always look deeper into why and never stop at the basic symptom of a problem.
As always, let us know what you think on our forum.
Tweaked default graphics settings. The game should choose better default graphics settings for computers with integrated GPUs or less than 6 GB of RAM.
Bugfixes
Fixed that GUI element size wasn't updated in inactive tabs when ui scaled changed. more
Fixed "Confirm Message" conflicting with some key-bindings. "Confirm Message" can no longer be bound to mouse input. more
Fixed possible crash when rendering GUI element with dynamically loaded sprite. more
Fixed recipe window showing wrong item count or not enough ingredients in some situations. more
Fixed a crash when deleting the force of a car with an active logistic network through vehicle equipment grid. more
Mod names are no longer allowed to contain rich text. more
Fixed IME (Input Method Editors) did not work (Windows only). more
Fixed placement of oil and uranium patches back to that of 0.17.40. more
Fixed that roboports with a request_to_open_door_timeout of 0 wouldn't work correctly. more
Fixed that products wouldn't allow amount_min of 0 for items. more
Fixed that migrated/removed fuel items could leave the game in an invalid state. more
Fixed a crash when building combat robots after resetting the achievements in-game. more
Fixed that assembler ghosts would carry over the unresearched blueprint bug from 0.17.38. more
Fixed crash related to clearing a blueprint book from the cursor. more
Fixed that the rotation of blueprint was not saved to the blueprint library in some situations.
Hello, the bugfixing period boringly continues, we got down to 159 active bug reports, so in few weeks we should be finally down with this burden. But at least the graphics department has something new to show:
New design for the chemical plant
After some time working on the redesign of the chemical plant, we can finally show the results:
In the old version, we had the problem of not being very clear when the chemical plant was working or not. So apart from the style modernisation and high resolution, this redesign was aimed for solving this readability issue. As an addition, we tried also to be very clear at the time of viewing what kind of chemical recipe the plant is processing.
Finally we came with the solution of adding a big window - pipe style - showing the moving liquids inside with the tinted color, and also adding a chimney releasing smoke when the plant is on.
As you can see in the animation above, the smoke is also taking the tinted color of the processed chemical, so it should be crystal clear what it’s going on now with this entity. This tinted smoke is very experimental, and we need to make more testing before releasing it, the point is to avoid a too colorful pollution, but in terms of concept I find it 'very chemical' having colored smoke, which could fit perfectly with the subject.
Here you can see the four rotations:
Factorio wouldn’t be Factorio if the things would be easy as "rotate the model in 3D and done". Due to readability requirements, camera perspective, and interaction with any other entity in the game, we have to recompose the entity for every rotation. That’s why even rotating the entity 90 degrees the window remains at the front, and the chimney at the back. Basically every rotation is like a new entity that tries to look like its other rotations, but somehow rotated (!?).
We truly believe that this new design is going to be a good improvement for the game. Slowly but steady, Factorio is getting to its 1.0 release.
As always, let us know what you think on our forum.
Improved efficiency of noise program compilation and quality of error messages.
Bugfixes
Fixed a crash that would sometimes happen after deleting a blueprint from the library. more
Fixed crash related to train schedule containing only temporary stations. more
Fixed GUI inspector vertical align value inconsistency (middle instead of center). more
Fixed LuaInventory::sort_and_merge when used on cargo wagons with inventory limits set. more
Fixed that distractor robots would show in the bonus GUI under the follower robots section. more
Fixed that reading invalid chain signals wouldn't work correctly. more
Fixed yet another ghost connection error related to consistency checks. more
Fixed some cases of multi-layered icons not being scaled correctly. more
Fixed power switch connection consistency problem. more
Fixed "Confirm Message" key-binding not working when bound to some mouse buttons. more
Fixed backwards/forwards max speed fuel modifier related to two-headed trains. more
Fixed interactions of assemblers and underground pipe connections blocked by induced fluid mixing. more
Fixed setting entity ghosts to minable=false didn't work. more
Fixed that the statistics GUI would show count values < 0.5 as "no count". more
Fixed a performance problem with high speed idling trains on circular rail networks. more
Fixed signal placement visualisation for special cases related to straight diagonal rail. more
Fixed that items supposed to be removed on clearing cursor (copy, cut, paste, blueprints from blueprint library etc.) were put into character corpse. more
Fixed uranium cannon shells shooting backwards when aimed closed to the tank.more
Fixed Programmable Speaker alert textbox not losing focus when pressing ENTER. more
Fixed desync caused by setting font colors on buttons. more
You can get experimental releases by selecting the 'experimental' beta branch under Factorio's properties in Steam.