Hosted Matches

Hosted matches allow your game to use Game Center’s matchmaking service to find players, but use your own server to connect the players to each other. Hosted matches require you to implement your own custom low-level networking code, because Game Center’s servers are not involved in the match play at all. However, hosted games offer larger match sizes and the ability to add your own server into every match.

Matching Players for a Hosted Match

The code you write for hosted matchmaking is similar to the code you write for real-time matches. Before you attempt to create a game that uses hosted matches, you should already be familiar with real-time matchmaking. The critical difference between the two models is that hosted matchmaking returns player identifiers instead of a completed match object. Your game then connects that player to your own server. Your server must match that player’s network address to the player identifier and, similar to a match, perform routing when one device in the match needs to communicate with others.

Table 9-1 lists the most common methods for real-time matchmaking and the corresponding methods or implementation details for hosted matchmaking.

Table 9-1  Methods to implement hosted matchmaking

Real-time matchmaking

Hosted matchmaking

Your view controller delegate implements the matchmakerViewController:didFindMatch: method to receive the match.

Your delegate implements the matchmakerViewController:didReceiveAcceptFromHostedPlayer: method to receive a notification that a player has accepted an invitation to join the match.

Your programmatic matchmaking code calls findMatchForRequest:withCompletionHandler: to create a new match.

Your programmatic code calls findPlayersForHostedMatchRequest:withCompletionHandler: to find a set of new players for a match.

Your programmatic code calls addPlayersToMatch:matchRequest:completionHandler: to add players to a match.

Your programmatic code calls findPlayersForHostedMatchRequest:withCompletionHandler: to find a set of new players for a match. Because you implement your own match architecture, you need to decide when you make this call whether or not you are adding the players to an existing hosted match.

Your game receives an invitation.

The GKInvite object’s hosted property tells you whether the match is a hosted match. Typically, this matters only if your game implements both hosted and nonhosted matches.

Hosted Matches Overview

By default, when you perform the matchmaking process, Game Kit returns an instance of the GKMatch object on each device connected to the match. Each device then uses its match object to communicate with other participants. For most games, this default behavior is exactly what you want. The GKMatch class abstracts the underlying network topology so that your game can simply focus on sending data to other participants without you having to worry about how the data is transmitted.

However, some games may want to support more players than the maximum number of supported players on Game Center, or may want their own server to arbitrate the match. In these cases, you can still use matchmaking to find players for a hosted match. A hosted match does not use GKMatch objects. Instead, each copy of your game receives the player identifiers for all of the players in the match. Your game then takes additional steps to connect the players to your server.

Creating a hosted match requires your game to implement all of the low-level networking required for your game. In particular, you must do all of the following in your game:

Creating a Hosted Match Using the Matchmaker View Controller

To create a hosted match using the matchmaker view controller, you set the view controller’s hosted property to YES before presenting the view controller. Listing 9-1 shows a simple example of this.

Listing 9-1  Creating a hosted match

- (IBAction)hostMatch: (id) sender
{
    GKMatchRequest *request = [[GKMatchRequest alloc] init];
    request.minPlayers = 2;
    request.maxPlayers = 2;
 
    GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc] initWithMatchRequest:request];
    mmvc.matchmakerDelegate = self;
    mmvc.hosted = YES;
 
    [self presentViewController:mmvc animated:YES completion:nil];
}

When the view controller is hosted, your delegate implements the matchmakerViewController:didReceiveAcceptFromHostedPlayer: method to process the new player. Your delegate needs to behave differently depending on which device your game is running on:

Dismissing the MatchMaking View Controller

After all invitees have accepted your app’s match request, you send the information about the players to the server, and then send a start-game message to all of the invitees. When invitees receive the start-game message, they must manually close the view controller for their app.