Box2D Physics completely different on iOS compared to Android?

Hi,

I’m currently having trouble concerning the Physics in my Cocos2dx game. In iOS they are fine but when I port the project to Android the physics are much weaker.

Can anyone explain if it’s possible to get them working the same on both platforms?

Thanks
Mark

This makes me wonder if you’ve somehow tied your physics to screen properties like density, width or something device specific.

How do the physics perform on a PC or Mac desktop?

They will never be exactly the same because the processors are different - processors tend to handle floating point numbers differently, and have different rounding errors.
This tends to show itself more after a certain amount of time though - eg, you cant be sure that the end result will be the same given the same input parameters… so “replays” in cross platform, or even cross- devices will veer off course if they only rely on the same input data… so you would have to manually correct it every so often with key frames, saved from the original play-through…

as for your problem - if you think it is more immediate than that… there might be a difference in how you are calculating your input values…
like Cory said, something to do with screen size / pixel density - that is maybe relevant if you are taking user input from touch…

Are you sure that the actual box2d values that are being input are the same in both?

A very common problem is frame rate. Eg, if one devices is struggling to display at the same FPS, then the physics might also be running slower… and things might appear to be more heavy as a result.
The default, exmaple code is not very good at fixing this.
There are two ways to compensate:
the first is to pass the deltatime to the physics engine in each update (not sure if the example code does this or not)
This means that if 0.02 seconds has passed, everything will move twice as far as it would have done if 0.01 seconds had passed…
however, only one collision check, air resistance check, ect will have been computed…. that might be fine (and is certainly better than it NOT taking into consideration the delta time, eg having moved only the 0.01 distance… therefore half the speed.)

however, this can produce sliiightly different result… an object might react similar if it is moving twice as far per step at 30 steps per second than an object running at 60 steps per second, but the 60 one will catch collisions earlier ect…

what i am getting at is, to try and recreate the same effect each time, you should update your physics with a FIXED timestep…
eg always update at 60 steps per second (or whatever speed works).
now, as per my example… if the game laggs behing, to 30 fps… then it should have completed TWO physics steps… so instead of running the physics engine with delta time (telling it to move everything twice as far)… you should run in twice with a normal sized step…
this means that it always catches collisions at the same point, and does all the other stuff at the same point…

Obviously it isnt quite as simple at 60 and 30 fps…
so to implement a fixed time step you sould remember how much time has passed… and therefore when a new physics update is required.

//here is some code:
void PhysicsNode::update(float dt)
{
timeRemaining += dt; //timeRemaining is just a float which measures how much time has passed
// requiredTimestep is the interval at which box2d should update… here requiredTimestep = 1/60
while(timeRemaining >= requiredTimestep){
timeRemaining-=requiredTimestep;
//here you should update physics
//you MUST pass requiredTimestep to the physics delta time INSTEAD of dt
}
}

This code means that the physics will always update at requiredTimestep… if it is running too fast, it will add the dt to timeRemaining, and NOT execute a physics step… it will just add on and therefore be more likely to update next frame… and if it is running too slow, it might even update twice…

Another advantage to this is that you can loose accuracy for the sake of processor time by updating your physics even less than your game rendering FPS.

Does that all make sense?
Might be the source of your problem… it certainly will be required if you want the same experience across different play sessions or devices.
but it might also be a problem with your input values if you think the problem is more immediate.

all the best,
Dan

Hi all,

thanks for the replies. From what I can tell the screen width is not being taken into consideration. Both the iOS and Android Versions are running in the same resolution too.

both games display as running at 60fps but on the off-chance this is incorrect I will look into adding the fixed timestep.

Many Thanks
Mark

I’d just like to point out that in our iOS version we had to switch the Optimization Level to None [~~o0] in order to have the Release Build match the Debug build physics. Could some optimization be occuring when building for Android causing a similar issue?
For reference, here is our Android.mk and Application.mk files,
ANDROID.MK
<pre>
LOCAL_PATH := $
include $
LOCAL_MODULE := game_shared
LOCAL_MODULE_FILENAME := libgame
LOCAL_SRC_FILES := hellocpp/main.cpp …/…/Classes/AppDelegate.cpp …/…/Classes/GameScene.cpp …/…/Classes/MenuProfile.cpp …/…/Classes/MenuScene.cpp …/…/Classes/MenuScores.cpp …/…/Classes/MyContactListener.cpp …/…/Classes/PhysicSprite.cpp …/…/Classes/SplashPublisher.cpp …/…/Classes/SplashTitle.cpp
#CLASSES_ROOT := $/…/…/Classes
#CLASSES_SRC_FILES := $/*.cpp)
#LOCAL_SRC_FILES = $=)
# Scoreloop files
LOCAL_SRC_FILES
= …/…/SDKs/upSL/android/jni_scoreloop.cpp …/…/SDKs/wrapper/SLWrapper/SLWrapper.cpp …/…/SDKs/wrapper/Utils/Logger.cpp
LOCAL_C_INCLUDES := $/…/…/…/cocos2dx/cocos2dx/platform $/…/…/libs/Box2D $/…/…/SDKs $/…/…/SDKs/wrapper $/…/…/SDKs/wrapper/SLWrapper $/…/…/SDKs/wrapper/Utils $/…/…/SDKs/upSL $/…/…/Classes
LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static
LOCAL_WHOLE_STATIC_LIBRARIES = cocosdenshion_static
LOCAL_WHOLE_STATIC_LIBRARIES
= box2d_static
LOCAL_WHOLE_STATIC_LIBRARIES = chipmunk_static
LOCAL_WHOLE_STATIC_LIBRARIES
= cocos_extension_static
include $
$ $ $
$
$
</pre>
APPLICATION.MK
<pre>
APP_STL := gnustl_static
APP_OPTIM := release
APP_CPPFLAGS :=~~frtti

Thanks