You are on page 1of 154

Game Center

Programming Guide
Contents

About Game Center 11


At a Glance 12
Some Game Resources Are Provided at Runtime by the Game Center Service 12
Your Game Displays Game Centers User Interface Elements 13
Game Center Features Require an Authenticated Player 13
Leaderboards Require Your Game to Have a Scoring Mechanism 13
Leaderboard Sets Allow You to Manage Your Leaderboards 14
Achievements Require Your Game to Measure Players Progress 14
Challenges Allow Players to Challenge Each Other 14
Matchmaking Requires Your Game Design to Incorporate Multiplayer Gaming 14
How to Use This Document 15
Prerequisites 16
See Also 16

Developing a Game Center-Aware Game 17


Supporting Game Center in Your User Interface 17
Adapting Your Game Design 21
Customizing the Game Center Sounds 22
Creating and Managing Game Center Resources 23
Game Groups 25
Incorporating Game Center into Your Game 26
Requiring Game Center in Your Game (iOS only) 27
Optionally Supporting Game Center in Your Game 27

Displaying Game Center User Interface Elements 28


Game Center UI Is Displayed by Your View Controller (iOS) 28
Game Center UI Is Displayed by Your Window (OS X) 29
Displaying Notification Banners 30

Working with Players in Game Center 32


Game Center Manages Player Accounts 32
Player Identifier Strings Uniquely Identify Players 33
The Local Player Is the Player Signed in to the Device 33
Player Objects Provide Details About Players 34

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

2
Contents

Common Tasks When Working with Players 36


Authenticating a Local Player on the Device 36
Retrieving the Local Players Friends 41
Retrieving Information About Players 42
Loading a Photo for a Player 43
Allowing the Local Player to Invite Other Players to Be Friends 43

Leaderboards and Leaderboard Sets 45


Checklist for Supporting Leaderboards 45
Leaderboards Require a Scoring Mechanism 46
A Game Can Have Multiple Leaderboards 47
One Leaderboard Is the Default Leaderboard 47
Combined Leaderboards Gather Scores from Multiple Single Leaderboards 48
Working with Leaderboards in iTunes Connect 48
Adding Leaderboard Support to Your Game 50
Loading Information About Your Games Leaderboards (iOS 6) 50
Reporting Scores to Game Center 51
Working with the Default Leaderboard (iOS 7) 53
Working with the Default Leaderboard (iOS 6) 54
Displaying the Standard Leaderboard (iOS 6) 54
Retrieving Score Data 55
Extending Leaderboards Using Score Contexts 60
Leaderboard Sets 61
Checklist for Supporting Leaderboard Sets 62
A Game Can Have Multiple Leaderboard Sets 63
Game Group Leaderboard and Leaderboard Set Limits 63
Working with Leaderboard Sets in iTunes Connect 63
Adding Leaderboard Set Support to Your Game 64

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

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

3
Contents

Resetting Achievement Progress 77


Displaying the Standard Achievement User Interface 78
Creating a Custom Achievement User Interface 79

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

Real-Time Matches 100


Checklist for Adding Real-Time Matchmaking to Your Game 100
Getting Started 101
Finding Players for a Match 101
Exchanging Data Between Match Participants 101
Adding Voice Chat to a Match 102
Overview of Real-Time Matches in Game Center 103
Finding Players for a Match 103
Using the Standard Matchmaking User Interface 104
Implementing a Custom Match User Interface 108
Finding Player Activity in Your Game 112
Exchanging Data Between Match Participants 113
Designing Your Network Game 113
Starting the Match 115

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

4
Contents

Determining the Best Server 116


Sending Data to Other Players 117
Receiving Data from Other Players 117
Disconnecting from a Match 118
Adding Voice Chat to a Match 118
Creating an Audio Session (iOS only) 118
Creating Voice Channels 119
Starting and Stopping Voice Chat 119
Enabling and Disabling the Microphone 120
Controlling the Volume of a Voice Chat 120
Seeing When a Players State Changes 121

Hosted Matches 122


Matching Players for a Hosted Match 122
Hosted Matches Overview 123
Creating a Hosted Match Using the Matchmaker View Controller 124
Dismissing the MatchMaking View Controller 124

Turn-Based Matches 125


Checklist for Implementing a Turn-Based Match 126
Every Match Has a List of Participants 126
The Match Data Represents the State of the Match 127
Your Game Decides the Rules of Play 129
Save the Match Data Whenever Important Events Occur 131
Implementing a Turn-Based Match Using Game Kit 131
Game Center Imposes Limits on the Match 132
Joining a New Match 132
Working with Existing Matches 136
Retrieving Information About a Match 137
Working with Match Data 138
Advancing the State of the Match 141
Setting the Match Outcome When a Participant Leaves a Match 141
Ending a Match 143
Responding to Match Notifications 143
Adding Exchanges to a Turn-Based Match 145
Anatomy of an Exchange 145
Sending an Exchange Request 146
Responding to an Exchange Request 148
Resolving an Exchange Request 149

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

5
Contents

Testing Your Game Center-Aware Game 151


Testing a Game Center-Aware Game 151
Testing Your Game in iOS Simulator 152

Document Revision History 153

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

6
Figures, Tables, and Listings

Developing a Game Center-Aware Game 17


Figure 1-1 A game user interface screen flow 18
Figure 1-2 Game Center-enabled UI 20
Figure 1-3 Publishing an app on the App Store 23
Figure 1-4 Developing and distributing Game Center assets 24
Table 1-1 Game Center feature summary 21

Displaying Game Center User Interface Elements 28


Listing 2-1 Displaying the Game Center user interface 28
Listing 2-2 Responding when the player finishes viewing the Game Center content 29
Listing 2-3 Displaying the Game Center user interface in OS X 29
Listing 2-4 Responding when the player dismisses the Game Center content 30
Listing 2-5 Displaying a notification banner 30

Working with Players in Game Center 32


Figure 3-1 Local and remote players 34
Table 3-1 Important Player Object Properties 35
Table 3-2 Local Player Object Properties 35
Listing 3-1 Setting an authentication handler 37
Listing 3-2 Authenticating the local player 38
Listing 3-3 Retrieving a local players friends 41
Listing 3-4 Retrieving a local players friends (previous) 41
Listing 3-5 Retrieving player details 42
Listing 3-6 Loading a players photo 43
Listing 3-7 Displaying a friend request 44
Listing 3-8 Responding when the player dismisses the friend request 44

Leaderboards and Leaderboard Sets 45


Figure 4-1 Leaderboard data is filtered, sorted, and returned to your game 57
Figure 4-2 Combined leaderboards include scores from the single leaderboards 58
Figure 4-3 Leaderboards combined into a leaderboard set 62
Table 4-1 Properties for a single leaderboard 48
Table 4-2 Leaderboard language properties 49
Table 4-3 Game Kit classes used to implement leaderboard support 50

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

7
Figures, Tables, and Listings

Table 4-4 Useful leaderboard object properties 51


Table 4-5 Properties that affect the leaderboard data query 56
Table 4-6 Game Kit classes used to implement leaderboard set support 64
Listing 4-1 Retrieving information about available leaderboards 50
Listing 4-2 Reporting a score to Game Center (iOS 7) 51
Listing 4-3 Reporting a score to Game Center (iOS 6) 52
Listing 4-4 Loading the default leaderboard for the local player (iOS 7) 53
Listing 4-5 Updating the default leaderboard when reporting a score (iOS 7) 53
Listing 4-6 Updating the default leaderboard directly 54
Listing 4-7 Loading the default leaderboard for the local player (iOS 6) 54
Listing 4-8 Updating the default leaderboard directly (iOS 6) 54
Listing 4-9 Displaying the leaderboard page of the Game Center user interface 55
Listing 4-10 Responding when the player dismisses the Game Center content 55
Listing 4-11 Retrieving the top ten scores 58
Listing 4-12 Retrieving the top scores for players in a match 59
Listing 4-13 Retrieving information about available leaderboard sets 64
Listing 4-14 Retrieving information about available leaderboards 65

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

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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

Real-Time Matches 100


Figure 8-1 Network topologies 115
Table 8-1 Classes used to implement real-time matches 103
Listing 8-1 Showing the standard matchmaking interface 104
Listing 8-2 Implementing the cancellation method 105
Listing 8-3 Implementing the error handling method 105
Listing 8-4 Implementing the match found method 105
Listing 8-5 Installing an invitation handler 107
Listing 8-6 Programmatically finding a match 108
Listing 8-7 Canceling a match search 109
Listing 8-8 Programmatically adding friends to a match 110
Listing 8-9 Searching for all activity for your game on Game Center 112
Listing 8-10 Starting a match 116
Listing 8-11 Sending a position to all players 117
Listing 8-12 Creating an audio session that can play and record 118
Listing 8-13 Creating voice channels 119
Listing 8-14 Receiving updates about the player 121

Hosted Matches 122


Table 9-1 Methods to implement hosted matchmaking 122
Listing 9-1 Creating a hosted match 124

Turn-Based Matches 125

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

9
Figures, Tables, and Listings

Figure 10-1 Mary starts a new match 126


Figure 10-2 The current player wants to view the match 128
Figure 10-3 A turn flowchart for a hypothetical 4X game 130
Figure 10-4 Bob has been eliminated from the match 142
Figure 10-5 Initializing a trade through an exchange 146
Figure 10-6 Accepting a trade through an exchange 148
Table 10-1 Classes in Game Kit used to implement turn-based match support 131
Table 10-2 Important match limits 132
Table 10-3 Common actions to perform on a match 136
Table 10-4 Important properties of a match object 137
Table 10-5 Important properties of a participant object 138
Table 10-6 Turn-based event handler methods 144
Listing 10-1 Displaying the standard interface to join a turn-based match 133
Listing 10-2 Implementing the cancellation method 133
Listing 10-3 Implementing the error handling method 134
Listing 10-4 Implementing the match found method 134
Listing 10-5 Finding a turn-based match programmatically 135
Listing 10-6 Retrieving the list of matches the local player is participating in 136
Listing 10-7 Loading the match data from Game Center 140
Listing 10-8 Saving the match data to Game Center 140
Listing 10-9 Advancing to the next participant in a match 141
Listing 10-10 Sending an exchange request to another player 147
Listing 10-11 Canceling an exchange request 147
Listing 10-12 Replying to an exchange request 148
Listing 10-13 Resolving completed exchanges before ending a turn 149

Testing Your Game Center-Aware Game 151


Table 11-1 Different kinds of app builds 151

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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)

Your Game Displays Game Centers User Interface Elements


Game Kit provides many classes that present full-screen user interfaces to the player. Standard classes are
provided to display leaderboards, achievements, and matchmaking screens. For example, the
GKGameCenterViewController class provides the simplest way to display Game Center content in your
game.

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)

Game Center Features Require an Authenticated Player


All of Game Centers features require an authenticated player on the device, known as the local player. Before
your game uses any Game Center features, it must successfully authenticate the local player. Most Game Center
classes function only if there is an authenticated player, and those classes implicitly reference the local player.
For example, when your game reports scores to a leaderboard, it always reports scores for the local player.

Your game must disable all Game Center features when there is not an authenticated player.

Relevant Chapter: Working with Players in Game Center (page 32)

Leaderboards Require Your Game to Have a Scoring Mechanism


Leaderboards allow your game to post scores to the Game Center service. Players can view these scores by
viewing a leaderboard in the Game Center app, but your game can also display the standard leaderboard
interface with just a few lines of code. Or, if you'd rather customize the appearance of a leaderboard, your
game can download the raw score data. You can create multiple leaderboards for your game and customize
each with your games scoring mechanisms.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

13
About Game Center
At a Glance

Relevant Chapter: Leaderboards and Leaderboard Sets (page 45)

Leaderboard Sets Allow You to Manage Your Leaderboards


Combine leaderboards into leaderboard sets to logically group leaderboards for your game. Implementing
leaderboard sets raises the number of leaderboards that your game is allowed to contain. Combine all of the
leaderboards for a single level into a set or combine the high score leaderboard from each level into a set, the
decision on how to combine your leaderboards is up to you.

Relevant Chapter: Leaderboards and Leaderboard Sets (page 45)

Achievements Require Your Game to Measure Players Progress


An achievement is a specific goal that the player accomplishes within your game, such as Find 10 gold coins
or Capture the flag in less than 30 seconds. As with leaderboards, a player views achievements within the
Game Center app or in your game. Within the Game Center app, players can compare earned achievements
with those earned by friends. Within your game, you can choose to display the standard user interface or you
can download the raw data to create your own custom interface.

Relevant Chapter: Achievements (page 66)

Challenges Allow Players to Challenge Each Other


A challenge is sent from one player to another. Each challenge is a specific goal that the challenged player
must complete. When a challenge is completed, both the challenger and the challenged player are notified.
Challenges are automatically provided in any game that supports either leaderboards or achievements. However,
you can also take the extra step of implementing customized support for challenges directly in your game.

Relevant Chapter: Challenges (page 81)

Matchmaking Requires Your Game Design to Incorporate Multiplayer Gaming


Matchmaking allows players interested in playing online multiplayer games to discover each other and be
connected to a match. Game Center supports three kinds of matchmaking:
A real-time match requires all of the players to be connected to Game Center simultaneously. Game Kit
provides classes that implement the low-level networking infrastructure to allow the devices to exchange
data in real time.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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)

How to Use This Document


If you are new to developing Game Center-aware games, start by reading Developing a Game Center-Aware
Game (page 17). This chapter the process for designing and implementing a game that supports Game Center.
Next, read Displaying Game Center User Interface Elements (page 28) which describes common conventions
for displaying Game Centers user interface elements in your game. This topic is particularly important for OS
X developers as it explains the infrastructure Game Kit provides for displaying Game Center content over your
own user interface. iOS developers will find that Game Center conforms to the standard programming model
for view controllers.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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

Game Kit also relies heavily on delegation and block objects.

See Also
See Game Kit Framework Reference for details on the Game Kit framework.

The GKAuthentication sample demonstrates how to implement user authentication.

The GKLeaderboards sample demonstrates how to implement leaderboards.

The GKAchievements sample demonstrates how to implement achievements.

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

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Supporting Game Center in Your User Interface


When you add Game Center support to your game, parts of your games user interface displays Game Center
content. Some of this content, such as player authentication, is required. Other user interface elements, such
as leaderboards, are optional, but are often expected by players.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Figure 1-1 A game user interface screen flow

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

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Figure 1-2 Game Center-enabled UI

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

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Adapting Your Game Design


