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

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

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.

Unfortunately this is a problem, for which there is no sure answer; at least not without access to your system to run a whole variety of checks.
The failure in the profile may be because your game is running tight loops the timing of which get's upset in unpredictable ways and your game is crashing due to timing or resource issues (where those timing issues don't crop up with the debugger in the same way). If that's the case, there is probably not much you can do about it. Or it may be because there is a problem in your code. The problem is it can be very difficult to figure out which of these is the case. It's probably best to assume the problem is in your code though and do some further investigation.
The first thing to do, if you haven't done it already, is run the static analysis tool (Analyse from the Product menu in Xcode). Consider each of the raised errors carefully, and work to remove all of them. Sometimes they might seem obvious and you think you can ignore them, but some prodding reveals they are a symptom of a deeper problem.
If you haven't tried already, try running the instrument to check for zombies. There's a high chance this will fail also if the allocation instrument is failing, but if there are some stale references to de-allocated objects hanging around they could be causing the problem you are experiencing. Another instrument you can try is the performance analyser, to check where your app is spending most of it's time. There may be some really significant problem with the overallocation of resources you are not aware of. If you can't run the memory profiler, it will be difficult for you to see if this is the case, but using the performance analyser, it might be possible to see if your app is getting hung up for too long somewhere it shouldn't be.
Lastly - if all else fails and this may be a sledgehammer to crack a nut - and also may not in any case provide the solution. If you aren't using ARC, consider how long it would take to convert your app to using it (definitely create a branch first before doing it though). The Apple algorithms for object allocation/deallocation are very efficient and there is a very good chance if you have subtle memory management errors, they will be eliminated by Automatic Reference Counting.

Related

how to know that where exactly app getting stuck in xcode?

My app gets stuck for a specific operation and that operation is too big having so many method calls and services requests, so i cannot put breakpoints on each method and debug, is there any other way i can get to know where exactly my app is stucked in xcode?
The operation wasn't too big to write the code, so it isn't too big to add breakpoints, logging statements, assertions and so on.
The only other way that works sometimes is taking a long shower in the morning, not thinking about work at all, and suddenly the realisation what you did wrong jumps to your mind. It has worked for me sometimes, but the first method is more reliable.
If you have reason to believe that the most time is spent in one operation, just let it run with the debugger attached and then press the pause button and see where you are...
A somewhat niftier approach would be to start with Instruments (i.e. the Time Profiler). It's easy to use and should be the first weapon of your choice for performance issues.
You can set a conditional break point in Xcode to debug a specific condition, for more detail go through Jeffrey Sambells blog!

XNA Update() function update rate, varies greatly on different machines

