Codea runtime quits my app after some time [FIXED with Codea 2.3.3]

@Ignatz Showing memory usage was the first thing I tried. My max memory usage gets to 1248.43 and then goes back down to about 400+ and never gets back to the max memory. It keeps cycling from lower that the max memory and about 400+.

@Ignatz: Thanks for your answer. Doing some manual garbage collection was one of the questions in my OP. Anyhow, had never to do this before the mentioned updates. I’ll try and come back with the results.

@HeiKoDea - the other thing I would definitely do is to use meshes. Meshes are highly recommended as soon as you get past a few sprites.

When you use sprites, I believe Codea has to create a mesh for each of them and then destroy it afterwards, which is 60,000 mesh creations and destructions per minute.

If you create a mesh for each image, then you only ever have 4 meshes, which never get destroyed, and you simply have to translate to each screen position and draw the mesh. You will probably find you don’t need garbagecollection at all.

@Ignatz @HeiKoDea The code is still running (20 min) and my max memory usage is still 1248.43 . Will let it keep running.

@Ignatz @HeiKoDea The code finally crashed. Took me to the iOS screen. Was able to get back into the screen of the program. Memory usage showed 770. When I touched the screen it exited to the Codea home screen. It ran for about 25 minutes before it crashed. The only problem is that’s too long in between crashes to keep trying things.

Increased the random sprites from 1000 to 5000. max memory only went to 1251 and cycled approx 1180 to 450. I don’t think it’s a Codea memory issue. I was also watching a monitor app and noticed that my free memory was sometimes really low, about 32 MB but would go back up. I wonder if IOS free memory eventually got too low.

@dave1707 - I think the real solution is to use meshes

As an aside - have you seen all the parameters for garbagecollection? I didn’t know it had any.

http://www.tutorialspoint.com/lua/lua_garbage_collection.htm

@Ignatz I knew about all the parameters, but the only one I ever used was “count”. Meshes might be a solution, but memory wasn’t that high and it was cycling the way it should. I don’t think that’s the problem, I think it might be an IOS memory issue.

but an iOS memory issue is what meshes will solve!

Just 4 meshes vs 60,000 new meshes per second, is no contest…

@Ignatz, @dave1707: Thanks for digging into it. I’ll try Ignatz’ recommendation using meshes. Sounds plausible to me so far. Anyhow, I’m using much lesser sprites in my original app (20 to 180) and wonder why it crashes now and hasn’t crashed before the updates.

PS: Found out using my test-code above for some time might have much more effect than any illegal substances to see colors and patterns… :smiley:

I’m still seeing spots in front of my eyes, I think I’m damaged for life!

Would love to see the copy/paste-rate after my PS above… :smiley:
(Are you OK, Dave?)

@HeiKoDea - this code seems to run about twice as fast as sprites. If you’re going to use hundreds of images, it’s best to put them in one mesh.

This is quite efficient with addRect and setRect (to adjust positions).

However, because meshes can only use one texture, this requires combining your images into one, and then setting texture coordinates to use the part of the image that you want. This is a problem because addRect and setRect assume the entire texture will be used for each rectangle.

What I’ve done in the code below is to calculate the texture coords and store them in a separate table, then after using setRect to reposition them in draw, I assign this table to be the texture coords of the mesh.

function setup()
    ---displayMode(FULLSCREEN)
    bgImg = readImage("Cargo Bot:Background Fade")
    tile = {
    readImage("Cargo Bot:Crate Blue 1"),
    readImage("Cargo Bot:Crate Green 1"),
    readImage("Cargo Bot:Crate Red 1"),
    readImage("Cargo Bot:Crate Yellow 1")
    }
    --combine all the images into one
    local w,h=tile[1].width,tile[1].height
    local img=image(w*2,h*2)
    --centre position of each image on our new image
    local p={vec2(w/2,h/2),vec2(w/2,h*3/2),vec2(w*3/2,h/2),vec2(w*3/2,h*3/2)}
    setContext(img)
    for i=1,4 do
        sprite(tile[i],p[i].x,p[i].y)
    end
    setContext()
    --create a single mesh
    --calculate texture positions at the corners of the 4 images
    local e={vec2(0,0),vec2(0.5,0),vec2(1,0),vec2(0,0.5),vec2(0.5,0.5),
              vec2(1,0.5),vec2(0,1),vec2(0.5,1),vec2(1,1)}
    --now the set of positions for each image
    texPos={
        {e[1],e[2],e[5],e[5],e[4],e[1]}, --bottom left
        {e[2],e[3],e[6],e[6],e[5],e[2]}, --bottom right
        {e[4],e[5],e[8],e[8],e[7],e[4]}, --top left
        {e[5],e[6],e[9],e[9],e[8],e[5]} --top right
        }
    m=mesh()
    m.texture=img
    m.w,m.h=w,h
    n=1000  --the number of images to display
    tp={}
    local k=0
    for i=1,n do
        u=math.random(1,4)
        local t=tile[u]
        m:addRect(-w/2,-h/2,w,h)
        --texture positions, store them outside the mesh
        for j=1,6 do
            k=k+1
            tp[k]=texPos[u][j]
        end
    end
    parameter.text("mem")
    parameter.number("FPS",0,60,60)
    tick,tickMax=0,20 --for garbage collection
end

function draw()
    background(40, 40, 50)
    sprite(bgImg, WIDTH/2, HEIGHT/2, WIDTH, HEIGHT)
    for i = 1, n do
        local x,y=math.random(1, WIDTH), math.random(1, HEIGHT)
        m:setRect(i,x,y,m.w,m.h) --adjust vertices
    end
    m.texCoords=tp --reset texture positions
    m:draw()
    mem=math.floor(collectgarbage("count"))
    tick=tick+DeltaTime --check if garbage needs collecting
    if tick>tickMax then 
        collectgarbage()
        print("collected")
        tick=0
    end
    FPS=FPS*0.9+.1/DeltaTime
end

@Ignatz: Wow, thanks for your effort! Will try it tomorrow and let you know. Nevertheless, this means to me changing my whole app which is based mostly on single graphics, because a command (sprite) isn’t reliable in Codea. Holy Cow.

well, you could just collect garbage with what you have

I meant to say, I was surprised to see memory also increasing with the mesh above…

@Ignatz the sprite command caches the meshes it creates, so I don’t think it’s quite as bad as " 60,000 mesh creations and destructions per minute."

But yeah, sprite is convenient when working quickly or performance isn’t an issue, meshes are the boss.

I would try the same destruction-testing of some test mesh code though (ie leaving it running for 200 minutes or whatever), before making wholesale changes to a project.

I would try simply collecting garbage first, to see if that fixes it

@yojimbo2000 - a couple of years ago, Simeon explained what was involved in a sprite call, and I reproduced it in a post (below). In another forum discussion, John says sprites are cached until memory runs low.

https://coolcodea.wordpress.com/2013/03/27/meshes-what-are-they/

I would try simply collecting garbage first, to see if that fixes it

+1

If there is any kind of moment where the state of play resets and a bunch of objects are destroyed, like a new level or whatever, that’s a good place to collectgarbage. Or you could try it every couple of seconds as suggested above.

I thought when I got up this morning and looked at this discussion, you guys would have the cause all figured out. Meshes might fix it, but what was the reason it crashed. I don’t think it was a Codea memory issue because memory usage didn’t get that high and memory was cycling OK on it own. Also, it wasn’t the Codea code that crashed because the screen was still there.