This small work is to describe my experiences with generating maps for open source game Widelands. To get an idea visit https://www.widelands.org/maps/ and filter map by author ‘Tibor’ and ‘TiborB’ - both are me. My goal was and is to generate as realistic maps as possible. Part of my workflow is to import output of this map generation script (an txt file) into widelands editor. But this is out of scope of this my blog.
Diamond-square algorithm is great here, and very easy to implement. But if you look at real world terrain - local minimas are almost non-existent. I mean a complete valley completely encircled by slopes. The reason is that every point needs an water outflow way and is eventually connected to a sea that is generally lowest point on earth. With exception of few areas on the earth.
And diamond-square algorithm create local minimums and maximums as a feature.
What are basics of this algorithm:
We start with raw diamond square filling up the TERRAIN array
The water rains from sky as drops
The number of drops is defined (parameter of scrip is drops per pixel)
the lifetime of a drop is defined (parameter of scrip) as a number of iterations (epochs) and all drops live the same time
each drop moves independently
each iteration every drop “wake up” and looks if it can move downward
multiple drops can be on the same spot
TERRAIN is defined as 2D array and WATER is separate 2D array with count of drops per each field (pixel)
individual drop in a water column on a single point does not have own “elevation”, we presume it is always positioned on the top elevation = TERRAIN[x,y] + WATER[x,y]
Each drop initializes on random position and (as expected) increased water value in WATER 2D array
Each drop when evaporates (after expiration of lifetime) decreases the water level on water 2D array
When a drop moves it takes some soil with it if elevation difference is sufficient, so drop move changes WATER array always and TERRAIN array most of time
Amount of moved soil is derived from TERRAIN[x,y] + WATER[x,y] differences between initial and target point. As a rule, final point terrain+water height cannot be higher than final terrain+water on starting point
a drop can move only to one of 8 nearest points.
erosion process wraps (map wrapping is also feature of diamond-square)
exception to “each drop moved each iteration” - in fact only 3 drops from a single spot can move in each iteration. This is just a speed-up thing. Note that you can have water column high in hundreds.
You can have rivers visible, but for the game map I used threshold for WATER values to have actual lakes visible only. So individual drops and rivers are usually very thin and gets filtered out
- variations in soil hardness
- relation between evaporation and place of rain - simulation of a wind with static direction