Time based physics implementation

@mmathias6410
I don’t understand connection between small objects and TBP you mentioned.
TBP will not give you more fps in your game (rather v. v.). It may give more accuracy and same behavior of physics objects on different fps. But even with TBP you will not gain full determinism (http://code.google.com/p/box2d/wiki/FAQ#Determinism).
If you need just more accuracy, did you try setVelocityIterations, setPositionIterations, setScale?

One suggestion for overall physics speed up - Corona utilize old version of box2d (2.1.2 Apr 2010). box2d currently updates very often and new version is faster.

[import]uid: 9058 topic_id: 15627 reply_id: 67703[/import]

@Andriy Sorry, if I wasn’t clear. What I meant was something like the liquid sim, or ropes or tentacles are constructed of a number of smaller objects in constant collision. It’s not the size of the objects, it’s the number of collisions.

TBP will not give you more fps in your game… It may give more accuracy and same behavior of physics objects on different fps.

Correct. Not looking for more fps. Looking for the same behavior of physics objects at variable fps. Don’t need more accuracy. Need smoother less choppy animations, as producerism said.

The reason I mention eaguirre’s liquid sim is because it seems a lot of people who haven’t run into this issue in their own projects have the attitude of “Why would anyone need 200 physics object all colliding at once? That’s ridiculous!” The liquid sim is an example of the kind of cool things that COULD be done with Corona, but currently cannot because it requires 200 physics objects all colliding at once.

Also, as pointed out above, it appears to be a simple fix and has been done in other implementations of Box2D (as shown in several of the above links). Maybe it’s not a simple fix. I don’t know. There’s been no response from Ansca. [import]uid: 40137 topic_id: 15627 reply_id: 67742[/import]

@Andriy Pertsov
I appreciate the help you’ve tried to provide, but as has already been stated in the thread that fix is only a patch job which will only be helpful in that specific case, and even then it isn’t a true fix. Our game has multiple levels of physics calculations going on, and a slight drop in frame rate can have an adverse effect on the physics. You say there is almost no difference between 60 and 30fps in your fix, but add a bunch of “almosts” together and it equates to something much more.
So physics performance is not a problem and it’s good enough.
Imagine if the developers of games which require precise platforming such as Super Mario Bros and Sonic the Hedgehog had just said their physics are good enough. It would be incredibly frustrating to try and cross a chasm of platforms when you only have a rough guess of where you are going to land after each jump. In those cases, close enough could be the difference of one pixel, but that pixel is the difference between life and death. That is a big deal.

Compare that to puzzle games such as Bewjeweled, where “close enough” physics wouldn’t make a lick of difference in the overall product. The point is, different developers have different needs, and as evidenced in this thread there are quite a few developers who absolutely need TBP to be implemented, and soon.

I can’t think of a more important feature the could be put into Corona. Quality is our #1 priority, we want to make sure the player has the best experience we can possibly provide them. At the moment this isn’t possible, and I’m worried that the overall quality of our game may suffer from lack of a simple feature. [import]uid: 87279 topic_id: 15627 reply_id: 67776[/import]

@pagodawestgames
Imagine if the developers of games which require precise platforming
Later I wrote, you need TBP if you want “more accuracy and same behavior of physics objects on different fps”. But you need fixed-point math if you “require precise platforming” (see box2d FAQ).

You say there is almost no difference between 60 and 30fps in your fix, but add a bunch of “almosts” together and it equates to something much more.
Almost here means “almost no visible difference”. Using setVelocityIterations, setPositionIterations, setScale you may achieve just “no visible difference” in Bullet example.

I don’t want to argue anymore, my point was to look for solution of problems with what you have. I just don’t like to wait and imho this feature will not be implemented soon. I wish I’m wrong. [import]uid: 9058 topic_id: 15627 reply_id: 67908[/import]

Like I said, I appreciate the fact that you were trying to help find a solution. What I don’t appreciate is that you were trying to downplay the importance of an issue that affects practically every developer here, whether they know it or not.

Solid, consistent gameplay should always be a developer’s first priority - before extra features, before graphics, before anything. If you don’t have the core of your game consistent so that everyone can have the same experience, none of the other features on top of it mean anything.

Again, the workarounds you have provided may slightly minimize the effects of not having TBP implemented, but the fact is that when the framerate drops (which it inevitably will at times) the physics will change no matter how many patches you try to apply. Thus, framerate independent physics are a must. [import]uid: 87279 topic_id: 15627 reply_id: 68206[/import]

If anyone has any suggestions as to how to do this without physics I would be most appreciative, because at this point we are stripping it out of our game and moving on.

I realize Ansca is currently busy getting ready to ship next week, but the lack of any response or acknowledgement here is frustrating and disappointing. Bug #8292 that pagodawestgames filed back in September still has a status of Incoming - Needs Review.

I don’t think the Ansca people understand that ignoring an issue is worse than saying, “Sorry, this isn’t in our future plans.” Or maybe they don’t understand the problem. [import]uid: 40137 topic_id: 15627 reply_id: 71022[/import]

From the release notes of daily build 2012.721:

Also, adds physics.setTimeStep( dt ) where ‘dt’ is in seconds. Pass ‘dt’ of 0 to get an approximate time-based physics (the error will be the desired frame interval, e.g. 1/30 sec). Pass ‘dt’ of -1 to get default behavior (frame-based).

So maybe the answer to our prayers?? [import]uid: 9422 topic_id: 15627 reply_id: 78006[/import]

this is a start! It’s certainly what we were asking for, and opens up the possibilities for quite a few more options. [import]uid: 49447 topic_id: 15627 reply_id: 78047[/import]

Yes, this is great!

Setting the timeStep to 0 did not work well at all for me on the device. It was extremely jerky and appeared to be skipping a large number of frames at a time.

However, physics.setTimeStep(1/30) greatly improved the performance over prior builds. (I have the fps set to 30 in the config.lua).

I tested on both iPhone4 and iPad (original, not iPad2). There was only a very small lag on the iPhone4 which is about a bazillion times better than before, and no noticeable lag on the iPad when there was definitely one before.

Since it can be set dynamically, it appears it’s only a matter of tuning and adjusting the timeStep when the element/elements that cause the lag appear on screen. Though that means tuning on each device or finding a magic number that works without the need for dynamic adjustment. Either way, this is a huge improvement.

I still think the communication from Ansca on this leaves a lot to be desired. We’ve known that stand alone Game Center is coming for quite a while now. However, the silence on this issue has been deafening, which makes it extremely difficult to plan for the future. Even something as noncommittal as “We’re trying, but we don’t know if it’ll work” is better than silence. Especially after Corona staff members promise (in the forums) more info as soon as they have it. Maybe there should be an account setting where we can opt out of the secret-agent-omg-what’s-the-new-secret-feature! bs, and get the Coming Soon news in a more straightforward fashion. 95% of the people here are already sold on Corona and don’t need teasers. [import]uid: 40137 topic_id: 15627 reply_id: 78058[/import]

“Since it can be set dynamically, it appears it’s only a matter of tuning and adjusting the timeStep when the element/elements that cause the lag appear on screen. Though that means tuning on each device or finding a magic number that works without the need for dynamic adjustment. Either way, this is a huge improvement.”

I agree, and it seems that an agnostic “TimeFixer” component could be made, which would keep track of elapsed frames, and adjust the timestep dynamically based on the FPS. A bit like a “plug-and-play” component which you just include, and it takes care of the rest ([lua]TimeFixer.setAutomaticDelta()[/lua]).

I was thinking about it all this morning, since it would also be cool to just call a method on a component like [lua]TimeFixer.setMode(“slowmo”, Easing.LINEAR)[/lua] which would automatically ease into a predefined slow-motion state, then [lua]TimeFixer.setMode(“normal”, Easing.LINEAR)[/lua] would bring it back out.

[import]uid: 49447 topic_id: 15627 reply_id: 78067[/import]

EDIT: Finally tested on device (iPhone4) and this worked for me, much better than time step setting at 0.

Yes, I’ve been playing around with this basic time step fixer, but I can’t test on a device until later tonight. It assumes a 30fps setting and that 1/current frame rate is the correct ratio. It’s probably not that simple, but if it’s going to work at all then SOME ratio is the correct one and it’s just a matter of finding one that works.

Trying to set the time step each frame just crashes the simulator. Every 10 frames seems to be OK, less than that makes my code buggy. However, the interval may need to be higher on a device.

[code]
– Outside of game loop/enterFrame event
local mFloor = math.floor
local prevTime, frameCounter = 0, 0
local baseTimeStep, curTimeStep, frameInterval = 30, 30, 10
physics.setTimeStep(1/baseTimeStep)
– Either inside a game loop/enterFrame event or as a function
– called from game loop/enterFrame
– CALC FPS
local curTim = system.getTimer()
local dt = curTime - prevTime
prevTime = curTime
local fps = mFloor(1000/dt)e
frameCounter = frameCounter + 1

– CHECK EVERY N FRAMES
if frameCounter == frameInterval then
if fps < baseTimeStep then
– DROP IN FPS, SET NEW TIME STEP
physics.setTimeStep(1/fps)
curTimeStep = fps
else
– REVERT BACK TO BASE TIME STEP
if curTimeStep < baseTimeStep then
physics.setTimeStep(1/baseTimeStep)
curTimeStep = baseTimeStep
end
end

frameCounter = 0
–print(fps)
end
[/code] [import]uid: 40137 topic_id: 15627 reply_id: 78095[/import]

“Trying to set the time step each frame just crashes the simulator.”

Just wanted to mention, in the windows simulator, I haven’t had any crashes setting the FPS on each iteration of the game loop. I did notice though, that by setting the frameInterval to 1 caused a problem because you also set frameCounter to 1 in the FPS check.

Try moving it to the bottom, like this:

[lua]adjustFPS = function()
local curTime = system.getTimer()
local dt = curTime - prevTime
prevTime = curTime
local fps = mFloor(1000/dt)

– CHECK EVERY N FRAMES
if frameCounter == frameInterval then
if fps < baseTimeStep then
– DROP IN FPS, SET NEW TIME STEP
physics.setTimeStep(1/fps)
curTimeStep = fps
else
– REVERT BACK TO BASE TIME STEP
if curTimeStep < baseTimeStep then
physics.setTimeStep(1/baseTimeStep)
curTimeStep = baseTimeStep
end
end

frameCounter = 0
–print(fps)
end

frameCounter = frameCounter + 1

end[/lua]

That fixed the issue for me. [import]uid: 49447 topic_id: 15627 reply_id: 78309[/import]

One more update… I’m set on creating a separate component that will take care of adjustingFPS for you (and eventually allowing for slow-mode and etc.). Here’s what I’ve made so far, based on the code from mathias:

GameScreen.lua: (somewhere in your game code)
[lua]local TimeMachine = require(“TimeMachine”)
TimeMachine.start()[/lua]

TimeMachine.lua:
[lua]local M = {}

M.fps = 30

local mFloor= math.floor
local prevTime, frameCounter = 0, 0
local baseTimeStep, curTimeStep = M.fps, M.fps

M.updateInterval = 1

physics.setTimeStep(1/baseTimeStep)

M.adjustFPS = function()
local curTime = system.getTimer()
local dt = curTime - prevTime
prevTime = curTime
local fps = mFloor(1000/dt)

– CHECK EVERY N FRAMES
if frameCounter == M.updateInterval then
if fps < baseTimeStep then
– DROP IN FPS, SET NEW TIME STEP
physics.setTimeStep(1/fps)
curTimeStep = fps
else
– REVERT BACK TO BASE TIME STEP
if curTimeStep < baseTimeStep then
physics.setTimeStep(1/baseTimeStep)
curTimeStep = baseTimeStep
end
end

frameCounter = 0
–print(fps)
end

frameCounter = frameCounter + 1
end

M.start = function()
Runtime:addEventListener(“enterFrame”, M.adjustFPS)
end

M.stop = function()
Runtime:removeEventListener(“enterFrame”, M.adjustFPS)
end

return M[/lua]

Obviously there is plenty of room for improvement, but just a start. This way there could be a single “TimeMachine” class that handles all things FPS related (within physics projects), and which can be used in multiple projects. Feel free to add on or make any suggestions. [import]uid: 49447 topic_id: 15627 reply_id: 78313[/import]

It’s nice to surface the the capability of setting our own physics stepping limits etc, but a part of me feels there should simply be a flag that allows corona users to use either method and that the engine itself should mange the time based implementation.

I think the whole external Director api to internal Storyboard api is a good example of this. [import]uid: 8545 topic_id: 15627 reply_id: 78393[/import]

“there should simply be a flag that allows corona users to use either method and that the engine itself should mange the time based implementation.”

That’s exactly what this is. The “flag” would be setting the timestep to -1, which defaults to how Corona works already. Setting to a positive number, gives you control over it. It’s more than a flag, but operates just how you describe. [import]uid: 49447 topic_id: 15627 reply_id: 78407[/import]

It’s always great to see Ansca listen to the developers and implement such an important feature. Even though there has been little communication from them on this issue, it’s nice to know that they were listening. A whole new world is now open to us, and this puts a lot of worries we were having to rest!

Bring on the bullet time :slight_smile: [import]uid: 87279 topic_id: 15627 reply_id: 78747[/import]