GS2-Grade Transaction Actions
Combining actions, and concurrency
The background common to every service is collected in Combining Transaction Actions. Read that first; the rest of this section is what GS2-Grade adds to it.
Apart from ApplyRankCapByUserId, the transaction actions of GS2-Grade address one grade status, identified by the combination of namespace, user, grade model, and property. A status is rewritten as a whole on every update.
| Operation | Repeated in one transaction | Across a nested transaction | Boundary that separates targets |
|---|---|---|---|
Adding a gradeAddGradeByUserId | Combined, and the values are added up | Fails | namespace, user, grade model, property |
Subtracting a gradeSubGradeByUserId | Combined, and the values are added up | Fails | namespace, user, grade model, property |
Applying the rank capApplyRankCapByUserId | Combined | Depends on GS2-Experience | the GS2-Experience status it writes to |
Expanding into other actionsMultiplyAcquireActionsByUserId | Combined, and the inner actions are gathered into one list | Updates nothing itself | — |
| All verify actions | First wins | No collision, because they only read | target, verify type, required grade |
Adding and subtracting are separate rows sharing a boundary, so a grade cannot be added and subtracted against the same status in one transaction.
ApplyRankCapByUserId does not update the grade status. It reads the current grade and sets the rank cap of the matching GS2-Experience status. Where the same transaction contains a GS2-Experience action against that status, they collide and the transaction fails; read the GS2-Experience page for what can sit alongside it.
MultiplyAcquireActionsByUserId reads the grade and issues the actions it was given, multiplied, as a transaction of its own. It updates nothing itself, but the restrictions of the services those expanded actions belong to apply as they are, and so does “Take care with nested transactions” below.
Verify actions look at the status as of the start of the transaction. You cannot verify a grade that is reached by the same transaction.
Take care with nested transactions
A grade status is rewritten as a whole, so even two additions of the same grade, which would have been combined if written side by side, make the transaction fail when one of them arrives from the inside. Take the contents of any rewards or draws into account as well, and design so that only one place in a transaction updates one status.
If you want to avoid these restrictions
Adding a grade is an acquire action and subtracting one is a consume action. Turning acquireActionUseJobQueue on clears collisions between additions, but an addition together with a subtraction needs enableAtomicCommit turned off.
Concurrency and retries
A grade status is rewritten as a whole, so even two additions collide; there is no relaxation here like the one experience has in GS2-Experience, where a change within a band does not collide. When several requests update the same status at the same time, the one confirmed later returns a conflict (409). Nothing is wrong with the request, so retrying will succeed. Applying the rank cap may also conflict with a concurrent update to the matching GS2-Experience status.
Verify Action
Gs2Grade:VerifyGradeByUserId
Verify grade by User ID
Verifies that the specified user’s grade value satisfies a specified condition (server-side operation). Supports six comparison operators: less, lessEqual, greater, greaterEqual, equal, and notEqual. If the condition is not met, an error is returned with a descriptive message including the expected and actual values. When multiplyValueSpecifyingQuantity is true, the verification threshold value is multiplied by the specified quantity.
Quantity specification supported: NO
| Type | Condition | Required | Default | Value Limits | Description | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||||||||||||||||
| userId | string | ✓ | ~ 128 chars | User ID Specify #{userId} to substitute the currently logged-in user’s ID. | ||||||||||||||||
| gradeName | string | ✓ | ~ 128 chars | Grade Model Name The name of the grade model that this status belongs to. References the grade model definition which contains the grade entry mappings, linked experience model, and reward addition tables. | ||||||||||||||||
| verifyType | string (enum) enum { “less”, “lessEqual”, “greater”, “greaterEqual”, “equal”, “notEqual” } | ✓ | Type of verification
| |||||||||||||||||
| propertyId | string | ✓ | ~ 1024 chars | Property ID A developer-defined identifier for this grade status, unique within the user and grade model. It is strongly recommended to use the same value as the property ID of the linked GS2-Experience status, as this ensures correct synchronization of grade values with rank caps. | ||||||||||||||||
| gradeValue | long | 1 | 1 ~ 9223372036854775805 | Current Grade The current grade value of this status. Used as an index into the grade model’s grade entries array to determine the rank cap for the linked GS2-Experience model. When this value changes, the rank cap of the associated experience status is automatically updated to the value defined in the corresponding grade entry. | ||||||||||||||||
| multiplyValueSpecifyingQuantity | bool | false | Whether to multiply the value used for verification when specifying the quantity | |||||||||||||||||
| timeOffsetToken | string | ~ 1024 chars | Time offset token |
{
"action": "Gs2Grade:VerifyGradeByUserId",
"request": {
"namespaceName": "[string]Namespace name",
"userId": "[string]User ID",
"gradeName": "[string]Grade Model Name",
"verifyType": "[string]Type of verification",
"propertyId": "[string]Property ID",
"gradeValue": "[long]Current Grade",
"multiplyValueSpecifyingQuantity": "[bool]Whether to multiply the value used for verification when specifying the quantity",
"timeOffsetToken": "[string]Time offset token"
}
}action: Gs2Grade:VerifyGradeByUserId
request:
namespaceName: "[string]Namespace name"
userId: "[string]User ID"
gradeName: "[string]Grade Model Name"
verifyType: "[string]Type of verification"
propertyId: "[string]Property ID"
gradeValue: "[long]Current Grade"
multiplyValueSpecifyingQuantity: "[bool]Whether to multiply the value used for verification when specifying the quantity"
timeOffsetToken: "[string]Time offset token"transaction.service("grade").verify.verify_grade_by_user_id({
namespaceName="[string]Namespace name",
userId="[string]User ID",
gradeName="[string]Grade Model Name",
verifyType="[string]Type of verification",
propertyId="[string]Property ID",
gradeValue="[long]Current Grade",
multiplyValueSpecifyingQuantity="[bool]Whether to multiply the value used for verification when specifying the quantity",
timeOffsetToken="[string]Time offset token",
})Gs2Grade:VerifyGradeUpMaterialByUserId
Verify grade up material by User ID
Verifies whether a material property ID is valid for grading up the specified property for the specified user (server-side operation). The verification builds a regex pattern from the grade entry’s PropertyIdRegex and GradeUpPropertyIdRegex, then checks if the material property ID matches. Supports two verification types: ‘match’ (material must match the pattern) and ’notMatch’ (material must not match the pattern).
Quantity specification supported: NO
| Type | Condition | Required | Default | Value Limits | Description | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||||||||
| userId | string | ✓ | ~ 128 chars | User ID Specify #{userId} to substitute the currently logged-in user’s ID. | ||||||||
| gradeName | string | ✓ | ~ 128 chars | Grade Model Name The name of the grade model that this status belongs to. References the grade model definition which contains the grade entry mappings, linked experience model, and reward addition tables. | ||||||||
| verifyType | string (enum) enum { “match”, “notMatch” } | ✓ | Type of verification
| |||||||||
| propertyId | string | ✓ | ~ 1024 chars | Property ID A developer-defined identifier for this grade status, unique within the user and grade model. It is strongly recommended to use the same value as the property ID of the linked GS2-Experience status, as this ensures correct synchronization of grade values with rank caps. | ||||||||
| materialPropertyId | string | ✓ | ~ 1024 chars | Property ID A developer-defined identifier for this grade status, unique within the user and grade model. It is strongly recommended to use the same value as the property ID of the linked GS2-Experience status, as this ensures correct synchronization of grade values with rank caps. | ||||||||
| timeOffsetToken | string | ~ 1024 chars | Time offset token |
{
"action": "Gs2Grade:VerifyGradeUpMaterialByUserId",
"request": {
"namespaceName": "[string]Namespace name",
"userId": "[string]User ID",
"gradeName": "[string]Grade Model Name",
"verifyType": "[string]Type of verification",
"propertyId": "[string]Property ID",
"materialPropertyId": "[string]Property ID",
"timeOffsetToken": "[string]Time offset token"
}
}action: Gs2Grade:VerifyGradeUpMaterialByUserId
request:
namespaceName: "[string]Namespace name"
userId: "[string]User ID"
gradeName: "[string]Grade Model Name"
verifyType: "[string]Type of verification"
propertyId: "[string]Property ID"
materialPropertyId: "[string]Property ID"
timeOffsetToken: "[string]Time offset token"transaction.service("grade").verify.verify_grade_up_material_by_user_id({
namespaceName="[string]Namespace name",
userId="[string]User ID",
gradeName="[string]Grade Model Name",
verifyType="[string]Type of verification",
propertyId="[string]Property ID",
materialPropertyId="[string]Property ID",
timeOffsetToken="[string]Time offset token",
})Consume Action
Gs2Grade:SubGradeByUserId
Subtract grade by User ID
Subtracts the specified grade value from the specified user’s current grade for the given grade model and property (server-side operation). After updating the grade value, the rank cap is automatically applied to the linked GS2-Experience status. The rank cap value is determined by the grade entry matching the new grade level. Returns the updated grade status along with the Experience Namespace name and the updated Experience status.
Quantity specification supported: YES
Reversible action: YES
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| userId | string | ✓ | ~ 128 chars | User ID Specify #{userId} to substitute the currently logged-in user’s ID. | ||
| gradeName | string | ✓ | ~ 128 chars | Grade Model Name The name of the grade model that this status belongs to. References the grade model definition which contains the grade entry mappings, linked experience model, and reward addition tables. | ||
| propertyId | string | ✓ | ~ 1024 chars | Property ID A developer-defined identifier for this grade status, unique within the user and grade model. It is strongly recommended to use the same value as the property ID of the linked GS2-Experience status, as this ensures correct synchronization of grade values with rank caps. | ||
| gradeValue | long | 0 | 0 ~ 9223372036854775805 | Lost Grade | ||
| timeOffsetToken | string | ~ 1024 chars | Time offset token |
{
"action": "Gs2Grade:SubGradeByUserId",
"request": {
"namespaceName": "[string]Namespace name",
"userId": "[string]User ID",
"gradeName": "[string]Grade Model Name",
"propertyId": "[string]Property ID",
"gradeValue": "[long]Lost Grade",
"timeOffsetToken": "[string]Time offset token"
}
}action: Gs2Grade:SubGradeByUserId
request:
namespaceName: "[string]Namespace name"
userId: "[string]User ID"
gradeName: "[string]Grade Model Name"
propertyId: "[string]Property ID"
gradeValue: "[long]Lost Grade"
timeOffsetToken: "[string]Time offset token"transaction.service("grade").consume.sub_grade_by_user_id({
namespaceName="[string]Namespace name",
userId="[string]User ID",
gradeName="[string]Grade Model Name",
propertyId="[string]Property ID",
gradeValue="[long]Lost Grade",
timeOffsetToken="[string]Time offset token",
})Acquire Action
Gs2Grade:AddGradeByUserId
Add grade by User ID
Adds the specified grade value to the user’s current grade for the given grade model and property. After updating the grade value, the rank cap is automatically applied to the linked GS2-Experience status. The rank cap value is determined by the grade entry matching the new grade level. Returns the updated grade status along with the Experience Namespace name and the updated Experience status.
Quantity specification supported: YES
Reversible action: YES
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| userId | string | ✓ | ~ 128 chars | User ID Specify #{userId} to substitute the currently logged-in user’s ID. | ||
| gradeName | string | ✓ | ~ 128 chars | Grade Model Name The name of the grade model that this status belongs to. References the grade model definition which contains the grade entry mappings, linked experience model, and reward addition tables. | ||
| propertyId | string | ✓ | ~ 1024 chars | Property ID A developer-defined identifier for this grade status, unique within the user and grade model. It is strongly recommended to use the same value as the property ID of the linked GS2-Experience status, as this ensures correct synchronization of grade values with rank caps. | ||
| gradeValue | long | 0 | 0 ~ 9223372036854775805 | Gained Grade | ||
| timeOffsetToken | string | ~ 1024 chars | Time offset token |
{
"action": "Gs2Grade:AddGradeByUserId",
"request": {
"namespaceName": "[string]Namespace name",
"userId": "[string]User ID",
"gradeName": "[string]Grade Model Name",
"propertyId": "[string]Property ID",
"gradeValue": "[long]Gained Grade",
"timeOffsetToken": "[string]Time offset token"
}
}action: Gs2Grade:AddGradeByUserId
request:
namespaceName: "[string]Namespace name"
userId: "[string]User ID"
gradeName: "[string]Grade Model Name"
propertyId: "[string]Property ID"
gradeValue: "[long]Gained Grade"
timeOffsetToken: "[string]Time offset token"transaction.service("grade").acquire.add_grade_by_user_id({
namespaceName="[string]Namespace name",
userId="[string]User ID",
gradeName="[string]Grade Model Name",
propertyId="[string]Property ID",
gradeValue="[long]Gained Grade",
timeOffsetToken="[string]Time offset token",
})Gs2Grade:ApplyRankCapByUserId
Apply rank cap to GS2-Experience Status by User ID
Applies the rank cap corresponding to the current grade to the linked GS2-Experience status for the specified user (server-side operation). Looks up the grade entry matching the current grade value to determine the rank cap value. This is useful when the grade has been modified externally and the Experience rank cap needs to be synchronized. Returns the updated grade status along with the Experience Namespace name and the updated Experience status.
Quantity specification supported: NO
Reversible action: NO
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| userId | string | ✓ | ~ 128 chars | User ID Specify #{userId} to substitute the currently logged-in user’s ID. | ||
| gradeName | string | ✓ | ~ 128 chars | Grade Model Name The name of the grade model that this status belongs to. References the grade model definition which contains the grade entry mappings, linked experience model, and reward addition tables. | ||
| propertyId | string | ✓ | ~ 1024 chars | Property ID A developer-defined identifier for this grade status, unique within the user and grade model. It is strongly recommended to use the same value as the property ID of the linked GS2-Experience status, as this ensures correct synchronization of grade values with rank caps. | ||
| timeOffsetToken | string | ~ 1024 chars | Time offset token |
{
"action": "Gs2Grade:ApplyRankCapByUserId",
"request": {
"namespaceName": "[string]Namespace name",
"userId": "[string]User ID",
"gradeName": "[string]Grade Model Name",
"propertyId": "[string]Property ID",
"timeOffsetToken": "[string]Time offset token"
}
}action: Gs2Grade:ApplyRankCapByUserId
request:
namespaceName: "[string]Namespace name"
userId: "[string]User ID"
gradeName: "[string]Grade Model Name"
propertyId: "[string]Property ID"
timeOffsetToken: "[string]Time offset token"transaction.service("grade").acquire.apply_rank_cap_by_user_id({
namespaceName="[string]Namespace name",
userId="[string]User ID",
gradeName="[string]Grade Model Name",
propertyId="[string]Property ID",
timeOffsetToken="[string]Time offset token",
})Gs2Grade:MultiplyAcquireActionsByUserId
Multiply acquire actions by grade-based rate
Multiplies the quantities of the specified acquire actions by a rate multiplier determined by the user’s current grade. The rate multiplier is looked up from the grade model’s acquireActionRates using the specified rateName and the current grade value. The multiplied acquire actions are then executed as a transaction, enabling grade-based reward scaling (e.g., higher grades receive more resources).
Quantity specification supported: NO
Reversible action: NO
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| userId | string | ✓ | ~ 128 chars | User ID Specify #{userId} to substitute the currently logged-in user’s ID. | ||
| gradeName | string | ✓ | ~ 128 chars | Grade Model Name The name of the grade model that this status belongs to. References the grade model definition which contains the grade entry mappings, linked experience model, and reward addition tables. | ||
| propertyId | string | ✓ | ~ 1024 chars | Property ID A developer-defined identifier for this grade status, unique within the user and grade model. It is strongly recommended to use the same value as the property ID of the linked GS2-Experience status, as this ensures correct synchronization of grade values with rank caps. | ||
| rateName | string | ✓ | ~ 128 chars | Reward Addition Table Name A unique identifier for this multiplier table within the grade model. Referenced when applying grade-based reward scaling to specific acquire actions in transactions. | ||
| acquireActions | List<AcquireAction> | [] | 0 ~ 100 items | List of Acquire Actions | ||
| timeOffsetToken | string | ~ 1024 chars | Time offset token |
{
"action": "Gs2Grade:MultiplyAcquireActionsByUserId",
"request": {
"namespaceName": "[string]Namespace name",
"userId": "[string]User ID",
"gradeName": "[string]Grade Model Name",
"propertyId": "[string]Property ID",
"rateName": "[string]Reward Addition Table Name",
"acquireActions": [
{
"action": "[string]Type of Acquire Action",
"request": "[string]JSON string of the request used when executing the action"
}
],
"timeOffsetToken": "[string]Time offset token"
}
}action: Gs2Grade:MultiplyAcquireActionsByUserId
request:
namespaceName: "[string]Namespace name"
userId: "[string]User ID"
gradeName: "[string]Grade Model Name"
propertyId: "[string]Property ID"
rateName: "[string]Reward Addition Table Name"
acquireActions:
- action: "[string]Type of Acquire Action"
request: "[string]JSON string of the request used when executing the action"
timeOffsetToken: "[string]Time offset token"transaction.service("grade").acquire.multiply_acquire_actions_by_user_id({
namespaceName="[string]Namespace name",
userId="[string]User ID",
gradeName="[string]Grade Model Name",
propertyId="[string]Property ID",
rateName="[string]Reward Addition Table Name",
acquireActions={
{
action="[string]Type of Acquire Action",
request="[string]JSON string of the request used when executing the action"
}
},
timeOffsetToken="[string]Time offset token",
})