Each feature in Game Center imposes requirements on your game design. For example, a leaderboard score
is a numerical value representing how well the player did while playing your game. To implement a leaderboard
in your game, the game design must include a play mechanism and calculate a score based on how well the
player did. The requirements and limitations for each Game Center feature are described in the detailed chapters
later in this document. Table 1-1 summarizes the relevant characteristics.

Table 1-1 Game Center feature summary

Feature Requirements Limitations Assets

Leaderboard Scoring mechanism Maximum number of Strings,


leaderboards, formatting options leaderboard
for leaderboard scores sorting, artwork

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

21
Developing a Game Center-Aware Game
Customizing the Game Center Sounds

Feature Requirements Limitations Assets

Leaderboard A leaderboard Maximum number of Strings,


Sets leaderboards and sets allowed. leaderboard
All apps in a group must either grouping, artwork
have sets or not have sets.

Achievement Tracking code to watch Maximum number of Strings, artwork


what a player does in achievements per game,
the game maximum point allocation.

Challenges You must implement


either leaderboards or
achievements

Matchmaking Multiplayer game Number of players, size of data Custom invitation


design packets, networking sound

Customizing the Game Center Sounds


You can change the default Game Center sounds using GKInvite. For example, when a player receives an
invitation, Game Center plays a sound to announce the invitation. Your game can instead provide a custom
sound to be played when invitations for it are received. To do this, include a sound file in your app bundle. All
of the default Game Center sounds can be changed using a custom sound file. The file must be in either caf,
aif, or wav format and be named GKInvite plus the appropriate file extension.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

22
Developing a Game Center-Aware Game
Creating and Managing Game Center Resources

Creating and Managing Game Center Resources


Building a game that supports Game Center is different from building a game that does not. All games have
resources, such as images, models, and sound files, used to render the games user interface. However, you
also need to create specific resources to support Game Centers user interface. The way you provide these
assets is different than in a standard app. Figure 1-3 shows the process for a standard app.

Figure 1-3 Publishing an app on the App Store

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Figure 1-4 Developing and distributing Game Center assets

Here are some of the changes to the development process:


Originally, the iTunes Connect record was created at the end of the development process, when you were
ready to submit the app for review. When creating a Game Center-aware game, you create the iTunes
Connect record as soon as you are ready to implement and test your Game Center features. The iTunes
Connect record is needed to authorize your game to access the Game Center service.
Assets you create in iTunes Connect are automatically copied to a special test environment provided by
Apple. This environment mimics the regular Game Center service but is private to developers. Development
builds of your game automatically load the assets from the test environment.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Two distinct forms of grouping are possible in iTunes Connect:


Shared game assets. You create a common pool of leaderboards and achievement assets that are shared
by all versions of your game. If a player has both versions of your game, items earned in one version are
visible in the other.
Matchmaking compatibility. This allows you to specify which versions of your game can form matches.
You ensure that all games in a compatibility group share the same networking code. A matchmaking
group can even be formed between different versions of a game shipping with a single bundle ID. For
example, if you shipped four versions of your game (1.0, 1.1, 2.0, 3.0), you could specify that version 1.0
and version 1.1 of the game could play together, because nothing in version 1.1 changed the networking
implementation.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Incorporating Game Center into Your Game


Heres a reasonable process to follow when designing a game that supports Game Center:
1. Decide which Game Center features you plan to support.
2. Define your game mechanics, keeping in mind the requirements and limitations of Game Center.
3. Implement your game engine, ignoring Game Center for now. Focus on developing the other aspects of
your game, such as your game engine and gameplay. You do this to avoid needing to create an iTunes
Connect record earlier than you need to.
4. When you need to implement Game Center:
a. Create an iTunes Connect record for your game, using the games bundle ID. Enable Game Center in
the iTunes Connect record; setting this flag in the iTunes Connect record authorizes the Game Center
service to allow your game to connect to it.
b. Create an explicit app ID using your games bundle ID.
c. Enable Game Center in this app ID; this authorizes the app on the device to contact Game Centers
servers.
d. Create a new provisioning profile using this new explicit app ID.
e. Test to ensure you can build and sign your game using this profile.
f. Add the Game Kit framework to your project.
g. Import the GameKit/GameKit.h header file.
5. If your game requires Game Center, add the Game Center key to the list of capabilities your app requires
from the device. See Requiring Game Center in Your Game (iOS only) (page 27).
6. If your game does not require Game Center, you should establish a weak link from your game to the Game
Kit framework. Then, when your game launches, test to make sure that Game Center is supported. See
Optionally Supporting Game Center in Your Game (page 27).
7. Implement authentication.
8. Implement other Game Center features.
9. Test your Game Center features using the Game Center development environment.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

26
Developing a Game Center-Aware Game
Incorporating Game Center into Your Game

Requiring Game Center in Your Game (iOS only)


If your game requires Game Center to function (for example, a multiplayer game that requires Game Center
to match players), you want to ensure that only devices that support Game Center can download your game.
To ensure that your game runs only on supported devices, add the gamekit key to the list of required device
capabilities in your games Info.plist file. See App-Related Resources.

Optionally Supporting Game Center in Your Game


If you want your game to use Game Center but your game does not require Game Center to function properly,
you can weak link your game to the Game Kit framework and test for its existence at runtime. See SDK
Compatibility Guide for more information.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Game Center UI Is Displayed by Your View Controller (iOS)


The convention used by Game Kit is for one of your view controllers to present the Game Kit view controller.
Your view controller acts as a delegate to the view controller it presents so that the view controller can be
informed when the player is finished looking at the presented screen.

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.

Listing 2-1 Displaying the Game Center user interface

- (void) showGameCenter

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

28
Displaying Game Center User Interface Elements
Game Center UI Is Displayed by Your Window (OS X)

GKGameCenterViewController *gameCenterController = [[GKGameCenterViewController


alloc] init];

if (gameCenterController != nil)

gameCenterController.gameCenterDelegate = self;

[self presentViewController: gameCenterController animated: YES


completion:nil];

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

[self dismissViewControllerAnimated:YES completion:nil];

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.

Game Center UI Is Displayed by Your Window (OS X)


In OS X, view controllers do not play the same role as they do in iOS. In many cases, some other object
responsible for your user interface displays the Game Center control. It does this through the use of the
GKDialogController class. This class presents the user interface in a window provided by your game.

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.

Listing 2-3 Displaying the Game Center user interface in OS X

- (void) showGameCenter

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

29
Displaying Game Center User Interface Elements
Displaying Notification Banners

GKGameCenterViewController *gameCenterController = [[GKGameCenterViewController


alloc] init];

if (gameCenterController != nil)

GKDialogController *sdc = [GKDialogController sharedDialogController];

sdc.parentWindow = myWindow;

[sdc presentViewController: gameCenterController];

Listing 2-4 shows how the delegate changes.

Listing 2-4 Responding when the player dismisses the Game Center content

- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController
*)gameCenterViewController

GKDialogController *sdc = [GKDialogController sharedDialogController];

[sdc dismiss: self];

Displaying Notification Banners


Listing 2-5 shows how to display a notification banner in your game. It constructs a title and message using
private methods and then displays the banner. When the banner disappears from the screen, the completion
block is called and the code advances to some other part of the games user interface.

Listing 2-5 Displaying a notification banner

- (void) showBanner

NSString* title = [self generateTitle];

NSString* message = [self generateBannerMessage];


[GKNotificationBanner showBannerWithTitle: title message: message

completionHandler:^{

[self advanceToNextInterfaceScreen]

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

30
Displaying Game Center User Interface Elements
Displaying Notification Banners

}];

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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

Game Center Manages Player Accounts


To take advantage of Game Centers features, a user creates a Game Center account that identifies to identify
themselves as a specific user. That user is known as a player on Game Center. The Game Center service keeps
track of critical account information for that player, such as who that player is, what games that player has
played, what the player has accomplished in each game, and who that players friends are. Some of this
information is directly available to your game; typically this is information specifically related to the game and
general information about the player.

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

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Player Identifier Strings Uniquely Identify Players


Every player account is uniquely identified by a player identifier string. The identifier string is created when
the players account is first created and never changes, even if other information in the account changes. Thus,
player identifiers are the only reliable way to track a particular player. For this reason, the Game Kit API uses
player identifiers wherever a specific player needs to be identified. If Game Center needs to identify a specific
player in your game, the Game Kit API returns that players identifier. Your game uses a player identifier to
retrieve information from Game Center about that player.

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.

The Local Player Is the Player Signed in to the Device


When you design your game, youll find that your game is often aware of multiple players at the same time.
For example, if you design a game using multiplayer networking, then you have informationand a player
identifierfor each player in the match. However, on any particular device, one player always takes precedence

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Figure 3-1 Local and remote players

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.

Player Objects Provide Details About Players


When your game needs details for a particular player, it retrieves those details by making a query to Game
Center using the players player identifier. Game Kit returns those details to your game in a GKPlayer object.
Table 3-1 lists some of the more interesting properties on a player object.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

34
Working with Players in Game Center
Game Center Manages Player Accounts

Table 3-1 Important Player Object Properties

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.

Table 3-2 Local Player Object Properties

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

35
Working with Players in Game Center
Common Tasks When Working with Players

Common Tasks When Working with Players

Authenticating a Local Player on the Device


Your game should start to authenticate the player as early as possible after launching, even before you present
the user interface. Authentication is an asynchronous process and wont slow down the loading of your title
screen. Waiting until after the title screen is presented before authenticating the user only increases the delay
until the player can play your game. The main reason you need to authenticate the player as early as possible
is so that iOS can launch your game specifically to handle events that the player is interested in. For example,
if your game supports turn-based matches, it might be launched because the player has already tapped a
notification banner. Thus, you need to authenticate early so that your game can retrieve and process the Game
Center event.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

36
Working with Players in Game Center
Common Tasks When Working with Players

Authenticating a Local Player (iOS 6)


Listing 3-1 shows how to set an authentication handler. The method retrieves the shared instance of the
GKLocalPlayer class and then sets that objects authenticateHandler property to point to a block object
that handles authentication events. Once you set an authentication handler, Game Kit automatically authenticates
the player asynchronously, calling your authentication handler as necessary to complete the process. Each
time your game moves from the background to the foreground, Game Kit automatically authenticates the
local player again.

Listing 3-1 Setting an authentication handler

- (void) authenticateLocalPlayer

GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];

localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError


*error){

if (viewController != nil)

//showAuthenticationDialogWhenReasonable: is an example method name.


Create your own method that displays an authentication view when appropriate for
your app.

[self showAuthenticationDialogWhenReasonable: viewController];

else if (localPlayer.isAuthenticated)

//authenticatedPlayer: is an example method name. Create your own


method that is called after the loacal player is authenticated.

[self authenticatedPlayer: localPlayer];

else

[self disableGameCenter];

}];

The authentication handler shows the distinct conditions your code needs to handle:

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Authenticating a Local Player (iOS 5, OS X v10.8)


Listing 3-2 shows an implementation of a method that authenticates the local player. The method retrieves
the shared instance of the GKLocalPlayer class and calls that objects
authenticateWithCompletionHandler: method. Authenticating the local player happens asynchronously;
your game continues to launch after initiating the player authentication. If necessary, this method call displays
the authentication user interface over your game. When authentication completes, Game Kit calls the block
object provided by your game.

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.

Listing 3-2 Authenticating the local player

- (void) authenticateLocalPlayer

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

38
Working with Players in Game Center
Common Tasks When Working with Players

GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];

[localPlayer authenticateWithCompletionHandler:^(NSError *error) {

if (localPlayer.isAuthenticated)

// Player was successfully authenticated.

// Perform additional tasks for the authenticated player.

}];

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.

Common Authentication Errors and Their Meanings


Two common errors that can be received by your game are worth describing in more detail:
Receiving a GKErrorGameUnrecognized error means that you have not enabled Game Center for your
app in iTunes Connect. Sign in to your iTunes Connect account and verify that your app has Game Center
enabled. Also, confirm that the bundle identifier in your Xcode project matches the bundle identifier you
assigned to your app in iTunes Connect.
Receiving a GKErrorNotSupported error means that the device your game is running on does not
support Game Center. You should disable all Game Center related features.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Authenticating the Local Player in a Multitasking App


A game that supports both multitasking and Game Center must take additional steps when authenticating
the local player. When your game is in the background, the status of the authenticated player may change,
because the player may sign out or a new player may sign in. As such, you can never rely on the information
staying the same when your game moves into the background,.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

40
Working with Players in Game Center
Common Tasks When Working with Players

Retrieving the Local Players Friends


You may want to your game to reference the local players friends. For example, you might do this if you are
implementing your own custom matchmaking or challenge interface and want to allow the player to pick and
choose players from the friends list. Unlike the other properties of a local player object, the friends property
is not filled when the local player object is returned to your game because that data can potentially be quite
large and take a while to send over the network. Instead, you choose when you want your game to load this
information.

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.

Listing 3-3 Retrieving a local players friends

- (void) retrieveFriends

GKLocalPlayer *lp = [GKLocalPlayer localPlayer];

if (lp.authenticated)

[lp loadFriendsWithCompletionHandler:^(NSArray *friendIDs, NSError *error)


{

if (friendIDs != nil)

[self loadPlayerData: friendIDs];

}];

Listing 3-4 Retrieving a local players friends (previous)

- (void) retrieveFriends

GKLocalPlayer *lp = [GKLocalPlayer localPlayer];

if (lp.authenticated)

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

41
Working with Players in Game Center
Common Tasks When Working with Players

[lp loadFriendsWithCompletionHandler:^(NSArray *friends, NSError *error) {

if (friends != nil)

[self loadPlayerData: friends];

}];

Retrieving Information About Players


Regardless of which Game Kit class returned player identifiers to your game, you retrieve detailed information
about those players in the same way by calling the
loadPlayersForIdentifiers:withCompletionHandler: class method on the GKPlayer class. Listing
3-5 shows a skeletal implementation. This Game Kit method takes two parameters. The first is an array of player
identifiers for the players you are interested in. The second is a completion handler to be called after Game Kit
retrieves the data from Game Center. Game Kit loads the data asynchronously in the background and calls
your completion handler after the task completes. The completion handler receives an array of GKPlayer
objects (one for each identifier) as well as an error parameter.

