Leaderboards #

Global and regional leaderboards are used in Blocks and Cities by Kyoso Interactive.
Global and regional leaderboards are used in Blocks and Cities by Kyoso Interactive.

Leaderboards are a common feature in games to provide engagement and competitiveness among your player base, and Nakama provides a feature-rich implementation of leaderboards. The Hiro wraps the features and functionality of the Nakama leaderboards system, and adds: built-in support for regional leaderboards, identified by their ISO Code, convenient display for friends leaderboards (using Nakama’s Friends feature), and a convenient way to fan-out score updates to multiple leaderboards.

Customization parameters #

The following JSON represents the customization parameters you can use to configure the default user experience for the leaderboard system.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
{
  "events": {
    "leaderboard_id1": {
      "name": "Chef Tournament",
      "description": "Play a tournament against other chefs for great rewards!",
      "operator": "set",
      "sort": "desc",
      "start_time": 0,
      "end_time": 0,
      "reset": "0 0 */3 * *", // At 12:00 AM, every 3 days.
      "score_target": 0,
      "max_reroll_count": 0,
      "bucket_size": 50,
      "resource_id": "",
      "cost": {
        "currencies": {
          "coins": 0
        }
      },
      "reward_ranges": [
        {
          "rank_start": 1,
          "rank_end": 1,
          "reward": {
            "currencies": {
              "gems": 100
            }
          }
        }
      ],
      "reward_ranges_team": [
        {
          "rank_start": 1,
          "rank_end": 1,
          "reward": {
            "currencies": {
              "gems": 100
            }
          }
        }
      ]
    }
  }
}

The JSON schema defines an events object which must contain an individual object for each leaderboard you wish to define in the system. You can configure as few or as many energy types as needed for your desired gameplay.

Each leaderboard is keyed by id and may define the following:

PropertySubpropertyDescription
nameThe name of this leaderboard.
descriptionThe description of this leaderboard.
operatorThe leaderboard operation (e.g. set, best, incr, or decr).
sortThe leaderboard sort type (e.g. asc or desc).
start_timeThe start time (as a UNIX timestamp) of this leaderboard.
end_timeThe end time (as a UNIX timestamp) of this leaderboard.
resetThe reset schedule of this leaderboard expressed as a CRON expression.
score_targetAn optional score target a user must reach for the leaderboard event to be considered won.
max_reroll_countThe maximum amount of times a user can reroll their score.
bucket_sizeThe size of the bucket of users when using bucketed leaderboards.
resource_idA string hint for the client (e.g. addressable field).
costAn object that defines the entry cost for this leaderboard.
currenciesA string:int dictionary of currencies and quantities the user should receive as a reward.
reward_rangesAn array of objects that define the various rewards available to players based on their final rank in the leaderboard.
rank_startThe first rank included in the reward range.
rank_endThe last rank included in the reward range.
rewardAn object that defines what rewards the players will receive. See schema below for properties.
reward_ranges_teamAn array of objects that define the various rewards available to players who participate in a team based on the team’s final rank in the leaderboard.
rank_startThe first rank included in the reward range.
rank_endThe last rank included in the reward range.
rewardAn object that defines what rewards the players will receive. See schema below for properties.

The rewards properties above (reward_ranges, reward_ranges_team) have the additional sub-properties:

PropertyDescription
currenciesA string:int dictionary of currencies and quantities the user will receive for the given rank range.

Initializing the leaderboards system #

The leaderboards system relies on the Nakama System which must be passed in as dependency via the constructor. You can also pass an array of leaderboard Ids for which you would like to retrieve the initial leaderboard records for.

1
2
var leaderboardsSystem = new LeaderboardsSystem(nakamaSystem, new [] { "<leaderboardId>" });
systems.Add(leaderboardsSystem);

Subscribing to changes in the leaderboards system #

You can listen for changes in the leaderboards system so that you can respond appropriately, such as updating the UI, by implementing the appropriate interface.

1
2
3
4
5
var disposer = SystemObserver<LeaderboardsSystem>.Create(leaderboardsSystem, system => {
  Instance.Logger.Info($"System updated.");

  // Update UI elements etc as necessary here...
});

Refreshing the leaderboards system #

To ensure the leaderboards system has the latest information from Nakama you can refresh it.

1
await leaderboardsSystem.RefreshAsync();

You can also refresh an individual leaderboard by passing it’s ID and optionally a cursor.

1
await leaderboardsSystem.RefreshAsync("<leaderboardId>", "<optionalCursor>");

Getting leaderboard records #

You can get cached leaderboard records for a specific leaderboard.

1
var records = leaderboardsSystem.GetRecords("<leaderboardId>");

Getting leaderboard records for specific users #

You can get leaderboard records for a specific set of users, by providing either an array of user Ids, a list of friends or a Team (as defined in the TeamNakamaSystem).

For specific users:

1
var records = await leaderboardsSystem.GetRecordsAsync("<leaderboardId>", new[] { "<userId1>", "<userId2>" });

For friends:

1
2
var friendsList = await _nakamaSystem.Client.ListFriendsAsync(_nakamaSystem.Session);
var records = await leaderboardsSystem.GetRecordsAsync("<leaderboardId>", friendsList);

For the user’s team:

1
var records = await leaderboardsSystem.GetRecordsAsync("<leaderboardId", teamSystem);

Getting the user’s own leaderboard record #

You can get the user’s own leaderboard record.

1
var record = leaderboardsSystem.GetRecord("<leaderboardId>");

Submitting a leaderboard score #

You can submit a leaderboard score for the user.

1
2
3
4
5
var score = 100;
var subscore = 10;
var metadata = "<metadataJson>";

var record = await leaderboardsSystem.WriteScore("<leaderboardId>", score, subscore, metadata);