Documentation index for AI agents

GS2-Mission Transaction Actions

Specification of verify/consume/acquire 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-Mission adds to it.

The transaction actions of GS2-Mission address two kinds of target.

  • Counter: identified by the combination of namespace, user, and counter name. It holds one value per reset type.
  • Progress of a mission group: identified by the combination of namespace, user, and mission group. It records which tasks are complete and which rewards have been taken, per task.
OperationRepeated in one transactionAcross a nested transactionBoundary that separates targets
Adding to a counter
IncreaseCounterByUserId
Combined, and the values are added upAdded upnamespace, user, counter name
Subtracting from a counter
DecreaseCounterByUserId
Combined, and the values are added upFailsnamespace, user, counter name
Resetting a counter
ResetCounterByUserId
The scopes are combined into one action. Above a total of 20 scopes the combining stops and the second and later ones are silently droppedFailsnamespace, user, counter name
Setting a counter
SetCounterByUserId
Combined if equal; rejected when the transaction is issued if the values differFailsnamespace, user, counter name
Taking a reward
ReceiveByUserId BatchReceiveByUserId
Gathered into one, with duplicate task names removedFailsnamespace, user, mission group
Reverting a receive
RevertReceiveByUserId
Combined if the task is the same; rejected when the transaction is issued if the tasks differFailsnamespace, user, mission group
All verify actionsFirst wins. VerifyCounterValueByUserId is the exception: two with differing thresholds are both checkedNo collision, because they only readtarget, verify type, threshold

Only additions to a counter are written as a pure increment; everything else rewrites the counter as a whole. That is why additions merge even across a nested transaction, while subtracting, resetting, and setting cannot sit alongside another row on the same boundary. Two subtractions are fine because they are combined into one before execution.

Do not place reverts for different tasks in the same transaction. A revert writes to one row per mission group, so the boundary cannot be split per task. Listing the same task more than once is fine — the duplicates are removed — but listing two different tasks is rejected with an error (400). The check runs where acquire actions are gathered, so it applies not only to APIs that issue a transaction but also to APIs that merely preview the rewards. Receives are solved by folding them into a batch receive, but there is no API that takes an array of reverts, so the same fix is not available here.

Receives for the same mission group are gathered into a single batch receive however many you list. Writing the same task twice is not an error either; the duplicate is simply removed. Only when the gathered task count exceeds the limit of the receiving side does it become a too-many error (400) at run time.

There is one combination the table does not cover. You cannot take the reward of a task that the same transaction completed. Completion is recorded as a result of adding to a counter, but taking a reward looks at the progress as of the start of the transaction, so it cannot see that completion yet. Split the transaction.

Taking a large number of tasks at once can hit an internal limit on how much can be checked in one go. As a rough guide, this starts to happen somewhere above a dozen or so tasks in one transaction. Where a transaction that takes many rewards fails, split it into several.

Verify actions look at the state as of the start of the transaction. You cannot verify a counter value or a completion that is reached by the same transaction.

Take care with nested transactions

Additions to a counter are safe across a nested transaction: updates arriving by either route end up as one update. Progress is safe too, as long as the tasks differ.

Subtracting, resetting, and setting a counter are not. Touching the same counter both from the inside and from the outside makes the transaction fail. Check whether a reward or a draw moves one of your mission counters.

If you want to avoid these restrictions

Adding to and setting a counter, and reverting a receive, are acquire actions; subtracting from and resetting a counter, and taking a reward, are consume actions. Turning acquireActionUseJobQueue on clears a collision between an addition and a set, but a collision with a subtraction or a reset, and taking the reward of the same task twice, are between consume actions and need enableAtomicCommit turned off. Reverting receives for different tasks cannot be worked around by either setting: the check runs when the transaction is issued, before the setting is applied. Split the transaction.

Concurrency and retries

Additions to a counter do not conflict however many concurrent requests overlap. Within one mission group, completions and receives for different tasks do not conflict either.

Subtracting, resetting, and setting a counter, taking the same reward, and changes made through the console or the server API are written with a revision check, so they may return a conflict (409) when another update to the same target overlaps. It also happens across a counter’s reset boundary. Nothing is wrong with the request, so retrying will succeed.


Verify Action

Gs2Mission:VerifyCompleteByUserId

Verify Completion Status by User ID

Verifies the completion or receipt status of a mission task for the specified user.

