Howdy, Stranger!

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

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

edited March 12 in Questions Posts: 41

Yep, I know there might be many reasons after coding several 10k lines which perform many animations in my game but after trying a lot of debugging/optimizing my code, I found no solution to the following problem:

The Codea runtime quits my app after some time.
(It seems not Codea itself that crashes, it just quits my running app in Codea without any errors given)

My developing environment details:
• I'm developing on an iPad Air2 using BBEdit on OSX 10.9.5 via copy/paste to Air Code.
• This happens since around last quarter of 2015 when I updated from iOS 8.x to 9.x and Codea was also updated to the recent version ( 2.3.2(61) ). It never happened before these updates.
• No, I didn't verify if the problem goes away after compiling with recent Xcode, because I have not updated to latest El Capitan by now.

After hardly verifying my code for stupid mistakes, I'm simply lost now and hope to get some ideas from you guys:

• Did I missed some kind of manual garbage collection I should include in my code? (collectgarbage("count") returns always only +/- 1MB in my app)
• Could it be iOS 9.x which stops it because of power consumption? (I optimized my code carefully for this)
• Does anyone else has similar experiences?
• Any ideas whatever to try else?

Thanks a lot for your time and help,

Heiko

PS: Found https://codea.io/talk/discussion/7376/what-can-make-codea-just-crash-out#latest but couldn't resolve the problem with the provided comments.