Listing 3-5 Retrieving player details

- (void) loadPlayerData: (NSArray *) identifiers

[GKPlayer loadPlayersForIdentifiers:identifiers withCompletionHandler:^(NSArray


*players, NSError *error) {

if (error != nil)

// Handle the error.

if (players != nil)

// Process the array of GKPlayer objects.

}];

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Loading a Photo for a Player


In addition to the information found in the player object, you can also attempt to load a photo for the player.
Not all player objects have photos associated with them, so your code must be able to work without them.

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.

Listing 3-6 Loading a players photo

- (void) loadPlayerPhoto: (GKPlayer*) player

[player loadPhotoForSize:GKPhotoSizeSmall withCompletionHandler:^(UIImage


*photo, NSError *error) {

if (photo != nil)

[self storePhoto: photo forPlayer: player];

if (error != nil)

// Handle the error if necessary.


}

}];

Allowing the Local Player to Invite Other Players to Be Friends


The Game Center app allows players to send invitations to other players. Use the
GKFriendRequestComposeViewController class to allow a player to send friend requests. The friend
request must be presented modally by a view controller that your game creates and can not be pushed onto
a navigation controller.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Listing 3-7 Displaying a friend request

- (void) inviteFriends: (NSArray*) identifiers

GKFriendRequestComposeViewController *friendRequestViewController =
[[GKFriendRequestComposeViewController alloc] init];

friendRequestViewController.composeViewDelegate = self;

if (identifiers)

[friendRequestViewController addRecipientsWithPlayerIDs: identifiers];

[self presentViewController: friendRequestViewController animated: YES


completion:nil];

[friendRequestViewController release];

When the player dismisses the friend request, the delegates


friendRequestComposeViewControllerDidFinish: method is called. Listing 3-8 shows how your view
controller should dismiss the request.

Listing 3-8 Responding when the player dismisses the friend request

-
(void)friendRequestComposeViewControllerDidFinish:(GKFriendRequestComposeViewController
*)viewController

[self dismissViewControllerAnimated:YES completion:nil];

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Checklist for Supporting Leaderboards


To add leaderboards to your game, you need to take the following steps:
1. Before you add leaderboards, add code to authenticate the local player. See Working with Players in
Game Center (page 32).
2. Decide how you want to use leaderboards in your game. You choose how many leaderboards to use and
how each leaderboard interprets its score data. You are free to design a different scoring mechanism for
each leaderboard. See Leaderboards Require a Scoring Mechanism (page 46).
3. Go to iTunes Connect and configure the leaderboards for your game. For each leaderboard, you configure
the kind of score recorded and how the score is formatted for display. Leaderboard formatting can be
localized for different languages and regions. See Working with Leaderboards in iTunes Connect (page
48).
4. Add code to report scores to Game Center. See Listing 4-3 (page 52).
5. Add code to display a leaderboard to the local player. See Working with the Default Leaderboard (iOS
7) (page 53).
Optionally, you can retrieve score data from Game Center and use it to create your own custom leaderboard
user interface. See Retrieving Score Data (page 55).

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

45
Leaderboards and Leaderboard Sets
Leaderboards Require a Scoring Mechanism

Leaderboards Require a Scoring Mechanism


To build leaderboards into your game, that game needs to have a gameplay mechanism that allows your game
to calculate a score. You are free to design your gameplay and scoring mechanism however you want. The
only restriction is that your scoring mechanism must return a 64-bit integer value. When you report a score,
you report this integer value to Game Center so it can be stored.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

46
Leaderboards and Leaderboard Sets
A Game Can Have Multiple Leaderboards

A Game Can Have Multiple Leaderboards


You can define up to 100 different leaderboards for a game (or game group) if your game does not support
leaderboard sets. The number of different leaderboards allowed increases to 500 leaderboards per game when
leaderboard sets have been enabled. See Leaderboard Sets (page 61) for more information. Each leaderboard
has its own score type, sorting order, and formatting information. When you implement multiple leaderboards,
you choose what sort of score data to record in each leaderboard, which essentially means that each leaderboard
may have its own scoring mechanism, if desired.

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.

One Leaderboard Is the Default Leaderboard


When you define your leaderboards in iTunes Connect, one leaderboard is designated as the default
leaderboard. When your game performs a leaderboard task without specifying a category, the default
leaderboard is automatically chosen.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

47
Leaderboards and Leaderboard Sets
Combined Leaderboards Gather Scores from Multiple Single Leaderboards

Combined Leaderboards Gather Scores from Multiple Single


Leaderboards
A combined leaderboard is a special type of leaderboard that combines scores reported to multiple leaderboards
into one leaderboard. The individual leaderboards continue to exist and are where you report scores to. You
dont report scores to combined leaderboards. For example, if your game offers multiple race tracks, you can
create a single leaderboard for each race track and a combined leaderboard that shows the best time earned
on any track.

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.

Working with Leaderboards in iTunes Connect


After youve considered the design of your scoring mechanism, you go to iTunes Connect to precisely define
each leaderboard. Defining a leaderboard is a critical step; once your game ships to customers, many pieces
of the leaderboard cannot be changed. Its important to note that the information you enter into iTunes Connect
must match your games implementation. As such, you should exercise caution when creating your leaderboards
and test your game thoroughly before releasing it.

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.

Table 4-1 Properties for a single leaderboard

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Table 4-2 Leaderboard language properties

Property Description

Language This is the language in which your leaderboard appears.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

49
Leaderboards and Leaderboard Sets
Adding Leaderboard Support to Your Game

Adding Leaderboard Support to Your Game


To implement leaderboard support in your game, you use the classes listed in Table 4-3.

Table 4-3 Game Kit classes used to implement leaderboard support

Class Name Class Function

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.

GKLeaderboard A GKLeaderboard object provides information about a leaderboard,


including its leaderboard ID and title. You also create GKLeaderboard
objects when you want to retrieve score data from a leaderboard. You
typically do this if you want to create your own custom leaderboard user
interface.

GKGameCenterView- The GKGameCenterViewController class provides a standard user


Controller interface to display Game Center content to the player. This content includes
a leaderboard page.

GKLeaderboardView- The GKLeaderboardViewController class provides a standard user


Controller interface to display a leaderboard. If the GKGameCenterViewController
class is available, you should use that class instead.

The following sections describe common tasks and how to implement them.

Loading Information About Your Games Leaderboards (iOS 6)


Listing 4-1 shows the preferred mechanism for loading information about the available leaderboards. It returns
an array of leaderboard objects, one for each leaderboard defined for your game on Game Center.

Listing 4-1 Retrieving information about available leaderboards

- (void) loadLeaderboardInfo

[GKLeaderboard loadLeaderboardsWithCompletionHandler:^(NSArray *leaderboards,


NSError *error) {

self.leaderboards = leaderboards;

}];

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Table 4-4 Useful leaderboard object properties

Property Description

category The leaderboard ID for the leaderboard.


NOTE: Deprecated in iOS 7. Use identifier instead.

identifier The leaderboard ID for the leaderboard.

title The localized title you defined in iTunes Connect.

groupIdentifier Holds the group identifier for when your game shares the leaderboard with
other games in a game group.

Reporting Scores to Game Center


Your game transmits scores to Game Center by creating an array of GKScore objects, whether you are reporting
a single score or multiple scores. A score object has properties for the player that earned the score, the date
and time the score was earned, the identifier for the leaderboard the score should be reported to, and the
actual score that was earned. You allocate and initialize a new score object for each score, configure their
properties, and then call the reportScores:withCompletionHandler: method to send the data to Game
Center.

Listing 4-2 shows how to use an array of GKScore objects to report a score to Game Center.

Listing 4-2 Reporting a score to Game Center (iOS 7)

- (void) reportScore: (int64_t) score forLeaderboardID: (NSString*) identifier

GKScore *scoreReporter = [[GKScore alloc] initWithLeaderboardIdentifier:


identifier];

scoreReporter.value = score;

scoreReporter.context = 0;

NSArray *scores = @[scoreReporter];

[GKLeaderboard reportScores:scores withCompletionHandler:^(NSError *error) {

//Do something interesting here.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Security and Score Reporting


When you design a game that reports scores to Game Center, you should also consider the security needs of
your game. You want scores reported to Game Center to be an accurate accounting of how players are doing.
Here are two suggestions:
Store your games preferences and saved games in a secure format, rather than in clear text. If your games
data is stored in clear text, a player can download the saved game data using iTunes, modify it, and resync
it back to the device. This may allow the player to achieve a higher score than you intended.
Always set reasonable minimum and maximum values for a leaderboard.

Reporting Scores to Game Center (iOS 6)


If your game needs to run on an earlier version of iOS or OS X, your game transmits scores to Game Center by
creating a GKScore object. A score object has properties for the player that earned the score, the date and
time the score was earned, the category for the leaderboard the score should be reported to, and the actual
score that was earned. You allocate and initialize a new score object, configure its properties, and then call its
reportScoreWithCompletionHandler: method to send the data to Game Center.

Listing 4-3 shows how to use a score object to report a score to Game Center.

Listing 4-3 Reporting a score to Game Center (iOS 6)

- (void) reportScore: (int64_t) score forLeaderboardID: (NSString*) category

GKScore *scoreReporter = [[GKScore alloc] initWithCategory:category];

scoreReporter.value = score;

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

52
Leaderboards and Leaderboard Sets
Adding Leaderboard Support to Your Game

scoreReporter.context = 0;

[scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {

// Do something interesting here.

}];

Working with the Default Leaderboard (iOS 7)


The default leaderboard is set when you create your leaderboards in iTunes Connect. However, the default
leaderboard is a per-player setting also; as a player plays your game you can update the default leaderboard
shown to that player.

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)

[[GKLocalPlayer localPlayer] loadDefaultLeaderboardIdentifierWithCompletionHandler:

(void(^)(NSString *leaderboardIdentifier, NSError *error)) {

//Use the leaderboard identifier.

}]

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)

GKScore *scoreReporter = [[GKScore alloc]


initWithLeaderboardIdentifier:identifier];

scoreReporter.shouldSetDefaultLeaderboard = YES

...

However, you can also use the GKLocalPlayer object to update the default leaderboard directly.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

53
Leaderboards and Leaderboard Sets
Adding Leaderboard Support to Your Game

Listing 4-6 Updating the default leaderboard directly

[[GKLocalPlayer localPlayer] setDefaultLeaderboardIdentifier: newLeaderboard


completionHandler: (^)(NSError *error) {

// Log the error.

Working with the Default Leaderboard (iOS 6)


When targeting devices running iOS 6, use the code similar to that in Listing 4-7 to load the default leaderboard.
Use the category identifier when identifying the default leaderboard.

Listing 4-7 Loading the default leaderboard for the local player (iOS 6)

[[GKLocalPlayer localPlayer] loadDefaultLeaderboardCategoryIDWithCompletionHandler:

((^)(NSString *categoryID, NSError *error)) {

// Use the category ID.

}]

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.

Listing 4-8 Updating the default leaderboard directly (iOS 6)

[[GKLocalPlayer localPlayer] setDefaultLeaderboardCategoryID: newCategory


completionHandler: (^)(NSError *error) {

// Log the error.

Displaying the Standard Leaderboard (iOS 6)


In addition to sending scores to Game Center, you should also allow players to view scores within your game.
The simplest way to do this is with a GKGameCenterViewController object. You can adjust the behavior
of a Game Center view controller so the initial content it displays is the leaderboard page. Listing 4-9 shows
how to accomplish this. The method instantiates a new view controller and sets its gameCenterDelegate
property to point to the presenting view controller. It then configures the other properties to show the

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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

- (void) showLeaderboard: (NSString*) leaderboardID

GKGameCenterViewController *gameCenterController = [[GKGameCenterViewController


alloc] init];

if (gameCenterController != nil)

gameCenterController.gameCenterDelegate = self;

gameCenterController.viewState = GKGameCenterViewControllerStateLeaderboards;

gameCenterController.leaderboardTimeScope = GKLeaderboardTimeScopeToday;

gameCenterController.leaderboardCategory = leaderboardID;

[self presentViewController: gameCenterController animated: YES


completion:nil];

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

[self dismissViewControllerAnimated:YES completion:nil];

Retrieving Score Data


There are times when you want to retrieve score data from Game Center. The most common reason to download
the score data is when you want to create a custom leaderboard user interface. Your game uses a
GKLeaderboard object to retrieve score data. In this case, the leaderboard object represents a query on the
data stored on Game Center. You set properties on the GKLeaderboard object to filter which scores are
returned to your game, then tell the object to load the scores. Table 4-5 lists the properties you can set.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

55
Leaderboards and Leaderboard Sets
Adding Leaderboard Support to Your Game

Table 4-5 Properties that affect the leaderboard data query

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Listing 4-11 Retrieving the top ten scores

- (void) retrieveTopTenScores

GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] init];

if (leaderboardRequest != nil)

leaderboardRequest.playerScope = GKLeaderboardPlayerScopeGlobal;

leaderboardRequest.timeScope = GKLeaderboardTimeScopeToday;

leaderboardRequest.identifier = @"Combined.LandMaps"

leaderboardRequest.range = NSMakeRange(1,10);

[leaderboardRequest loadScoresWithCompletionHandler: ^(NSArray *scores,


NSError *error) {

if (error != nil)

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

58
Leaderboards and Leaderboard Sets
Adding Leaderboard Support to Your Game

// Handle the error.

if (scores != nil)

// Process the score information.

}];

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.

Listing 4-12 Retrieving the top scores for players in a match

- (void) receiveMatchBestScores: (GKMatch*) match

GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] initWithPlayerIDs:


match.playerIDs];

leaderboardRequest.timeScope = GKLeaderboardTimeScopeAllTime;

leaderboardRequest.identifier = @"Combined.LandMaps"

leaderboardRequest.range = NSMakeRange(1,10);

