Inaccuracy of the physics engine?

Hey guys check this video out :
Its two runs of my latest game with exactly the same track, fps and physics body moving but the outcomes are slightly different which is making my game a bit unplayable as in its not really possible to make a full length track that works exactly the same every time.

@Luatee: can you try something for me? Turn off interpolation on your physics bodies and see if that fixes your issue. I have a theory but I want to see if this works before I explain it.

I set interpolation of the physics body (now a 60x30 square polygon) to false and the track doesnt have interpolation on but its still happening and im not quite sure how to solve it

Hmm, that blows my theory out of the water. In my experience with Box2D outside of Codea it’s behavior is deterministic, so my only thought is that it’s something specific to either a) Codea, or b) your code, but I doubt it’s Box2D. Most likely it’s b)

Actually, I take that back, my theory might still hold water, but with some modification (it doesn’t have to do with interpolation).

I think what’s going on has to do with the way the physics time stepping is implemented in Codea (which is what allow interpolation for smooth motion, regardless of framerate). Most likely they implemented it this way:

What this can mean is that, although the physics engine is being updated with a fixed timestep, the iterative nature of the solver can produce unexpected results depending on the elapsed time from one Codea frame update to the next. For example, if one game loop step takes longer than the fixed timestep, on the next frame update Codea will actually end up stepping the physics engine twice, potentially leading to a slightly different result from one run to the next (since due to environment-wide variability like garbage collection, OS-level operations, etc, you aren’t guaranteed that from one run to the next your updates will always use the same time deltas). This is just a theory, but it makes some sense to me. Maybe someone smarter than me can lend some credence to or debunk this theory.

EDIT: nope, I take this back. I just read the article again (it’s been awhile), and had forgotten that the algorithm ensures that the results are deterministic. If indeed the time step is implemented this way in Codea than I doubt that’s the problem. I’m back to thinking that either Codea doesn’t implement their time step this way (though if memory serves correctly since the last time I’ve looked at the runtime they do), or you have some issue in your code itself. What are the inputs? Can you influence the simulation at all (for example with the accelerometer or with touch), or is it strictly “hit the play button and watch what happens”?

I think it’s caused by the precision of Codeas’ calculations. I created a program with 2 circles that bounced off the edges and each other. I addled code to restart the positions and velocity anytime I touched the screen. I had one of the circles leave a trail of it’s path and each time I touched the screen, the one circles’ path would overlay the previous ones, but eventually it would start to deviate from the trail. That’s probably what’s happening to your program. Even though you start out the same, the small errors start adding up and the calculations start to deviate. The longer the program runs, the more things are going to differ.

@dave1707: Nope. If you are running your physics simulation with a fixed time step, the results will be the same run after run, regardless of how long the program has been running, if the input is identical (again, I’ve had a lot of experience with Box2D outside of Codea, and this is definitely the case). Sure, there may be tiny rounding errors due to using floating point math, but again, if the time step is constant, and the input is identical, those errors will be consistent fom run to run. So, either a) Codea’s physics time step is not truly constant, b) something else that Codea is doing is causing the inconsistency, or c) the simulation’s input is not identical from run to run.

. @toadkick I start the simulation each time with the same x,y values and the same linearVelocity for both objects. Sometimes the trails overlap, sometimes it starts to vary a little. If I keep restarting the simulation, the new trail will follow one of the trails, either the original or one of the varied ones. Something changes, but it’s repeatable from one run to the next.

@dave1707: when you say “restart”, do you mean “terminate and restart the program” or do you mean a “warm” restart, where you reset the simulation state within the program itself, without terminating the program? There is a subtle difference, and I might have another hypothesis depending on your answer.

If it works when terminating/restarting, but not with “warm” restarting, then this is definitely an issue with Codea’s implementation. If it’s inconsistent both ways…then I have no idea what the specific cause might be.

@Luatee is correct about this: if the results of the simulation are not deterministic, it is impossible to provide physics-based gameplay that feels fair and predictable.

. @toadkick I just do a warm restart so that the trail from each run remains on the screen. Each restart starts with the same values for the 2 objects.

@dave1707: I’d recommend reconfiguring your test so that you can terminate/restart the program and test the consistency. Since you only have a two simulated objects on screen, you can save out their orientation/motion information every frame (using one of the save*Data functions), and compare the numbers across two runs.

This is my hypothesis: “warm” starting does not re-initialize Box2D, thus the input to your simulation is not identical in each run (in other words, the physics engine’s state will not be the same when you warm restart your program as it was when you cold started the program).

Well I’m still a bit peeved that this is the case, as my game will not be a good runner if the outcomes vary each time the ball starts again. The thing is I don’t even do a restart, I just recreate the physics bodies but obviously being maths the lines will not change as the points surrounding it do not change. I’m not experienced in java/c++ so I couldn’t run a test in box2d itself, that might be a good idea though?

@Luatee Codea uses a fixed timestep for physics calculations so it should be deterministic. Does the bike in your demo have any forces acting on it besides gravity? Do you use DeltaTime for any calculations in your game?

There is only gravity acting on the body, so I’m not sure whats going on. I only use DeltaTime for a fps watcher such as text("FPS: "…1/DeltaTime,x,y)

.@toadkick I altered my program to save 470 plots to local data. Each time I hard restart the program, I read the 470 plots back in and plot the original trail. I then start the 2 balls bouncing around and the ball that does the plot followed it’s path 10 out of 10 times. When I did soft restarts, the ball followed it’s path about 7 out of 10 times. So what path the ball takes depends on the timing of the soft restart. If that’s the case, you can’t guarantee the same path unless you hard restart the program each time which probably isn’t an option in a normal game.

@dave1707: Thanks for confirming. I think a possible solution would be for Codea to provide a way for us to manually reset Box2D from within our programs (not sure how easy/hard that would be to do). I think this would solve @Luatee’s issue too.

Another thing that might provide consistency is to make sure you’ve manually destroyed all of your physics objects when you do a warm restart, but I am not holding out much hope for this method.

Well seeming as I haven’t put in a way to save tracks yet it isn’t going to work that well for me to test this. I did notice when I was doing my testing the track was completed about 6 times out of 10, it seemed every other running of the simulation worked fine, this was with about 6 different runs of deleting the physics bodies then recreating them (without restarting the app at all) so it is going to be a lot harder for me to fix this situation from what I can see, feel free to correct me if Im wrong

@Luatee: I am about 99% sure that being able to reset the entire physics engine from within your program would solve your issue (assuming of course that you’ve saved your tracks, so that they can be recreated after the reset).

well if it was just a physics engine reset then thats alright as I can store all the values before doing so then restoring them after, I hope that this will be seen and heard by the developers of codea anyway otherwise I’ll have to go back to my other game

I altered my program to destroy all the physics objects and recreate them each time I do a soft restart. I did 20 soft restarts and all 20 times the plotting ball followed the original path. So destroying and recreating the objects look like it will work.