Sprite Kit is the new “graphics rendering and animation infrastructure” from Apple, which came out with the release of iOS 7. It provides similar functionalities to existing Open Source projects like Cocos2D and Sparrow, but in addition to being just a graphics engine, it also includes physics support out of the box. It is very easy to build complete physics powered games using Sprite Kit, but this simplicity also comes with it’s downsides, as you’ll see in this post.
We have recently finished our first Sprite Kit game for the iPhone: Tapathon! Touch Racing. Having now built a complete game using Sprite Kit, I want to share my first experiences and feelings about it.
1. Intuitive and easy to use API
Having an Adobe Flash background, it was very easy for me to jump right into Sprite Kit. Game objects are organized in a tree structure and every object inherits from SKNode. There are all kinds of SKNodes: SpriteNodes which render Rectangles or Textures, ShapeNodes which render arbitrary shapes, EmitterNodes for particle systems and so on. Very straight forward.
2. Built in physics engine
Every SKNode also has a property named physicsBody, which brings things to life. Just as expected, physical bodies can consist of arbitrary shapes like rectangles, circles, polygons, paths and so on. The API is very similar to the popular physics engine Box2D and it’s built right into Sprite Kit. It’s just so easy and intuitive! Wow!
3. Particle system
The particle system is probably the coolest thing about Sprite Kit. You get the WYSIWYG Editor built right into XCode – no need to jump between IDE and external or web based tools to design your particles. The particle system is really feature rich and flexible. Any aspect can also be changed by code during the animation and you can even add custom actions to each particle created.
4. Node searches
Sprite Kit provides an interesting feature called advanced searches. With advanced searches you are able retrieve named nodes from the tree that match queries specified in Sprite Kit’s own search syntax. It is possible to search descendants recursively or search parents up to the root and include wildcards in your query. I find this feature very interesting and have not seen such a thing in game frameworks before. However, I have not made much use of it yet.
5. Action system
I’ve never used Cocos2D, but I know that the concepts behind Sprite Kit’s action system are borrowed from Cocos2D and I really like it. I am used to tweening engines like the one Sparrow uses and find the action system to be a bit more precise and easy to use. You can also create complex animation-chains and even reverse them. I am only a bit disappointed by the provided timing modes since the only existent modes are linear, easeOut, easeIn and easeInOut. I am missing things like bounce, back or elastic.
1. No custom shaders
This may not be a big drawback for the average game, but since we cannot plug in any custom render code, we will eventually hit the visual limits of Sprite Kit. For custom rendering we still require an open source framework, or must write our own game engine on top of OpenGL ES.
UPDATE: Custom shaders will be supported in iOS 8!
2. No predictable physics
The physics system adjusts it’s running speed according to the framerate. This means that if your simulation runs on a slower device, which cannot draw at the full framerate of 60 FPS, it will adjust it’s increments to keep up with the speed. This sounds like a good thing in the first place. The downside of this is that the physics will become more and more unstable, the more the framerate drops.
While the example shown might be a bit extreme (60 FPS vs 3 FPS), there are genres where even small differences in the simulation cannot be accepted. One of the most well-known solutions to this is to use a fixed timestep. I could not find out how I could enable this in Sprite Kit.
3. Limited extensibility
For larger projects it’s appealing to subclass SKNode and to provide your own reusable node classes – even Sprite Kit’s documentation suggests to do so. It’s just very disappointing that this is so limited. Correct me if I am wrong but I couldn’t figure out any clean way to get notified when the node is being added or removed from a parent node, so you have neither access to the parent node, the scene nor the physics world – the latter will deny you from placing physical joints within the node. Even worse: there seems to be no update or render method to override.
4. No scene stacking
Sprite Kit can only present one scene at a time. I would rather have a scene stack where I could push/pop scenes to and maybe have multiple scenes running at once. However this would make Sprite Kit more complex, so in this point I am a bit unsure.
5. Existing pitfalls
Some things in Sprite Kit don’t work as expected:
Multi-tasking: If your game is pushed into the background, Sprite Kit won’t automatically pause your game correctly, instead, it will just crash with EXC_BAD_ACCESS (gpus_ReturnNotPermittedKillClient). This means you have to do this by yourself. That’s not that big a deal, it’s just a bit disappointing that it’s not included out of the box in a framework that aims for simplicity.
- Stretched Textures: SKSpriteNodes support a centerRect property which you can use to make your texture stretchable in a Scale-9 grid.
But beware! This feature does currently not work as expected, the result looks like crap! I hope Apple will solve this soon.
UPDATE: Use the setXScale and setYScale methods and it will work just fine. I was reassigning the size property, which did not actually scale the sprite, but re-assign the native size of the sprite.
Scene Setup: Setting up the coordinate system correctly for the scene is not very well documented and the correct solution is not very intuitive. Please check out the post from my colleague Thomas.
I really like Sprite Kit. It’s the perfect fit for small games such as Tapathon and most likely also some bigger projects. I guess that at some point it will stop being so useful because of it’s limited extensibility and for some genres, the physics system will just not be stable enough. However I really like its simplicity and expressive API – you can create simple game prototypes in no time.