I'm coding an emulator in XNA. The emulator's accuracy depends greatly on real fps. The fps must be 60 per second. While Microsoft claims their update function on FIXED TIME SETUP, should be called exactly 60 times per second, in my emulator (or a blank XNA 4.0 refresh project), I've collected these values so far, using differect processors: AMD athlon 2x 6000 (the unsynced ones, that need an extra optimized update from AMD to run correctly) 60-61 tps. Intel i5 (2.8 i think) 55tps. On an old Lenovo laptop with a slow centrino 59-60tps (the desired one). Same goes for an old intel p4 hyperthreading; exactly 60 tps. On a DELL implementation (don't remember the cpu) it was 52-53 tps.
So what should I do. Timer's accuracy on seperate threads is horrible too. Besides, the update function will be called too in parallel (using almost 100% of the cpu).
Make a different profile for each cpu? (Assume that the tps, [times per second] counting is correct)
The Update method calls are not 100% fixed. On a PC they will try to be made 60 times per second, but that depends on the machine and the logic of your game.
You can check if the system is working slower than it should by checking the GameTime.IsRunningSlowly property on your game (link here).
Also, you can modify the ticks it makes every second, for example a phone project starts with 33 ticks per second configured, against the 60 of a normal Windows Game project.
It would be wise to check Shawn Hargreaves blog post about GameTime, it won't fix your problem but you will give you a better understanding of how the Update method works and maybe get an idea on how to fix the problem.
I quote part of his post here:
By default XNA runs in fixed timestep mode, with a TargetElapsedTime
of 60 frames per second. This provides a simple guarantee: •We will
call your Update method exactly 60 times per second •We will call your
Draw method whenever we feel like it
Digging into exactly what that means, you will realize there are
several possible scenarios depending on how long your Update and Draw
methods take to execute.
The simplest situation is that the total time you spend in Update +
Draw is exactly 1/60 of a second. In this case we will call Update,
then call Draw, then look at the clock and notice it is time for
another Update, then Draw, and so on. Simple!
What if your Update + Draw takes less than 1/60 of a second? Also
simple. Here we call Update, then call Draw, then look at the clock,
notice we have some time left over, so wait around twiddling our
thumbs until it is time to call Update again.
What if Update + Draw takes longer than 1/60 of a second? This is
where things get complicated. There are many reasons why this could
happen:
1.The computer might be slightly too slow to run the game at the desired speed.
2.Or the computer might be way too slow to run the game at the desired speed!
3.The computer might be basically fast enough, but this particular frame might have taken an unusually long time for some reason. Perhaps
there were too many explosions on screen, or the game had to load a
new texture, or there was a garbage collection.
4.You could have paused the program in the debugger.
We do the same thing in response to all four causes of slowness: •Set
GameTime.IsRunningSlowly to true. •Call Update extra times (without
calling Draw) until we catch up. •If things are getting ridiculous and
we are too far behind, we just give up.
If this doesn't help you, then posting some code showing what you think may be making the process slower would help.

removeWithCompletionHandler causes logging out of Game Center

