Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Terrain generator replay

dave1707dave1707 Mod
in Code Sharing Posts: 9,725

Here’s an updated version of some code I wrote previously. It’s a terrain generator, best viewed in landscape mode. Run the code to create a random terrain that shows water, grass, dirt, and snow. Tap the restart icon to create another random terrain. If you create some terrain that you think is interesting, you can tap the > icon to show the print area. That shows values that can be hard coded to recreate that terrain anytime you run with them. I have values that are commented out that I thought created an interesting view. Just uncomment the lines and run it. If you come across one that’s interesting, just post the values.

viewer.mode=FULLSCREEN

function setup()
    assert(OrbitViewer, "Please include Cameras as a dependency")
    scene = craft.scene() 
    v=scene.camera:add(OrbitViewer,vec3(275,100,100), 500, 0, 2000)
    v.camera.farPlane=10000
    v.rx,v.ry=50,-40

    scene.voxels.blocks:addAssetPack("Blocks")
    dirtgrass = scene.voxels.blocks:new("DirtGrass")
    dirtgrass.setTexture(ALL, "Blocks:Dirt Grass")
    water = scene.voxels.blocks:new("Water")
    water.setTexture(ALL, "Blocks:Water")
    snow = scene.voxels.blocks:new("Snow")
    snow.setTexture(ALL, "Blocks:Snow")
    grass = scene.voxels.blocks:new("Grass Top")
    grass.setTexture(ALL, "Blocks:Grass Top")

    scene.voxels.visibleRadius=40
    scene.voxels:resize(vec3(30,1,30))          
    scene.voxels.coordinates = vec3(100,0,100) 

    offsetX=math.random(500)
    offsetZ=math.random(500)   
    dirtLevel=math.random(70,90)
    grassLevel=math.random(40,60)
    waterLevel=math.random(5,15)

    --offsetX=2
    --offsetZ=156    
    --dirtLevel=70
    --grassLevel=42
    --waterLevel=7

    output.clear()
    print("offsetX    "..offsetX)
    print("offsetZ    "..offsetZ)
    print("dirtLevel  "..dirtLevel)
    print("grassLevel "..grassLevel)
    print("waterLevel "..waterLevel)

    val=400
    m=1/val
    h=craft.noise.perlin()
    xx=0 
    for x=1,val do
        xx=xx+m
        zz=0
        for z=1,val do  
            zz=zz+m
            y=math.abs(h:getValue(xx+offsetX,0,zz+offsetZ))*150//1
            if y>127 then
                y=127-(y-127)
            end
            if y>=dirtLevel then
                scene.voxels:fill("Snow")
                scene.voxels:block(x,y,z)
            elseif y>=grassLevel then
                scene.voxels:fill("DirtGrass")
                scene.voxels:block(x,y,z)
            elseif y>=waterLevel then
                scene.voxels:fill("Grass Top")
                scene.voxels:block(x,y,z)
            else
                scene.voxels:fill("Water")
                scene.voxels:block(x,waterLevel,z)
            end
        end
    end
end

function update(dt)
    scene:update(dt)
end

function draw()
    update(DeltaTime)
    scene:draw()
end