Comments

  • IgnatzIgnatz Mod
    Posts: 5,396

    @HeiKoDea - as you will appreciate, it's extremely difficult to figure out your problem without seeing code that we can run outselves.

    Is it possible to create a minimal cut down version of your app that shows the behaviour, and which can be shared?

    Also, is the problem occurring in Codea itself on its own, Codea using AirCode, or after you transfer the code to Xcode?

  • Posts: 41

    @Ignaz: Thanks for your response.
    If you read carefully what I wrote above, you'll find out that it's not a code problem in my app. The problem appears since the mentioned updates.
    Thanks anyway,
    Heiko

  • Posts: 41

    To further refine: The quitting occurs under same app running conditions unexpectedly between 30 minutes and several hours. This makes it hard to track down.

  • Posts: 41

    Should it be considered as a bug in conjunction with iOS9.x and be posted better in the Bugs section?

  • Posts: 1,983

    it's not a code problem in my app

    How can you be so sure? I know it's tempting to blame the OS, the runtime etc, but 99% of the time, it's your own code.

    I would put it in Xcode, deploy it to an iPad, run it while tethered to the Mac, and see whether the Xcode diagnostics tab tells you anything.

    Do people really play iPad games for hours at a time tho? I'd say that as long as my position in the game is frequently saved, I wouldn't mind if an iPad app crashed after an hour's use. If I have to deal with an interruption, a FaceTime call or whatever, you can't count on the game's state persisting, so progress-saving is important.

  • Posts: 41

    @yojimbo2000: As I wrote above, I can be sure because it happens since the updates. Also I wrote that it's quitting between 30 minutes and several hours, which is not usual behavior for an app. And yes, of course my app saves the game states between levels. Again I wrote above that I currently can't update to latest Xcode to test by now and it wouldn't solve the quitting inside Codea anyhow. Thanks anyway for your comment.

  • dave1707dave1707 Mod
    Posts: 5,896

    One suggestion is to save the amount of memory used every so many minutes. Then when your app quits, you can see the amount of memory that was last used. If it's a high amount, then you know you have a memory leak. If not, then you can look for something else.

  • Posts: 1,983

    I can be sure because it happens since the updates

    And you haven't changed the code at all since then, and you definitely tested it for hours at a time before the updates?

  • Posts: 41

    @dave1707: Thanks for your suggestion. It can't be a memory leak. As I stated above my app uses just around 1MB. I'm already constantly reading the used memory and show it onscreen. Also even while a lot of animations happen, my code is optimized to rarely go below 55fps.

  • Posts: 1,983

    The only thing I had to tweak in my code when the last Codea update appeared was how certain shaders are declared.

  • Posts: 41

    @yojimbo2000: Yes, I haven't changed the code and I definitely tested it for hours before the updates. I don't use shaders. Thanks.

  • dave1707dave1707 Mod
    edited March 2016 Posts: 5,896

    @HeiKoDea Can you list the things you do. Do you use meshes or recursion or graphics, etc. It's hard to say what might be happening when we don't know what you're doing. You may be only using 1MB while your app is running, but it might spike just before it crashes. Since you know your upper memory limit, maybe you can save the size of memory used anytime it exceeds your upper limit.

    EDIT: By graphics, I mean stuff like setContext or large images, etc.

  • Posts: 222

    @HeiKoDea you can be sure that something has changed since the update. However, that does not mean that it is a bug in the update. It could still be a bug in your code which has exercised a perfectly legit change in Codea. The only way to be sure, unfortunately, appears to be to find a way to cause it quickly and every time, that is consistent with what the more complex program is doing.

    I had hoped that people knew some things one could do that might crash Codea, so that I could look into my code to see if I was doing any of them. Unfortunately, the discussion hasn't provided that information.

  • Posts: 1,983

    There used to be 1 or 2 things that reliably caused Codea to bail, but they've gradually been patched. Eg pointing the camera along the same axis as its up axis. I think that no longer makes Codea crash (but still shouldn't be done).

  • Posts: 41

    Thanks to all for your suggestions.

    @dave1707: There are no recursions nor meshes in my code. I use prepared .png graphics stored inside the project and animate them mostly with the juice library. The only .jpg is for filling the background, which is always animated by the acceleration sensor to have a kind of parallax effect. Most of the quitting occurs when the app is idle and has nearly nothing to work inside the draw() loop or anywhere else. Therefore a spike is very unlikely but I'll try your suggestion.

    @RonJeffries: I fully agree. I think the only way to find out is to write a small test app and let it run for a while. I'll let you know if I find something in the next days.

    @yojimbo2000: I don't use the camera in my app.

  • Posts: 41

    Some more details:

    • It's not Codea that crashes therefore I couldn't find any messages inside the iOS system logs. It's my app running inside Codea that jumps after a while to the iOS home screen. If I double click the home button the last screen of my app is shown in the list. Tapping it immediately quits the app showing the Codea home screen. After that I can use Codea without restarting and without errors.

    • Usually I don't run any other apps while in Codea. The only exception is sometimes the SystemMonitor app, which never showed any unusual memory/CPU/GPU usage.

    • I don't use any network connection code in my app.

    • The app is all about plane ol' 2D animated graphics. No rocket science.

  • Posts: 41

    Ok, here's a simple code example which crashes Codea in between 5 to 30 minutes:

    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")
        }
    end
    
    function draw()
        background(40, 40, 50)
        sprite(bgImg, WIDTH/2, HEIGHT/2, WIDTH, HEIGHT)
        for i = 1, 1000 do
            sprite(tile[math.random(1, 4)], math.random(1, WIDTH), math.random(1, HEIGHT))
        end
    end
    
  • IgnatzIgnatz Mod
    edited March 2016 Posts: 5,396

    that code crashes my eyes in about 10 seconds! :s

    (but it should make the problem easier to fix, now we have a working example to play with!)

  • IgnatzIgnatz Mod
    Posts: 5,396

    @HeiKoDea - I think I have a simple fix for you

    If you check memory usage, eg with collectgarbage("count"), you'll see it just keeps climbing as the program runs, and so running out of memory is the most likely cause of your problem.

    If you run collectgarbage(), the memory use (on my iPad) drops to about 400, before starting to climb again. So if you collect garbage (say) every minute, that should be enough to restrict memory usage and avoid the crashes.

  • dave1707dave1707 Mod
    Posts: 5,896

    @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+.

  • Posts: 41

    @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.

  • IgnatzIgnatz Mod
    edited March 2016 Posts: 5,396

    @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.

  • dave1707dave1707 Mod
    Posts: 5,896

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

  • dave1707dave1707 Mod
    Posts: 5,896

    @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.

  • dave1707dave1707 Mod
    Posts: 5,896

    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.

  • IgnatzIgnatz Mod
    Posts: 5,396

    @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

  • dave1707dave1707 Mod
    Posts: 5,896

    @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.

  • IgnatzIgnatz Mod
    Posts: 5,396

    but an iOS memory issue is what meshes will solve!

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

  • Posts: 41

    @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:

  • IgnatzIgnatz Mod
    Posts: 5,396

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

  • edited March 2016 Posts: 41

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

  • IgnatzIgnatz Mod
    Posts: 5,396

    @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
    
  • Posts: 41

    @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.

  • IgnatzIgnatz Mod
    Posts: 5,396

    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....

  • Posts: 1,983

    @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.

  • IgnatzIgnatz Mod
    Posts: 5,396

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

  • IgnatzIgnatz Mod
    Posts: 5,396

    @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/

  • edited March 2016 Posts: 1,983

    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.

  • dave1707dave1707 Mod
    Posts: 5,896

    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.

  • IgnatzIgnatz Mod
    Posts: 5,396

    It's clearly a graphics issue because there's nothing else.

    And when you're simply drawing a bunch of small built in images over and over, I don't see how it can be anything else but memory.

    Anyway, if anyone wants to try collecting garbage and then sit and go blind watching it for two hours, be my guest!

  • dave1707dave1707 Mod
    Posts: 5,896

    @Ignatz I don't think it's a Codea memory issue. The memory cycles the way it should and doesn't keep climbing causing Codea to run out of memory. And when the crash does occur and you look at the running iOS apps, the Codea program is still there along with the other apps. I think I'll add the garbage collect to the program and let it run, but I won't stare at the screen.

  • dave1707dave1707 Mod
    Posts: 5,896

    I added collectgarbage() in the draw routine and the program crashed back to the iOS screen after 18 minutes. Memory used was only 384 when the program was running.

  • Posts: 41

    I don't think it's fixable with a collectgarbage(). I tried it both in the test code and my app. The only thing I can say is, as more sprites you use as sooner it crashes: 1000 sprites = 5...30min, 200 sprites = 30min...3hrs. I have a simple page in my app with only 5 sprites and it crashes as well after some hours.

    Again, as it never happened before the updates, I clearly consider this as a serious bug.

    I'm developing my app now since summer last year. It only needs simple sprite usage. The animations are made with Simeons Juice lib, which also uses sprites. I can't rewrite huge parts of my app just to code around a bug. The publishing of my app was planned in summer this year. A lot of artwork, SFX and music composing has been done for it too and it needs to earn some bucks soon. I'm really getting short of breath now...

    Thanks for all your effort, testing and validation. I only can hope that Simeon takes a look as soon as possible now to this problem.

    Cheers, Heiko

  • IgnatzIgnatz Mod
    Posts: 5,396

    @Simeon, can you please look at this thread, if you haven't seen it?

    Thanks

  • Posts: 41

    Perfect, Codea 2.3.3 seems to fix this issue!

    I ran the test for 3hrs without crashes.

    Thanks Simeon and thanks to the contributors of this thread.

Sign In or Register to comment.