Coastline extension and Heightmap templates

Three months passed since the previous post. Too much time and too less done for the period, but the work had never stopped. Going with the baby steps I have reworked some basic functional, including a heightmap generation I want to cover in this post.

I was quite happy with the heightmap and coastlines I got, but there were a couple of problems. The heightmap generation output was too uniform, all produced islands were perfectly fitted into a volcanic (high) island model, but islands could be not only volcanic. I have to re-visit the heightmap routine in order to add some variety. The solution is to create a couple of pre-made templates and apply them based on a random or user selection.

Coastline extension

Another issue is a coastline and let’s start with it. I had too options there – curved and linear coastlines. Let’s take a look on the example from the initial post:

Linear variant works perfectly, but I don’t like its angularity. The curved coastline looks better, but it’s too smoothed and “vanished”. The real problem with this curved approach is that coastline got interpolated independently from the graph structure, so we see a curved coastline but actual graph is not changed. So to add any new visible element I have to consider both graph structure and rendered coastline. Frankly speaking, I do not know how to resolve it, but I can try to make a graph much more detailed along the coastline. In this case the real linear and approximate curved coastlines will be much closer to each other and the gap won’t be distinguishable.

This proposed graph extension is not a small change and caused a general logic overthinking. The basic approach is to define a new set of points and calculate a new Voronoi graph, containing more points along the coastline. I cannot just increase the points amount as it significantly slows the map generation and make it slow on zooming and dragging. So new elements addition should be accompanied by an unnecessary points removal.

I cannot insert additional points along the coastline not knowing where it lies, so a heightmap generation remains as is. When basic heightmap is done, I select a “coastal” polygons, i.e. polygons lying along the both sides of the coastline, and add these polygons’ points to a new array. To extend the coastline for each of them I add one more point for an every neighboring polygon of the same type (ocean or land). As a new point I take a 1/3 of the connecting line with a small random swing. My basic diagram has about 8k polygons, about 500 of them are “coastal”. As coastal polygons usually have two neighbors of the same type, the graph is extended for an additional 1000 elements. Not too much and as we already started to change the diagram, we can go further.

Out of 8k polygons 20-30% are land polygons and other are ocean and lake ones. So most of the resources go to the ocean part, while I’m not even render it. Potentially this data could be used for a various things like ocean decoration and sea trade routes, but all these stuff could be done without the initial graph. As we already added some ocean polygons along the coastline and extended them, we can just omit all other non-land polygons and forgot about them. This provides a space to make land polygons much more detailed, for example we can try to create a plausible mountain ranges. I did not explore all the options here and just added all the remained land polygon sites to the array without changing.

The result is quite interesting. From the initial 8k we got about 3k elements. You may notice how the reworked diagram resembles the landmass now still being a proper Voronoi diagram:

As I said before I’m not going to use this graph for an ocean related stuff, so it is OK that  near-border polygons are so big. The extended “coastal” ocean polygons provide a kind of clip for a landmass, so the landmass remains almost untouched, while a new coastline looks much more detailed.

Below is the coastline versions comparison. The first two images show initial graph, the rest two are for a reworked one. On the very first and the third images coastline is linear, on the second and the fourth line is interpolated. Curved ones look more natural and beautiful and while the initial curved coastline (2nd) doesn’t coincide with the graph structure distinctly, the reworked coastline is much more detailed and allows some interpolation.

As a conclusion I have to say that this extension approach looks promising. I may try to detail the graph even more in a future, but as of now I’m quite happy with the result (the 4th image above).

Heightmap templates

The next aspect I want to cover is a heightmap templates. The initial routine generates rather good volcanic islands, so I will consider it as a first template — High Island. As was described in one of my previous posts the heightmap generation is an iteration model based on a “blob” placement. Initial big blob represents island core mountain, about 10-15 small blobs (“hills”) add some variety to the big island or can be a separate smaller islands. The template idea is to take these two landforms, add additional ones and combine them in a way to create a recognizable pre-made template.

Mountain remains a base landform for all templates. If I don’t want a map to have a mountain in the center, I still use this form and just re-scale the land heights to be more flat. Hill is also a good form, I just added the negative variant to represent a land depression, called Pit. I have also added a variable to control hills dispersion as it affects whether a map will be a single island or a couple of islands. A linear and narrowed variant of Hill is Range, its negative variant is Trough.

Combining and re-scaling these forms I have made 5 templates:

  • High Island: mountain, ~15 hills, a couple of troughs, pits and ranges. I’ve added new forms to the template to make it look more interesting. In a rare cases it generates a couple of islands, it’s OK as templates are not intended to be something very rigid.
  • Low Island: almost the same template, but without ranges and re-scaled to 0.3 modifier. So, having the same coastline, it looks more flat.
  • Continental Islands: mountain, 5 troughs. Designed to be a couple of big “continental” islands, but usually produces a one big rugged island. Not sure, but I may change it to something different in a future.
  • Archipelago: mountain, ~15 hills, 2 troughs and 8 pits. This works better, usually produces some small islands that look integrally connected.
  • Atoll: even a bigger mountain with some special code to simulate the atoll generation. Actually, it takes mountain’s coastal polygons and increases their height a bit, while other land polygons are replaced by a shallow lagoon. The resulted map looks like an atoll, but I’m not sure this template is usable as landmass is too small and there are no any interesting features like mountains.

On a random map generation any of these 5 templates could be selected and applied. On a manual map creation, user will have an option to apply a template or add any landforms separately. I will also consider the idea of a built-in template editor, but as of now templates creation is not super flexible (I had to add a custom code to make the Atoll template).

