Friday Facts #219 - Cliffs

Posted by Twinsen, Albert, TOGoS on 2017-12-01

Cliffs - introduction and gameplay (Twinsen)

Several months ago TOGoS (Dan) half-jokingly mentioned that what Factorio really needed was mountains and cliffs. This was also suggested many many many times. Albert immediately got very excited and they started having some discussions about how to make it happen.

Fast forward a few months, and Ernestas had made some cliff graphics that looked really nice when layered onto pretty much any type of terrain. Fast forward a few more months and add a few months of programming and polishing, and cliffs are almost done, so we will be showing them to you today.

Cliffs, together with the other map changes TOGoS did, should make the map look much more diverse and interesting compared to 0.15. Hopefully it will make exploration more fun, since you will be finding more diverse and unique areas in the world.

Since cliffs block your path, they can affect gameplay significantly. To not make this annoying, cliffs are never too long and often have gaps. We tried to balance the length so they will be long enough to create interesting combat situations, or with some modifications serve as a natural wall against the biters, but so long that they block your path when you want to get somewhere. Cliffs will also not appear in the starting area, to give you plenty of space for your initial base.

Finally, in Factorio nothing should stand in the way of automation, so if you don't like cliffs, you can always blow them up using a new mid-game item called "Cliff explosives".

Cliffs - graphics (Albert)

Map generation is hard mainly because it is procedurally generated. That means that the computer is mixing all the pieces to create the terrain on the fly. This leads the artists to a very difficult situation,because it is very hard to guess in which conditions the tilesets will be used.

Factorio terrain 0.1
We started the generation of terrain in Factorio with very basic rules, mainly mixing clusters of 32px tiles. But obviously that wasn't enough.

Factorio terrain 0.3
With better looking tiles, transitions from one terrain to another, and variations of tiles, terrain looks much better. But this technique was a pain for the artist to generate an interesting and detailed tileset. The 32px grid was killing any attempt to have a natural looking terrain.

Factorio terrain 0.12
New technique: Instead of having only variations of 32px tiles, we produce a tileset with different sizes (x32, x64, x128, x256) in order to break this squary sense of grid, and even being able to render more detail in bigger sized tiles. So terrain looks much more natural. The visible tile-grid is almost gone, and we start spreading a new concept for us: the doodads. These are little sprites of plants and rocks randomly spread throughout the map in order to provide more variability and an organic feeling.

Factorio terrain 0.15
Things are getting better, the doodads were optimised and we're able to place much more of them, creating more interesting patterns and mixtures. It is also worth it to mention that the introduction of the high resolution graphics does a lot to help the look of the terrain.

Factorio terrain 0.16
After all those iterations, the next terrain generation integrates a couple of new concepts: the decals which are "just" doodads but ground-related. Decals are meant to generate terrain accidents and details without being oppressed by the rules of "tileability" and size. Basically decals are patches on top of a tileset that are very rich in detail. In combination with the doodads, the absence of the tile-grid and the high-res, we start to have a natural looking terrain. I have to add that the good and fast work of Ernestas, our environment artist, made possible the evolution of this new state of terrain. Now with our new techniques, the creation of a new tileset is very smooth.

Even with all the improvements, terrain still looks too flat, so another addition to 0.16 are the cliffs. Finally we can break the flatness of the Factorio surface, without having to change the mechanics of the game.

This new feature can add a bit to the fun of designing a factory by taking advantage of the topology of the map.

Or can lead combat to more interesting situations.

There are more additions to the terrain, and we will dedicate more time to this subject in future posts.

Cliffs - Programming (TOGoS)

After seeing a graphical mock-up, I was tasked to figure out how they would be integrated into the game.

We had some thoughts about making them tiles, or even a new kind of terrain layer, but in the end decided the simplest way forward was just to make cliffs entities. The "cliff" entity prototype type has some smart logic in it about how all the different cliff orientations work, and that if a cliff gets destroyed, its neighbours need to be fixed up. There are also some special cases about how they interact with projectiles, but for the most part, cliffs just act as walls.

The other aspect to cliffs is how to generate them on the map. Since we already have an elevation function, we can just place cliffs wherever we have a steep slope, right? Well, it is not quite that simple. Because of the way the cliff entities were designed, we can't just place them anywhere, we need to make sure they get placed many segments in a row. The rows of cliffs also need to be spaced apart (in cases where there's enough of an elevation change to have multiple rows of cliffs), or they don't look good.

The first approach I took was to look at the change in elevation on each side of each 4x4 tile (the size of one cliff segment) cell. If an edge crossed a certain elevation and was steep enough, then we'd say that edge crossed a cliff, and select an appropriate cliff segment to put in the cell based on which edges crossed the cliff elevation upwards or downwards.

Cliff segments are placed between cell edges (yellow) that cross the cliff line (purple) at a sufficient slope

A couple of problems became apparent:

  1. Slopes of north-south and east-west cell edges that cross a cliff line aren't necessarily correlated. The result being that cliffs running nearly north-to-south, for example, would often have gaps at points where they crossed a grid line to the east or west.
  2. There was nothing in this algorithm preventing 'impossible' cells, such as one where every edge has a cliff crossing, and we don't have a cliff graphic to represent that situation.

In the end I removed the slope calculation. We still check that edges cross a threshold elevation, but instead of using slope as the second factor for cliff placement, there's an additional noise layer called 'cliffiness' which applies equally to the north-south and east-west edges. That fact that this noise layer is completely independent of elevation has the added benefit that it's easier to tweak, e.g. to ensure that there are gaps in cliff faces every so often.

To prevent impossible situations, the cliff generator now builds up map of cliffs for an entire chunk at a time, and then, cell by cell, removes edges marked as cliff-crossing until no cell has more than 2 'cliff-crossing' (this concept becoming more and more removed from the original elevation function) edges. Of course edges shared with neighbouring chunks are off-limits to the edge removal algorithm, since they have to match whatever cliffs are generated (independently) for that chunk.

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