Updated to 2.0 and seeing some 'slowdown' in physics or setContext

Here’s a sample code, if you run on the last version of Codea it’s smooth, but on 2.0 it’s choppy …

The reason there’s 4 blocks of for loops is that the original code also does destroys, etc.,

but basically it used to run great and now it doesn’t and I can’t pinpoint the issue …

I’m using setContext to draw paths already taken by the balls, and switch the context inside for loops.

Any Advice would be appreciated!



function setup()
    
    supportedOrientations(LANDSCAPE_LEFT)
    displayMode(FULLSCREEN)
    backingMode(STANDARD)
        
    walls = {}
    balls = {}
    
    cell = 40
    
    createLevel()

end

function createLevel()
    
    myImage = nil
    myImage = image(WIDTH,HEIGHT)
    setContext(myImage)
    fill(42, 31, 106, 255)
    rect(0,0,WIDTH,HEIGHT)
    setContext()

        for y = 0, 18 do
            for x = 0, 20 do
                if x==0 or x==2 or x==4 or x==16 or x==18 or x==20 or y==0 or y==18 then
                    createBox(x*cell,y*cell,cell,cell)
                end
            end
        end
    
    createCircle(cell*1,cell*17,cell/2,1)
    createCircle(cell*3,cell*17,cell/2,2)
    createCircle(cell*17,cell*17,cell/2,3)
    createCircle(cell*19,cell*17,cell/2,4)

end

function createCircle(x,y,r,i)
    local circle = physics.body(CIRCLE, r)
    circle.type = DYNAMIC
    circle.x = x
    circle.y = y
    circle.restitution = 0
    circle.mass = 0
    circle.friction = 0
    circle.interpolate = true
    circle.sleepingAllowed = false
    circle.info = i
    table.insert(balls,circle)
end

function createBox(x,y,w,h)
    local box = physics.body(POLYGON, vec2(-w/2,h/2), vec2(-w/2,-h/2), vec2(w/2,-h/2), vec2(w/2,h/2))
    box.type = STATIC
    box.x = x
    box.y = y
    box.restitution = 0
    box.mass = 0
    box.friction = 0
    box.interpolate = false
    box.sleepingAllowed = true
    table.insert(walls,box)
end

function draw()
    
        sprite(myImage, WIDTH/2, HEIGHT/2, WIDTH, HEIGHT)

        for i,body in ipairs(balls) do
            if body.info == 1 then
                body.linearVelocity = vec2(Gravx,Gravy)
                setContext(myImage)
                fill(60, 140, 0, 255)
                ellipse(body.x+body.radius,body.y+body.radius,body.radius*1.5)
                setContext()
                fill(120, 200, 60, 255)
                ellipse(body.x+body.radius,body.y+body.radius,body.radius*2)
                fill(255, 255, 255, 255)
                ellipse(body.x+body.radius,body.y+body.radius,cell/2)
            end
        end
    
        for i,body in ipairs(balls) do
            if body.info == 2 then
                body.linearVelocity = vec2(Gravx,Gravy)
                setContext(myImage)
                fill(140, 0, 140, 255)
                ellipse(body.x+body.radius,body.y+body.radius,body.radius*1.5)
                setContext()
                fill(200, 60, 200, 255)
                ellipse(body.x+body.radius,body.y+body.radius,body.radius*2)
                fill(255, 255, 255, 255)
                ellipse(body.x+body.radius,body.y+body.radius,cell/2)
            end
        end
    
        for i,body in ipairs(balls) do
            if body.info == 3 then
                body.linearVelocity = vec2(Gravx,Gravy)
                setContext(myImage)
                fill(0, 100, 160, 255)
                ellipse(body.x+body.radius,body.y+body.radius,body.radius*1.5)
                setContext()
                fill(60, 160, 220, 255)
                ellipse(body.x+body.radius,body.y+body.radius,body.radius*2)
                fill(255, 255, 255, 255)
                ellipse(body.x+body.radius,body.y+body.radius,cell/2)
            end
        end
    
        for i,body in ipairs(balls) do
            if body.info == 4 then
                body.linearVelocity = vec2(Gravx,Gravy)
                setContext(myImage)
                fill(180, 0, 0, 255)
                ellipse(body.x+body.radius,body.y+body.radius,body.radius*1.5)
                setContext()
                fill(240, 60, 60, 255)
                ellipse(body.x+body.radius,body.y+body.radius,body.radius*2)
                fill(255, 255, 255, 255)
                ellipse(body.x+body.radius,body.y+body.radius,cell/2)
            end
        end
    
        Gravx = math.ceil(Gravity.x*5000)
        Gravy = math.ceil(Gravity.y*5000)
        if Gravx > 200 then Gravx = 200 end
        if Gravx < -200 then Gravx = -200 end
        if Gravy > 200 then Gravy = 200 end
        if Gravy < -200 then Gravy = -200 end

            for i,body in ipairs(walls) do
                fill(29, 155, 213, 100)
                noStroke()
                rect(body.x,body.y,cell,cell)
            end