It’s all to today. As usual comments are highly welcomed and I hope you will suggest some new templates to add. The current version is not deployed, I have to switch from JSFiddle to a local machine, so I will share the code only when it is a least partially finished or somebody asks me directly. Meanwhile you may check the alpha on Blocks, I have updated it with some features useful for a real D&D usage.

22 thoughts on “Coastline extension and Heightmap templates

  1. I have used your fantasy map generator to create a few small islands in a pirate story for a table-top rpg campaign. Thank you. I hope to see a version that can create a large continent in the near future.

    Liked by 1 person

    1. Thank you for the feedback! I’m not sure I can turn it into a large continent in a nearest future. This is a well-known scale problem. Can you imagine my current Islands represent the whole continent? What should they have to look like continents? I assume it should be more complicated relief and coastline. So I have to make a plausible-looking mountain ranges.


      1. I think that these work fine as continents if you allowed significantly more burgs in the options as the scale. As it stands, there can only be 700 towns on the entire continent. I went in and changed the allowed maximum regions (200) and towns (6000) significantly higher manually and just mentally scaled up the distances. I think that should give me an approximate area of 24 million km^2, which is more “continent sized” (north america is 24,256,000 Sq. Km)


      2. Wow, thanks. I thought my default maps are already too crowded. I will play with the limits, maybe 1000-2000 burgs will also work. I have only ~3000 polygons, I cannot place 6000 towns without changing the placement logic.


      3. Is there a place in the code where I can increase the number of polygons? I’m trying to make a very large map for a campaign I’m running, and I think your engine could support it better than other map generators I’ve seen. I have coding experience, so I could just clone your github, but it would be better if I can just change in the inspect elements like the option maximums.


      4. Yes, there is a place:
        var sampler = poissonDiscSampler(mapWidth, mapHeight, 5.9);
        5.9 is a minimal distance between a sample points (polygon sites), reduce the number to get more polygons. Please do it gently, it can easily freeze your browser.

        But, it’s not enough. You’ll have a small polygons, while the land mass will also remain small. So you have to change the defineHeightmap() subfunctions in order to change the island generation routine.


  2. Love the maps, just stumbled across them. I am wondering if there is a setting for having neutral land between countries/regions? A generic wilderness that separates some or all of the regions? An example might be a desert that is not controlled by anyone? In any event, I love the work. Cheers and thanks.


      1. It might be useful to have the map colour half the burgs as black circles to indicate ruins that can be explored or settlements for hostiles such as bandits or orcs.


      2. Hi Arion!

        Interesting idea. I have already added an option to generate “neutral” burgs, can try to add some ruins. I assume the better variant is to add a “Burg Icon” editor like I did for a labels. You will have an ability to select Icon, e.g. ruins or temple, set it’s size, colors etc. How do you find it?


  3. I was actually thinking about having the map automatically generate the “neutral” burgs or ruins in “no-mans-land” or areas not claimed by regions with capitals instead of manually adding such features because people are lazy. Instead of a slider for number of regions, perhaps two sliders — one for normal regions and the other for unclaimed areas — so that some of the regions generated automatically become unclaimed regions for exploring.

    As for manually adding burgs and other features, I like it but there is one problem… I can edit the labels but how do i delete the circles without resetting the whole map? Additionally, after manually adding a hill, is there a way to undo it?


  4. Hi, great comment, thank you. I’ve already added neutral lands and burgs as a placeholder, adding a real places of interest is quite challenging. I’m more concentrated on a major things, now it’s a new wind model (looks cool works bad) and roads system (just started to implement). I assume I can turn some neutral burgs into a ruins and build an icon editor, so users will be able to make their own POIs (look like it requires icons development which is super slow process).

    You cannot remove the burg icons (circles) via UI. But you can open browser Dev Tools and remove any element manually from the SVG. The map output is just a SVG file, feel free to operate with it as a standard SVG. As I said before, UI icon editor, with remove button, is in my plans for a future release. Thanks again, I’m glad you help me to test all these stuff!


  5. Great map generator. As you’ve looked to nature too see how rain falls, you might be able to do the same for mountain ranges. Mountains are created either by volcanic activity (as Arenal in Costa Rica or the Hawaii islands) or by continental drift. The latter actually creates ranges instead of single mountains. I don’t know the math, but you might be able to create a few islands and then “drift” them towards each other where you can increase the height of the colliding cells.

    Anyways, maybe a “simpler” (usually more difficult) addition would be to account for lattitude climate dependencies, where the north would be colder and the south warmer (or the other way around if you live in Australia 😉

    Finally, you could also create some dent’s cause by meteor impacts. These would generally create circular mountain ranges and atol-like islands. I recon this could be achieved by randomly lowering a cell and then adjust its neighbors, the reverse way you’ve started the islands in the beginning.


    1. Hi! Thanks for a comment. I can generate mountains, or even tectonics, the problem is how to do it in the easiest way, as this kind of processing is very resource consuming. And I have only about 300ms to generate the whole heightmap, while a good simulation will take seconds, if not minutes.

      As for climate. I will add a temperature gradient with 3 options available – Southern Hemisphere, Northern Hemisphere and Equator. Then I just need to apply the input temperature and scale it to the whole map using a gradient. It’s not hard to implement, but there are some issues with a balance.

      Interesting idea, good for d&d maps. Pits are already available, so you have an option to draw a dent. I expect some of them could be auto-generated as well.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s