I think the first problem I usually have is island formation. Specially if we want atolls, or a chain of islands. Are we going to model a hot spot like Hawaii? Or something like the Caribbean, or the Pacific Rim? How many hexes per island are we going to aim for? If it is going to be just three or four per island, then questions of altitude are moot. But if we want to generate islands like Cuba and Tahiti, the result would be very different.

If you want, you can copy and paste this description into Text Mapper and it should regenerate the map shown above.

The random tables look like this:

;mountain
1,the air up here is cold
1,snow fields make progress difficult
1,there is a hidden meadow up here, hidden from view from below
1,steep cliffs make progress practically impossible without climbing gear
1,nothing grows up here except for a few patches of lichen on gray rocks
...

“A map is a symbolic depiction emphasising relationships between elements of some space,” says Wikipedia. But Sophie Lagacé goes further than. In Mapping the Veins of a World she talks about the importance of water shaping the map, the importance of rivers and “a multitude of smaller streams flowing towards the river like blood vessels or veins in a leaf.”

I agree with the beauty and I importance of water! I spent way to much time writing the river and mountain code for my Alpine Map Generator – and the documentation view where I get an image of the various stages so that I can check how the water flows.

At the end of her blog post, Sophie adds: “To be truly useful, the map should have an impact on the adventures. Otherwise it’s just a page decoration, and all to often a mediocre one.”

And that got me thinking. My maps are a way to structure access to locales, to explain realms of influence, borders.

In my current game I encouraged people to transport goods along the major river, and to build a road, and fords are hard to find so perhaps in the future there will also be a bridge to be built. This is the slow backdrop developing because people need to spend gold for xp in the game, so infrastructure built by players is a thing.

But I haven’t progressed much further than that. A lack of timber wouldn’t affect the game, more swamps wouldn’t affect the game, control of a mountain pass wouldn’t affect the game and I feel it should – but I also don’t want to get bogged down in details.

Perhaps finding that balance between geography as backdrop and geography as an anchor for adventure is what I’m struggling to find. Perhaps I need to have a table for random monthly events based on the surrounding territories.

Summer and forests adds the possibility of a forest fire

Winter and lakes adds the possibility of creatures crossing the ice

Spring and rivers adds the possibility of flooding

Mountains and winter adds the possibility of avalanches cutting you off for months

Summer and swamps adds the possibility for disease striking the local settlement

And perhaps some rules that are always in effect:

There is always timber trade from forested areas along rivers to settlements without forests

Mountains in winter are impassable

I’d like to return to the question of usefulness of a map. What impact does it have on adventures?

Perhaps a look at the actual maps people use at their gaming table would help. Why am I not seeing a lot of people simply using Google Maps? I think that’s because it doesn’t highlight the things gamers need:

adventuring locales are not highlighted

modern settlements are not what many of us are looking for

I need simple terrain to describe the area: forests, rivers, mountains, not the fractal mix of reality

small but important features are missing: menhirs, stone circles, wells, statues – these all exist at different zoom levels, but at the table I just want a single map

So why not the opposite extreme: what are the benefits of a point crawl, a graph of interesting locations like in the old text adventures?

the edges of the graph can be labelled with the time it takes to travel from one node to the other

no time wasted counting hexes or squares or using a ruler

who cares about miles per hour, miles per day, whether horses are really faster than humans and all that?

given the question of how to travel from A to B it still provides all the interesting locations between A and B in the right order, and it provides alternative routes

Things that the graph doesn’t provide:

opportunities to get lost

a way to make short cuts because nobody really knows what lies between the nodes – it’s undefined

there is no way to zoom out and identify important strategic and economic positions based on geography; in a point crawl, you must decide upon these locations and create a node for them

This last point is perhaps the most interesting to me because it allows me to discover more details in an existing map. The map is itself more than the set of its elements. If there is a valley here and a valley there, then perhaps these are also spheres of political influence. If there is a forest here and a settlement there, then perhaps there is a constant flow of timber between the two.

When looking at a setting map or regional wilderness map these days, I ask myself how much of a difference this map would make at my table:

Are the distances important in my game?

Is the terrain important in your game?

Are rivers and mountain ranges important obstacles?

Are the locations mines, pastures, or forests important assets?

Is the distribution of settlements important in terms of politics?

Is there an opportunity to get lost, take risky short cuts, claim unsettled terrain?

The answers to these questions determine the amount of information I would like to see on a map.

I’ve been working on the Alpine map generator some more. It uses Text Mapper to render the output into an SVG image and it uses the Gnomeyland icons by Greg MacKenzie so it looks nice. Sadly, I’ve developed a pathetic obsession about getting it “right”. To illustrate my obsession and to help me fight it, let me document what I’m talking about. This is a “bug” I just fixed.

