EOS Integration KitAlpha
v5.0.1

Leaderboards

Display global and friend rankings with EOS leaderboard integration

Leaderboards compare player progression. In EOS, leaderboards are tied to statistics and automatically update when stat values change.

Leaderboards require setup in the EOS Developer Portal. Create leaderboards and link them to stats before using the API.

You cannot directly write to leaderboards. All updates flow through the linked statistic.

Portal Setup

  1. Go to the EOS Developer Portal
  2. Navigate to Game ServicesLeaderboards
  3. Click + New Leaderboard
  4. Configure the leaderboard:
FieldDescription
Leaderboard NameUnique identifier (UPPERCASE, no spaces)
Stat NameThe stat that drives rankings
AggregationHow scores combine (Sum, Max, Min, Latest)
TimespanNever Expire, Daily, Weekly, Monthly, or custom

Set Timespan to "Never Expire" for all-time leaderboards, or use time-based spans for seasonal competitions.

Read Around Rank

Get leaderboard entries centered around a specific rank. Use rank 1 to get the global top players.

Read Leaderboard Around Rank node
Copy and paste into Unreal Engine Blueprint editor
  • Leaderboard Id: The leaderboard name from portal
  • Rank: Center rank (1 for top of leaderboard)
  • Limit: Maximum entries to return
#include "EIKCore/Public/Interfaces/IEIKLeaderboards.h"

void UMyClass::ReadTopPlayers()
{
    TSharedPtr<IEIKLeaderboards> Leaderboards = GetLeaderboardsInterface();
    if (!Leaderboards.IsValid()) return;

    FEIKReadLeaderboardAroundRankParams Params;
    Params.LeaderboardId = TEXT("HIGH_SCORES");
    Params.Rank = 1;  // Start from top
    Params.Limit = 10;

    Leaderboards->ReadEntriesAroundRank(0, Params,
        FEIKAsyncCallback<FEIKLeaderboardResult>::CreateLambda(
            [](const TEIKAsyncResult<FEIKLeaderboardResult>& Result)
            {
                if (Result.IsSuccessful())
                {
                    for (const FEIKLeaderboardEntry& Entry : Result.GetValue().Entries)
                    {
                        UE_LOG(LogTemp, Log, TEXT("#%d %s: %lld"),
                            Entry.Rank, *Entry.DisplayName, Entry.Score);
                    }
                }
            }));
}
#include "Online/OnlineServices.h"
#include "Online/Leaderboards.h"

using namespace UE::Online;

void UMyClass::ReadTopPlayers()
{
    IOnlineServicesPtr Services = GetServices(EOnlineServices::Epic);
    ILeaderboardsPtr Leaderboards = Services->GetLeaderboardsInterface();

    FReadEntriesAroundRank::Params Params;
    Params.LocalAccountId = GetLocalAccountId();
    Params.BoardName = TEXT("HIGH_SCORES");
    Params.Rank = 1;
    Params.Limit = 10;

    Leaderboards->ReadEntriesAroundRank(MoveTemp(Params))
        .OnComplete([](const TOnlineResult<FReadEntriesAroundRank>& Result)
        {
            if (Result.IsOk())
            {
                for (const FLeaderboardEntry& Entry : Result.GetOkValue().Entries)
                {
                    UE_LOG(LogTemp, Log, TEXT("#%d: %lld"),
                        Entry.Rank, Entry.Score);
                }
            }
        });
}
#include "OnlineSubsystem.h"
#include "Interfaces/OnlineLeaderboardInterface.h"

void UMyClass::ReadTopPlayers()
{
    IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get(FName(TEXT("EIK")));
    IOnlineLeaderboardsPtr Leaderboards = OnlineSub->GetLeaderboardInterface();

    FOnlineLeaderboardReadRef ReadObject = MakeShared<FOnlineLeaderboardRead>();
    ReadObject->LeaderboardName = FName(TEXT("HIGH_SCORES"));

    Leaderboards->ReadLeaderboardsAroundRank(1, 10, ReadObject);

    Leaderboards->AddOnLeaderboardReadCompleteDelegate_Handle(
        FOnLeaderboardReadCompleteDelegate::CreateLambda(
            [ReadObject](bool bWasSuccessful)
            {
                if (bWasSuccessful)
                {
                    for (const FOnlineStatsRow& Row : ReadObject->Rows)
                    {
                        UE_LOG(LogTemp, Log, TEXT("#%d %s"),
                            Row.Rank, *Row.NickName);
                    }
                }
            }));
}

Read Around User

Get leaderboard entries centered around a specific player's rank. Shows the player's position relative to nearby competitors.

Read Leaderboard Around User node
Copy and paste into Unreal Engine Blueprint editor
  • Leaderboard Id: The leaderboard name from portal
  • Target Account Id: User to center around (leave empty for local player)
  • Offset: Positions to shift from user's rank
  • Limit: Maximum entries to return
