Graphics and Games • iOS, OS X • 59:26
Turn-based gaming has taken off with the addition of asynchronous multiplayer gaming in Game Center. Dive into the latest developments in turn-based play. See how to add in-game trading, player chat, negotiations, and much more by using exchanges. Learn about the API and gain insight into managing game states and multiple game sessions.
Speaker: Nathan Taylor
Unlisted on Apple Developer site
Downloads from Apple
Transcript
This transcript has potential transcription errors. We are working on an improved version.
Good morning. I'm Nathan Taylor. I manage the iOS Game Center team and today, I want to talk to you about Turn-Based Gaming in Game Center. So, here are the things I'm going to cover today. I'm going to talk about turn-based gaming for the most part of this talk.
I'm going to start with a brief overview, you know, what is turn-based gaming and what other multiplayer types of gaming does Game Center provide? Throughout the talk, I'm going to cover some new features, will be interspersed. Let me give you a little load on what they are in a bit.
Then I'm going to cover the basic scenarios of turn-based gaming and this is sort of all the scenarios that you need to cover to make a good turn-based game. And in doing this, you know, I'm going to show a lot of code and, you know, kind of go over some of the decisions that you have to make when you're handling some of the events you get. And then I'm going to go into advance scenarios of turn-based gaming. These are some of the things that are difficult to do with turn-based gaming today and show you a solution that we're offering in iOS 7 to help you solve this.
Game Center has three ways to do multiplayer and play with your friends, all right. The first that we offered is peer-to-peer multiplayer, you know, and this is, you know, device-- a device multiplayer up to four players, Game Center provides auto-matching and invitations and, you know, we connect the devices and provide the networking layer and allow players to play a synchronous game.
Similarly, we offer, you know, through the same auto-matching invitation mechanism a server-hosted multiplayer. And this is where you use Game Center's auto-matching and invitations you bring your own server into your own networking through your server between the devices. And this will allow up to 16 players. And the topic of today's session, turn-based multiplayers relatively new compared to this others in Game Center. And we think it's going to be ideal solution in multiplayer allows, you know, up to 16 players to take turns and passing the turn, you know, device in a fully asynchronous manner.
And this is sort of how turn-based gaming works, you know, so we sort of have this table and people see it around the table and its kind of like a board game, right? Everybody's going to take their turn and the turn will move on to the next person.
So, you'll take your turn, indicate to Game Center to pass it turn to Sue, Sue will take her turn, pass it to Bob, and then we've got an empty seat here and this is kind of represents the seat that we're going to auto-match and fill with somebody else who wants to play with us. So, when the turn passes to the empty seat we will auto-match in a new player Meg here, Meg will take her turn.
And then, the other thing about turn-based gaming is that the turn sequence is entirely determined by you. It's not purely sequential. So, you can send the turn to whoever you need to base on your game rules. So, here, you know, Meg will then turn to Sam, Sam-- sorry, let me start that over. Sam will send it back to Meg, and then Meg can send it back to you.
And this will proceed however your game [inaudible] needs to go. You can implement, you know, skips, reverses, whatever type-- whatever your game needs. So, Game Center turn-based multiplayer provides all the matchmaking in invitation services. Your users can invite their friends to play or they can pick up and play an auto-match game with other players around the world. The important part to remember is the matching and invites are asynchronous. You know, invites do not go out until the turn moves to the participant that had-- you know, that's waiting to be invited, and then when they get the invitations immediately their turn.
Game Center, also, provides all the storage of the game save, you know, we also do the synchronization and the updating of clients. So, we use push notifications when you pass the turn to the next player. They get notified on their devices and then they can pull down the game state and take their turn and upload it. The turn-based game scenario in Game Center also covers player status. So, this is where you know, if hey, this person is on auto-match, he's invited, he's actively playing, has quit the game, or when the game is over.
With all this, you know, we kind of feel that turn-based game is really the ideal solution for multiplayer gaming on a mobile platform. Users can play whenever they have spare time. You know, we always have our iPhones with us, our devices in our pocket. And, you know, we don't actually have, you know, 10 minutes to sit together with somebody and play and, you know, be involved for a real time game but we have a spare of minute here, we're online, we're on the bus and we can take a couple of turns then get on with our life.
So, here's a breakdown of the capabilities of turn-based gaming. Users can have up to 30 simultaneous matches for your game, so they can be playing with, you know, 30 different games with however many game friends that your game allows. There's up to 16 players per game. Gameplay as well as invitations in auto-matching is fully asynchronous, right? Player one is taking their turn, the other players two, three, four don't know anything about it until it's completed.
The game data can be up to 64 kilobytes. You know, a little a while ago we increased this from the initial 4 kilobyte. We offer 64 kilobytes of storage. Seats are filled as I said through invitations and auto-matching and it's fully asynchronous. The turn order is entirely up to you. Game Center doesn't take any part in the turn order. You specify who the turn goes to and you can tell us who it should we go to next if that person is unavailable.
And to that effect we have this fallback list so you can specify a complete list; it could be all the players in the game of who we should go to in case the next person is not available and the person after that's not available. So, it provides a recovery mechanism for games or people are away or forget about their game. And finally, we give time outs. You can specify a time out but the default time of the game center uses these two weeks.
So, let's take a look at what actually happens with the game data. The way game center does synchronization of term based game data is that the person whose turn it is is the only person who can write the game data. All other players can, you know, download from the server, read from it and view the game state but only the person who knows the term can write new data to the servers.
So, you have to turn here and you're going to write the data send it up to the Game Center servers and pass to turn to Sue. Sue gets notified. We badge your application on Sue's devices, and then when Sue decides to launch a game and play it, he will pull down the game data and then Sue can take her turn, move it, pass the turn to Bob and Bob gets notified.
But Bob is on vacation and can't play. So, your time out comes into effect. You fallbacks fall and also take place and we automatically will notify Meg who can then pull down the turn data and take her turn. And then, it's up to you. Do you want to let Meg choose? Do you want to give Bob another chance to take his turn later? Or, do you drop Bob from the match? It's up to you and your users on how your game should proceed in the state.
So, let's take a quick look at what the match data is, right? This is basically an NSData object. It's completely opaque to Game Center. We don't write anything to it. We don't read it. It's just a blob that we pass it to servers, store for you and it will let you download onto-- into the game so you can show your data. You completely define the contents. Only the current player can upload new data. And they can upload new data with an intermediate upload and they upload new data when they finish their turn and at the end of the game, you upload the final state.
All other players can read this data at any time. The can pull down, view the current state. So, if there's stuff you want them ask in there about turn, well, you know, sets some flags in the data so they can see, hey, you know, this guy is taking his turn.
I don't want to show you what he's done, you know, fog of war type of stuff. Remember that it's limited size, 64 kilobytes. It's not a whole lot, you know. But you can do a quite a bit with it as long as you are smart and you use and, you know, efficient data packing strategies.
You know, small games might be able to get away with encoding a P-list or, you know, serializing our objects directly into this. But if you got a more complex game, you going to want to think about this, you know, turn your games into some [inaudible], use some bit fields, do what you need to to pack data tightly. If you need more, you can always point to data stored on your own servers. And to do this you can either store reference inside the match data, or you can just use the match-- session ID to reference it.
So, users have some interesting expectations of turn-based games, right? It's a little bit different when they're playing peer-to-peer game, you're playing one game and that's all there is. You know, you can't really do anything else. But with turn-based games it's always asynchronous, they can come and go as they want.
So, to get this, they expect to be able to have multiple simultaneous matches. So, your game needs to be able to handle the scenario. You now, you don't want to be in this case with the user, you can just have one match but somehow get a second and there's no way to manage it in your game, that's a problem, right? How do they find the match with the other friend if they're playing? Each game has its own state, its own players, and in the end, its own outcome. And some users like to keep the match around and be able to show it to their friends when they've won. You know, when they got all the work, all the titles filled, they can show off to their friends.
One player at a time, right? It's turn-based. There's only one person taking the turn and they're the only person who can upload the game state. Other players are observers until it becomes their turn. And the other thing in your mind is your game on the other device is not running, right? These things are handled through notifications that game center handles. We will tell you-- your game will launch when we needed to and the user going to take, you know, choose a match, take their turn, exit, go back to, you know, doing work and, you know, whenever they get a notification they'll take another turn.
And the tricky part with turn-based gaming is because it is asynchronous. You can get notified about any of these other 30 matches that the user might have in their game at any time, right? User's playing one match and gets a new turn in another match. Sometimes the right answer here is take them to that other match.
Sometimes it's not. You know, and you often want to give the user the choice but do so in as non-disruptive way of possible. You also may have user-viewing the game and one of the players is not their turn when someone takes their turn, you know, and passes it to, you know, the third player.
And there you might want to immediately update the state 'cause they're looking at it and show the live updates. You can make it feel like it's a live game. And I'm going to go into the decisions you have to make when handling these kind of events, so that it can give sort of the correct and ideal user experience here.
So, before I start looking at some scenarios, let me give an overview of some of the new features we have in iOS 7. One, the first here is that we allow you to report the scores and achievements for all the players of the match from the one device that the takes the final turn. This was a request and it was a good one. It was really hard to get the right scores and achievements up when actually the last term can change all that.
So, one player with the final submission of the match can report all the scores, because now this is, you know, an internet world and people play in multiple different countries and have, you know, speak different languages. We now allow for you to specify turn messages that will be localized on the receiver's device. So, with a little extra work, you can specify, you know, when you send the turn, you know, the message, you know, key and we will localize it for the user that receives it.
We also have a new feature to be able to easily remind people that have forgotten to take the turn this is now their turn. So, there's an API to do this and you can give your users buttons to remind their friend to take turns. As alluded to in the earlier games in our talk there's an improved event handling model and I'm going to go into some depth on this on how to use this event handling model for turn-based games.
And then, we have a big new feature and this is what will help us all in the advance scenarios in turn-based gaming and we call turn-based exchanges. I'm going to talk about more-- that more at the end. And lastly, you know, game center its little tricky debug at times with turn-based gaming.
And so, we've done a little bit better parameter checking in error handling. So, hopefully, you know, with iOS 7 you'll get notified of mistakes that you may making your code and catch those in sandbox before you go live and I hopefully be able to figure them out easier.
So, let's take a quick look at the primary classes you use in doing turn-based gaming and the principle class of all is the turn based match. This represents the game instance and you might have 30 of them. It includes the list of participants. You know, these are the empty seats or the players that are filled in and playing the game.
It includes the current game state. You know, this is the NSData that you provided us. We also let you know who currently has the turn so you know if it's your player on the current device or someone else. And with turn-based exchanges, all exchanges that have been made are also listed and accessible from the match.
The next class, the participant, you know, this is the seat. This is how many people are playing the game and who they are if you know. Alright so, if we know who they are it's a player ID but you got to keep in mind that maybe an open seat and maybe waiting to auto-match. It may be an invitation that your player sent, you'll know who it is but they haven't actually gotten to take the turn yet.
This also then includes the status, so that you can know this, right? Are they invited? Are they matching? Are they currently playing the game? Or are they done? And lastly and it's a little bit often forgotten is the outcome. For each participant of the game when you end the game we've [inaudible] a mechanism to set the outcome and we provide you a basic enum so you can set this to, you know one lost, first, second third place. And there's also a range in this [inaudible] that you can use for custom outcomes. So, you can use this to display state in your game. And you need to fill this in when you end the game or when a player quits on their turn.
So, the other class, you know, that you often use this that the Game Center GK turn-based match maker view control. This is the Game Center interface for turn-based games. Now, if you want easy access to creating matches inviting friends and listening available matches and allowing management of this, you can use the view controller. It per basically provides management from matches.
So, let's look at the basic scenarios that all turn-based games kind of has to be able to handle. And I'd like to say, you know, that is only three items, but I've got seven on the slide. You know, and the kind of a grouped into sort of three things. Creating a match, dealing with the turns and then dealing with, you know, and managing multiple matches. So, the first thing you're going to want to build is make sure a way-- there's a way that in your app for user to create a match and invite their friends.
Then the thing you're going to do most often and most important thing to get absolutely right is playing a turn, right? This is your game logic and then how you communicate that turn to the Game Center server. At the end of the match, when all the turns are taken you need to end the match appropriately.
This will notify all the users that the game is over and just put it into the completed section of the other list and make it so they can remove it if they want. And then in managing matches, you need to be able to list all the open matches, remove a match and quit a match. In quitting, there're two ways, you know, in turn or out of turn.
So, creating a match can be done with the view controller. If you want to use our UI, you can use the turn-based matchmaker view controller, provides all the management you need, list the matches allows users to remove them with a little help from you, they can quit in turn and it provides auto-matching invitations. And you create this by specifying a match request.
However, if you want to do it programmatically and you want to provide your own UI for this and we encourage this, you know, nothing kind of fits better in your app than your own, UI design. We provide a mechanism so you can do auto-matching and invitations programmatically. And that's what I'm going to show you next. It's really not too difficult.
This is how to create a match and allows someone to invite their friends at the same time. So, you provide a mechanism what the user choose, which friends they want to invite, you know, get the player ID's of these friends. Set up a match request. We'll just specify the minimum and maximum number of players here, four and four.
And then we'll set the players to invite on a-- on the match request, right? So, players to invite as a property that you put your friend ID's in and set the invite message. Usually this is something we've recommend you'll have the user type in 'cause this is kind of a personal message that's [inaudible] to the friends that you're going to invite.
And then one API call, it's a class method on GK turn-based matching you can call, find match for request with your request and then a completion handler. On completion, you either get a match, it will immediately be your players turn in that match. They'll need to take some action or you'll get an error if we were unable to create that match for you.
So, said users can enable to matches and you can see matches here can be in various states. It might be your players turn. It might be someone else's turn. You know, so, how do you handle this? Well, it's really simple. There's pretty much two APIs and you do and sort of two actions you need to take.
If you want to list matches, build your own UI around this. You can use the class method, load matches with completion handler. And this will give you an array of the existing matches. All the active matches, all the completed matches and then you can sort this as you'd like and display it to the user.
When the user's done with the match, you know, you want to implement some way for them to remove this match from their list. You know, some matches will get auto removed overtime as new matches are created, but users want to keep their list clean. So, provide a mechanism when you remove a match and it's quite simple. It's an instance method on the turn-based match called Remove with Completion Handler and this will simply remove it from the users match list. And then alternatively you can use the view controller.
So, most important thing you can do in any turn-based game is take turns. Every player in the game presumably is going to take a turn, multiple turns and this is going to be the most common thing and there's a lot of stuff you want to do here. So, essentially taking a turn involves making the match data, passing it up to the server, setting who the player is next.
And so, let's take a look at the actual full sequence. First, you're going to unload the current state from the server. So, this is the effect, pulling down the most recent match data, so that you have current stuff-- most current data to operate on. You will then apply your game logic to it to both allow the user to take their turn.
You will then be able to save the enemy, hit save if you want. So, if the users in the middle of the turn, it's really nice to let them save their state so that if they want to resume on another device, but they happen to put the device away and your app gets jetsam to be able to come back and come back to where they were in the middle of their turn. You can save the enemy at state. And in doing this, you have to keep in mind that other players in the game can see that state unless you explicitly kind of hide it through flags in the match state.
Next, when the user is done, they've taken their turn, you know, kind of the results. You need to choose the next player sequence, right? Who should the turn go to next and specify the fallback so that we can recover gracefully if that person is unable to take their turn. And then finally, you're going to submit the turn to Game Center and Game Center will then notify the next player and this will repeat.
So, to load the current state, there's basically a single API to do this. It's an instance method on the match, load match data with completion handler. This will return to you, your latest match data and then usually what you'll do is take the match data, you know, and apply it to your view controller and show it to the user.
After that, you know, you've let your user play with the match there, right. They've taken their turn. They manipulated the data, they've-- you know, drawn some cards, moved their token, roll the die. You'll want to, you know, update the match or generate the new match data for the user actions.
Now, because I said, you know, your device and user make want to-- you need to put your app away, your app is in the background and make it jetsam. The user might want to switch to another device and pick this up later. Save the enemy that state to server, right? And to do this, there's an API called save current turn with match data with completion handler.
This doesn't move who the current turn is. This only uploads the new data or into the server so that's available to all the players. And then, we're going to continue, you know, taking the turn. So, the next step as I mentioned was to choose who which you go to next.
This is entirely based on your game rules. Game Center doesn't really take any part in who the turn goes to next. The things you keep mind though is you need to select active players or players that you want to become active, remember auto-matching and invitation is asynchronous. To get those people into the game, to get send invites to auto-matching when-- they need to get the turn. And when they do, it will be that persons turn.
You also want to be able to guard against missed turns. So, you can check to see if a player has timed out in the past, right? And you can also provide-- you provided us the list of the multiple participants. You're not picking just the next person. You're going to give us everybody. You can find out who timed out.
Make the decision or look if the user choose whether they should, you know, still be in the game, you know, if they time out, did they forfeit or did they get three tries. That's up to you, right? You then, you know, just specify this list of participants. You're going to use time outs so that if someone takes too long or it's not available to move on to the next person.
The last person on this list because after that games and doesn't know what to do won't time out. And what we actually recommend you do here is basically specify the full turn cycle and put the last person on the list is the person who is currently taking the turn.
This way if everything goes wrong, the person who took the turn last played in the game can make a decision of, all right, if I want to give up on this game, I want to go play with someone else or do I try again, right? So, this is the work that you need to do here. There aren't really an API's on this slide but you're going to again update your match data with the latest state.
You're going to determine the next participant list and then you're going set up a turn message. And this gets us into the next new feature, localizable message. You're essentially going to be providing us localizable strings in your bundle. Game Center will use the strings on the recipient's device to generate the message that we show in notification center on the lock screen and the message of this show and the Game Center user interface both from the Game Center app.
And in the-- you know, in game UI in your screen. So, this allows us to actually show something, a message here that is localized to, you know, the user current device. And we've seen games that you, you know, that, you know, this player played this word, right? It would be nice to be able to make that appropriately localized and this can be a format string. All right, so that you can say you can specify the player name, you give us the word played and with any formats and with to format parameters. And then you give us, you know, the word if you're a word game.
We localize it on the recipients device, but before we send it, we also as a fallback localize it on the senders device and the senders language, because there is a chance that the person, if it's being invited to play the game for the first time it may not have it on the device. Their bundle's not there. We can't localize the message, but we will have something to fallback to.
And then, you know, ideally the user will quick notification Game Center will take them to the store and they will buy your game. To do this, we need two items from you. The first and most important is the message string or format string. You know, this is works to the standard, and you know, localizable strings mechanism. So, you're going to specify a string key that will be looked up in your localizable strings table inside of the bundle on the recipient device. Optionally, if you're using a format string, you can pass this to us in array of format arguments.
So, let's look at how we do this, right? This first part is your job, you know, giving us the key and the arguments. Then on the match, you're going to set the localizable message with this key and arguments. And then, finally we're to the meat of this whole taking a turn sequence.
This is the last bit. We're going to end the turn, right. Your user has done everything that you need to do. It's time for the next person to take their turn. So, you will call in turn with next participants specifying there's array of participants that we determined earlier.
Specifying a time out, here we use the default time out using your current match data that you determined earlier and then the completion handle would be called with an error if there is a problem submitting this turn, otherwise, it will move on to the next player and they will be notified and the game will proceed.
Reminders, this is another new feature, right. Turns-- Turn-based games is fully asynchronous. You know, we notify the user, they download the data when they're ready to take a turn but nothing happens if, you know, until they actually launched the game and do it. The games can only proceed as fast as their slowest player, right. Each player gets a turn. They spend their time taking up turn. They forget about it perhaps.
Time outs and fallbacks help keep things moving along. Help us recover from failure cases. But it's really nice to be able to continue in the game and be able to nudge someone, "Hey, remember you're playing with me and take your turn now." So, sometimes, you need to remind a player to play.
And we do this through a simple API and to send a reminder on the turn-based game. It's a single one way push with a localizable message. Let's take a look at the code to do this. Just as before, you're going to set up a localizable message with arguments and then call. Send reminder to participants. Note that is actually an array of participants with the localizable message key in arguments and the completion handler.
And you'll see why the array is kind of important a little bit later but the common case is the sender to who currently has the turn. But there are cases with some new features, turn-based exchanges where you might be waiting on actions from multiple people and you can remind everybody to take their actions.
So, it's all over, right? All the turns have been taken. All the cards are played. You know, there's no more property to buy somewhere. Everybody's gone bankrupt. Whatever rules determine the end of your game and you decide that. And instead of take-- the last person taking their turn and moving on to someone else. You decide that, all right the game is over. And now, I need to end the game. And what do you need to do? So, when it's all over, you know, there are various reasons this can happen.
They finish your game according to the rules, right. There's nothing left to do in the game. And then, there are other cases where games can end, right? If everybody quits the game, you know, and they can quit in turn or they can forfeit the game out of turn.
You know, these are things to think about in winning the game. But ultimately the game is ended by the last person to play instead of taking their turn. And so, instead of calling in turn with next participants you're going to call a different API and let me get to that.
So, before we end the game, right, it's usual to be able to say and let the user know, who won, who lost. So, we'd like you to set the outcomes. So, we start here by taking the current match data and determining your final match data, this last match data. You know, this is so that everybody whose still has the game in their session list can download the match data, can show off how well or poorly they did to their friends.
Then you're going to walk over all the participants in the match and then for each active participant, you know, people out still playing, you know, we want you to change their status to done, because they're not playing anymore, and then, determine their outcome and set the outcome property.
This is entirely based on you, right? You're going to look at the match data, you know, you know the positions of the different player, you'll set the outcome, and you can use our enums or you can use-- you notice the reserved bit range and user custom outcome so you can pull this down later. This will be saved in the match when you end the turn. And so, when later you download the match, you can query this off to participants.
[ Pause ]
Let's continue on the ending the game here. We get to another new feature and this is what I kind of start of any features. At the end of the game, you now know the scores that everybody got, the achievements that everybody got. And this used to be a real kind of tricky in hairy situation, right? You-- Before now, you would have to kind of submit a new score as everybody took a turn and kind of hope that that was the final, you know, representative of the final score at the end of the match.
And submit achievements as their earned and we still recommend you to do that. But at the end of the game you can now generate scores for all the participants and generate achievements for all the participants. There are new APIs for initialization of scores as you can meet them with player IDs. So, they will be specified to someone who's not the local player.
And then, when you're in the match you can use the new API to in match and turn with the new match data. This is your final match data and we give us the scores and achievements. Games Center then we'll submit these scores and achievements in bulk associated specifically with this match. So, we know who is participating. You can't submit scores or achievements for people that weren't members of this match.
This is really the only way to submit scores for someone else and we're using the match and the match data and the participants on the servers as a verification of this data that things are being submitted for the appropriate people. And then at the end of the match, you get a completion handler an error will tell you if there're some problems submitting this.
That's it. When you're done, that match is over. Your user can look at it and view it some other time, move on to other matches and play. But all along this process, because turn-based gaming is asynchronous, there were events. You've got events for invites, the very start of the match. You got events whenever it became your players turn. And you get events when the turn move between other players. We have a new mechanism in iOS 7 to handle these events.
Previously, we had basically a singleton GK turn-based event handler object that you would set a delegate to. And it was a singleton and you can only have one delegate and you had to kind of process events all in one place. We now have this listener model and you're going to want to implement the GK turn-based event listener.
It's a protocol for turn-based events. These events include state changes such as invitations, new turns, turns getting passed, match data getting saved and updated, as well as match ended events when you're in the game and for the turn-based exchanges, the various exchange or events for requests, cancellations and completions.
As with all the events these kind of come from the local player. The local player is the producer of these events 'cause they all sort of involve the local player. And this replaces the older turn-based handler and delegate which we have deprecated in iOS 7. The nice part is you can have multiple listeners. All of the protocol methods are optional. You can implement the ones you want, where you want them.
And so, it can simplify the decisions you have to make. For example, your app delegate can remain in responsibility of receiving new turn notifications, right? When the user activates the app and you've got a turn, you know, you want to jump right into that and you're going to start that with your app again.
But, if the users viewing a match, your view controller for that game state can listen for the events for updates. And it can ignore all other updates except ones that affect that match. And then it can just show the updates to the user. It doesn't have to worry about anything else.
To do this, you know, you're going to set up for listener. And you start by adopting this protocol. The next thing you do is you're going to register your listener or listeners with the local player using the simple registered listener method. And as I've said, you can register multiple listeners. You can separate responsibilities in your app. And ultimately you can have simpler code and less convoluted decision trees when you get turn-based events. So, let's take a look at what the protocol provides. These are the basic turn events.
We have, you know, the generic turn event. This is when the match state changes and it's, you know, player received the turn event for match, did become active. So, this is you and get this is on invites. You can get this one when it comes your turn and when the match state changes.
The next is match requests from Game Center. This is relatively uncommon, but Game Center provides a mechanism for users to essentially choose to play your game with one of their friends. When this happens, your game gets launched and the event you will receive is player did request match with players.
The right action here is for you to create a new match with these players, so that, the user can immediately start playing with their friends. And finally the last basic event we have is the match ended event. You've ended the turn and all players. So, you've ended the match and all players now get notified that the match is over. And this is player match ended.
So, let's take a look at the new turn event. As I've said, this is sort of the most complicated scenario and I'm going to actually walk through this with the sort of the full decision tree you make. So, it's going to go over kind of multiple slides here. And we're going to start here with, you know, the method its player receive turn event for match did become active. And the part focused on first that did become active.
This flag will be, yes, and true win the event is the one that we activated your application for. And this happens when the user taps on a banner for the event in a notification center, you know, they swipe on the lock screen when we launch their game, or they select the turn-based match in Game Center in the turn, you know the common turn list that we all have and select to play this match. We will launch your game and you will receive this event as soon as you set up this listener. If did become active is true, what you need to do is immediately switch to this match. The user has already chosen to play this match.
It doesn't make sense to ask them again. You want to basically save off any current state, allow them to go to this new match. And then you're done, you don't have to really handle anything else. You know, you-- they're ready to play. But if it's not the one that activated your app, now you want to handle it more selectively.
So again, we're going to continue with the received turned event from match. Here, we want to look for matches that are the current match. So, this is something that if you were-- you want a separate responsibilities that your view controller for the game can do. And then you just can listen for matches that match the current match. Now, you can do the easy equal check between my current match and the matches passed on this event.
If it is a match, it's the same one, you can call refresh match and update the UI for the user so they can see the latest turns that were taken and-- yeah, you can do simple animations, whatever is necessary to make your game fun. If it's not the current match, there's a little bit more work to do.
So again, we're going to receive a turned event, this time, it's not the current match. What's the right thing to do here? Well, did the player just get a new turn? Is it the player's turn? So here were checking this by comparing the current participant's player ID to the local player's ID-- like the producer of this event, the player passing is the local player. If these player IDs are the same, this indicates that your player now is the current player in this turn. That's kind of an important event.
So, what you want to do here is consider some way to notify the user. They might be busy in having fun taking a turn so you don't want to take them immediately out of that current match. So, we recommend, you know, some way to notify them. You can use Game Centers, you know, notification banner, API and show a banner on the top of your screen. You can-- put a badge on your UI somewhere. You can show an alert but let the user know that somebody is waiting on them somewhere else, that they have another option-- but don't take them out of their turned context.
All right, so that wraps up the turn events and we'll look at now this match request. As I said, this is rare but it's an important scenario. The user wants to play with their friends. In Game Center, the application has launched your game. How to handle this is really quite simple. It's like creating any match. So, the first thing you do is you create a match request. Here, I create one with, you know, two players.
I'm going to set the array that was passing a play ready is to invite as the players to invite on this match request. I'm going to let the user specify the invite message and then just like any-- creating a match I showed you earlier, you're going to simply call find match for request with completion handler.
So, that's everything you need do for basic turn-based gaming today. Now, I'm going to get into the new stuff. This is turn-based exchanges and you might ask, what is turn-based exchange? Well, a turn-base exchange is an out of band exchange of data between players. Recall that with the current turn-base gaming mechanism, the only person who can, basically, put new data into the match is the one who currently has the turn, he can upload it.
And when he does that, he passes the turn to someone else. Exchanges allow you to pass a little bit of data from one player to another, from any player to another. And this is done through basically a single reply, a single request, and then a reply, one reply, from each player that that request may have been sent to.
What this allows is for you to do some interesting things, you can do trading, you can do auctions, but you also get to keep the current player of the game, you player, in control of the duration of their term, right? Other ways to handle some of these complex scenarios which I will show you later, you know, you're kind of relinquishing control and-- and the game can, you know, kind of get messed up.
But we now allow users to control the duration, have the communications with the other players in the match, and be able to control how long it takes with time-outs, and you have the ability to cancel this at any time. And as with everything in turn-base gaming, this is fully asynchronous. You know, the user only has to wait as long as they want to wait. You don't have to wait for a reply. You can abandon it and cancel a request.
Why are we giving you exchanges? Well, we heard a lot of feedback. There were kind of-- when we introduced turn-based gaming, there were some concerns about how this would work with more complex games. And we believe, exchanges are the solution to these difficult scenarios. Let's take a look at some of the scenarios that we think turn-base exchanges really help solve.
And I expect that you, being as creative as you are, can find some really cool usage of-- uses of these. But the primary one, you know, one of the first ones here is trading resources, right? You're in the middle of turn-base game and your player's taking their turn and they want to trade some gold to someone else and get some ore.
Well, it's challenging. What type of trades are there? Well, there are trades that are initiated by the current player. We could make that happen with turn-base gaming before exchanges. But there are other types of trades such as trades initiated by a different player who doesn't currently have to turn with your player or trades between two people that are unrelated to the current player. We also offer things like auctions of properties where you're going to involve one or more or all the players in the action.
And then you can do things like simultaneous turns or otherwise known as kind of gated matches, where you let everybody take a small action, you gather the results, you integrate it into the turn, you move it on, and you take next turn. And this also can be used for like a simple messaging thing where you can let users send thoughts, or cubits and kind of send little hints out of band and to their partners.
So, before exchanges, how would you handle these difficult scenarios? Well, it all starts with the turn, right? You start with the turn, then you might edit the game state, put it into some special mode that says, "Hey, I'm trading." And then you're going to pass the turn to the players that the user wants to trade with and you'll give it a short time-out so that you can actually recover and then return the turn to the original player.
And at the end you'll resolve a special mode, you know, "Hey, the user accepted the trade, but the resources in their game state let them finish their turn." Why is this really hard? Why is this none ideal? Well, you've relinquished the turn and that means that the full duration of this turn is not under the player's control, right? If the other player that you gave a turn to that you want to trade with, answer is fast, create might work, but if you have to wait for that time out if they're not available to reply, they can take a very long time to resolve and your player never really got to finish their turn.
What is this look like with the exchanges? Well, it's simpler here, you know, we've taken out a few of the steps. We start the turn, we request an exchange, I want to trade with you. You receive a reply, here is my counter offer, you'll then take this exchange you'll resolve it into the matched data, maybe you'll initiate more exchanges. But you can leave this up to the user. What they're doing is based on them. If they don't want to wait for them for reply, you can cancel them for them, then they'll end their turn.
What are-- what are the classes you use for exchanges? Well, we added a few more for this. Obviously there's a new class called GK turn-base exchange. This represents the requests. It has the sender, that's usually your player, but it can be any of the people if you're sending them, you know, the [inaudible] player.
All the recipients of the exchanges, this is one or more of the participants of the match. You can send these to open seats, right, just like moving a turn to an open seat. You send and exchange to an open seat, it will trigger the invitation or trigger auto match to fill that seat, so someone will come in and handle that exchange.
Each exchange has its status, whether it's active, if you-- it's been canceled, if it's completed, and then the final one is resolved. Each exchange covered its own message, right, so you can include a visible message, a string for the user and a small payload. We allow you to specify data up to one kilobyte with each exchange. And then the exchange will track its replies. You might-- if it's only sent to one person, you get one reply and then it will be completed and you need to resolve it. So the next class, obviously, as it falls from this is the GK turn-base exchange reply.
This has the recipient. This is the person who current exchange was sent to and who is replying. It has a message, so you can have a message in response, you know, and these generate banners and notifications, so that the user can see that they left-- they left the game, they can see, you know, that hey I got a response, you know, this person like, you know, will make a counter offer for my trade. And then each reply has a small payload as well, one kilobyte, so that you can, you know, take this payloads and request and reply and then integrate them into the match data.
So, what does this look like? We've got our table here. You have the game data. It's your turn. But you want to trade with Meg and Bob. So, you'll send one exchange out to Meg. We're going out of band here so the turn goes away, and we'll send another exchange to Bob, both of them will get notified, now we're waiting for replies.
We get a reply quickly form Meg. And we like it. You know, the user-- users happy with it. They accept the trade, so you can cancel the exchange to Bob. Integrate the results of this exchange in reply into the turn-base-- turn state, go back to taking the term and then finish it. Upload the turn data that has the results of the exchange, and then move the turn to Sue.
So, there's sort of a three Rs to exchanges. This is what you want to remember from exchanges. You're going to request an exchange, all right, the first R. It all starts with this. It can be started by any player in that match. It can be started at any time. Each exchange can target one or multiple players, and they all include a small payload.
The next R, the second is to reply to the exchange, each player that we send the exchange to, we expect a reply from or time-out and you can cancel if you need to. And then the last or the important one is all completed exchanges, that is all the exchanges that we've got replies for need to be resolved into the match date before ending the current turn. If you fail to do so, you will receive an error, and you'll need to go back and resolve those into the state and then try again.
So what does this look like? Well, to request an exchange, you know, determine the number of players. You can send it to one of more people, remember you can send it to empty seats, so if you-- especially if you're doing like a gated turn-base match for simultaneous turns, you want-- sending it to empty seats is very important to be able to fill them in.
For each participant that we sent it to, we expect a single reply. And the API to do is send exchange to participants with data, localize well message, arguments, and the time out. And then you'll get a completion handler that will be callback with the exchange that was successfully created.
Replying is essentially just as simple. This is an instance method on the exchange itself. Each exchange gets a single reply form each participant that it was sent to, and the exchanges marked completed, once all replies or time outs are received from each participants. And then once completed, you need to resolve it. So to reply, you call reply with localized well message, given arguments, the data payload that is all yours, and the completion handler.
And then that's it. The reply is sent, the recipient receives it, and the game can move on. Once your user is done with an exchange, right? They don't want the results. They're tired. You know, they want to get on and finish their turn. You can cancel exchanges. This leaves the control and the duration of the exchange and the turn in control of your player.
And so when you don't want to wait for further replies, cancel it. You can cancel active, once that you're still waiting for replies, or even complete an exchange. I mean this is going to essentially say, I'm discarding the results from this completed exchange. I don't need to reconcile, resolve it. And the act of cancelling an exchange removes it from the match.
So, did you saw-- you can call the instance method on the exchange; cancel with localized message, given some arguments and a completion handler. The users that have been waiting for exchange will be able to see a notification that, yes this request that you've done previously has been canceled. And lastly now, the final R is resolving the exchanges. Remember that all completed exchanges needed resolve and an exchange is complete once you receive all the replies for it including time outs.
It's also very important to remember that you need to resolve all the completed exchanges and that exchanges could be done between players that are not the current player, some of you-- you're going to have to check and see, you know, which exchanges have been completed, handle that and integrate that into your match data. You know, how you do that is all up to you. You own the payloads and the requests and the replies. You own the match data, you know, but you need to tell us that you have resolved this exchange, and we will remove resolved exchanges from the match.
So what you do is you gather the data form the exchange and reply. You do what you need to with that. You then merge this into the match state and then when you resolve it, we'll remove the match so that it's no longer there. Resolving the exchange. So, we give you a convenience method to get all the completed exchanges on the match. It's this property, completed exchanges.
You're going to go-- then take this completed exchanges and you're going to gather the data-- the match, sorry, the data from each exchange and each reply and put it into your new match data, the merged match data here. And then just like when we say saving an intermediate turn, we have this method where you can save this new merged data without passing the turn. So, you call saved merged matched data with resolved exchanges and completion handler. And the reason you want to do this is you want to resolve exchanges as they get completed. But you don't necessarily end the turn when you do this.
And then usually continues with the turn. Exchanges have their own event handler protocol methods here. So, as I mentioned earlier, there are three. You get to be notified with an event when you're player receives a new exchange request, that is player received exchange request from match. You'll be notified when exchange request that your player has gets canceled.
The player received exchange cancellation from match. And you also be notified when you have in exchange that you sent out has been completed, or any exchange has been completed. And this is, you know, the player received exchange replies. We're going to give you all replies at this time. For this completed exchange, for match.
So, let's look at how we, you know, what kind of we want to do when we handle an exchange. This is sort of similar to getting a turned event, right? Exchanges, you know, user handling exchange, they're going to be playing your games like a mini turn. Right, so you you're going to want to determine whether this exchange, you know, the match is for is your current match, right? If it's the one the user's currently in, immediately show them the data, hey, you know, there's a trade request if you want to handle it.
If they're doing something else in your app, they're playing another match, the same logic kind of holds that we have for turn state changes. You don't want them to take this immediately 'cause this will interrupt what they're doing. But you want to, you know, notify them in some manner. You know, showing some badge in your UI, showing an alert, using Game Center's notification banners.
When you get in a cancel exchange, it's pretty similar. You know, if the users kind of currently working on that match, viewing that match, dealing with that exchange, you need to basically, say, oh sorry we don't need you to reply anymore, return them to the match. If they are, you know, not dealing with this exchange right now, what you do is a little less important, right? You know, you've notified them somehow, you know, you've got a badge count. Well, you want to clear that so you'll, you know, we use that badge somewhere, hide your alert if you had one, you know, clear the banner, and then they'll be able to continue.
Finally, you know, when an exchange is completed, you've done all the replies you expect to receive, you know, what do you want to do here? Well, you're user that's getting the reply is probably going to want to do something with it. If it's a trade, you know, you'll see all the different offers and you want to let them pick which one if they want to accept or maybe make counter.
And so, you know, we check, this the current match, is this the current exchange, immediately show them the replies because they're ready to see that. If it's not, you know, show them, you know, or clear appropriately the banners that you need to show. And let them know that something is waiting for them to finalize and finish their match-- their turn.
So, I mentioned that this also helps also in difficult scenarios and I talked about trading and simultaneous turns, and auctions of properties. Let's see how you do this. Using exchanges for trading, you let the user decide what they're going to offer for trade, right? It all starts there.
Then they will send one exchange request to each potential trade partners or if it's going to be offered to everybody, you'll send out, you know, one for each participant in the match. Once they've decided they like something, they can cancel all the outstanding exchanges, and then move on. You know, you resolve the complete exchange into the match and let the user go on and finish their turn maybe they'll make another trade.
And they could have multiple trades going on at the same time. It's entirely up to your logic. What does this look like? Well, you've actually seen this animation before. You get the match data, going to send two requests to Meg and Bob. Meg's going to give me a reply, I like. I'll cancel the request to Bob, resolve it into this-- the match state and finish the turn.
Simultaneous turns, it's a little more complex but, you know, it involves basically a single exchange. So, you're going to send one exchange to all the participants of the game. You'll then wait until all the replies are received or time out. You then can resolve this completed exchange into the match and finish the turn.
Auctions, you can do similarly or you can choose some other mechanism to do this. You know, send out an exchange to all the participants in the auction. Give it a shot time out, wait until all the replies are received, determine the high bidder, you know, reward the item. You repeat if you've got some ties. Send it just to those people let them handle their tie and then, you know, continue and resolve the completely exchanged match and finish the turn.
This looks a bit different, right? We're going to have a lot of exchanges going or a lot of lines that's going to exchange. I'm going to send it out to everybody. We're going to start getting replies. They're coming in. We get all the replies, exchanges completed. We resolve it into the match and we finish our turn.
So, that's how you can use exchanges to do complex things, very difficult scenarios. You can make more complex, more full featured turn-based games and use on very interesting things. So, it's important to remember the expectations that users have of turn-based gaming on mobile environments. You have multiple sessions, they expect to be able to have matches, be able to manage to just create new ones, list them, remove old ones.
Remember, you have to remember anything, everything is asynchronous. So, use the new event listener, separate your code, make it your code a little more simpler but, you know, do the right things, and don't take users out of the current context when it is not appropriate. And then yes, when you want to switch the current match. Well, you have to think about when these are chose to move to a new match, when they get an invite for the new turn.
Wrapping things up, you know, turn-based games are great in mobile. We believe its sort of optimal solution in mobile, where people can pick up and play whenever they have a spare moment. We provide multiple sessions, up to 30 sessions for your game and your player. It's a very simple structure and only one person can write to the data. Game Center manages all the synchronizations through this model.
And we have exchanges, a new feature for iOS 7 that make very difficult scenarios pretty easy, it opens up new game modes and the things to remember are the three Rs of exchanges, request, reply and resolve. We want to thank you for coming today. If you need more information, you can contact Allan Shaffer [phonetic] or Browser New Documentation. There were successions earlier for-- what's new in Game Center and what's new in iTunes Connect. Thank you. [Applause]
[ Silence ]