Skip to content

Leaderboards

The purpose of this feature is to allow the player to see the Leaderboard.

Leaderboards provide competitive ranking systems that encourage player engagement and retention by displaying player performance relative to others.

Leaderboards API

Submiting Score

Here is a snippet from the sample LeaderboardFlowInterpolationExample.cs:

 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
private async void SetupBeamable()
{
    _beamContext = BeamContext.Default;
    await _beamContext.OnReady;
    Debug.Log($"_beamContext.PlayerId = {_beamContext.PlayerId}");

    LeaderboardContent leaderboardContent = 
    await _leaderboardMainMenuCustom.LeaderboardBehavior.Leaderboard.Resolve();

    Debug.Log($"PopulateLeaderboard Starting. Wait < 30 seconds... ");
    int leaderboardRowCountMin = 10;
    int leaderboardScoreMin = 99;
    int leaderboardScoreMax = 99999;

    // Populate with custom values 
    Dictionary<string, object> leaderboardStats = new Dictionary<string, object>();
    leaderboardStats.Add("leaderboard_score_timestamp", new 
    DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds());
    leaderboardStats.Add("leaderboard_score_velocity", 99); // 99 score delta per second

    // Populates mock "alias" and "score" for each leaderboard row
    string loggingResult = await MockDataCreator.PopulateLeaderboardWithMockData(
    _beamContext, 
    leaderboardContent,
    leaderboardRowCountMin,
    leaderboardScoreMin,
    leaderboardScoreMax,
    leaderboardStats);

    Debug.Log($"PopulateLeaderboard Finish. Result = {loggingResult}");
}

Rendering Score

Here is a snippet from the sample LeaderboardItemCustom.cs:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public void Update()
{
    // Prepare value
    long scoreTimestamp = long.Parse(_rankEntry.GetStat("leaderboard_score_timestamp"));
    long scoreVelocity = long.Parse(_rankEntry.GetStat("leaderboard_score_velocity"));
    long currentTimestamp = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();
    long millisecondsSinceSubmission = currentTimestamp - scoreTimestamp;
    long scoreSinceSubmission = (millisecondsSinceSubmission * scoreVelocity) / 1000;

    // Render value
    double score = _rankEntry.score + scoreSinceSubmission;
    TxtScore.text = $"{score:00000}";
}

Getting Board

When calling either GetBoard or GetAssignedBoard, the parameters share the following semantics:

Parameter Description
leaderBoard/boardId The board whose subset of rank entries you want to retrieve.
• For the partitioned case (GetAssignedBoard), it'll always return you the partition containing the requesting/authenticated user.
from Is the first "rank" you want to retrieve. This parameter is ignored if a focus is given.
• If this value is greater than the lowest rank, you'll get no RankEntries back: if there are 10 entries in the board and you pass in from=15, you'll get an empty array of RankEntries in your LeaderBoardView.
max Is the number of ranks, starting from from, and moving towards the lowest rank that you want to retrieve.
• As in, if from=20 and max=10, you'll get ranks [20~30].
• If there are not enough entries to fill this amount, the search is truncated.
focus is a User's PlayerId that'll be used as the middle RankEntry of the resulting LeaderBoardView.
• Takes max/2 ranks above the focus and max/2 ranks from below the focus.
• It is inclusive. As in, if focus is at rank 50 and you pass in max=10, you should see [40~61].
• If there are not enough entries in the leaderboard either above or below you, the corresponding max/2 will be truncated.
outlier A GamerTag whose RankEntry is guaranteed to be included. When this is passed in, the resulting entry is stored in LeaderBoardView.rankgt.

Here is a snippet from LeaderboardServiceExample.cs:

 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
private async Task<List<RankEntry>> LeaderboardServiceGetBoard(string id, long userId)
{
    LeaderBoardView leaderBoardView = await _beamContext.Api.LeaderboardService.GetBoard(id, 0, 100, 
    userId);

    foreach (RankEntry rankEntry in leaderBoardView.rankings)
    {
        // Get alias for userId of rankEntry
        long nextUserId = rankEntry.gt;
        var stats = 
                await _beamContext.Api.StatsService.GetStats("client", "public", "player", nextUserId );

        string alias = "";
        stats.TryGetValue(alias, out alias);
        if (string.IsNullOrEmpty(alias))
        {
            alias = "Unknown Alias";
        }

        // Log
        Debug.Log($"Rank = {rankEntry.rank}, Alias = {alias}, Score = {rankEntry.score}");
    }

    return leaderBoardView.rankings;
}

WebGL Sample

You can try out this feature in the interactive WebGL demo: Unity WebGL Player - Leaderboard Flow Example