void UMyClass::ReadAroundLocalPlayer()
{
    TSharedPtr<IEIKLeaderboards> Leaderboards = GetLeaderboardsInterface();

    FEIKReadLeaderboardAroundUserParams Params;
    Params.LeaderboardId = TEXT("HIGH_SCORES");
    // Leave AccountId invalid to use local player
    Params.Offset = 0;
    Params.Limit = 10;

    Leaderboards->ReadEntriesAroundUser(0, Params,
        FEIKAsyncCallback<FEIKLeaderboardResult>::CreateLambda(
            [](const TEIKAsyncResult<FEIKLeaderboardResult>& Result)
            {
                if (Result.IsSuccessful())
                {
                    for (const FEIKLeaderboardEntry& Entry : Result.GetValue().Entries)
                    {
                        UE_LOG(LogTemp, Log, TEXT("#%d %s: %lld"),
                            Entry.Rank, *Entry.DisplayName, Entry.Score);
                    }
                }
            }));
}
void UMyClass::ReadAroundLocalPlayer()
{
    ILeaderboardsPtr Leaderboards = GetLeaderboardsInterface();

    FReadEntriesAroundUser::Params Params;
    Params.LocalAccountId = GetLocalAccountId();
    Params.AccountId = GetLocalAccountId();
    Params.BoardName = TEXT("HIGH_SCORES");
    Params.Offset = 0;
    Params.Limit = 10;

    Leaderboards->ReadEntriesAroundUser(MoveTemp(Params))
        .OnComplete([](const TOnlineResult<FReadEntriesAroundUser>& Result)
        {
            if (Result.IsOk())
            {
                for (const FLeaderboardEntry& Entry : Result.GetOkValue().Entries)
                {
                    UE_LOG(LogTemp, Log, TEXT("#%d: %lld"),
                        Entry.Rank, Entry.Score);
                }
            }
        });
}
void UMyClass::ReadAroundLocalPlayer()
{
    IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get(FName(TEXT("EIK")));
    IOnlineLeaderboardsPtr Leaderboards = OnlineSub->GetLeaderboardInterface();
    FUniqueNetIdPtr UserId = OnlineSub->GetIdentityInterface()->GetUniquePlayerId(0);

    FOnlineLeaderboardReadRef ReadObject = MakeShared<FOnlineLeaderboardRead>();
    ReadObject->LeaderboardName = FName(TEXT("HIGH_SCORES"));

    Leaderboards->ReadLeaderboardsAroundUser(UserId.ToSharedRef(), 10, ReadObject);

    Leaderboards->AddOnLeaderboardReadCompleteDelegate_Handle(
        FOnLeaderboardReadCompleteDelegate::CreateLambda(
            [ReadObject](bool bWasSuccessful)
            {
                if (bWasSuccessful)
                {
                    for (const FOnlineStatsRow& Row : ReadObject->Rows)
                    {
                        UE_LOG(LogTemp, Log, TEXT("#%d %s"),
                            Row.Rank, *Row.NickName);
                    }
                }
            }));
}

Read For Users

Get leaderboard entries for specific players. Useful for showing friends' scores or comparing with party members.

Read Leaderboard For Users node
Copy and paste into Unreal Engine Blueprint editor
  • Leaderboard Id: The leaderboard name from portal
  • Account Ids: Array of users to query
void UMyClass::ReadFriendsScores(const TArray<FEIKAccountId>& FriendIds)
{
    TSharedPtr<IEIKLeaderboards> Leaderboards = GetLeaderboardsInterface();

    FEIKReadLeaderboardForUsersParams Params;
    Params.LeaderboardId = TEXT("HIGH_SCORES");
    Params.AccountIds = FriendIds;

    Leaderboards->ReadEntriesForUsers(0, Params,
        FEIKAsyncCallback<FEIKLeaderboardResult>::CreateLambda(
            [](const TEIKAsyncResult<FEIKLeaderboardResult>& Result)
            {
                if (Result.IsSuccessful())
                {
                    for (const FEIKLeaderboardEntry& Entry : Result.GetValue().Entries)
                    {
                        UE_LOG(LogTemp, Log, TEXT("%s: #%d with %lld"),
                            *Entry.DisplayName, Entry.Rank, Entry.Score);
                    }
                }
            }));
}
void UMyClass::ReadFriendsScores(const TArray<FAccountId>& FriendIds)
{
    ILeaderboardsPtr Leaderboards = GetLeaderboardsInterface();

    FReadEntriesForUsers::Params Params;
    Params.LocalAccountId = GetLocalAccountId();
    Params.BoardName = TEXT("HIGH_SCORES");
    Params.AccountIds = FriendIds;

    Leaderboards->ReadEntriesForUsers(MoveTemp(Params))
        .OnComplete([](const TOnlineResult<FReadEntriesForUsers>& Result)
        {
            if (Result.IsOk())
            {
                for (const FLeaderboardEntry& Entry : Result.GetOkValue().Entries)
                {
                    UE_LOG(LogTemp, Log, TEXT("#%d: %lld"),
                        Entry.Rank, Entry.Score);
                }
            }
        });
}
void UMyClass::ReadFriendsScores(const TArray<FUniqueNetIdRef>& FriendIds)
{
    IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get(FName(TEXT("EIK")));
    IOnlineLeaderboardsPtr Leaderboards = OnlineSub->GetLeaderboardInterface();

    FOnlineLeaderboardReadRef ReadObject = MakeShared<FOnlineLeaderboardRead>();
    ReadObject->LeaderboardName = FName(TEXT("HIGH_SCORES"));

    Leaderboards->ReadLeaderboards(FriendIds, ReadObject);

    Leaderboards->AddOnLeaderboardReadCompleteDelegate_Handle(
        FOnLeaderboardReadCompleteDelegate::CreateLambda(
            [ReadObject](bool bWasSuccessful)
            {
                if (bWasSuccessful)
                {
                    for (const FOnlineStatsRow& Row : ReadObject->Rows)
                    {
                        UE_LOG(LogTemp, Log, TEXT("#%d %s"),
                            Row.Rank, *Row.NickName);
                    }
                }
            }));
}

On this page