Mercury Fallen takes place underground and I felt it rather important that the maps are proceduraly generated for various reasons. I’ve spent a bunch of time looking over articles and techniques to get my brain in gear on the process. I’ve messed a bit with map generation in earlier projects, but I always enjoy doing some research to get some fresh ideas.
What’s In A Map?
While Mercury Fallen is a 3D game, the map itself is just a 2D grid/array of cells. Each cell can contain a ground, a floor, a structure or an item. In some cases a cell may contain only 1 of these things such as a dirt or stone structure that takes up the whole cell, but there can be many in the idea of a floor, with a structure such as a lamp or a loose item for a colonist to go collect. On the coding side of things these different types of elements in a cell are thrown in to Cell Layers which is just a means of organizing the objects within the cell.
Some of the first methods for generating a simple map was just adding dirt floor to all the cells. This gave me a nice flat map to use for testing out various other elements. At some point, though, it started to become necessary to have a proper map.
Given that I was dealing with cave structures I thought that cellular automata would be a good approach to create some organic looking cave areas.
The first step of the process was to randomly fill the 2d grid/array with dirt. This generates a big mess of dirt tiles that looks pretty ugly.
The next step is to iterate over the grid a few times using the cellular automata process which results in a much more organic look.
While this process generated some decent caves I started questioning how I might add in additional resources such as stone/ore etc.. My first attempt at this was layering in additional cellular passes using the solid dirt as a mask. This worked enough to get started on other things, but I eventually came back to this whole process and revamped it entirely.
After having some additional thoughts on what will be added in the map I realized I needed to go back and work more on the map generation. After doing some more research I realized that using a heightmap may get better results.
Once a heightmap is procedurally generated I can mask different height values to different cell types. The below image shows masking and coloring a heightmap to values for water, dirt floor, dirt filled, stone and ore.
This creates a pretty nice looking map that has a nice organic look to it. The only thing I didn’t like, though, was that certain elements were too consistent such as there always being a dirt floor around water and stone was always encased by solid dirt. I wanted a bit more randomness in there for flavor.
First I layered in some more solid dirt by doing a cellular automata pass, but masking off the result to only effect tiles that were originally only dirt floor. Secondly I created another heightmap at a higher frequency and blending in values for ore and stone to give more variation.
This was the final result
While I’ll probably end up going back and tweaking it further I find this to be a better end result, than what I had previously. This map also gives me lots of little areas to hide secret items in as well. 🙂