Strange stutter in box2D on different Android devices

I develop the engine and the game simultaneously in C ++, and I use box2D for the back of the physics. I am testing various devices for Android and on 2 of 3 devices, the game works fine, as well as physics. However, on my galaxy 10.1 tab, I sporadically get a kind of stutter. Here is a YouTube video showing:

http://www.youtube.com/watch?v=DSbd8vX9FC0

The first device the game is running on is Xperia Play ... the second device is the Galaxy Tab 10.1. Needless to say, the Galaxy tab has much better hardware than the Xperia Play, but Box2D lags behind random intervals for random periods of time. The code for both machines is exactly the same. In addition, the rest of the engine / game is actually not far behind. All this time it worked at a speed of 60 frames per second. Thus, this “stutter” seems to be some kind of delay or failure when actually reading the values ​​from box2D.

The sprites you see move around, checking to see if they have an attached physical body during rendering and set their positional values ​​based on the world position of the physical body. So it seems that in this particular process, box2D does not seem to be in sync with the rest of the application. Pretty strange. I understand that this is a long shot, but I decided that I would send it here anyway to see if anyone has any ideas ... since I'm completely at a standstill. Thanks for any input in advance!

Oh P.S. I use a fixed time step, as this seems to be the most frequently offered solution for such things. I switched to a fixed time step, developing it on my desktop, I ran into a similar problem only more serious, and the solution was a fixed step. Also, as I said, the game works stably at a speed of 60 frames per second, which is controlled by a timer with a low latency, so I doubt that this is the problem. Thanks again!

+4
source share
2 answers

As I mentioned in the comments, this led to a timer resolution issue. I used a timer class that was supposed to access the system timer with the highest resolution, cross platform. Everything worked perfectly, except when it came to Android, some versions worked, and some versions did not. One such case was the 10.1 tab of the galaxy.

I ended up rewriting my getSystemTime() method to use a new addition to C ++ 11 called std::chrono::high_resolution_clock . This also works great (everywhere except Android) ... except that it is not yet implemented in any Android NDK. It is assumed that it will be implemented in version 5 of the NDK R7 chip, which at the time of this message is 80%.

I did some research on various methods of accessing system time or something, thanks to which I could create a reliable timer on the NDK side, but all it does is that these various methods are not supported on all platforms. I went through the painful process of writing my own kernel from scratch just so that I could support every version of the android, so betting on incompatible methods is pointless.

The only reasonable solution for everyone who is faced with this problem, in my opinion, is to simply abandon the idea of ​​implementing such code on the NDK side . I am going to do it on the Java side instead, since so far in all my tests it has been reliable enough for all the devices I tested on. More on this here:

http://www.codeproject.com/Articles/189515/Androng-a-Pong-clone-for-Android#Gettinghigh-resolutiontimingfromAndroid7

Update
Now I have implemented my proposed solution to make timing on the java side, and it worked. I also found that processing any relatively large number, regardless of the type of data (the number, for example, nano seconds from calling a monotonous clock) on the NDK side, also seriously lags some versions of android. Thus, I optimized this as much as possible by moving the pointer to the system time to make sure that we do not go through the copy.

Finally, my assertion that the call of a monotonous clock by the NDK is unreliable, however, seems to be false. From Android Docking Stations to System.nanoTime () ,

... and System.nanoTime (). This watch is guaranteed to be monotonous, and is the recommended basis for synchronizing the intervals of general purpose events of the user interface, measuring performance and everything else that does not need to measure the elapsed time during sleep sleep.

Thus, it would seem, if this can be trusted, the call of the clock is reliable, but, as already mentioned, other problems arise, such as processing the allocation and resetting the massive number, which leads to the fact that the frame rate is almost reduced alone by two times on the Galaxy Tab 10.1 with Android 3.2. Final conclusion:, supporting all Android devices the same way, either damn close or not, and using native code seems to make it worse.

+2
source

I'm very new to game development, and you look a lot more experienced, and it might be silly to ask, but do you use delta time to update your world? Although you say you have a constant frame rate of 60 frames per second, maybe your frame counter is calculating something wrong, and you should use delta time to skip some frames when the FPS is low, or your world seems to "remain behind". I'm sure you are familiar with this, but I think a good example is here: DeltaTimeExample , although this is a C implementation. If you need, I can paste the code from my Android projects on how I use the delta time that I developed after this book: The Beginning of Android Games .

+1
source

Source: https://habr.com/ru/post/1396372/


All Articles