GS2-Buff

Buff feature

GS2-Buff provides a centralized function to manage compensation and rewards for microservices provided by GS2, as well as corrections to the maximum value of user data. It can be used to realize features such as increasing rewards for a limited period of time or raising the maximum value of user data while a subscription is active.

Rather than directly rewriting other microservices, GS2-Buff propagates correction values to each microservice via meta information called a “context stack” passed in API calls. A major characteristic is therefore that buffs can be applied or removed without rewriting the master data or player data of any microservice when the buff content or duration is changed.

Use cases

Typical use cases for GS2-Buff are as follows:

  • A limited-time campaign that doubles the amount of experience gained
  • A flat 20% discount on items sold in a specific showcase
  • Raising the maximum stamina value while a subscription is active
  • Increasing quest rewards only while a specific piece of equipment is equipped
  • Halving the consumption of enhancement materials during an event period
graph LR
  Player["Player"] -->|ApplyBuff| Buff[GS2-Buff]
  Buff -->|Context Stack| Player
  Player -->|API + Context Stack| Other["Other Microservices<br/>(GS2-Experience / GS2-Stamina / GS2-Showcase, etc.)"]
  Other -.reference.-> Buff
  Other -->|Corrected values| Player

Master Data Management

Registering master data allows you to configure data and behavior that can be used by the microservice.

Available master data types:

  • BuffEntryModel: Basic model that defines the correction value and its targets

Master data can be registered through the management console, imported from GitHub, or registered from CI using GS2-Deploy or various language CDKs.

Main configuration items of BuffEntryModel

Setting Description
name Unique name identifying the buff
metadata Arbitrary metadata for client-side use
expression Type of correction calculation (Rate Add / Mul / Value Add)
targetType Whether the correction target is a “model” or an “action”
targetModel / targetAction Target model/action name, condition GRN, and correction rate
priority Application priority. Calculated in order from the smallest value
applyPeriodScheduleEventId Validity period defined by a GS2-Schedule event

Buff entity

The unit of correction applied to each microservice. Defines the degree of increase or decrease for each parameter, with the base value set to 1.0.

The main types of buffs available and their calculation methods are as follows:

  • Rate Add: Adds to the correction rate
  • Mul: Multiplies the correction rate
  • Value Add: Directly adds to the value (only for model or action values)

Rate Add and Mul perform operations on the correction rate. For example, Rate Add 1.5 makes the correction value 2.5x, while Mul 1.5 makes it 1.5x. Value Add directly adds to the value; Value Add 5 results in a correction of +5.

Application priority

The correction value can be set with an application priority. Correction values are calculated in order starting from the one with the smallest priority value. For example, suppose the following correction values are defined:

Correction value type Correction value Application priority
Rate Add 0.2 1
Mul 1.5 2
Rate Add 0.2 3

In this case, the calculation is performed in the following order:

1.0 + 0.2 = 1.2
1.2 * 1.5 = 1.8
1.8 + 0.2 = 2.0

The final correction value is then 2.0x.

Correction calculations involving Value Add

If a correction value contains a “Value Add”, the correction calculation is calculated once before the priority at which the “Value Add” is defined, and then the value is added to the calculated value.

Correction Value Type Correction Value Application Priority
Rate Add 0.2 1
Mul 1.5 2
Value Add 2 3
Rate Add 0.2 4

In this case, the calculation of correction values up to just before the appearance of Value Add is performed first.

1.0 + 0.2 = 1.2
1.2 * 1.5 = 1.8

This correction value is then applied once to the input value. For example, if the input is 10, multiplying by 1.8 gives a corrected value of 18. The “Value Add” of +2 is then applied to the corrected value, resulting in a corrected value of 20.

Next, the calculation of the correction value from immediately after the appearance of Value Add is performed.

1.0 + 0.2 = 1.2

This correction value is then applied once to the input value. If the input is 10, multiplying by 1.2 gives a corrected value of 12. This value is added to the corrected value after “Value Add”.

20 + 12 = 32

Thus the final corrected value for an input of 10 is 32.

The entire equation can be summarized as follows, where the input value is x:

((x * (1.0 + 0.2) * 1.5) + 2) + x * (1.0 + 0.2)

Setting correction targets

There are two main types of buff correction targets: “models” and “actions”. Please refer to the documentation on buffs for each microservice to find out what models and actions can be set.

Models

Examples of models that can be applied include:

  • GS2-Experience rank cap
  • GS2-Stamina stamina maximum value
  • GS2-Showcase acquire action
  • GS2-Showcase consume action

Actions

Examples of actions that can be applied include:

  • GS2-Experience amount of experience gained
  • GS2-Stamina stamina recovery amount
  • GS2-Stamina stamina consumption amount

Setting the conditions for applying the correction

If applied to GS2-Showcase, to which DisplayItem is the correction value applied? If applied to GS2-Experience, to which Status should the correction value be applied? This parameter is used to set such application conditions.

