Fantasy Map Generator, Explained

After reading this you will understand how a single seed becomes a whole continent: how layered noise builds terrain, how a radial mask forces land into the middle, how water flows downhill into rivers, and how temperature and moisture pick each biome.

Feed the generator one number and it hands you a coastline, mountain ranges, branching rivers, six or seven biomes and a scatter of named towns. Change the seed by one and you get a different continent with the same believable structure. The map is not hand-drawn and it is not fully random. It is a short chain of deterministic rules stacked on top of noise, and each rule is simple enough to check by hand.

This guide takes that chain apart. Every step below is arithmetic you could do on a single grid cell with a calculator, then repeated across the grid.

What the generator actually is

The core object is a height field: a grid of numbers, one per cell, each roughly between 0 and 1. Everything else reads off that field. Sea level is a threshold on height. Mountains are the high tail. Rivers follow the downhill gradient. Biomes come from height (which sets temperature) plus a second noise field (which sets moisture).

The height itself is fractional Brownian motion, usually written fBm. You sample a smooth noise function several times at doubling frequencies and halving amplitudes, then add the samples. Low frequencies give continents and gulfs. High frequencies give the crinkle of a rocky shore. Summing them gives a surface that looks rough at every zoom level, which is exactly the statistical property real coastlines have.

A "seed" is just the starting number for the pseudo-random generator that lays down the noise. Same seed, same map, forever. That is why you can share a seed with your players and everyone sees the identical world.

When to use it, and when not

Use it when you need a plausible world fast: a campaign setting, a novel's map, a wiki header, a placeholder for a game prototype. The output is internally consistent, which matters. Rivers reach the sea. Deserts sit where it is hot and dry. Ports sit on coasts. A reader who studies the map will not find a river running uphill.

Do not use it as a model of real geology or climate. It has no plate tectonics, no prevailing winds, no ocean currents, no rain shadow computed from mountain orientation. Moisture here is noise plus "are you near a river," not simulated weather. The map is a convincing artifact, not a forecast. If you want the honest version of climate classification, the tool uses a simplified Whittaker diagram, and that is where the resemblance to science stops.

The formula behind the terrain

The raw height at a point is a sum of noise octaves:

H(x,y) = \sum_{i=0}^{n-1} \left(\tfrac{1}{2}\right)^{i} \, \text{noise}\!\left(2^{i} x,\; 2^{i} y\right)

Here n is the number of octaves (often 5 or 6), i indexes them, 2^{i} is the frequency multiplier (lacunarity 2), and (1/2)^{i} is the amplitude falloff (persistence 0.5). The function noise returns a smooth value that you can normalise to 0..1. Each later octave wiggles twice as fast and contributes half as much.

To make a continent rather than a wall-to-wall landscape, multiply by a radial mask that fades to zero at the edges:

H'(x,y) = H(x,y) \cdot \left(1 - \left(\tfrac{r}{R}\right)^{p}\right)

where r is the distance from the map centre, R is the half-width, and p (say 2 to 3) controls how sharply the land drops off near the border. Cells past the edge go below sea level and become ocean. That single multiplication is why every seed gives you land in the middle and water around it.

Land is any cell with H' \ge s, where s is sea level. Raise s and the coastline floods inward; islands break off and the continent shrinks.

Reproducing the default map, one cell at a time

Take the demo defaults and follow a single cell near the centre. Suppose the four strongest octaves at this cell return normalised values 0.62, 0.48, 0.55 and 0.40.

  1. Weight each octave by (1/2)^{i}: 1.00, 0.50, 0.25, 0.125.
  2. Weighted values: 0.62, 0.48 * 0.50 = 0.240, 0.55 * 0.25 = 0.1375, 0.40 * 0.125 = 0.050.
  3. Sum H = 0.62 + 0.240 + 0.1375 + 0.050 = 1.0475. Divide by the total weight 1.875 to normalise: H \approx 0.559.
  4. The cell sits at 30% of the way from centre to edge, so r/R = 0.30. With p = 2 the mask is 1 - 0.30^{2} = 0.91.
  5. Masked height H' = 0.559 \cdot 0.91 \approx 0.509.
  6. Default sea level is 0.40. Since 0.509 \ge 0.40, this cell is land. It clears sea level by 0.109, so it is low coastal ground, not mountain.

Repeat that for every cell and you have the whole continent. A cell out at r/R = 0.9 would have mask 1 - 0.81 = 0.19, dragging even a high 0.559 down to about 0.106, well below sea level. That is the ocean rim.

The first octave carries most of the shape. Later octaves add fine detail at rapidly shrinking weight, which is why the surface is smooth overall but crinkly up close.

How rivers are carved

Rivers are not painted on. They are computed from the height field by the same logic hydrologists use. Two passes do the work.

First, flow direction. For each land cell, look at its eight neighbours and point the flow arrow at the lowest one. Every cell now drains to a single downstream cell, so water can only go downhill.

Second, flow accumulation. Process cells from high to low. Each cell starts with one unit of rain and passes its total to its downstream neighbour. A cell deep in a valley collects the sum of everything uphill of it. Draw a river wherever accumulated flow crosses a threshold T.

