Hi all,
With the iOS 9 release I decided to remove my game from the store, because it was totally broken (Sprite kit game implemented in Swift). Meanwhile I did implement many workarounds (such as using my own gesture recognizers as sometimes nodes did not receive touch messages and so on). Now the frame rate is again at 60 fps during the entire game except for the first time two nodes are removed from the scene by the player - which is finally the goal of this game. In my game the player needs to move gaming pieces together so they are touching and will be removed. During this removement a sound is played and an SKEmitterNode shows a very short particle effect. SKEmitterNodes are also used in other parts of the game, but they are all working fine. However, for the first time two nodes are removed it takes several seconds until the scene continues to render. When I repeat this first level it works well to. I also tried the following things:
- removed the SKEmitterNode and all SKActions, just called removeFromParent for the two nodes
- only set the hidden property to try without any animation
- set PreferOpenGL in info.plist
Nothing helps! I did some measurements and for me it looks like this is a CPU-bound effect, but the measured times inside my app are all very small. When I have a look at the Metal system trace using Instruments I can see a gap of nearly 2,0s where just nothing happens for exactly this situation! Meanwhile I could find the issue: its a spritekit internal call:
Running Time Self (ms) Symbol Name
1722.0ms 85.8% 0,0 __51-[SKView _vsyncRenderForTime:preRender:postRender:]_block_invoke
=> 1713.0ms 85.4% 0,0 SKCRenderer::render(SKCNode*, float vector[4], std::__1::shared_ptr<jet_framebuffer> const&, unsigned int vector[4], matrix_float4x4, bool, NSDictionary*, SKCStats*, SKCStats*)
=> 1678.0ms 83.6% 0,0 SKCRenderer::buildRenderPass(std::__1::shared_ptr<SKCRenderPass> const&)
15.0ms 0.7% 0,0 SKCRenderer::flushRenderOps()
What can I do to avoid this situation??? Or is this already a known issue of spritekit fixed in the furth-comming iOS 9.2 release? At the moment I cannot bring my game back into store, because this is not the user experience users expect on Apple devices.
Thanks a lot for any advice you can give to me...
Best regards,
Juergen
After this post I dived in deeper into the stack trace of the Instruments measurement. The method buildRenderPass calls
Running Time Self (ms) Symbol Name
1673.0ms 83.4% 0,0 SKCLabelNode::rebuildFont()
When this happens a SKLabelNode will be shown with the scores for the first time using the system font. I don't know why this is an issue in iOS 9.1 on real devices and no performance issue on previous iOS versions or within the simulator, but precreating the SKLabelNode and using a copy of it for this animation did the trick! Maybe in iOS 8 and on the simulator it is not so time consuming to create a font to be used for SKLabelNode. It took me two days to find this out, but maybe this information will be helpful for others.
Best regards,
Jürgen