Generating terrain is a very common procedural generation exercise – many people tackle this as a first step to learning procedural generation, and many games use procedural generation for some or all of their terrain. Most terrain generation approaches you’ll find on the Internet use Perlin or Simplex noise. With careful selection of parameters, you can use noise to generate realistic-looking mountains and interesting land shapes.
One problem with using noise in this way is that there is little control over the end result. If you are generating the terrain for some specific purpose, it’s hard to guarantee that the terrain will suit your purpose. For example, if you need terrain with many small islands, it’s difficult to be certain that noise will generate that. This might be the time that noise generates rolling hills and deep valleys instead.
For the past few years, I’ve been working on a fantasy map generator called. DRAGONS ABOUND uses noise for terrain generation, but it also has a number of methods to procedurally generate various terrains that are more intentional. This enables DRAGONS ABOUND to create interesting maps by combining terrains in specific ways. In this article I’ll talk about how DRAGONS ABOUND generates an archipelago of small islands, but you can read about a number of other methods on the DRAGONS ABOUND blog.
Some islands — like the Hawaiian islands — are formed by volcanoes rising from isolated spots on the sea floor. Other islands — like the Caribbean islands — are formed by the same sort of plate tectonics that create mountain ranges. It's just that the action happens where the ocean is deep enough to cover up most of the mountains. Only the tops of the “mountain range" rise out of the sea, forming a chain of islands along the edge of the tectonic plate. This suggests creating an island chain by using the same process used to create mountain ranges but putting them in an ocean area and sinking them so that only the tops are visible.
While this would work to create free-standing ocean islands like the Caribbean islands, in this article I'm going to use this technique to create island chains that extend off the end of a peninsula, like the Florida Keys:
Or the South Shetland Islands off the coast of Antarctica:
The first step is to create the proper shape of islands — a kind of wedge-shaped area of islands stretching out from a peninsula. So if I have a bit of map that has a little peninsula like this:
I want to add some islands in roughly this area:
If the islands start dense and wide near the shore and get narrower and lower as they stretch out to see, it will hopefully appear as if the same ridge that created the peninsula continues out to sea, sinking lower and becoming islands. So I can use the triangle shape as a mask and generate islands within that triangle. To test this out, I'll try filling the mask with a solid chunk of land. (I'm placing this off the edge of a simple circular land shape to get a notion of how it would sit in relation to a peninsula.)
That looks pretty good. Now I need to turn that flat land into a scatter of islands. How can I do that? Well, as the title of this article suggests, islands are just mountains up to their necks in the ocean.
To start with, I will generate mountains in the mask rather than just flat land:
Here I've simply filled the triangle with terrain generated using Perlin noise. I used noise parameters that will give me a lot of small pointy mountains — three octaves of ridged multi-fractal noise. I chose this because I want to get a lot of small islands, but you can play around with different noise formulae to find a setting that you like.
Now I need to sink the mountains into the ocean so that only the tops are showing. With a little playing around with heights, I got this:
This already looks pretty good. I control how far to sink the mountains by setting a percentage of area within the mask that should be islands, and then I lower all the mountains until only that percentage is above water. (I'm showing more islands in these images than I think looks best on a map because I want the shape of the chain to be evident. In practice, I find about 25% land looks good.)
For a further refinement, I can perturb the shape of the mask with noise to get something that is less regular. You can read in more detail about using noise to perturb a basic shape on my blog, but the basic idea is to move the edges of the shape based upon noise. The noise for two points that are close to each other will be similar (that’s what distinguishes noise from random numbers) so the edges will be distorted (or perturbed) in a consistent way. To see what this looks like, I’ll start with the basic triangular mask:
And here are some perturbed versions:
I'm using fairly minor perturbations here. It's important that the island chain point away from peninsula to be convincing, so I don't want to use so much perturbation that I lose that basic arrow shape. Here is an example of an island chain created with a perturbed mask:
Perturbing the mask has made the arrowhead shape less obvious and the overall shape of the peninsula islands more natural and organic.
Now that I can create an island chain, the next step is to identify candidate peninsulas on the map and figure out how to properly align the mask with the peninsula. Sadly, the research field of peninsula identification seems to be moribund, so I was forced to invent my own algorithm.
A peninsula is a point on the coast line where the land bulges out into the sea. To detect these spots, I slide 2 points (Beginning and End) along the coast line, keeping them a fixed distance along the coast apart. At each step, I check whether the midpoint of the line between Beginning and End is over land. For example:
Here the green point is on the midline between Beginning and End and is over land. So I know that the coast between Beginning and End forms a peninsula. If there is water, I have a bay:
(In practice, it's better to check a number of points along the line between B and E and make sure they're all land, because in some situations where B and E are straddling a long narrow bay the midpoint might be land with water to one side.)
Once a peninsula is detected, the next step is to determine where to anchor an island chain and which direction it should point. This starts by placing a new point on the Middle point of the coastline between Beginning and End:
This point is the anchor for the island chain. To measure how “pointy" the peninsula is, I create a line from the Middle point to the line between Beginning and End:
The ratio of the length of this line (the blue arrow) to the length of the line between Beginning and End is a measure of the peninsula's “pointiness". Pointier peninsulas are better for anchoring island chains. I don't want to put an island chain off every peninsula, so I scan the coastline, rank candidate locations based upon their pointiness, and then use the top candidates.
Here's an example island (generated with Perlin noise) with the top four peninsulas highlighted:
You might note that the blue arrow isn't always perpendicular to the red dotted line. This happens because “M" is at the midpoint of the coast line between “B" and “E". Since the coastline is wiggly, the midpoint is not always exactly in the “middle". In the example at the lower right part of the map you can see how sliding the red dotted line along the coast sometimes finds somewhat odd “peninsulas". However, in general the algorithm works pretty well.
The best candidate on this map turns out to be the lower middle peninsula, so that is where I'll add an island chain. To size the mask for this chain, I'll make the base of the wedge the length of the dotted red line, and I'll make the length of wedge about three times the length of the blue line. On the following map I've filled in the mask with solid land to illustrate it's size and shape:
Keeping the mask no wider than the peninsula helps it look like a continuation of the peninsula. The length is more a matter of taste — choose what looks good to you.
Before creating the island range, I perturb the mask to make the regular shape less obvious:
And now I can generate the islands:
Here are a couple more examples:
That covers the basic process DRAGONS ABOUND uses to create small archipelagos. As I hope the explanation makes clear, this process uses noise (both to perturb the basic mask shape and to create the mountains) but harnesses the noise within a procedural generation algorithm that creates a specific kind of terrain. This enables DRAGONS ABOUND to create novel maps that also suit a particular purpose. For example, if I wanted to generate a map for a fantasy role-playing campaign that started with the players being shipwrecked, I could use the archipelago island generation to make a map which I could be certain would have some suitable rocks for a shipwreck. The combination of a structured procedural generation algorithm driven by noise can be a powerful method in your developer’s toolkit.