Here’s the old map:

What’s wrong you ask? I was confused by the canyon carved into the mountains from lake 17.04. I expected it to flow into 18.05. Let’s check the height map before lakes start flooding, looking for an outlet:

Why would the river flow from 16.03 (height 7) to 15.04 (height 9)? This makes no sense.

So I studied my debug logs:

Lake started with 1704
Candidates: 1704
Looking at candidate 1704
River now: 1704
A neighbor of 1704 is 1804 with target 1704
Adding 1804 to our lake because it empties into our lake; the river leading here: 1704 1804
A neighbor of 1704 is 1603 with target 1704
Adding 1603 to our lake because it empties into our lake; the river leading here: 1704 1603
A neighbor of 1704 is 1803 with target 1704
Adding 1803 to our lake because it empties into our lake; the river leading here: 1704 1803
A neighbor of 1704 is 1703 with target 1704
Adding 1703 to our lake because it empties into our lake; the river leading here: 1704 1703
A neighbor of 1704 is 1705 with target 1704
Adding 1705 to our lake because it empties into our lake; the river leading here: 1704 1705
A neighbor of 1704 is 1604 with target 1704
Adding 1604 to our lake because it empties into our lake; the river leading here: 1704 1604
Candidates: 1804 1603 1803 1703 1705 1604
Looking at candidate 1804
River now: 1704 1804
Adding lake 1805 to our candidates: 1603 1803 1703 1705 1604 1805
A neighbor of 1804 is 1905 with target 1805
Adding 1905 to our lake because it empties into our lake; the river leading here: 1704 1804 1905
A neighbor of 1804 is 1904 with target 1803
Adding 1904 to our lake because it empties into our lake; the river leading here: 1704 1804 1904
Candidates: 1805 1603 1803 1703 1705 1905 1604 1904
Looking at candidate 1603
River now: 1704 1603
A neighbor of 1603 is 1602 with target 1702
Adding 1602 and 1702 to our lake, but need to explore
We flowed back into the lake via 1704 1603 1602 1702 1703
... 1702 is a new candidate with river: 1704 1603 1602 1702
... 1602 is a new candidate with river: 1704 1603 1602
Back at 1603 with river 1704 1603
A neighbor of 1603 is 1504 with target 1505
Adding 1504 and 1505 to our lake, but need to explore
Adding 1506 to our lake and keep exploring
Adding 1606 to our lake and keep exploring
Adding 1707 to our lake and keep exploring
Adding 1807 to our lake and keep exploring
Adding 1808 to our lake and keep exploring
Adding 1909 to our lake and keep exploring
Adding 2009 to our lake and keep exploring
Adding 2010 to our lake and keep exploring
Adding 2110 to our lake and keep exploring
Adding 2210 to our lake and keep exploring
Adding 2211 to our lake and keep exploring
Adding 2212 to our lake and keep exploring
Adding 2313 to our lake and keep exploring
Adding 2413 to our lake and keep exploring
Adding 2514 to our lake and keep exploring
Adding 2614 to our lake and keep exploring
Adding 2715 to our lake and keep exploring
Adding 2716 to our lake and keep exploring
Adding 2816 to our lake and keep exploring
Adding 2817 to our lake and keep exploring
Adding 2918 to our lake and keep exploring
Adding 2919 to our lake and keep exploring
Adding 3019 to our lake and keep exploring
Adding 3120 to our lake and keep exploring
Adding 3220 to our lake and keep exploring
We left the map via 1704 1603 1504 1505 1506 1606 1707 1807 1808 1909 2009 2010 2110 2210 2211 2212 2313 2413 2514 2614 2715 2716 2816 2817 2918 2919 3019 3120 3220
Arrows for 1704 should now point to 1603
Arrows for 1603 should now point to 1504

The key is the list of candidates after looking at the first round of neighbors: 1804 1603 1803 1703 1705 1604. These are sorted by height, 16.04 is last, which is great. But it also means that 16.03 (wrong direction: east into the mountains) is the equivalent of 17.05 and 18.04 (south east, towards lake 18.05).

Clearly, I needed a better sorting algorithm for the next candidates to look for: the candidates at the same level needed to be sorted by their lowest neighbor which had not already been looked at.

A bit later:

Lake started with 1704
Candidates: 1704
Looking at candidate 1704
River now: 1704
A neighbor of 1704 is 1803 with target 1704
Adding 1803 to our lake because it empties into our lake; the river leading here: 1704 1803
A neighbor of 1704 is 1804 with target 1704
Adding 1804 to our lake because it empties into our lake; the river leading here: 1704 1804
A neighbor of 1704 is 1705 with target 1704
Adding 1705 to our lake because it empties into our lake; the river leading here: 1704 1705
A neighbor of 1704 is 1703 with target 1704
Adding 1703 to our lake because it empties into our lake; the river leading here: 1704 1703
A neighbor of 1704 is 1603 with target 1704
Adding 1603 to our lake because it empties into our lake; the river leading here: 1704 1603
A neighbor of 1704 is 1604 with target 1704
Adding 1604 to our lake because it empties into our lake; the river leading here: 1704 1604
lowest neighbor of 1703 is 1702
lowest neighbor of 1703 is 1702
lowest neighbor of 1703 is 1702
Candidates: 1804 1705 1703 1803 1603 1604
Looking at candidate 1804
River now: 1704 1804
Adding lake 1805 to our candidates: 1705 1703 1803 1603 1604 1805
A neighbor of 1804 is 1905 with target 1805
Adding 1905 to our lake because it empties into our lake; the river leading here: 1704 1804 1905
A neighbor of 1804 is 1904 with target 1803
Adding 1904 to our lake because it empties into our lake; the river leading here: 1704 1804 1904
lowest neighbor of 1703 is 1702
lowest neighbor of 1703 is 1702
lowest neighbor of 1703 is 1702
Candidates: 1805 1705 1703 1905 1803 1603 1604 1904
Looking at candidate 1705
River now: 1704 1705
A neighbor of 1705 is 1706 with target 1707
Adding 1706 and 1707 to our lake, but need to explore
Adding 1807 to our lake and keep exploring
Adding 1808 to our lake and keep exploring
Adding 1909 to our lake and keep exploring
Adding 2009 to our lake and keep exploring
Adding 2010 to our lake and keep exploring
Adding 2110 to our lake and keep exploring
Adding 2210 to our lake and keep exploring
Adding 2211 to our lake and keep exploring
Adding 2212 to our lake and keep exploring
Adding 2313 to our lake and keep exploring
Adding 2413 to our lake and keep exploring
Adding 2514 to our lake and keep exploring
Adding 2614 to our lake and keep exploring
Adding 2715 to our lake and keep exploring
Adding 2815 to our lake and keep exploring
Adding 2816 to our lake and keep exploring
Adding 2917 to our lake and keep exploring
Adding 2918 to our lake and keep exploring
Adding 2919 to our lake and keep exploring
Adding 3019 to our lake and keep exploring
Adding 3120 to our lake and keep exploring
Adding 3220 to our lake and keep exploring
We left the map via 1704 1705 1706 1707 1807 1808 1909 2009 2010 2110 2210 2211 2212 2313 2413 2514 2614 2715 2815 2816 2917 2918 2919 3019 3120 3220
Arrows for 1704 should now point to 1705
Arrows for 1705 should now point to 1706

1804 1705 1703 1803 1603 1604 is the correct sorting order. 18.04 and 17.05 are at the front and the southern passage is discovered.

Notice my additional debug message I needed to check that for hex 17.03 the neighbor 17.04 is not checked. It would be the lowest neighbor indeed but we have already looked at it, so we need to ignore it. By the time we’re looking at 17.03, only the three northern hexes are options and 17.02 is indeed the lowest neighbor.

So now, since 18.04 and 17.05 are equally likely, the algorithm picked 17.05 and lake 17.04 doesn’t flow into lake 18.05 but their rivers meet in 17.06 and I think the map is much better, now. Here’s the corrected water flow map:

And with this correction, the final map also looks different. No more canyon into the mountains!

Now I get the urge to draw lines indicating the water divides. Noooo!

And just in case I make further changes to the algorithm, here’s what the application would generate right now for this width, height, and seed.

☯

Time passes and I’ve spotted another problem in the map above. Take a look at lake 34.05 which drains through one of the highest peaks in the area, 35.07. How on earth did that happen?

We need to look at the earlier maps again. Before the flood processor kicks in we can already see that any water on the peak 35.07 will immediately drain into lake 37.09.

So, the algorithm goes:

look at all the neighbors of 34.05. None look very exciting, they all drain back into 34.05.

all its neighbors drain back into the lake with the exception of our peak, 35.07; and with that, we found our lake 37.09

looking at all our candidates, lake 37.09 looks like the most promising, since it lies lower than any of the candidates

And that explains it. The problem seems to be that once we are looking at a candidate like 34.06, we’ll evaluate all its neighbors, even the very high ones like 37.09, even if a candidate of similar height like 35.05 has a much better neighbor like 36.05 which would drain off to the north west.

If you follow the link, you’ll get a random 20x10 hexmap using the new map generator, with the old SVG framework, and using the same old map icons by +Greg MacKenzie.

The source of your map is in the SVG file, as a comment. Alternatively, use the following link to generate a map description and hit the submit button to render it. If you like it, go back and save the map description:

