GS2-Ranking SDK for Game Engine API Reference
Model
EzScore
Score
Holds the registered scores for each game player per category. Each score entry is identified by a unique ID and associated with a category and scorer user. In sum mode, new scores are added to the existing total via the AddScore operation rather than creating separate entries. Scores outside the category’s minimum/maximum range are rejected at registration.
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| categoryName | string | ✓ | ~ 128 chars | Category Name | ||
| userId | string | ✓ | ~ 128 chars | User ID | ||
| uniqueId | string | ✓ | UUID | ~ 36 chars | Unique ID A UUID that uniquely identifies this score entry. Automatically generated on creation. Used to distinguish multiple score entries from the same user in the same category when uniqueByUserId is disabled. | |
| scorerUserId | string | ✓ | ~ 128 chars | User ID | ||
| score | long | ✓ | 0 ~ 9223372036854775805 | Score The score value registered by the player. Must be within the category’s configured minimum/maximum range. In sum mode, this value can be incremented via the AddScore operation. | ||
| metadata | string | ~ 512 chars | Metadata Arbitrary values can be set in the metadata. Since they do not affect GS2’s behavior, they can be used to store information used in the game. |
EzRanking
Ranking
Represents a single entry in a ranking leaderboard, containing the user’s rank, score, and associated metadata. There are two types: global ranking (all players compete on a shared board with batch calculation) and scope ranking (per-user boards based on subscribed players with real-time reflection). Rankings are sorted by the category’s configured order direction, and entries with the same score share the same rank while maintaining distinct indices.
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| rank | long | ✓ | 1 ~ 9223372036854775805 | Rank The ranking position of this entry, starting from 1. Entries with the same score share the same rank value. For example, if two users tie for 1st place, both have rank 1 and the next entry has rank 3. | ||
| index | long | ✓ | 0 ~ 9223372036854775805 | Index A zero-based sequential index within the ranking list. Unlike rank, the index is always unique and sequential even when multiple entries share the same score. Used for pagination and range-based queries. | ||
| userId | string | ✓ | ~ 128 chars | User ID | ||
| score | long | ✓ | 0 ~ 9223372036854775805 | Score The score value for this ranking entry. In sum mode, this is the accumulated total of all registered scores. The value used for ranking sort order depends on the category’s orderDirection setting. | ||
| metadata | string | ~ 512 chars | Metadata Arbitrary metadata associated with this ranking entry. Inherited from the score registration and returned alongside ranking results. Maximum 512 characters. | |||
| createdAt | long | ✓ | Datetime of creation Unix time, milliseconds * Automatically configured on the server |
EzSubscribeUser
Subscribe User
Represents an individual subscription relationship within a scope ranking category. Each entry indicates that the parent user is subscribed to (following) the target user’s scores in the specified category.
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| userId | string | ✓ | ~ 128 chars | User ID | ||
| targetUserId | string | ✓ | ~ 128 chars | Target User ID The user ID of the player being subscribed to. This user’s scores will appear in the subscribing user’s scope ranking for the specified category. |
EzCategoryModel
Category Model
Different rankings can be created for different categories.
Categories can have a minimum and maximum score that can be registered, and scores outside of that range are discarded. When calculating rankings, it is possible to set whether the scores are to be ranked in ascending or descending order, with the smallest scores being ranked higher (ascending order) or the largest scores being ranked lower (descending order).
You can select global or scope as the type of ranking.
Global is a ranking where all players see the same results, and Scope is a ranking where each game player has a different result, such as a ranking among friends or a ranking in a guild.
For global ranking, you can set the ranking interval from 15 minutes to 24 hours for each category. Scope rankings reflect the calculate results in real time.
The ranking data has a setting called “generation,” and the registered scores can be reset by changing the generation.
| Type | Condition | Required | Default | Value Limits | Description | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| name | string | ✓ | ~ 128 chars | Category Model name Category Model-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||||||||
| metadata | string | ~ 1024 chars | Metadata Arbitrary values can be set in the metadata. Since they do not affect GS2’s behavior, they can be used to store information used in the game. | |||||||||
| scope | String Enum enum { “global”, “scoped” } | ✓ | Scope The type of ranking for this category. “global” creates a single leaderboard shared by all players, recalculated at configured intervals (batch processing). “scoped” creates per-user leaderboards based on subscribed players (e.g., friends or guild members), with real-time score reflection.
| |||||||||
| globalRankingSetting | EzGlobalRankingSetting | {scope} == “global” | ✓* | Global Ranking Setting Configuration specific to global ranking mode, including calculation interval, fixed timing, score uniqueness, generation management, and additional time-windowed scopes. Only applicable when scope is set to “global”. * Required if scope is “global” | ||||||||
| entryPeriodEventId | string | ~ 1024 chars | Entry Period Event ID GRN of a GS2-Schedule event that defines the time window during which score registration is accepted. Outside this period, score submission requests are rejected. If not set, scores can be registered at any time. | |||||||||
| accessPeriodEventId | string | ~ 1024 chars | Access Period Event ID GRN of a GS2-Schedule event that defines the time window during which ranking data can be viewed. Outside this period, ranking retrieval requests are rejected. If not set, rankings can be accessed at any time. |
EzGlobalRankingSetting
Global Ranking Setting
Global is a ranking where all players see the same results. The ranking interval can be set from 15 minutes to 24 hours.
The ranking data has a setting called “generation,” and the registered scores can be reset by changing the generation.
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| calculateIntervalMinutes | int | ✓ | 15 ~ 1440 | Calculate Interval Minutes The interval in minutes between successive ranking recalculations. The system periodically recalculates the global ranking based on all registered scores at this interval. Range: 15 to 1440 minutes (15 minutes to 24 hours). | ||
| additionalScopes | List<EzScope> | 0 ~ 10 items | Additional Scopes A list of additional time-windowed aggregation scopes. Each scope defines a separate ranking that only considers scores registered within a specified number of days. This enables creating daily, weekly, or monthly leaderboards alongside the all-time global ranking. Maximum 10 scopes. |
EzScope
Aggregation Scope
Defines an additional time-windowed aggregation scope for Global Ranking mode. Normally, global ranking is calculated for all registered scores regardless of when they were submitted. By adding scopes, you can create separate rankings that only consider scores registered within a specified number of days, enabling daily, weekly, or monthly leaderboards alongside the all-time ranking.
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| name | string | ✓ | ~ 128 chars | Scope Name A unique name identifying this aggregation scope within the category. Used to distinguish between multiple time-windowed ranking boards (e.g., “daily”, “weekly”). Maximum 128 characters. | ||
| targetDays | long | ✓ | 1 ~ 365 | Target Days The number of days to include in the aggregation window. Only scores registered within this number of days from the current time are considered for the scoped ranking. Range: 1-365 days. |
Methods
getCategory
Get the details of a specific ranking category
Retrieves a single ranking category by name, including its scoring rules and configuration.
The response includes:
- Score range: The minimum and maximum allowed score values
- Sort order: Whether higher scores rank better (descending) or lower scores rank better (ascending, useful for time attack rankings)
- Scope type: Whether it’s a global ranking or a scoped (friend) ranking
- For global rankings: The calculation interval and timing settings
- Entry/access period: If linked to GS2-Schedule events, when players can submit scores and view rankings
Use this to display ranking rules or settings on a detail screen.
Request
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| categoryName | string | ✓ | ~ 128 chars | Category Model name Category Model-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). |
Result
| Type | Description | |
|---|---|---|
| item | EzCategoryModel | Category Model |
Implementation Example
var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).CategoryModel(
categoryName: "category-0001"
);
var item = await domain.ModelAsync(); var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).CategoryModel(
categoryName: "category-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->Ranking->Namespace(
"namespace-0001" // namespaceName
)->CategoryModel(
"category-0001" // categoryName
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}Value change event handling
var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).CategoryModel(
categoryName: "category-0001"
);
// Start event handling
var callbackId = domain.Subscribe(
value => {
// Called when the value changes
// The "value" is passed the value after the change.
}
);
// Stop event handling
domain.Unsubscribe(callbackId); var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).CategoryModel(
categoryName: "category-0001"
);
// Start event handling
var callbackId = domain.Subscribe(
value => {
// Called when the value changes
// The "value" is passed the value after the change.
}
);
// Stop event handling
domain.Unsubscribe(callbackId); const auto Domain = Gs2->Ranking->Namespace(
"namespace-0001" // namespaceName
)->CategoryModel(
"category-0001" // categoryName
);
// Start event handling
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Ranking::Model::FCategoryModel> value) {
// Called when the value changes
// The "value" is passed the value after the change.
}
);
// Stop event handling
Domain->Unsubscribe(CallbackId);Warning
This event is triggered when the value stored in the SDK’s local cache changes.
The local cache is updated only when executing the SDK’s API, or by executing stamp sheets via GS2-Distributor with GS2-Gateway notification enabled, or by executing a GS2-JobQueue with GS2-Gateway notification enabled.
Therefore, callbacks will not be invoked if the value is changed in any other way.
listCategories
Get a list of all ranking categories
Retrieves all ranking categories defined in the namespace. Each category represents a separate leaderboard — for example, “High Score”, “Boss Time Attack”, “Weekly Battle Wins”, etc.
There are two types of rankings:
- Global ranking: All players are ranked together on a single leaderboard. Rankings are recalculated periodically (not in real-time), so there is a delay between submitting a score and seeing it reflected in the rankings.
- Scoped ranking: Each player sees a personalized leaderboard showing only themselves and the players they have subscribed to (like a “Friend Ranking”). This is calculated in real-time.
Use this to display the list of available leaderboards on your ranking screen — for example, tabs for “World Ranking”, “Friend Ranking”, “Weekly Ranking”, etc.
Request
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). |
Result
| Type | Description | |
|---|---|---|
| items | List<EzCategoryModel> | List of Category Models |
Implementation Example
var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
);
var items = await domain.CategoryModelsAsync(
).ToListAsync(); var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
);
var it = domain.CategoryModels(
);
List<EzCategoryModel> items = new List<EzCategoryModel>();
while (it.HasNext())
{
yield return it.Next();
if (it.Error != null)
{
onError.Invoke(it.Error, null);
break;
}
if (it.Current != null)
{
items.Add(it.Current);
}
else
{
break;
}
} const auto Domain = Gs2->Ranking->Namespace(
"namespace-0001" // namespaceName
);
const auto It = Domain->CategoryModels(
);
TArray<Gs2::UE5::Ranking::Model::FEzCategoryModelPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}Value change event handling
var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
);
// Start event handling
var callbackId = domain.SubscribeCategoryModels(
() => {
// Called when an element of the list changes.
}
);
// Stop event handling
domain.UnsubscribeCategoryModels(callbackId); var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
);
// Start event handling
var callbackId = domain.SubscribeCategoryModels(
() => {
// Called when an element of the list changes.
}
);
// Stop event handling
domain.UnsubscribeCategoryModels(callbackId); const auto Domain = Gs2->Ranking->Namespace(
"namespace-0001" // namespaceName
);
// Start event handling
const auto CallbackId = Domain->SubscribeCategoryModels(
[]() {
// Called when an element of the list changes.
}
);
// Stop event handling
Domain->UnsubscribeCategoryModels(CallbackId);Warning
This event is triggered when the value stored in the SDK’s local cache changes.
The local cache is updated only when executing the SDK’s API, or by executing stamp sheets via GS2-Distributor with GS2-Gateway notification enabled, or by executing a GS2-JobQueue with GS2-Gateway notification enabled.
Therefore, callbacks will not be invoked if the value is changed in any other way.
listSubscribes
Get the list of players you are following for friend ranking
Retrieves the list of players that the current player has subscribed to (is following) for the specified ranking category. This is used with scoped (friend) rankings — when you subscribe to another player, their scores appear in your personalized friend ranking.
Use this to display a “Following” list on the ranking screen, showing which players’ scores are included in the friend leaderboard.
For example, if the player has subscribed to PlayerA, PlayerB, and PlayerC, the friend ranking will show scores from these three players plus the player themselves.
Request
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| categoryName | string | ✓ | ~ 128 chars | Category Model name | ||
| gameSession | GameSession | ✓ | GameSession |
Result
| Type | Description | |
|---|---|---|
| items | List<EzSubscribeUser> | List of Subscribed User Information |
Implementation Example
var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
);
var items = await domain.SubscribeUsersAsync(
).ToListAsync(); var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
);
var it = domain.SubscribeUsers(
);
List<EzSubscribeUser> items = new List<EzSubscribeUser>();
while (it.HasNext())
{
yield return it.Next();
if (it.Error != null)
{
onError.Invoke(it.Error, null);
break;
}
if (it.Current != null)
{
items.Add(it.Current);
}
else
{
break;
}
} const auto Domain = Gs2->Ranking->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->RankingCategory(
"category-0001", // categoryName
nullptr // additionalScopeName
);
const auto It = Domain->SubscribeUsers(
);
TArray<Gs2::UE5::Ranking::Model::FEzSubscribeUserPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}Value change event handling
var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
);
// Start event handling
var callbackId = domain.SubscribeSubscribeUsers(
() => {
// Called when an element of the list changes.
}
);
// Stop event handling
domain.UnsubscribeSubscribeUsers(callbackId); var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
);
// Start event handling
var callbackId = domain.SubscribeSubscribeUsers(
() => {
// Called when an element of the list changes.
}
);
// Stop event handling
domain.UnsubscribeSubscribeUsers(callbackId); const auto Domain = Gs2->Ranking->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->RankingCategory(
"category-0001", // categoryName
nullptr // additionalScopeName
);
// Start event handling
const auto CallbackId = Domain->SubscribeSubscribeUsers(
[]() {
// Called when an element of the list changes.
}
);
// Stop event handling
Domain->UnsubscribeSubscribeUsers(CallbackId);Warning
This event is triggered when the value stored in the SDK’s local cache changes.
The local cache is updated only when executing the SDK’s API, or by executing stamp sheets via GS2-Distributor with GS2-Gateway notification enabled, or by executing a GS2-JobQueue with GS2-Gateway notification enabled.
Therefore, callbacks will not be invoked if the value is changed in any other way.
subscribe
Follow a player to include them in your friend ranking
Subscribes to another player so that their scores appear in your scoped (friend) ranking for the specified category. This is like a “Follow” feature — after subscribing, the target player’s scores will be visible in your personalized friend leaderboard.
Common use cases:
- When the player adds someone as a friend, automatically subscribe to them for all ranking categories
- On a player profile screen, provide a “Follow on Leaderboard” button
- After a match, let the player follow opponents they played against
You cannot subscribe to yourself (your own score is always included in your friend ranking automatically).
Request
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| categoryName | string | ✓ | ~ 128 chars | Category Name | ||
| gameSession | GameSession | ✓ | GameSession | |||
| targetUserId | string | ✓ | ~ 128 chars | Target User ID |
Result
| Type | Description | |
|---|---|---|
| item | EzSubscribeUser | Subscribed User Information |
Implementation Example
var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
);
var result = await domain.SubscribeAsync(
targetUserId: "user-0002"
);
var item = await result.ModelAsync(); var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
);
var future = domain.SubscribeFuture(
targetUserId: "user-0002"
);
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
}
var future2 = future.Result.ModelFuture();
yield return future2;
if (future2.Error != null)
{
onError.Invoke(future2.Error, null);
yield break;
}
var result = future2.Result; const auto Domain = Gs2->Ranking->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->RankingCategory(
"category-0001", // categoryName
nullptr // additionalScopeName
);
const auto Future = Domain->Subscribe(
"user-0002" // targetUserId
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}
// obtain changed values / result values
const auto Future2 = Future->GetTask().Result()->Model();
Future2->StartSynchronousTask();
if (Future2->GetTask().IsError())
{
return Future2->GetTask().Error();
}
const auto Result = Future2->GetTask().Result();unsubscribe
Unfollow a player and remove them from your friend ranking
Removes the subscription to the specified player for the specified ranking category. After unsubscribing, the target player’s scores will no longer appear in your scoped (friend) ranking.
Use this when the player wants to stop seeing someone’s scores in their friend leaderboard — for example, when removing a friend or unfollowing a player.
Request
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| categoryName | string | ✓ | ~ 128 chars | Category Name | ||
| gameSession | GameSession | ✓ | GameSession | |||
| targetUserId | string | ✓ | ~ 128 chars | Target User ID |
Result
| Type | Description | |
|---|---|---|
| item | EzSubscribeUser | Unsubscribed Subscribed User Information |
Implementation Example
var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
).SubscribeUser(
targetUserId: "user-0002"
);
var result = await domain.UnsubscribeAsync(
); var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
).SubscribeUser(
targetUserId: "user-0002"
);
var future = domain.UnsubscribeFuture(
);
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
} const auto Domain = Gs2->Ranking->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->RankingCategory(
"category-0001", // categoryName
nullptr // additionalScopeName
)->SubscribeUser(
"user-0002" // targetUserId
);
const auto Future = Domain->Unsubscribe(
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}
const auto Result = Future->GetTask().Result();getNearRanking
Get rankings around a specific score
Retrieves a portion of the ranking centered on the specified score value. This is useful for showing the player “where they would rank” — for example, displaying a few players above and below the player’s score on the leaderboard.
Typical use case: After the player finishes a game, show them their score and the nearby rankings: “98th: PlayerX (5,200 pts) → You: 5,150 pts → 99th: PlayerY (5,100 pts)”
This API is only available for global rankings. For scoped (friend) rankings, use GetRanking instead since the list is small enough to display entirely.
Request
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| categoryName | string | ✓ | ~ 128 chars | Category Model name Category Model-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| additionalScopeName | string | ~ 128 chars | Scope Name A unique name identifying this aggregation scope within the category. Used to distinguish between multiple time-windowed ranking boards (e.g., “daily”, “weekly”). Maximum 128 characters. | |||
| score | long | ✓ | 0 ~ 9223372036854775805 | Score The score value for this ranking entry. In sum mode, this is the accumulated total of all registered scores. The value used for ranking sort order depends on the category’s orderDirection setting. |
Result
| Type | Description | |
|---|---|---|
| items | List<EzRanking> | List of Ranking Scores |
Implementation Example
var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).User(
userId: "user-0001"
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
);
var items = await domain.NearRankingsAsync(
score: 1000L
).ToListAsync(); var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).User(
userId: "user-0001"
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
);
var it = domain.NearRankings(
score: 1000L
);
List<EzRanking> items = new List<EzRanking>();
while (it.HasNext())
{
yield return it.Next();
if (it.Error != null)
{
onError.Invoke(it.Error, null);
break;
}
if (it.Current != null)
{
items.Add(it.Current);
}
else
{
break;
}
} const auto Domain = Gs2->Ranking->Namespace(
"namespace-0001" // namespaceName
)->User(
"user-0001" // userId
)->RankingCategory(
"category-0001", // categoryName
nullptr // additionalScopeName
);
const auto It = Domain->NearRankings(
1000L // score
);
TArray<Gs2::UE5::Ranking::Model::FEzRankingPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}getRank
Get a specific player’s rank and score
Retrieves the ranking information for a specific player, including their rank position and score. Use this to show “Your Rank: 42nd (8,500 pts)” on a result screen or profile page.
You need to specify the scorerUserId (the player whose rank you want to look up). The uniqueId can be omitted (defaults to “0”) if the category only allows one score per player. If the category allows multiple scores per player, specify the uniqueId to identify which score to look up.
Request
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| categoryName | string | ✓ | ~ 128 chars | Category Model name Category Model-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| additionalScopeName | string | ~ 128 chars | Scope Name A unique name identifying this aggregation scope within the category. Used to distinguish between multiple time-windowed ranking boards (e.g., “daily”, “weekly”). Maximum 128 characters. | |||
| scorerUserId | string | ✓ | ~ 128 chars | User ID of the user who earned the score | ||
| gameSession | GameSession | ✓ | GameSession | |||
| uniqueId | string | “0” | ~ 36 chars | Score Unique ID |
Result
| Type | Description | |
|---|---|---|
| item | EzRanking | Ranking |
Implementation Example
var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
).Ranking(
scorerUserId: "user-0001",
index: null
);
var item = await domain.ModelAsync(
scorerUserId : "user-0001"
); var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
).Ranking(
scorerUserId: "user-0001",
index: null
);
var future = domain.Model(
scorerUserId : "user-0001"
);
yield return future;
var item = future.Result; const auto Domain = Gs2->Ranking->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->RankingCategory(
"category-0001", // categoryName
nullptr // additionalScopeName
)->Ranking(
"user-0001", // scorerUserId
nullptr // index
);
const auto Future = Domain->Model(
"user-0001" // scorerUserId
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}Value change event handling
var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
).Ranking(
scorerUserId: "user-0001",
index: null
);
// Start event handling
var callbackId = domain.Subscribe(
value => {
// Called when the value changes
// The "value" is passed the value after the change.
}
);
// Stop event handling
domain.Unsubscribe(callbackId); var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
).Ranking(
scorerUserId: "user-0001",
index: null
);
// Start event handling
var callbackId = domain.Subscribe(
value => {
// Called when the value changes
// The "value" is passed the value after the change.
}
);
// Stop event handling
domain.Unsubscribe(callbackId); const auto Domain = Gs2->Ranking->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->RankingCategory(
"category-0001", // categoryName
nullptr // additionalScopeName
)->Ranking(
"user-0001", // scorerUserId
nullptr // index
);
// Start event handling
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Ranking::Model::FRanking> value) {
// Called when the value changes
// The "value" is passed the value after the change.
}
);
// Stop event handling
Domain->Unsubscribe(CallbackId);Warning
This event is triggered when the value stored in the SDK’s local cache changes.
The local cache is updated only when executing the SDK’s API, or by executing stamp sheets via GS2-Distributor with GS2-Gateway notification enabled, or by executing a GS2-JobQueue with GS2-Gateway notification enabled.
Therefore, callbacks will not be invoked if the value is changed in any other way.
getRanking
Get the ranking leaderboard
Retrieves the ranking list for the specified category, showing players ordered by their score. This is the main API for displaying a leaderboard screen — for example, “1st: PlayerA (10,500 pts), 2nd: PlayerB (9,800 pts), …”.
You can specify a startIndex to begin from a specific rank position (e.g., startIndex=0 for the top, startIndex=99 for ranks around 100th place).
For global rankings, the data is based on the last calculation, so there may be a delay between score submission and ranking updates. For scoped (friend) rankings, the data is calculated in real-time.
If the category supports additional scopes, you can specify additionalScopeName to filter the ranking further.
Request
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| categoryName | string | ✓ | ~ 128 chars | Category Model name Category Model-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| additionalScopeName | string | ~ 128 chars | Scope Name A unique name identifying this aggregation scope within the category. Used to distinguish between multiple time-windowed ranking boards (e.g., “daily”, “weekly”). Maximum 128 characters. | |||
| gameSession | GameSession | GameSession | ||||
| limit | int | 30 | 1 ~ 1000 | Number of data items to retrieve | ||
| pageToken | string | ~ 4096 chars | Token specifying the position from which to start acquiring data | |||
| startIndex | long | 0 ~ 9223372036854775805 | Index to start retrieving rankings |
Result
| Type | Description | |
|---|---|---|
| items | List<EzRanking> | List of Ranking Scores |
| nextPageToken | string | Page token to retrieve the rest of the listing |
Implementation Example
var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
);
var items = await domain.RankingsAsync(
).ToListAsync(); var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
);
var it = domain.Rankings(
);
List<EzRanking> items = new List<EzRanking>();
while (it.HasNext())
{
yield return it.Next();
if (it.Error != null)
{
onError.Invoke(it.Error, null);
break;
}
if (it.Current != null)
{
items.Add(it.Current);
}
else
{
break;
}
} const auto Domain = Gs2->Ranking->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->RankingCategory(
"category-0001", // categoryName
nullptr // additionalScopeName
);
const auto It = Domain->Rankings(
);
TArray<Gs2::UE5::Ranking::Model::FEzRankingPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}Value change event handling
var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
);
// Start event handling
var callbackId = domain.SubscribeRankings(
() => {
// Called when an element of the list changes.
}
);
// Stop event handling
domain.UnsubscribeRankings(callbackId); var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
);
// Start event handling
var callbackId = domain.SubscribeRankings(
() => {
// Called when an element of the list changes.
}
);
// Stop event handling
domain.UnsubscribeRankings(callbackId); const auto Domain = Gs2->Ranking->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->RankingCategory(
"category-0001", // categoryName
nullptr // additionalScopeName
);
// Start event handling
const auto CallbackId = Domain->SubscribeRankings(
[]() {
// Called when an element of the list changes.
}
);
// Stop event handling
Domain->UnsubscribeRankings(CallbackId);Warning
This event is triggered when the value stored in the SDK’s local cache changes.
The local cache is updated only when executing the SDK’s API, or by executing stamp sheets via GS2-Distributor with GS2-Gateway notification enabled, or by executing a GS2-JobQueue with GS2-Gateway notification enabled.
Therefore, callbacks will not be invoked if the value is changed in any other way.
putScore
Submit a score to the ranking
Registers the player’s score in the specified ranking category. Call this when the player achieves a score you want to record — for example, after completing a stage, finishing a time attack, or at the end of a match.
You can optionally attach metadata to the score (as a string). This is useful for storing extra display information like the player’s character name, team composition, or replay data — anything you want to show alongside the score on the leaderboard.
How the score is used depends on the category type:
- Global ranking: The score is collected and the ranking is recalculated at the next scheduled interval. There is a delay before the ranking is updated.
- Scoped ranking: The score is reflected immediately and appears in the friend rankings of players who have subscribed to this player.
Note: Depending on the category settings, only the highest score (or lowest for ascending rankings) may be kept per player, or multiple scores may be allowed.
Request
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| categoryName | string | ✓ | ~ 128 chars | Category Model name Category Model-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| gameSession | GameSession | ✓ | GameSession | |||
| score | long | ✓ | 0 ~ 9223372036854775805 | Score The score value for this ranking entry. In sum mode, this is the accumulated total of all registered scores. The value used for ranking sort order depends on the category’s orderDirection setting. | ||
| metadata | string | ~ 512 chars | Metadata Arbitrary metadata associated with this ranking entry. Inherited from the score registration and returned alongside ranking results. Maximum 512 characters. |
Result
| Type | Description | |
|---|---|---|
| item | EzScore | Registered Scores |
Implementation Example
var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
);
var result = await domain.PutScoreAsync(
score: 1000L,
metadata: null
);
var item = await result.ModelAsync(); var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RankingCategory(
categoryName: "category-0001",
additionalScopeName: null
);
var future = domain.PutScoreFuture(
score: 1000L,
metadata: null
);
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
}
var future2 = future.Result.ModelFuture();
yield return future2;
if (future2.Error != null)
{
onError.Invoke(future2.Error, null);
yield break;
}
var result = future2.Result; const auto Domain = Gs2->Ranking->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->RankingCategory(
"category-0001", // categoryName
nullptr // additionalScopeName
);
const auto Future = Domain->PutScore(
1000L // score
// metadata
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}
// obtain changed values / result values
const auto Future2 = Future->GetTask().Result()->Model();
Future2->StartSynchronousTask();
if (Future2->GetTask().IsError())
{
return Future2->GetTask().Error();
}
const auto Result = Future2->GetTask().Result();getScore
Get a specific score submitted by a player
Retrieves a single score record for the specified player in the specified ranking category. Use this to display the details of a specific score — for example, showing the score value, submission time, and any attached metadata (like character name or replay data).
The uniqueId identifies which score to retrieve when a player has multiple scores. If the category only allows one score per player (the most common case), you can omit the uniqueId or set it to “0”.
Request
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| categoryName | string | ✓ | ~ 128 chars | Category Name | ||
| gameSession | GameSession | ✓ | GameSession | |||
| scorerUserId | string | ✓ | ~ 128 chars | User ID | ||
| uniqueId | string | “0” | ~ 36 chars | Score Unique ID |
Result
| Type | Description | |
|---|---|---|
| item | EzScore | Score |
Implementation Example
var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Score(
categoryName: "category-0001",
scorerUserId: "user-0002",
uniqueId: "unique-0001"
);
var item = await domain.ModelAsync(); var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Score(
categoryName: "category-0001",
scorerUserId: "user-0002",
uniqueId: "unique-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->Ranking->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Score(
"category-0001", // categoryName
"user-0002", // scorerUserId
"unique-0001" // uniqueId
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}Value change event handling
var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Score(
categoryName: "category-0001",
scorerUserId: "user-0002",
uniqueId: "unique-0001"
);
// Start event handling
var callbackId = domain.Subscribe(
value => {
// Called when the value changes
// The "value" is passed the value after the change.
}
);
// Stop event handling
domain.Unsubscribe(callbackId); var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Score(
categoryName: "category-0001",
scorerUserId: "user-0002",
uniqueId: "unique-0001"
);
// Start event handling
var callbackId = domain.Subscribe(
value => {
// Called when the value changes
// The "value" is passed the value after the change.
}
);
// Stop event handling
domain.Unsubscribe(callbackId); const auto Domain = Gs2->Ranking->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Score(
"category-0001", // categoryName
"user-0002", // scorerUserId
"unique-0001" // uniqueId
);
// Start event handling
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Ranking::Model::FScore> value) {
// Called when the value changes
// The "value" is passed the value after the change.
}
);
// Stop event handling
Domain->Unsubscribe(CallbackId);Warning
This event is triggered when the value stored in the SDK’s local cache changes.
The local cache is updated only when executing the SDK’s API, or by executing stamp sheets via GS2-Distributor with GS2-Gateway notification enabled, or by executing a GS2-JobQueue with GS2-Gateway notification enabled.
Therefore, callbacks will not be invoked if the value is changed in any other way.
listScores
Get a list of scores submitted by a specific player
Retrieves all scores that a specific player has submitted in the specified ranking category. Use this to show a player’s score history — for example, listing all their attempts at a time attack stage.
This is different from viewing the ranking (which shows all players sorted by score). This API focuses on one specific player’s submitted scores.
If the category only allows one score per player, this will return a single entry. If the category allows multiple scores (e.g., multiple attempts), this returns all of them.
Request
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| categoryName | string | ✓ | ~ 128 chars | Category Model name | ||
| scorerUserId | string | ✓ | ~ 128 chars | User ID | ||
| gameSession | GameSession | ✓ | GameSession | |||
| limit | int | 30 | 1 ~ 1000 | Number of data items to retrieve | ||
| pageToken | string | ~ 1024 chars | Token specifying the position from which to start acquiring data |
Result
| Type | Description | |
|---|---|---|
| items | List<EzScore> | List of Scores |
| nextPageToken | string | Page token to retrieve the rest of the listing |
Implementation Example
var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var items = await domain.ScoresAsync(
categoryName: "category-0001",
scorerUserId: "user-0002"
).ToListAsync(); var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var it = domain.Scores(
categoryName: "category-0001",
scorerUserId: "user-0002"
);
List<EzScore> items = new List<EzScore>();
while (it.HasNext())
{
yield return it.Next();
if (it.Error != null)
{
onError.Invoke(it.Error, null);
break;
}
if (it.Current != null)
{
items.Add(it.Current);
}
else
{
break;
}
} const auto Domain = Gs2->Ranking->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
const auto It = Domain->Scores(
"category-0001", // categoryName
"user-0002" // scorerUserId
);
TArray<Gs2::UE5::Ranking::Model::FEzScorePtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}Value change event handling
var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
// Start event handling
var callbackId = domain.SubscribeScores(
() => {
// Called when an element of the list changes.
}
);
// Stop event handling
domain.UnsubscribeScores(callbackId); var domain = gs2.Ranking.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
// Start event handling
var callbackId = domain.SubscribeScores(
() => {
// Called when an element of the list changes.
}
);
// Stop event handling
domain.UnsubscribeScores(callbackId); const auto Domain = Gs2->Ranking->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
// Start event handling
const auto CallbackId = Domain->SubscribeScores(
[]() {
// Called when an element of the list changes.
}
);
// Stop event handling
Domain->UnsubscribeScores(CallbackId);Warning
This event is triggered when the value stored in the SDK’s local cache changes.
The local cache is updated only when executing the SDK’s API, or by executing stamp sheets via GS2-Distributor with GS2-Gateway notification enabled, or by executing a GS2-JobQueue with GS2-Gateway notification enabled.
Therefore, callbacks will not be invoked if the value is changed in any other way.