Gah, I’m pulling my hair out of an issue that seems to be occurring only on my iOS device (iPhone 6 running iOS 8) with the latest public build.
I have a game where objects are being thrown right-to-left on the screen and I am trying to catch them. In later levels, the number of objects increase, and at a random point in these later levels the game stutters for about half a second. When I connected my phone to the Xcode console window, I noticed at the point of stutter a crash report log had been generated, with the following message on the console:
Jan 3 00:09:36 DSI-iPhone ReportCrash[5213] \<Error\>: task\_set\_exception\_ports(B07, 400, D03, 0, 0) failed with error (4: (os/kern) invalid argument) Jan 3 00:09:36 DSI-iPhone ReportCrash[5213] \<Notice\>: ReportCrash acting against PID 5212 Jan 3 00:09:36 DSI-iPhone diagnosticd[5093] \<Error\>: error evaluating process info - pid: 5212, punique: 5212 Jan 3 00:09:36 DSI-iPhone ReportCrash[5213] \<Notice\>: Formulating crash report for process Boutique Blitz[5212] Jan 3 00:09:36 DSI-iPhone ReportCrash[5213] \<Notice\>: Saved report to /var/mobile/Library/Logs/CrashReporter/ExcResource\_Boutique Blitz\_2015-01-03-000936\_DSI-iPhone.ips
So I opened the device logs and noticed this in the crash log:
Exception Type: EXC\_RESOURCE Exception Subtype: WAKEUPS Exception Message: (Limit 150/sec) Observed 513/sec over 300 secs
Now, my game runs at 60 fps. If i tweak it to 30 fps the stutter / crash log problem never appears to happen. But 30 fps is not smooth for this game so that is not a solution or workaround for me.
I also have an enterFrame function, which I believe is the culprit. But I don’t know exactly what part is causing this issue to happen. Here’s my enterFrame function, I hope someone can give me an idea? (Warning: trying to figure out what I’m doing here will hurt your eyes and brain)
-- -- This is how it works: -- For each level there will be a certain number of thrown objects -- shown on the screen at once (Level 1 can only have 1 obj at once). -- We will call each set of objects on the screen a 'wave'. -- -- After a certain number of waves, the level is incremented, and more -- objects will be shown at once on the screen (i.e. the waves will be -- bigger). -- updateScene = function(event) ------------------------------------------- -- Wait for last obj in wave to be created ------------------------------------------- if timer\_handles["eachObjInWave" .. throw\_info.num\_waves] or game\_state == "game\_over" or game\_state == "paused" then return end -- NOTE: There will be a pause after the last object in wave is thrown, before -- next wave is thrown again. local check\_id = throw\_info.allowed\_at\_once -- In later levels, have no pause; check after a certain number of objects thrown if throw\_info.allowed\_at\_once == throw\_info.max\_allowed then check\_id = check\_id - 3 end for id = 1, check\_id do if throw\_info[id].obj then return end end local delay\_after\_previous = throw\_info.delay\_list[throw\_info.allowed\_at\_once] onscreen\_id = 1 throw\_info.bonus\_thrown = false local created --------------------------------------------------------------------------------------- -- Here we draw each wave (throw\_info.allowed\_at\_once) --------------------------------------------------------------------------------------- timer\_handles["eachObjInWave" .. throw\_info.num\_waves] = timer.performWithDelay( delay\_after\_previous, function() -- Create an object to throw, and perform three different transitions on it so that it -- does an arc from right to left. created = createThrowObj(throw\_info.level, onscreen\_id) if created then -------------------------------------------------------------------- -- If all objects have been thrown, we have completed a single wave -------------------------------------------------------------------- if onscreen\_id == throw\_info.allowed\_at\_once then throw\_info.num\_waves = throw\_info.num\_waves + 1 -------------------------------------------------------------------- -- Increase the level after a set number of waves -------------------------------------------------------------------- if (throw\_info.num\_waves % throw\_info.waves\_per\_level) == 0 then throw\_info.level = throw\_info.level + 1 if throw\_info.allowed\_at\_once \< throw\_info.max\_allowed then throw\_info.allowed\_at\_once = throw\_info.allowed\_at\_once + 1 end end end onscreen\_id = onscreen\_id + 1 end -- of IF created timer\_handles["eachObjInWave" .. throw\_info.num\_waves] = nil end, throw\_info.allowed\_at\_once) end