if (query != nil)
{

[query loadScoresWithCompletionHandler: ^(NSArray *scores, NSError *error)


{

if (error != nil)

// Handle the error.

if (scores != nil)

// Process the score information.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Extending Leaderboards Using Score Contexts


Although the score and formatting system allows you to create interesting leaderboards, you may want to
extend the leaderboard system to include other information specific to your game. You do this using score
contexts. A GKScore object has a context property that holds a 64-bit integer. The value stored in this
property is stored along with the score. Game Center doesnt use this value at all, nor does it affect score
formatting. Your game is free to use this integer to store whatever information you want.

Here are a few possibilities:


You can use the context property to store flags that provide additional content. For example, in a racing
game, use the flags to store what kind of car the person completed the racetrack with. Then, in your own
custom leaderboard user interface, you could display the appropriate car image next to each score.
Record the users actions and other data in to a file. You then design your game engine to be able to replay
the contents of that file. You store the file on your own server and use the context field as an index to
reference the file. Your custom leaderboard user interface can then offer the ability to see exactly how
someone earned the score.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Figure 4-3 Leaderboards combined into a leaderboard set

Checklist for Supporting Leaderboard Sets


To add leaderboard sets to your game, you need to take the following steps:
1. Before you add achievements, add code to authenticate the local player. See Working with Players in
Game Center (page 32).
2. Ensure that your game contains at least one leaderboard. See Adding Leaderboard Support to Your
Game (page 50) for information on creating leaderboards.
3. Go to iTunes Connect and configure leaderboard sets for your game. For each leaderboard set, add the
desired leaderboards to the leaderboard set. See Working with Leaderboard Sets in iTunes Connect (page
63).
4. Add code to load the leaderboard sets associated with the current game. See Loading Leaderboard Sets
to Your Game (page 64).

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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).

A Game Can Have Multiple Leaderboard Sets


You can define up to 100 different leaderboard sets for your game. Each leaderboard set can contain up to
100 leaderboards with a maximum of 500 leaderboards for your game. You choose which leaderboards are
placed inside of each leaderboard set. Games that dont use leaderboard sets are limited to 100 leaderboards.

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

Game Group Leaderboard and Leaderboard Set Limits


The number of leaderboards and leaderboard sets within a group is limited only by the number of apps within
the group. Each game within a group can have a number of leaderboard sets and leaderboards, as stated in
A Game Can Have Multiple Leaderboard Sets (page 63). For example, if a group has three apps inside of it,
then the group can have a total of 300 leaderboard sets and 1500 leaderboards. However, an individual app
is still limited to 100 leaderboard sets and 500 leaderboards.

Working with Leaderboard Sets in iTunes Connect


After you have decided to use leaderboard sets in your game, you must configure the leaderboard sets in
iTunes Connect. In iTunes Connect you can create new leaderboard sets and move your leaderboards into
them. For complete details on managing your games leaderboards and leaderboard sets see iTunes Connect
Developer Guide .

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

63
Leaderboards and Leaderboard Sets
Leaderboard Sets

Adding Leaderboard Set Support to Your Game


To implement leaderboard set support in your game, you use the classes listed in Table 4-6.

Table 4-6 Game Kit classes used to implement leaderboard set support

Class Name Class Function

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.

GKLeaderboard A GKLeaderboard object provides information about a leaderboard,


including its leaderboard ID and title. You also create GKLeaderboard
objects when you want to retrieve score data from a leaderboard. You
typically do this if you want to create your own custom leaderboard user
interface.

GKLeaderboardSet A GKLeaderboardSet object provides information about the leaderboard


sets contained within your game. Each set contains from 1 to 100
GKLeaderboard objects assigned to the set.

GKGameCenterView- The GKGameCenterViewController class provides a standard user


Controller interface to display Game Center content to the player. This content includes
a leaderboard page.

GKLeaderboardView- The GKLeaderboardViewController class provides a standard user


Controller interface to display a leaderboard. If the GKGameCenterViewController
class is available, you should use that class instead.

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.

Loading Leaderboard Sets to Your Game


Listing 4-13 shows the preferred mechanism for loading information about the available leaderboard sets. It
returns an array of leaderboard set objects, one for each leaderboard set defined for your game on Game
Center.

Listing 4-13 Retrieving information about available leaderboard sets

- (void) loadLeaderboardSetInfo

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

64
Leaderboards and Leaderboard Sets
Leaderboard Sets

[GKLeaderboardSet loadLeaderboardSetsWithCompletionHandler:^(NSArray
*leaderboardSets, NSError *error) {

self.leaderboardSets = leaderboardSets;

}];

Loading Leaderboards Within a Set


Listing 4-14 shows the preferred mechanism for loading information about the available leaderboards. It returns
an array of leaderboard objects, one for each leaderboard defined for your game on Game Center. Call this
method on a specific GKLeaderboardSet object to retrieve its leaderboards.

Listing 4-14 Retrieving information about available leaderboards

- (void) loadLeaderboardInfo

[GKLeaderboard loadLeaderboardsWithCompletionHandler:^(NSArray *leaderboards,


NSError *error) {

self.leaderboards = leaderboards;

}];

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Checklist for Supporting Achievements


To add achievements to your game, you need to take the following steps:
1. Before you add achievements, add code to authenticate the local player. See Working with Players in
Game Center (page 32).
2. Design your games achievements. See Designing an Achievement (page 67).
3. Go to iTunes Connect and configure the achievements for your game. You provide all of the data needed
to display achievements to the player. See Configuring Achievements in iTunes Connect (page 69).
4. Add code to report the local players progress to Game Center. By storing the progress on Game Center,
you also make the players progress visible in the Game Center app. See Reporting Achievement Progress
to Game Center (page 71).
5. Add code to load the local players previous progress on achievements from Game Center. The local players
progress should be loaded shortly after the player is successfully authenticated. See Loading Achievement
Progress (page 74).

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Create Achievements That Require Different Levels of Skill or Dedication


Provide achievements for both new players and experienced playersand the players in between. Achievements
are a reward to the player for playing your game. If all of your games achievements are too easy to beat, the
rewards will seem cheap and the player wont feel challenged. On the other hand, if all the achievements are
too difficult to earn, then players may not be rewarded often enough to continue playing your game. Strive
to include achievements that can be earned when learning how to play the game and also achievements that
reward players for learning how to play your game well.

Another reason to include more difficult achievements is that they encourage players to use them when
challenging other players. See Challenges (page 81).

Create Achievements for Different Sections Or Modes Present in Your Game


For various reasons, you might choose to partition the gameplay into smaller games or game modes. Some
reasons include:
Distinct sets of game rules or rule variants (capture the flag, survival)
Distinct game levels or maps
A game with an underlying story separated into distinct acts or story arcs

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Use Hidden Achievements to Delight and Reward the Player


Hidden achievements should be used sparingly. Usually, you want players to know whats expected of them
in your game, so that they can actively set goals for themselves. And hidden achievements cannot be used to
create new challenges. However, a hidden achievement can be a great opportunity to surprise a player with
something unexpected. For example, any of the following might be places where a hidden achievement could
be helpful:
An unexpected element in the plot or a story.
The player succeeds at a crazy stunt.
You can flip the convention from an achievement being something the player tries hard to earn into
something more ignoble, earned when they fail spectacularly. The achievement then represents a way to
inject humor into the situation. For example, an achievement called Hot Foot that might appear after the
player has fallen into lava 20 times.

Save Some of Your Budget for Later Versions of Your Game


There are limits to how many achievements you can create in your game and how many points you can reward
to the player:
Each game can have up to 100 achievements.
Each game can award up to 1000 points.
No individual achievement can award more than 100 points.

Avoid spending all of your budget on the initial version of your game. Save some of your budget to support
updates and new content.

Configuring Achievements in iTunes Connect


When you are ready to add achievements, you define them first in iTunes Connect. For each achievement, you
provide values for all of the properties listed in Table 5-1. Further, for each language you plan to localize the
achievement into, you provide data for all of the properties listed in Table 5-2.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

69
Achievements
Configuring Achievements in iTunes Connect

Table 5-1 Achievement properties

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.

Achievement ID A chosen alphanumeric identifier for your achievement. This ID is limited


to 100 characters. Your achievement ID is a permanent setting and therefore
cannot be edited at a later date. The achievement ID is used inside your
game to refer to this achievement.

Point Value The points that your achievement is worth.

Hidden Achievements marked as Hidden remain hidden to a player on Game Center


until after the first time you report progress for that achievement.

Achievable More Than Indicates whether the user can earn the achievement multiple times.
Once

Table 5-2 Achievement language properties

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

70
Achievements
Adding Achievement Support to Your Game

Adding Achievement Support to Your Game


When you are ready to implement achievements in your game, you do so using the classes listed in Table 5-3.

Table 5-3 Classes in Game Kit used to implement achievement support

Class Name Description

GKAchievement Holds information about the players progress towards completing an


achievement. Your game creates GKAchievement objects to report
progress to Game Center. Game Kit can also load the current progress
stored on Game Center and return it to your game using GKAchievement
objects.

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.

GKAchievementView- Provides a standard user interface to display an achievements page. If the


Controller GKGameCenterViewController class is available, you should use that
class instead.

Reporting Achievement Progress to Game Center


Your game should report progress to Game Center whenever the player makes progress towards completing
an achievement. By storing progress information in Game Center, you gain a few benefits:
The Game Center app can display the players progress towards the achievement.
If a player has multiple devices, your game on another device can retrieve the players progress towards
achievements.

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.

When you report progress to Game Center, two things happen:

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Listing 5-1 Reporting progress on an achievement

- (void) reportAchievementIdentifier: (NSString*) identifier percentComplete:


(float) percent

GKAchievement *achievement = [[GKAchievement alloc] initWithIdentifier:


identifier];

if (achievement)

achievement.percentComplete = percent;

[achievement reportAchievementWithCompletionHandler:^(NSError *error)

if (error != nil)

NSLog(@"Error in reporting achievements: %@", error);

}];

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

72
Achievements
Adding Achievement Support to Your Game

Listing 5-2 Reporting progress on an achievement for another player

- (void) reportAchievementIdentifier: (NSString*) identifier forPlayer: (NSString


*) playerID percentComplete: (float) percent

GKAchievement *achievement = [[GKAchievement alloc] initWithIdentifier:identifier


forPlayer:playerID];

if (achievement)

achievement.percentComplete = percent;

[achievement reportAchievementWithCompletionHandler:^(NSError *error)

if (error != nil)
{

NSLog(@"Error in reporting achievements: %@", error);

}];

To report progress on multiple achievements at once, use the


reportAchievements:withCompletionHandler: class method instead. Listing 5-3 shows a possible
implementation. This example creates three achievement objects representing three achievements the player
has just completed. It then bundles the achievement objects into an array and reports them all with a call to
the class method.

Listing 5-3 Reporting progress on multiple achievements

- (void) completeMultipleAchievements

GKAchievement *achievement1 = [[GKAchievement alloc] initWithIdentifier:


@"DefeatedFinalBoss"];

GKAchievement *achievement2 = [[GKAchievement alloc] initWithIdentifier:


@"FinishedTheGame"];

GKAchievement *achievement3 = [[GKAchievement alloc] initWithIdentifier:


@"PlayerIsAwesome"];

achievement1.percentComplete = 100.0;

achievement2.percentComplete = 100.0;

achievement3.percentComplete = 100.0;

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

73
Achievements
Adding Achievement Support to Your Game

NSArray *achievementsToComplete = [NSArray


arrayWithObjects:achievement1,achievement2,achievement3, nil];

[GKAchievement reportAchievements: achievementsToComplete


withCompletionHandler:^(NSError *error)

if (error != nil)

NSLog(@"Error in reporting achievements: %@", error);

}];
}

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.

Loading Achievement Progress


You load the local players current progress information from Game Center by calling the
loadAchievementsWithCompletionHandler: method. If the operation completes successfully, it returns
an array of GKAchievement objects, one object for each achievement your game previously reported progress
for.

Listing 5-4 shows how your game might implement this.

Listing 5-4 Loading achievement progress

- (void) loadAchievements

{ [GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *achievements,


NSError *error) {

if (error != nil)

// Handle the error.

if (achievements != nil)

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

74
Achievements
Adding Achievement Support to Your Game

// Process the array of achievements.

}];

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.

@property(nonatomic, retain) NSMutableDictionary *achievementsDictionary;

2. Initialize the achievements dictionary.

achievementsDictionary = [[NSMutableDictionary alloc] init];

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)

for (GKAchievement* achievement in achievements)

[achievementsDictionary setObject: achievement forKey:


achievement.identifier];

}];

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

- (GKAchievement*) getAchievementForIdentifier: (NSString*) identifier

GKAchievement *achievement = [achievementsDictionary


objectForKey:identifier];

if (achievement == nil)

achievement = [[GKAchievement alloc]


initWithIdentifier:identifier];

[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.

- (void) reportAchievementIdentifier: (NSString*) identifier


percentComplete: (float) percent

GKAchievement *achievement = [self


getAchievementForIdentifier:identifier];

if (achievement)

achievement.percentComplete = percent;

[achievement reportAchievementWithCompletionHandler:^(NSError
*error)

if (error != nil)

// Log the error.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

76
Achievements
Adding Achievement Support to Your Game

}];

Best Practices for Reporting Achievement Progress


When designing a game that uses Game Center achievements, you need to balance the need to be responsive
to the player against your goal to use as few device resources as possible. With those two concepts in mind,
consider the following practices:
Report progress on an achievement as soon as the player makes progress. Dont delay reporting until a
later time; if a player earns an achievement, the banner should be displayed immediately.
Report progress only when the player has actually made further progress. Do not report changes to Game
Center if the player has not made progress, because it consumes network resources without actually
changing the state of the data on Game Center.
If the player makes progress on multiple achievements simultaneously, use the technique shown in Listing
5-3 (page 73) to report the progress. Using this class method is more efficient.
If your game displays a custom banner or indicator when a player earns an achievement, set the
showsCompletionBanner property to NO before reporting the achievement to Game Center.

Resetting Achievement Progress


You may want to allow the player to reset their progress on achievements in your game. Listing 5-5 demonstrates
how to do this. First, this method clears any locally cached achievement objects created by the previous
example. Then, it calls Game Kit to reset the players progress stored on Game Center.

Listing 5-5 Resetting achievement progress

- (void) resetAchievements

// Clear all locally saved achievement objects.

achievementsDictionary = [[NSMutableDictionary alloc] init];

// Clear all progress saved on Game Center.

