Codea 3.9 (407)

@dave1707 - thanks for the suggestion, on running It gives the usual black screen with the utility/error window for a second or two. No printout then ‘crashes’.

@Bri_G Try running with collectgarbage() in the draw() function. That will keep memory usage low and will eliminate that if it still crashes.

@Bri_G Heres my version of the code. Try running it and see if it crashes as much as the original. Have you tried turning your iPad off then on.

viewer.mode=FULLSCREEN

function setup()
    assert(OrbitViewer, "Please include Cameras as a dependency")
    scene = craft.scene()
    v=scene.camera:add(OrbitViewer,vec3(80,0,80),600,0,10000)
    v.rx=30
    v.ry=30
    
    dirtLevel=math.random(45,80)
    grassLevel=math.random(15,45)
    waterLevel=math.random(5,15)
    xx,zz=math.random(50),math.random(50)
    generateArea()
end

function generateArea()
    scene.voxels.blocks:addAssetPack("Blocks")
    snow = scene.voxels.blocks:new("Snow")
    snow.setTexture(ALL, "Blocks:Snow")
    dirtgrass = scene.voxels.blocks:new("DirtGrass")
    dirtgrass.setTexture(ALL, "Blocks:Dirt Grass")
    grasstop = scene.voxels.blocks:new("Grass Top")
    grasstop.setTexture(ALL, "Blocks:Grass Top")
    water = scene.voxels.blocks:new("Water")
    water.setTexture(ALL, "Blocks:Water")
        
    scene.voxels:resize(vec3(100, 1, 100))
    scene.voxels.visibleRadius = 40
    scene.voxels.coordinates = vec3(10, 0, 10)
    scene.voxels:iterateBounds(vec3(0,0,0),vec3(255,1,255),generateVoxels)
end

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

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

