Just me, or SpriteKit in GMs terribly broken?

I've updated to ElCap GM, XCode 7GM, and iOS 9GM and a project I'm working on seems to be broken at every turn.


  • Atlases don't work properly
  • Atlasses in Asset Catalogs don't work properly
  • still getting PKPhysics* types in methods expecting SKPhysics* types
  • the Actions editor is buggy as **** and doesn't properly handle image references
  • sizing of physics bodies based off of textures seems to not work right...


I've filed bugs where possible (way back in early betas), some of these issues are intermittent or difficult to track down... but it certainly doesn't seem to me that SpriteKit is anywhere near ready for release. Am I doing something just fundamentally wrong?


At this point, my project is so full of kludges to avoid crashing left and right, I don't know if I'll every be able to release it 😠

Replies

Hi Greven,


I use the SKSCropNode for drawing character's eyes. The pupil is drawn inside a crop node, with a mask that matches the shape of the eye. I have up to 7 characters on screen at once - each pair of eyes is one crop node. Since the pupils can move around within the eye, I can't rasterise or flatten the node.


I undestand that they're not particularly performance light, but it's only since iOS9 that there have been performance issues rendering more than a few SKCropNodes. The sample program I submiteed with my bug shows this when run alongside iOS8.


I have managed to get my app running better through flattening other nodes to reduce the node and draw count, but SKCropNodes are essential and still seem to be the main performance hit. If I render my scenes without eyes, everything runs and a consistent and solid 60fps.


Thanks

Hello Greven!


Let's take a look at 2 situations:


1. There is SKCropNode which has 1 child.

2. There is exactly the same SKCropNode with the same mask, but it has 40 children, all of them moving.


Will both have the same GPU/CPU load or the second one will take more resources?


In other words: should I move 40 moving sprites to another node and avoid putting them as children to SKCropNode?


Thank you!

Hi Digicub,


Great to hear you've had some luck with rasterizing for the other parts of your scene. It is a very useful technique in general and is employed heavily as a memory vs speed trade off.


The performance concern you are going to have relates to the number of pixels touched. There are two techniques employed for masking at draw time; a stencil buffer bitmask and a gradient alpha buffer mask. The technique picked depends on the overdraw situation and the need for antialiasing among other reasons. Both techniques have a per pixel overhead that is non-trivial, however the alpha buffer technique is more expensive but has no visual glitches or overdraw issues. If drawing the pupils under the face works that would be much cheaper than masking - which gives you a hint of the cost.


Cost is basically broken down as :


1) a set per pixel cost for the size of the mask (roughly equivalent to drawing the mask alpha blended on top)

2) a per pixel cost for each object drawn inside the mask no matter if it is masked out or not - the test to see if it is included or not is the expensive part.


As the number of pixels touched increases so does the cost.


If the pupils don't move every frame you may still get a significant win by using an SKEffectNode and letting it choose when to re-rasterize. It will automatically detect a change and re-raterize as per the SKEffectNode.shouldRasterize documentation:


"When caching is enabled, changes to the effect node’s children trigger updates to the cached image in the next frame of animation. However, changing the filter’s properties does not."


Hope that helps.


Cheers

Hi pavel,


The one whose children touches more pixels is going to be the expensive one. The number of children matters less than the number of rasterized fragments that need to be tested against the mask. Whenever you can avoid putting them as children of a crop node that is best.


SKCropNodes are best used where a draw order solution doesn't work. Otherwise they should be avoided as there is a large GPU cost to masking. They are there because sometimes there is no other way to make a certain effect, however they are not cost-free.


Othewise see the response to Digicub for more info.


Hope it helps


Cheers

Thank you for the feedback Greven. Is there any way to force the SKCropNode to use the stencil buffer bitmask technique instead of gradient alpha buffer mask, since it's cheaper?


Unfortunately I can't draw the eyes under the face (would need 100s of face/eye-hole combinations), but I could potentially add a skin-coloured eye-shaped mask in front of the pupils. Seems a bit hacky, but at least would remove the need for a crop node.


I'm not sure I understand how I could use an SKEffectNode to do the same thing though?


Thanks!

So does anybody know how to get rid of


Invalid Request: requesting subtype without specifying idiom


message that we see so many times without obvious reason?


And it looks like we have 9.2 released to everybody, which is good. But 9.2 is the same build as 9.2beta4, which is not so good, because FPS of beta 4 is not as it was in 8.4 and (i believe) worse than it was in beta3.

I got this message after install XCode 7.2 and only when I ran in iphones on simulator. In real devices does not show me this message.

What's the recommendation for transitioning to another sprite framework? Is Unity a good choice? Apple seems to have abandoned SpriteKit but they haven't provide recommendations as to what people should move to.

I've also got some clients who want to stick with Sprite Kit and some who wanted to abandon it and move to Unity. So I'm dealing with both now.


The Unity bad for me


1. It's a much more complex framework and it takes longer and more resources to get stuff done

2. Learning curve - It's a massive framework and I don't think one person could get to grips with all of it

3. Very time consuming to debug memory and low level crashes

4. It's another skill set to keep on top of

5. You get Andriod distribution, but that's not without a host of other issues


In short, its harder to deliver a product. It takes longer, costs more, and is more complex


The Unity good for me


1. Plenty of developers and designers are comfortablel working with it

2. Stable enough

3. Developer support actually provide developer support


Gaming seems to be a cornerstone of the Apple TV strategy - so Sprite Kit has not been abandoned .

I don't know what's going on inside Apple - From my point of view, Sprite Kit on IOS 8.4 was great. But on IOS 9+ there has been a terrible drop in the engineering quality. 9.2 is definately a major step up - but I still found a memory leak within 5 minutes of using 9.2

Commercially, I've never seen a major vendor treat it's "valued" developers so shabbily - they basically hung everyone out to dry by shipping something they must have known would break existing Apps (and damage developers revenues and reputation), with no developer communication. Not even an acknowledgement in any of the release notes, posts to forums.. etc. Just complete silence.

The whole episode cost me considerable time, money, and reputation with my clients thinking I've created terrible products.

Now I give clients two options:

1. Unity = expensive - more resources & takes longer

2. Sprite Kit = Cheaper and shorter delivery - I point them to this page and let them take the business risk

Hi Digicub,


There is no way to reliably force either one as the decision is made at render-time depending on the content and the blend and batching state. We did tune the algorithms in 9.2 based on feedback from the forums, so thanks for engaging with us, and hopefully your content is more performant on 9.2.


Heavy SKCropNode usage is uncommon on the store, with less than 5% of the SpriteKit games on the store using it at all. Amongst that group the requests were overwhelmingly about correctness in layering cropped content, thus it was prioritized. Speed vs memory tradeoffs are at the developers fingertips by either reorganizing content or rasterizing via an SKEffectNode or straight to an SKTexture.


In your case you could probably use an SKEffectNode and set it to rasterize; thus you would only pay for the cropping when the eyes move relative to the face, instead of every frame regardless of movement. That would be a memory vs CPU/GPU tradeoff that you can control.


Hope that helps.


Cheers

Today Apple replied to my bug report opened in October 2015 "Any scene built with SpriteKit performs with significantly smaller FPS than it was on iOS 8".


Wow. Can't wait to jump into my time machine and find me iOS8 to compare it with ios11.