What algorithm to use for random terrain?

by Harry the hacker   Last Updated September 07, 2016 08:05 AM

(Please note, I am aware that the generation is not truly random and relies on mathematical equations, and that my language of choice is C++)

So I've been learning programming for a while now and I'm looking to make a top down 2D game. I want this game to generate random terrain pretty much like Dwarf Fortress but with sprites, however for this question let's just say that there just ASCII characters. I want it to generate mountains, rivers, inland lakes etc. I know of algorithms but have not been able to find a list of them all. The ones i know of are:

Perlin Noise, Diamond Square, Midpoint Displacement and some other minor ones.

However I don't know which one to use and struggle to find a good article on any of them. Is there one right for the job, or does it just come down to personal opinion? And if you can find a list of all the algorithms and maybe a good article on one it would really help. Thanks!

Answers 1

This is the code that generate this kind of terrain (background for my "platform" game): https://drive.google.com/open?id=0B5yRPbmIAqr0X2wwX1BwNTZZMHc

(I hate python so sorry if this is an horrible code, and english is not my main language, so be patient pls)

import sys
import random
import pprint
import math
w = 350 #width of the terrain
h = 350 #height "  "    "

sz = 10 #size of a tile

sz_x = w / sz
sz_y = h / sz
area = sz_x*sz_y

bkg = [[' ' for x  in range(sz_x)] for y in range(sz_y)] #initialinzing background matrix

plates = [' ', '/', '.', 'I', '#'] #tile types
#each plates has it own probability to be "spawned", the following array is
#defined as couples of (total_previous_probability + this_probability / 2, (this_probability / 2) ^2)
probability = [[2.5, 2.5**2], [35, 30**2], [72.5, 7.5**2], [85, 5**2], [95, 5**2]] #5, 60, 15, 10, 10
temp_probability = [0, 0, 0, 0, 0]
nm_plates = [0,0,0,0,0] #for debug purpose

def get_random_plate(temp_prob):
    plate = 0
    max_prob = 0
    i = random.randint(0, 100)
    for p in range(len(plates)):
       prob = -(i - probability[p][0])**2 + probability[p][1] + math.sqrt(temp_prob[p] / 9);
    if(prob > 0 and prob + temp_prob[p] > max_prob):
        max_prob = prob+ temp_prob[p]
        plate = p
return plate

#list of predefined point (x, y, types), you can make this random
#in the link you can see five different "big areas" of one types built around theese point
#you can have a lot more of this points, more points of the same time you
#have in a little area more this area will be filled with the type of that points
sp_point = [
[10, 10, 0],
[27, 5, 0],
[15, 25, 2],
[25, 25, 2],
[5, 29, 3],
[16, 16, 4],

def create_bkg(temp_prob):
for y in range(sz_y):
    for x in range(sz_x):
        temp_prob = [0, 0, 0, 0, 0]
        for p in sp_point:
            sqrDist = (x - p[0])**2 + (y - p[1])**2
            temp_prob[p[2]] += (area / (sqrDist + 0.1))**3

        plate = get_random_plate(temp_prob)
        nm_plates[plate] += 1
        bkg[x][y] = plates[plate]

def print_bkg():
    for y in range(sz_y):
        for x in range(sz_x):
        print ''    
    print '\n'

This generates the tile map, then I think you can create something like an height map: you read each tile of the matrix and "make it higher or lower" (I don't know how to say that) based on the surrounding tiles:

#pseudo code
if (this_tile_is_a_mountain) count mountain tiles in an area of x tile;
this_height += (number_of_mountain_tiles_found * x)^y / z
#and so on, same for lakes

In the code above you can edit some line to change the behaviour of the algorithm:

temp_prob[p[2]] += (area / (sqrDist + 0.1))**3 #you can change how temp_prob is computed

#more higher it is more "dense" will be the "one type" areas
#or you can reduce the effect it has on the result editing the following lines:
prob = -(i - probability[p][0])**2 + probability[p][1] + math.sqrt(temp_prob[p] / 9); #change this nine, remove the sqrt, add another sqrt sqrt(sqrt(x))
if(prob > 0 and prob + temp_prob[p] > max_prob): //add a here: sqrt(temp_prob[p])
    max_prob = prob+ temp_prob[p] //or add it here, or both
    plate = p

Just try

(I really need someone who can rewrite this in real english...)

September 07, 2016 09:26 AM

Related Questions

Generate cave like Terrain in 2D

Updated January 30, 2018 00:13 AM

Generation of a moon terrain

Updated May 08, 2017 21:13 PM

Procedural terrain generation is very slow

Updated February 13, 2019 20:13 PM