Friday Facts #163 - New rails & New problems

Posted by V453000 on 2016-11-04

Rseding has just arrived for another 6 week visit here at the office, and his timing is pretty great as we start shifting the focus onto 0.15, of which our to-do list is extremely long.

0.14 now stable

We have just launched 0.14.18 as our stable build, this means it has been pushed to all users on steam, along with the website users being prompted to automatically update. Stable however doesn't mean we won't be releasing any further 0.14 builds, as inevitably with more people playing the release, there will be many more bugs found. In fact we are already in the process of releasing a quick fix for the stable, as people have reported that the demo does not work, a minor issue to most, but something that might not give the best first impression.

Once we have all the kinks sorted out, stable release means we will be taking a look at our marketing options in the upcoming weeks. We feel that 0.14 is a good distance from the early access release, and a whole lot more improved from the stable 0.12 we initially launched with, so it is a good time to make another push to spread the word. As always, we owe much of our success to all of the players who continue to make the effort of telling their friends about the game, and we would have never come so far without such a great community supporting us.

Rails and their problems

As kovarex mentioned in one of the recent FFF, the current rails are using a very simple system which aims to minimize the amount of used sprites, so it only uses five sprite types: horizontal rail, vertical rail, diagonal rail, horizontal curve and vertical curve.

Then these four sprite types were flipped and rotated to their positions. To ‎make this visually work, it was necessary to use top-down projection with minimal signs of perspective. Which is a gigantic limitation, especially since almost all of the entities are projected at 45 degrees. Each of the four sprite types had four layers each to prevent things from overlapping in junctions, I will describe that in more detail later down.

Old and new basic rail rings. On the left same colour shows identical sprites. On the right all sprites are unique.

Now, we are defining unique sprite for each rail piece, and for straight ones we add 2 extra variations. The main benefit of this is removing the top down limitation‎ and having the rails more consistent with the rest of the game. Another aim is getting them into high resolution - and since the old rails were made in 2D, any kind of conversion to both more resolution and a different perspective wasn't doable, so we took our chance to redesign them. The "more 3D" perspective brought new problems though. Most of them are fixable through adding more layers...

First issue appeared fast - the vertical sides of rails would overlap the top side in junctions. I have been battling this exact problem in OpenTTD with no success for a long time, so I immediately knew that the solution is to split them into 2 layers, something I couldn't do back then, but we can in factorio.

Proceeding further, the old rails had the ties (sleepers/ wood planks)‎ at 45degrees on diagonal tracks in order to be perpendicular to them. Which didn't look utterly wrong as the whole thing was top-down - it even made sense in that way. But now, when at 45 degrees, it suddenly looked very wrong, so it had to be redone. Another thing we don’t really know why is that the old rails had more ties in horizontal view than in vertical, which should be exactly the opposite way to make the illusion of perspective… so we fixed that, too.

Redoing the ties was not that easy though, as they need to tile properly to all other combinations where they could connect. As I soon realized, doing this by trial and error / by eye was extremely tedious and took a long time without any results, I would fix one combination and other 2 combinations would break.

Luckily, blender has a very convenient feature for this called Group instances, which lets me group objects, and the use their clones to preview all the combinations with a live preview. The slight issue was that there is 148 ties, and apart from grouping they also need to be cut by the grid to represent how the final sprite is going to look.

Doing this manually is tedious and if I needed to repeat the process, my brain would probably derail. So I spent a few days getting into blender's python, and with the help of our programmers, we managed to create a script which automatically detects if an object has an intersection in a sprite, and cuts it + groups it to that sprite if it does. This creates a live preview which makes it very easy to see what is tiling with what. Automation, anyone?

To make entities look nice, almost all of them have some kind of integration as we call it. This is usually a slight dark outline/glow where they touch the ground. As a result, it looks more connected to the ground, and makes sure that it works in all the various terrains we have (and Jurek is adding more at this very moment). Next step was to make the rails integrate with the terrain properly. The old rails had just a very binary noise without any semi-transparency, which is simple but hides yet another problem - when tracks overlap in junctions, the semi-transparency starts stacking on top of each other. In some cases there is unfortunately no systematic solution so it was solved visually to minimize the effect.

As I mentioned earlier, the old rails were using 4 layers. Worth mentioning that only 3 of them were absolutely necessary to reach the same functionality. Since the rail metal parts needed splitting into two layers with the new system, we are suddenly using all 4 of them, and we are even adding a 5th layer to have junctions draw more nicely.

Early in the process (after the first render), I quickly realized that the rails are using almost 200 images when counting both normal and high resolution. After every re-rendering, I would have to go and rename all of them because their format needs slight adjustment for our naming conventions, and I would have to crop each of them. So, for the first time I attempted to write a python script to do these things for me, and it’s magic! Automation is magic?

And then I went and iterated the rails over and over again to get a nice result.

Once again we discovered that making high resolution sprites isn’t just 'render it in double size', as you can probably tell from reading the above. Especially with something in totally different projection than the previous version. We believe the result is worth it in the end.

As always, let us know what you think on our forums