GS2-Buff
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 rateMul: Multiplies the correction rateValue 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.0The 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.8This 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.2This 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 = 32Thus 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 appliedGet 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.