Please refer to the documentation for each microservice’s buff to find out what application conditions can be set for each buff.

Models and GRNs

Specify the model and GRN as the application condition. Some buffs allow multiple models to be specified. For example, for GS2-Showcase, there is a pattern that specifies the GRN of the Showcase in order to apply the correction to all DisplayItems in the Showcase, and a pattern that specifies the GRN of a DisplayItem to apply the correction only to a specific DisplayItem in the Showcase.

Multiple application conditions can be set for a buff, and if any of the conditions is met, the correction value is applied. In other words, by setting multiple DisplayItems as application conditions for one buff entity, a single buff entity can define correction values for multiple DisplayItems.

How to apply corrections

Calling GS2-Buff’s ApplyBuff API returns a “context stack” response. Every API provided by GS2 has an interface that allows a context stack to be specified. By specifying the context stack returned by GS2-Buff in each API call, the buff can be applied.

In some high-level SDKs, such as those for game engines, the context stack is wrapped and does not need to be explicitly specified.

sequenceDiagram
  participant Player as Player
  participant Buff as GS2-Buff
  participant Other as Other Microservice
  Player->>Buff: ApplyBuff
  Buff-->>Player: Context Stack
  Player->>Other: API call (with Context Stack)
  Other-->>Player: Buff-applied value

Scope of application of buffs

The scope of buff application is broad, and buffs are also applied in master data acquisition APIs. If a master data acquisition API is called with the context stack specified, the buffed value is returned. If you want to display the value of the unbuffed state alongside it in the game, you need to combine API calls that do not include the context stack.

Linking buff entities to GS2-Schedule

Buff information in the context stack retains its validity period. This means that if a buff entity has a GS2-Schedule event set as its validity period, the buff will automatically stop being applied once outside the event period.

However, if the buff application conditions are changed or a new buff is added, you need to call ApplyBuff again to reflect the buffs.

Expiry date of context stacks

Context stacks have an expiry date. After 24 hours from the time ApplyBuff is called, the context stack loses its effect.

ApplyBuff should be executed again within 24 hours even if the conditions have not changed.

Overriding rates from scripts

By returning OverrideBuffRate (a pair of name and rate) as the return value of the synchronous applyBuffScript, you can dynamically override the rate of the corresponding buff at the time of application. This is useful when you want to vary buff rates finely according to player state, time of day, or equipped gear.

Script Triggers

Event triggers can invoke GS2-Script before and after buff application. Triggers support synchronous or asynchronous execution, and completion notifications can be delivered via doneTriggerTargetType, such as to Amazon EventBridge.

Main event triggers and script setting names are:

  • applyBuffScript (completion notification: applyDone): before and after applying a buff. The buff rate can also be dynamically overridden via the script’s return value.

Example implementation

Apply a buff

When ApplyBuff is called, the Gs2 object itself is switched to a new instance that holds the post-buff context. By using the returned Gs2 object for subsequent access, you can use each microservice with the buff applied.

    var domain = gs2.Buff.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Buff();
    gs2 = await domain.ApplyBuffAsync();

    // Accessing through the new gs2 object processes values with the buff applied
    const auto Domain = Gs2->Buff->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Buff(
    );
    const auto Future = Domain->ApplyBuff(
    );
    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();

    // Accessing through the new Gs2 object processes values with the buff applied

Get a list of registered buff entities

You can retrieve the currently registered buff entities for purposes such as displaying a list of in-game campaigns.

    var items = await gs2.Buff.Namespace(
        namespaceName: "namespace-0001"
    ).BuffEntryModelsAsync(
    ).ToListAsync();
    const auto It = Gs2->Buff->Namespace(
        "namespace-0001" // namespaceName
    )->BuffEntryModels();
    TArray<Gs2::UE5::Buff::Model::FEzBuffEntryModelPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

Get a specific buff entity

    var item = await gs2.Buff.Namespace(
        namespaceName: "namespace-0001"
    ).BuffEntryModel(
        buffEntryName: "buff-0001"
    ).ModelAsync();
    const auto Domain = Gs2->Buff->Namespace(
        "namespace-0001" // namespaceName
    )->BuffEntryModel(
        "buff-0001" // buffEntryName
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;
    const auto Item = Future->GetTask().Result();

Combining with other microservices

GS2-Buff is used in combination with other microservices rather than on its own. Examples of major integrations and corresponding correction targets are as follows:

Integration Examples of correction targets
GS2-Experience Experience gain amount, rank cap
GS2-Stamina Stamina maximum value, recovery amount, consumption amount
GS2-Showcase DisplayItem sale price, acquired quantity
GS2-Money2 Deposit amount, consumption amount
GS2-Inventory Item acquired quantity
GS2-Quest Quest reward acquired quantity
GS2-Enhance Number of enhancement materials consumed

For details on which model and action names each microservice accepts buffs for, please refer to the documentation of that microservice.

Detailed Reference