SpriteKit adds new features to make it even easier to create high-performance, power-efficient 2D games. See how tile maps enable you to lay out large scenes quickly and check out new APIs for warp transformations and custom shader attributes. Learn about focus-based interactions on Apple TV, rendering on Apple Watch, and new tools built right into Xcode for measuring performance and integrating with GameplayKit.
I'm Ross. I'm an engineer here in the Games Technology Team at Apple. And I'm really excited to be able to show you what we've been working on for the past year.
Before we jump into talking about the new features we're introducing this year, I'd like to take a moment to quickly recap what SpriteKit is for anyone who may not be familiar with it.
So, SpriteKit is our 2D graphics framework for games.
It's designed to be highly flexible and super easy to use while still offering great performance. So, there are as few barriers as possible between you and the great games that you want to make.
It's supported across all of our platforms including iOS, macOS, tvOS and this year we're proud to say that is available on watchOS as well.
Any app, I know, isn't that awesome? Any App that uses SpriteKit automatically gets access to the latest version of the framework available without needing to be rebuilt and redeployed, so you're always up-to-date. And it's naturally integrated with Swift, so you can use it, all these great features, from our newest language.
But the framework is only half of the SpriteKit picture.
The other half is our Xcode integrated live editor which lets you preview your scenes directly from the editor and lay them out visually.
It offers timeline-based animation which allows you to bring life to your games along with our robust particle editor.
It's fully integrated with the Asset Catalog, so you can leverage features like app thinning and on-demand resources without having to jump through any hoops. And this year we're introducing tile ap editing and GameplayKit integration, both of which we'll talk about a little later on.
And finally, SpriteKit is fully Metal-backed on all devices that support it, so you get access to its great performance benefits automatically without having to do anything.
So, this year we're continuing to introduce great new features that make it easier than ever for you to make great games for Apple platforms. So, without further ado, let's jump into what's new. Now, normally with sessions like this one, we'd put the tools stuff at the end. But today we're going to turn that on its head a little bit. And that's because the editor is absolutely integral to getting the most out of SpriteKit.
And this year we've got some really exciting additions. So, let's start with the scene outline view.
Knowing what's in your scene and how objects relate to one another is extremely important for effective scene management.
In Xcode 7, this was accomplished through the Jump Bar.
The Jump Bar is designed to make navigating between files in your workspace easier but when you're in SpriteKit, it also has all the nodes in your hierarchy. And this is great for navigating through those nodes but it would be nice if we could see the entire hierarchy at the same time.
So, now in Xcode 8 you can, with the new scene outline view.
It's a new panel that allows you to see all the nodes in your scene and their parent-child relationship simultaneously.
In addition to being able to select nodes, you can also rename them and remove them from the scene. You can also change their parent-child relationship of the nodes by dragging them around, much like you reorder keynotes, slides in keynotes.
Drag a child onto another node to make it a child, drag a node onto another node to make it a child of that node or drag a child out from its parent to break that relationship.
We also have the ability to lock and hide nodes.
Locked nodes can't be modified or selected from the scene view. And that can make navigating your scene much easier when you have a lot of notes and it's getting kind of cluttered. And the same with hiding. It's great for when you have really large objects and you want to access some nodes that might be behind them.
So, all these features make the scene outline view really useful and it's making, makes managing your scene much, much easier. So, next I'd like to talk a little bit about how we've begun to integrate the GameplayKit into the SpriteKit editor.
So, last year we introduced GameplayKit, a brand-new framework that offers ready to use solutions for problems that are commonly encountered when creating games.
One of the features included last year is entities and components, which is a design pattern that's focused on modularity and reusability.
Components encapsulate behavior and you assign them to objects or entities to change their behavior.
And you do this without having to write specific code for every object in your scene.
Now, we're not going to go into great detail about how these work but it's useful to think of components as code building blocks that you assemble in different ways to create objects that behave in different ways. Typically, you might have a component that represents health for objects that can be damaged.
Or a component that has physics data for objects that can collide with one another.
Or a component that allows an object to be a player controlled by player input. Components are really powerful and allow you to control how your objects behave.
And now we're bringing entities and components into the SpriteKit editor.
You can assign components that you create directly to the nodes from within your scene from the new entities and components panel of the inspector.
Additionally, you can choose to expose properties on the custom components you create and those will then appear in the editor and you can tweak them for each node.
The best part about all this is if you're already using GameplayKits, entities and components, we're now doing all the hard work for you and you can do all of your object composition straight from the editor.
Another great feature that GameplayKit introduced was pathfinding.
Pathfinding is all about finding the best route from point A to point B and it does this by operating what's called a navigation graph.
Navigation graphs are collections of nodes joined together by connections. And they describe how an object can move through your scene without colliding with any obstacles. And now we've integrated navigation graphs into the SpriteKit editor.
So, you can create and edit them directly in your scene.
You can add and remove navigation nodes and make connections between them simply by clicking in the editor.
And you can leverage the graph you create in code.
Creating the graph this way allows you to quickly and easily define how entities can navigate your scene, making pathfinding a breeze. So, now let's talk a little bit about a feature that helps you, yeah I know, it's pretty awesome, isn't it? Now to talk a little bit about a feature that helps you get the most out of your performance of your game, the FPS performance gauge. You may have used the FPS report in Xcode 7.
As you're running your App, you're provided a number of real-time performance statistics, including your frame rate, GPU utilization, and CPU/GPU frame time.
And this is really helpful for analyzing performance but further granularity would be great. Now in Xcode 8, you get, also get a timeline history of your SpriteKit apps time, frame time for both the CPU and the GPU.
Additionally, it breaks down the CPU time so you're able to see how much time is being spent rendering, running the update loop, evaluating the actions of physics and idle time.
This information can be immensely useful in determining where you need to focus your efforts to improve performance.
The FPS performance gauge is designed to help you improve your games on our mobile platforms. It's available for use with iOS and watchOS applications.
So, we've covered some great additions to the editor and now I'd like to change gears a little bit and talk about a new feature that's found in both the editor and the framework, tile maps.
So, for anyone who may not be familiar with what tile maps are, they're simply a grid of evenly spaced images.
And they're great for piecing together scenes from a set of small, repeating images, called tiles.
Think of tiles as, tile maps is a jigsaw puzzle and tiles as the pieces.
Individually they don't look like much but put them together and you can easily create large, detailed scenes.
So, before we get into the details of the feature, let's talk a little bit about why I might want to use them.
Building scenes from small repeating images is pretty common when creating games. And without tile maps, if you wanted to do this, you'd have to manually place each individual image by hand.
And this totally works.
And using a set of small images is great for keeping memory overhead low.
They can also be rearranged to make adjustments to how the scene looks.
However, copy pasting and manually aligning each individual image is really tedious and time-consuming.
It can also cause your scene to get cluttered with lots of nodes which quickly makes things really difficult to manage.
So instead you could use large, more detailed images with lots of detail. A sample game released last year, DemoBots, used this approach.
So, let's say one large image in your scene is practically instant and that definitely keeps your scenes clutter free. But if you want to change how things look, you need to make modifications to your source assets.
Plus, large images require more memory and if you want more variety in your game, you'll need additional large assets which in turn further increases your memory overhead.
So, tile maps gives you the best of both of those solutions.
They're easy to manage, as each tile map is just a single node in your scene.
They can be quickly modified.
Say for instance I want to change the sand tiles here to water.
All I have to do is tell the tile map to change the type and it's done.
And by using a set of smaller tile images, tile maps allow you to have large, detailed scenes with minimal memory overhead.
Tile maps are also great for lots of different games and art styles.
You can use them for top-down RPG's, side scrolling platformers, isometric city builders, hex-based board games. Tile maps are incredibly flexible.
So, as you've seen, tile maps are very visual and instead of just telling you that how they work, we're going to jump into a demo so I can show you. So, here we are in the SpriteKit editor and we've already got a tile map in our scene. So, let's go ahead and select that. And so the quickest way to start editing a tile map is simply double-click on it. And that brings up our new tile editing bar at the top of the screen here.
And by default, we have the brush tool selected which allows us to paint into our tile map. And so the paint, all we have to do is simply click and we start placing tiles in our map.
If you want to change what type of tile we're placing in there, all we have to do is click on our select tile button over here and that shows us all the different tiles I have available for placement.
So, here let's place edge tiles and a corner tile here and a couple more edge tiles. And we can see how can easily place, piece together your scenes this way.
But individually placing all these images is still a bit tedious. So, I'm going to show you better way of doing this.
So, here we're just going to a place a new tile map in our scene.
And by default on our tile maps, we have a feature in the inspector enabled called enable automapping.
And what this does is when I start to edit my map and I go to select my tiles, you'll see that instead of individual tiles for placement, we now have these groups of tiles here organized into different types of terrain, grass, dirt, stone and water. So, I'll go ahead and select one. And now when we go to place it in the tile map, we click and place the center tile in addition to all the edge tiles automatically. And this is really great for quickly and easily creating your scenes. Now, instead of having to place each individual edge tile and corner tile, we can just paint and it automatically sets up each of the tiles that we need here without having us to go through any extra hoops which a lot of time. That makes painting tiles extremely fast.
So, let's take a look at how the tile sets are put together.
So, the tile sets arrive in their own SKS file. And as you see here, you can see all of our different types that we have, like grass, dirt, stone, and water.
And you can see that they're arranged so that you can see how they're supposed to be put together. So, let's put a new tile group in here.
So, all we have to do to set up a new tile group that works with our automapping is to drag the tiles we want to use into their corresponding slots here. You can see that we have those silhouettes that vaguely what the tile's supposed to look like.
So, we'll just grab some tiles from our active browser be here. And we just drag-and-drop them in and it's super quick and super easy to set up a new tile group.
So there. Let's give it a name.
We'll call this one garden.
And that's it.
So now we can go into a scene.
We'll create a tile map here.
We'll start editing it.
And you'll see our garden tile group is already in here. So, I just grab that and start placing it. And you can see how easy it is to just set up a new tile group that already works with automapping. You don't have to do anything extra. But there's a little more that we can do with the tile groups as well. So, I'll go back to our tile, we'll go to another tile set that I premade over here. And at first glance it looks the same.
But then when I start clicking on these individual tiles here, you can see that we have a bunch of variants available for each tile. And this is the same for each one of our different slots here.
So, when we paint this tile group into a tile map, it will randomly select one of these variants for each tile. So, you can have a lot more variety to your tile maps. Additionally, you can assign weights to each of the styles, these variants.
See here, the red flowers have a plate, have a placement weight of 3.
White flowers have a placement weight of 2. And the blue have a placement weight of 1.
So, the red flowers are much more common than the white flowers and more common than the blue flowers. So, now let's go back to our scene.
We'll create another tile map and we'll assign our advanced tile set to it.
Now, when we start painting these tiles, you can see our variants are now showing up.
So, you can see the tiles sets are very flexible and allow you to achieve a lot of different looks without having to do a lot of work which is super useful.
So, another thing we can do with the tile maps is layer them.
So, here in the tile map on the left here, it appears as if there's just a single tile map.
But if I grab it here, you'll see that's actually 2 layered on top of each other. And so you see we can layer them on top of one another to make it make it appear as if we have more versatile tile assets than we actually have. So, it looks like these assets are designed to transition to the grass tiles. So, they actually have along the edges. So, when we move these guys over here, they just naturally transition to the grass. And so we move it on over onto the dirt to achieve the same effect. Now looks as if they're transitioning onto the dirt.
So, this allows you to get a lot more mileage out of your art assets. If you just have them transition to being transparent on the edges, you can layer them together and, any way you can conceive allowing you to get a lot more flexibility out of the art that you have.
So, another thing that we can do with our tile sets is they can be animated.
So, here we have a nice tile set with some grass and some water. We'll press the animate button and if you look closely you can see the shore line on the water tiles here is undulating. So, now let's take a look at the tile set for this set tile map.
Set the water. You can see, preview the animation straight from our tile set editor. And I can select one of the variants and you can see we just have, so we have a list of all the frames that are in our animation. Now, we give it a time per frame to set up the animation. Now, this is basically identical to how our animate with textures app should works.
And it's just that easy to set up animation. Which is a really great way of bringing life to your scenes.
But in additional to frame animation on the tiles, we can also animate the tile maps themselves.
So, the tile maps are just SK nodes. So, you can do everything you can do with an SK node. So of course you can drag them around. You can scale them.
You can rotate them. I note that you can still actually edit the tile maps while they're like this although it gets a little awkward when you're at some weird angles like this but, it still works.
But because SK nodes, the tile maps are just nodes, we can run actions on them. So, here you see I have a bunch of actions that I've already set up on my tile map by moving the scale and rotating it.
So, we just animate this thing. We can see yeah, we move, we scale, we rotate and then we put it back. And so you see that we have multiple ways of bringing animation to our tile maps which can be really useful.
In fact, we can leverage this layering and the animation to create some interesting effects.
So, in this scene, I've got three different layers set up in our tile map here.
Don't want to do that yet.
And if I position the camera over here and we hit animate, we're simply moving these tile map layers at different rates and this achieves the appearance of depth, an effect that we call parallax scrolling. And all I'm doing here is simply moving the foreground layer at one rate of speed, the middle ground layer at half that speed and the background layer at half that speed again. And that achieves the effect that we want. And it's just incredibly easy.
So, in addition to having simple square tiles in our tile maps, we also have support for hex tiles and isometric tiles as well. So, you have lots of flexibility in terms of the appearance that you can achieve for your game.
So, speaking of which, let's take a look at a game sample right now.
So, here we've got a little platform that I built.
A little guy that can run around. And you can see that I got the parallax scrolling going on in the background. And you'll note that I'm colliding with the tiles here.
And I achieve this by leveraging custom user data that we can put on each of our tiles. Here, I'll show you in our tile set. Select one of the variants here. And you can see that we have some user data over here.
And I just have a value called edgeTile which is a Boolean, and I set to 1.
So, in code, I'm going through the tile map in our platform demo here, and I'm looking for all of these edge tiles. And whenever I find one, I create some physics data to allow the player to collide with it.
And since it is just in our tile map here, say I wanted to get over this large wall here.
When I run the game, you'll see that my guy can't actually jump high enough to get over it. And he really wants to because that red button over there looks really tempting. I really want to push that thing.
So, since we're just generating our physics data from our tiles and our user data, all we can do is just going here and erase these tiles and build and run our game again.
The tiles are now gone and we can now move through there. And we didn't have to change code or anything. We just used the data that we pulled from the tile map to set up our tile. It's that simple.
And now as a reward, I get to jump on the button.
So, that's how our tile maps work in the editor.
So, now that we've shown you how they work in the editor, let's take a look at the framework side of things.
And if you're creating tile maps from within the editor, you're not going to need to bother with most of the stuff. But it's good to get an overview of how it works.
So, tile maps are implemented in class SKTileMapNode, which as mentioned in the demo is just an SKNode.
It holds all the information about the tiles you've placed in it.
But to be able to place tiles, it first needs a tile set. And the tile set is defined in the class SKTileSet.
It contains all the tile groups they can use.
Additionally, it also defines the type of tiles it can contain and they can either be regular square grid tiles, isometric tiles or hexagonal tiles.
The tile groups are defined in class SKTileGroup.
And as we saw on the demo, a tile group is a set of related tiles, typically things like type of terrain like grass or water.
The tile group also has the rules that define how the individual tiles in the group should be placed in the map. And those rules are defined in the class SKTileGroupRule.
That also holds all the tile variants that work with the pattern it describes. And finally, each tile is described through an SKTileDefinition which defines the appearance of the tile.
Each one has at least one image and as you saw in the demo, they can be animated with multiple images to help bring life to your tile maps.
Additionally, the tiles can be flipped and/or rotated, allowing you to get more out of your existing assets. Now, let's take a quick look at some code so you can see how you can create and modify a tile map through the API.
The first step is to get the tile set you want to use. Now, you can create these programmatically but it's a very involved process and we highly recommend that you create them using the tile set editor.
Getting one you've already created is easy.
Just call this convenience initializer with the name of the tile set that you want to use.
Then, to create a new tile map, we just need to provide it with the tile set we want to use and the number of columns and rows in the map along with the size of each tile.
If you want to start placing tiles in the map, we're going to need a tile group.
So, here we're just grabbing the first one that's defined in the tile set. Once we have a tile map and a tile group we want to place, we can start setting individual tiles.
Here we're setting our tile group on the tile at column 4, row 7.
We can also operate on the entire map at once. Here we are filling every tile on the map with our tile group.
So, if you're creating and modifying tile maps through the SpriteKit editor, you may not need to use any of the API we just covered.
But unless you're using tile maps for entirely static backgrounds, you want to, probably want to be able to query them. There are a bunch of useful things you can do.
Say for instance you want to detect when a player moves over a particular tile and inject some custom user data you've set on the tile definition.
You can do this by first converting the player's position and a tile maps frame of reference. Then, you'd use the methods highlighted here to get the column and row of the tile that contains that position. Next, you query the tile definition that exists in that column and row. And finally, now that you've got the tile definition, you can check the user data for the custom value that you're interested in. And then act on that data information however you want. And the demo we just showed, we're doing thing very similar to this to detect when the player jumps on the big red button.
When they are over a tile with a button custom user data property, we trigger the fireworks.
It's all a lot to take in, so let's quickly recap the features that tile maps offer.
By creating scenes from a set of small, repeating images, tile maps help you get more out of your art budget.
Overall, you'll need fewer assets and it also brings the benefit of reduced memory overhead.
They support animation, both in the form of animated tile images and actions at the node level.
Tile maps are designed to be layered on top of one another, which further increases the versatility of your art assets and enables effects like parallax scrolling.
They're extremely flexible and great for lots of different art styles and types of games.
Large tile maps are automatically divided into smaller chunks and only the parts that are currently visible are drawn which provides a big performance boost. Additionally, if all the tile images used by the tile map are in the same Asset Catalog, Sprite Atlas, each chunk will batch all the tiles together and render them with a single draw call.
Tile maps also come in a variety of flavors, standard square grids, isometric tiles and hexagonal tiles.
On the tool side, editing tile maps is simple and easy.
Just point and click to place tiles in your map.
Automapping does all the hard work for you so you don't need to individually place every edge and corner tile. And you can of course turn it off to do the detail work by hand.
Finally, creating new tile sets is extremely quick.
Just drag-and-drop the images you want to use into their corresponding slots in the tile set editor and you're good to go. So, that covers tile sets.
Now I'd like to invite my colleague, Clement, up to talk to you about the rest of the awesome features we have this year.
Thank you, Ross.
All right, some cool stuff, right? So, hello. My name is Clement.
I'm a software engineer here at Apple in the Game Technologies Team.
And guess what? We actually have more to talk about, so let's see what else is new in SpriteKit.
And the first up is Warp Transformation.
So, currently you have many ways to do transforms on your Sprite.
You can apply a scale to make things bigger or smaller.
You can apply a rotation to make it spin around the axis. Or if you like to get your hands dirty, you can also write a custom shader such as this low resolution shader that you can see right there. This year we're very happy to announce a new kind of transformation called Warp Transformation.
Warp Transformation allows you to define a custom distortion using degrees of points. So, for example if we take a 2 by 2 grid, it's basically 8 points and what you can see here in green is our source position, also called reference position.
Then I get a second grid here but it's going to mean a distortion.
So, what you see here is my definition position and as you can see, I move the points around to create a distortion. So now if I apply like this to my spaceship of earlier, this is what I get. As you can see, we get a nice and smooth distortion of a spaceship.
And the distortion is going to follow the displacement between the source and disposition position. So, let me show you some examples of what you can do with Warp Transformation.
And my first example is a squash affect. So, what I'm doing here is just bring the points towards the center to create a cool squash effect. Next, I had a stretch effect. I am pulling the nose of the spaceship and making it wiggle from right to left.
It can look a bit funny.
And the next big thing here is keyframe-based animation.
So, usually in 2D games if an artist is going to make static frames for animation.
And it's a pretty long process, especially if you need to iterate a new design multiple times.
And Warp Transformation, making animation is as simple as just moving points around. And if you have any complex scenarios such as a keyframe-based animation, you can just provide multiple grades and everything is going to be done at one time. You no longer need static frames.
So, now let me explain you the basic concept behind Warp Transformation.
So again, if we have a 2 by 2 grid here, we have an index set of points from 0 to 8 in the grid layout.
This point, this point, sorry, the grid, and the cells in this grid are quad with multiple triangles. So, now from the computer graphics standpoint, what we have here is a list of vertices like change and texture coordinates are actually going to be the same. And then you just set the GPU to the interpolation for us.
So, this is fine and we could just to stop here, but initially what happens if I use my 3D emoji, the cat emoji, and I limit it to one quad which is basically a 1 by 1 grid, so, come on. Show me some distortion. All right, go for it.
Yeah, it doesn't look quite right.
And the reason why is because we're only moving one point, so only one triangle is being distorted. So, what can we do about this? Well, we could make the grid more dense and upload more quads. But then it's kind of tedious for you because you have more points to manipulate.
Especially because Sprite is pretty big.
It's almost as if you had to, you know, move pixels around, right? So, no. As you have guessed, we have a trick here. So, in SpriteKit, this is what we do.
Again, 2 by 2 grid.
We, so you only have to manipulate 8 points and as you do the distortion of the points moving around, this is what happens.
There we go.
So, we do automatic quad subdivision for you.
And this is great because it gives you a good trade-off between a high level of details and minimal quads using the distortion.
And again, you only manipulate 8 points. So, here, as I move the points in the top left, you can see that I'm going a bit far so the level of distortion is a bit high. So we you do subdivision.
But at the bottom right, it's a bit more mild distortion so we only subdivide twice.
And because we want to provide you with more control, we actually allow you to specify the maximum number of subdivision. So, if I take my spaceship of earlier and I make it a bit distorted a little bit like that, you might see some distortion, sorry, some artifacts throwing up, such as this bump at the bottom.
So, if I go with only one subdivision, you might see artifacts. But if you go up to 4, for instance, we clearly lose all the artifacts and have this nice smooth line at the bottom of the spaceship.
So again, this is perfect for you if you want to tune your visuals and/or your performance. Because of course, the less quad you have, the best for performance.
All right, this is cool but how do we do this in Swift? Okay, so first thing. Remember, we have a grid layout. So, 8 points labeled from 0 to 8.
I'm going to provide a list of source position, a list of definition position, which are all float 2.
I can just create my warp geometry grid by providing the column, the rows, the destination positions, source positions, and then I just save it to my Sprite.
And we have the distortion. And optionally you can also set subdivision level to whatever you want with the default being 2.
And because it is SpriteKit, we also, I did a bunch of new SK actions for you to use. So, making a transformation is as simple as just saying SKActionWarp to and give a grid and a time.
Or, if you have something more complex such as a keyframe-based animation, you can provide a list of grids and a list of times.
So, okay, let's do a quick demo here to show you Warp Transformation in action.
Alright. So, I'm actually going to be using the same demo is Ross, but this time I'm going to go on the left side because it's where all the cool stuff is.
All right, so we have this guy here, let's go explore for a bit. Oh, look at that. All right, so what we have here is 2 sets of animation.
We have one animation that makes the tree we go from left to right and one that makes your mushrooms squash from, you know, a bigger size to smaller size.
And we also added some randomness to make things rotate at different times.
It just makes your scene much more alive and fun to look at.
Okay, so let's keep it exploring here.
Okay, oh, look at this, there's a guy here.
Well, what's the best way to say hi in a platformer? I think it's just to jump on them, right? There ago.
So, what I did here is just as I jumped on this guy and then the collision body with the physics body, I'm just running in SKAction to make it, you know, squash.
All right, so that's pretty cool. Let's go back to the slides.
So, Warp Transformations are very powerful and enable a broad range of possibilities for your game. So I really hope you're going to use them and have fun with that. And next let's talk about per-node attributes for custom shaders.
Shaders are awesome. I really love shaders.
And there is a best way for you to make exact digital looks for your game.
In SpriteKit, we support custom shaders since the beginning with SKShader class which is basically a frequent shader which you apply to your nodes. It comes with a few built-in symbols such as the time, the texture, texture coordinates and many more. And if you have any specific needs, you can also specify it's an in SKUniform for your special variables.
All right, so what about we build a game using a shader. Okay, so I really love platformers. So, what about some platforms. Here we go, that's pretty good.
Okay, I want something cute, so what about a bunny. Oh yeah, that's awesome. I love this guy, he's pretty cute. Right? You know what, I'm going to name my game Dark Bunny. So let's put some bad guys and spikes and danger, just like that. Right, that's better.
Unfortunately our bunny's going to be hit a few times and because I want I don't want to make my game too hard, I'm going to have the help system health system and the health bar, just like this.
And guess what? The health bar is going to be shader.
You see it coming, right? Okay. So, how would I go about making a shader, sorry, making a health bar here in SpriteKit? So I add a Sprite for the health bar. I have a shader to control the visuals such as the blinking pattern, the caller and how filled in it is. So, here our bunny has only half-life so it's only filled halfway. And to control these visuals, I have a uniform that I call health. It's going to be a flood value that there is from one being full-life to zero being pretty close to not full-life. Okay. But because games are usually more fun when you have multiple players, let's put some guys here. We can have up to three players.
To, that means at any time it can have someone who's full-life, someone who's half-life and someone who's pretty close to being knocked out.
Okay, so again, In SpriteKit, fairly simple. I have my Sprite, my shader, my uniform.
But now how would I go if I wanted to make it with multiple players? Well, I have to do this.
Yeah, I have to duplicate my shader but that just doesn't make sense, right? Why do we have to do that? That's just bad. And it's bad because, while it's the same shader, right? And it's going to break the batching mechanism, meaning more draw calls. And it's just too complicated, right? Well, if you wanted to instead do something like this, I have only one shader and it is shared between sprites.
And, well, starting this year, you can just do that using attributes.
With custom attributes, you can just create an attribute, attach it to your shader, and then directly set the values on the nodes themself. So, here I have a custom attributes name health and I just set the health value on the Sprite itself. It's super simple. In Swift, this is what it looks like. I'm creating my attribute using the SK attribute class. I give it a name, so here, health, the type, float.
I attach it to my shader. Because my shader only uses one attribute, I'm giving a list of one attribute.
Lastly I can directly set the values of the Sprite. So, here play one has only 0.2 percent of life left, so I'm just doing set attribute value for attribute name health.
So, this is very convenient and simple if you're dealing with per-node customization and shaders.
So, now let's talk about a few platform specific items. And the first one being focus interaction on Apple TV.
So, for those of you who've already been making apps for Apple TV, you already know what focus interaction is. But for those of you who do not, let me just recap what happened last year.
Last year we introduced the new Apple TV, tvOS and its brand-new user interface as well as the Siri remote and its touchpad.
So, now one of the major differences between iPhone and Apple TV is interaction.
So, on iPhone the user's going to directly interact on the phone by touching the screen.
On Apple TV on the other hand, the user will always have the controller in his hand between him and the interface. And we actually call this interaction focus-based interaction. So, let me show you what happens if I was to move my cursor in the main menu of the Apple TV with focusing.
So, as you can see, we only have one element focus at a time and scrolling ware is tuned to reader responsive and react your fingertip very well.
So, in fact, this is very important. And it's so important that we built our system and our frameworks using focus interaction in mind.
So it means that if you happen to make an app using UIKit, you don't need to re-create the focus system interaction.
All you have to do is just lay out your views, say which one are focusable, and then you're done.
It's very simple to use and provides a consistent user experience, whether you are in the main menu of Apple TV or in your application.
And as a bonus, we support of course the Siri remote, game controllers and many Bluetooth controllers and many, many more.
If you want to learn more about focus interaction on Apple TV, there is a session this week and you can find many more resources online. All right, so the big news here is that we have SpriteKit support for focus interaction.
So, that's pretty great. Yeah, thank you.
So, this is actually pretty great for any kind of user interface in your game such as game menus or you could have subbuilder in our game using focus such as a chess game or a game or many more. And the cool thing here is that it's just so much simpler.
What you can see here is DemoBot. It's a sample code app from last year and it used to be for iOS and macOS. We did a port to tvOS and it just felt so much better to remove all this code for the interaction and the navigation. It was just so much cleaner, so much simpler.
Speaking of DemoBot, let's see how we would go about creating this menu right there using SpriteKit and focus interaction. The first thing you need to know is that UIKit introduces new protocol called UIFocusItem which conforms to the UIFocusEnvironment. This extends the focus system to nonview item.
So, as you have guessed, now SKNode is actually conforming to that as well.
So, the first thing you need to do is make a subclass. So, here for my menu element, I'm going to use some rectangles. I'm going to use a SpriteNode.
So first, make a subclass. Second, you need to override that canBecomeFocused method to true so that your node is focusable. Next you have to obtain your node into the focus system and to do that, you just have to set the isUserInteractionEnabled to true.
And the last thing you need to do is override the data did focus and context, which is going to give you updates on your focus updates. So, you can override this in your view, in your scene or any node that actually makes sense for your app.
So, here the context subject gives me the next focused item, the previously focused item, and in my case I'm going to look for a menu element and if I'm hitting this, I can just run some SKAction. So, this is how it looks like in action. As I finish the game, I am being prompted with the menu and I can just use my Siri remote to scroll through or game controller, it will just work as well. And I have the same feel as it would have in the main menu on Apple TV.
Again, very simple, very powerful. We recommend highly for you to use it.
All right, a pretty big one here.
SpriteKit on Apple Watch. So, as you have seen, for watchOS 3.0, we brought some frameworks to Apple Watch.
And yeah, SpriteKit is available. So, that means that now you can do very interactive application using this high-performance 2D graphics platform. And of course we bring all the stuff you love such as particles, animation, physics, actions and all the editors are compatible so you can use the scene editor. You can use the particle editor. We have all the editing tools such as new performance gauge that Ross just told it out.
All of this is just working.
So, a typical SpriteKit game looks like this.
I have an SKView and then it contains an SKScene which itself contains multiple nodes.
Such as the SpriteNode, a ShapeNode, whatever.
On Apple Watch, though, there's no notion of view. Instead, you present your content using WatchKit interface. And in fact it's going to be the major difference here.
So, instead of using an SKView, I will be using a WKInterfaceSKScene. It looks pretty much it.
All right, so let's see how we would go from an existing game on iOS to make it a support for watchOS. So, that's some code, that's some sample code for a game on iOS. So, pretty typical, I have my view. I'm doing some set up on my scene and everything.
All right. So, what I have to do now is just click on file.
new, target, select the template I want. So here I'm going to use a game app template for my target.
Give it the best name ever, so I'm going to call it Apple Watch Game.
And then click next. And you're done. No, seriously, you're done.
Xcode is going to create all the files you need such as the storyboard and the interface controller as well. And if you take a look at the storyboard, we actually wired up everything for you already.
So, this guy is actually connected to my outlet as you can see at the top here. And you're just ready to go. You have your WKInterfaceScene and you have the same stuff you had before. So, it's very simple. All right, so some compatibility now on the Apple Watch.
There's no SKAudioNode on Apple Watch but of course you can still play a sound using SKAction playSoundFileNamed.
There's no SKVidioNode but you can use the WKInterfaceMovie instead.
And lastly if you're doing a special effect using CI filters, you can still do them but you have to use an SKShader.
So, we're really excited about what you can do with Apple Watch in SpriteKit. It's going to enable you to make even more interactive and fun apps with the platform.
So, since we have more and more platforms, let me just talk about a few best practices for SpriteKit.
The first one being Asset Catalog.
Use Asset Catalog.
It's great. It works very well with SpriteKit and it provides a lot of cool features for your game to make things simple and faster.
The first thing being the Sprite Atlas.
In Asset Catalog, you can make a texture atlas which is a fundamental piece of optimization for tile maps where you have multiple textures combined into one big texture which reduces the number of draw calls to a very low amount. Next we have support for multiple asset sizes such as, you know, 1x, 2x, 3x, which is great for multiple platforms such as the iPad, iPhone, watchOS. And again, you don't need to do any conditionals, like oh, is this that platform or this one. No, you just call your texture and you're done. We do rest for you.
We have support for on-demand resource which is fundamental for tvOS.
And lastly we do app slicing, meaning that if you have resource that are specific platform, we'll be only using this for the bundle and then compiling them into the runtime binaries as small as possible which gives you a very small bundle and a small download on the App Store.
So yeah, Asset Catalog is great, go for it. Next, about performance and battery life. So, a big change in SpriteKit this year is that we do not render all the time. Now, we only render when your scene is dirty. So, if something change, we will be issuing some draw calls but if nothing changed, we will not be doing anything.
So, if you're using any debiting tools such as the performance gauge, you might see the needle not moving. And it's actually a good thing because it means that you are not rendering anything new.
If you need to control the frame weight, you we also have a couple ways for you to do that.
The first one being preferredFramesPerSecond on SKView.
At any time, you can just set the frame rate to whatever you want, which can be convenient for, you know, if you have the menu and you have a low frame rate need here. And when you come back to your game, you can go back to 60 or 30 FPS based on your performance needs. The second one is a bit more advanced.
It's a delegate in SKView which is giving you thisShouldRenderAtTime method with the absolute time of the game. So, this method is going to be called at each frame and you can decide based on the time whether yes or no you want to render the frame. So, this gives you a very fine-grained control of the rendering for your game. All right. And that's it. So, what's new in SpriteKit? A lot this year.
The first being the scene outline view, which allows you to manipulate your scene graph from Xcode.
The GameplayKit integration. If you're already using GameplayKit component, now you can just set them on your nodes directly using Xcode. FPS high performance gauge which gives you a real-time breakdown of your scene performance, very, very useful.
Tile maps for complex yet high performance levels.
Warp Transformation to make you game have fun and complex animation using just a grid of points.
Per-node attributes for custom shaders if you're using per-node customization and building of shaders, very convenient.
And of course focus interaction on Apple TV and SpriteKit on Apple Watch, which is the big one for this year. If you want to learn more, you can go to the developer.apple.com website.
We have a lot of sessions for gaming this year but most of them are already done. But you can still see them online by going on the website we I just showed earlier.
And tomorrow you can go to What's New in Game Center as well as Game Technologies for Apple Watch if you want to learn more about these platforms and frameworks. All right.
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.