function generateVoxels(x, y, z, id)
    perlin=craft.noise.perlin()
    height=math.abs(perlin:getValue(xx+x/200,zz+z/200,0))*80
    if height>=dirtLevel then
        scene.voxels:fill("Snow")
        scene.voxels:block(x,height//1,z)
        scene.voxels:block(x,height//1-1,z)
        scene.voxels:block(x,height//1-2,z)
    elseif height>=grassLevel then
        scene.voxels:fill("DirtGrass")
        scene.voxels:block(x,height//1,z)
        scene.voxels:block(x,height//1-1,z)
        scene.voxels:block(x,height//1-2,z)
    elseif height>=waterLevel then
        scene.voxels:fill("Grass Top")
        scene.voxels:block(x,height//1,z)
        scene.voxels:block(x,height//1-1,z)
        scene.voxels:block(x,height//1-2,z)
    else
        scene.voxels:fill("Water")
        scene.voxels:block(x,waterLevel,z)
    end    
end

@dave1707 @jfperusse - thanks for your version, both ran OK. But, I added the mem check routine to both and in your first the level ran up rapidly to 39000+ and continued to climb more slowly. In the second the level went up to over 35000 and continued to climb more slowly.

Both versions continued climbing after the terrain generation without any positional change by touch interaction. Is that what would be expected from a static unchanged terrain ?

Is there a memory leak in the Voxel routines which is exacerbated by the code from Creator27 ?

@dave1707 @jfperusse - found out what the issue was - IT WAS MEMORY as you mentioned and it was down to one line in the generate function

scene.voxels:resize(vec3(10^4, 1, 10^4))

At 10000 X 10000 voxels that’s a bit excessive. Works fine for me up to 1000x1000 but not sure what the limit is.

It does beg the question - how Codea memory is allocated and what is the best way to provide resources - local drive and folders or Dropbox. Can you read graphics from Photos? Do you have to minimise the number of development projects ?

How does Codea allocate it’s Pad granted memory?

I tend to keep all my resources locally graphics, sound code etc - can you arrange resources better to improve project development ?

I also have a lot of unfinished projects and downloads from the website present in the Codea folder.

@dave1707 @jfperusse @Creator27 - in an attempt to find my limit on the size of the terrain that I could generate using the terrain code from @Creator27 I created a voxSize variable and changed it progressively to get the value. Code below to save you time.


-- assert(OrbitViewer)
seed = math.random(1, 10^10)

function setup()
    -- Create a new craft scene
    scene = craft.scene()
    scene.camera:add(OrbitViewer, vec3(0, 0, 0), 10, 0, 100000000)
    scene.camera.farPlane = math.maxinteger
    voxSize = 8600
    generateArea()
end

function generateArea()
    --
    scene.voxels.blocks:addAssetPack("Blocks")
    local grass = scene.voxels.blocks:new("Grass")
    grass.setTexture(ALL, "Blocks:Dirt Grass")
    grass.setTexture(UP, "Blocks:Grass Top")
    grass.setTexture(DOWN, "Blocks:Dirt")
    local snow = scene.voxels.blocks:new("Snow")
    snow.setTexture(ALL, "Blocks:Snow")
    local sand = scene.voxels.blocks:new("Sand")
    sand.setTexture(ALL, "Blocks:Sand")
    
   -- scene.voxels:resize(vec3(10^4, 1, 10^4))
    scene.voxels:resize(vec3(voxSize, 1, voxSize))
    scene.voxels.visibleRadius = 40
    scene.voxels.coordinates = vec3(0, 0, 0)
    scene.voxels:iterateBounds(vec3(0, 0, 0), vec3(100, 1, 100), generateVoxels)
end

function update(dt)
    -- Update the scene (physics, transforms etc)
    scene:update(dt)
end

-- Called automatically by codea 
function draw()
    update(DeltaTime)
    
    -- Draw the scene
    scene:draw()	
    mem=collectgarbage("count")
    text(mem//1,WIDTH/2,HEIGHT-50)
end

function generateVoxels(x, y, z, id)
    local perlin = craft.noise.perlin()
    local height = perlin:getValue(x / 280, z / 292, seed)
    if height >= math.random(7, 8) / 10 * -1 then
        scene.voxels:fill("Grass")
    else
        if math.random(1, 10000) / height < 500 then
            scene.voxels:fill("Snow")
        end
    end
    if height >= .00001 then
        scene.voxels:fill("Sand")
    end
    scene.voxels:block(vec3(x, height * -56, z))
end

I found that a value of 8700 didn’t crash Codea but there were black areas in the terrain. Above that the terrain could become very small in size and sometimes decent size with missing voxels. I think the missing voxels mentioned in the other thread were as a result of getting too close to the memory limit.

Normally Voxel terrains use less visible sizes and, I suspect, built on the fly from an array to minimise the pressure on the graphics processor and speed up movement of the terrain.

I would be interested in feedback from other users who are willing to test the limits of their own Pads.

@Bri_G Using the above code I can go as high as voxSize = 10837 which gives me a bad_alloc error message.

The resize code gives you a chunk of blocks. A resize(1,1,1) will let you draw 16x128x16 blocks. A resize(100,1,100) will do 1600x128x1600 blocks which is more than enough. So my max resize value of resize(10836x1x10836) should let me draw a max size of 173376x128x173376 blocks.

@dave1707 - have you taken the project above that to see if it crashes as I described above?

I’m not sure which version you’re referring to, but I haven’t had any version crash on me. See my above post where I describe the resize command.

@Bri_G If you want to mess around with memory, resize, and crashes, try this code. This draws a 300x128x300 cube of blocks. You can change the resize values and the 300 in the iteratebounds line of code to change how many blocks are drawn. It takes awhile to draw the cube, so be patient.

viewer.mode=FULLSCREEN

function setup()
    assert(OrbitViewer, "Please include Cameras as a dependency")
    scene = craft.scene()
    v=scene.camera:add(OrbitViewer,vec3(10,70,10),200,0,10000)
    v.camera.farPlane=10000
    v.rx=30
    v.ry=30

    generateArea()
end

function generateArea()
    scene.voxels.blocks:addAssetPack("Blocks")
    water = scene.voxels.blocks:new("Error")
    water.setTexture(ALL, "Blocks:Error")
    
    scene.voxels:resize(vec3(20,1,20))  -- size of 320x128x320
    scene.voxels.visibleRadius=40
    scene.voxels.coordinates = vec3(10,0,10)
    scene.voxels:iterateBounds(vec3(1,1,1),vec3(300,128,300),generateVoxels)
end

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

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

function generateVoxels(x,y,z)
    scene.voxels:fill("Error")
    scene.voxels:block(x,y,z)
end

FYI, from what I can see in Codea, a Voxel Block takes 64 bits of memory. With the default 10^4 x 10^4 size, we can easily calculate that this will take at least 800 MB in memory. On top of that, we must account for textures loaded in memory (on iOS devices, and likely on all mobile devices, they use “unified” memory which means the memory is shared between the CPU and the GPU).

For reference, the maximum RAM we can allocate on an iPad 9.7" (which has 2GB of RAM) is around 1400 MB (see iphone - ios app maximum memory budget - Stack Overflow). However, we have to take into account that Codea uses some of that RAM already (e.g. code editor buffers, etc.).

Hello everyone!

Build 403 introduces a major improvement to Air Code: auto-completion!

See below for a few screenshots showing this improvement.

Let us know what you think about it if you try it out!

Looking forward to your comments and suggestions.

color() completion and picker

font() and sprite() completion


Control structures snippets

autocomplete_4

objc completion

Auto-documentation using - - -

2 Likes

@jfperusse - loaded up 403, after a little fiddling got it up and running. Like the file access, ran a few small projects by running the main.lua file.

Had a few issues which may be down to slow response on the iPad. Got the initial screen up but button response slow on pad. Also, not sure about how to close a project. Managed to get a blank screen up with parameter window open and buttons on bottom but touch not responding - or maybe a slow response. Eventually crashed for me and reported via crash dialogue in usual way.

Apart from those issues it’s starting to look like a neat way to develop.

Hi @Bri_G! Glad you got it working, and thanks for the feedback :slight_smile: You can have files from different projects opened in VSCode, but only one project running on the iPad. Though you can quickly stop the currently running one and launch another one by simply switching to one of its files.

Before getting the crash, how many different projects had you opened, and were these big projects? I’ll see if I can find the crash report.

Thanks!

@jfperusse - the projects I ran were small to moderate size.

I ran them by highlighting main.lua and using the blue run button on the bottom of the VSCode window to run them.

Edit: forgot another possible contributor - I was recharging my iPad at the same time via an external drive with suitable usb charging available.

Important AirCode update coming in the next build: Codea Reference added to the sidebar.

Here’s a preview, I’ll update the title here once the build is available.

(The preview was recorded with a device set to French, which shows how the new Codea Reference will use the same language as the device it is connected to, if the language is available in Codea.)

1 Like

Build 405 is now live with the new Codea Reference section as well as displaying of Lua errors directly in VSCode.

1 Like

@sim @john @jfperusse I don’t know if I’m doing something wrong or there’s a problem with Codea. Here’s a stripped down version of a program. What happens is when the program starts, sometimes it displays the graphics and other times it just shows a blank screen. Run the program and slide your finger back and forth to move the grass. Moving the grass has nothing to do with the problem. Exit the code and run it again. Most of the time it shows the graphics, but sometimes it won’t even after multiple times of restarts. Sometimes I have to exit Codea to get it to work. Sometimes when it shows a blank, I can exit the code and run a different program and that one will show a blank screen.

Does anyone else show the blank screen or is it just me.

viewer.mode=FULLSCREEN

function setup()  
    fill(255)   
    dx=0
    rectMode(CENTER)    
    tab={} 
    for z=1,40 do
        table.insert(tab,rec(40*z,0))
    end    
    p1=physics.body(CIRCLE,25)
    p1.x=WIDTH/2
    p1.y=300
    r1=rec(40,40)
    r2=rec(1600,40)
end

function draw()
    background(0)
    pos=vec2(WIDTH/2-p1.x,200)
    translate(pos.x,pos.y)
    for z=1,#tab do
        sprite(asset.builtin.Platformer_Art.Block_Grass,tab[z].a.x,tab[z].a.y,40,40)
    end  
    r1:draw()  
    r2:draw()
    ellipse(p1.x,p1.y,50)
    sprite(asset.builtin.Tyrian_Remastered.Button_Glow,p1.x,p1.y,50,50)
    vel=p1.linearVelocity
    p1.linearVelocity=vec2(vel.x,vel.y)
    if math.abs(vel.x)<.1 then
        dx=0
    end
end

function touched(t)
    if t.state==CHANGED then
        dx=dx+t.deltaX
        p1.linearVelocity=vec2(dx,0)
    end
end

rec=class()

function rec:init(x,y)
    local a
    self.a=physics.body(POLYGON,vec2(-20,-20),vec2(20,-20),vec2(20,20),vec2(-20,20))
    self.a.x=x
    self.a.y=y
    self.a.type=STATIC
    return a
end

function rec:draw()
    rect(self.a.x,self.a.y,40) 
end
2 Likes

Hi @dave1707, we have a similar issue in our backlog which we can reproduce in the Flappy sample, and I believe this is due to the loading of PDF assets. @sim, had your started looking into this issue?

@sim @john @jfperusse I changed my code to read the assets into variables in setup and use the variables in draw. I couldn’t get the blank screen to happen after that. Maybe that’s how it should be done anyways.