Comments

  • edited October 24 Posts: 2,496

    @dave1707 - interesting, I remember that. Looks great from the top but as you scroll around you see the gaps from the side. Easy remedied, just make the blocks bigger. Also, intriguing as you see the slow progress of the display is that down to the creation loop in setup taking time and update just continually adds the expansions until it’s complete?

    Probably much faster on the new pads in particular the metal ones.

    p.s. is there a way to programmatically colour the Voxel blocks ?

  • dave1707dave1707 Mod
    Posts: 9,725

    @Bri_G The loop is complete way before the drawing. It’s like things are built up in memory and then the generation code reads it and draws it on the screen. I don’t fully understand what’s really happening.

  • Posts: 2,496
    @dave1707 - that is just what I'd expect. I wonder if Codea deals with the initial data then has to pass it on to Craft in suitable sized packages so the model is gradually built up.

    I did something with mesh which seemed faster, but cubes weren't involved.
  • edited October 25 Posts: 1,547

    Here’s a few sets of settings I found sort of interesting. Nothing jaw-dropping, just kind of neat. I added a parameter controller for switching between them.


    -- dave1707 terrain viewer.mode=FULLSCREEN function setup() assert(OrbitViewer, "Please include Cameras as a dependency") scene = craft.scene() v=scene.camera:add(OrbitViewer,vec3(275,100,100), 500, 0, 2000) v.camera.farPlane=10000 v.rx,v.ry=50,-40 scene.voxels.blocks:addAssetPack("Blocks") dirtgrass = scene.voxels.blocks:new("DirtGrass") dirtgrass.setTexture(ALL, "Blocks:Dirt Grass") water = scene.voxels.blocks:new("Water") water.setTexture(ALL, "Blocks:Water") snow = scene.voxels.blocks:new("Snow") snow.setTexture(ALL, "Blocks:Snow") grass = scene.voxels.blocks:new("Grass Top") grass.setTexture(ALL, "Blocks:Grass Top") scene.voxels.visibleRadius=40 scene.voxels:resize(vec3(30,1,30)) scene.voxels.coordinates = vec3(100,0,100) offsetX=math.random(500) offsetZ=math.random(500) dirtLevel=math.random(70,90) grassLevel=math.random(40,60) waterLevel=math.random(5,15) settings = { {title = "original", offsetX=2, offsetZ=156, dirtLevel=70, grassLevel=42, waterLevel=7}, {title = "multiple thin rivers", offsetX=2.5, offsetZ=2.5, dirtLevel=2.5, grassLevel=2.5, waterLevel=2.5}, {title = "big thick floating rivers", offsetX=0, offsetZ=0, dirtLevel=20, grassLevel=200, waterLevel=40}, {title = "neat mini-lakes and islands", offsetX=500, offsetZ=00, dirtLevel=90, grassLevel=60, waterLevel=15}, {title = "big & intricate waterways", offsetX=400, offsetZ=333, dirtLevel=40, grassLevel=60, waterLevel=15} } fontSize(fontSize()*1.5) fill(255) title = settings[1].title generateFrom(settings[1]) parameter.integer("settingsSet", 1, #settings, 1, function(value) clear() generateFrom(settings[value]) title = settings[value].title end) end function clear() scene.voxels:fill( 'name', 'empty') scene.voxels:box(vec3(0,0,0), vec3(400, 400, 400)) end function generateFrom(settings) local offsetX, offsetZ, dirtLevel, grassLevel, waterLevel = settings.offsetX, settings.offsetZ, settings.dirtLevel, settings.grassLevel, settings.waterLevel val=400 m=1/val h=craft.noise.perlin() xx=0 for x=1,val do xx=xx+m zz=0 for z=1,val do zz=zz+m y=math.abs(h:getValue(xx+offsetX,0,zz+offsetZ))*150//1 if y>127 then y=127-(y-127) end if y>=dirtLevel then scene.voxels:fill("Snow") scene.voxels:block(x,y,z) elseif y>=grassLevel then scene.voxels:fill("DirtGrass") scene.voxels:block(x,y,z) elseif y>=waterLevel then scene.voxels:fill("Grass Top") scene.voxels:block(x,y,z) else scene.voxels:fill("Water") scene.voxels:block(x,waterLevel,z) end end end output.clear() print(settings.title..":" .."\noffsetX "..offsetX .."\noffsetZ "..offsetZ .."\ndirtLevel "..dirtLevel .."\ngrassLevel "..grassLevel .."\nwaterLevel "..waterLevel) end function update(dt) scene:update(dt) end function draw() update(DeltaTime) scene:draw() text(title, WIDTH/2, HEIGHT*0.95) end
  • dave1707dave1707 Mod
    Posts: 9,725

    @UberGoober Those look really interesting. I keep running my code just to see what kind of terrain pops up. Nothing as interesting as yours so far.

  • Posts: 1,547

    I think my names for them might be more interesting than the actual terrains :)

  • Posts: 1,547

    Here’s a project and video showing each of the above terrains, plus a little bit of walking around in them.

    Btw the joystick code is adapted from @dave1707’s dual-joystick code, so this is kind of a Frankenstein’s monster of different bits of dave1707 programming. :)

  • dave1707dave1707 Mod
    Posts: 9,725

    @UberGoober Looks good.

  • edited November 26 Posts: 1,547

    Now updated to use third-person camera.

    It’s really at least a second or two of fun to play with, try it out!

Sign In or Register to comment.