[GKAchievement resetAchievementsWithCompletionHandler:^(NSError *error)


{

if (error != nil)

// handle the error.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Displaying the Standard Achievement User Interface


In addition to sending achievement progress to Game Center, you should also allow players to view their
progress from within your game. The simplest way to do this is with a GKGameCenterViewController
object. You can adjust the behavior of a Game Center view controller so that it shows the achievements page
when presented. Listing 5-6 shows how to accomplish this. It instantiates a new view controller and sets its
gameCenterDelegate property to point to the presenting view controller. It then configures the controllers
view state to show the achievements page. Finally, it presents the leaderboard and waits for the delegate to
be called. On OS X, you use the GKDialogController to display the view controller, as described in Displaying
Game Center User Interface Elements (page 28).

Listing 5-6 Displaying the achievements page of the Game Center user interface.

- (void) showLeaderboard: (NSString*) leaderboardID

GKGameCenterViewController *gameCenterController = [[GKGameCenterViewController


alloc] init];

if (gameCenterController != nil)

gameCenterController.gameCenterDelegate = self;

gameCenterController.viewState = GKGameCenterViewControllerStateAchievements;

[self presentViewController: gameCenterController animated: YES


completion:nil];

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

78
Achievements
Adding Achievement Support to Your Game

Listing 5-7 Responding when the player dismisses the Game Center content

- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController
*)gameCenterViewController

[self dismissViewControllerAnimated:YES completion:nil];

Creating a Custom Achievement User Interface


When creating your own custom achievement user interface, load the data initially provided to iTunes Connect
into your game. The data is returned to your game using GKAchievementDescription objects.

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.

Listing 5-8 Retrieving achievement metadata from Game Center

- (void) retrieveAchievmentMetadata

[GKAchievementDescription loadAchievementDescriptionsWithCompletionHandler:

^(NSArray *descriptions, NSError *error) {

if (error != nil)

// Process the error.

if (descriptions != nil)

// use the achievement descriptions.

}];

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Listing 5-9 Loading a completed achievement image

[achievementDescription loadImageWithCompletionHandler:^(UIImage *image, NSError


*error) {

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Game Center supports two kinds of challenges:


A score challenge is issued based on a leaderboard score previously earned by the challenger. The challenge
is completed when the challenged player earns a better score. When the challenged player beats a score
challenge, Game Center automatically issues a new score challenge to the original challenger. Score
challenges continue to pass back and forth between the two players as they work to beat each others
scores.
An achievement challenge is issued from an achievement that the challenger has already completed.
The challenge is completed when the challenged player completes the achievement.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

81
Challenges
Checklist for Supporting Challenges

Checklist for Supporting Challenges


To add challenges to your game, you need to take the following steps:
First, add support for leaderboards or achievements to your game. See Leaderboards and Leaderboard
Sets (page 45) and Achievements (page 66).
Optionally, add code to allow a player to send challenges within your game. See Issuing Challenges from
Your Game (page 82)
Optionally, add code to receive and act on challenge notifications. See Receiving Information About
Existing Challenges (page 85) and Reacting to Challenge Events (page 87)

Issuing Challenges from Your Game


You issue a challenge from within your game using either a GKScore object or a GKAchievement object.
Both classes implement an issueChallengeToPlayers:message: method with a similar signature. Issuing
a challenge does not display a user interface to the player issuing the challenge; this is code you need to
implement yourself. The following section shows a series of methods you can use to issue an achievement
challenge.

The design for score-based challenges is similar. Create a score object, submit the score, then use it to generate
a challenge request.

Displaying the Challenge User Interface


Listing 6-1 begins the challenge process. This method is called when the player completes an achievement.
The first thing the code does is create a new achievement object to tell Game Center that the achievement
has been completed. If the player completes multiple achievements for a challenge at once, create a new
object for each achievement and add the achievement to an array. Note that a challenge can only be performed
on a completed achievement. It disables the achievements default completion banner because it plans to
display a custom challenge screen instead. The method reports the progress to Game Center and then triggers
a segue to display the games custom challenge user interface.

Listing 6-1 Displaying the challenge user interface

- (void) bossMonsterDefeated

GKAchievement *achievement = [[GKAchievement alloc]


initWithIdentifier:@"MyGame.bossDefeated"];

achievement.percentComplete = 100.0;

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

82
Challenges
Issuing Challenges from Your Game

achievement.showsCompletionBanner = NO;

[achievement reportAchievements: [NSArray arrayWithObjects:achievement, nil]


WithCompletionHandler:NULL];

[self performSegueWithIdentifier:@"achievementChallenge" sender:achievement];

Displaying and Dismissing the Challenge View Controller


Listing 6-2 shows the issuing view controllers prepareForSegue:sender: method. When the method
detects that this is a segue to show the achievement user interface, it sets the issuing view controller as a
delegate. The achievement object is also provided to the challenge view controller so that it can customize its
user interface to match the earned achievement.

Listing 6-2 Preparing the challenge view controller

- (void )prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

if ([segue.identifier isEqualToString:@"achievementChallenge"])

MyAchievementChallengeViewController* challengeVC =
(MyAchievementChallengeViewController*) segue.destinationViewController;

challengeVC.delegate = self;

challengeVC.achievement = (GKAchievement*) sender;

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.

Listing 6-3 Dismissing the challenge view controller

- (void) challengeViewController:(MyAchievementChallengeViewController*)controller
wasDismissedWithChallenge:(BOOL)issued

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

83
Challenges
Issuing Challenges from Your Game

[self dismissViewControllerAnimated:YES completion:NULL];

if (issued)

[controller.achievement issueChallengeToPlayers:controller.players
message:controller.message];

Best Practices for Issuing Challenges


The local player must always have control over when and how a challenge is issued. Your game must never
issue a challenge on the players behalf without the player first approving the challenge. When you implement
your custom user interface for challenges, you must ensure that the player has the option to not issue a
challenge. Even when a player issues a challenge, the player needs to be in control of who receives the challenge
and what message is displayed to those players.

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

- (void) challengeLesserMortalsForScore: (int64_t) playerScore inCategory:


(NSString*) category

GKLeaderboard *query = [[GKLeaderboard alloc] init];

query.category = category;

query.playerScope = GKLeaderboardPlayerScopeFriendsOnly;

query.range = NSMakeRange(1,100);

[query loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {

NSPredicate *filter = [NSPredicate predicateWithFormat:@"value <


%qi",playerScore];

NSArray *lesserScores = [scores filteredArrayUsingPredicate:filter];

[self presentChallengeWithPreselectedScores: lesserScores];

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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

- (void) challengePlayersToCompleteAchievement: (GKAchievement*) achievement

[achievement selectChallengeablePlayerIDs:[GKLocalPlayer localPlayer].friends


withCompletionHandler:^(NSArray *challengeablePlayerIDs, NSError *error) {

if (challengeablePlayerIDs)

[self presentChallengeWithPreselectedPlayerIDs: challengeablePlayerIDs];

}];

Receiving Information About Existing Challenges


A common design for a game that directly supports challenges is to offer a Challenges button on the title
screen. When the button is tapped, your game presents a list of challenges issued to the local player. If a
challenge is then selected from the list, your game automatically transitions to a screen that allows the player
to work towards completing the selected challenge.

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.

Listing 6-6 Retrieving the list of challenges

- (void) showChallengesList

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

85
Challenges
Receiving Information About Existing Challenges

[GKChallenge loadReceivedChallengesWithCompletionHandler:^(NSArray *challenges,


NSError *error) {

if (challenges)

[self presentChallengeList: challenges];

}];

Table 6-1 lists the most common properties used to populate your user interface.

Table 6-1 Common challenge properties

Property Description

issuingPlayerID The player identifier for the issuing player.

receivingPlayerID The player identifier for the player that received the challenge.

issueDate The date the challenge was issued.

completionDate The date the challenge was completed.

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.

Table 6-2 Challenge subclasses

Subclass Description

GKScoreChallenge Read the score property to obtain a score object representing the
score used to generate the challenge.

GKAchievementChallenge Read the achievement property to obtain an achievement object


representing the achievement that completes the challenge.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

86
Challenges
Reacting to Challenge Events

Reacting to Challenge Events


Your game can directly connect to the notification system so that it is called directly when challenges issued
to or by the local player are updated. By default Game Kit automatically displays a banner when the status of
a challenge changes, but you can also suppress specific banners if you want to display a custom user interface
instead.

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.

Listing 6-7 Installing a challenge event handler

- (void) installChallengeHandler

GKChallengeEventHandler *eventHandler = [GKChallengeEventHandler


challengeEventHandler];

eventHandler.delegate = self;

Responding to Challenge Events


Game Kit displays banners to the local player under the following circumstances:
When the local player receives a challenge
When the local player completes a challenge
When a remote player completes a challenge issued by the local player

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.

Table 6-3 Kinds of challenge events

Event Method to Control Banner Method to Handle the Event


Presentation

A local player receives a shouldShowBanner- localPlayerDid-


challenge ForLocallyReceivedChallenge: ReceiveChallenge:

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

87
Challenges
Reacting to Challenge Events

Event Method to Control Banner Method to Handle the Event


Presentation

A local player completes shouldShowBanner- localPlayerDid-


a challenge ForLocallyCompleted- CompleteChallenge:
Challenge:

A remote player shouldShowBanner- remotePlayerDid-


completes a challenge ForRemotelyCompleted- CompleteChallenge:
Challenge:

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

NSString *issuerID = challenge.issueingPlayerID;

[GKPlayer loadPlayersForIdentifiers@[issuerID] withCompletionHandler:^(NSArray


*players, NSError *error) {

GKPlayer *player = [players lastObject];

// Load the challenging player's photo.

[player loadPhotoForSize: GKPhotoSizeNormal withCompletionHandler:^(UIImage


*photo, NSError *error) {

[self presentCompletedChallenge: challenge photo: photo


name:player.displayName];

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

88
Challenges
Reacting to Challenge Events

}];

}];

Responding When the Local Player Selects a Challenge


When a player receives a new challenge and the banner appears, the player may tap the challenge banner to
immediately play the challenge. Similarly, the player can look up a challenge in the Game Center app and
choose to launch your game to play the challenge. To be notified when the player wants to play a challenge,
you implement the localPlayerDidSelectChallenge: method. If your game was launched to handle the
challenge, the handlers localPlayerDidSelectChallenge: method is called immediately after the
authentication process completes.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Game Center Supports Multiple Kinds of Matches


Table 7-1 lists the different kinds of matches supported by Game Center matchmaking. Each kind of match
has different restrictions and capabilities.

Table 7-1 Game Center match types

Match Type Description

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

90
Matchmaking Overview
Game Center Provides Multiple Ways to Connect Players into a Match

Match Type Description

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.

Game Center Provides Multiple Ways to Connect Players into a Match


Game Center makes it as easy as possible for your game to connect players into a match:
Your game can present the standard matchmaking user interface. This interface allows players to invite
friends to the match or to allow the remaining empty slots to be filled by other players searching for a
match.
Your game can programmatically invite players or search for other waiting players. In this case, you are
responsible for implementing your own matchmaking user interface to give the player control over this
process. You typically use this approach when you want to add your own steps to the matchmaking process
or when you want the matchmaking user interface to fit with your games artistic style.
A player can use the Game Center app to create a match with another player.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

91
Matchmaking Overview
Matchmaking and Gameplay Are Separate Tasks

Matchmaking and Gameplay Are Separate Tasks


Finding players for a match is a distinct behavior that is different from actually playing a match. In most
circumstances, matchmaking and gameplay occur at different times. The typical behavior for most games is
to first create a match and then to play the match. However, other scenarios are possible:
For a real-time match, it is possible for a match to already exist even while you search for more players.
In this case, the match exists simultaneously with the matchmaking process, which means that match
participants can exchange data while additional players are discovered.
For a turn-based match, matchmaking does not need to be complete before a match starts. Instead,
whenever a new player is needed to continue the match, matchmaking automatically executes to fill that
position.

You Can Match Across Different Versions of Your Game


In iTunes Connect, you can provide compatibility information that describes which versions of your game can
see each other during the matchmaking process. Each compatible group of devices and versions of your game
are matched as separate groups. The ability to create these matchmaking groups is quite flexible:
When you create a new version of a game (such as a bug fix), you can declare whether the new version is
compatible with the older versions (and which ones, specifically).
You can create distinct games (with different bundle identifiers) and still allow them to play against each
other.
You can create distinct games on both OS X and iOS and match them against each other.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

92
Matchmaking Overview
Creating Any Kind of Match Starts with a Match Request

Creating Any Kind of Match Starts with a Match Request


All new matches start with a match request that describes the desired parameters for the match. Essentially,
the match request tells Game Center how many players to find and which players to find for the match. Game
Kit also uses the match request to customize its matchmaking behavior. For example, when your game displays
the standard matchmaking interface, the request is used to customize the screens appearance. The way that
Game Kit and Game Center use match requests is described in later chapters for each type of match. However,
because all of the matches share a common infrastructure, you need to understand how to create and configure
a match request before reading other chapters.

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.

Table 7-2 Important match request properties

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).

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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).

A Match Request Must Specify the Number of Players in the Match


Listing 7-1 shows a simple match request. All match requests are required to set the minimum and maximum
players for a match; Game Center respects these boundaries and always ensures that the final match has the
correct number of players.

Listing 7-1 A simple match request

GKMatchRequest *request = [[GKMatchRequest alloc] init];

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.

Table 7-3 Maximum number of players for each kind of match

Match Type Maximum Number of Players

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

94
Matchmaking Overview
Creating Any Kind of Match Starts with a Match Request

Inviting a List of Players


By default, Game Center uses a match request to find other waiting players to fill a match. For example, if a
match requires four people to be present before it can start, then Game Center finds four waiting participants,
forms them into a match, and then returns that match. This scenario is useful because it allows waiting players
to be quickly matched together. However, not everyone wants to play with a randomized set of players each
time a match is played. Often, players want to play specifically against friends. For this reason, the standard
user interface allows a player to invite specific friends to the game. However, your game can also choose to
provide this support programmatically by assigning an array of player identifier strings to the 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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

95
Matchmaking Overview
Creating Any Kind of Match Starts with a Match Request

Separate players based on the map the match is played on.

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

GKMatchRequest *request = [[GKMatchRequest alloc] init];

request.minPlayers = 2;

request.maxPlayers = 4;

request.playerGroup = MyMap_Forest | MyRulesCaptureTheFlag;

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.

Player attributes have a few limitations:


Roles are checked only for auto-matched players. If the player invites friends to join the match, friends do
not pick a role and do not have an attribute set.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Implementing Player Attributes


Player attributes are implemented using the playerAttributes property on the match request. By default,
the value of this property is 0, which means that the attributes property is ignored. If the propertys value is
non-zero, Game Center uses it to match a specific role.

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.

Listing 7-3 Setting the player attributes on the match request

GKMatchRequest *request = [[GKMatchRequest alloc] init];

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.

The algorithm looks roughly like this:


1. A matchs mask starts with the mask of the inviting player.
2. Game Center looks for players with match requests that have a non-zero player attributes value. Game
Center searches for players whose masks include set bits that are not currently in the matchs mask.
3. After a player is added to the match, the value of the new players player attributes value is logically ORed
into the matchs mask.
4. If the matchs mask does not equal FFFFFFFFh, Game Center searches for other players to join the match.
If the match is complete, but the game still requires more players to reach the minimum, Game Center
continues to search for more players to add.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

97
Matchmaking Overview
Creating Any Kind of Match Starts with a Match Request

Player Attributes Example: A Role-Playing Game


Assume that you are creating a role-playing game with four roles: Fighter, Wizard, Thief, and Cleric. Every match
consists of four players, and the match must have one and only one player for each role. To implement this
requirement, your game creates masks for each role that matches the four-step algorithm described earlier.
Listing 7-4 provides an example set of masks.

Listing 7-4 Creating the masks for the character classes

#define MyRole_Fighter 0xFF000000

#define MyRole_Cleric 0x00FF0000

#define MyRole_Wizard 0x0000FF00

#define MyRole_Thief 0x000000FF

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.

Player Attributes Example: Chess


For chess, you might want to allow players to choose whether they want to play the black pieces, the white
pieces, or they dont care what color they start with. Listing 7-5 (page 98) provides an example set of masks
for this design.

Listing 7-5 Creating the masks for chess

#define MyRole_Black 0xFFFF0000

#define MyRole_White 0x0000FFFF

#define MyRole_Either 0xFFFFFFFF

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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

Figure 7-1 Adding figure that shows the chess combinations

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Checklist for Adding Real-Time Matchmaking to Your Game


The checklist for creating a game that supports real-time matches is more extensive than that for other Game
Center technologies and comprises three main areas: matchmaking, data exchange, and voice chat. As part of
this process, you also have many design decisions to make about how matches are played in your game,
including:
How many players can play at once
What does a network version of your game looks like
What data needs to be shared to build your design

These and other questions impact the design of your gameplay and networking code.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Finding Players for a Match


Determine whether your game will use the standard matchmaking interface, display a custom matchmaking
interface, or use a combination of both. Regardless of which implementation you choose, you must support
the chosen implementation behavior inside your game as well as add support for handling invitations received
from outside of your game.
If you are implementing the standard user interface, see Using the Standard Matchmaking User
Interface (page 104).
If you are implementing a custom user interface, see Implementing a Custom Match User Interface (page
108).

Exchanging Data Between Match Participants


This is the most complex step of the process as it requires you to perform extensive design work for both the
game mechanics for a real-time match and the low-level details of synchronizing communication between the
participants of the match.
Design the network messages your game uses to communicate with other participants in the match. Most
games exchange information at the start of the match to provide each participant the same initial game
state, and then send updates as events occur within the game. See Designing Your Network Game (page
113).
Write code to use the match object to send data to other match participants. Your game encodes the
game state into binary data and uses the match object to transmit it to other players. See Sending Data
to Other Players (page 117).
Implement a match delegate to handle events that can occur during the match:

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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).

Adding Voice Chat to a Match


Voice chat support is optional, but can take a good game and turn it into a great game. It allows the players
a closer and more natural level of interaction. Here are the steps for implementing voice chat in your game:
Decide how many voice channels your game needs. For example, a free-for-all match can use a single
channel for all participants while a match with multiple teams might use a separate channel for each team
and an additional channel that includes all players in the game.
If your game is running in iOS, configure an audio session to enable the microphone. All games that record
or play audio must have an audio session. See Creating an Audio Session (iOS only) (page 118).
Create the voice channel by calling the match objects voiceChatWithName: method. The match returns
a GKVoiceChat object. See Creating Voice Channels (page 119).
Call the voice chat objects start method to activate the channel. See Starting and Stopping Voice
Chat (page 119).
Enable the microphone for a chat channel when a player needs to speak into it. Each participant can speak
into only one channel at a time. See Enabling and Disabling the Microphone (page 120).
Provide controls in your game that allow the user to enable and disable voice chat, set volume levels or
mute players within a channel. See Controlling the Volume of a Voice Chat (page 120).
Decide whether your game should support a push-to-talk model or whether it should continuously sample
the microphone. In a push-to-talk game, provide a control that the player presses to transmit voice data
to other players. In a game that continuously samples the microphone, provide a control to mute the
microphone.
Implement an update handler that is called when a player connects or disconnects, or when a player starts
or stops speaking. Typically, you use this handler to update your games user interface to display up to
date information for each player in the voice chatfor example, highlighting a user interface item when
a player is speaking. See Seeing When a Players State Changes (page 121).

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

102
Real-Time Matches
Overview of Real-Time Matches in Game Center

Overview of Real-Time Matches in Game Center


Table 8-1 lists the classes you use when designing a game that uses real-time matches in Game Center.

Table 8-1 Classes used to implement real-time matches

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.

GKInvite Delivered when a player accepts an invitation to play in a match.

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.

Finding Players for a Match


When a player wants to create a match, your game must display a user interface to allow the player to see and
configure the state of the match. The simplest way to implement this is to use the standard user interface
provided by the GKMatchmakerViewController class. It implements many common matchmaking scenarios
with a small investment in code. However, if you want to implement your own custom behavior, you can design
your own custom user interface and then call the GKMatchmaker class to perform this task programmatically.
The matchmaker class returns data to your game so that it can update its own user interface.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

103
Real-Time Matches
Finding Players for a Match

Using the Standard Matchmaking User Interface


The standard matchmaking user interface is often displayed in response to the user tapping a button on your
games title screen. It can appear immediately after the button is tapped or after several interim screens between
the title screen and the matchmaking screen. For example, if your match request includes player groups or
player attributes, you usually have your own custom user interface screen to configure the match request
before displaying the default matchmaking user interface.

Presenting the Matchmaking User Interface


Listing 8-1 shows how a view controller presents the matchmaking user interface to the player. It creates and
configures a match request and then initializes a new matchmaker view controller object using the match
request. The presenting view controller makes itself the matchmaking view controllers delegate and then
presents the matchmaking interface over itself. The player interacts with the matchmaking screen until the
match is ready to start or an error occurs.

Listing 8-1 Showing the standard matchmaking interface

- (IBAction)hostMatch: (id) sender

GKMatchRequest *request = [[GKMatchRequest alloc] init];

request.minPlayers = 2;

request.maxPlayers = 2;

GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc]


initWithMatchRequest:request];

mmvc.matchmakerDelegate = self;

[self presentViewController:mmvc animated:YES completion:nil];

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).

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

