Graphics, Media, and Games • iOS • 41:36
The ultimate challenge is to compete against a skilled opponent, and Game Center makes it easy for your players to discover each other and play together over a network. Understand the process to add players to a multi-player match. Go into the details of peer-to-peer and server-hosted multiplayer games. Learn about sending data or game state to remote players, and discuss how you can take advantage of in-game voice chat.
Speakers: Jordan Ceccarelli, Christy Warren
Unlisted on Apple Developer site
Downloads from Apple
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
I know you guys got a lot of awesome games out there, and I want to help you by showing you how to add multiplayer to your gaming using Game Center. So first of all, what is multi-player? Well, you can play with others over the networks. These can be your friends, and these can be people you never met before. Multi-player works on both Wi-Fi and cellular, so there's no limits to when you can do multi-player. This is a great opportunity for social gaming. You can foster competition among your players and have them engaged for long periods of time.
This also increases the impact of leaderboards and achievements. If I'm playing a single-player game and I'm off in the corner there, and I get a little achievement against killing some robot or something, so what? But if I'm playing tennis and I ace the guy across the hall and I get the high score, I'm going to go, "Yeah, look at that leaderboard. Look at that achievement I got. I got 10 aces against you in that game." Now, that's awesome. That gets your players engaged. Makes it much more fun.
Now, why add multiplayer? Well, the number one reason you want to add multiplayer is this little message. This is from Notification Center. If I own this game and you don't, and they swipe that, they're going to go right to the store and they can buy your game. So you get free viral marketing right there. It's easy and it's free. This will also make your game stand out.
People love to play against real opponents. Now, if you play that bot, you know, three or four times, you're going to figure it out. But if you're playing that guy across the hall, they're going to keep coming up with new ways to try to beat you. And it'll just go on and on. Also, if your spouse or significant other loves to play games, maybe your game can let them play cooperatively.
She also mentioned that many of the top games on the App Store, if you go to the top 20 today, I bet you you're going to find a significant number that have a major multi-player component. And if you go to any website for gaming, and there's a really popular game that they're talking about, the game doesn't support multi-player.
You can bet their player is asking for it, going, "When are you going to do multi-player?" or even debates about it. but it's a big deal for games. This will also increase the longevity of your game. I mean, most of our games are 5, 10, maybe even 30 hours. But once I finish that single-player campaign, I'm just going to go on and play the next one.
But if your single-player campaign is awesome and I can get all my buddies in the hall of my office to come and play with me, we're going to be playing your game for the next year, and don't you want that? I I do if I'm developing a game. And this gives your game a chance for immortality. If you look back over the history of gaming, the last 10 or 20 years, think about the great gaming franchises. Heck, think about the great gaming franchises today that are talked about. They use multiplayer.
So what you're going to learn today is how to add multiplayer to your game. We're going to talk about the matchmaking UI that we provide. We're going to talk about how you can do programmatic auto-matching. We're going to talk about peer-to-peer communication and the best practices. We're going to tell you how we can help you if you want to host your own game on a server. We're going to tell you how to set up voice chat. And we're going to talk about some issues you need to be aware of relating to Game Center services.
So first of all, these are the styles of multiplayer we support. We support peer-to-peer, turn-based and server-based. In peer-to-peer, let's say you have four players in your game. They're each going to have a copy of your game, and they're going to communicate with each other simultaneously, or in any way you want.
In turn-based, things are more orderly. They'll progress from this player to that player to that player, and so forth, in a very well-ordered sequence. In server-based, you provide your own server, you make your own rules. So let's compare these a little bit. Peer-to-peer supports two to four players. Turn-based and server-based are both two to 16, so they up the limit significantly. The gameplay on peer-to-peer and server is simultaneous. Turn base is sequential.
Now for hosting, on peer-to-peer, it can be hosted on one of the devices in the game, or it can be fully distributed. Turn-based, by its nature, is fully distributed. And on the server, again, it's all up to you. In communications, peer-to-peer supports point-to-point or broadcast. Turn-base is point-to-point, and server is, again, up to you.
Now for data transmission, for turn-based and peer-to-peer, we provide you APIs, so it's really easy. It's literally you pack something into an NSData and send. There's nothing more to it. On server-based, unfortunately, you have to do a little more work, but then you get the benefit of the flexibility.
So let's talk about the basic flow of multiplayer. I've broken it into these three categories that I kind of cutely say: get ready, get set, go. So in the get ready phase, the first thing you've got to do to make a multiplayer game is to pick the players.
Fortunately, we provide you two ways to do so. You can use our UI, or you can do it programmatically and make an auto-match. Either way, you're going to get a player list. And once you have that player list, you wait for each of the players to connect to your device. And once they're connected, you can set up your game and play. And the way you, at that point, all you have to do is communicate data and observe changes in those player state as they come and go or whatever.
So let's talk about choosing players. We have this UI here that lets you invite friends or auto-match. And if you look here, we have examples of both. The players on the bottom are auto-match players. They're just filled there based on the limits you specify. If you click that invite button, it'll take you to a picker that'll let you pick your friend, and then they'll be added to the list like Corey is here.
Now, another important point here is that when you implement this, there's three entry points you have to consider. The most easy to understand entry point is in-game. You've got a button that says "Play Multiplayer." The player presses it, and you get the UI up. Now, the other ways that, you know, this UI will need to come up is, let's say you're in Game Center, and you navigate to your friend's game, and you see that he's playing Russian Bow. Well, there's a play button in Game Center. If they hit play, we will launch your app for you, and we'll supply the app some information, and you have to respond to this and put up the UI.
Similarly, when I invite my friend on their device, they're going to get a message, an alert up, or a notification message. If they swipe play, then we will launch your game, they will get an invite, and they'll need to put up the UI. So in all three, these are three different ways in which you'll need to put up the UI.
So I'm going to now go through a walkthrough of what it takes to implement multiplayer in your game. So I've gone into the pick players and matchmaking. Once you have those, you need to implement didChangeSate and configure your communications. And then during play, you can send or receive data.
Before we go into that, I want to talk about GK Local Player. Some of you may have heard of this before. This represents the user on this device. It's responsible for authentication. It provides the list of friends. But most importantly for multiplayer is this invariant player ID. This is how you're going to associate saves, you're going to cache data, cache achievement progress, record high scores.
And now with iCloud, you're going to store that data on the cloud. Now, one thing I strongly recommend is that when you store data on the cloud, include the player ID key in the key you pass up. And the reason you want that is you may have one iCloud account on your device, but let's say you have your kids using your device to play games. They may have separate Game Center accounts. So to make sure that all works smoothly, please use the player ID to, you know, to make sure that all works smoothly. please use the player ID to store your data.
So authentication. We strongly encourage you to authenticate at launch. If you don't do this, operations may fail, or they will fail because they'll return errors. Another thing to know about authentication is it may get called later. So I'll tell you why that's significant in a moment. So to authenticate, you construct a local player, you call authenticate with completion handler, and you pass in this block. And when it gets called, you check to see if the local player is authenticated. If you do so, you enable Game Center services. If you don't, you disable the features.
Now, this block may get called later. Like, for example, if I'm playing a game with you, and I get a phone call, well, it's going to switch out the app, and I'm going to, you know, talk to my mom or something. When I come back, it has to re-authenticate. So this block holds on to anything that it's referring to for almost the entire life of your app.
So it's... Anything it's referring to will be retained due to the way blocks work, so just be aware of that and manage your memory appropriately. Another caution is thread safety. Multi-player APIs may not be called back on the main thread. This includes delegate callbacks and block-based callbacks. This is because our APIs are asynchronous. And because of this, you need to make sure that you synchronize access to any data that you're talking to, or do a perform selector on main thread to move control back to your main thread based on that. It's up to you.
So now we're going to talk about the matchmaking UI in more detail. So the features of the matchmaking UI, we provide you the standard UI that lets you invite friends to play the game and auto-match. But again, another really cool thing is you can rate games right here. So again, another way that you can market your game by adopting these features.
And when one player uses this UI, if they invite someone, the friend gets a push notification sent to their device, and they can accept or decline, or they can buy the game if they don't have it. So now, I'm going to invite the incomparable Jordan Ceccarelli up to demo some of these features. Thank you, Jordan.
Good morning, everyone. I'm back. If you were here for the last session, we talked a little bit about the single-player experience for Rochambeau, which is this app here in the corner. It's our demo app that we're showing right now to show you people how cool Game Center can be for an app. So right now, instead of talking about single-player, we're going to talk about a live multi-player game. So we will launch the app, and-- oh, look at that. We've got an invite. Let's see. Jessica wants to play with us. How convenient.
Jessica, if you're out there, can you send me another one? Didn't get that one in time. Now one thing, you can barely hear it, but if you listen very closely, you can hear a custom audio sound play when we get this invite. Fancy. Normally, if you've been using Game Center, you'll notice that we normally play the trumpet sound, and we're allowing you to make a custom sound for your invite. That's been cancelled. All right, let's do one more.
There we go. Nice custom sound there. Better than the trumpets, I think. Fits the theme of the game. And here we are right in the matchmaking sheet. So Jessica has started the game with me. And so in this case, we want to pick rock, paper, or scissors. And it's going to -- you know, Jessica's going to pick, I'm going to pick, we'll play a game with each other. So Jessica always picks rock. I know this for a fact. I've looked at the leaderboards, and I can see that that's her trend. So I'm going to pick paper because I'm going to beat Jessica.
Alas, it turns out Jessica has picked scissors, and I have lost. So Jessica gets the crown for this. I'm a little bitter about that, so I'm going to say no, I don't want to play again. But maybe I've come up with a new strategy. I've realized that there is no way Jessica can win again.
So I'm going to play a multi-player game, but this time I'm going to invite Jessica. So we'll invite a friend. Here's our friend list. Hey, she'll know. She'll know what I mean. So this is, again, this is the matchmaking sheet. We're waiting for Jessica to accept the game. And Jessica is now ready, so we can play the game.
So for sure, Jessica will pick rock this time. So paper for the win. Okay, so Jessica's picked scissors once again and gotten the crown. So directly beneath their choice, we can see the time that they took. In the event of a tie, it would just say, "Yay, who did it faster?" So we're not going to play again. But instead, we're going to show another way you can start this game. We can swing by to the actual Game Center client UI, switch over to friends, and we'll look at Jessica here, and we have a game.
Now normally, when you hit play game, if you're in your games, it just launches the game, you're good to go. But in this case, we're in a friend's game sheet. So if we select play game, it'll launch the game, and it'll go straight into an invite sheet, and they'll be auto-selected and ready to go.
What would normally happen in this case, you can see this today, because we ship with this functionality, it launches a matchmaking sheet, and that person will already be auto-selected. So from that point, you just hit play game, they immediately go into the game. And it would look something like this. It's basically a shorter way to get around a live game. We'll invite again.
See if Jessica's up for the challenge. Third time's a charm, right? Yes! Alright. All right, this time let's go rock. Yes! All right, this is excellent. I have won, I get the crown, so now I don't feel bad. If I were to leave right now, I could leave a victor, even though I only won one, but I like leaving on a high note.
So, as you can see, so this game, when you play against the computer, you'll play it a little bit, it's fun, you'll eventually get bored, but now that I'm playing with my friend Jessica or any of my other friends, say, in my office or my family members, this is a game we can just keep playing, because it's fun. So, with that, now you know a little bit how this game should work, and back to you, Christy, you can talk about all these awesome features. Thank you. Thank you, Jordan.
I can't help you with the demo gods, but I might be able to help you with the Roshambo gods. One little advice there, don't announce your move before you make it. Can I have the slides back, please? You don't want to stare at my iPad, do you? Your slide's way cooler. Yes. Thank you.
So now that he's showed you how to do this, let's show you how to implement it. So there's several classes involved doing the matchmaking UI. You make this thing called a match request. You pass it to a GK matchmaker view controller. Internally, it'll use a GK matchmaker, and this will, voila, produce a GK match. And this match is the thing that you'll use to, you know, observe your state changes and send data back and forth. So the match is kind of what you'll live with throughout the course of your game.
So the steps to make a match is to make the match request, initialize a matchmaker view controller with that request, show the controller. At this point, the user can invite the players up to max players. Auto-match will fill in the rest, and you get your match. Let's talk about what this match request is for a moment.
Well, in match request, you can set the minimum and maximum number of players. You can also assign player groups and attributes. However, we'll talk about those a little later. So for now, let's just go through a little code example. So let's say we're talking about two players playing together.
On the initiator side, the initiator sets up the match request and then passes it to the view controller. So here's a simple match request that's for two to four players. They allocate and edit and set the properties. Now they show the matchmaker view controller. So they allocate it. Now this is important. You need to set the matchmaker delegate or various other callbacks that you'll want won't happen, and then you present it.
So there's a few outcomes that can happen for the matchmaking UI. You know, the coolest one is if the user hits play, then you'll actually get that match. This is the function that will give you the match that you'll use throughout the rest of the game. So at this point, you need to set the match delegate to self, and then you can set up and get going with your game.
Now, if the user happens to hit cancel, maybe they don't like playing with that player because they keep beating them or something, then you need to clean up your state. You know, take down the matchmaker view controller and go back to the main menu. Similarly, if the match fails, let's say Jordan's inviting someone who's driving through a tunnel or has other networking issues, you'll get a failure. And you need to look at the error, take appropriate action, and then clean up like you would with cancel.
Now, to handle invites, we provide you this invite handler block that you set. And this is called both when the user launches the game from the Game Center app, or when a user's accepted an invite. In both cases, you'll initialize a new matchmaker view controller with appropriate data, either the requests and players or the invite info, and then put up the UI. So to show this, You know, here's your invite handler block. It's set on the GK Matchmaker.
And by the way, the GK Matchmaker is a shared singleton matchmaker. You don't construct them. You just use this one. And there's an interesting feature of this block. It has two arguments. An invite or players. And only one of these will be non-nil at any given time. And you use this to dispatch. So if you have an invite, invite will be non-nil. If you have players, players will be non-nil.
So in this code here, we go if you have an invite, you construct the matchmaker view controller, init with invite, you set the delegate, and you pose it. In your else case, if you have players, you construct it with the match request that you've saved from before, your players, delegate, pose it. I mean, it's pretty easy.
So in summary, you create a match request, you present the standard UI, you handle invites. And by the way, invites may be called at various times. Let's say you're launching your app and an invite comes in. Well, you need to be prepared for that to show up right after you authenticate. So don't get your game going too far in one way before you do this.
Also, it may get called during the game. Let's say I'm playing the game with Jordan, and my other friend invites me, and I decide, you know, I really want to play with this other person instead. And I go, "Accept." Well, the user has basically made a decision to exit the game with Jordan, so you have to clean up that game and start a new one with a new player.
You just need to handle those various times. And also, the same UI works even if you want to host the game yourself. It won't do everything for you, but will help you out. And now I'm going to go into programmatic automatch, which is really easy, but it builds on these concepts.
So in this case, you get rid of the GK Matchmaker view controller, and you just have the match request and the matchmaker. Create the match request, you feed it to the matchmaker, and guess what? A GK match appears. So show how this is done. You basically get the shared matchmaker. You call find match for request, and you handle the error, and if you don't have an error and you get a match, you basically are ready to play.
Now let me talk a little bit more about this match request. You know, I didn't talk about player groups or attributes, so let's do that now. So to understand player groups, let's assume that you have a racing game, and you have four tracks: oval, figure eight, curvy, and the wave.
And you want to let your players choose which track they want to compete on. So in this case, they wish to do the figure eight. Well, you make the match request. You set the player group to figure eight, which is an enum that you decide. You can choose any arbitrary numbers for this that you wish.
And it's that easy to support different tracks. The other ideas for group assignment include difficulty. If you're really not very good at a game, or maybe you're really awesome, well, you can segregate your players by group. Maybe a game type like deathmatch, capture the flag, or team fortress. Or if your game is really sensitive to lag and you want to minimize latency, well, maybe you group players from North America together, and Europe, and Asia. And that way, they have the best chance to minimize ping.
And if you use player groups, we give you an API to check the activity on a group. So if for some reason you make 20 groups, But like, if one player goes into one group that has no players, well, you can then shift them to another group that's more busy. So that'll help you manage the assignment of these groups in a dynamic way.
Now, player attributes. This is sort of the flip side of the coin. Let's say I want to play on the red team or the blue team. I want to play in a role-playing game. I want to play a fighter, or I want to be the little mage. Well, player attributes let you do these kinds of things. What we do is we provide you a 32-bit unsigned integer, and you assign that for each player, and we OR those values together to form a match. Let me use an example of chess.
Well, I really love to play black, because I like the challenge. So my black bits are going to be all the high order bits. Now let's say someone else likes to play white because they want the advantage of a half move. Well, in that case, they're going to be the low-order bits.
Let's say finally, like Jordan, he doesn't care. He'll play anyone. So we set all ones. Now we OR the values of the players together, and if two players OR together to form 1-1-1-1-1, you get a match. This is a really cool feature. You guys can come up with really cool things to enhance your games. So in summary, auto-match, you create a match request, use player groups and attributes as desired, and then request the match, wait for the players to connect, and play. It's that easy. Now, hosting your own server.
You can use the programmatic automatter, you can use our UI, as I've already mentioned. Now, this is important. You need to use the player ID to track players. Typically, when you make your own server, it might be multi-platform or something. You'll probably have your own sign-in scheme. Well, whatever those usernames are, they need to be associated with player IDs, so you have to maintain that association and keep track of them. As you create matches, you need to communicate these matched players to your server. And unfortunately, we can't do much to help you other than using our networking classes, but you have to implement your own networking.
So, a way to summarize is that we'll hook you up, but then you've got to provide the play. So automatching using the programmatic automatching API is really simple. You make the match request, you set minimum, maximum players. You get the shared matchmaker, and you go find players hosted for match request.
It's a little different than the other one. In this case, it's going to return a list of player IDs rather than a GK match. And you check those player IDs if the count is greater than zero. And if so, you can start your match. If there's an error, you have to handle the error.
Now for the matchmaking UI, there's some small changes. You make the matchmaker view controller. You set hosted to yes, and then you're good to go. You present it. However, There's one little subtle thing here, which is, let's say I go invite Jordan. And so I go to that picker, I choose Jordan, it sends him an invite. He hits accept. His side is going to go sign him onto your server.
But I'm also going to get a callback when he hits Accept, called Did Receive Accept from Hosted Player. And when this comes in, you need to go onto the server and check that he's actually there. And if you do so, call Set Hosted Player Ready or Connected. And if you do this, on the UI where it says Waiting for Jordan, it'll go to Ready. So this is how you provide feedback that the person is actually on the server. So this is a little thing to help you that you have to deal with that we can't do for you.
Now, on both sides, once they hit play, you know, if there's any auto-matches, it's going to go out and do the auto-matches, and when that's all done, it's going to call did-find-players. At this point, you dismiss the view controller, and you start the match. By the way, you should do dismiss the view controller on the other version, too. It was just not on the slide. Jordan Ceccarelli, Christy Warren So now we're going to talk about peer-to-peer networking.
So peer-to-peer networking is our features to handle communications among players. This allows you to send data and receive data. We have options for reliable and unreliable communications, and I'll get into that in a moment. It also, you need to handle player state changes. You know, we've already talked a little bit about waiting for players to connect. We can also handle disconnection mid-game. And we can even add players to an existing game. This is a new feature for iOS 5.
I also recommend you use host selection to minimize network overhead, and I'll explain what that is a little more in a moment. So the classes to use in peer-to-peer multiplayer, they're used in both the wait for players stage and the play stage. In wait for players, you just observe state changes, and this is the right time to perform host selection if you choose to do so. During the play stage, you just send and receive data, and you also listen to did change state just in case people disconnect and you've got to take some action.
So let's talk about sending data. How many of you out there like games that really lag when you play multiplayer? Anyone? Boo! Yeah, I hate that. How many of you like really fast, responsive games? Yeah. So how do you do this? Well, you want to keep data size as small as possible, and you want to minimize update frequency. What that means is you may have written this game that updates at 30 or 60 frames a second, but you definitely don't want to send updates to your peers at that rate. That would be crazy.
And if you're sending updates, you don't want to send your entire model. Let's say we have a tennis -- go back to the tennis game example. If I'm running across the court to hit that backhand or forehand, you don't need to send every animated frame of my motion. You could just send a point maybe every fifth of a second and then let the game interpolate. So that would both keep data size small and minimize update frequency.
Now, let's get back to reliable versus unreliable. So if we're playing tennis, and I just beat Jordan in a game, well, it's one game in a set, but when I send the notice that I won, then I want to get an acknowledgment. I don't want to go into the start of the next game until his device acknowledges it. So that's what reliable means, is that I send the data, and I'll get an acknowledgment.
In contrast with unreliable data, I won't get an acknowledgement for it. It's just best possible delivery. So where would that be useful? Well, if I'm running across the court and I'm sending the updates of position, if I were to be reliable, I'd be moving like this. And so forth. But with Unreliable, I'm just sending smooth updates. And if a packet gets dropped, fine, the other side can interpolate.
Now, the code here shows how to send data to all players. What you do is you make an NSData. You should pack it tightly with your, you know, you know, when you populate it. I recommend you don't use the, you know, NSCoder, because they tend to, you know, make a lot -- use up a lot of space. This is a case where you need to pack your data tightly. And you just call sendData to all players, and then you just have to handle the error.
This is our broadcast. Now, if you want to send to a subset of your players or do point-to-point, you do the same thing, but you just send data to players. Receiving data is really easy. You just implement this method on your GK match delegate. Did receive data, and you parse it. Now let's talk about waiting for players to connect.
You know, I've mentioned this method did change state, and how you can, you know, observe different state changes. But there's one little subtlety here that I need to talk about, which is expected players. Now, this is a property on the match, and it's the number of players you're waiting on. This is not all the players in the match, but rather, let's say, you know, my four-player example. I invite Jordan to play, and there's two auto-match players. Well, in that case, expected number of players is two.
And then as those players connect, that'll count down one, zero, and then we're ready to go. So the way you handle this is if the game has not already started and the match make expected players goes to zero, that's your sign that it's time to start playing. So this little code skeleton kind of sketches this out for you.
Now some offline considerations. Players may come and go. I may be playing, and as I've described before, I take a phone call. Somebody may lose link because they drive through a tunnel, or they may not like the way the game is going, and they may rage hit the home button and go to home. Well, it's important that your game continues in all these cases if there's remaining players, so make sure you handle the disconnect gracefully.
Now, a new feature for iOS 5 is we allow it to reconnect for one-on-one games. What you do is you -- and this is an opt-in because we didn't want to affect compatibility with older games. So what you do is you implement this method should re-invite player on your match delegate, and you just return true. It's as easy as that.
We also allow you to add players to an existing game. So if I'm playing with Jordan, I say, "Hey, you want to come join the fun?" "Sure." Create a match request, create a matchmaker view controller. You call add players to match, and that's illustrated here. It's one new method, and you can add players to the match.
So let's talk about being a good network citizen. We've talked quite a bit about keeping network traffic to a minimum, minimizing the size of the packets, and only sending them as often as you need to. Another level of this is choosing the right network strategy. And we recommend you pick a peer to act as the host.
So to illustrate this, kind of the naive way to implement peer-to-peer is let's say we have four games, one over there, one there, one there, and each of them have a copy of the game model, and each of the players is taking actions. And they're just going to broadcast their updates to each other.
Well, they may get them in different orders. They're going to get updates. They're going to update their models. But now the models may not be in sync, you know, because of different network latencies. So you have to implement a coherency protocol to keep the models up to date. So more traffic. So this is a mess. It's really complicated in your game logic, and it uses a lot of bandwidth. So there's a better alternative.
Pick one device. Pick the one that's on Wi-Fi. Pick the newest device. Come up with your own metric. Come up with your own way to pick one. But pick one. And make that sort of the truth. Now, each of the peers can send their updates to that master in point-to-point communication.
And then the host can broadcast its world updates to the peers. This will at least cut your network bandwidth in half and most likely much more. Thank you. So to summarize peer-to-peer networking, GK Match provides all the API. You need to handle player state changes, and I strongly encourage you to be a good network citizen. And another choice here is consider going the extra mile and hosting your own server. So in-game voice chat.
So voice chat, it's a really cool feature. It adds a lot more liveliness to your game. If I'm playing tennis and I just ace my friend, if he's on the other side of the country, it's just going to be pixels on a screen. But if we're in there in voice chat, I can go, "Yeah, I gotcha!" That's what voice chat will give you.
So this allows players to talk to each other, and gets them more involved, and enhances the sense of competition. It's really easy to integrate, and we handle the networking for you. So some of the features of chat include multiple name chats. So let's say in our tennis example we're playing doubles, and we want to have one chat for all the four players in the game, but I also want to have a private chat for the red team over here. I want to be able to talk strategy or maybe a flaw in their game.
So we allow you to do both. And you can hear audio from whatever set of chats that you wish at any given time. Now, one limitation is the microphone is routed to only one of these chats at a time. You can adjust the volume of a chat or mute the player. Now you handle player state feedback via player state update handler.
So to set up voice chat, you set up an audio session, and the way you do this is you get the shared instance. You then set category, audio/video session category, play and record, and then you set it as active. So once you've made your sessions, here's a little example of what I just talked about with the tennis. So we have a main chat and my team chat for red team. So what we do is we get voice chat with name to get that particular chat.
We stop the main chat so that they can't hear what I'm telling my partner, and then you start the team chat. At that point, you call make team chat active to yes, and this will route the microphone to your team chat. And another good piece of advice here is add audio-visual feedback that the microphone is active. So you can say set -- self-indicate microphone active. That's something you have to implement.
But you might put a microphone by your picture in the game or something. Now, handling player state changes. You know, there's player connected, disconnected, speaking, and silent. These are here for you to You know, make your UI even richer. So if somebody's talking, you can make little sound waves coming out of their photo. So it's really cool.
You should use this. So things to consider in multiplayer setup. Well, you set this up in iTunes Connect, and you set up this thing called a compatibility matrix, which will determine what versions of your game can match with other versions of your game. And let's say I invite Jordan to play Rochambeau.
You know, if I happen to have the latest version and he doesn't, then it'll check the compatibility matrix, and if they aren't compatible, then it'll offer him an update if it's available. But I can only upgrade him to the current version, so if I'm playing some older version, he's going to get the newer version if they're compatible.
So, kind of to wrap up here, some notes on testing. When you get your game out to players, the last thing you want them to do is have a bad experience, have stuff not work. It takes a lot of work to get the stuff to work well. So you need to test on multiple devices, iPads, iPhones, older iPhones, newer iPhones. You need to test on different accounts, different networks.
You know, in this country, Verizon versus AT&T, for example. But test it around the world if you can, because different carriers may have very different quirks that may affect your gameplay. Now, testing on the simulator is limited, so don't -- it's really not going to get you very far. You can't do invitations, there's no voice chat, and there are no push notifications.
So in summary, multiplayer is a really popular feature. It adds longevity to your app. And I've talked about peer-to-peer and hosted gaming. You're going to learn about turn-based in the next session, so stick around for that. It's awesome. We talked about the basic flow, how to use our provided matchmaker UI, some cool things you can do with auto-match.
We told you how we can help you set up for a hosted server. We've talked about peer-to-peer communication and best practices. I've shown you about voice chat. Talked about compatibility and upgrades during Game Center services. And finally, I've given my admonishment about testing. Please test. I want to love your game. I want your game to go to the top of the charts. Good luck.
For more information, talk to Alan Schaffer. and related sessions. You know, they're going to be the essential game technology talks repeated on Friday. and Turn-Based Gaming coming after this. And Nate is going to repeat his session on Friday as well. So please come to those. So thank you very much.