How to get a seed and perlin noise /randomnumber in Python in BGE
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