104
Real-Time Matches
Finding Players for a Match

Listing 8-2 Implementing the cancellation method

- (void)matchmakerViewControllerWasCancelled:(GKMatchmakerViewController
*)viewController

[self dismissViewControllerAnimated:YES completion:nil];

// Implement any specific code in your game here.

The matchmakerViewController:didFailWithError: delegate method is called when matchmaking


encounters an error while trying to set up the matchfor example, when a device loses its network connection.
Similar to when the player cancels the matchmaking process, your game dismisses the view controller and
moves to a previous screen.

Listing 8-3 Implementing the error handling method

- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController
didFailWithError:(NSError *)error

[self dismissViewControllerAnimated:YES completion:nil];

// Implement any specific code in your game here.

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.

Listing 8-4 Implementing the match found method

- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController
didFindMatch:(GKMatch *)match

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

105
Real-Time Matches
Finding Players for a Match

[self dismissViewControllerAnimated:YES completion:nil];

self.myMatch = match; // Use a retaining property to retain the match.

match.delegate = self;

if (!self.matchStarted && match.expectedPlayerCount == 0)

self.matchStarted = YES;

// Insert game-specific code to start the match.

Processing Invitations from Other Players


When a player accepts an invitation from another player, your game is launched (if necessary) and an invitation
is delivered to your game. Your game receives this invitation by implementing an invitation handler. When
you use the standard user interface, your invitation handler creates a match view controller and initializes it
with data provided to the invitation handler. The invitation handler then presents the match view controller
similar to when the player wanted to create a new match directly; in most cases, you use the same delegate
code.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Listing 8-5 Installing an invitation handler

[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray


*playersToInvite) {

// Insert game-specific code here to clean up any game in progress.

if (acceptedInvite)
{

GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc]


initWithInvite:acceptedInvite];

mmvc.matchmakerDelegate = self;

[self presentViewController:mmvc animated:YES completion:nil];

else if (playersToInvite)

GKMatchRequest *request = [[GKMatchRequest alloc] init];

request.minPlayers = 2;

request.maxPlayers = 2;

request.playersToInvite = playersToInvite;

GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc]


initWithMatchRequest:request];
mmvc.matchmakerDelegate = self;

[self presentViewController:mmvc animated:YES completion:nil];

};

Adding Players to an Existing Match


Occasionally, a match may drop below the number of players your game requires. For example, this situation
can occur if a player loses their network connection. In this case, instead of disbanding the match entirely, you
might want to add additional players.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Implementing a Custom Match User Interface


Implementing a complete custom match interface can be as simple as displaying a network progress indicator
until auto-matching completes, or as sophisticated as implementing a complete custom view controller that
replicates the standard behavior. The latter is potentially a significant investment in programming time, as it
needs to include support for all of the following:
Inviting specific players into a match
Listening for responses from invited players
Looking for nearby players (available via Wi-Fi or Bluetooth)

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.

Auto-matching to Fill a Match


The simplest interface your game can provide is an instant match button. When this button is pressed, the
player is added to a match without needing to enter any additional information.

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.

Listing 8-6 Programmatically finding a match

- (IBAction)findProgrammaticMatch: (id) sender

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

108
Real-Time Matches
Finding Players for a Match

GKMatchRequest *request = [[GKMatchRequest alloc] init];

request.minPlayers = 2;

request.maxPlayers = 4;

[[GKMatchmaker sharedMatchmaker] findMatchForRequest:request


withCompletionHandler:^(GKMatch *match, NSError *error) {

if (error)

// Process the error.

else if (match != nil)


{

self.myMatch = match; // Use a retaining property to retain the match.

match.delegate = self;

if (!self.matchStarted && match.expectedPlayerCount == 0)

self.matchStarted = YES;

// Insert game-specific code to begin the match.

}];

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.

Listing 8-7 Canceling a match search

[[GKMatchmaker sharedMatchmaker] cancel];

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

109
Real-Time Matches
Finding Players for a Match

Inviting Specific Players to a Match


If you are implementing a complete custom user interface, you need to allow players to invite their friends to
a match. Typically, this means that your game presents an interface that shows all the players currently in the
match, with empty slots for positions to be filled. A player can then pick one or more of those empty slots and
issue an invitation to a specific player. To accomplish this, your game needs to be able to send the invitations
and receive notifications when the invitations are processed.

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.

Listing 8-8 Programmatically adding friends to a match

- (void)inviteFriends: (NSArray*) friends

GKMatchRequest *request = [[GKMatchRequest alloc] init];

request.minPlayers = 2;

request.maxPlayers = 4;

request.playersToInvite = friends;

request.inviteMessage = @"Your Custom Invitation Message Here";

request.inviteeResponseHandler = ^(NSString *playerID, GKInviteeResponse


response)

[self updateUIForPlayer: playerID accepted: (response ==


GKInviteeResponseAccepted)];

};

...

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Searching for Nearby Players


The standard user interface allows players to discover other nearby players, even when neither player is currently
connected to Game Center directly. The discovery uses local Wi-Fi or Bluetooth to find other players. This
capability is very useful when players are away from their normal network but still want to play against each
other. You can implement similar behavior in your custom user interface.

Heres how you typically implement this behavior:


1. Provide a button in your user interface to allow the player to search for nearby players. When pressed,
this button presents a new user interface screen that displays any nearby players it finds. Alternatively,
your user interface can simply display nearby players automatically. If you choose this approach, it usually
makes sense to keep this player list separated from the rest of the user interface.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

111
Real-Time Matches
Finding Players for a Match

2. Call the shared matchmakers startBrowsingForNearbyPlayersWithReachableHandler: method,


passing in a block to receive notifications of players as they enter and leave the area. When a player is
found, add the player to your visible list of players. When a player disappears, remove the player.
3. If the player selects one or more players to send an invitation to, create a match request and add the player
identifiers for those players to the match request. Then, follow the behavior described in Inviting Specific
Players to a Match (page 110).
4. When your browsing screen is removed from the screen (either because the player canceled browsing or
because he or she invited players already) call the stopBrowsingForNearbyPlayers method.

Processing Invitations from Other Players


The procedure for receiving invitations from other players is almost identical to the procedure you would
follow when using the standard user interface. You install an invitation handler, but instead of showing the
standard user interface, you show your own custom interface. Your code uses the acceptedInvite and
playersToInvite parameters to determine what kind of invitation was received. See Processing Invitations
from Other Players (page 106).

Finding Player Activity in Your Game


Players who are looking for a multiplayer match often want to be matched immediately, or at least be aware
of when matchmaking may take longer. For example, if a player is online during a period of time when players
are not regularly online, the number of players who are interested in joining a match may be substantially
smaller than during prime time. The determination of how many players are online is referred to as player
activity. The GKMatchmaker class provides a pair of methods you can use to test for the activity on Game
Center related to your game.

Listing 8-9 Searching for all activity for your game on Game Center

- (void)findAllActivity

[[GKMatchmaker sharedMatchmaker] queryActivityWithCompletionHandler:^(NSInteger


activity, NSError *error) {

if (error)

// Process the error.

else

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

112
Real-Time Matches
Exchanging Data Between Match Participants

// Use the activity value to display activity to the player.

}];

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.

Exchanging Data Between Match Participants


After you have created your match, the participants in the match need to exchange data to synchronize the
state of the match between each other. This section describes how to implement and design this part of your
matchmaking code.

Designing Your Network Game