end


@escape75 Things aren’t working the way you think they are. To see my point, comment out the line createBox in the function createLevel() and run your code. If it does what I see, the balls move sideways and down which mean they are constantly hitting the side of the box they’re in.

Well the balls will move depending on Gravity.x/y so sideways if you hold the device sideways, but I commented out the walls anyways and what I saw was interesting …

The path drawn by the balls was still jaggy, unlike in previous versions of Codea where it was nice and smooth … so what’s going on in the new physics? :slight_smile:

@escape75 Change the *5000 to *200. Move the following code to the beginning of draw().

function draw()

        Gravx = math.ceil(Gravity.x*200)
        Gravy = math.ceil(Gravity.y*200)
        if Gravx > 200 then Gravx = 200 end
        if Gravx < -200 then Gravx = -200 end
        if Gravy > 200 then Gravy = 200 end
        if Gravy < -200 then Gravy = -200 end

        ......

I tried moving the code without changing the Gravity multiplier, and it had no effect.

When you reduce the multiplier it’s smoother, but also much slower, and also you can see quite a simulation delay once in a while

Remember this was working perfectly in previous version, very smooth, the balls would fall down with a constant rate.

Almost as if interpolate is not working anymore ?

@escape75, try setting physics.continuous = true I think that perhaps the less frequent physics is what causes the jumpiness

@escape75 Run this code and then hit replay when the ball reaches the bottom. This might be your problem. It looks odd to me. What I see when I run this is skipping as the ball moves down the screen. Sometimes it’s ok, sometimes it’s not.


supportedOrientations(PORTRAIT)
    
function setup()
    b=physics.body(CIRCLE,5)
    b.x=WIDTH/2
    b.y=HEIGHT-10
    b.gravityScale=2
    backingMode(RETAINED)
end

function draw()
    fill(255)
    ellipse(b.x,b.y,10)    
    if b.y<0 then
        physics.pause()
    end
end

I can definitely see what you mean … question is… how did this behave on a previous version of Codea I wonder ?

JakAttak: I alreasy tried continuous and also bullet property and it didn’t make any difference.

@escape75 I ran that on my iPad1 with version 1.5.? and it does the same thing. Sometimes it’s a nice continuous run, other times there are gaps.

What if you run my code on iPad1, the first example I posted ?

I wonder if it will seem smoother …

@escape75 I ran your code on my iPad1 and the same jerky motion was there also. Looks exactly like what we see on Codea 2.0 .

Ok so I’m guessing Codea 2.0 changed how much time is used calculating physics, that would explain why it’s running much slower than Codea 1.5.5 on my iPad Air, but very similar on iPad 1 which doesn’t have the same CPU capabilities …

Good thing I submitted my app while on Codea 1.5.5 as it’s not running the same way on Codea 2.0 I guess :slight_smile:

After further testing I’m pretty sure the issue isn’t with physics, but setContext

Performance of that seems to have dropped considerably, when you uncomment the setContext (8 places) in my code you will see the smooth ball motion.


Having just the first 2 setContexts in the code, slows down the whole animation big time!


Please try on iPad 1 :slight_smile:

@escape75, that could be related to the changes to allow setContext to retain z-level

Update: I calculated FPS without setContext as 60 fps,
and with 8 setContexts it goes down to 20 FPS.

@escape75 Removing the 6 setContext on the iPad1 makes it run smooth also.

Ok great, so the question is … is 2 setContexts per draw() allowed, but 8 not?

And why did it work fine on Codea 1.5.5 … is this possibly a bug ?

Update: Even 2 setContexts slow it to 50 FPS, so it seems the
slowdown
is 5 FPS per setContext on an iPad Air, quite a bit no?

@escape75 Why are you using setContext anyways. Make the changes I show below.


function createLevel()
    
    --myImage = nil
    --myImage = image(WIDTH,HEIGHT)
    --setContext(myImage)
    --fill(42, 31, 106, 255)
    --rect(0,0,WIDTH,HEIGHT)
    --setContext()

        for y = 0, 18 do




function draw()

    background(42, 31, 106, 255)
    
        --sprite(myImage, WIDTH/2, HEIGHT/2, WIDTH, HEIGHT)