GS2-Experience SDK for Game Engine API Reference
Model
EzStatus
Status
Status is an entity that exists for each property ID. Holds the current experience and rank cap values.
Property ID is a status-specific ID and can be set to any value by the developer. For GS2, it is recommended to use a value as the property ID that adds an experience point model suffix to the end of the Item Set GRN in GS2-Inventory or the Entry GRN in GS2-Dictionary that possesses experience points.
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| experienceName | string | ✓ | ~ 128 chars | Experience Model name The name of the experience model that defines the ranking rules for this status. Determines which rank threshold table and rank cap settings are applied. | ||
| propertyId | string | ✓ | ~ 1024 chars | Property ID A developer-defined identifier that uniquely identifies this status within the user’s scope. It is recommended to use a value that appends an experience model suffix to the GS2-Inventory Item Set GRN or GS2-Dictionary Entry GRN that possesses the experience. | ||
| experienceValue | long | 0 | 0 ~ 9223372036854775805 | Cumulative experience gained The total experience value accumulated by this status. The current rank is derived from this value using the rank threshold table. Experience cannot be gained beyond the threshold corresponding to the current rank cap. | ||
| rankValue | long | 0 | 0 ~ 9223372036854775805 | Current Rank The rank (level) derived from the cumulative experience value using the rank threshold table. Starts at 0 and increases as experience thresholds are crossed. Cannot exceed the current rank cap value. | ||
| rankCapValue | long | ✓ | 0 ~ 9223372036854775805 | Current Rank Cap The maximum rank this status can currently reach. Initially set to the experience model’s defaultRankCap, and can be raised up to maxRankCap through rank cap increase operations such as limit breaking. | ||
| nextRankUpExperienceValue | long | 0 | 0 ~ 9223372036854775805 | Experience points required for the next rank-up The cumulative experience threshold needed to advance to the next rank. Returns 0 if the status has already reached the rank cap. Useful for displaying progress bars or remaining experience in the game UI. |
EzExperienceModel
Experience Model
Defines the rules for an experience and rank system. Sets thresholds for the experience required to rank up, as well as the default rank cap and maximum rank cap. The rank cap limits the maximum rank a status can reach, and can be raised per-status up to the maximum rank cap (e.g., through limit breaking). Optionally includes acquire action rate tables that adjust reward multipliers based on the current rank.
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| name | string | ✓ | ~ 128 chars | Experience Model name Experience Model-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| metadata | string | ~ 2048 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. | |||
| defaultExperience | long | 0 | 0 ~ 9223372036854775805 | Initial Experience Value The experience value assigned to a newly created status. Typically set to 0 so that players start at the beginning of the progression. The initial rank is determined from this value using the rank threshold table. | ||
| defaultRankCap | long | ✓ | 0 ~ 9223372036854775805 | Initial value of rank cap The default maximum rank that a newly created status can reach. Experience beyond this rank’s threshold is discarded or triggers an overflow script. The rank cap can be raised per-status up to maxRankCap through operations like limit breaking. | ||
| maxRankCap | long | ✓ | 0 ~ 9223372036854775805 | Maximum rank cap The absolute upper limit for the rank cap. Even through rank cap increase operations (such as limit breaking), the rank cap cannot exceed this value. Must be greater than or equal to defaultRankCap. | ||
| rankThreshold | EzThreshold | ✓ | Rank Up Threshold References the threshold table that defines the cumulative experience values required for each rank. The number of entries in the threshold determines the maximum possible rank, and each entry’s value specifies the experience needed to reach the next rank. | |||
| acquireActionRates | List<EzAcquireActionRate> | 0 ~ 100 items | List of Reward addition tables Defines rank-based multiplier tables that adjust reward quantities when the status’s rank is used as a reference. Each table maps ranks to multipliers, enabling mechanics like higher-rank characters receiving more rewards from the same actions. |
EzThreshold
Rank Up Threshold
The Rank Up Threshold is a sequence of numbers needed to determine rank (level) from experience. If the value [10, 20] is set, experience values between 1 and 9 are rank 1, experience values between 10 and 19 are rank 2, experience values at 20 are rank 3, and no more experience values can be obtained.
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| metadata | string | ~ 2048 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. | |||
| values | List<long> | ✓ | 1 ~ 10000 items | List of Rank Up Experience Threshold An ordered array of cumulative experience values defining the rank progression. The number of entries determines the maximum achievable rank. For example, [10, 20] means rank 1 at 0-9 EXP, rank 2 at 10-19 EXP, and rank 3 at 20+ EXP (with no further gains possible). |
EzAcquireAction
Acquire Action
EzAcquireActionRate
Reward Addition Table
Defines a rank-based multiplier table that adjusts reward quantities based on the status’s current rank. Each entry in the table corresponds to a rank and specifies a multiplier applied to the acquisition amount. Supports both standard double-precision values and big number string representations for large-scale calculations.
| Type | Condition | Required | Default | Value Limits | Description | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| name | string | ✓ | ~ 128 chars | Reward addition table name A unique identifier for this reward addition table. Referenced when specifying which multiplier table to apply to a particular acquire action. | ||||||||
| mode | String Enum enum { “double”, “big” } | “double” | Reward addition table type Selects the numeric precision for the multiplier values. Use “double” for standard floating-point numbers (up to 2^48), or “big” for string-represented numbers supporting up to 1024 digits when large-scale calculations are needed.
| |||||||||
| rates | List<double> | {mode} == “double” | ✓* | 1 ~ 10000 items | Amount added per rank (multiplier) An array of multiplier values indexed by rank. The i-th entry defines the reward multiplier applied when the status is at rank i. Used when the mode is set to “double”. * Required if mode is “double” | |||||||
| bigRates | List<string> | {mode} == “big” | ✓* | 1 ~ 10000 items | Amount added per rank (multiplier) An array of string-represented multiplier values indexed by rank. The i-th entry defines the reward multiplier applied when the status is at rank i. Used when the mode is set to “big” for calculations requiring large-number precision. * Required if mode is “big” |
EzVerifyActionResult
Verify Action execution result
EzConsumeActionResult
Consume Action execution result
EzAcquireActionResult
Acquire Action execution result
EzTransactionResult
Transaction execution results
Result of a transaction executed using the server-side automatic transaction execution feature
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| transactionId | string | ✓ | 36 ~ 36 chars | Transaction ID | ||
| verifyResults | List<EzVerifyActionResult> | 0 ~ 10 items | List of verify action execution results | |||
| consumeResults | List<EzConsumeActionResult> | [] | 0 ~ 10 items | List of Consume Action execution results | ||
| acquireResults | List<EzAcquireActionResult> | [] | 0 ~ 100 items | List of Acquire Action execution results |
Methods
getExperienceModel
Get an experience model by name
Retrieves a single experience model by specifying its name. The returned information includes the EXP required for each level (rank-up thresholds), the default max level, and the absolute max level. Use this to calculate and display level progress — for example, to show how much more EXP a player’s weapon needs to reach the next level, or what the max level is after limit breaking.
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 (.). | ||
| experienceName | string | ✓ | ~ 128 chars | Experience Model name Experience Model-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). |
Result
| Type | Description | |
|---|---|---|
| item | EzExperienceModel | Experience Model |
Implementation Example
var domain = gs2.Experience.Namespace(
namespaceName: "namespace-0001"
).ExperienceModel(
experienceName: "experience-0001"
);
var item = await domain.ModelAsync(); var domain = gs2.Experience.Namespace(
namespaceName: "namespace-0001"
).ExperienceModel(
experienceName: "experience-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->Experience->Namespace(
"namespace-0001" // namespaceName
)->ExperienceModel(
"experience-0001" // experienceName
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}Value change event handling
var domain = gs2.Experience.Namespace(
namespaceName: "namespace-0001"
).ExperienceModel(
experienceName: "experience-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.Experience.Namespace(
namespaceName: "namespace-0001"
).ExperienceModel(
experienceName: "experience-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->Experience->Namespace(
"namespace-0001" // namespaceName
)->ExperienceModel(
"experience-0001" // experienceName
);
// Start event handling
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Experience::Model::FExperienceModel> 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.
listExperienceModels
Get a list of experience models
Retrieves all experience models registered in this namespace. An experience model defines a leveling system — how much EXP is needed to reach each level, the default max level, and the absolute max level. Use this to build level-up related UI, such as showing “EXP to next level: 150/500” or displaying the level-up thresholds on a character 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 (.). |
Result
| Type | Description | |
|---|---|---|
| items | List<EzExperienceModel> | List of Experience Model |
Implementation Example
var domain = gs2.Experience.Namespace(
namespaceName: "namespace-0001"
);
var items = await domain.ExperienceModelsAsync(
).ToListAsync(); var domain = gs2.Experience.Namespace(
namespaceName: "namespace-0001"
);
var it = domain.ExperienceModels(
);
List<EzExperienceModel> items = new List<EzExperienceModel>();
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->Experience->Namespace(
"namespace-0001" // namespaceName
);
const auto It = Domain->ExperienceModels(
);
TArray<Gs2::UE5::Experience::Model::FEzExperienceModelPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}Value change event handling
var domain = gs2.Experience.Namespace(
namespaceName: "namespace-0001"
);
// Start event handling
var callbackId = domain.SubscribeExperienceModels(
() => {
// Called when an element of the list changes.
}
);
// Stop event handling
domain.UnsubscribeExperienceModels(callbackId); var domain = gs2.Experience.Namespace(
namespaceName: "namespace-0001"
);
// Start event handling
var callbackId = domain.SubscribeExperienceModels(
() => {
// Called when an element of the list changes.
}
);
// Stop event handling
domain.UnsubscribeExperienceModels(callbackId); const auto Domain = Gs2->Experience->Namespace(
"namespace-0001" // namespaceName
);
// Start event handling
const auto CallbackId = Domain->SubscribeExperienceModels(
[]() {
// Called when an element of the list changes.
}
);
// Stop event handling
Domain->UnsubscribeExperienceModels(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.
getStatus
Get the level/EXP status of a specific item or character
Retrieves the current level, EXP, and max level for a specific property owned by the player. The property is identified by the experience model name (which leveling system to use) and the property ID (which specific item or character). Use this to display a detail screen — for example, “Iron Sword Lv.15 — EXP: 3200/5000 — Max Lv: 50”.
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 (.). | ||
| experienceName | string | ✓ | ~ 128 chars | Experience Model name The name of the experience model that defines the ranking rules for this status. Determines which rank threshold table and rank cap settings are applied. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| propertyId | string | ✓ | ~ 1024 chars | Property ID A developer-defined identifier that uniquely identifies this status within the user’s scope. It is recommended to use a value that appends an experience model suffix to the GS2-Inventory Item Set GRN or GS2-Dictionary Entry GRN that possesses the experience. |
Result
| Type | Description | |
|---|---|---|
| item | EzStatus | Status |
Implementation Example
var domain = gs2.Experience.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
experienceName: "character_ssr",
propertyId: "property-0001"
);
var item = await domain.ModelAsync(); var domain = gs2.Experience.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
experienceName: "character_ssr",
propertyId: "property-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->Experience->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Status(
"character_ssr", // experienceName
"property-0001" // propertyId
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}Value change event handling
var domain = gs2.Experience.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
experienceName: "character_ssr",
propertyId: "property-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.Experience.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
experienceName: "character_ssr",
propertyId: "property-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->Experience->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Status(
"character_ssr", // experienceName
"property-0001" // propertyId
);
// Start event handling
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Experience::Model::FStatus> 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.
getStatusWithSignature
Get the level/EXP status with a tamper-proof signature
Retrieves the same level/EXP information as GetStatus, but also returns a cryptographic signature that proves the data hasn’t been tampered with. This is useful when you need to verify the player’s level in a trusted way — for example, when using the level as a condition in other services, or when passing level data to an external system that needs to confirm its authenticity.
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 (.). | ||
| experienceName | string | ✓ | ~ 128 chars | Experience Model name The name of the experience model that defines the ranking rules for this status. Determines which rank threshold table and rank cap settings are applied. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| propertyId | string | ✓ | ~ 1024 chars | Property ID A developer-defined identifier that uniquely identifies this status within the user’s scope. It is recommended to use a value that appends an experience model suffix to the GS2-Inventory Item Set GRN or GS2-Dictionary Entry GRN that possesses the experience. | ||
| keyId | string | “grn:gs2:{region}:{ownerId}:key:default:key:default” | ~ 1024 chars | Encryption Key GRN |
Result
| Type | Description | |
|---|---|---|
| item | EzStatus | Status |
| body | string | Object to be verified |
| signature | string | signature |
Implementation Example
var domain = gs2.Experience.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
experienceName: "character_ssr",
propertyId: "property-0001"
);
var result = await domain.GetStatusWithSignatureAsync(
keyId: "key-0001"
);
var item = await result.ModelAsync();
var body = result.Body;
var signature = result.Signature; var domain = gs2.Experience.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
experienceName: "character_ssr",
propertyId: "property-0001"
);
var future = domain.GetStatusWithSignatureFuture(
keyId: "key-0001"
);
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;
var body = future.Result.Body;
var signature = future.Result.Signature; const auto Domain = Gs2->Experience->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Status(
"character_ssr", // experienceName
"property-0001" // propertyId
);
const auto Future = Domain->GetStatusWithSignature(
"key-0001" // keyId
);
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();
const auto Body = Result->Body;
const auto Signature = Result->Signature;listStatuses
Get a list of the player’s level/EXP statuses
Retrieves the player’s current level and EXP information for their items or characters. You can optionally filter by experience model name — if omitted, all statuses across all experience types are returned. Each status includes the current EXP, current level, and max level for a specific property (e.g., a weapon or character). Use this to build a list screen showing all of the player’s leveled items — for example, “Iron Sword Lv.15, Fire Staff Lv.8”.
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 (.). | ||
| experienceName | string | ~ 128 chars | Experience Model name | |||
| gameSession | GameSession | ✓ | GameSession | |||
| pageToken | string | ~ 1024 chars | Token specifying the position from which to start acquiring data | |||
| limit | int | 30 | 1 ~ 1000 | Number of data items to retrieve |
Result
| Type | Description | |
|---|---|---|
| items | List<EzStatus> | List of Status |
| nextPageToken | string | Page token to retrieve the rest of the listing |
Implementation Example
var domain = gs2.Experience.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var items = await domain.StatusesAsync(
experienceName: "character_ssr"
).ToListAsync(); var domain = gs2.Experience.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var it = domain.Statuses(
experienceName: "character_ssr"
);
List<EzStatus> items = new List<EzStatus>();
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->Experience->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
const auto It = Domain->Statuses(
"character_ssr" // experienceName
);
TArray<Gs2::UE5::Experience::Model::FEzStatusPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}Value change event handling
var domain = gs2.Experience.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
// Start event handling
var callbackId = domain.SubscribeStatuses(
() => {
// Called when an element of the list changes.
}
);
// Stop event handling
domain.UnsubscribeStatuses(callbackId); var domain = gs2.Experience.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
// Start event handling
var callbackId = domain.SubscribeStatuses(
() => {
// Called when an element of the list changes.
}
);
// Stop event handling
domain.UnsubscribeStatuses(callbackId); const auto Domain = Gs2->Experience->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
// Start event handling
const auto CallbackId = Domain->SubscribeStatuses(
[]() {
// Called when an element of the list changes.
}
);
// Stop event handling
Domain->UnsubscribeStatuses(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.