A long term project I am slowly working on requires the generation of a realistic continental world map – something like the maps you find in Civilization. I’ve spent a few weeks working on methods to generate these maps, and decided to summarise what I’ve learned about realistic world generations. These are for flat 2D maps – I did play with the idea of generating a spherical world map (something like this), but eventually decided it would add complexities I’d rather avoid for now to other areas. I may come back to the spherical world later on as I feel it is a much more satisfying solution to the problem.
There are several stages to producing a realistic world. The first is to produce terrain – continents, oceans, islands, mountains, lakes and so on. Once these are in place some kind of climate model is needed to produce deserts, forests, frozen polar regions and so on. Finally the world needs to be populated according to the game needs – cities, or starting points for characters or civilizations and so on. For the moment I am going to focus on the first problem, producing a realistic terrain for the world.
Looking around I found that there are several possible methods. A common method (and the one used by Minecraft) uses something called Perlin noise. The algorithm to generate Perlin noise is explained well here or here. Perlin noise looks something like this:
To make sure I understood the algorithm I wrote a short Python script to generate Perlin noise. In the original algorithm the noise value generated will be 0.0 at regular intervals, so to prevent this I added a slight offset to the grid.
The first pass of the algorithm generated a map like this:
It certainly looks fairly random, but it is far too smooth to look like a realistic map. To make it more realistic I am going to sum together several different “octaves” of Perlin noise. What does this mean? Basically, Perlin noise has a scale. The largest the scale the larger the features that will be generated. The two images below show Perlin noise generated with a large scale and with a small scale. The idea is to use large scale noise to generate the big features (i.e. continents and islands) and then add smaller scale noise to create smaller features (hills and mountains). The “amplitude” is also important here. The large scale noise map will have an amplitude of 1, and I will add each successive layer with an amplitude half of the previous one.
I’m actually not incredibly happy with the results. The world generated by this map reminds me of something like the Greek islands, not something on the scale of a whole world. I’m really looking for a method of generating maps that results in continents and oceans – something that isn’t really repetitive. I’m starting to think along the lines of some kind of more realistic tectonic model…