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".
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.
There are more additions to the terrain, and we will dedicate more time to this subject in future posts.
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.
A couple of problems became apparent:
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.