Quantity specification supported: NO

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
missionGroupNamestring
~ 128 charsMission Group Name
The name of the mission group that this completion record belongs to. One Complete record exists per user per mission group.
userIdstring
~ 128 charsUser ID
Specify #{userId} to substitute the currently logged-in user’s ID.
verifyTypestring (enum)
enum {
  “completed”,
  “notCompleted”,
  “received”,
  “notReceived”,
  “completedAndNotReceived”
}
Type of verification
DefinitionDescription
completedCondition is achieved
notCompletedCondition is not achieved
receivedReward has been received
notReceivedReward has not been received
completedAndNotReceivedCondition is achieved and reward has not been received
missionTaskNamestring
~ 128 charsMission Task Model name
Unique Mission Task Model name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
multiplyValueSpecifyingQuantityboolfalseWhether to multiply the value used for verification when specifying the quantity
timeOffsetTokenstring~ 1024 charsTime offset token
{
    "action": "Gs2Mission:VerifyCompleteByUserId",
    "request": {
        "namespaceName": "[string]Namespace name",
        "missionGroupName": "[string]Mission Group Name",
        "userId": "[string]User ID",
        "verifyType": "[string]Type of verification",
        "missionTaskName": "[string]Mission Task Model name",
        "multiplyValueSpecifyingQuantity": "[bool]Whether to multiply the value used for verification when specifying the quantity",
        "timeOffsetToken": "[string]Time offset token"
    }
}
action: Gs2Mission:VerifyCompleteByUserId
request:
  namespaceName: "[string]Namespace name"
  missionGroupName: "[string]Mission Group Name"
  userId: "[string]User ID"
  verifyType: "[string]Type of verification"
  missionTaskName: "[string]Mission Task Model name"
  multiplyValueSpecifyingQuantity: "[bool]Whether to multiply the value used for verification when specifying the quantity"
  timeOffsetToken: "[string]Time offset token"
transaction.service("mission").verify.verify_complete_by_user_id({
    namespaceName="[string]Namespace name",
    missionGroupName="[string]Mission Group Name",
    userId="[string]User ID",
    verifyType="[string]Type of verification",
    missionTaskName="[string]Mission Task Model name",
    multiplyValueSpecifyingQuantity="[bool]Whether to multiply the value used for verification when specifying the quantity",
    timeOffsetToken="[string]Time offset token",
})

Gs2Mission:VerifyCounterValueByUserId

Verify counter value by User ID

Verifies that a counter’s scoped value meets the specified condition for the specified user.

Quantity specification supported: YES

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
userIdstring
~ 128 charsUser ID
Specify #{userId} to substitute the currently logged-in user’s ID.
counterNamestring
~ 128 charsCounter Model name
The name of the Counter Model that this counter instance is based on. Links to the counter model definition that specifies the scopes and reset timings.
verifyTypestring (enum)
enum {
  “less”,
  “lessEqual”,
  “greater”,
  “greaterEqual”,
  “equal”,
  “notEqual”
}
Type of verification
DefinitionDescription
lessCounter value is less than the specified value
lessEqualCounter value is less than or equal to the specified value
greaterCounter value is greater than the specified value
greaterEqualCounter value is greater than or equal to the specified value
equalCounter value is equal to the specified value
notEqualCounter value is not equal to the specified value
scopeTypestring (enum)
enum {
  “resetTiming”,
  “verifyAction”
}
“resetTiming”Scope type
Indicates whether this scoped value is based on a reset timing schedule or a verify action condition.
DefinitionDescription
resetTimingReset timing
verifyActionVerify Action
resetTypestring (enum)
enum {
  “notReset”,
  “daily”,
  “weekly”,
  “monthly”,
  “days”
}
{scopeType} == “resetTiming”
✓*
Reset timing
The reset timing for this scoped value. Determines the period over which the counter value is accumulated before being reset. Only applicable when scopeType is “resetTiming”.
DefinitionDescription
notResetNot Reset
dailyDaily
weeklyWeekly
monthlyMonthly
daysEvery fixed number of days
* Required if scopeType is “resetTiming”
conditionNamestring{scopeType} == “verifyAction”
✓*
~ 128 charsCondition Name
The name of the verify action condition that this scoped value corresponds to. Used to identify which condition scope this value belongs to. Only applicable when scopeType is “verifyAction”.
* Required if scopeType is “verifyAction”
valuelong00 ~ 9223372036854775805Count value
The accumulated counter value for this scope. Increases when the counter is incremented and decreases when decremented. The value is capped at the maximum and will not go below zero.
multiplyValueSpecifyingQuantityboolfalseWhether to multiply the value used for verification when specifying the quantity
timeOffsetTokenstring~ 1024 charsTime offset token
{
    "action": "Gs2Mission:VerifyCounterValueByUserId",
    "request": {
        "namespaceName": "[string]Namespace name",
        "userId": "[string]User ID",
        "counterName": "[string]Counter Model name",
        "verifyType": "[string]Type of verification",
        "scopeType": "[string]Scope type",
        "resetType": "[string]Reset timing",
        "conditionName": "[string]Condition Name",
        "value": "[long]Count value",
        "multiplyValueSpecifyingQuantity": "[bool]Whether to multiply the value used for verification when specifying the quantity",
        "timeOffsetToken": "[string]Time offset token"
    }
}
action: Gs2Mission:VerifyCounterValueByUserId
request:
  namespaceName: "[string]Namespace name"
  userId: "[string]User ID"
  counterName: "[string]Counter Model name"
  verifyType: "[string]Type of verification"
  scopeType: "[string]Scope type"
  resetType: "[string]Reset timing"
  conditionName: "[string]Condition Name"
  value: "[long]Count value"
  multiplyValueSpecifyingQuantity: "[bool]Whether to multiply the value used for verification when specifying the quantity"
  timeOffsetToken: "[string]Time offset token"
