Skip to main content

Retrieving leaderboards

You can fetch global and user leaderboards using the leaderboards interface. Please note that Epic Online Services does not support globally ranking arbitrary lists of users (such as friends).

info

It can take up to 24 hours for a global leaderboard to start ingesting stats after you create it in the Epic Online Services developer portal. You won't see leaderboard results for global leaderboards until they've started ingesting stats.

Querying global leaderboards (by ranked range)

To query a range of entries from a global leaderboard, get the leaderboard interface and create the FOnlineLeaderboardRead object:

#include "OnlineSubsystem.h"
#include "OnlineSubsystemUtils.h"
#include "Interfaces/OnlineLeaderboardInterface.h"

// ...

IOnlineSubsystem *Subsystem = Online::GetSubsystem(WorldContextObject->GetWorld());
IOnlineIdentityPtr Identity = Subsystem->GetIdentityInterface();
IOnlineLeaderboardsPtr LeaderboardsInterface = Subsystem->GetLeaderboardsInterface();

// Create the read object, which will contain the results when the operation completes.
// The LeaderboardId should match the leaderboard name in the developer portal.
FOnlineLeaderboardReadRef ReadRef = MakeShared<FOnlineLeaderboardRead, ESPMode::ThreadSafe>();
ReadRef->LeaderboardName = FName(LeaderboardId);

Register the event handler to handle the result. It's recommended that you pass the read object to the handler when registering it, as the callback parameters do not include it. QueryLeaderboardsDelegateHandle is declared as an FDelegateHandle.

this->QueryLeaderboardsDelegateHandle = LeaderboardsInterface->AddOnLeaderboardReadCompleteDelegate_Handle(
FOnLeaderboardReadComplete::FDelegate::CreateUObject(
this,
&UMyClass::HandleLeaderboardResult,
ReadRef));

Then call ReadLeaderboardsAroundRank.

caution

You can't have multiple ReadLeaderboardsAroundRank operations running at the same time. If you try to call ReadLeaderboardsAroundRank while there is still another call running, you'll receive an error.

This is a limitation of the EOS SDK, which doesn't support concurrent global leaderboard queries.

if (!LeaderboardsInterface->ReadLeaderboardsAroundRank(
0, // The rank to target.
100, // The inclusive range around the rank.
ReadRef))
{
// The call failed.

// Remove the event handler.
LeaderboardsInterface->ClearOnLeaderboardReadCompleteDelegate_Handle(this->QueryLeaderboardsDelegateHandle);
this->QueryLeaderboardsDelegateHandle.Reset();
}

When your callback fires, you'll want to handle any errors (check bWasSuccessful), and then deregister the event handler:

void UMyClass::HandleLeaderboardResult(
const bool bWasSuccessful,
FOnlineLeaderboardReadRef LeaderboardRef)
{
// Remove the event handler.
IOnlineSubsystem *Subsystem = Online::GetSubsystem(WorldContextObject->GetWorld());
IOnlineLeaderboardsPtr LeaderboardsInterface = Subsystem->GetLeaderboardsInterface();
LeaderboardsInterface->ClearOnLeaderboardReadCompleteDelegate_Handle(this->QueryLeaderboardsDelegateHandle);
this->QueryLeaderboardsDelegateHandle.Reset();

if (!bWasSuccessful)
{
// Operation was not successful.
return;
}

for (auto Row : LeaderboardRef->Rows)
{
// Row.PlayerId -> The player ID.
// Row.PlayerNickname -> The player's nickname.
// Row.Rank -> The rank in the global leaderboards.

// Since this is a global leaderboard, the stat that the leaderboard
// is tracking is available in "Score":
int32 Score;
Row.Columns[TEXT("Score")].GetValue(Score);
}
}

Querying friend leaderboards

Similar to querying global leaderboards, get the leaderboards interface and then create the FOnlineLeaderboardRead. However, when querying user leaderboards, you need to specify stat names instead of a leaderboard ID.

FOnlineLeaderboardReadRef ReadRef = MakeShared<FOnlineLeaderboardRead, ESPMode::ThreadSafe>();
ReadRef->ColumnMetadata.Add(FColumnMetaData(FName(TEXT("MyStatName")), EOnlineKeyValuePairDataType::Int32));
ReadRef->SortedColumn = FName(TEXT("TestScore"));

Then call ReadLeaderboardsForFriends:

if (!LeaderboardsInterface->ReadLeaderboardsForFriends(0 /* LocalUserNum */, ReadRef))
{
// Call failed; remove the event handler.
}

When you iterate through the rows in your callback, use the stat name for the column instead of "Score":

for (auto Row : LeaderboardRef->Rows)
{
// Row.PlayerId -> The player ID.
// Row.PlayerNickname -> The player's nickname.
// Row.Rank -> The rank relative to other friends.

// Since this is a user leaderboard, use the stat name as the column name:
int32 Score;
Row.Columns[TEXT("MyStatName")].GetValue(Score);
}

Querying leaderboards for arbitrary users

You can also query a leaderboard from an arbitrary set of users over any stats you have defined. This functions similar to reading friend leaderboards, except that you can use any user IDs that you like.

These queries are set up and handled the same as querying friend leaderboards; the only difference is that you call ReadLeaderboards instead:

TArray<TSharedRef<const FUniqueNetId>> Players;
Players.Add(/* user ID */);
// ... add more player IDs.

if (!LeaderboardsInterface->ReadLeaderboards(0 /* LocalUserNum */, ReadRef))
{
// Call failed; remove the event handler.
}

Unsupported methods

The plugin does not support the ReadLeaderboardsAroundUser call, because this functionality is not available in the EOS SDK itself. If you call ReadLeaderboardsAroundUser, it will return results equivalent to calling ReadLeaderboards with just the single player specified (and a range of 0).