2024-04-17 A map generator for solo play

Inspired by @enfors@ttrpg-hangout.social quest for a random map generator that would work for solo-gaming, where the exploration roll happens as you enter a new hex and no overall map is known beforehand, I've been thinking of a Solo algorithm for Text Mapper.

Solo algorithm

Text Mapper

As always, my main issue with maps is river systems. I just can’t help it! 😅 The solo-gaming constraint makes this an interesting challenge because you can’t ever go back and redo a hex that’s been discovered.

The first problem was that I needed a model of how the map was going to be explored to simulate the key constraint. What I use is a biased random walk of ever increasing length that keeps starting in the middle of the map, where the "safe haven" is imagined to be. The random walk is biased in as much as it prefers to pick an unexplored hex, if possible.

Example explorations on the map.

When debugging, the numbers on the map represent the order in which the hexes are discovered, the coordinates and the altitude from 0 to 10.

Of course my algorithm still runs into impossible situations like rivers meeting in a local minimum that I can't fix because there are no take-backs. In those situations I have decided to place a cave entrance and would run it as an entrance into the underworld. Who wouldn't want rivers to disappear into the underworld‽

Examples: In the map above, when entering 1008 or 1405, river flow could turn out to be problematic since all the surrounding hexes have been explored and can no longer be changed.

Every hex has two extra data points:

1. altitude from 0 (the deep ocean) to 10 (the highest peaks)

2. optionally, a direction of water flow (where it goes to)

The strange part about this is that you cannot tell which hex is "up river" without actually going there and seeing whether this is where the water came from. If the next hex has no river then you followed a small creek that got smaller and smaller and finally it disappeared. If the next hex has a river that flows elsewhere, then you crossed a ridge and now you're in another valley.

When determining a random neighbour, roll a d6: 1 is north, 2 is north-east, 3 is south-east, 4 is south, 5 is south-west, 6 is north-west.

Here's how you start the map:

1. Pick a hex in the middle of the map. Assign it the altitude 5.

2. Roll a d6 for the *direction of the local river*. The starting hex always has a river.

3. Roll 2d6 and *adjust the altitude* (see below).

4. Use the same 2d6 result for the check whether the new hex has *water flow* (see below).

5. Now that altitude and water flow are known, determine the terrain (see below).

6. Use the same 2d6 result for the check whether the new hex has a *settlement or ruin* (see below). The starting hex always starts with a village.

7. Repeat steps 3 to 6 for the six hexes around the start hex.

8. When entering a new hex, repeat steps 3 to 6.

Adjust the altitude

The provisional altitude of the new hex starts out as the altitude of where you're coming from (no sudden changes).

The altitude of the new hex is adjusted based on the 2d6 roll made above.

1. If all the known hexes around the current hex are at altitudes 0–1, then the max altitude is 0 (deep ocean). No other factors come into play, so you can skip the rest of the altitude adjustment.

2. If there are neighbouring hexes with water flowing from there to the current hex, then their lowest altitude is the current's hex max altitude (because rivers don't flow up).

Take the 2d6 roll made above and look up the altitude change on the following table:

+-----+--------+
| 2d6 | Change |
+-----+--------+
|   2 |     -2 |
|   3 |     -1 |
| 4–9 | –      |
|  10 | +1     |
|  11 | +1     |
|  12 | +2     |
+-----+--------+

Apply the change to the provisional altitude and adjust for the maximum.

Example: You're entering a new hex from a hex with altitude 5. You know is that is has a neighbouring hex with altitude 4 that has a river going towards the same hex. The max altitude is therefore a 4. Roll 2d6. If you get a 2, the change is -2 and the new hex has an altitude of 5 - 2 = 3; otherwise it has an altitude of 4 because of the max and you don't need to bother with anything else.

A height map without the effects of water flow

Water flow

If the altitude of the new hex is 0, there is no water flow (deep ocean).

The new hex has water flow if any of the following is true:

1. if there is a river flowing from a neighbouring hex into the new hex;

2. if the altitude of the new hex is 1 (so that lakes can drain);

3. if the altitude is 2–8 and the 2d6 roll for altitude adjustment was a 5–8.

If so, determine the direction of the water, trying one of the following:

1. pick at random from the unknown neighbouring hexes and the known neighbouring hexes at a *lower* altitude with a river that doesn't end up in the new hex you're looking at (avoid circular rivers)

2. pick a random, known, neighbouring hex at the *same* altitude with a river that doesn't end up in the new hex you're looking at (avoid circular rivers)

3. or – "it's magic!" – just pick one from the neighbouring hexes (all of them at a higher altitude, of course) with a river that doesn't end up in the new hex you're looking at (avoid circular rivers)

4. finally, if all else fails, then it's an *entrance into the underworld* and the river ends right here!

Sadly, this algorithm doesn't tell you whether a newly discovered hex at altitude 1 is a sweet water lake or salty coastal waters. As mentioned above, this algorithm also doesn't tell you from which neighbouring hex a river comes from.

Terrain

Based on altitude and water flow, the terrain can be determined.

+----------+---------------------+----------+
| Altitude |     With river      | No river |
+----------+---------------------+----------+
|        0 | ocean               |
|        1 | coastal             |
|        2 | swamp               | desert   |
|        3 | swamp               | plain    |
|        4 | forest              | plain    |
|        5 | forest              | plain    |
|        6 | forested hills      | rough    |
|        7 | green hills         | hills    |
|        8 | mountains           |
|        9 | mountain or volcano |
|       10 | glacier             |
+----------+---------------------+----------+

In this context, a swamp is a forested wetland; rough are stony badlands, unfit for agriculture but possibly suited for goat nomads. Green hills are suitable for sheep farming and cattle grazing.

There's a 1-in-6 chance of a mountain being in fact a volcano. Roll 1d6 to find out.

Settlements or ruins

If this is the *starting hex*, the settlement is a village.

If the 2d6 roll for altitude adjustment was a 7, there might be a settlement or ruin in the new hex.

If the terrain is *forest* or *forested hill*, pick at random: village, ruin, tower, ruined tower, castle or ruined-castle.

If the terrain is *desert*, *swamp* or *green hills*, pick at random: ruin, ruined tower, ruined castle.

A map with rivers, terrain, and settlements

​#Text Mapper ​#Maps ​#RPG