I tried to document this as well as I could, just a little starter 3d project. It simply provides a block class and a quick snippet of code that generates noise onto which the blocks are mapped. It creates a nice, hilly effect

```
--# block
block = class()
function block:init(x,y,z,dim,tex,p)
-- you can accept and set parameters here
--use parameters to define all vertices needed to make a cube
self.verts={
vec3(x+dim/2,y-dim/2,z+dim/2),
vec3(x-dim/2,y-dim/2,z+dim/2),
vec3(x+dim/2,y-dim/2,z-dim/2),
vec3(x-dim/2,y-dim/2,z-dim/2),
vec3(x+dim/2,y+dim/2,z+dim/2),
vec3(x-dim/2,y+dim/2,z+dim/2),
vec3(x+dim/2,y+dim/2,z-dim/2),
vec3(x-dim/2,y+dim/2,z-dim/2)
}
--use parameter p to determine how much of image to crop out
self.tex={
vec2(0+p/2,0+p/2),
vec2(0+p/2,1-p/2),
vec2(1-p/2,0+p/2),
vec2(1-p/2,1-p/2)
}
--set up our actual mesh
self.m=mesh()
--put the verts in order into our mesh
self.m.vertices={
self.verts[1],self.verts[5],self.verts[3],
self.verts[3],self.verts[7],self.verts[5],
self.verts[1],self.verts[5],self.verts[2],
self.verts[2],self.verts[6],self.verts[5],
self.verts[2],self.verts[6],self.verts[4],
self.verts[4],self.verts[8],self.verts[6],
self.verts[4],self.verts[8],self.verts[3],
self.verts[7],self.verts[8],self.verts[3],
self.verts[5],self.verts[6],self.verts[8],
self.verts[5],self.verts[7],self.verts[8],
self.verts[1],self.verts[2],self.verts[4],
self.verts[1],self.verts[3],self.verts[4]
}
--put the texCoords into our mesh
self.m.texCoords={
self.tex[3],self.tex[4],self.tex[1],
self.tex[1],self.tex[2],self.tex[4],
self.tex[3],self.tex[4],self.tex[1],
self.tex[1],self.tex[2],self.tex[4],
self.tex[3],self.tex[4],self.tex[1],
self.tex[1],self.tex[2],self.tex[4],
self.tex[1],self.tex[2],self.tex[3],
self.tex[4],self.tex[2],self.tex[3],
self.tex[4],self.tex[2],self.tex[1],
self.tex[4],self.tex[3],self.tex[1],
self.tex[4],self.tex[2],self.tex[1],
self.tex[4],self.tex[3],self.tex[1]
}
--set the user-defined texture
self.m.texture=tex
--make sure there is no tint
self.m:setColors(255,255,255)
end
function block:draw()
-- Codea does not automatically call this method
--draw the mesh
self.m:draw()
end
function block:touched(touch)
-- Codea does not automatically call this method
end
--# Main
function setup()
--set up our height map
m={}
--set up our control variable
control=math.random(1,100)
--generate heightmap
for y=1,20 do
m[y]={}
for x=1,20 do
m[y][x]=block(x*20,noise(x/10,y/10,control)*100,y*20,20,"Cargo Bot:Game Area",0.1)
end
end
--initialize the y position
pos=0
end
function draw()
background(40,40,40)
--set perspective and field of view
perspective(45,WIDTH/HEIGHT)
--set the camera position, look values, and orientation
camera(0,pos,0, 200,0,200, 0,1,0)
--iterate through table and draw each element
for i,v in pairs(m) do
for a,b in pairs(v) do
b:draw()
end
end
--move upwards
pos = pos + 1
end
```