Each participant in the match relies on a GKMatch object to exchange data with the other participants connected
to the match. The GKMatch class does not define the format or content of your network messages. Instead, it
simply sees your messages as bytes to transmit. This gives you great flexibility in designing your network game.
The rest of this section describes key concepts you need to understand before implementing your network
game.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Starting the Match


When Game Kit delivers a GKMatch object to your game, the connections to other participants in the match
may not be established yet. The playerIDs array on that users device can be empty if no other players are
connected, or it might hold a subset of players that have already been connected. Your game must wait until
all players are connected before starting the match. To determine how many players are waiting to join the
match, your game reads the matchs expectedPlayerCount property. When the value of this property
reaches 0, all players are connected and the match is ready to start.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Listing 8-10 Starting a match

- (void)match:(GKMatch *)match player:(NSString *)playerID


didChangeState:(GKPlayerConnectionState)state

switch (state)

case GKPlayerStateConnected:

// Handle a new player connection.

break;

case GKPlayerStateDisconnected:

// A player just disconnected.

break;

if (!self.matchStarted && match.expectedPlayerCount == 0)

self.matchStarted = YES;

// Handle initial match negotiation.

Determining the Best Server


If you are implementing a client-server architecture on top of the peer-to-peer model provided by the match
object, choosing the right server is critical to achieving good network performance and latency in the resulting
match. For this reason, Game Kit provides built-in support that allows all the peers in the game to test each
other to determine the best server. You implement this by calling the
chooseBestHostPlayerWithCompletionHandler: method. When the operation completes, the player
identifier that is returned is the person whose device would make the best server for your game.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

116
Real-Time Matches
Exchanging Data Between Match Participants

Sending Data to Other Players


To send data from one device to other devices connected to the match, your game creates a message and
encapsulates it in an NSData object. You send this message to all connected players using the
sendDataToAllPlayers:withDataMode:error: method, or to a subset of the players using the
sendData:toPlayers:withDataMode:error: method.

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.

Listing 8-11 Sending a position to all players

- (void) sendPosition
{

NSError *error;

PositionPacket msg;

msg.messageKind = PositionMessage;

msg.x = currentPosition.x;

msg.y = currentPosition.y;

NSData *packet = [NSData dataWithBytes:&msg length:sizeof(PositionPacket)];

[match sendDataToAllPlayers: packet withDataMode: GKMatchSendDataUnreliable


error:&error];

if (error != nil)

// Handle the error.

When the method returns without reporting an error, the message has been queued and will be sent when
the network is available.

Receiving Data from Other Players


When the match receives data sent by another participant, the message is delivered by calling your match
delegates match:didReceiveData:fromPlayer: method. Your implementation of this method needs to
decode the message and act on its contents.

- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString


*)playerID

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

117
Real-Time Matches
Adding Voice Chat to a Match

Packet *p = (Packet*)[data bytes];

if (p.messageKind == PositionMessage)

// Handle a position message.

Disconnecting from a Match


When a player is ready to leave a match, your game calls the match objects disconnect method. A player
may also be automatically disconnected if their device does not respond for a certain period of time. When a
player disconnects from the match, the other participants in the match are notified by calling the match
delegates match:player:didChangeState: method.

Adding Voice Chat to a Match


Game Kit provides all of the low-level voice encoding and transmission so that you do not have to handle this
yourself. However, any game that supports voice chat should provide its own custom user interface that allows
players to configure the voice chat. This means that a player should be able to:
Opt-in or out of any voice chat options you provide.
Mute other players as well as control the overall volume of voice chat.
Mute the microphone.
Choose which channel he or she speaks into, if your game supports multiple channels.
See which player is speaking.

Creating an Audio Session (iOS only)


Before your game can use the voice chat services provided by the match object, you must create an audio
session that has the capability to both play and record sounds. If your game provides other sound effects, you
probably already have an audio session. Listing 8-12 shows the code necessary to create an audio session that
allows the microphone to be used.

Listing 8-12 Creating an audio session that can play and record

AVAudioSession *audioSession = [AVAudioSession sharedInstance];

[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:myErr];

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

118
Real-Time Matches
Adding Voice Chat to a Match

[audioSession setActive: YES error: myErr];

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 .

Creating Voice Channels


Your game never directly creates GKVoiceChat objects. Instead, voice chat objects are created on your behalf
by the GKMatch object. A single match can create multiple channels, and a single player can be assigned to
more than one channel at a time. Audio received on any of the channels is mixed together and outputted
through the speakers.

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.

Listing 8-13 Creating voice channels

GKMatch* match;

GKVoiceChat *teamChannel = [[match voiceChatWithName:@"redTeam"] retain];

GKVoiceChat *allChannel = [[match voiceChatWithName:@"allPlayers"] retain];

Starting and Stopping Voice Chat


Voice data is not sent or received through a voice channel until the channel is started. You start a voice chat
by calling the voice chat objects start method:

[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:

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

119
Real-Time Matches
Adding Voice Chat to a Match

The device is on a Wi-Fi network.


There is a microphone connected to the device.

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.

Enabling and Disabling the Microphone


When you want the player to be able to speak, you enable the microphone. Depending on the nature of your
game, you may want to enable the microphone continuously while your game is running, or you may want
to include a push-to-talk button in your interface.

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.

Controlling the Volume of a Voice Chat


Your game can control the volume of a voice chat in two ways. First, your game can set the overall volume
level for the chat by changing the voice chat objects volume property:

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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:

[teamChannel setMute: YES forPlayer: player];

To unmute a player, you make the same call, passing NO instead.

[teamChannel setMute: NO forPlayer: player];

Seeing When a Players State Changes


You can implement an update handler when your game wants to be notified about changes in a players status.
The handler is a block object that the voice chat object calls when a player connects to or disconnects from
the channel and when a player starts and stops speaking. For example, you use the update handler to highlight
a players name in your user interface when that player is speaking.

Listing 8-14 shows an implementation of an update handler for player state.

Listing 8-14 Receiving updates about the player

teamChat.playerStateUpdateHandler = ^(NSString *playerID, GKVoiceChatPlayerState


state) {

switch (state)

case GKVoiceChatPlayerSpeaking:

// Insert code to highlight the player's picture.

break;

case GKVoiceChatPlayerSilent:

// Insert code to dim the player's picture.

break;

};

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Matching Players for a Hosted Match


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

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

Table 9-1 Methods to implement hosted matchmaking

Real-time matchmaking Hosted matchmaking

Your view controller delegate Your delegate implements the


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

Your programmatic matchmaking code Your programmatic code calls


calls findMatchForRequest: findPlayersForHostedMatchRequest:
withCompletionHandler: to create withCompletionHandler: to find a set of new players
a new match. for a match.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

122
Hosted Matches
Hosted Matches Overview

Real-time matchmaking Hosted matchmaking

Your programmatic code calls Your programmatic code calls


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

Your game receives an invitation. The GKInvite 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.

Hosted Matches Overview


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

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

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

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

123
Hosted Matches
Creating a Hosted Match Using the Matchmaker View Controller

Creating a Hosted Match Using the Matchmaker View Controller


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

Listing 9-1 Creating a hosted match

- (IBAction)hostMatch: (id) sender

GKMatchRequest *request = [[GKMatchRequest alloc] init];

request.minPlayers = 2;

request.maxPlayers = 2;

GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc]


initWithMatchRequest:request];

mmvc.matchmakerDelegate = self;

mmvc.hosted = YES;

[self presentViewController:mmvc animated:YES completion:nil];

When the view controller is hosted, your delegate implements the


matchmakerViewController:didReceiveAcceptFromHostedPlayer: method to process the new
player. Your delegate needs to behave differently depending on which device your game is running on:
When called on the players device, the device needs to connect to your own server. When successfully
connected, call the setHostedPlayer:connected: method to tell the view controller that the player
has connected to the match.
When called on another players device, your game needs to determine that it can talk to the new players
device through your server. Once it knows it can send messages to the other client, call the
setHostedPlayer:connected: method to update the user interface.

Dismissing the MatchMaking View Controller


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

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

125
Turn-Based Matches
Checklist for Implementing a Turn-Based Match

When play passes to another player

Checklist for Implementing a Turn-Based Match


To add turn-based support to your game, you write code to handle the following activities:
Allow the local player to join a match. See Joining a New Match (page 132).
Allow the local player to see the list of existing matches. See Working with Existing Matches (page 136).
Allow the local player to view the state of a match in progress. See Working with Match Data (page 138).
Allow the player to take a turn in the match. See Advancing the State of the Match (page 141).
When a player leaves a match, set the players match outcome. See Setting the Match Outcome When a
Participant Leaves a Match (page 141).
When all the players have a match outcome set, end the match. See Ending a Match (page 143).
Handle invitations and other match events. See Responding to Match Notifications (page 143).
Expand your game to include exchanges. See Adding Exchanges to a Turn-Based Match (page 145).

Every Match Has a List of Participants


Think of a turn-based match on Game Center as a board game in the middle of a table. Around the table are
empty seats, waiting to be filled by potential players. The number of players is set when the match is first
created and never changes.

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.

Figure 10-1 Mary starts a new match

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

The Match Data Represents the State of the Match


Your game sends to Game Center match data that describes the state of a match. Game Center sets a limit on
the size of this match data but otherwise does not care about its contents. Your game should store whatever
data is necessary to preserve the match state.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

128
Turn-Based Matches
Your Game Decides the Rules of Play

Your Game Decides the Rules of Play


When you design a turn-based game, you create the rules that dictate play. You decide exactly what actions
a player is allowed to take and when play passes to another player. When play passes to another player, you
decide which player plays next.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Figure 10-3 A turn flowchart for a hypothetical 4X game

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Save the Match Data Whenever Important Events Occur


The current players device can save the data to Game Center immediately whenever any action is taken,
without transferring control to another player. You should save match data whenever anything interesting
happens. Consider the following list as critical places where data should be sent to Game Center:
The action should be immediately visible to other players if those players choose to look at the match.
The action should be irrevocable, such as when the action reveals information previously hidden from the
player or generates a randomized result that needs to be persistent.
The action changes the current player.

Implementing a Turn-Based Match Using Game Kit


To implement turn-based support in your game, you use the classes listed in Table 10-1.

Table 10-1 Classes in Game Kit used to implement turn-based match support

Class Name Class Function

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

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

131
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit

Class Name Class Function

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.

Game Center Imposes Limits on the Match


Table 10-2 describes two of the important limits you need to consider when designing your game. These limits
are subject to change and can both be queried at runtime.

Table 10-2 Important match limits

Item Limit Runtime Access

Number of Players 16 Call the maxPlayersAllowedForMatchOfType: class method of


the GKMatchRequest class.

Size of Match Data 64k Read the matchDataMaximumSize property of the


GKTurnBasedMatch object.

Joining a New Match


For players, a new match begins when the player joins a match. As with other forms of matchmaking, your
game starts the process by creating a GKMatchRequest object, as described in Creating Any Kind of Match
Starts with a Match Request (page 93). A match request does not guarantee that a new match is going to be
created; it may also match the player into an existing match that has an empty position as the current player.

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.

Showing the Standard Matchmaking User Interface


You use a GKTurnBasedMatchmakerViewController object to display the standard user interface. Listing
10-1 shows a typical implementation.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

132
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit

Listing 10-1 Displaying the standard interface to join a turn-based match

- (IBAction)joinChessMatch: (id) sender

GKMatchRequest *request = [[GKMatchRequest alloc] init];

request.minPlayers = 2;

request.maxPlayers = 2;

GKTurnBasedMatchmakerViewController *mmvc = [[GKTurnBasedMatchmakerViewController


alloc] initWithMatchRequest:request];

mmvc.turnBasedMatchmakerDelegate = self;

[self presentViewController:mmvc animated:YES completion:nil];

The presenting view controller in this example implements the


GKTurnBasedMatchmakerViewControllerDelegate pattern. For matchmaking, you need to handle three
of the protocols methods.

The turnBasedMatchmakerViewControllerWasCancelled: delegate method is called when the player


dismisses the matchmaking screen by tapping the Cancel button. In most cases, you should simply return to
the previous screen in your game. A minimal version of this code can be found in Listing 10-2.

Listing 10-2 Implementing the cancellation method

-
(void)turnBasedMatchmakerViewControllerWasCancelled:(GKTurnBasedMatchmakerViewController
*)viewController

[self dismissViewControllerAnimated:YES completion:nil];

The turnBasedMatchmakerViewController:didFailWithError: delegate method is called when


matchmaking encounters an error while trying to find the match. For example, the device may have lost its
network connection. Your implementation should also return to your games previous screen. A minimal version
of this code can be found in Listing 10-3.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

133
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit

Listing 10-3 Implementing the error handling method

- (void)turnBasedMatchmakerViewController:(GKTurnBasedMatchmakerViewController
*)viewController didFailWithError:(NSError *)error

[self dismissViewControllerAnimated:YES completion:nil];

Finally, the turnBasedMatchmakerViewController:didFindMatch: method is called when a match has


been found or created. The match object is returned to your delegate. Typically, your game dismisses the
matchmaker view controller and immediately starts its own user interface to allow the player to play a turn.
The implementation in Listing 10-4 uses a custom segue to show the gameplay screen. The match is passed
as the sender so that it can be passed as an input to the new view controller.

Listing 10-4 Implementing the match found method

- (void)turnBasedMatchmakerViewController:(GKTurnBasedMatchmakerViewController
*)viewController didFindMatch:(GKTurnBasedMatch *)match

[self dismissViewControllerAnimated:YES completion:nil];

[self performSegueWithIdentifier:@"GamePlayScene" sender:match];

- (void )prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

if ([segue.identifier isEqualToString:@"GamePlayScene"])

MyGamePlayViewController* gameVC = (MyGamePlayViewController*)


segue.destinationViewController;

gameVC.delegate = self;

gameVC.match = (GKTurnBasedMatch*) sender;

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

134
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit

Implementing a Custom Match Interface


To create your own custom match interface, you typically use methods on the GKTurnBasedMatch class.
Listing 10-5 shows a trivial implementation of this technique. It creates a new match request and then uses it
to find a new match. (Typically, if your game was implementing a custom match interface, it might set other
properties of the request object, such as the playersToInvite property.) If a match is found, it transitions
to the gameplay screen.

Listing 10-5 Finding a turn-based match programmatically

- (IBAction)findProgrammaticMatch: (id) sender

GKMatchRequest *request = [[GKMatchRequest alloc] init];

request.minPlayers = 4;