I am using GKTurnBasedMatch's removeWithCompletionHandler to programmatically remove old (finished, i.e., with status = GKTurnBasedMatchStatusEnded) turn-based matches from Game Center when needed (to avoid extra loading burden, I want to keep the amount of finished matches to a minimum).
I am getting no error and the match is correctly removed.
However, most times I do this, my user gets kicked out of Game Center, so the local player is no longer authenticated. This happens on iOS7, with both iPhone and iPad.
Did anyone experience this? Is there any way around it?
NB: I might as well not remove matches from GC, as I use internal business logic to determine which matches should be listed to the user and show, say, only the 10 (unfinished) most recent ones. However, I am afraid that hundreds of games might be kept in GC and that this might slow down interactions with GC when I have to list ongoing matches.
If you're calling removeWithCompletionHandler inside of a completion handler for another Game Center API call then you might be experiencing the very same issue that's been plaguing me for a while. The solution I tried today involves simply delaying the call to removeWithCompletionHandler for a few seconds, like so:
[match performSelector:#selector(removeWithCompletionHandler:) withObject:^(NSError *error) { /* callback code here */ } afterDelay:3.0];
For me, this worked great but meant I had to rework a few things in relation to displaying active games... so be wary of that if this solution works for you. Also, it's worth noting that the 3 second delay is an arbitrary value I picked and it worked for me.
In my case, I was calling removeWithCompletionHandler inside the completion handler block for the various quit methods on GKTurnBasedMatch.
I imagine there is some issue on Game Center's end where the two requests cannot be made so close together without resulting in such woe. This is evidenced by the fact that the issue did not ever occur for me when I slowly stepped through the calls to Game Center.
EDIT
Here's some cool news; seems like they've fixed the bug in iOS 8. I built an app which demonstrates the bug for bug-reporting purposes (originally for iOS 7). I've tested that same app running in iOS 8 and it seems that the bug has been squashed.
Finally.
IMO, you should consider adding the removeWithCompletionHandler call in now.

iOS touchesMoved delay between first and second calls

I have some problems in my iOS app.
I have checked timestamps in the touchesMoved with clock() function and use difference between current and previous values. Difference between 1st and 2nd events is greater than others.
Have you any ideas?
iOS is not a hard-realtime OS. There is generally no expectation that touch events will be delivered with regular frequency/uniform periods. You should not structure your app to depend on that. Events are delivered via the main thread, which could be delayed by other processing (drawing, etc.)
EDIT: If you're seeing huge differences in periods between the 1st and 2nd touches (relative to the periods between subsequent touch events), the first step would be to run the app in Instruments' Profiler template to see if some work that you're doing on the main thread in response to the first touch is causing the delay. If the delay is of your own doing, then fixing that is the first order of business.
Beyond that, you could try using various signal processing approaches to re-sample your data into uniform periodic data, but the problem is that any of those algorithms won't be able to deliver the first re-quantized point until at LEAST the 2nd (and more likely the 3rd or even later) event comes in, so if the principal problem is "The 2nd event doesn't come as soon as you'd like", then this won't help you.
Another good test: Try making an empty single-view sample app that does nothing but log the events as they come in -- if you see the same "odd" delay between 1st and 2nd touches in that trivial sample app, then that's just "how it is," and you can stop wasting time trying to change the OS behavior and move on to some different approach/solution.

I'm making a multiplayer game and I need to verify that players aren't speed hacking

For security reasons I have a feeling that that testing should be done server side. Nonetheless, that would be rather taxing on the server, right? Given the gear and buffs a player is wearing they will have a higher movement speed, so each time they move I would need to calculate that new constant and see if their movement is legitimate (using TCP so don't need to worry about lost, unordered packets). I realize I could instead just save the last movement speed and only recalculate it if they've changed something affecting their speed, but even then that's another check.
Another idea I had is that the server randomly picks data that the client is sending it and verifies it and gives each client a trust rating. A low enough trust rating would mean every message from the client would be inspected and all of their actions would be logged in a more verbose manner. I would then know they're hacking by inspecting the logs and could ban/suspend them as well as undo any benefits they may have spread around through hacking.
Any advice is appreciated, thank you.
Edit: I just realized there's also the case where a hacker could send tiny movements (within the capability of their regular speed) in a very high succession. Each individual movement alone would be legite, but the cumulative effect would be speed hacking. What are some ways around this?
The standard way to deal with this problem is to have the server calculate all movement. The only thing that the clients should send to the server are commands, e.g. "move left" and the server should then calculate how fast the player moves etc., then finally send the updated position back to the client.
If you leave any calculation at all on the client, the chances are that sooner or later someone will find a way to cheat.
[...] testing should be done server side. Nonetheless, that would be rather taxing on the server, right?
Nope. This is the way to do it. It's the only way to do it. All talk of checking trust or whatever is inherently flawed, one way or another.
If you're letting the player send positions:
Check where someone claims they are.
Compare that to where they were a short while ago. Allow a tiny bit of deviation to account for network lag.
If they're moving too quickly, reposition them somewhere more reasonable. Small errors may be due to long periods of lag, so clients should use interpolation to smooth out these corrections.
If they're moving far too quickly, disconnect them. And check for bugs in your code.
Don't forget to handle legitimate traversals over long distance, eg. teleports.
The way around this is that all action is done on the server. Never trust any information that comes from the client. If anybody actually plays your game, somebody will reverse-engineer the communication to the server and figure out how to take advantage of it.
You can't assign a random trust rating, because cautious cheaters will cheat only when they really need to. That gives them a considerable advantage with a low chance of being spotted cheating.
And, yes, this means you can't get by with a low-grade server, but there's really no other method of preventing client-side cheating.
If you are developing in a language that has access to Windows API function calls, I have found from my own studies in speed hacking, that you can easily identify a speed hacker by calling two functions and comparing results.
TimeGetTime
and...
GetTickCount
Both functions will return the number of seconds since the system started. However, TimeGetTime is much more accurate than GetTickCount, whereas TimeGetTime is accurate up to ~1ms vs. GetTickCount, which is accurate at around ~50ms
Even though there is a small lag between these two functions, if you turn on a speed hacking application (pick your poison), you should see a very large difference between the two result sets, sometimes even up to a couple of seconds. The difference is very noticable.
Write a simple application that returns the GetTickCount and TimeGetTime results, without the speed hacking application running, and leave it running. Compare the results and display the difference -- you should see a very small difference between the two. Then, with your application still running, turn on the speed hacking application and you will see the very large difference in the two result sets.
The trick is figuring out what threshold will constitue suspicious activity.

Resources