A(c) = 1 + \sum_{u \,\to\, c} A(u)

Here A(c) is the accumulated flow at cell c, and the sum runs over every upstream cell u that drains directly into c. Because tributaries merge into the cell below them, their flows add, which is why rivers grow wider downstream and join like real ones. Lower the threshold and you get a dense dendritic network; raise it and only the major trunks survive.

If your map looks like it has too few rivers, the issue is almost always the flow threshold, not the terrain. A high T hides every stream that has not yet gathered enough tributaries.

How biomes get assigned

Each land cell gets two numbers. Temperature falls with both latitude and altitude:

T_{cell} = 1 - |{\,\text{lat}\,}| - k \cdot (H' - s)

where \text{lat} runs from -1 at the poles to 0 at the equator, and k scales how fast high ground cools. Moisture is a separate noise field nudged upward near rivers and coasts. The pair (T_{cell}, M_{cell}) lands you in one box of a simplified Whittaker grid.

A rough Whittaker lookup: which biome a temperature and moisture pair selects
TemperatureLow moistureMedium moistureHigh moisture
ColdTundraTundraTaiga
CoolGrasslandForestTaiga
WarmGrasslandForestForest
HotDesertGrasslandJungle

A cell at temperature 0.85 (hot) and moisture 0.15 (low) reads as desert. Push its moisture to 0.9 and the same hot cell becomes jungle. That single flip, hot-and-dry versus hot-and-wet, is the most instructive control on the whole map.

Two sliders set temperature (0 cold to 1 hot) and moisture (0 dry to 1 wet). A dot moves across a Whittaker grid whose coloured cells match the table above, and a label names the biome under the dot. Drag temperature up at low moisture and watch tundra, grassland and desert appear in turn; drag moisture up at high temperature and watch desert become grassland then jungle.

Reading and interpreting a finished map

Read height first. Bright or high cells are mountains; the towns will avoid them. Trace a river from its thin headwaters to the fat trunk at its mouth: the mouth is almost always a town, because river mouths score high on the settlement rule. Coasts and fertile grassland score high too.

The town names come from a syllable engine, not a dictionary. Each style (Norse, Desert trader, and others) is a set of allowed syllables and joining rules, sampled with the same seeded generator. That is why Vorndalr and Skagfjord feel Norse while Al-Zahret feels like a trader town: the syllable pools differ, the machinery is identical.

A typical split at default settings. Raise sea level and the ocean bar grows while every land biome shrinks in proportion.

Common mistakes

The three failures below account for most maps that look wrong.

Treating sea level as terrain
Raising sea level does not add water to a fixed world. It reclassifies existing cells: land within 0.05 of the old threshold turns to sea. Expect coastlines to retreat and low isthmuses to drown.
Expecting real climate
There is no rain shadow, no wind. A desert can sit directly beside a jungle because their moisture noise values differ, not because a mountain blocked rain. That is a limit of the model, not a bug.
Confusing seed with style
The map style (atlas, parchment, heightmap) only changes colours and shading. The same seed produces the identical terrain, rivers and towns under every style. Change the seed to change the world.

Small changes to mountain scale or climate can shuffle biomes across the whole map, because they shift the temperature term for every cell at once. If you found a seed you love, note the exact settings too. A different mountain scale on the same seed is a different world.

Related tools

The terrain here is the same fBm noise that drives Flow-Field Particles, and its fractal roughness is what the Box-Counting Dimension Lab measures on curves like coastlines. For the pure fractal mathematics underneath, see the Mandelbrot Explorer. Town placement borrows from nearest-region logic you can watch directly in Voronoi & Lloyd Relaxation, and the tile-solver approach to procedural worlds appears in Wave Function Collapse. To see how flat maps distort a round world, try Map Projection Distortion.

Frequently asked questions

Why does the same seed always give the same map?

The seed initialises a pseudo-random number generator whose output is fully determined by its start value. Every noise sample, river threshold check and name draw reads from that one stream in a fixed order, so the whole map is reproducible. Share the seed and settings and anyone recreates it exactly.

Why do rivers never run uphill?

Each cell drains only to its lowest neighbour, and flow accumulates strictly downstream. A river is drawn along that downhill path once accumulated flow passes the threshold. The height field is fixed before rivers are computed, so water has nowhere to climb.

Can I get a world that is mostly ocean with scattered islands?

Yes. Raise the sea level. As the threshold climbs, only the highest cores of the continent stay above water, and the mask-thinned edges break into an archipelago. A sharper radial falloff exponent p speeds this up.

Is the climate model realistic?

Only loosely. It uses the real axes of the Whittaker diagram, temperature and moisture, but temperature is a simple function of latitude and altitude, and moisture is noise plus river proximity. There are no winds, currents or rain shadows. It produces believable maps, not weather.

Why did one biome vanish when I changed mountain scale?

Mountain scale changes altitude, and altitude enters the temperature term for every land cell. A larger scale cools the highlands enough to turn forest into taiga or taiga into tundra across a whole range at once. Small parameter changes have global effects.