transaction.service("mission").verify.verify_counter_value_by_user_id({
    namespaceName="[string]Namespace name",
    userId="[string]User ID",
    counterName="[string]Counter Model name",
    verifyType="[string]Type of verification",
    scopeType="[string]Scope type",
    resetType="[string]Reset timing",
    conditionName="[string]Condition Name",
    value="[long]Count value",
    multiplyValueSpecifyingQuantity="[bool]Whether to multiply the value used for verification when specifying the quantity",
    timeOffsetToken="[string]Time offset token",
})

Consume Action

Gs2Mission:ReceiveByUserId

Receive rewards for mission accomplishment

Marks the specified mission task as received for the specified user.

Quantity specification supported: NO

Reversible action: YES

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
missionGroupNamestring
~ 128 charsMission Group Name
The name of the mission group that this completion record belongs to. One Complete record exists per user per mission group.
missionTaskNamestring
~ 128 charsTask Name
userIdstring
~ 128 charsUser ID
Specify #{userId} to substitute the currently logged-in user’s ID.
timeOffsetTokenstring~ 1024 charsTime offset token
{
    "action": "Gs2Mission:ReceiveByUserId",
    "request": {
        "namespaceName": "[string]Namespace name",
        "missionGroupName": "[string]Mission Group Name",
        "missionTaskName": "[string]Task Name",
        "userId": "[string]User ID",
        "timeOffsetToken": "[string]Time offset token"
    }
}
action: Gs2Mission:ReceiveByUserId
request:
  namespaceName: "[string]Namespace name"
  missionGroupName: "[string]Mission Group Name"
  missionTaskName: "[string]Task Name"
  userId: "[string]User ID"
  timeOffsetToken: "[string]Time offset token"
transaction.service("mission").consume.receive_by_user_id({
    namespaceName="[string]Namespace name",
    missionGroupName="[string]Mission Group Name",
    missionTaskName="[string]Task Name",
    userId="[string]User ID",
    timeOffsetToken="[string]Time offset token",
})

Gs2Mission:BatchReceiveByUserId

Receive rewards for multiple mission tasks in bulk

Marks multiple mission tasks as received at once within the same mission group.

Quantity specification supported: NO

Reversible action: NO

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
missionGroupNamestring
~ 128 charsMission Group Name
The name of the mission group that this completion record belongs to. One Complete record exists per user per mission group.
userIdstring
~ 128 charsUser ID
Specify #{userId} to substitute the currently logged-in user’s ID.
missionTaskNamesList<string>
1 ~ 100 itemsTask name list
timeOffsetTokenstring~ 1024 charsTime offset token
{
    "action": "Gs2Mission:BatchReceiveByUserId",
    "request": {
        "namespaceName": "[string]Namespace name",
        "missionGroupName": "[string]Mission Group Name",
        "userId": "[string]User ID",
        "missionTaskNames": [
            "[string]Task Name"
        ],
        "timeOffsetToken": "[string]Time offset token"
    }
}
action: Gs2Mission:BatchReceiveByUserId
request:
  namespaceName: "[string]Namespace name"
  missionGroupName: "[string]Mission Group Name"
  userId: "[string]User ID"
  missionTaskNames: 
    - "[string]Task Name"
  timeOffsetToken: "[string]Time offset token"
transaction.service("mission").consume.batch_receive_by_user_id({
    namespaceName="[string]Namespace name",
    missionGroupName="[string]Mission Group Name",
    userId="[string]User ID",
    missionTaskNames={
        "[string]Task Name"
    },
    timeOffsetToken="[string]Time offset token",
})