request.maxPlayers = 16;

[GKTurnBasedMatch findMatchForRequest: request


withCompletionHandler:^(GKTurnBasedMatch *match, NSError *error)

if (match)

[self performSegueWithIdentifier:@"GamePlayScene" sender: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.

Handling Invitations Programmatically


If a match request includes a list of players to invite, then those players are added to the list of players in the
newly created match. However, invitations are not actually delivered until one of those players becomes the
current player. When that happens, a push notification is sent to the player. The process for handling notifications
is described later in Responding to Match Notifications (page 143). For now, all you need to know is that you
can display your own interface that allows the player to accept or decline the match invitation. You call the
match objects acceptInviteWithCompletionHandler: method to accept the invitation or its
declineInviteWithCompletionHandler: method to decline the invitation.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

135
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit

Working with Existing Matches


If you display the standard matchmaking user interface, then the player sees existing matches as well. The
player can choose an existing match already in progress and perform other common tasks. If the player picks
an existing match, the turnBasedMatchmakerViewController:didFindMatch: method is called, exactly
as it was called when a new match was created. Note that in this case, the player may not be the current player.

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

[GKTurnBasedMatch loadMatchesWithCompletionHandler:^(NSArray *matches, NSError


*error) {

if (matches)

// Use the match data to populate your user interface.

}];

Table 10-3 lists the most common actions a player might want to perform on a match.

Table 10-3 Common actions 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.

Delete a completed match Call the match objects removeWithCompletionHandler: method.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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).

Create a rematch Call the rematchWithCompletionHandler: method on an ended


match.

Retrieving Information About a Match


When a player decides to view a match, your game reads the properties of the match to determine the current
state of the match. Table 10-4 lists the most common properties you need to access.

Table 10-4 Important properties of a match object

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.

status States whether the match is still in progress.

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.

participants An array of GKTurnBasedParticipant objects. The objects in the array


are always stored in the same order. You read the properties of participant
objects to build your user interface. These objects are also used as inputs
to certain methods on the match object. Table 10-5 lists the most common
properties used to implement your game.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

137
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit

Table 10-5 Important properties of a participant object

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.

Working with Match Data


When a match is first created, the match data is empty. But once the match begins and players start taking
turns, your game is expected to provide match data that makes sense for your game. The match data is an
NSData object and its size is limited, so you need to be creative and encode your games data so that it fills
as little space as possible.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

And here are some other general guidelines:


Avoid using the NSCoder class except for the most trivial of games. Although useful for general-purpose
apps, the NSCoder class may not archive data in a compact enough format for your game. You cannot
precisely predict the size of the archive it produces. Instead, you allocate your own block of memory and
perform your own data serialization.
Encode individual items as compactly as needed. For example, in a 16-player game, you can encode the
participant number of the player in 4 bits. Balance the need for compactness with the need for readability
in your code. For example, a chess position could be encoded in as little as 6 bits, but in practice a chess
match does not approach the match data limit.
If your game runs in both OS X and iOS, use network data encoding techniques to avoid byte ordering
problems.

Loading Match Data


When you need to load the match data, you call the match objects
loadMatchDataWithCompletionHandler: method to retrieve the match data. When the completion
handler is called, you receive the match data. After the operation completes, the match objects matchData
property is also updated to point at the same data object.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

139
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit

Listing 10-7 Loading the match data from Game Center

- (void) loadAndDisplayMatchData

[this.myMatch loadMatchDataWithCompletionhandler: ^(NSData *matchData, NSError


*error) {

if (matchData)

// App-specific routine to decode the match data.

this.gameData = [MyMatchDataClass initWithData: matchData];

// Display the match.

}
}];

Saving Match Data


If the player takes an action that is irrevocable (but control is not yet passed to another player), encode the
updated match data and send it to Game Center by calling the
saveCurrentTurnWithMatchData:completionHandler: method.

Listing 10-8 Saving the match data to Game Center

- (void) updateMatchData

// App-specific routine to encode the match data.

NSData *updatedMatchData = [this.gameData encodeMatchData];

[this.myMatch saveCurrentTurnWithMatchData: updatedMatchData completionHandler


^(NSError *error) {

if (error)

// Handle the error.

}];

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

140
Turn-Based Matches
Implementing a Turn-Based Match Using Game Kit

Advancing the State of the Match


Eventually, the current player takes an action that either ends the match or requires another participant to act.
Typically, your game updates the message property of the match object, encodes the match data, and
determines who acts next in the match. Usually, this means encoding the list of all participants in the match
in the order they will act next. The reason you do this is that sometimes players drop from a match without
forfeiting; they just stop playing. You dont want the match to end because it is stuck waiting forever for an
absent player. Instead, you encode the list of participants so that if one participant forfeits a turn, the match
advances to another participant.

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.

Listing 10-9 Advancing to the next participant in a match

- (void) advanceTurn

NSData *updatedMatchData = [this.gameData encodeMatchData];

NSArray *sortedPlayerOrder = [this.gameData encodePlayerOrder];

this.MyMatch.message = [this.gameData matchAppropriateMessage];

[this.myMatch endTurnWithNextParticipants: sortedPlayerOrder turnTimeOut:


GKTurnTimeoutDefault

matchData: updatedMatchData completionHandler ^(NSError *error)


{

if (error)

// Handle the error.

}];

Setting the Match Outcome When a Participant Leaves a Match


As the match progresses, participants may leave the match. For example, your game logic might determine
that a participant has been eliminated from the match.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Responding to Match Notifications


A player can receive notifications about turn-based matches. For example, the most common notification a
player receives is when that player becomes the current player for a match (and is expected to take action). In
all cases, after a player accepts a notification, your game is called to handle the event. It should process the
event and display an appropriate user interface specific to your game.

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

[GKTurnBasedEventHandler sharedTurnBasedEventHandler].delegate = self;

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Table 10-6 Turn-based event handler methods

Event Event Type Event Handler Method

Player receives an invitation Push handleInviteFromGameCenter:

It becomes the players turn Push handleTurnEventForMatch:


didBecomeActive:

A match ended Push handleMatchEnded:

It becomes someone elses turn Foreground handleTurnEventForMatch:


didBecomeActive:

A player updated the match data Foreground handleTurnEventForMatch:


didBecomeActive:

A player receives an exchange Push player: receivedExchangeRequest:


request forMatch:

A player cancels an exchange Push player:


request receivedExchangeCancellation:
forMatch:

All players have responded or timed Push player: receivedExchangeReplies:


out while responding to an forCompletedExchange: forMatch:
exchange

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

144
Turn-Based Matches
Adding Exchanges to a Turn-Based Match

Adding Exchanges to a Turn-Based Match


Add exchanges to your game to expand what your game can do. Exchanges allow players other than the
current player to affect the current turn. Whether through trading items with another player or directly affecting
the current players turn, exchanges provide for greater flexibility in how you design your game.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

145
Turn-Based Matches
Adding Exchanges to a Turn-Based Match

Sending an Exchange Request


Depending on how you design your game, any player can initiate an exchange request, whether they are the
current player or not. For example, during Marys turn, Fred decides that he wants to trade cards with Kelly.
Fred chooses the cards he wants to trade to Kelly and what he wants in return. He then sends the exchange
request to Kelly. After the request is sent, an update is sent to Mary so that the match can be updated. See
Figure 10-5 .

Figure 10-5 Initializing a trade through an exchange

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

146
Turn-Based Matches
Adding Exchanges to a Turn-Based Match

Listing Sending an exchange request to another player


10-10

- (void) exchangeRequest (GKTurnBasedParticipant receiver)

NSArray *recipients = @[receiver];

[self sendExchangeToParticipants:recipients data:data localizableMessageKey:key


arguments:arguments timeout:timeout completionHandler:^(GKTurnBasedExchange
*exchange, NSError *error) {

// refresh your match data

}];

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.

Listing Canceling an exchange request


10-11

-(void)player:(GKPlayer *)player exchangeCanceled:(GKTurnBasedExchange *)exchange


match:(GKTurnBasedMatch *)match

// update your match data to show the canceled request

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

147
Turn-Based Matches
Adding Exchanges to a Turn-Based Match

Responding to an Exchange Request


After an exchange request is created, the players in the recipients array receive a push notification. Opening
the game will present the exchange message. The recipient can choose to respond to the exchange request
or let it time out. Figure 10-6 shows Kelly accepting Freds trade and responding to his exchange request. After
the exchange is completed, the exchange result is sent to the current player. The exchange is reconciled at
the end of the current players turn.

Figure 10-6 Accepting a trade through an exchange

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.

Listing Replying to an exchange request


10-12

-(void) replyToExchange

[self replyWithLocalizableMessageKey:key arguments:arguments data:data


completionHandler:^(NSError *error) {

// refresh your match data

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

148
Turn-Based Matches
Adding Exchanges to a Turn-Based Match

Resolving an Exchange Request


All completed exchanges must be resolved before the local players turn is completed. Resolve completed
exchanges by calling saveMergedMatchData:withResolvedExchanges:completionHandler: before
calling endTurnWithNextParticipants:turnTimeout:matchData:completionHandler: when ending
a players turn.

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.

Listing Resolving completed exchanges before ending a turn


10-13

- (void) advanceTurn

NSData *updatedMatchData = [this.gameData encodeMatchData];

NSArray *sortedPlayerOrder = [this.gameData encodePlayerOrder];

NSArray *exchangesToResolve = [this.gameData retrieveCompletedExchanges];

[this.myMatch saveMergedMatchData: updatedMatchData withResolvedExchanges:


exchangesToResolve

completionHandler ^(NSError *error) {

if (error)
{

// Handle the error.

} else {

this.MyMatch.message = [this.gameData matchAppropriateMessage];

[this.myMatch endTurnWithNextParticipants: sortedPlayerOrder


turnTimeOut: GKTurnTimeoutDefault

matchData: updatedMatchData completionHandler ^(NSError


*error) {

if (error)

// Handle the error.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

149
Turn-Based Matches
Adding Exchanges to a Turn-Based Match

}];

};

}];

Failing to resolve completed exchanges before ending the turn returns an error.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Testing a Game Center-Aware Game


As a developer, you are required to create a separate Game Center account for testing. At any given time, you
must choose whether to log in to a development environment for testing, or in to the live environment. Start
by launching the Game Center app and signing out the currently authenticated player. After this, run your
game or another Game Center-enabled game. Depending on how that app is distributed, you enter different
credentials. If that app is provisioned for development, enter your test account information (signing you in to
the development environment). Otherwise, enter your live account information (signing you in to the live
environment. Table 11-1 shows which builds run in which environments.

Important: Always create new test accounts to test your game in Game Center. Never use an existing
Apple ID.

Table 11-1 Different kinds of app builds

Build Audience Game Center Environment

Simulator build Developer Development environment

Developer build Developer Development environment

Ad hoc distribution build Beta testers Development environment

Signed Distribution build End users Live environment

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

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.

Testing Your Game in iOS Simulator


Leaderboards and achievements work the same way in iOS Simulator as they do on a device. However,
matchmaking invitations may not be sent or received while your game is running in iOS Simulator.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

152
Document Revision History

This table describes the changes to Game Center Programming Guide .

Date Notes

2013-10-22 Added information on resolving turn-based exchanges.

2013-09-18 Added information about leaderboard sets and exchanges.

2012-09-19 Renamed to Game Center Programming Guide. Removed chapters not


related to Game Center apps. Updated to include features added in iOS
5 and iOS 6. Also updated to include OS X support.

2012-07-17 Added to the OS X Developer Library

2011-03-08 Revised the process for authenticating the local player. Clarified many
aspects of Game Center usage.

2010-10-25 Clarified the requirements for performing server-based matchmaking.


Improved the guidelines implementing voice chat in a Game Center
application.

2010-08-27 Updated to add Game Center classes.

2009-05-28 Revised to include more conceptual material.

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.

2013-10-22 | Copyright 2013 Apple Inc. All Rights Reserved.

153
Apple Inc.
Copyright 2013 Apple Inc.
All rights reserved.

No part of this publication may be reproduced,


stored in a retrieval system, or transmitted, in any
form or by any means, mechanical, electronic,
photocopying, recording, or otherwise, without
prior written permission of Apple Inc., with the
following exceptions: Any person is hereby
authorized to store documentation on a single
computer for personal use only and to print
copies of documentation for personal use
provided that the documentation contains
Apples copyright notice.
No licenses, express or implied, are granted with
respect to any of the technology described in this
document. Apple retains all intellectual property
rights associated with the technology described
in this document. This document is intended to
assist application developers to develop
applications only for Apple-labeled computers.
Apple Inc.
1 Infinite Loop
Cupertino, CA 95014
408-996-1010

Apple, the Apple logo, Cocoa, iTunes, Mac, OS X,


and Xcode are trademarks of Apple Inc.,
registered in the U.S. and other countries.
iCloud is a service mark of Apple Inc., registered
in the U.S. and other countries.
App Store is a service mark of Apple Inc.
iOS is a trademark or registered trademark of
Cisco in the U.S. and other countries and is used
under license.
Even though Apple has reviewed this document,
APPLE MAKES NO WARRANTY OR REPRESENTATION,
EITHER EXPRESS OR IMPLIED, WITH RESPECT TO THIS
DOCUMENT, ITS QUALITY, ACCURACY,
MERCHANTABILITY, OR FITNESS FOR A PARTICULAR
PURPOSE. AS A RESULT, THIS DOCUMENT IS PROVIDED
AS IS, AND YOU, THE READER, ARE ASSUMING THE
ENTIRE RISK AS TO ITS QUALITY AND ACCURACY.
IN NO EVENT WILL APPLE BE LIABLE FOR DIRECT,
INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES RESULTING FROM ANY DEFECT OR
INACCURACY IN THIS DOCUMENT, even if advised of
the possibility of such damages.
THE WARRANTY AND REMEDIES SET FORTH ABOVE
ARE EXCLUSIVE AND IN LIEU OF ALL OTHERS, ORAL
OR WRITTEN, EXPRESS OR IMPLIED. No Apple dealer,
agent, or employee is authorized to make any
modification, extension, or addition to this warranty.
Some states do not allow the exclusion or limitation
of implied warranties or liability for incidental or
consequential damages, so the above limitation or
exclusion may not apply to you. This warranty gives
you specific legal rights, and you may also have other
rights which vary from state to state.

You might also like