There are still some things I think are annoying which is why I’ve left the “height” labels in as I need to think about this some more.

The river being painted over settlements looks bad, it should perhaps go between the hex background color (such as green) and the icons (i.e. below the forest and below the thorp). I’m not sure how good this looks if I’m using a road instead of a river but there you go. (Fixed!)

There are a few more icons I think of using. What about large towns, cities, shrines? No bushes, I think. Where do single trees come in? Where to place a keep? What about using more colors, ocre and sienna maybe? The complete list of icons and colors can be seen in the Gnomeyland example.

Also, anybody spotting stuff that defies explanation? Sometimes a river will drain to one side of a ridge – sometimes even appear to flow along side a lowland before turning away – and that is annoying. Perhaps these are opportunities to generate gorges?

I think there needs to be a more deliberate spacing of the settlements. “Random” results in random clustering which makes no sense, I think. (Fixed!)

Anybody interested in talking about the algorithm I used? I didn’t put it into words but I might if you want to talk about it and prefer not to see any Perl code… And I definitely need to add a link to this somewhere in the web app.

Updates

trails now connect settlements, if within two hexes, three at most

cliffs now separate higher altitudes from lower altitudes if the altitude difference is 2 or more

I’m hoping that cliffs make waterfalls obvious.

I still keep thinking about a way to add shadows and lighting like Swiss Topographical maps have it. Take a look at this nearby hill. Note how subtle shadows indicate altitude changes without you having to read the altitude lines.

Now compare it with this prototype:

I don’t think I like it. Light is basically assumed to come from the east, and if the neighboring hexes are higher up or further down, a little shadow is cast. And yet, something is off. The entire thing is too busy. Are the shadows too deep? Is the problem that these are polygons instead of fuzzy shadows? I tried using two different shades of light and dark so that it would look more organic but it didn’t help. Is it because we can skim over multiple hexes with out eyes and thus if A < B < C then it is not enough that C cast a shadow on B and B casts a shadow on A, do we expect that all of B lies in shadows?﻿

I’ve been working for many hours every day, working on better river flows, or basically better flooding of lakes and rivers cutting through higher surrounding areas searching for a passage, creating canyons as they cut through the land.

Today I rewrote Text Mapper to be a Mojolicious application. I hope the important URLs still work exactly as they used to, so if you’re using Text Mapper as part of an application of yours, you should be fine. If not, let me know and I’ll see what I can do about it.

Another big step forward are the examples on the Text Mapper Help page. You can click on the links to see the examples, live. This makes me very happy.

These days, I use Text Mapper to maintain the player’s map for my Greyheim campaign. You can see it on the Greyheim Region page.

The reason I rewrote the application was that I actually wanted to write a new algorithm to generate maps – maps that would look like Swiss maps: rivers, ranges of hills and mountains, passes, all of that.

(If you click the Randomlink then you won’t be able to get back to the text that generated it all – you’ll have to look at the page source and at the very end you’ll find the text that generated the map in a comment, just in case.)

To get a feel for the icons available, do the following in another tab:

Campaign Wiki Bonus: If you can find a way to store your text describing the map online, then your map will be live – you can change the text and reload your map, and it will have changed as well. For one of my campaigns, for example, I keep the text on on a page, and I use the link to the raw text of that page to generate the actual map.

Dropbox: If you store your map in a public (!) text file you can edit the map and regenerate the map on demand. Here’s the text file for my current map.

I can just paste include https://dl.dropboxusercontent.com/u/2749916/Greyheim.txt into the Text Mapper box, or

Text Mapper also includes a random wilderness generator using Erin D. Smale’s algorithm (Part 1 for the terrain, Part 2 for the encounters). Currently I’m only supporting major encounters 1 to 3: settlements, fortresses and religious orders. Please note that these will be rare. Not every random map will contain one of these.

I also added agriculture. If a settlement is built on a plains hex, that hex is colored like soil or light soil. If the settlement is not built on a plains hex, or if it is a large town or a city, then a neighboring plains hex will be changed to soil or light soil colored fields.

À propos random maps: A few days ago I added this random maps feature. It allows you to keep reloading the page until you like what you see. You can always save the result as a .svg file and keep editing it using Inkscape. If you want to tweak it online, however, you need the actual map data. It’s available from the page source. At the end of the SVG, you will find the map data in a comment like this one:

Comments

Add your comment here:

Please make sure you contribute only your own work, or work licensed under the GNU Free Documentation License. Note: in order to facilitate peer review and fight vandalism, we will store your IP number for a number of days. See Privacy for more information. See Info for text formatting rules. You can edit the comment page if you need to fix typos. You can subscribe to new comments by email without leaving a comment.