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 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.
  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.
  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.
  4. Add code to report scores to Game Center. See Reporting Scores to Game Center.
  5. Optionally, you can retrieve score data from Game Center and use it to create your own custom leaderboard user interface. See Retrieving Score Data.

Getting Leaderboards info

Use the class method to retrieve the list of leaderboards you configured on iTunes Connect. 

using SA.IOSNative.GameKit;
...
ISN_GKLeaderboard.LoadLeaderboards((result) => {
    if (result.IsSucceeded) {
        foreach(var leaderboards in result.Leaderboards) {
            Debug.Log(leaderboards.Identifier);
            Debug.Log(leaderboards.GroupIdentifier);
            Debug.Log(leaderboards.Title);
        }
    } else {
        Debug.Log("Load Leaderboards failed! Code: " + result.Error.Code + " Message: " + result.Error.Message);
    }
});

Leaderboards Require a Scoring Mechanism

To include leaderboards into your game, you must 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 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:

  • 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 score—for example, a racing game that records 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 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, as it reduces the likelihood that a player can cheat if they discover a way to report an absurdly high score.

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 leaderboard, 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.

Reporting Scores to Game Center

Your game transmits scores to Game Center by creating an array of ISN_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 method to send the data to Game Center.

The score object is initialized with the leaderboard ID for the leaderboard it reports its score to and then your score reporting 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.

using SA.IOSNative.GameKit;
...
ISN_GKScore scoreReporter= new ISN_GKScore("itunes.leaderboard.id");
scoreReporter.Value = 100;
scoreReporter.Context = 1;

scoreReporter.Report((result) => {
    if (result.IsSucceeded) {
        Debug.Log("Score Report Success");
    } else {
        Debug.Log("Score Report failed! Code: " + result.Error.Code + " Message: " + result.Error.Message);
    }
});

Note: The Context property is stored and returned to your game, but is otherwise ignored by Game Center. It allows your game to associate an arbitrary 64-bit unsigned integer value with the score data reported to Game Center. You decide how this integer value is interpreted by your game. For example, you might use the Context property to store flags that provide game-specific details about a player’s score, or you might use the context as a key to other data stored on the device or on your own server. The context is most useful when your game displays a custom leaderboard user interface.

You may also submit the whole array of scores. see the example below:

using SA.IOSNative.GameKit;
...
ISN_GKScore scoreReporter1 = new ISN_GKScore("itunes.leaderboard.id.1");
scoreReporter1.Value = 100;
scoreReporter1.Context = 1;


ISN_GKScore scoreReporter2 = new ISN_GKScore("itunes.leaderboard.id.2");
scoreReporter2.Value = 100;
scoreReporter2.Context = 1;

var scores = new List<ISN_GKScore>() {scoreReporter1, scoreReporter2};

ISN_GKScore.ReportScores(scores, (result) => {
    if (result.IsSucceeded) {
        Debug.Log("Score Report Success");
    } else {
        Debug.Log("Score Report failed! Code: " + result.Error.Code + " Message: " + result.Error.Message);
    }
});

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

Displaying the Standard Leaderboard

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 ISN_GKGameCenterViewController object. You can adjust the behavior of a Game Center view controller so the initial content it displays is the leaderboard page. Configure the other properties to show the leaderboard page, displaying only scores earned in the last day. You then present the view controller. Display the view controller, as described in Displaying Game Center User Interface Elements

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 ISN_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 ISN_GKLeaderboard object to filter which scores are returned to your game, then tell the object to load the scores.

See the example how to query the leaderboard score:

using SA.IOSNative.GameKit;
using SA.IOSNative.Foundation;
...
var leaderboardRequest = new ISN_GKLeaderboard();
leaderboardRequest.Identifier = "itunes.leaderboard.id";
leaderboardRequest.PlayerScope = ISN_GKLeaderboardPlayerScope.Global;
leaderboardRequest.TimeScope = ISN_GKLeaderboardTimeScope.AllTime;
leaderboardRequest.Range = new ISN_NSRange(1, 10);
leaderboardRequest.LoadScores((result) => {
    if (result.IsSucceeded) {
        Debug.Log("Score Load Success");
        foreach(var score in result.Scores) {
            Debug.Log(score.Value);
            Debug.Log(score.Context);
            Debug.Log(score.Date);
            Debug.Log(score.Rank);
            Debug.Log(score.Player.PlayerID);
            Debug.Log(score.Player.DisplayName);
            Debug.Log(score.Player.Alias);
        }

        Debug.Log(leaderboardRequest.MaxRange);
        Debug.Log(leaderboardRequest.LocalPlayerScore.Value);
        Debug.Log(leaderboardRequest.LocalPlayerScore.Context);
        Debug.Log(leaderboardRequest.LocalPlayerScore.Date);
        Debug.Log(leaderboardRequest.LocalPlayerScore.Rank);
    } else {
        Debug.Log("Score Load failed! Code: " + result.Error.Code + " Message: " + result.Error.Message);
    }
});

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  ISN_GKScoreobject 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, 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 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 can implement the replay directly into your gameplay. For example, in the hypothetical racing game, you could use a player’s replay file to display a phantom car for the current player to race against.