GameKit Guide
GameKit Guide
GameKit Guide
Programming Guide
Contents
2
Contents
Achievements 66
Checklist for Supporting Achievements 66
Designing an Achievement 67
Create Achievements That Show the Different Things Players Can Do in Your Game 68
Create Achievements That Require Different Levels of Skill or Dedication 68
Create Achievements for Different Sections Or Modes Present in Your Game 68
Use Hidden Achievements to Delight and Reward the Player 69
Save Some of Your Budget for Later Versions of Your Game 69
Configuring Achievements in iTunes Connect 69
Adding Achievement Support to Your Game 71
Reporting Achievement Progress to Game Center 71
3
Contents
Challenges 81
Checklist for Supporting Challenges 82
Issuing Challenges from Your Game 82
Displaying the Challenge User Interface 82
Displaying and Dismissing the Challenge View Controller 83
Best Practices for Issuing Challenges 84
Receiving Information About Existing Challenges 85
Reacting to Challenge Events 87
Responding to Challenge Events 87
Responding When the Local Player Selects a Challenge 89
Matchmaking Overview 90
Game Center Supports Multiple Kinds of Matches 90
Game Center Provides Multiple Ways to Connect Players into a Match 91
Matchmaking and Gameplay Are Separate Tasks 92
You Can Match Across Different Versions of Your Game 92
Creating Any Kind of Match Starts with a Match Request 93
A Match Request Must Specify the Number of Players in the Match 94
Inviting a List of Players 95
Player Groups 95
Player Attributes 96
4
Contents
5
Contents
6
Figures, Tables, and Listings
7
Figures, Tables, and Listings
Achievements 66
Table 5-1 Achievement properties 70
Table 5-2 Achievement language properties 70
Table 5-3 Classes in Game Kit used to implement achievement support 71
Listing 5-1 Reporting progress on an achievement 72
Listing 5-2 Reporting progress on an achievement for another player 73
Listing 5-3 Reporting progress on multiple achievements 73
Listing 5-4 Loading achievement progress 74
Listing 5-5 Resetting achievement progress 77
Listing 5-6 Displaying the achievements page of the Game Center user interface. 78
Listing 5-7 Responding when the player dismisses the Game Center content 79
Listing 5-8 Retrieving achievement metadata from Game Center 79
Listing 5-9 Loading a completed achievement image 80
Challenges 81
Table 6-1 Common challenge properties 86
Table 6-2 Challenge subclasses 86
Table 6-3 Kinds of challenge events 87
Listing 6-1 Displaying the challenge user interface 82
Listing 6-2 Preparing the challenge view controller 83
Listing 6-3 Dismissing the challenge view controller 83
Listing 6-4 Retrieving the list of players with lower scores than the one just earned 84
8
Figures, Tables, and Listings
Listing 6-5 Determining the list of players who can complete an achievement challenge 85
Listing 6-6 Retrieving the list of challenges 85
Listing 6-7 Installing a challenge event handler 87
Listing 6-8 Suppressing the challenge banner when the player completes a challenge 88
Listing 6-9 Displaying a custom user interface when the player completes a challenge 88
Matchmaking Overview 90
Figure 7-1 Adding figure that shows the chess combinations 99
Table 7-1 Game Center match types 90
Table 7-2 Important match request properties 93
Table 7-3 Maximum number of players for each kind of match 94
Listing 7-1 A simple match request 94
Listing 7-2 Creating a player group based on the map and rule set 96
Listing 7-3 Setting the player attributes on the match request 97
Listing 7-4 Creating the masks for the character classes 98
Listing 7-5 Creating the masks for chess 98
9
Figures, Tables, and Listings
10
About Game Center
People love to play games. Games on the App Store are no exceptiongames continue to be the most popular
category of apps on iOS. Games are inherently a social activity. Sometimes, this social interaction is part of the
game itself, such as when the game provides competitive or cooperative multiplayer gameplay. But even for
games intended for single-player experiences, players like to see and share their accomplishments.
Because social gaming is such an important part of the game-playing experience, Apple supports it directly
with the Game Center service. Game Center allows a players devices to connect to the Game Center service
and exchange information.
Each player performs different activities but all of them are interacting with Game Center:
Bob uses the Game Center app provided by Apple to view his scores earned in a game that supports Game
Center. The Game Center app shows both Bobs scores and scores earned by other players. Even though
the scores are displayed by the Game Center app, the score data and formatting are provided to Game
Center by the game.
Joe is playing an adventure game that supports achievements. He just discovered an item for a quest he
wants to complete. The game sends a message to Game Center to update the progress stored there.
11
About Game Center
At a Glance
Mary, Alice, and Charlie are playing a game that supports Game Centers matchmaking. Game Center allows
the three players devices to find and connect to each other. The game exchanges data between the
participants through Game Centers servers.
Sara plays another multiplayer game also using Game Centers matchmaking. Saras game supports
turn-based play and Sara has received a push notification that it is her turn to act.
At a Glance
Game Center is best viewed as a collection of interconnected components that provide features both to game
developers and to end users:
The Game Center service is the online portion of Game Center. The Game Center servers store player and
game data and vend the data and other services to Mac and iOS devices.
The Game Kit framework provides classes that developers use to add support for Game Center to their
games. Game Kit is available starting in iOS 4.1 and OS X v10.8.
The Game Center app provides a centralized app that players use to access Game Centers features.
For players to take advantage of Game Center in your gameand for your game to be visible in the Game
Center appyou must explicitly add support for Game Center to your game. You do this by implementing
authentication and then at least one other Game Center feature.
Some Game Resources Are Provided at Runtime by the Game Center Service
All apps include images and localized text inside of its bundle that are used to display the apps user interface.
The app loads these resources from the bundle as needed. When you design a Game Center-aware game,
some of the resources you create are not stored in the bundle. Instead, those resources are uploaded to the
Game Center service during development of your game. At runtime, your game downloads the resources from
Game Center. The main reason for storing these resources on Game Center is that those resources are also
used by the Game Center app. For example, when the Game Center app displays one of your games
leaderboards, it downloads the resources you provided so that it displays the score data the same way as your
game.
The requirement that some of your resources be provided to Game Center affects how you design, develop,
and test your game.
12
About Game Center
At a Glance
Relevant Chapter: Developing a Game Center-Aware Game (page 17), Testing Your Game
Center-Aware Game (page 151)
In iOS, these interfaces are provided as view controllers. A view controller in your game presents one of these
view controllers when necessary. On OS X, the same classes are used, but Game Center provides the infrastructure
required to display them in windows.
Game Kit also provides support for banners. A banner appears for a short time to display a message to the
player. Game Kit automatically presents some banner messages to the player when certain events occur, but
your game can use the GKNotificationBanner class to display your own messages.
Relevant Chapter: Displaying Game Center User Interface Elements (page 28)
Your game must disable all Game Center features when there is not an authenticated player.
13
About Game Center
At a Glance
14
About Game Center
How to Use This Document
A hosted match is similar to a real-time match, but involves your own server in the match. In this model,
you use Game Center to perform matchmaking but design and implement your own low-level networking
code.
A turn-based match uses a store-and-forward model. Your game stores a snapshot of the match data on
the Game Center servers where it can later be downloaded by any players in the match. At any given time,
one of the players is designated as the person who can take a turn in the match. Your game downloads
the match data, the player takes a turn, then your game uploads the modified match data to Game Center.
When a players turn ends, your game designates the next player to act and that player receives a push
notification.
Exchanges allow players who are not the current player to take actions within your game. A player
initiates an exchange by sending an exchange request to one or more other players. These players
are then able to respond to the exchange or let it time out. During the exchange, updates are also
sent to the current player so that match data can be updated.
Relevant Chapter: Matchmaking Overview (page 90), Real-Time Matches (page 100), Hosted
Matches (page 122), Turn-Based Matches (page 125)
All developers must read Working with Players in Game Center (page 32) to learn how to authenticate players
in their game. Then, as necessary, read the other chapters to learn how to implement specific Game Center
features.
Although this guide describes many aspects of communicating with Game Center and using Game Centers
networking features, it is not a reference for low-level networking design patterns. Game Kit provides some
networking infrastructure, but to implement a real-time network game, you need to understand and be
prepared to handle common networking problems such as slow networks and disconnects.
15
About Game Center
Prerequisites
Prerequisites
Before attempting to create a Game Center-aware game, you should already be familiar with developing apps
on whichever platform you are targeting:
Start Developing iOS Apps Today
Start Developing Mac Apps Today
See Also
See Game Kit Framework Reference for details on the Game Kit framework.
The following WWDC session videos also describe Game Center features:
WWDC 2012: What's New in Game Center
WWDC 2012: Integrating Your Games with Game Center
WWDC 2012: Multiplayer Gaming with Game Center
WWDC 2012: Building Game Center Games for OS X
16
Developing a Game Center-Aware Game
Adding Game Center support requires more than simple coding changes. Game Center imposes specific
requirements on the design of your game. For example, to implement leaderboards, your game must have a
way to quantitatively measure a player's performance. But more than that, Game Center changes how you
design and test your game. You aren't simply adding code to your app; you are also configuring assets used
by Game Center. These assets are configured separately from your app bundle but are intimately tied to the
code in your game. You need to test these pieces to ensure that all of the pieces work correctly together.
To create a Game Center-aware game, you need to understand these basics before you begin writing code.
17
Developing a Game Center-Aware Game
Supporting Game Center in Your User Interface
Figure 1-1 shows an example model for a games user interface, shown as a series of screens and transitions
between them. Not all games use this exact organization of user interface screens, but it provides a useful
starting point for a discussion of how adding Game Center might alter your games user interface.
When this sample game is launched, the first thing the player sees is a loading screen. Games often require
large, memory-intensive images, 3D models, sounds and game data. These resources must be accessed quickly
while the game is running. Often, to accomplish this, a game loads critical resources when first launched and
keeps them in memory until the app terminates. A typical loading screen displays information about the game
or your company, along with a progress bar or an animated user interface while the content loads.
After the game has loaded enough resources, it transitions to a menu screen. Typically, this is the first interactive
screen the player sees. The menu screen has a series of buttons that players use to launch the gameplay or
other features of the game. For example, any or all of the following functions are commonly accessed from
the menu screen:
Single-player play mode
Multiplayer play mode
Game configuration options
Social networking services
18
Developing a Game Center-Aware Game
Supporting Game Center in Your User Interface
Using the the screen flow shown in Figure 1-1, tapping the single-player Play button allows the user to choose
the color of their team and the type of transportation they will use in the game. The purpose of this screen is
to provide the player with options on how they want to play the game. Depending on the design of your game,
this configuration process could be a simple interface on a single screen or a complex series of user interface
screens. For example:
A chess game that allows the player the choice of color.
A puzzle game that allows the player to select a particular puzzle to play.
A role-playing game that has a series of screens that allow the player to configure a character.
The gameplay screen is where the bulk of your game logic executes. This part of your project includes rendering
code, user interface interactions, and game logic that executes your games concept. Depending on the type
of game you are implementing, your apps gameplay can be a single screen or a series of multiple screens with
transitions between them.
After the player completes a game, an epilogue screen appears to tell the player how they did. For example,
a game that includes a scoring mechanism can show the player how their score was calculated. Once the player
dismisses this screen, the game transitions back to the main menu.
19
Developing a Game Center-Aware Game
Supporting Game Center in Your User Interface
Figure 1-2 shows the example game modified to incorporate Game Center.
All Game Center apps must authenticate the player. The authentication typically begins as soon as the user
starts your game. In the sample game, the authentication process begins while the title screen is displayed. If
a player is not currently signed in to Game Center, the title screen is temporarily replaced with Game Centers
authentication screen. This screen stays up until the player completes the authentication process or cancels.
Either action returns the player to the title screen. If a player is already signed in to a Game Center account,
then the authentication screen is never displayed. Instead, a banner is briefly displayed to welcome the player
back without leaving the main menu.
The menu screen now includes buttons to display Game Center content. When the player presses one of these
buttons, the game allocates, initializes and presents one of Game Kits user interface classes. When dismissed,
control returns back to the title screen.
The game shown in Figure 1-2 has also been modified to provide a multiplayer game mode. As with single-player
mode, the game presents a series of screens to configure the game. Some of these screens are specific to the
game and are used to configure the games options. Other screens display the built-in matchmaking user
20
Developing a Game Center-Aware Game
Adapting Your Game Design
interface. Note that your own games configuration screens can appear both before and after the matchmaking
screen. The choices made before a matchmaking screen appears are usually choices that affect the matchmaking
experience. For example, the player can choose a specific map to play on, so that they can be matched with
players interested in the same map. The configuration screens that appear after matchmaking is complete are
used to allow the players, now connected into a match, to make other decisions about how the match is played.
Both sets of screens include match configuration data that must be synchronized to all players in the match.
Finally, a Game Center-aware game can be launched because the player received a push notification related
to Game Centerfor example, when the player has been invited to join a match. If your game was launched
as a result of a push notification, it can transition directly into a matchmaking screens immediately after the
authentication process completes. In this case the title screen appears only for a brief period of time.
While Figure 1-2 (page 20) focuses on new screens of content to display, the content on existing screens can
change too, or the tasks you perform on those screens can change. For example, at the end of the match, you
can have your game report the score it displays to a Game Center leaderboard. Similarly, during gameplay, as
a player makes progress towards an achievement, your game sends the updated progress to Game Center.
It is important that you remember that this is only one possible way to design your games user interface. You
should consider other alternatives when building your user interface, and choose one that makes the most
sense for your game. For example, many games use a customized graphics design with a consistent artistic
theme. In this case, the standard user interface classes of Game Center wont match your games theme. So,
one question you must ask is whether you want to use the standard user interface (which takes little effort to
add) or whether you want to incorporate your own custom user interface. If you decide to create a custom
user interface, you should further decide whether to create that user interface as distinct screens of content
or incorporate the content into existing interfaces, such as your games menu screen.
21
Developing a Game Center-Aware Game
Customizing the Game Center Sounds
22
Developing a Game Center-Aware Game
Creating and Managing Game Center Resources
You develop and test your app on your own development machine. App resources are embedded in the
app bundle you create using Xcode. The process of building your app includes these resources in the final
bundle, where they are loaded by your apps binary at runtime.
When your app is complete, you submit the app bundle for review by copying it to iTunes Connect. At
the same time, you create a record in iTunes Connect using the same bundle ID as the one in your app
bundle. This record includes metadata that describes the app; most of this data is used to describe your
app in the App Store. Once submitted, Apple reviews your app and it is either approved or denied.
After your app is approved, you choose when it is published. Once published, the app bundle and metadata
are copied from iTunes Connect to the App Store. There, users discover and purchase the app. Once
purchased, the app bundle is downloaded to the users device.
23
Developing a Game Center-Aware Game
Creating and Managing Game Center Resources
Figure 1-4 shows the additional steps required and the process when creating Game Center assets. Although
this step is not shown, your app bundle and metadata are submitted to iTunes Connect as before.
24
Developing a Game Center-Aware Game
Creating and Managing Game Center Resources
When your game is published, the Game Center assets are copied to the Game Center service in the same
way that your game is copied to the App Store. These builds of your game load the assets from the live
Game Center servers.
Once your assets are published to the live servers, some assets become more difficult to change because
they are already in use by players and live versions of your game. For example, leaderboard scores are
formatted using the leaderboard assets you created. If you changed your scoring mechanism and changed
your leaderboard assets to match, older scores would still be posted on Game Center and would be
inconsistent with newer scores. For this reason, some assets you create cannot be modified after a version
of your game that uses those assets ships. You should set up your development process to ensure that
your assets (and the related code) are extensively tested before you submit your game for review so that
changes to these assets are not necessary.
Game Groups
Game Groups are an additional feature in iTunes Connect that allow you to tie multiple Game Center-aware
games into a single connected group that shares some portion of your Game Center content. Each game in
the game group is a distinct game on iTunes Connect with its own record. However, some assets are shared.
The benefit of a game group is that you can ship multiple distinct versions of your game on the App Store but
still allow these games to act as if they are a single game online. For example:
You have separate iOS and OS X versions of your game.
You have free and paid versions of your game.
25
Developing a Game Center-Aware Game
Incorporating Game Center into Your Game
Game Groups impose additional process overhead on your game design. Now, instead of merely having to
deal with synchronization issues between your game code and the assets you create in iTunes Connect, you
now also need to synchronize any implementation changes between the different game implementations.
See Groups in iTunes Connect Developer Guide for information on how to create and manage game groups
in iTunes Connect.
26
Developing a Game Center-Aware Game
Incorporating Game Center into Your Game
27
Displaying Game Center User Interface Elements
Game Center provides two distinct types of user interface elements for you to use in your game. The first type
is intended to be displayed modally by your game, covering your own games user interface and temporarily
interrupting the normal flow of your game. Typically these user interface screens allow a player to interact
with content loaded from Game Center or to perform Game Center tasks. When the player finishes interacting
with one of these screens of content, your game shows the next appropriate screen, either by returning to
one of your game screens or by advancing to another screenful of content.
In iOS, a fullscreen user interface is packaged as a view controller, and follows the standard conventions of
view controllers on the system. One of your games view controllers is expected to present these view controllers
when needed, and later respond when the view controller is dismissed. On OS X, a special class provided by
Game Kit provides a similar infrastructure so that your game can present the user interface. Other chapters in
this document show the iOS code for presenting a view controller; this chapter shows you how to use the
GKDialogController class to present one of these view controller on OS X.
The second type of user interface element is a banner that is displayed for a short time to the player. Afterwards,
the banner automatically disappears from the screen. While players can interact with some banners, usually
banners are simply used to display a message to the player. Game Center displays many banners on behalf of
your game, but you can also present your own banners to the player if your game has information you need
to display.
Listing 2-1 shows most the common use of this pattern, which is to show the Game Center user interface. The
Game Center view controller displays many different pieces of Game Center content, so most games should
offer a button that brings the player to this screen, even if the game also shows Game Center content using a
custom user interface.
- (void) showGameCenter
28
Displaying Game Center User Interface Elements
Game Center UI Is Displayed by Your Window (OS X)
if (gameCenterController != nil)
gameCenterController.gameCenterDelegate = self;
Listing 2-2 shows a typical implementation of the delegate, which simply dismisses the presented view controller.
Listing 2-2 Responding when the player finishes viewing the Game Center content
- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController
*)gameCenterViewController
In most cases, your game would pause gameplay or other real-time behavior when displaying one of these
standard user interface classes. When the view controller is later dismissed, it can resume these activities.
Listing 2-3 shows how the code in Listing 2-1 is modified to display in OS X. This code loads the singleton
dialog controller and points the dialog controller at the games window. Then it presents the view controller.
The view controller is instantiated and configured exactly as it was on iOS.
- (void) showGameCenter
29
Displaying Game Center User Interface Elements
Displaying Notification Banners
if (gameCenterController != nil)
sdc.parentWindow = myWindow;
Listing 2-4 Responding when the player dismisses the Game Center content
- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController
*)gameCenterViewController
- (void) showBanner
completionHandler:^{
[self advanceToNextInterfaceScreen]
30
Displaying Game Center User Interface Elements
Displaying Notification Banners
}];
31
Working with Players in Game Center
Players are a critical part in any game that supports Game Center, because all Game Center features are related
to the players. As a game developer, you need to understand some of the infrastructure that Game Center
uses to support player accounts and how you implement it in your app. After reading this chapter, you will
understand how to manage player information in your game. In particular, youll learn:
How a game identifies different players on Game Center
How a player logs themselves into Game Center and how your game knows whether a player is logged
into a device it is running on
How to retrieve details about particular players from Game Center
How to implement support in your game so that a player can invite other players to become friends on
Game Center
When a player wants to access Game Center on a particular device, the player signs in, or authenticates on
that device. A player authenticates their account by launching the Game Center app or by launching any game
that implements Game Center support. In either case, the player is presented with an interface to provide their
account name and password. Once authenticated, the player is associated with that device persistently until
they explicitly sign out of Game Center in the Game Center app. Only one player is allowed to be authenticated
on a device at a time; for a new player to be authenticated on the device, the existing authenticated player
must sign out first.
Game Center is intended to be a social experience. Game Center allows a player to invite other players to be
friends. When two players are friends, they can see each others status in the Game Center app, compare scores,
and invite each other into matches more easily. Through Game Kit, your game can also access some information
32
Working with Players in Game Center
Game Center Manages Player Accounts
about a local players friends or allow the player to invite players to become friends. For example, you can use
this functionality to allow a player to send a friend invitation to a player they just met in a match played within
your game.
In addition to using player identifiers in your interactions with Game Center, your game should also use the
player identifier whenever it wants to store data locally about a specific player. For example, if your game
stores data to track a players progress (such as on the device, on your own server, or on iCloud), use player
identifiers to distinguish between multiple players playing on the same device. That way, if a different player
signs into the device, you can immediately personalize the experience by showing content specific to that
player.
Important: Never make assumptions about the format or length of player identifier strings. Although any
individual player identifier string is immutable, the format and length of player identifier strings are subject
to change. You must treat player identifier strings as opaque tokens.
33
Working with Players in Game Center
Game Center Manages Player Accounts
over other players. The local player is the player that is currently authenticated to play on that device. In Figure
3-1, two players are connected in a network match. On the left device, Bob is the local player and Mary is a
remote player. On the right device, Mary is the local player and Bob is a remote player.
Almost all classes in Game Kit that send data to or retrieve information from Game Center expect the device
to have an authenticated local player. The work those classes do is always on behalf of the local player. For
example, if your game reports scores to a leaderboard, it can only report a score earned by the local player. As
such, before using any Game Center features, your game must first authenticate that there is a local player on
the device. Game Kit returns an error to your game if it attempts to perform Game Center-related tasks that
require an authenticated player when one isnt available on the device.
Important: Games that support multitasking should take special note of this behavior. When your game
moves into the background, the player may launch the Game Center app and sign out. Also, another player
might sign in before control is returned to your app. Whenever your game moves to the foreground, it may
need to disable its Game Center features when there is no longer an authenticated player or it may need
to refresh its internal state based on the identity of the new local player.
34
Working with Players in Game Center
Game Center Manages Player Accounts
Property Description
playerID A string that holds the player identifier string used to retrieve this player information.
displayName A user-readable string you can display for this player in your own user interface. For
example, in a network match, you might show the display names for each player in
the match so that everyone knows who they are playing against.
isFriend A Boolean value that states whether the player is a friend of the local player. Note
that this property reflects the general design of Game Center; all information returned
to your game is based on the local player that is signed in to the device.
The GKLocalPlayer class is a special subclass of the GKPlayer class, and includes additional properties
specific to the local player:
The friends property is populated with the identifier strings for other players on Game Center that are
marked as the local players friends.
The underage property states whether this player is underage.
Property Description
friends An array of player identifiers for the players who are friends of the local player. This
property is populated only after your game specifically requests a list of identifiers for
the local players friends from Game Center.
underage A Boolean value that states whether the local player is underage. Some Game Center
features are disabled when the value of this property is YES; Game Center returns a
GKErrorUnderage error if you try to use those features. Your game can also use this
property to decide whether it should disable some of its own features for an underage
player.
In addition to the display name for a given player, if the player has provided a photo, you can download that
players photo to your game and use it in your games user interface.
35
Working with Players in Game Center
Common Tasks When Working with Players
When your game authenticates a player, Game Kit first checks to see whether there is already an authenticated
player on the device. Because a player stays authenticated until they explicitly sign out of Game Center, it is
quite common that an authenticated player is already on the device. In this situation, a banner is briefly shown
to let the player know that authentication succeeded, and then your game is immediately notified.
If there is not currently an authenticated player on the device, then an authentication dialog needs to be
displayed so that the player can sign in with an existing account or create a new Game Center account. This
is important, because it means that supporting authentication also means transparently supporting account
creation.
Important: Game Kit handles opting out of Game Center across all games that support Game Center. If a
player has already declined to create an account, when your game authenticates the player, it is told there
is no authenticated player. The player never sees an authentication dialog. Because Game Kit handles this
process across all games, your game should not include its own mechanism to disable Game Center
authentication or ask a players permission to authenticate. Instead, your game should simply authenticate
the player every time it launches and respond appropriately when authentication completes.
The actual process of displaying the user interface to the player depends on which mechanism you use to
authenticate. There are two ways you can authenticate a player. The original mechanism first used in iOS 4.1
automatically displays a user interface to the player if necessary, but this may happen at an unusual time during
your games launch sequence. The newer mechanism, first implemented in iOS 6, hands your game a view
controller to display at a time of your choosing. Typically, this means your game can cleanly pause its own
animations and other features before displaying the view controller. The newer mechanism allows you to
create a better user experience for the player, and thus is the preferred way to implement authentication. In
OS X, use notifications to know when the authentication dialog is shown and manually pause your game.
36
Working with Players in Game Center
Common Tasks When Working with Players
- (void) authenticateLocalPlayer
if (viewController != nil)
else if (localPlayer.isAuthenticated)
else
[self disableGameCenter];
}];
The authentication handler shows the distinct conditions your code needs to handle:
37
Working with Players in Game Center
Common Tasks When Working with Players
If the device does not have an authenticated player, Game Kit passes a view controller to your authentication
handler. When presented by your game, this view controller displays the authentication user interface.
Soon after, your game should pause other activities that require user interaction and present this view
controller. Game Kit dismisses this view controller automatically when complete, and calls your
authentication handler again.
If the authentication process succeeded, the viewController parameter passed into your authentication
handler holds nil. The local player objects authenticated property holds YES and its other properties
are set to match those of the connected player. Your game should complete the authentication process.
If the authentication process failed, the viewController parameter passed into your authentication
handler holds nil. The local player objects authenticated property holds NO and its other properties
are cleared. Your game should disable all Game Center features.
Always check the authenticated property on the local player object to determine whether Game Kit was
able to authenticate a local player. Do not rely on the error received by your game to determine whether an
authenticated player is available on the device. Even when an error is returned to your game, Game Kit may
have sufficient cached information to provide an authenticated player to your game. Also, it is not necessary
for your game to display errors to the player when authentication fails; Game Kit already displays important
errors to the player on your behalf. Most authentication errors are returned to your game primarily to assist
you with debugging.
If your game supports multitasking, Game Kit keeps a reference to this completion handler until your app
terminates and it cannot be changed. This means any objects referenced in the block are also kept in memory
indefinitely. Each time your game moves from the background to the foreground, Game Kit automatically
authenticates the local player again and calls your completion handler to provide updated information about
the state of the authenticated player.
- (void) authenticateLocalPlayer
38
Working with Players in Game Center
Common Tasks When Working with Players
if (localPlayer.isAuthenticated)
}];
Your game should always check the authenticated property on the local player object to determine whether
Game Kit was able to authenticate the player. Do not rely on the error received by your game to determine
whether an authenticated player is available on the device. Even when an error is returned to your game, Game
Kit may have sufficient cached information to provide an authenticated player to your game. Also, it is not
necessary for your game to display errors to the player when authentication fails; Game Kit already displays
important errors to the player on your behalf. Most authentication errors are returned to your game primarily
to assist you in debugging it.
Enable Other Game Center Code Immediately After a Player Is Successfully Authenticated
Once the player has been successfully authenticated, your game can read other properties on the local player
object to determine the players display name and other attributes. You can also use other classes that access
Game Center. In most cases, your game should immediately enable other code related to Game Center. For
example, here are some common tasks that most games perform after successfully authenticating the local
player:
Read the displayName property to retrieve the local players name. Use this display name throughout
your game when you want to refer to the player; do not prompt the player separately for their name.
39
Working with Players in Game Center
Common Tasks When Working with Players
Add event handlers to receive events for Game Center features. For example, turn-based matches, real-time
matches and challenges all require event handlers to process Game Center events. Because your game
may have been launched specifically to receive a pending invitation; adding event handlers immediately
after authenticating the player allows those events to be processed promptly.
Retrieve the local players previous progress on achievements. See Listing 5-4 (page 74).
Retrieve a list of player identifiers for the local players friends. This is a first step before loading more
detailed information about those players. See Retrieving the Local Players Friends (page 41).
If your game stores its own custom information for a particular player (such as state variables indicating
the players progress through your game), your completion handler might also load this data so that it
can restore the players progress.
Here are some guidelines for authenticating the local player in a game that supports multitasking:
Like other multitasking apps, your game should archive its state before moving into the background.
As soon as your game moves to the background, the value of the local player objects authenticated
property becomes and remains invalid until your game moves back to the foreground. You cannot read
the value to determine if the player is still authenticated until Game Kit reauthenticates the player and
calls your authentication handler. Your game must act as though there is not an authenticated player until
your completion handler is called. Once your handler is called, value stored in the authenticated property
is valid again.
If the value of the authenticated property changed to NO, then there is no longer a local player authorized
to access Game Center content. Your game must dispose of any Game Kit objects that were created using
the previous local player.
If the value of the authenticated property is YES, then there is a local player authenticated on the
device. However, a new player may have logged in. Your game should store the player identifier for the
local player after it authenticates the player. Then, on future calls to your completion handler, compare
the value of the local player objects playerID property to the identifier stored by your game. If the
identifier changed, then a new player has signed in. Your game should dispose of any objects associated
with the previous player and then create or load the appropriate state for the new local player.
40
Working with Players in Game Center
Common Tasks When Working with Players
Retrieving details about the local players friends is a two-step process. First, your game loads the list of player
identifiers for the local players friends (which also sets the friends property). Then, as with any other player
identifiers, your game calls Game Center to retrieve the details for those players.
Listing 3-3 shows how your game loads the list of player identifiers for the local players friends. It then calls
the loadPlayerData: method defined in Listing 3-5 (page 42) to fetch the details for those players. When
using iOS 6.0 and earlier, change the friendIDs property to friends.
- (void) retrieveFriends
if (lp.authenticated)
if (friendIDs != nil)
}];
- (void) retrieveFriends
if (lp.authenticated)
41
Working with Players in Game Center
Common Tasks When Working with Players
if (friends != nil)
}];
if (error != nil)
if (players != nil)
}];
42
Working with Players in Game Center
Common Tasks When Working with Players
If Game Kit was unable to load information for all of the players, it provides an error to the completion handler.
When this occurs, the players parameter may provide a partial array for the players that Game Kit was able
to obtain information about. For this reason, Listing 3-5 tests the error condition separately from processing
the array of player objects.
Listing 3-6 shows a typical implementation of this concept, which follows the same pattern as other Game Kit
classes. It calls the loadPhotoForSize:withCompletionHandler: method on the player object, and then
waits for the completion handler to be called. Note that there is not a property on the player object that stores
the returned photo. You must write your own code to associate player photos with player objects.
if (photo != nil)
if (error != nil)
}];
43
Working with Players in Game Center
Common Tasks When Working with Players
Listing 3-7 shows one way your view controller can allow a player to send a request to other players. For this
method, an array of player identifiers is passed in as a parameter. The method instantiates a
GKFriendRequestComposeViewController object, sets its delegate, and adds the list of players intended
to receive the invitation. The view controller then presents the friend request and returns.
GKFriendRequestComposeViewController *friendRequestViewController =
[[GKFriendRequestComposeViewController alloc] init];
friendRequestViewController.composeViewDelegate = self;
if (identifiers)
[friendRequestViewController release];
Listing 3-8 Responding when the player dismisses the friend request
-
(void)friendRequestComposeViewControllerDidFinish:(GKFriendRequestComposeViewController
*)viewController
44
Leaderboards and Leaderboard Sets
Many games offer scoring systems that measure how well a player does in the game. Scores are not just a way
for players to measure their own progress; they also provide a way for players to compare their skills with those
of other players. In Game Center, a leaderboard is a database of score data. Your game posts scores to a
leaderboard so that the player can later view those scores.
When you add leaderboards to your game, you define what a score means in your game and how score data
is formatted for display.
45
Leaderboards and Leaderboard Sets
Leaderboards Require a Scoring Mechanism
How can you make the integer into something more interesting? As part of the development process, you
configure a leaderboard description in iTunes Connect so that Game Center understands what scores mean
in your leaderboard. You describe to Game Center what type of score is stored in the leaderboard and how to
convert your score into a string for display. An advantage of this mechanism is that the same description is
used by the Game Center app to show your games scores.
The most critical decision to make is what kind of score is stored in the leaderboard. Game Center provides
three basic formatting types:
An abstract number, such as an integer or a fixed point number.
A time value, such as minutes or seconds.
A monetary value, such as dollars or euros.
You also decide the order in which scores are ranked. When scores are ranked low-to-high, a lower score is
considered a better scorefor example, a racing game that records the time it took to complete the race. In
this circumstance, a faster timethat is, a lower scoreis better, so a sorting order of low-to-high is appropriate.
In contrast, a game that adds points to the players total for each successful action taken in the game expects
that a higher score is better, so a high-to-low sorting order would be more appropriate.
Once you have the formatting type and sorting order chosen, you also customize the final results with a
localized formatting string. For example, if you chose to represent the score as an integer, you might choose
point and points as the English localization for singular and plural values of scores stored in that leaderboard.
Other games might use the same score type, but use different localized strings ( laps, cars).
When you design a scoring mechanism, make sure that you consider the range of possible (legal) score values.
When you create the leaderboard description, you can also provide minimum and maximum values for scores
reported to it. Providing a score range adds a layer of security onto your leaderboard, because it reduces the
likelihood that a player can cheat if they discover a way to report an absurdly high score.
46
Leaderboards and Leaderboard Sets
A Game Can Have Multiple Leaderboards
Here are a few possibilities on how you can use different leaderboards in your game:
A game with multiple levels of difficulty can have a different leaderboard for each level of difficulty.
A game with different maps (levels, tracks) can have a different leaderboard for each map.
A game with different play modes (rule sets) can have a different leaderboard for each play mode.
You might create multiple scoring mechanisms that evaluate the players skill in different ways, and create
a different leaderboard for each. For example, a racing game might evaluate the players best track time,
best lap time, as well as a score based how well the player drifts while driving around the track. Evaluating
players in different ways allows players to find multiple ways to improve their skills.
To allow leaderboards to be differentiated from each other in your game, you assign each leaderboard a
leaderboard ID, also known as a category. Your game uses a leaderboard ID to report the score to the
appropriate leaderboard. For example, if your game included three leaderboards for different levels of difficulty,
you might use myGame.easy, myGame.normal and myGame.hard as the leaderboard IDs.
The initial value for the default leaderboard is the value you assign in iTunes Connect. However, as a player
plays your game, you can set a different default leaderboard for that player. You can change the default
leaderboard automatically when reporting a new score or you can change the default leaderboard independent
of score reporting. For example, if your game has multiple sequential levels and a leaderboard for each level,
you can change the default leaderboard each time the local player advances to a higher level. That way, future
scores (or displayed leaderboards) automatically show the best level the player has played.
47
Leaderboards and Leaderboard Sets
Combined Leaderboards Gather Scores from Multiple Single Leaderboards
When deciding whether to set up one or more combined leaderboards for your game, keep the following
guidelines in mind:
Only noncombined leaderboards can be included in a combined leaderboard. That is, you cannot combine
other combined leaderboards into a combined leaderboard.
A noncombined leaderboard can only be attached to one combined leaderboard.
The noncombined leaderboards that are attached to a combined leaderboard must have the same score
format type and sort order. And, in practice, they should share the same scoring mechanism in your game.
For complete details on managing your games leaderboards and leaderboard sets see iTunes Connect Developer
Guide . However, for your convenience, Table 4-1 describes the properties you use to define a single leaderboard.
Table 4-2 lists the properties you set for each language you plan to localize your game into.
Property Description
Leaderboard An internal name for your leaderboard, used only in iTunes Connect. This is the
Reference Name name that you use to search for your leaderboard in iTunes Connect.
Leaderboard ID A chosen alphanumeric identifier for your leaderboard. This ID is limited to 100
characters. Your leaderboard ID is a permanent setting and cannot be edited at
a later date.
48
Leaderboards and Leaderboard Sets
Working with Leaderboards in iTunes Connect
Property Description
Score Format Type Choose the type of format in which you want scores to be expressed in the
leaderboardfor example, integer, elapsed time, or money.
Sort Order Choose between Low to High or High to Low for the display of your
leaderboard scores. Choose Low to High if you want lowest scores displayed
first. Choose High to Low if you want highest scores displayed first.
Score Range Define the score range using 64-bit signed integers. The values must be between
the long min (-2^63) and long max (2^63 - 1). Any scores outside of this range
will be deleted. Score range values are optional, but if they are added then both
values must be set and they must not be equal. When first adding a score range,
or when changing it in the future to a smaller range that will restrict data, all
data outside of the range will be lost and cant be recovered.
Property Description
Name The name of the leaderboard that appears in the standard leaderboard user
interface.
Score Format This property determines how your scores are displayed when the leaderboard
is displayed in the specified language. For example, if your leaderboard stores
a score as money, you may want to specify different types of money based on
the language you select. The permitted values for this property are based on
your Score Format Type.
Score Format Suffix This suffix is added to the end of scores displayed in the singular form. This suffix
(Singular) is optional, but is useful for clarifying the type of score stored in the leaderboard.
Examples include point, and hit.
Score Format Suffix This suffix is added to the end of scores displayed in the plural form. This suffix
(Plural) is optional, and is useful for clarifying the type of score stored in the leaderboard.
Examples include points, coins, and hits.
Image A localized image that represents the leaderboard. This property is optional; if
specified, the image is displayed as part of the standard leaderboard user
interface. The image must be a .jpeg, .jpg, .tif, .tiff, or .png file that is
512 x 512 or 1024 x 1024 pixels, at least 72 dpi, and in the RGB color space.
For more information on setting up your leaderboards in iTunes Connect, see Game Center.
49
Leaderboards and Leaderboard Sets
Adding Leaderboard Support to Your Game
GKScore A GKScore object holds information for a score that was earned by the
player. Your game creates GKScore objects to post scores to a leaderboard
on Game Center. When a game retrieves score information from a
leaderboard those scores are returned as GKScore objects.
The following sections describe common tasks and how to implement them.
- (void) loadLeaderboardInfo
self.leaderboards = leaderboards;
}];
50
Leaderboards and Leaderboard Sets
Adding Leaderboard Support to Your Game
Table 4-4 lists the properties that you typically access on a leaderboard object.
Property Description
groupIdentifier Holds the group identifier for when your game shares the leaderboard with
other games in a game group.
Listing 4-2 shows how to use an array of GKScore objects to report a score to Game Center.
scoreReporter.value = score;
scoreReporter.context = 0;
51
Leaderboards and Leaderboard Sets
Adding Leaderboard Support to Your Game
}];
The score object is initialized with the leaderboard ID for the leaderboard it reports its score to and then the
method sets the value property to the score the player earned. The leaderboard ID must be the identifier for
a leaderboard you configured in iTunes Connect. The player who earned the score and the time the score was
earned are set automatically when the score object was created. Scores are always reported for the local player.
Your game should create the score object and report the score to Game Center immediately after the score is
earned. This sets the date and time accurately and ensures that the score is reported correctly. If for some
reason the score could not be reported because of a network error, Game Kit automatically resends the data
when the network becomes available.
Listing 4-3 shows how to use a score object to report a score to Game Center.
scoreReporter.value = score;
52
Leaderboards and Leaderboard Sets
Adding Leaderboard Support to Your Game
scoreReporter.context = 0;
}];
If you need to know the default leaderboard for the local player, you retrieve it using code similar to that in
Listing 4-4.
Listing 4-4 Loading the default leaderboard for the local player (iOS 7)
}]
The most common time to update the default leaderboard is when you report a score, and Game Kit provides
a convenient way to set the default leaderboard as you report the score. Create the score object, and then set
its shouldSetDefaultLeaderboard property to YES. When the score is reported, the score objects category
becomes the new default leaderboard ID.
Listing 4-5 Updating the default leaderboard when reporting a score (iOS 7)
scoreReporter.shouldSetDefaultLeaderboard = YES
...
However, you can also use the GKLocalPlayer object to update the default leaderboard directly.
53
Leaderboards and Leaderboard Sets
Adding Leaderboard Support to Your Game
Listing 4-7 Loading the default leaderboard for the local player (iOS 6)
}]
Changing the leaderboard in iOS 6 is accomplished by changing the category identifier for the leaderboard.
Listing 4-8 provides an example of how to do this using the
setDefaultLeaderboardCategoryID:completionHandler: method.
54
Leaderboards and Leaderboard Sets
Adding Leaderboard Support to Your Game
leaderboard page, displaying only scores earned in the last day. The view controller is then presented. In OS
X, you use the GKDialogController class to display the view controller, as described in Displaying Game
Center User Interface Elements (page 28).
Listing 4-9 Displaying the leaderboard page of the Game Center user interface
if (gameCenterController != nil)
gameCenterController.gameCenterDelegate = self;
gameCenterController.viewState = GKGameCenterViewControllerStateLeaderboards;
gameCenterController.leaderboardTimeScope = GKLeaderboardTimeScopeToday;
gameCenterController.leaderboardCategory = leaderboardID;
When the player finishes looking at the leaderboard, the delegate is called. Listing 4-10 shows a typical
implementation, which simply dismisses the presented view controller.
Listing 4-10 Responding when the player dismisses the Game Center content
- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController
*)gameCenterViewController
55
Leaderboards and Leaderboard Sets
Adding Leaderboard Support to Your Game
Property Effect
playerScope You can choose whether to restrict the search to the local players friends or to find
scores from any player. Optionally, you can also initialize a leaderboard object to
search for scores for a specific group of players that you supply.
timeScope You can choose to filter based on when the score was earned.
category You can choose to filter based on which leaderboard the score is displayed in.
NOTE: Deprecated in iOS 7. Use identifier instead.
identifier You can choose to filter based on which leaderboard the score is displayed in. For
iOS 7.
range You can pick scores within a specific range. For example, the range [1,10] returns
the best ten scores found by the query.
Retrieving a subset of leaderboard data stored on Game Center has the following steps:
1. Start with the set of all scores stored in the leaderboard.
2. Discard any scores that do not match the playerScope, timeScope and identifier properties.
Use the category property when supporting games developed for iOS 6 and earlier.
3. Keep only the best remaining score for each player.
4. Sort the list of scores from best to worst.
5. Return the subset of scores requested by the range property.
56
Leaderboards and Leaderboard Sets
Adding Leaderboard Support to Your Game
Figure 4-1 shows an example of one possible search. The code that performs this search is provided later in
Listing 4-11 (page 58). In this example, scores more than a day old are ignored. Then, from the remaining set
of scores, we see that Bob has two scores, so only his best score is kept. Finally, the scores are sorted and
ranked. The selected range is then returned to the game.
Figure 4-1 Leaderboard data is filtered, sorted, and returned to your game
57
Leaderboards and Leaderboard Sets
Adding Leaderboard Support to Your Game
If you provide a category that matches a combined leaderboard, all of the scores in the single leaderboards
are pooled together before filtering and sorting occurs. Figure 4-2 shows the same scores as in the earlier
example, but now you can see that the scores are actually stored in two different leaderboards that make up
a combined leaderboard.
Figure 4-2 Combined leaderboards include scores from the single leaderboards
Listing 4-11 shows an example leaderboard data query. The method for this query initializes a new leaderboard
object and configures the playerScope, timeScope, and range properties to grab the top ten scores earned
today.
- (void) retrieveTopTenScores
if (leaderboardRequest != nil)
leaderboardRequest.playerScope = GKLeaderboardPlayerScopeGlobal;
leaderboardRequest.timeScope = GKLeaderboardTimeScopeToday;
leaderboardRequest.identifier = @"Combined.LandMaps"
leaderboardRequest.range = NSMakeRange(1,10);
if (error != nil)
58
Leaderboards and Leaderboard Sets
Adding Leaderboard Support to Your Game
if (scores != nil)
}];
Your game can create a leaderboard request that retrieves scores for a specific list of players you are interested
in. Listing 4-12 provides an array of player identifiers to the query. When you provide a list of players, the
playerScope property is ignored.
leaderboardRequest.timeScope = GKLeaderboardTimeScopeAllTime;
leaderboardRequest.identifier = @"Combined.LandMaps"
leaderboardRequest.range = NSMakeRange(1,10);
if (query != nil)
{
if (error != nil)
if (scores != nil)
59
Leaderboards and Leaderboard Sets
Adding Leaderboard Support to Your Game
}];
Note: Use leaderboardRequest.category when maintaining games that support iOS 6 and
earlier.
In either case, the returned GKScore objects provide the data your game needs to create a custom user
interface. Your game can use the score objects playerID to load the players alias, as described in Retrieving
Information About Players (page 42). The formattedValue property provides a string with the score value
formatted according to the parameters you provided in iTunes Connect.
Important: You may be tempted to write your own formatting code rather than using the formattedValue
property. Do not do this. Using the built-in support makes it easy to localize the score value into other
languages, and provides a string that is consistent with the presentation of your scores in the Game Center
app.
To maintain an optimal user experience, only query the leaderboard for data your game needs to use or display.
For example, do not attempt to retrieve all the scores stored in the leaderboard at once. Instead, grab smaller
portions of the leaderboard and update your views as necessary.
60
Leaderboards and Leaderboard Sets
Leaderboard Sets
You can implement the replay directly into your gameplay. For example, in the hypothetical racing game,
you could use a players replay file to display a phantom car for the current player to race against.
Leaderboard Sets
Leaderboard sets offer developers the ability to combine several leaderboards into a single group. iOS developers
are able to create leaderboard sets starting with iOS 7. Leaderboard sets are not supported in OS X v10.9.
The following example shows why you would want to incorporate leaderboard sets in your game.
The created game has several different worlds with each world containing several leaderboardsfor
example, a leaderboard for most coins collected, highest score obtained, and most enemies captured.
The developer combines the different leaderboards into a single leaderboard set for each world.
Users can see a displayed list of world leaderboard sets. Opening a set shows the leaderboards contained
in the set.
61
Leaderboards and Leaderboard Sets
Leaderboard Sets
Important: After you decide to use leaderboard sets, every leaderboard must be placed into a leaderboard
set. You can not have a leaderboard outside of a leaderboard set in games that support leaderboard sets.
Figure 4-3 shows the leaderboards for each world combined into a leaderboard set.
62
Leaderboards and Leaderboard Sets
Leaderboard Sets
5. Add code to load the leaderboards contained within a leaderboard set. See Loading Leaderboards Within
a Set (page 65).
Here are a few possible ways to use different leaderboard sets in your game:
A game with multiple scoring mechanisms for each world (score, enemies captured, coins collected) can
combine the leaderboards for each world into a leaderboard set.
A game with multiple scoring mechanisms for each world (score, enemies captured, coins collected) can
combine all of the leaderboards for a single scoring mechanism into a leaderboard set.
A game with multiple playable characters (warrior, archer) can combine all of the leaderboards for a
particular character into a single leaderboard set.
You can combine the number of leaderboards and leaderboard sets in any format as long as the individual
maximums are not exceeded. The following are all allowable combinations:
5 leaderboard sets, each containing 100 leaderboards
100 leaderboard sets, each containing 5 leaderboards
3 leaderboards sets, each containing 50 leaderboards; 2 leaderboard sets, each containing 100 leaderboards;
1 leaderboard set containing 1 leaderboard
63
Leaderboards and Leaderboard Sets
Leaderboard Sets
Table 4-6 Game Kit classes used to implement leaderboard set support
GKScore A GKScore object holds information for a score that was earned by the
player. Your game creates GKScore objects to post scores to a leaderboard
on Game Center. When a game retrieves score information from a
leaderboard those scores are returned as GKScore objects.
Before you can load the leaderboards contained within a set, you must load the set itself. Retrieve the list of
leaderboard sets for your game from Game Center and display their titles.
- (void) loadLeaderboardSetInfo
64
Leaderboards and Leaderboard Sets
Leaderboard Sets
[GKLeaderboardSet loadLeaderboardSetsWithCompletionHandler:^(NSArray
*leaderboardSets, NSError *error) {
self.leaderboardSets = leaderboardSets;
}];
- (void) loadLeaderboardInfo
self.leaderboards = leaderboards;
}];
65
Achievements
Achievements are a great way to track what a player has done in your game and to give the player more
incentive to keep playing your game. An achievement represents a quantitative goal that the player can
accomplish in your game. As the local player plays your game, they make progress towards completing the
achievement. When the player meets or exceeds the goal, the achievement is considered earned, and the
player is rewarded. Your game defines the goal and the game mechanics that describe how a player earns the
achievement. In practice, Game Center does not need to know anything about your game design; it only knows
what progress the player has made towards an achievement.
In Game Center, an achievement earns a player achievement points. When you define an achievement, you
decide how many points it is worth. A player can see the total number of points that can potentially be earned
in your game as well as how many points he or she has currently earned. The Game Center app allows players
to compare their achievements with those of friends; this comparison screen includes the total points earned.
When you add an achievement to your game, you configure how the achievement is granted and how it is
described to the player. You also design the game mechanics that allow the player to make progress towards
completing the achievement.
66
Achievements
Designing an Achievement
6. Add code to display the players progress towards achievements. See Displaying the Standard Achievement
User Interface (page 78) to see how your game can display the standard achievements screen.
Optionally, you can retrieve achievement data from Game Center and use it to create your own custom
achievement user interface. See Creating a Custom Achievement User Interface (page 79).
Designing an Achievement
The design of an achievement starts with a simple statement of the achievements goal. Here are some example
goals that can define a game:
Capture 10 pirates.
Defeat 1 boss.
Find 1000 gold coins.
Earn first place in 5 races.
Earn first place on 5 different race tracks.
A goal statement describes a triggering condition (Earn first place on a different race track) and a quantity
(5). The triggering condition is essential as it defines something your game logic needs to track. In the racing
example, your game must check the victory conditions at the end of each race, but it also needs to record
which race tracks a player has defeated.
The quantity usually defines how granular the task is for the player. With some achievements, quantity is
irrelevant; the achievement is either earned or not. For example, Defeat the end-game boss is not a goal that
the player generally earns partial credit towards completing. In contrast, a goal of Capture 10 pirates is a
more granular task. Your game needs to track the number of pirates captured and use this count to report
progress to Game Center.
When you design an achievement, consider a few other characteristics: value, visibility, and repeatability. These
characteristics affect more than the design of your game; later, when you define your achievement in iTunes
Connect, youll set attributes based on these characteristics:
The value of an achievement is a measure of how difficult you believe it will be for a player to earn the
achievement. Some achievements are easily earned in a few minutes of play. Difficult achievements might
require hours of focused gameplay or require the player to develop advanced playing skills or strategies
to earn the achievement.
The visibility of an achievement determines whether a player can see the achievement at the start of play
or whether the achievement must be discovered during play. By default, achievements are visible to the
player. This is helpful, because a player can scan the list of available achievements and see what actions
earn rewards. However, some achievements can be more useful if hidden. For example, if your game
67
Achievements
Designing an Achievement
includes a story or plot, listing all of the achievements at the start of play may reveal too much of the story
to the player. Achievements critical to the story can be marked as hidden so that you can choose when
the player sees them.
An achievement is normally not repeatable. After the achievement is earned, the player sees no further
messages about that achievement. If an achievement is marked as repeatable, then each time your game
reports that the player has completed the achievement, the player sees the appropriate reward banner.
You have a lot of room to be creative with the kinds of achievements you create. Here are some common
strategies for designing achievements that can guide you through the process.
Create Achievements That Show the Different Things Players Can Do in Your
Game
When experienced players purchase new games, they examine the list of achievements to see whats possible
in those games. Your list of achievements should strongly communicate what you want players to think about
or do while playing your game. You want achievements to provide a variety of different goals a player can
strive towards. When you provide a variety of goals and achievements, players continue to play your game.
Another reason to include more difficult achievements is that they encourage players to use them when
challenging other players. See Challenges (page 81).
68
Achievements
Configuring Achievements in iTunes Connect
If your game does partition its gameplay into smaller mini-games, define achievements for each, because it
encourages players to try each of the game modes or to complete your game.
Avoid spending all of your budget on the initial version of your game. Save some of your budget to support
updates and new content.
69
Achievements
Configuring Achievements in iTunes Connect
Property Description
Achievement Reference An internal name that you must provide for each achievement, used only
Name in iTunes Connect. This is the name you will use if you search for the
achievement in iTunes Connect.
Achievable More Than Indicates whether the user can earn the achievement multiple times.
Once
Property Description
Language The language in which you would like this achievement to appear.
Title The localized title of this achievement as you would like it to appear in Game
Center.
Pre-earned Description The description of your achievement as it appears to a Game Center player
before he or she earns it.
Earned Description The description of your achievement as it appears to a Game Center player
after he or she earns it.
Image A localized image that represents the achievement. The image must be a
.jpeg, .jpg, .tif, .tiff, or .png file that is 512 x 512 or 1024 x 1024
pixels, at least 72 dpi, and in the RGB color space. This property is required.
For more information on setting up your leaderboards in iTunes Connect, see Game Center.
70
Achievements
Adding Achievement Support to Your Game
GKAchievement- Holds the localized text and images for an achievement. The data for
Description achievement descriptions is retrieved from Game Center at runtime and
is based on the data you provided to iTunes Connect when you created
your achievement there.
GKGameCenterView- Provides a standard user interface to display Game Center content to the
Controller player. This content includes an achievements page.
Your game reports the players progress by using a floating-point percentage, from 0.0 to 100.0, that represents
how much of the achievement the player has completed. You decide how that percentage is calculated and
when it changes. For example, if the player earns an achievement simply for discovering a location in your
game, then you would simply report the achievement as 100 percent complete the first time you report progress
to Game Center. On the other hand, for an achievement like Capture 10 pirates, your reporting mechanism
increments by 10 percent each time the player captures a pirate.
71
Achievements
Adding Achievement Support to Your Game
If the achievement was previously hidden, it is revealed to the player. The achievement is revealed even
if your player has made no actual progress on the achievement (a percentage of 0.0).
If the reported value is higher than the previous value reported for the achievement, the value on Game
Center is updated to the new value. Players never lose progress on achievements.
When the progress reaches 100 percent, the achievement is marked as completed, and both the image and
completed description appear when the player views the achievements screen.
Listing 5-1 shows how to report progress to Game Center. First, a new achievement object is initialized using
an identifier string for an achievement. Next, the objects percentComplete property is set to reflect the
players progress. Finally, the objects reportAchievementWithCompletionHandler: method is called,
passing in a block to be notified when the report is sent.
if (achievement)
achievement.percentComplete = percent;
if (error != nil)
}];
In iOS 7, you can report achievements for other players when ending a turn-based match. Only the current
player is able to report achievements.
72
Achievements
Adding Achievement Support to Your Game
if (achievement)
achievement.percentComplete = percent;
if (error != nil)
{
}];
- (void) completeMultipleAchievements
achievement1.percentComplete = 100.0;
achievement2.percentComplete = 100.0;
achievement3.percentComplete = 100.0;
73
Achievements
Adding Achievement Support to Your Game
if (error != nil)
}];
}
Whether reporting progress on a single achievement or on multiple achievements at once, your game rarely
needs to do anything specific when an error occurs. If an error occurs, such as when a network is not available,
Game Kit automatically resends the data at an appropriate time.
- (void) loadAchievements
if (error != nil)
if (achievements != nil)
74
Achievements
Adding Achievement Support to Your Game
}];
A logical time to load the local players progress is immediately after the player is authenticated.
As the player progresses through your game, you want to update their progress on Game Center. If your game
has previously reported progress towards this achievement, your game should first load the players progress
from Game Center so that you know what progress the player has already made. If the player has made progress
on an achievement that the player has never made progress on before, your game should create a new
achievement object. An easy way to manage these achievement objects in your game is by using a mutable
dictionary, using the identifier property as a dictionary key, and the achievement object as the contents
for that key. Heres how to modify Listing 5-1 (page 72) and Listing 5-4 (page 74) to use a dictionary:
1. Add a mutable dictionary property to your class that reports achievements; this dictionary stores the
collection of achievement objects.
3. When your game loads achievement data, add the achievement objects to the dictionary.
- (void) loadAchievements
[GKAchievement loadAchievementsWithCompletionHandler:^(NSArray
*achievements, NSError *error)
if (error == nil)
}];
75
Achievements
Adding Achievement Support to Your Game
4. Implement a method that tests the dictionary for a particular achievement identifier. If the identifier does
not exist as a key in the dictionary, create a new achievement object and add it to the dictionary.
if (achievement == nil)
[achievementsDictionary setObject:achievement
forKey:achievement.identifier];
return achievement;
5. Modify the code in Listing 5-1 (page 72) to call getAchievementForIdentifier: to retrieve the
achievement object.
if (achievement)
achievement.percentComplete = percent;
[achievement reportAchievementWithCompletionHandler:^(NSError
*error)
if (error != nil)
76
Achievements
Adding Achievement Support to Your Game
}];
- (void) resetAchievements
if (error != nil)
77
Achievements
Adding Achievement Support to Your Game
}];
When your game resets a players progress on achievements, all progress information is lost. Hidden
achievements, if previously shown, are hidden again until your game reports progress on them. For example,
if the only reason those achievements were originally hidden was that they were associated with an In-App
Purchase, then you would reveal those achievements again.
Listing 5-6 Displaying the achievements page of the Game Center user interface.
if (gameCenterController != nil)
gameCenterController.gameCenterDelegate = self;
gameCenterController.viewState = GKGameCenterViewControllerStateAchievements;
When the player finishes looking at the leaderboard, the delegate is called. Listing 5-7 shows a typical
implementation, which simply dismisses the presented view controller.
78
Achievements
Adding Achievement Support to Your Game
Listing 5-7 Responding when the player dismisses the Game Center content
- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController
*)gameCenterViewController
Loading achievement descriptions is a two-step process. First, your game loads the text descriptions for all
achievements in your game. Then, when an achievement is completed and you want to display the completed
image, you explicitly load that image. This allows your game to load only images you need, which reduces its
memory footprint.
Listing 5-8 shows how to load the achievement descriptions using the
loadAchievementDescriptionsWithCompletionHandler: method.
- (void) retrieveAchievmentMetadata
[GKAchievementDescription loadAchievementDescriptionsWithCompletionHandler:
if (error != nil)
if (descriptions != nil)
}];
79
Achievements
Adding Achievement Support to Your Game
Although the properties are self-explanatory, one critical property worth noting is the identifier property.
This corresponds to the achievement identifier used in iTunes Connect and on a GKAchievement object. When
you design your custom user interface, you use the identifier property to match each
GKAchievementDescription object to the corresponding GKAchievement object that records the players
progress on that achievement.
The value of the image property is nil until you tell the object to load its image data. Listing 5-9 shows how
your game tells an achievement description to load the image.
if (error == nil)
// Use the loaded image. The image property also holds the same image.
}];
The GKAchievementDescription class also provides two default images your game can use. The
incompleteAchievementImage class method returns an image that should be used for any achievement
that has not been completed. If your game is unable to load an image for a completed achievement (or you
want to display an image while the custom image is loading), the placeholderCompletedAchievementImage
class method provides a generic image for a completed achievement.
80
Challenges
Achievements and leaderboards both allow players to measure their progress playing your game. But it is also
common for players to want to test their progress against each other. Its more satisfying to beat a friends
score than to merely achieve a decent score. Game Center embraces this idea in the form of challenges. Players
on Game Center can challenge other Game Center members to beat earned scores or achievements. Challenges
represent a different style of multiplayer experience where players compete against each other indirectly.
When a challenge is issued by one player to another, a push notification is sent to the challenged player. The
challenged player can then accept or refuse the challenge. If the player accepts the challenge, the challenge
is placed on a list of challenges associated with that player. Later, if the player beats the challenge, Game Center
notifies both the challenged player and the challenger that the challenge is complete.
If your game supports achievements or leaderboards, it automatically supports challenges without requiring
any additional code. In this case, players go to the Game Center app to challenge their friends. However, you
can also customize your game to directly support challenges:
You can allow players to challenge other players from within your game.
You can retrieve the list of open challenges for the local player.
Your game can receive notifications when players tap banners for new challenges.
Your game can receive notifications when players receive or complete challenges. You can even prevent
challenge banners from being displayed when your game is running, allowing you to completely control
the user interface displayed when a challenge event is received by your game.
You can determine whether your game shows challenge banners inside of the game by adding
GKShowChallengeBanners to your Info.plist. See Cocoa Keys for details.
81
Challenges
Checklist for Supporting Challenges
The design for score-based challenges is similar. Create a score object, submit the score, then use it to generate
a challenge request.
- (void) bossMonsterDefeated
achievement.percentComplete = 100.0;
82
Challenges
Issuing Challenges from Your Game
achievement.showsCompletionBanner = NO;
if ([segue.identifier isEqualToString:@"achievementChallenge"])
MyAchievementChallengeViewController* challengeVC =
(MyAchievementChallengeViewController*) segue.destinationViewController;
challengeVC.delegate = self;
Listing 6-3 shows the issuing controllers implementation of the delegate method. When the user dismisses
the challenge view controller, the delegate is called. The delegate method takes a parameter that states whether
the player issued a challenge. If the player issued a challenge, then the method retrieves the list of players and
the message from the challenge view controller and issues the challenge. Note that this design gives control
over issuing the challenge to the original view controller. If your design does not need this additional flexibility,
you could simply issue the challenge directly from the challenge view controller instead.
- (void) challengeViewController:(MyAchievementChallengeViewController*)controller
wasDismissedWithChallenge:(BOOL)issued
83
Challenges
Issuing Challenges from Your Game
if (issued)
[controller.achievement issueChallengeToPlayers:controller.players
message:controller.message];
Ideally, your game should provide default behavior that matches a players expectations. The default message
and list of players should be reasonable choices that a player might make. For example, when a player wants
to issue a score challenge, your first impulse might be to include all of a players friends in the challenge. In
practice, that may not be the best answer. Some of the players friends may have already earned much higher
scores. Instead, consider something like the algorithm in Listing 6-4. It searches the leaderboard using a
friends-only filter. The resulting friends list is then filtered so that only players who have not earned as high of
a score are challenged.
Listing 6-4 Retrieving the list of players with lower scores than the one just earned
query.category = category;
query.playerScope = GKLeaderboardPlayerScopeFriendsOnly;
query.range = NSMakeRange(1,100);
84
Challenges
Receiving Information About Existing Challenges
}];
Your challenge view controller can then use the score data to populate its user interface. For example, it can
use the player identifiers embedded in the score to load the name and photo of each challenged player. You
can perform a similar operation for achievement challenges using the
selectChallengeablePlayerIDs:withCompletionHandler: class method. Listing 6-5 shows a possible
implementation of this.
Listing 6-5 Determining the list of players who can complete an achievement challenge
if (challengeablePlayerIDs)
}];
Challenges are represented on the system by GKChallenge objects. You can get the list of outstanding
challenges by calling the loadReceivedChallengesWithCompletionHandler: class method. Listing 6-6
shows a simple implementation of this concept. This method loads the challenge objects and when that task
completes, the challenges are passed to another method to populate the user interface for the presented
content.
- (void) showChallengesList
85
Challenges
Receiving Information About Existing Challenges
if (challenges)
}];
Table 6-1 lists the most common properties used to populate your user interface.
Property Description
receivingPlayerID The player identifier for the player that received the challenge.
Each type of challenge is defined by a distinct subclass of GKChallenge. Table 6-2 lists the subclasses and
how to retrieve the remaining information needed to display the challenge to the player.
Subclass Description
GKScoreChallenge Read the score property to obtain a score object representing the
score used to generate the challenge.
86
Challenges
Reacting to Challenge Events
You hook into the challenge notification system by installing a challenge event handler, which is defined by
the GKChallengeEventHandlerDelegate protocol. After the local player is authenticated on the device,
your app installs a challenge event handler and is then notified when challenges change state. Listing 6-7
shows the code to install a new event handler.
- (void) installChallengeHandler
eventHandler.delegate = self;
In each of these situations, you can customize the behavior using a pair of methods. The methods for overriding
the behaviors are shown in Table 6-3. The first method in each pair allows you to choose whether a banner is
displayed at all. The second method in each pair allows you to handle the event yourself.
87
Challenges
Reacting to Challenge Events
For example, if you wanted to completely customize the appearance when the local player completes a
challenge, first you would suppress the banner from being displayed, as shown in Listing 6-8:
Listing 6-8 Suppressing the challenge banner when the player completes a challenge
- (BOOL)shouldShowBannerForLocallyCompletedChallenge:(GKChallenge *)challenge
return NO;
Then you implement a localPlayerDidCompleteChallenge: method to handle the challenge. Listing 6-9
shows a possible implementation of this method. First, it loads the player data for the player issuing the
challenge. In the completion handler for this first call, it then loads that players photo. Finally, when the photo
is loaded, it invokes its own method to display the loaded challenge data.
Listing 6-9 Displaying a custom user interface when the player completes a challenge
- (void)localPlayerDidCompleteChallenge:(GKChallenge *)challenge
88
Challenges
Reacting to Challenge Events
}];
}];
You implement the localPlayerDidSelectChallenge: method similarly to the other handler methods.
For example, you might use an implementation similar to that in Listing 6-9 (page 88) to load player information
and display an interface to the player.
89
Matchmaking Overview
In Game Center, a match is formed when a group of players want to play a game together. Each player plays
the game on their own device, and the experience on each device is tailored to the player playing on that
device with the match as a whole representing a shared experience. To accomplish this, the instances of the
game share data with each other so that there is agreement about the state of the match.
Game Center matchmaking provides the infrastructure needed to allow players to find other players interested
in playing in a match. It allows players to invite specific playersalmost always a friendor to simply find
other players looking for a match in your game. Once those players have been discovered and formed into a
match, Game Center makes it easy for you to implement the networking code needed for your game. When
necessary, Game Kit routes network data through Game Centers servers so that all of the matchs participants
are connected to each other, regardless of where they are or what kind of network they are on.
Matchmaking on Game Center is a complex topic, as there are many kinds of matches you can create and
many ways to create them. This chapter provides an overview of the process. The chapters that follow provide
details on the specific kinds of matches that Game Center offers.
Real-time All of the players are connected to Game Center simultaneously and for the duration
of the match. Game Kit provides all of the low-level networking support for a real-time
match in the GKMatch class. Your game implements its own logic to sit on top of this
networking infrastructure. Although intended for real-time games, it is usable for any
game that requires the players to be connected simultaneously.
90
Matchmaking Overview
Game Center Provides Multiple Ways to Connect Players into a Match
Turn-based The state of the match is stored on Game Centers servers. It is transmitted to the
participants when needed. The participants of the match are not connected to each
other, and are connected to Game Center only when they want to read or write the
match data. When a player takes a turn, his instance of the game updates the match
data stored on Game Center. Game Kit provides support for this match type in the
GKTurnBasedMatch class.
Self-hosted A networking implementation provided by your game and your own servers. When you
create a hosted match, Game Center helps you find players for your match
(matchmaking), but relies on your game to implement its own low-level networking
code. It is primarily intended for games that already have existing network
implementations.
A player can be invited to join a match even when a game is not launched on that players device. When a
player is sent an invitation, a push notification is sent to that players device. When the player accepts the
invitation, the game is launched immediately to handle the invitation. This behavior is important because it
increases the likelihood of players playing your game. In fact, a player can be invited to play in a match for a
game he or she does not own. In this case, the player is immediately offered an opportunity to purchase and
download your game.
91
Matchmaking Overview
Matchmaking and Gameplay Are Separate Tasks
Important: In each of these cases, all that iTunes Connect and Game Center provides is the ability to create
these larger matching groups across versions and products. Game Center itself does not provide any special
code to make your games compatible. When implementing your code, you are responsible for ensuring
that the network data exchanged between the participants can be interpreted properly by all of the devices
and versions of your game. For example, if you introduce a new version of your game with a different
network data format or a significant change in behavior, you need to ensure that players using this version
are not matched with players using incompatible game versions.
For more information on configuring multiplayer compatibility in iTunes, see Game Center.
92
Matchmaking Overview
Creating Any Kind of Match Starts with a Match Request
When designing your games match infrastructure, start by implementing the basic support for matchmaking
and get your network game working. Then, consider adding some of the more advanced features.
The match request is defined in Game Kit by the GKMatchRequest class. Table 7-2 lists the properties of a
match request.
Property Description
minPlayers The minimum number of players to find for the match. This property must be
set on every match request. See A Match Request Must Specify the Number
of Players in the Match (page 94).
maxPlayers The maximum number of players to find for the match. This property must
be set on every match request. See A Match Request Must Specify the Number
of Players in the Match (page 94).
defaultNumber- The default number of players to find for the match. This is used to configure
OfPlayers the default user interface to show the appropriate number of player slots.
However, the player can add or subtract slots so long as the number of players
stays between the minimum and maximum number of players, inclusive.
playersToInvite An optional property that declares a list of player IDs for a set of players to
invite to the match. See Inviting a List of Players (page 95).
inviteMessage If you are inviting a set of players to the match, you can provide a custom
string message that is displayed to those players. Typically, you provide the
player an opportunity to create this string in your custom user interface, then
use the string provided to populate your match request.
playerGroup An optional property that allows you to create distinct subsets of players in
your game. Each subset is matched separately against each other. Use these
subsets to allow players to provide more information about exactly what kind
of match they are looking for. See Player Groups (page 95).
93
Matchmaking Overview
Creating Any Kind of Match Starts with a Match Request
Property Description
playerAttributes An optional property that allows you to specify a distinct role the player wants
to play in the match. Use player attributes to allow players to define what or
how they want to play your game. See Player Attributes (page 96).
request.minPlayers = 2;
request.maxPlayers = 2;
request.defaultNumberOfPlayers = 2;
The minimum number of players must be at least 2. The maximum number of players allowed varies depending
on the kind of match being created. Table 7-2 (page 93) lists the current maximum; this maximum is subject
to change.
Peer-to-Peer 4
Hosted 16
Turn-based 16
At runtime, your game calls the maxPlayersAllowedForMatchOfType: method to determine the exact
number of players allowed for each kind of match.
94
Matchmaking Overview
Creating Any Kind of Match Starts with a Match Request
Providing a list of players alters Game Centers matching behavior. Here are a few examples of how the behavior
changes:
The standard user interface allows a player to pick a specific slot in the match and invite a specific person
to fill it. Game Kit reserves places for invited players until they respond or the process times out.
If you are using the programmatic interface for creating a real-time match and you provide a list of players
to invite, Game Center attempts to add only those players into the match. It does not perform the normal
matchmaking process. However, if the match needs more players, your game can create another match
request that performs normal matchmaking. This separation of behaviors allows you to precisely control
when randomized matchmaking occurs.
In a turn-based match, the players are added to the match immediately, but a player is sent an invitation
to join the match only when it becomes that players turn.
Player Groups
Game Centers default behavior is to automatically match any player waiting to play your game into any match
that needs more players. This has the advantage of matching players quickly into matches, but it also means
that players can be added to matches that they are not interested in playing. In that case, you can allow the
players to define the kind of matches they want to play, and then match them only with like-minded players.
This is accomplished with a player group.
A player group is defined by an unsigned 32-bit integer. When you set the playerGroup property on a match
request to 0, then the player can be matched into any waiting match. When you set the playerGroup property
to a nonzero number, then the player is matched only with players whose match requests share the same
player group number. Typically, if your game uses player groups, it provides a custom interface that allows
the player to pick the precise options he or she is interested in. It takes the choices of the player and combines
them to form a player group number.
Here are some examples of how you can partition a list of players:
Separate players by skill level.
Separate players by the set of rules used to adjudicate the match.
95
Matchmaking Overview
Creating Any Kind of Match Starts with a Match Request
Although it is up to you to determine exactly how many player groups you want to create, dont create groups
just to create them. Creating many smaller player groups can result in every player waiting for a long time to
play a match. Instead, create large groups that players can identify with.
Listing 7-2 shows how you might configure a match request that uses a player group. In this example, the
player group value is calculated by choosing both the map the player wants to play on and the rules set under
which the player wants to play. A constant for each is chosen and the two are bitwise ORed together to create
a unique number for the player group. Game Center only searches for other players with the same map and
group combination.
Listing 7-2 Creating a player group based on the map and rule set
request.minPlayers = 2;
request.maxPlayers = 4;
Player Attributes
A player attribute allows a player to pick the role he or she wants to play within a match. With player attributes,
each player can choose a specific role and Game Center finds a proper mix of players to ensure that all of the
roles are filled.
Here are some ways you can use player attributes in your game:
A game like chess can use player attributes to determine whether a player wants to be the black or white
pieces.
A role-playing game can offer different character roles with distinct strengths, weaknesses, and abilities
that player brings to the match.
A sports game can use player attributes to allow players to specify positions, such as pitcher or quarterback,
on the team.
A turn-based match can assign different locations on the map to distinct factions and use attributes to
ensure that each location is filled.
96
Matchmaking Overview
Creating Any Kind of Match Starts with a Match Request
Roles are not displayed in the standard user interface for matchmaking provided by Game Kit. Your game
must provide its own custom user interface to allow players to choose a role.
The match object returned to your game does not tell you which roles the players selected. Your game
must send the role-selection information separately after the match is created.
Your game defines a complete set of roles; all roles defined by your game must be filled by the time the
match is created. Because this calls for careful coordination between the roles that you define and the
number of players allowed in the match. Thus, player attributes require additional design and testing
effort.
To create the roles a player can play in your game, you create a 32-bit mask for each role a player can fill. It is
up to you to add a custom user interface in your game that allows the player to select a role. You set the
playerAttributes property on the match request to the mask for the players selection, as shown in Listing
7-3. Then, perform the standard or custom matchmaking as you normally would.
request.minPlayers = 4;
request.maxPlayers = 4;
request.playerAttributes = MyRole_Wizard;
If Game Center sees a nonzero player attribute in the match request, it adds players to the match intelligently
so that all of the players, when combined using a logical OR operation, have a complete mask of FFFFFFFFh.
97
Matchmaking Overview
Creating Any Kind of Match Starts with a Match Request
None of the role masks overlap; if any two masks are joined by AND, the resulting value is always 00000000h.
When all four role masks are logically ORed together, the entire match mask is filled (FFFFFFFFh). This ensures,
in a match with four players, that each role is filled exactly once.
98
Matchmaking Overview
Creating Any Kind of Match Starts with a Match Request
A chess match always requires two players, so with these masks there are four possible combinations of players
that can satisfy the condition for a completed mask:
One black player and one white player
One white player and one player that doesnt care
One black player and one player that doesnt care
Two players that do not care which color their pieces are
99
Real-Time Matches
In a real-time match, the players are connected to Game Center (and thus to each other) simultaneously. This
form of match is suitable for implementing any type of game that requires live participation. A key advantage
of real-time matches is that Game Kit and Game Center provide extensive support for real-time matches, which
simplifies the code you need to write. In particular, it solves many problems of finding players to join into a
match, it provides a high-level networking interface that lets you ignore many of the problems of the underlying
networking layer, and it provides extensive built-in support for voice chat. Game Kit allows you to focus on
implementing your game without worrying about the precise mechanics of how game and voice data are
delivered.
However, even though Game Kit solves many of these problems, your game design still needs to be prepared
to deal with complex issues that arise from real-time networking, including:
The need for multiple instances of your game (running on different devices) to perform tasks simultaneously
or near simultaneously, while synchronizing states between the devices
Network reliability
Network latency
Implementing a real-time match requires extensive work designing, implementing, and testing your game.
These and other questions impact the design of your gameplay and networking code.
100
Real-Time Matches
Checklist for Adding Real-Time Matchmaking to Your Game
Getting Started
The following tasks must be performed before starting your matchmaking implementation:
If your app is an OS X app, you must add the following entitlements or all real-time functionality fails:
com.apple.security.network.client
com.apple.security.network.server
Add code to your game to authenticate the local player. See Working with Players in Game Center (page
32).
Familiarize yourself with the matchmaking concepts described in Matchmaking Overview (page 90) as
well as the contents of this chapter.
101
Real-Time Matches
Checklist for Adding Real-Time Matchmaking to Your Game
The delegate is notified when other players are connected at the start of the game. Your delegate
usually waits until everyone is connected before starting the game. See Starting the Match (page
115).
The delegate receives the data that other players send. Your delegate reverses the procedure used
to send the data by decoding and acting on the data from the other players. See Receiving Data from
Other Players (page 117).
If players get disconnected while your game is running, the delegate receives a notification and must
decide whether to discontinue the match or reconfigure your game to handle the reduced number
of players. See Disconnecting from a Match (page 118).
102
Real-Time Matches
Overview of Real-Time Matches in Game Center
Class Description
GKMatchRequest A match request object specifies the properties of the match to be created.
See Creating Any Kind of Match Starts with a Match Request (page 93).
GKMatchmaker This singleton is used by all games that support real-time matchmaking. A
game must provide an invitation handler to the matchmaker object so that
push notifications that launch the game are handled promptly. Optionally, a
game that wants to create a custom matchmaking user interface uses the
matchmaker to programmatically search for matches.
GKMatchmakerView- A view controller class that displays the standard matchmaking user interface.
Controller The default user interface allows players to add friends to the match, search
for other players connected to Game Center, or even find players that are
physically in close proximity to each other, even if they do not currently have
a connection to Game Center.
GKMatch This object, which is returned to your game, holds information about the
players in the match. Each instance of your game uses its own GKMatch object
to communicate with other players in the match.
GKVoiceChat Returned by the match object and represents a specific voice channel players
can communicate over.
103
Real-Time Matches
Finding Players for a Match
request.minPlayers = 2;
request.maxPlayers = 2;
mmvc.matchmakerDelegate = self;
As the delegate, your view controller (or some other class) must implement a few methods to respond to
events. Each of these methods dismisses the view controller, and then performs any specific actions required
for your game.
The matchmakerViewControllerWasCancelled: delegate method is called when the player cancels the
matchmaking process before a match has been created. Typically, your game dismisses the view controller
and then backs out to the title screen (or some other reasonable user interface screen).
104
Real-Time Matches
Finding Players for a Match
- (void)matchmakerViewControllerWasCancelled:(GKMatchmakerViewController
*)viewController
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController
didFailWithError:(NSError *)error
Finally, if a match has been created and everyone is ready to start, your delegates
matchmakerViewController:didFindMatch: method is called. This method returns a GKMatch object
to your game. Typically, when the match starts, the match is returned to all of the participants, so this delegate
method is called on multiple devices at the same time.
Listing 8-4 shows a possible implementation of the delegate method. This method assigns the match object
to a property on the object and then adds the object as the match objects delegate. At this stage of the process,
all the players have been found, but it is possible for the match object to be returned before all players are
successfully connected. If all the players are already connected to the match, the game recognizes this and
immediately begins the match. Otherwise, it does nothing; the match delegate starts the match when the last
player connects. See Starting a match (page 116) for the match delegates role in this launch code.
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController
didFindMatch:(GKMatch *)match
105
Real-Time Matches
Finding Players for a Match
match.delegate = self;
self.matchStarted = YES;
Listing 8-5 shows the code you use to install a new invitation handler. The invitation handler is a block, so the
implementation is provided inline. When the handler runs, the player has already accepted the invitation, so
the handler stops any gameplay already in progress, instantiates the new view controller, and presents it to
the player.
The invitation handler takes two different parameters; on any call to your invitation hander, only one of these
parameters holds a non-nil value:
The acceptedInvite parameter is non-nil when your game receives an invitation directly from another
player. In this situation, the other players instance of your game has already created a match request, so
this instance does not need to create a match request.
The playersToInvite parameter is non-nil when your game is launched directly from the Game Center
app to host a match. This parameter holds an array of player identifiers listing the players to invite into
the match. Your game must create a new match request, assign its parameters as it would normally, and
then set the match requests playersToInvite property to the value passed in the playersToInvite
parameter. When the matchmaking screen is displayed, it is prepopulated with the list of players already
included in the match.
106
Real-Time Matches
Finding Players for a Match
Important: Your game needs to install an invitation handler as early as possible after your game
authenticates the local player; an appropriate place to set the handler is in the authentication handler that
executes after the local player is authenticated. It is critical that your game authenticate the local player
immediately after it launches and that it set the invitation handler immediately after the player is
authenticated.
if (acceptedInvite)
{
mmvc.matchmakerDelegate = self;
else if (playersToInvite)
request.minPlayers = 2;
request.maxPlayers = 2;
request.playersToInvite = playersToInvite;
};
107
Real-Time Matches
Finding Players for a Match
To implement this in your game, create and present a matchmaker view controller just as you did in the default
case. You only do this from one device already participating in the match. After presenting the view controller,
call the view controllers addPlayersToMatch: method, passing in the match to add the players to. The
match interface uses the information in the match request to add players to the existing match, rather than
creating a new match. The match object is still returned to your delegates
matchmakerViewController:didFindMatch: method.
The match is still active while the matchmaking screen is displayed; the devices in the match can still exchange
data with each other. However, you might need to pause the actual gameplay until a new player is found.
Because the match is active, voice chat channels continue working.
This section starts with the simplest scenariofinding a match with no user-interface implementationand
then builds to more detailed concepts needed to build your own user interface.
Listing 8-6 shows how to programmatically request a match. The code creates a match request, retrieves the
matchmaker singleton object and asks it to find a match for the player. The matchs completion handler is
called when a match is found or if an error occurs. If a match is returned to the completion handler, the match
is assigned to a property. As before, your game executes code to determine whether the match is ready to
begin.
108
Real-Time Matches
Finding Players for a Match
request.minPlayers = 2;
request.maxPlayers = 4;
if (error)
match.delegate = self;
self.matchStarted = YES;
}];
As in the example with the standard matchmaking interface, you can also add players to an existing match.
Instead of calling the findMatchForRequest:withCompletionHandler: method, your game calls the
addPlayersToMatch:matchRequest:completionHandler: method, passing in the match to add the
players to.
Canceling a Search
The matchmaking process takes time and may not complete quickly enough for some players. If your game
includes support for programmatic matching, it needs to provide a user interface that allows the player to
cancel an active search. Listing 8-7 shows how your game can terminate a pending search.
109
Real-Time Matches
Finding Players for a Match
You handle both of these problems by assigning more information to the match request. You need to assign
a list of players to invite and an invitee handler. As each invitation is processed, your handler is called. Listing
8-8 shows a typical implementation of the match request to handle this. In this example, a match request is
created and a list of player identifiers is assigned to the request. Also, this code provides a custom invitation
message; in your game, you should allow the player to customize this message.
When a response is received, if the response is equal to GKInviteeResponseAccepted, the player is added
to the match. In this case, the user interface code (not shown here) is updated to show that this player is now
part of the match. If any other response is received, the player is removed from the user interface so that the
slot appears empty again. Optionally, a more sophisticated example might display a specific error message to
the player detailing why the invitation was not accepted; see GKMatchRequest Class Reference for details.
request.minPlayers = 2;
request.maxPlayers = 4;
request.playersToInvite = friends;
};
...
110
Real-Time Matches
Finding Players for a Match
When a match request includes a list of player identifiers, then the matchmaking behavior changes (regardless
of whether you are creating a new match or adding players to a specific match). The normal process of finding
players for the match is suspended. Instead, the only thing the matchmaking code does is extend the invitations
to the players in the match request and wait for responses. Assuming your game does not cancel the
matchmaking process, it completes and returns a match to your game when all the invitations are processed.
Because some of the invitations may not be accepted, it is possible you may receive a match that still needs
more players. With this in mind, your custom user interface should implement the following behavior:
The first time the player invites players to join the match, create the match request with those players and
call the findMatchForRequest:withCompletionHandler: method. Wait for the match to be returned
(or cancel the request if the player cancels the invitations).
If the player wants to add more players to the match after the invitations are processed, perform the same
procedure again, but call the addPlayersToMatch:matchRequest:completionHandler: method
instead.
If the player wants to automatch the remaining slots, create a match request but do not include a list of
players to invite. Call the addPlayersToMatch:matchRequest:completionHandler: method to fill
the remaining slots. You must wait until all invited players have connected as all pending match requests
are cancelled when automatching the remaining player slots.
If the player wants to start the match with the players already in the match, call the
finishMatchmakingForMatch: method to end matchmaking entirely.
If you want to create a match that contains both invited players and automatched players, you must first create
the match with the invited players. After all invited players have connected, you can then add players through
automatching.
111
Real-Time Matches
Finding Players for a Match
Listing 8-9 Searching for all activity for your game on Game Center
- (void)findAllActivity
if (error)
else
112
Real-Time Matches
Exchanging Data Between Match Participants
}];
If your game uses player groups, you can use the queryPlayerGroupActivity:withCompletionHandler:
method to retrieve the activity for a specific player group.
The value returned by either method is the number of players who have recently requested a match.
Whenever you send data to other participants, you decide how much effort the match should use to send the
data. Matches can send your data reliably, which means the match retransmits the data until it is received by
the target(s), or unreliably, which means it sends the data only once.
A reliable transmission is simpler, but potentially slower; a slow or error-prone network may require the
device to send the message multiple times before it is successfully delivered to its intended recipients. A
match also guarantees that multiple reliable messages sent from one device to the same recipient are
delivered in the order they were sent.
Messages transmitted unreliably may never reach their destination or may be delivered out of order.
Unreliable transmissions are most useful for real-time transactions where any delay in transmission caused
by using reliable messaging invalidates the contents of the message. For example, if your game transmits
position and velocity information for a dead-reckoning algorithm, reliable messages might provide
positioning data that is badly out of date by the time it is delivered to the recipient. By using unreliable
messages, messages are delivered faster. Your game takes responsibility for network errors by sending
new messages with updated position and reckoning information.
113
Real-Time Matches
Exchanging Data Between Match Participants
The size of your messages also plays an important role in how quickly the data can be delivered to its targets.
Large messages must be split into smaller packets (such splitting is called fragmentation) and reassembled
by each target. Each of these smaller packets might be lost during transmission or delivered out of order. Large
messages should be sent reliably, so that Game Kit can handle the fragmentation and assembly. However, the
process of resending and assembly takes time. You should not use reliable transmissions to send large amounts
of real-time data.
Be mindful that your network data is being transmitted across servers and routers that are out of your control.
Your messages are subject to inspection and modification by other devices on the network. When your game
on one device receives network data from participants on other devices, it should treat that message as
untrusted data, and validate its contents before using it. See Secure Coding Guide for information on how to
avoid security vulnerabilities.
Here are some general guidelines to follow when designing your games networking:
Your message format needs to include a way to differentiate between message types. The GKMatch class
does not know anything about the contents of your messages, so you must implement that functionality
in your game. For example, you might create an enumerated type that identifies different kinds of messages,
and start each message with that enumerated type.
Send messages at the lowest frequency that allows your game to function well. Your games graphics
engine may be running at 30 to 60 frames per second, but your networking code can send updates much
less frequently.
Use the smallest message format that gets the job done. Messages that are sent frequently or messages
that must be received quickly by other participants should be carefully scrutinized to ensure that no
unnecessary data is being sent.
Pack your data into the smallest representation you can without losing valuable information. For example,
an integer in your program may use 32 or 64 bits to store its data. If the value stored in the integer is
always in the range 1 through 10, you can store it in your network message in only 4 bits.
Limit the size of unreliable messages to 1000 bytes or smaller.
Limit the size of reliable messages to 87 kilobytes or smaller.
Send messages only to the participants that need the information contained in the message. For example,
if your game has two different teams, team-related messages should be sent only to the members of the
same team. Sending data to all participants in the match uses up networking bandwidth for little gain.
Although the GKMatch object creates a full peer-to-peer connection between all the participants, you can
reduce the network traffic by layering a ring or client-server networking architecture on top of it. Figure
8-1 shows three possible network topologies for a four-player game. On the left, a peer-to-peer game has
12 connections between the various devices. However, you could layer a client-server architecture on top
of this by nominating one of the devices to act as the host. If your game transmits to or from the host
only, you can halve the number of connections. A ring architecture allows devices to forward network
114
Real-Time Matches
Exchanging Data Between Match Participants
packets to the next device only, but further reduces the number of connections. Each topology provides
different performance characteristics, so you will want to test different models to find one that provides
the performance your game requires.
graphic name
Game Centertopologies
Network Programming Guide
Figure 8-1
Apple, Inc.
Specify how to handle network disruptions. Networks are an inherently unreliable medium of
communication. A participant can be disconnected at any time while the match is in progress. Your game
must handle disconnection messages. For example, if you implemented your game to use a client-server
topology, then when the server disconnects from the match, your game might want to nominate a new
device to become the new server.
The appropriate place to perform this check is in the match delegates match:player:didChangeState:
method. This method is called whenever a member of the match connects or disconnects. Listing 8-10 is an
example of an implementation of your match:player:didChangeState: method. In this example, the
match delegate defines its own matchStarted property to record whether the match is already in progress.
If the match has not started and the count of expected players reaches zero, the method starts the match. In
your game, this is where any initial match state would be transmitted to other players or where additional
negotiations between the different participants take place.
115
Real-Time Matches
Exchanging Data Between Match Participants
Even before the match starts, all players already connected to the match can already exchange data with each
other. This allows your game to create voice channels (or your own user interface) that allows the players
already there to communicate with each other.
switch (state)
case GKPlayerStateConnected:
break;
case GKPlayerStateDisconnected:
break;
self.matchStarted = YES;
If you intend to search for the best server using this method, all devices in the match must be running on
versions of Game Kit that support this method, and every device in the match must call this method at the
same time. This allows all the devices to test and communicate with each other simultaneously. Typically, you
find the best server after everyone is connected and gameplay is ready to start.
116
Real-Time Matches
Exchanging Data Between Match Participants
Listing 8-11 shows how a game might send a position update to the other participants. The method fills a
structure with position data, wraps it in an NSData object, and then calls the matchs
sendDataToAllPlayers:withDataMode:error: method.
- (void) sendPosition
{
NSError *error;
PositionPacket msg;
msg.messageKind = PositionMessage;
msg.x = currentPosition.x;
msg.y = currentPosition.y;
if (error != nil)
When the method returns without reporting an error, the message has been queued and will be sent when
the network is available.
117
Real-Time Matches
Adding Voice Chat to a Match
if (p.messageKind == PositionMessage)
Listing 8-12 Creating an audio session that can play and record
118
Real-Time Matches
Adding Voice Chat to a Match
Note: Your app needs to stop any voice chats currently active after receiving an
AVAudioSessionDidBeginInterruptionNotification. You can restart any voice chats after
receiving an AVAudioSessionDidEndInterruptionNotification.
For more details on creating and using audio sessions, see Audio Session Programming Guide .
For multiple participants on different devices to join the same channel, they need a way to identify a particular
channel. This identification is accomplished through a channel name. A channel name is a string, defined by
your game, that uniquely names the channel. When two or more participants join a channel with the same
name, they are automatically connected to a voice chat with each other.
Listing 8-13 provides code that creates two channels. The first call to voiceChatWithName: creates a team
channel and the second creates a global channel. The code retains both channels.
GKMatch* match;
[teamChannel start];
After the start method is called, the voice chat object on that device connects to other participants in the
channel if the following are true:
119
Real-Time Matches
Adding Voice Chat to a Match
If either of these conditions is not met, the voice chat object waits until both are true before connecting to
the channel.
Similarly, when a player is ready to leave a channel or whenever you want a channel to be temporarily turned
off, you stop the chat using:
[teamChannel stop];
An advantage to stopping the channel (rather than simply muting the other players) is that the other players
are not required to send data to the player who has left the channel. This decrease in data transmission leaves
more bandwidth available for your games messaging.
A channel enables the microphone by setting the voice chat objects active property to YES:
teamChannel.active = YES;
Only one channel can enable the microphone at a time. When you enable the microphone for one channel,
the active property on the previous owner is automatically set to NO.
allChannel.volume = 0.5;
The volume property accepts values between 0.0 and 1.0, inclusive. A value of 0.0 mutes the entire channel;
a volume of 1.0 outputs voice data at full volume.
120
Real-Time Matches
Adding Voice Chat to a Match
Second, your game can selectively mute players in a channel. Typically, if your game intends to mute players,
it should offer a user interface that allows the player to choose which players they want to mute. To mute a
player, you call the voice chat objects setMute:forPlayer: method:
switch (state)
case GKVoiceChatPlayerSpeaking:
break;
case GKVoiceChatPlayerSilent:
break;
};
121
Hosted Matches
Hosted matches allow your game to use Game Centers 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 Centers 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.
Table 9-1 lists the most common methods for real-time matchmaking and the corresponding methods or
implementation details for hosted matchmaking.
122
Hosted Matches
Hosted Matches Overview
Your game receives an invitation. The GKInvite objects hosted property tells you whether
the match is a hosted match. Typically, this matters only if
your game implements both hosted and nonhosted
matches.
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:
Design and implement your own networking code to connect each device to your server.
Design and implement your own networking protocol to inform other devices of the state of any participant
in the match.
Design and implement your own server implementation to map player identifiers to the specific device
connected to your server. Thus, your server becomes responsible for routing network data between players.
If your game uses Game Kits standard matchmaking user interface, you must make sure each device
informs Game Kit after it connects to your server. This information allows Game Kit to update its user
interface.
123
Hosted Matches
Creating a Hosted Match Using the Matchmaker View Controller
request.minPlayers = 2;
request.maxPlayers = 2;
mmvc.matchmakerDelegate = self;
mmvc.hosted = YES;
124
Turn-Based Matches
In a turn-based match, the players of the match do not need to be simultaneously connected to Game Center
to play a match together. Instead, the game uses a store-and-forward approach; one player takes a turn before
passing the next play to another player. The players continue to take turns until the match ends with only one
player able to make changes to the game at a time.
Turn-based matches have many useful characteristics that make them great for implementing board games
and other similar styles of games; for example:
A player can participate in multiple matches simultaneously. A game loads whichever match the player
is interested in viewing or advancing.
Players must connect to Game Center only to take a turn.
A match can be created with less than a full complement of players, even a single player. Other players
are added as needed.
In iOS 7, exchanges are introduced to turn-based matches. Exchanges allow two or more players to take an
action, even when it is not their turn. This allows developers to create more complex and diverse turn-based
games than are currently possible by allowing more than just the local player to make changes to the game.
Some possible uses for exchanges are:
Two players want to trade cards in your game. This can be accomplished during another players turn.
One player wants to auction a card and all players have a chance to bid on the card at the same time.
Two players attack each other. They both take turns through exchanges until finished.
You can build a game by adding exchanges to the existing turn-based gaming model or create a game solely
through the use of exchanges. This chapter first describes how to implement a traditional turn-based match
and then adds information about exchanges later.
When you implement turn-based matches in your game, the list of players, the data for matches, and other
details are all stored on Game Center. Your game downloads this information as needed. Game Center is
primarily responsible for storing data. You are responsible for providing the game logic that uses this
infrastructure. In particular, you define:
What data must be stored on Game Center
When the match data needs to be updated
125
Turn-Based Matches
Checklist for Implementing a Turn-Based Match
When a match begins, only some of the seats may be filled by players. The other seats may be reserved for
specific players or to be filled by Game Centers matching service. For example, consider Figure 10-1. Mary has
created a new match with four seats. Because Mary created the match, she performs the first turn and then
play passes to another player.
126
Turn-Based Matches
The Match Data Represents the State of the Match
At this point, Game Center sees that this match needs a new player to continue play. When Bob searches for
a match, Game Center sees that Bob wants to play the same game as Marry and assigns Bob as a new player
of Marys match. Because this game was waiting on a new player to continue the match, it is now Bobs turn.
Game Center always tracks the players of a match in a specific order. That order never changes for the duration
of the match, regardless of which device your game is running on. In this example, if Mary is in the first seat
(slot), she stays in the first seat for the entire game.
Every match has the concept of the current player. The current player changes throughout the match and
represents the player whose turn it is to act. When that player finishes taking a turn, your game chooses another
player to act. That player is notified that it is now his or her turn and becomes the current player.
127
Turn-Based Matches
The Match Data Represents the State of the Match
At any time, a player in the match can launch your game to view the match. When a player launches the game,
your game loads the match data, interprets it, and displays it to the player.
graphic name
Figure 10-2 The currentGame Center
player wantsProgramming
to view theGuide
match
Apple, Inc.
Only the current player is allowed to change the match data. Provide the current player with a user interface
that allows them to take actions in the game. As the player takes actions, your game updates the match data
graphic name
and transmits it back to Game Center.
Game Center Programming Guide
Apple, Inc.
128
Turn-Based Matches
Your Game Decides the Rules of Play
As an example, consider chess. The player with the white pieces moves first. After white moves, play passes
to the player controlling the black pieces. After black makes a move, play passes back to white. The players
alternate turns until the match ends in either a checkmate or a stalemate. The rules dictate that play alternates
and each player makes a single move each time.
The rules that chess uses for players are very consistent, but Game Center allows you to design more flexible
games. For example, each time a player takes a turn, you can show them a different user interface screen and
present the player with different options for play. A players turn can be as simple as making a single decision
or as complex as choosing what to build, deciding where to send resources, and engaging in combat with
another player. Your game tracks the moves a player makes and the moves they are allowed to make as part
of your match data.
Consider another popular style of strategy game: the 4X game that encourages players to explore, expand,
exploit, and exterminate. In this style of game, multiple types of turns are used at different points in the match.
Here is one possible way to organize this:
At the start of the match, each player takes a starting turn. Play passes sequentially through the entire
player list. On a starting turn, a player action consists of naming the players empire and choosing options
for how they intend to play in the match. For example, a common 4X trope is for a player to choose a
faction that provides specific advantages and disadvantages during play. After all the players have
completed their starting turns, the match begins by allowing players to administrate their empires.
On an administrative game turn, each active player takes a turn, and play passes sequentially through the
player list. Each participant performs all the actions necessary to control their empire. After all players
complete their orders, the administrative turn ends. Your game then executes all the orders simultaneously,
usually on the client of the last player to take an administrative turn. If any player units come into conflict,
then a conflict game turn is executed; otherwise, a new administrative game turn starts.
On a conflict game turn, the game creates a list of all of the players involved in conflicts. Then, each player
on the list is given a turn to allow them to give combat orders. After all players give orders, the orders are
executed simultaneously and the conflicts are resolved at once. If any players are eliminated as a result of
combat, the game takes them out of the match on future turns. If only one player remains active in the
match, the match ends and that player is declared the winner. Otherwise, play continues with another
administrative game turn.
129
Turn-Based Matches
Your Game Decides the Rules of Play
Figure 10-3 shows how this hypothetical games logic is processed. It has three distinct kinds of player turns,
each with a different user interface, possible user actions, and data to be stored in the match data.
Whenever a player takes a turn, the match data indicates what type of turn the player takes. After a player
takes a turn, their actions are stored in the match data. The design also avoids passing turns to other players
for nontrivial reasons. Every player makes multiple decisions at once before passing control to another player.
130
Turn-Based Matches
Save the Match Data Whenever Important Events Occur
When the final player completes a turn, that players game client processes everyones turns simultaneously,
writing any necessary changes to the match data. Although this kind of design is not required, it keeps the
game moving by avoiding small, trivial player turns.
Table 10-1 Classes in Game Kit used to implement turn-based match support
GKTurnBasedMatch Describes a turn-based match stored on Game Center. You use this object
to inspect the current state of the match and to update the state of the
match when the current player takes a turn.
GKMatchRequest Describes the characteristics of a match and may include an initial list of
players to invite.
GKTurnBased- Describes a player in a match. Most of its properties are read-only, but the
Participant matchOutcome property is not; you assign an outcome to this property
when a player leaves a match.
GKTurnBased- Provides a standard user interface that allows the local player to create new
MatchmakerView- matches or view existing matches.
Controller
131
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit
GKTurnBasedEvent- Handles events when the player receives an invitation to join a match or a
Handler notification that an existing match has been updated. There is a single event
handler object provided to you by Game Kit. After the player is authenticated,
you assign an event handler to this singleton object. The exact events
delivered to your game vary depending upon whether your game is currently
the foreground app on the device. When your game is in the foreground,
it receives all events related to turn-based matches. If not running in the
foreground, your game is launched or brought to the foreground only when
important events are received.
You can choose to display a standard user interface provided by Game Center or implement your own custom
user interface. Regardless of which technique you use, the match returned to your game always has the local
player as the current player expected to take a turn.
132
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit
request.minPlayers = 2;
request.maxPlayers = 2;
mmvc.turnBasedMatchmakerDelegate = self;
-
(void)turnBasedMatchmakerViewControllerWasCancelled:(GKTurnBasedMatchmakerViewController
*)viewController
133
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit
- (void)turnBasedMatchmakerViewController:(GKTurnBasedMatchmakerViewController
*)viewController didFailWithError:(NSError *)error
- (void)turnBasedMatchmakerViewController:(GKTurnBasedMatchmakerViewController
*)viewController didFindMatch:(GKTurnBasedMatch *)match
if ([segue.identifier isEqualToString:@"GamePlayScene"])
gameVC.delegate = self;
134
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit
request.minPlayers = 4;
request.maxPlayers = 16;
if (match)
}];
One common scenario is supported automatically by Game Center. When a match ends, you can call its
rematchWithCompletionHandler: instance method to create a new match with the same participants.
135
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit
A player can choose to resign from a match from within the standard user interface. Your delegate must
implement a turnBasedMatchmakerViewController:playerQuitForMatch: method to handle a player
resignation. Your game must set a match outcome for the resigning player, and if necessary, choose another
player to act in the match. For more information, see Setting the Match Outcome When a Participant Leaves
a Match (page 141).
If you implemented a custom matchmaking user interface, you need to provide equivalent functionality that
allows a player to manage the list of matches. Listing 10-6 shows how to retrieve a list of matches that the
local player is participating in.
Listing 10-6 Retrieving the list of matches the local player is participating in
- (void) loadMatches
if (matches)
}];
Table 10-3 lists the most common actions a player might want to perform on a match.
Action Implementation
View a match Present your gameplay user interface, using the match object as an
input. See Listing 10-4 (page 134) for inspiration on how to implement
this.
136
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit
Action Implementation
Resign from a match Set the players outcome and then call a method to resign from the
match. See Setting the Match Outcome When a Participant Leaves a
Match (page 141).
End a match for all Set outcomes for all of the players and then call the matchs
participants endMatchInTurnWithMatchData: completionHandler: method.
See Ending a Match (page 143).
Property Description
matchID A string that uniquely identifies the match. If you want to store
match-specific data elsewhere, use this string as a key. Your game could
also save this ID and use it later to load this specific match. To load a specific
match, call the loadMatchWithID: withCompletionHandler: class
method.
message A text string your game sets to provide a human-readable status for the
match. Typically, you update this property before changing the current
player. The message is displayed by the standard user interface. If you
display a custom interface, you should also display the message.
currentParticipant The participant object for the next player expected to act in the match.
This object is always one of the objects stored in the participants array.
Table 10-5 lists the most common participant properties used to implement your game.
137
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit
Property Description
playerID The player identifier for the player, assuming this seat is filled. Use it to load display
names and photos for the player.
status Declares whether or not this seat is filled and, if it is, declares whether the player
is still active in the match.
timeoutDate The time at which the player must act before forfeiting a turn. Your game decides
what happens when a turn is forfeited. For some games, a forfeited turn might end
the match. For other games, you might choose a reasonable set of default actions
for the player, or simply do nothing.
matchOutcome When a player leaves a match, this property describes what happened to the player.
The player may have won or lost the match.
In general, the match data needs to store enough information so that your game can display the current state
of the match. If the player is the current player, then the match data should also store enough data so that
your game knows what kind of turn the player may take. Here are a few possible strategies you can follow
when designing your match data format:
Encode only player actions: In this design, your match data simply consists of the moves made by the
players. For example, in chess, you know that white goes first, moves always alternate, and a piece moves
from one board position to another. This makes it easy for you to encode each move as the starting and
ending position of the piece moved. The rest of the data (who made the moves) can be completely inferred.
When your game loads the match data, it quickly replays the moves to generate the current board position.
This strategy works best for games with a small number of possible kinds of actions and a small number
of moves per match. Also, with this model, it is very possible for your game to replay the moves in its user
interface, allowing players to see exactly what moves other opponents made to get the board into the
new state. Showing a player these moves makes it very easy for a player to understand how the game got
to the current state.
138
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit
Encode only the current state of the match: For very complex games, the actual state required to encode
the game could be very large. In this case, you may need to encode the current state of the match without
worrying about the actions that generated that match data. This is particularly true for very complex games
where the list of moves might grow too large to fit in the available storage space.
This strategy is recommended as a last resort. Players lose all context of what happened on previous turns
of the match. For games with long timeouts between turns, players may grow bored or frustrated if they
cannot remember the state of a match they were playing. This is particularly true when players participate
in multiple matches simultaneously.
Encode the current state of the match and a set of recent player actions: This is a hybrid strategy that
borrows elements from the other two strategies. Essentially, the match data stored on Game Center consists
of a recent snapshot of the match plus other data that encodes recent actions since that last snapshot
was taken. When the data that records the actions grows too large, your game replays some of those
moves to update the match snapshot and then deletes those moves from its list of actions.
With this strategy, you typically need to determine which actions the current player has seen (based on
when they last took a turn). When your game flattens the match data, it never removes any data that
hasnt been seen by all the participants. This allows all participants to see the moves their opponents
made.
139
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit
- (void) loadAndDisplayMatchData
if (matchData)
}
}];
- (void) updateMatchData
if (error)
}];
140
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit
Listing 10-9 shows a typical structure for this code, deferring some of the specific steps to app-specific routines
that are based on your games actual structure. Those methods represent the places where you need to provide
specific implementations in your game. The advanceTurn method first sets a new message, then encodes
the current match data as before. Finally, it calculates the order in which participants should act and calls the
endTurnWithNextParticipants:turnTimeout:matchData:completionHandler: method to actually
pass control to that list of players.
- (void) advanceTurn
if (error)
}];
141
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit
If the local player resigns from the match and is also the matchs current player, your game must call the match
objects
participantQuitInTurnWithOutcome:nextParticipants:turnTimeout:matchData:completionHandler:
method. This method is similar to the
endTurnWithNextParticipants:turnTimeout:matchData:completionHandler: method in that it
gives control to another participant. Because of this, you are required to update the match data and provide
a participant list. However, your game also provides a match outcome for the player that just exited the match
essentially, a numerical value that indicates why that player left the match. The participant object for that
player is updated to include this new match state. Once a participant has exited the match, your game may
not make that player the current player.
Game Kit provides some standard values you can use to set the match outcome. See Setting the Match
Outcome in GKTurnBasedParticipant Class Reference .
For example, in Figure 10-4, Bob has just been eliminated from the match. The game chooses to set an outcome
of GKTurnBasedMatchOutcomeFourth and make Mary the new current player. Bob may still view the match,
but may not take actions.
graphic name
Figure 10-4 Game
Bob has Center Programmingfrom
been eliminated Guide
the match
Apple, Inc.
Occasionally a player may resign the game when they are not the current player. To handle this, your game
calls the match objects participantQuitOutOfTurnWithOutcome:withCompletionHandler: method.
You provide a match outcome but do not provide new match data or a participant list.
142
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit
Ending a Match
Eventually, your game logic is going to decide that the match is over. All participants in the match must have
a valid match outcome before ending the match. Your game calls the match objects
endMatchInTurnWithMatchData:completionHandler: method to formally end the match. This method
is similar to the other methods that update the match state, but in this case you do not provide a list of
participants because no further actions are allowed in this match. You do update the saved match data to
describe how the match ended. Players can still select this match from the matchmaking user interface; your
game should display the match ending but not allow the player to take actions.
Your game receives turn-based match events by installing an event handler. As with other similar handlers,
you almost always install this handler as soon as the local player is authenticated. If your game was launched
specifically to handle an event, the event handler is called immediately.
- (void) installTurnBasedEventHandler
143
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit
To respond to events, your event handler implements the methods defined by the
GKTurnBasedEventHandlerDelegate protocol. Table 10-6 lists the events. Events received via a push
notification launch your game or bring your game to the foreground (if necessary) and are then delivered to
the game. Foreground events are delivered only if your game was running in the foreground when the event
was received.
When an event is received, your game should pause what it is doing and display a user interface that allows
the player to decide whether to load the notifications match for display. Even if this match is already loaded,
you should reload the matchs data, because it may have been updated by the event.
By default, when your game receives a notification, a badge is added to the game icon. Add
GKGameCenterBadgingDisabled to your Info.plist to change this behavior. See Cocoa Keys for details.
144
Turn-Based Matches
Adding Exchanges to a Turn-Based Match
Anatomy of an Exchange
In the basic turn-based match, control of the game moves from player to player, following rules defined by
the app. Only the current player can affect the match, with all other players relegated to observing the match.
This works very well for certain types of games, but as a game turn becomes more complicated, it is not
uncommon for multiple players needing to interact at the same time. Turn-based matches can quickly become
bogged down when each player must perform a small action in order for a turn to be completed. Exchanges
provide you with a way to create complex turns without slowing down the pace of the match.
Using exchanges, you can design your game so that players other than the current player can take actions
during a turn. An exchange is an interaction between the exchange initiator and one or more exchange
recipients. The following workflow is used for an exchange:
The initiator sends an exchange request to a recipient.
The recipients is notified that they have received an exchange request.
The recipient acts on the exchange request and sends their action back to the initiator.
The initiator is notified of the completed exchange.
The current player is notified of the completed exchange and updates the match data.
145
Turn-Based Matches
Adding Exchanges to a Turn-Based Match
When a player sends an exchange request, several pieces of information are required to successfully send the
request. There is no particular order in which this information needs to be collected. For example, your game
may ask who the sender wants to trade with before asking which cards to trade, or the sender could choose
cards to give and then designate who will receive the cards.
The sender chooses whom to send the exchange request to.
The nature of the request has to be determined. Is the player asking to trade cards, asking for help in
attacking another player, or something else?
The amount of time the recipients have to respond to the exchange request must be set. You can allow
the sender to choose this or set a hard time limit.
Design your game in such a way that a player can never send an exchange request to a player that has quit
the game. Sending an exchange request to a player that has quit the game will generate an error.
The amount of data that you can send is limited to a maximum of 1k. The data must be comprehensive enough
that the receiving players game can act and present the data to the player in a way that makes sense in the
context of your game. When the exchange request is sent, ensure that the current player also receives the
request data so that the current match can be updated. Listing 10-10 shows a basic exchange request. The
recipient of the exchange is placed into an array and the request is sent to the player listed in the recipients
array.
146
Turn-Based Matches
Adding Exchanges to a Turn-Based Match
}];
An exchange can be cancelled by the sender at any time, even after replies have been received. As an example,
this functionality can be used to simulate trading between players. The sender can propose a trade and if the
recipient responds with a different offer, the sender can decline and cancel the exchange. When the sender
cancels an exchange, a push notification is sent to all of the recipients telling them that the exchange has been
canceled.
147
Turn-Based Matches
Adding Exchanges to a Turn-Based Match
Listing 10-12 shows a basic reply format. The recipient responds to the exchange request and sends any relevant
data back to the original sender. Your game also needs to send the results of the exchange to the current
player so that they can update the match.
-(void) replyToExchange
148
Turn-Based Matches
Adding Exchanges to a Turn-Based Match
Listing 10-13 shows a typical structure for this code, deferring some of the specific steps to app-specific routines
that are based on your games actual structure. Those methods represent the places where you need to provide
specific implementations in your game. The advanceTurn method first sets a new message, then encodes
the current match data as before. Next, it calculates the order in which participants should act. All completed
exchanges are then identified and resolved using the
saveMergedMatchData:withResolvedExchanges:completionHandler: method. Finally, the
endTurnWithNextParticipants:turnTimeout:matchData:completionHandler: method is called
to actually pass control to that list of players.
- (void) advanceTurn
if (error)
{
} else {
if (error)
149
Turn-Based Matches
Adding Exchanges to a Turn-Based Match
}];
};
}];
Failing to resolve completed exchanges before ending the turn returns an error.
150
Testing Your Game Center-Aware Game
To help you test your game, Apple provides a nonproduction development environment for Game Center.
This development environment duplicates the live functionality of Game Center, but is separate from the live
servers. The development environment allows you to test your Game Center features without making your
game visible to regular users. You should thoroughly test your game in a development environment before
submitting it for approval.
Important: Always create new test accounts to test your game in Game Center. Never use an existing
Apple ID.
A development environment does not allow sharing of information about what games are being played. This
prevents your testers from revealing the existence of your game to other players.
151
Testing Your Game Center-Aware Game
Testing a Game Center-Aware Game
The development environment provides you with the ability to send friend requests using Game Center
nicknames only. You can not use a persons email address for a friend request inside of the development
environment.
152
Document Revision History
Date Notes
2011-03-08 Revised the process for authenticating the local player. Clarified many
aspects of Game Center usage.
2009-03-12 New document that describes how to use GameKit to implement local
networking over Bluetooth as well as voice chat services over any network.
153
Apple Inc.
Copyright 2013 Apple Inc.
All rights reserved.