Gs2Mission:DecreaseCounterByUserId

Decrease counter by User ID

Subtracts the specified value from the counter for the specified user.

Quantity specification supported: YES

Reversible action: YES

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
counterNamestring
~ 128 charsCounter Model name
The name of the Counter Model that this counter instance is based on. Links to the counter model definition that specifies the scopes and reset timings.
userIdstring
~ 128 charsUser ID
Specify #{userId} to substitute the currently logged-in user’s ID.
valuelong
1 ~ 9223372036854775805Value to be subtracted
timeOffsetTokenstring~ 1024 charsTime offset token
{
    "action": "Gs2Mission:DecreaseCounterByUserId",
    "request": {
        "namespaceName": "[string]Namespace name",
        "counterName": "[string]Counter Model name",
        "userId": "[string]User ID",
        "value": "[long]Value to be subtracted",
        "timeOffsetToken": "[string]Time offset token"
    }
}
action: Gs2Mission:DecreaseCounterByUserId
request:
  namespaceName: "[string]Namespace name"
  counterName: "[string]Counter Model name"
  userId: "[string]User ID"
  value: "[long]Value to be subtracted"
  timeOffsetToken: "[string]Time offset token"
transaction.service("mission").consume.decrease_counter_by_user_id({
    namespaceName="[string]Namespace name",
    counterName="[string]Counter Model name",
    userId="[string]User ID",
    value="[long]Value to be subtracted",
    timeOffsetToken="[string]Time offset token",
})

Gs2Mission:ResetCounterByUserId

Reset counter by User ID

Resets the counter values for the specified scopes for the specified user.

Quantity specification supported: NO

Reversible action: NO

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
userIdstring
~ 128 charsUser ID
Specify #{userId} to substitute the currently logged-in user’s ID.
counterNamestring
~ 128 charsCounter Model name
The name of the Counter Model that this counter instance is based on. Links to the counter model definition that specifies the scopes and reset timings.
scopesList<ScopedValue>
1 ~ 20 itemsList of scopes
timeOffsetTokenstring~ 1024 charsTime offset token
{
    "action": "Gs2Mission:ResetCounterByUserId",
    "request": {
        "namespaceName": "[string]Namespace name",
        "userId": "[string]User ID",
        "counterName": "[string]Counter Model name",
        "scopes": [
            {
                "scopeType": "[string]Scope type",
                "resetType": "[string]Reset timing",
                "conditionName": "[string]Condition Name",
                "value": "[long]Count value",
                "nextResetAt": "[long]Next reset timing",
                "updatedAt": "[long]Last Updated Timestamp"
            }
        ],
        "timeOffsetToken": "[string]Time offset token"
    }
}
action: Gs2Mission:ResetCounterByUserId
request:
  namespaceName: "[string]Namespace name"
  userId: "[string]User ID"
  counterName: "[string]Counter Model name"
  scopes: 
    - scopeType: "[string]Scope type"
      resetType: "[string]Reset timing"
      conditionName: "[string]Condition Name"
      value: "[long]Count value"
      nextResetAt: "[long]Next reset timing"
      updatedAt: "[long]Last Updated Timestamp"
  timeOffsetToken: "[string]Time offset token"
transaction.service("mission").consume.reset_counter_by_user_id({
    namespaceName="[string]Namespace name",
    userId="[string]User ID",
    counterName="[string]Counter Model name",
    scopes={
        {
            scopeType="[string]Scope type",
            resetType="[string]Reset timing",
            conditionName="[string]Condition Name",
            value="[long]Count value",
            nextResetAt="[long]Next reset timing",
            updatedAt="[long]Last Updated Timestamp"
        }
    },
    timeOffsetToken="[string]Time offset token",
})

Acquire Action

Gs2Mission:RevertReceiveByUserId

Revert the status of mission accomplishment to unreceived

Reverts the received status of a mission task back to unreceived.

Quantity specification supported: NO

Reversible action: YES

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
missionGroupNamestring
~ 128 charsMission Group Name
The name of the mission group that this completion record belongs to. One Complete record exists per user per mission group.
missionTaskNamestring
~ 128 charsTask Name
userIdstring
~ 128 charsUser ID
Specify #{userId} to substitute the currently logged-in user’s ID.
timeOffsetTokenstring~ 1024 charsTime offset token
{
    "action": "Gs2Mission:RevertReceiveByUserId",
    "request": {
        "namespaceName": "[string]Namespace name",
        "missionGroupName": "[string]Mission Group Name",
        "missionTaskName": "[string]Task Name",
        "userId": "[string]User ID",
        "timeOffsetToken": "[string]Time offset token"
    }
}
action: Gs2Mission:RevertReceiveByUserId
request:
  namespaceName: "[string]Namespace name"
  missionGroupName: "[string]Mission Group Name"
  missionTaskName: "[string]Task Name"
  userId: "[string]User ID"
  timeOffsetToken: "[string]Time offset token"
