Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Classic Chat / Controlling Physics irrespective of FPS

Author
Message
Funnell7
13
Years of Service
User Offline
Joined: 8th Sep 2011
Location: UK, England
Posted: 21st Mar 2013 08:54
Hello, I had a brief discussion regarding this on my WIP Thread, but wanted to bring it here for the benefit of others and also because I'm not entirely sure how to do this...

I'm trying to make the physics work consistently regardless of the FPS. For example, at the moment, when running at 60 FPS my characters jump (using velocity) is perfect and as expected, however, when I drop the FPS to say 30, the jump is inconsistent, as if the velocity is changing.

I naively thought it would be as simple as this:



But this doesn't appear to be the case. Does anyone have any ideas what I need to do...
Digital Awakening
AGK Developer
22
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Sweden
Posted: 21st Mar 2013 09:00
I don't use the physics in my platformer. I could never get them to work the way I wanted. I only use the built in collisions. I wonder if this is something you can fix by multiplying all the forces with the frame time.


Demo 3 is out now!
Markus
Valued Member
20
Years of Service
User Offline
Joined: 10th Apr 2004
Location: Germany
Posted: 21st Mar 2013 09:20 Edited at: 21st Mar 2013 09:22
the physics knows the frametime from sync/update.
you should jump(move) with add impulse or add forces.
Funnell7
13
Years of Service
User Offline
Joined: 8th Sep 2011
Location: UK, England
Posted: 21st Mar 2013 09:24
Why would Impulse or Forces be any different than Velocity? They are all 'physic forces', right?
Markus
Valued Member
20
Years of Service
User Offline
Joined: 10th Apr 2004
Location: Germany
Posted: 21st Mar 2013 09:58 Edited at: 21st Mar 2013 10:11
because the Velocity is calculated from physic engine.
(if the sprite bump at a wall the Velocity vector change his direction.)
you can use it to initialize or stop the player fast in 1 frame.

Velocity is the result from acceleration.
Funnell7
13
Years of Service
User Offline
Joined: 8th Sep 2011
Location: UK, England
Posted: 21st Mar 2013 10:11 Edited at: 21st Mar 2013 10:12
Ok, maybe I'm not understanding... Let me try and explain it this way... So to make my sprite jump, I do this:



This applies a minus velocity of 200. When running at 60 FPS, the sprite consistantly jumps to the correct height. However, when running at say 25 FPS, sometimes the sprite jumps to the correct height, other times it only jumps half or even quater of the height, i.e. inconsistant.

Are you suggesting that if I change this to Impulse instead, then the jump height would always be consistant? If so, would you mind explaining why Impulse would be different...
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 21st Mar 2013 10:15
Funnel7, can you provide a simple example of this. I have not found this problem using setSpritePhysicsVelocity. Box 2D should be consistent, the only time it may seem inconsistent is when you apply impulse or forces per update rather than as a calculated amount over time. Using a set velocity should always be consistent, if not there's a bug.


