Map Generator with Rivers (mapgen_rivers v1.0)
This is a map generator I have been developing since April 2020 (my "lockdown project"...), that aims at being as realistic as possible.It introduces a mapgen approach that is different from usual procedural noise-based mapgens. The concept is to simulate surface geological phenomena like river flowing and erosion, using physical equations, while other mapgens generally use noises to empirically mimick landforms.
It generates rivers whose behaviour is close to real-life: they flow strictly downhill, and combine together to form wider rivers, until they reach the sea. Another notable feature is the possibility of large lakes above sea level (in fact any enclosed depression will form a lake).
The mod pre-generates the map at first start of a world, by creating something that I call a "grid", that is stored in the world folder as raw data, and represents a downscaled map. It's the moment at which flow and erosion calculations are at play, because they need to act on the full map (since they can have unpredictable distant effects). During actual map generation, the grid is upscaled (15x by default) and smaller-scale features are added with noise.
Pre-generation used to be done with a separate Python program, but it has been rewritten in Lua for version 1.0 (July 2021).
(pictures are outdated but the concept is still the same)
Pre-generation: Initial and final topography for a tiny 50x50 grid.
Map generation on Minetest: using this grid, with simplest possible settings. The grid is upscaled: each grid cell becomes a 12x12 square, so the map is 600x600. Notice how the cell pattern is obvious on river angles:
Same map with twisting/distorsion on Lua side, and biomes, the cell pattern is practically hidden: Pre-generation:
- Initial topography is using Perlin noise
- Flow calculation: Water flow direction is determined at every point from local slope. Flow accumulation is computed in order to find rivers and their respective flux (depending on catchment area), and depressions are filled with lakes.
- River erosion simulation: Solves the equation E = K × D^m × S (Stream power law), that determines erosion rate E in function of water flux D (for "discharge"), downstream river slope S, and parameters K and m. This is a simplistic yet famous model, still widely used in geomorphological modelling.
- Diffusive erosion, for now only active on sea/lake floor. This type of erosion simulates landslides on the long term, and tend to hide smaller-scale features. It is a simple Gaussian blur.
- Isostatic equilibrium: compensation of loss/gain of weight by uplift/subsidence, only at large scale (using a large-windowed Gaussian blur). This avoids the case of mountain ranges being completely flattened by erosion. Instead, they tend toward an equilibrium.
- Grid twisting: The grid being a regular square grid, the generated rivers make unnatural square angles. This computation step allows to smooth their trajectory by giving every grid node an X/Z offset that locally minimizes the length of river sections. It computes the forces that would act on every grid node if the rivers were mechanical springs (and the strength of these springs depend on rivers fluxes).
- Horizontal distorsion using two 3D noises (one for each X/Z direction). They define for every point an horizontal vector determining an offset. This distorsion breaks the regularity of the grid (otherwise flagrant), but also nodes at different heights can have different offset vectors: the landscape can thus be sheared in random directions, allowing steep valleys/mountains to have very nice-looking overhangs (that would otherwise not be possible because all other calculations are strictly 2D).
- Biomes: complete biome system using the biomegen mod if present (that was at first supposed to be a part of the present project until I realized it might be of general interest), or a basic temperature and elevation system with grass and snow.
- Glaciers: in very cold areas, widened rivers made out of ice, to resemble glaciers. Optional and disabled by default.
- Spawn players at ground level
- Place rivers 1 node lower to avoid overflows
- Use physical equations derived from Manning formula to control rivers width and depth
- Add more small-scale features during mapgen (rocks, small hills, small ponds...)
- Replace base noise (the primordial terrain over which erosion is applied) by a more geologically realistic topography
- Implement variable erosion parameters
- Add more features during pregeneration, like faults, volcanoes, meteor craters... There is a big potential here, many things could be implemented and could give to every world and every place a different geological history.
- Harmonize settings so that all units are in Minetest nodes (some are still in grid nodes)
- Fix seed problems at pregen (lua not able to handle uint64)
- Put all settings at the same place, refactor settings.lua and create a separate file for default values
- Improve version detection and backward compatibility system
- Clean init.lua and move mapgen loop out of it
- Find a better serialization format for the grid
The first 4 screenshots use Ethereal as well.
Download
Latestv1.0.2
Browse on Gitlab
Dependencies: default (removed dependency in 1.0.2-dev)
Recommended: biomegen
--> biomegen was originally designed to be part of this project, until I realized it may have other uses.
License: GNU LGPL v3.0