Leaderboards

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

Leaderboards Require a Scoring Mechanism

To build leaderboards into a game, that game needs to have a gameplay mechanism that allows your game to end and a final score calculated. That is, your game does not have open-ended gameplay. You are free to design your gameplay and scoring mechanism however you want. The only restriction is that your scoring mechanism should 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 kind of score is stored in the leaderboard and how to convert it 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 game’s scores.

The most critical decision to make is what kind of score is stored in the leaderboard. Game Center provides three basic formatting types:

You also decide the order in which scores are ranked. When scores are ranked low-to-high, a lower score is considered a better score. For example, a racing game might want to record the time it took to complete the race. In this circumstance, a faster time—that is, a lower score—is better, so a sorting order of low-to-high is appropriate. In contrast, a game that adds points to the player’s total for each successful action taken in the game expects a higher score is better, so a high-to-low sorting 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, consider also the range of possible (legal) score values. When you create the leaderboard description, you may also provide minimum and maximum values for scores reported to it. Providing a score range adds an layer of security onto your leaderboard, because it reduces the likelihood that a player can discover a way to report an absurdly high score.

A Game Can Have Multiple Leaderboards

You can define up to 25 different leaderboards for a game (or game group). 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 might use different leaderboards in your game:

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. If 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 might 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.

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. Those leaderboards continue to exist and are where you report scores to. For example, if your game offered multiple race tracks, you might 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:

Working with Leaderboards in iTunes Connect

After you’ve 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. It’s important to note that the information you enter into iTunes Connect must match your game’s 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 game’s leaderboards 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 Reference Name

An internal name for your leaderboard, used only in iTunes Connect. This is the 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.

Score Format Type

Choose the type of format in which you want scores to be expressed in the leaderboard—for 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 can’t 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 (Singular)

This suffix is added to the end of scores displayed in the singular form. This suffix is optional, and is useful for clarifying the type of score stored in the leaderboard. Examples include “point”, or “ hit.”

Score Format Suffix (Plural)

This suffix is added to the end of scores displayed in the plural form. This suffix is optional, and is useful for clarifying the type of score stored in the leaderboard. Examples include “ points”, “ coins”, or “ 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”.

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.

GKGameCenterViewController

The GKGameCenterViewController class provides a standard user interface to display Game Center content to the player. This content includes a leaderboard page.

GKLeaderboardViewController

The GKLeaderboardViewController class provides a standard user 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 Game’s 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;
     }];
}

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.

title

The localized title you defined in iTunes Connect.

groupIdentifier

If your game is sharing this leaderboard with other games in a game group, this property holds the group identifier for the group.

Loading Information About Your Game’s Leaderboards (iOS 5, OS X 10.8)

If your game needs to run on earlier versions of iOS or OS X, you use the code in Listing 4-2 to retrieve the category and title information for all of the leaderboards in your game.

Listing 4-2  Retrieving categories and titles

- (void) loadCategoriesAndTitles
{
    [GKLeaderboard loadCategoriesWithCompletionHandler:^(NSArray *categories, NSArray *titles, NSError *error) {
        self.leaderboardCategories = categories;
        self.leaderboardTitles = titles;
     }];
}

Reporting Scores to Game Center

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.

Table 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

- (void) reportScore: (int64_t) score forLeaderboardID: (NSString*) category
{
    GKScore *scoreReporter = [[GKScore alloc] initWithCategory:category];
    scoreReporter.value = score;
    scoreReporter.context = 0;
 
    [scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
// Do something interesting here.
    }];
}

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 game’s preferences and saved games in a secure format, rather than in clear text. If your game’s data is stored in clear text, a player can download the save game data using iTunes, modify it, and resync it back to the device. This may allow the player to score a higher score than you intended.

  • Always set reasonable minimum and maximum values for a leaderboard.

Working with the Default Leaderboard

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

[[GKLocalPlayer localPlayer] loadDefaultLeaderboardCategoryIDWithCompletionHandler:
((^)(NSString *categoryID, NSError *error) {
// Use the category ID.
}

The most common place 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 object’s category becomes the new default leaderboard ID.

Listing 4-5  Updating the default leaderboard when reporting a score

    GKScore *scoreReporter = [[GKScore alloc] initWithCategory:category];
    scoreReporter.shouldSetDefaultLeaderboard = YES
...

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

Listing 4-6  Updating the default leaderboard directly

[[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-7 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 leaderboard page, displaying only scores earned in the last day. The view controller is then presented. On OS X, you use the GKDialogController to display the view controller, as described in “Displaying Game Center User Interface Elements.”

Listing 4-7  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-8 shows a typical implementation, which simply dismisses the presented view controller.

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

- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

Displaying the Standard Leaderboard (iOS 5, OS X 10.8)

If the GKGameCenterViewController class is not available, you use a leaderboard view controller to display leaderboard content. Listing 4-9 shows how to display a specific leaderboard’s scores earned in the last day.

Listing 4-9  Displaying the default leaderboard

- (void) showLeaderboard: (NSString*) leaderboardID
{
    GKLeaderboardViewController *leaderboardController = [[GKLeaderboardViewController alloc] init];
    if (leaderboardController != nil)
    {
        leaderboardController.leaderboardDelegate = self;
        leaderboardController.timeScope = GKLeaderboardTimeScopeToday;
        leaderboardController.category = leaderboardID;
        [self presentViewController: leaderboardController animated: YES completion:nil];
    }
}

When the user dismisses the leaderboard, the delegate’s leaderboardViewControllerDidFinish: method is called. Listing 4-10 shows how your view controller should dismiss the leaderboard.

Listing 4-10  Responding when the player dismisses the leaderboard content

- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

You may want to save the leaderboard view controller’s category and timeScope properties before disposing of the leaderboard view controller. These properties hold the values of the last selections the player chose while viewing the leaderboards. You can then use those same values to initialize the leaderboard view controller the next time the player wants to see the leaderboard.

Retrieving Score Data

In some cases, you may 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.

Table 4-5  Properties that affect the leaderboard data query

Property

Effect

playerScope

You can choose whether to restrict the search to the local player’s 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.

range

You can pick scores within a specific range. For example, the range [1,10] returns the best ten scores found by the query.

The query to the 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 category properties.

  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.

Figure 4-1 shows an example of one possible search. The code that performs this search is provided later in Listing 4-11. 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

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 10 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.category = @"Combined.LandMaps"
        leaderboardRequest.range = NSMakeRange(1,10);
        [leaderboardRequest loadScoresWithCompletionHandler: ^(NSArray *scores, NSError *error) {
            if (error != nil)
            {
                // 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 IDs 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.category = @"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.
            }
        }];
    }
}

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 object’s playerID to load the player’s alias, as described in “Retrieving Information about Players.” The formattedValue property provides a string with the score value formatted according to the parameters you provided in iTunes Connect.

To maintain an optimal user experience, your game should only query the leaderboard for data it 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 doesn’t 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, you might use the flags to store what kind of car the person completed the track with. Then, in your own custom leaderboard user interface, you could display the appropriate car image next to each score.

  • You could record the user’s actions and other data into 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.

  • You could implement the replay directly into your gameplay. For example, in the hypothetical racing game, you use a player’s replay file to display a phantom car for the current player to race against.


Did this document help you? Yes It's good, but... Not helpful...