this.mess = abs(sin(times#))
Markus
Valued Member
20
Years of Service
User Offline
Joined: 10th Apr 2004
Location: Germany
Posted: 21st Mar 2013 10:27
ok, looks good,
i try with syncrate 60 fps and 10 fps,
i kick a ball sprite in the air and it look ok/same.
i use 108 beta 8 for the test.

do you set the new velocity once or over some frames?
Funnell7
13
Years of Service
User Offline
Joined: 8th Sep 2011
Location: UK, England
Posted: 21st Mar 2013 11:45
I set it once i.e. if Button pressed > SetSpriteVelocity...

Baxs I'll throw something together after work. Thanks for taking a look.
Digital Awakening
AGK Developer
22
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Sweden
Posted: 21st Mar 2013 13:43
Make sure that you are using floats when dealing with coordinates.


Demo 3 is out now!
Marl
13
Years of Service
User Offline
Joined: 19th Nov 2011
Location: Bradford, UK
Posted: 21st Mar 2013 18:43
Quote: "Why would Impulse or Forces be any different than Velocity? They are all 'physic forces', right?"
Not quite.
Velocity is a measure of distance with respect to time, and object with no forces applied will move at a constant velocity.

Forces - which are also measured with respect to time, apply changes to velocity.

In simplest form; Velocity = Speed, Force = Acceleration

While you can apply a velocity to a sprite, and in theory it should move at that velocity consistently, you can't know if there are forces already in play which will change that velocity, immediately after you change it.

The physics engine allows for time when it applies these forces - which could explain the variation on different frame rates.

As others have said, use the physics or don't use the physics - just don't sit on the fence and pick and choose - it leads to unpredictable results.
Funnell7
13
Years of Service
User Offline
Joined: 8th Sep 2011
Location: UK, England
Posted: 21st Mar 2013 18:56
Quote: "As others have said, use the physics or don't use the physics - just don't sit on the fence and pick and choose - it leads to unpredictable results. "


@Marl, thank you very much for the explanation. To assign Velocity you use SetSpritePhysicsVelocity() which is why I thought I was using 'physics' and not 'sitting on the fence', but I think I understand what you are saying... I'm home from work now so will run several tests using impulse instead, thank you...
Marl
13
Years of Service
User Offline
Joined: 19th Nov 2011
Location: Bradford, UK
Posted: 21st Mar 2013 19:04
NO problem.

What surprised me was how much physics objects spin (with spin enabled of course).

I did some work with balls, and while in x / y terms ( linear velocity ) they moved quite slowly, looking closely, they were actually spinning very fast (angular velocity).

If you think about a fast spinning ball falling to the floor - though it might fall quite slowly, when it hits the floor all that spinning energy gets involved in the collision and so the ball flies across the room much faster than it was falling.

This is kind of what I meant by "other forces in play"
Funnell7
13
Years of Service
User Offline
Joined: 8th Sep 2011
Location: UK, England
Posted: 21st Mar 2013 19:33
Ok, so having run a few tests, it would appear that the issue only occurs when the FPS fluctuates (much like a struggling device would). So when I set the FPS to a specific rate (whether it be 30, 35, or 60), ever thing is consistent.

Now... I may have been incredibly silly here, but I tried to think of a way to get the Sync Rate to fluctuate like a device would, so I tried assigning a random value ever cycle ha. I know you wouldn't normally do this under normal circumstances, but I think this perfectly illustrates my issue...



If you run this code (no media needed) you will see that the jump is inconsistent. This is both the same for Impulse and Velocity... Am I being silly, or does that make sense?
Marl
13
Years of Service
User Offline
Joined: 19th Nov 2011
Location: Bradford, UK
Posted: 21st Mar 2013 20:00
Messing with the sync() rate will probably mess up the physics and not give a fair example of the effect "in-game"

It would be a better test to get the frame rate to drop through missed frames due to overwork.

Something like;

This fills up the game loop with activity until the frame rate drops, from this point, your frame rate should fluctuate without changing the sync() or varying the code.
Funnell7
13
Years of Service
User Offline
Joined: 8th Sep 2011
Location: UK, England
Posted: 21st Mar 2013 20:07
Quote: "Messing with the sync() rate will probably mess up the physics and not give a fair example of the effect "in-game""


Yeah I agree and will certainly try what you have posted. Having said that, the affects my code produces is identical to what I am experiencing in my wip, with devices which struggle to get to around 30 FPS. I was hoping this may have given an indication of what could be causing the issue, but it seems as though I may just have to accept that some devices just won't be able to run it?!
Markus
Valued Member
20
Years of Service
User Offline
Joined: 10th Apr 2004
Location: Germany
Posted: 21st Mar 2013 20:32
hmm, looks ok, i add a line for compare.
what agk player version did you use?

Funnell7
13
Years of Service
User Offline
Joined: 8th Sep 2011
Location: UK, England
Posted: 21st Mar 2013 20:55 Edited at: 21st Mar 2013 20:56
Hmmm, yeah you're right, adding Marl's code seems fine for me too... Maybe its something I am doing in my WIP then? (I hope it is because at least then I can fix it!)...

I'll do some digging, see if I can find anything, thank you all for your replies. I'll report back if I find anything.

EDIT: Sorry Markus, I ignored your question. I am using the latest beta.
Grumpy Jedi
14
Years of Service
User Offline
Joined: 16th Jan 2010
Location:
Posted: 22nd Mar 2013 01:27 Edited at: 22nd Mar 2013 01:40
I think I know what Funnell is talking about here.

if you set the sync rate with SetSyncRate(60,0) and give a physics sprite some velocity, it moves as expected.

However if you set the sync rate to 30 with SetSyncRate(30,0) and give a physics sprite some velocity, the sprite no longer moves fluidly, it appears to be "twitchy" and warp or jump every now and then as it moves.

It's more than just the change in framerate. You can actually get it almost smooth by calling StepPhysics with a value of GetFrameTime() + some milliseconds.

So it would seem the physics engine is getting slightly behind for some reason if the sync rate is set below 60.

I'm using version 1075 at the moment so I'll leave it to you guys to see if it's happening in 1076 and 1088.

This bit of code illustrates the problem perfectly...

Run the program and press the spacebar to change the sync rate on the fly and watch the effect it has on the physics.

EDIT: I was running this in a resolution of 960x640, if you use the default resolution the block will just go off your screen and you won't see the whole thing. Change the setup file resolution before running for best results

Funnell7
13
Years of Service
User Offline
Joined: 8th Sep 2011
Location: UK, England
Posted: 22nd Mar 2013 08:59 Edited at: 22nd Mar 2013 09:15
Thanks Grumpy Jedi, I think we may be getting somewhere now... I have made a few changes to the demo code which now shows exactly what I am trying to say.

If you run the below code, you will see I have added a line which shows where the block should jump to. Now, if you press 'Space' the FPS will drop in increments of 10. You should see that as the FPS drops, the block progressively doesn't quite reach the line (albeit, only marginly). And lastly, when you get to 10 FPS, the jump is significantly smaller...



EDIT: Its quite possible that these minor differences are actually to do with the Physics Collision and not so much the Velocity. Although that doesn't explain the huge difference when dropping as low as 10 FPS...
Grumpy Jedi
14
Years of Service
User Offline
Joined: 16th Jan 2010
Location:
Posted: 22nd Mar 2013 12:12
Quote: "It's more than just the change in framerate. You can actually get it almost smooth by calling StepPhysics with a value of GetFrameTime() + some milliseconds.
"


I retract that statement. I thought I had observed an improvement in smoothing when adjusting the physics speed in the past, but I'm not seeing it now so we'll chalk that up to a late night coding trick on the eyes.
Grumpy Jedi
14
Years of Service
User Offline
Joined: 16th Jan 2010
Location:
Posted: 22nd Mar 2013 12:45
Okay, so I've tracked down exactly whats going on in my example.

It all has to do with SetSyncRate().

I am using mode 0 for SetSyncRate() to save CPU and battery on mobile devices. I tried my code with mode 1 and sure enough it becomes smooth as silk at 30 FPS, however at the cost of GREATLY increased CPU usage.

Further testing gives these results.

SetSyncRate(30,0) Choppy with low CPU usage.

SetSyncRate(60,0) Smooth with low CPU usage.

SetSyncRate(30,1) Smooth with extremely High CPU usage.

SetSyncRate(60,1) Smooth with extremely High CPU usage.

The point of interest here is that a setting of 60,0 seems to be a much better choice than a setting of 30,1. Double the frame rate with smooth animation and a gigantic savings on CPU power.

So the choppiness I was seeing has nothing to do with the physics engine, it was just the less accurate mode 0 of SetSyncRate() when the FPS is capped at 30.
Funnell7
13
Years of Service
User Offline
Joined: 8th Sep 2011
Location: UK, England
Posted: 22nd Mar 2013 13:20
Thats right, I have mine set to '1' as I'm willing to take the hit on the CPU in favor of smoother physics at lower FPS Rates... My biggest concern is why physic forces differ.
Markus
Valued Member
20
Years of Service
User Offline
Joined: 10th Apr 2004
Location: Germany
Posted: 22nd Mar 2013 18:46
hmm,i tryed your example, i think the agk core developers can answer this.
Funnell7
13
Years of Service
User Offline
Joined: 8th Sep 2011
Location: UK, England
Posted: 22nd Mar 2013 21:50
Thanks Markus, I shall wait to see if any of the TGC guys catch A glimpse of this...
Paul Johnston
TGC Developer
22
Years of Service
User Offline
Joined: 16th Nov 2002
Location: United Kingdom
Posted: 23rd Mar 2013 00:17
The way we've set the physics engine up at the moment is for maximum performance rather than accuracy. This means that each frame AppGameKit does a single call to the physics engine with the amount of time that has passed (at 60fps this is about 17 milliseconds), and the physics engine simulates 17 milliseconds of time. At 30 fps the physics engine simulates 33 milliseconds every frame, and at 10 fps 100 milliseconds. This difference in timing can make the physics engine behave differently at different frame rates.

To make the physics accurate it needs to be given a fixed time step, say 17 milliseconds, and we call it multiple times to catch up to the frame rate. For example at 60 fps we would call the physics engine once a frame with a step of 17 milliseconds, but at 30 fps we would call it twice a frame with a step of 17 milliseconds to get close to the 33 milliseconds we need. This makes the physics engine do more work but makes it deterministic at all frame rates.

One problem with doing this is if stepping the physics engine twice lowers the frame rate further so next frame it must call the physics engine 3 times, which slows it down more, and so on until the app dies. So there is a limit to how much this can compensate for low frame rates.

The easiest way to implement something like this would be


but if you want to read more there are lots of discussions on this https://www.google.co.uk/search?q=box2d+time+step
Funnell7
13
Years of Service
User Offline
Joined: 8th Sep 2011
Location: UK, England
Posted: 23rd Mar 2013 12:37
Thank you for the reply Paul, I'll be honest, I have no idea what that code snippet is actually doing, but it works, perfectly!! Everything is now consistent irrespective of FPS which is exactly what I was trying to achieve!!! Thank you thank you thank you!

Here's the demo with Paul's code added in for anyone who's interested:

Login to post a reply

Server time is: 2024-11-24 09:27:48
Your offset time is: 2024-11-24 09:27:48