How to get a seed and perlin noise /randomnumber in Python in BGE I am generating a basic terrain using 3 for loops.  It currently results in a large block of cubes composed of columns of cubes all of the same height, height meaning how many cubes high each column is.  I want to change the top of every column to make an overall terrain look.  I hope to use perlin noise to take the columns XY (horizontal) location and use it as a seed to get the height of that column of cubes.

I also hope to use an initial seed that changes the effect of each horizontal seed value as well and the ability to reproduce the final results by being able to enter the seed at start up, but it is not top priority right now, but I would appreciate if you would include that, if you know how.

I want to be using the horizontal position to be the seed to generate the height position with the perlin noise to determine how many cubes high each column should be.  Please include full code or at least a good functioning chunk of code.  Thank you for reading and your time.
Blender comes with the mathutils module, which has a whole host of functions for just this kind of thing:



Here's the script for the above demo. It's a little boilerplate-y, really the gist of it is just the section in the middle (iterate over each vertex, get value from 2D location of vertex, set Z location of vertex)

from bge import logic
from mathutils import noise

# a list of various noise functions with some default values
noise_functions = [
    lambda p: noise.cell(p),
    lambda p: noise.fractal(p, 1.0, 2.0, 8),
    lambda p: noise.hetero_terrain(p, 1.0, 2.0, 8, 0),
    lambda p: noise.hybrid_multi_fractal(p, 1.0, 2.0, 8, 0, 1),
    lambda p: noise.multi_fractal(p, .5, 2.0, 8),
    lambda p: noise.noise(p),
    lambda p: noise.ridged_multi_fractal(p, .5, 2.0, 8, 1, 0),
    lambda p: noise.turbulence(p, 8, True),
    lambda p: noise.variable_lacunarity(p, 1),

    #lambda p: noise.voronoi(p),
]

verts_per_tic = 100 # number of verts to move every logic tic
zoffset = 1 # sort of useable as a "seed" when distorting a 2D plane on the Z axis like this
scale = .5

def move_verts(cont):
    own = cont.owner

    for m_index in range(len(own.meshes[0].materials)):
        v_range = own.meshes[0].getVertexArrayLength(m_index)

        cvert = own.get("current_vert", v_range)
        noise_scale = own.get("noise_scale", 1)

        if cvert &lt; v_range:
            # iterate over verts in the current material of the current object
            for v in range(cvert, min(cvert + verts_per_tic, v_range)):
                vertex = own.meshes[0].getVertex(m_index, cvert)

                # get the XY position of the current vertex and scale it
                sample_pos = vertex.XYZ.copy().xy * scale

                # turn the 2D XY vector into a 3D vector
                sample_pos.resize(3)

                # set the Z component to a pre-defined constant
                sample_pos.z = zoffset

                # feed it to the current noise function
                height = own["noise_generator"](sample_pos)

                # set the vertex position
                vertex.z = height


                cvert += 1

            own["current_vert"] = cvert    
        else:
            # if we've moved all the verts according to the current function, then pick a new one
            iter = own.get("iterations", 0)
            if iter &gt;= len(noise_functions):
                iter = 0

            own["noise_generator"] = noise_functions[iter]

            # cycle through each noise function
            iter += 1
            own["iterations"] = iter

            own["current_vert"] = 0