GS2-Ranking SDK for Game Engine API Reference

Specifications of models and API references for GS2-Ranking SDK for Game Engine

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.

TypeConditionRequiredDefaultValue LimitsDescription
categoryNamestring
~ 128 charsCategory Name
userIdstring
~ 128 charsUser ID
uniqueIdstring
UUID~ 36 charsUnique 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.
scorerUserIdstring
~ 128 charsUser ID
scorelong
0 ~ 9223372036854775805Score
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.
metadatastring~ 512 charsMetadata
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.

TypeConditionRequiredDefaultValue LimitsDescription
ranklong
1 ~ 9223372036854775805Rank
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.
indexlong
0 ~ 9223372036854775805Index
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.
userIdstring
~ 128 charsUser ID
scorelong
0 ~ 9223372036854775805Score
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.
metadatastring~ 512 charsMetadata
Arbitrary metadata associated with this ranking entry.
Inherited from the score registration and returned alongside ranking results. Maximum 512 characters.
createdAtlong
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.

TypeConditionRequiredDefaultValue LimitsDescription
userIdstring
~ 128 charsUser ID
targetUserIdstring
~ 128 charsTarget 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.

TypeConditionRequiredDefaultValue LimitsDescription
namestring
~ 128 charsCategory Model name
Category Model-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
metadatastring~ 1024 charsMetadata
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.
scopeString 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.
DefinitionDescription
“global”Global
“scoped”Scoped
globalRankingSettingEzGlobalRankingSetting{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”
entryPeriodEventIdstring~ 1024 charsEntry 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.
accessPeriodEventIdstring~ 1024 charsAccess 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.

TypeConditionRequiredDefaultValue LimitsDescription
calculateIntervalMinutesint
15 ~ 1440Calculate 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).
additionalScopesList<EzScope>0 ~ 10 itemsAdditional 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.

TypeConditionRequiredDefaultValue LimitsDescription
namestring
~ 128 charsScope 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.
targetDayslong
1 ~ 365Target 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

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
categoryNamestring
~ 128 charsCategory Model name
Category Model-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).

Result

TypeDescription
itemEzCategoryModelCategory 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);

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

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).

Result

TypeDescription
itemsList<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);

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

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
categoryNamestring
~ 128 charsCategory Model name
gameSessionGameSession
GameSession

Result

TypeDescription
itemsList<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);

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

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
categoryNamestring
~ 128 charsCategory Name
gameSessionGameSession
GameSession
targetUserIdstring
~ 128 charsTarget User ID

Result

TypeDescription
itemEzSubscribeUserSubscribed 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

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
categoryNamestring
~ 128 charsCategory Name
gameSessionGameSession
GameSession
targetUserIdstring
~ 128 charsTarget User ID

Result

TypeDescription
itemEzSubscribeUserUnsubscribed 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

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
categoryNamestring
~ 128 charsCategory Model name
Category Model-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
additionalScopeNamestring~ 128 charsScope 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.
scorelong
0 ~ 9223372036854775805Score
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

TypeDescription
itemsList<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

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
categoryNamestring
~ 128 charsCategory Model name
Category Model-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
additionalScopeNamestring~ 128 charsScope 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.
scorerUserIdstring
~ 128 charsUser ID of the user who earned the score
gameSessionGameSession
GameSession
uniqueIdstring“0”~ 36 charsScore Unique ID

Result

TypeDescription
itemEzRankingRanking

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);

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

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
categoryNamestring
~ 128 charsCategory Model name
Category Model-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
additionalScopeNamestring~ 128 charsScope 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.
gameSessionGameSessionGameSession
limitint301 ~ 1000Number of data items to retrieve
pageTokenstring~ 4096 charsToken specifying the position from which to start acquiring data
startIndexlong0 ~ 9223372036854775805Index to start retrieving rankings

Result

TypeDescription
itemsList<EzRanking>List of Ranking Scores
nextPageTokenstringPage 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);

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

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
categoryNamestring
~ 128 charsCategory Model name
Category Model-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
gameSessionGameSession
GameSession
scorelong
0 ~ 9223372036854775805Score
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.
metadatastring~ 512 charsMetadata
Arbitrary metadata associated with this ranking entry.
Inherited from the score registration and returned alongside ranking results. Maximum 512 characters.

Result

TypeDescription
itemEzScoreRegistered 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

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
categoryNamestring
~ 128 charsCategory Name
gameSessionGameSession
GameSession
scorerUserIdstring
~ 128 charsUser ID
uniqueIdstring“0”~ 36 charsScore Unique ID

Result

TypeDescription
itemEzScoreScore

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);

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

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
categoryNamestring
~ 128 charsCategory Model name
scorerUserIdstring
~ 128 charsUser ID
gameSessionGameSession
GameSession
limitint301 ~ 1000Number of data items to retrieve
pageTokenstring~ 1024 charsToken specifying the position from which to start acquiring data

Result

TypeDescription
itemsList<EzScore>List of Scores
nextPageTokenstringPage 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);