Search code examples
ioscocos2d-iphoneinstruments

ios game gets out of sync while analysing process in Instruments - how can I avoid that?


I am building an iOS game and I notice that the game performs fine while running normally in the XCode debugger. However, when i run it from within Instruments (Product-> Profile to trace Leaks), the game freezes when Instruments displays 'Analyzing Process' in the left sidebar. After that the game messes up all its state since some parts of the game that were being analyzed froze up while other parts kept going.

Is this something I can/need to fix or is it sufficient to make sure the game runs in release?

If a fix is needed, what do I need to do to make it work?

Update 1:

So we found the issue - the same problem repros even if we are playing the game, press the home button and click on the game icon and continue playing.

The issue is that most of our work is done in the update method, and it relies on the value of the (ccTime)dt parameter. The value of dt is usually < 0.1 seconds, and occasionally somewhere upto 0.5 seconds).When we pause (either by clicking the home button, or when instruments pauses the game to take a snapshot) and resume playing, the value of dt is several seconds! And that throws all our calculations out of range.

We tried a temporary (but ugly) workaround that fixes the issue: at the beginning of the update method, we add this:

if(dt > 1)
  return;

And it now works as expected - doesn't go out of sync. However, this is not a permanent solution, since sometimes, the values of dt are legitimately close to 1 second, and in resource crunched situations, this may lead to stutter (or worse).

We also considered another (equally ugly) solution of storing the previous value of dt, and then check in the update method:

if(dt > 10 * prevDt)
{
  return;
}

We tried calling unscheduleUpdate in AppDelegate.m's applicationDidEnterBackground, and called scheduleUpdate in the applicationWillEnterForeground method, but that approach did not work.

What is the best way to deal with updates with erratic time values due to external pauses?

Thanks Anand


Solution

  • I don't know much about how cocos2D works, but if you've run out of options, I would simply clamp the delta time to an upper range. In whatever update methods used delta time, I would do the following.

    double delta = (dt > 0.5) : (0.5) ? (dt);
    

    Use delta instead of dt from that point onward. The result is that any frame with a delta of over half a second will be limited to a delta of half a second. You don't want to skip frames, because then you could potentially skip many frames in a row which would be bad for the user; they'd probably think the app crashed or something. However, you don't want to run a frame with a large delta because then delta-dependent objects and forces will get multiplied many times for that frame, preventing you from catching collisions and stuff. So, we prevent the game from getting completely screwed over while not skipping frames by simply clamping the value downwards.

    The negative is that the app will appear to move more slowly when your frame rate drops to 2 frames per second. You lose the benefit of a time-based update method, which is the ability to always make the game appear to run at a well defined speed, when the engine is overburdened.

    To be honest, if you ever run at 2 frames per second for an extended period of time, you've got bigger problems to worry about. I don't think the user will notice if objects move slightly more slowly per second if the game is only rendering once every who-knows-when anyways.