transaction.service("mission").acquire.revert_receive_by_user_id({
    namespaceName="[string]Namespace name",
    missionGroupName="[string]Mission Group Name",
    missionTaskName="[string]Task Name",
    userId="[string]User ID",
    timeOffsetToken="[string]Time offset token",
})

Gs2Mission:IncreaseCounterByUserId

Increase counter by User ID

Adds the specified value to the counter for the specified user. After incrementing, all mission tasks referencing this counter are automatically re-evaluated, and any newly completed missions are returned in the changedCompletes response.

Quantity specification supported: YES

Reversible action: YES

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
counterNamestring
~ 128 charsCounter Model name
The name of the Counter Model that this counter instance is based on. Links to the counter model definition that specifies the scopes and reset timings.
userIdstring
~ 128 charsUser ID
Specify #{userId} to substitute the currently logged-in user’s ID.
valuelong
1 ~ 9223372036854775805Value to be added
timeOffsetTokenstring~ 1024 charsTime offset token
{
    "action": "Gs2Mission:IncreaseCounterByUserId",
    "request": {
        "namespaceName": "[string]Namespace name",
        "counterName": "[string]Counter Model name",
        "userId": "[string]User ID",
        "value": "[long]Value to be added",
        "timeOffsetToken": "[string]Time offset token"
    }
}
action: Gs2Mission:IncreaseCounterByUserId
request:
  namespaceName: "[string]Namespace name"
  counterName: "[string]Counter Model name"
  userId: "[string]User ID"
  value: "[long]Value to be added"
  timeOffsetToken: "[string]Time offset token"
transaction.service("mission").acquire.increase_counter_by_user_id({
    namespaceName="[string]Namespace name",
    counterName="[string]Counter Model name",
    userId="[string]User ID",
    value="[long]Value to be added",
    timeOffsetToken="[string]Time offset token",
})

Gs2Mission:SetCounterByUserId

Set counter by User ID

Sets the counter scoped values directly for the specified user, replacing existing values. Returns both the old and new counter states, as well as any newly completed missions in the changedCompletes response.

Quantity specification supported: NO

Reversible action: NO

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
counterNamestring
~ 128 charsCounter Model name
The name of the Counter Model that this counter instance is based on. Links to the counter model definition that specifies the scopes and reset timings.
userIdstring
~ 128 charsUser ID
Specify #{userId} to substitute the currently logged-in user’s ID.
valuesList<ScopedValue>0 ~ 20 itemsList of values to be set
timeOffsetTokenstring~ 1024 charsTime offset token
{
    "action": "Gs2Mission:SetCounterByUserId",
    "request": {
        "namespaceName": "[string]Namespace name",
        "counterName": "[string]Counter Model name",
        "userId": "[string]User ID",
        "values": [
            {
                "scopeType": "[string]Scope type",
                "resetType": "[string]Reset timing",
                "conditionName": "[string]Condition Name",
                "value": "[long]Count value",
                "nextResetAt": "[long]Next reset timing",
                "updatedAt": "[long]Last Updated Timestamp"
            }
        ],
        "timeOffsetToken": "[string]Time offset token"
    }
}
action: Gs2Mission:SetCounterByUserId
request:
  namespaceName: "[string]Namespace name"
  counterName: "[string]Counter Model name"
  userId: "[string]User ID"
  values: 
    - scopeType: "[string]Scope type"
      resetType: "[string]Reset timing"
      conditionName: "[string]Condition Name"
      value: "[long]Count value"
      nextResetAt: "[long]Next reset timing"
      updatedAt: "[long]Last Updated Timestamp"
  timeOffsetToken: "[string]Time offset token"
transaction.service("mission").acquire.set_counter_by_user_id({
    namespaceName="[string]Namespace name",
    counterName="[string]Counter Model name",
    userId="[string]User ID",
    values={
        {
            scopeType="[string]Scope type",
            resetType="[string]Reset timing",
            conditionName="[string]Condition Name",
            value="[long]Count value",
            nextResetAt="[long]Next reset timing",
            updatedAt="[long]Last Updated Timestamp"
        }
    },
    timeOffsetToken="[string]Time offset token",
})