GS2-Buff

バフ機能

GS2-Buff は GS2 が提供するマイクロサービスの対価や報酬、ユーザーデータの最大値の補正を一元管理する機能を提供します。 期間限定で報酬を増加させる機能や、サブスクリプション契約状態であればユーザーデータの最大値が増加するような機能を実現するために利用できます。

GS2-Buff は他のマイクロサービスを直接書き換えるのではなく、API 呼び出しの際に渡される「コンテキストスタック」というメタ情報を介して各マイクロサービスに補正値を伝播させます。 そのため、バフの内容や期間を変更しても各マイクロサービスのマスターデータやプレイヤーデータをいっさい書き換えることなく適用・解除が行えるのが大きな特徴です。

ユースケース

GS2-Buff が想定する代表的なユースケースは以下の通りです。

  • 期間限定で経験値の取得量を 2 倍にするキャンペーン
  • 特定のショーケースで販売される商品の価格を一律 20% オフ
  • サブスクリプション契約中はスタミナの最大値を引き上げる
  • 特定の装備を装備中のみクエスト報酬を増加させる
  • イベント期間中だけ強化素材の消費量を半減させる
graph LR
  Player["プレイヤー"] -->|ApplyBuff| Buff[GS2-Buff]
  Buff -->|コンテキストスタック| Player
  Player -->|API + コンテキストスタック| Other["他のマイクロサービス<br/>(GS2-Experience / GS2-Stamina / GS2-Showcase など)"]
  Other -.参照.-> Buff
  Other -->|補正後の値| Player

マスターデータ管理

マスターデータを登録することでマイクロサービスで利用可能なデータや振る舞いを設定できます。

マスターデータの種類には以下があります。

  • BuffEntryModel: 補正値と対象を定義する基本モデル

マスターデータの登録はマネージメントコンソールから登録する他、GitHubからデータを反映したり、GS2-Deployを使ってCIから登録するようなワークフローを組むことが可能です。

BuffEntryModel の主な設定項目

設定項目 説明
name バフを識別する一意な名前
metadata クライアント側で利用する任意メタデータ
expression 補正計算式の種別 (Rate Add / Mul / Value Add)
targetType 補正対象が「モデル」か「アクション」か
targetModel / targetAction 補正対象のモデル名・アクション名・条件 GRN・補正レート
priority 適用優先度。値が小さいものから順に計算
applyPeriodScheduleEventId GS2-Schedule のイベントによる有効期間

バフエンティティ

各マイクロサービスに加える補正の単位です。 基礎値を 1.0 として、各パラメータに対してどの程度増減させるかを定義します。

利用できる主なバフの種類と計算方法は以下の通りです。

  • Rate Add: 補正レートに加算
  • Mul: 補正レートに乗算
  • Value Add: 値を直接加算(モデルやアクションの数値のみ)

Rate AddMul は補正レートに対する演算で Rate Add 1.5 とすると補正値は2.5倍に、Mul 1.5 とすると補正値は1.5倍になります。Value Add は値を直接加算する演算で Value Add 5 とすると補正値は +5 となります。

適用優先度

補正値には適用優先度を設定できます。優先度に設定された値が小さい補正値から順番に補正値の計算が行われます。 たとえば、以下の補正値が定義されていたとします。

補正値の種類 補正値 適用優先度
Rate Add 0.2 1
Mul 1.5 2
Rate Add 0.2 3

この場合、以下の順番で補正値の計算が実行されます。

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

そして、最終的な補正値は 2.0倍 となります。

Value Add が含まれる補正計算

補正値の中に 「Value Add」が含まれる場合は、補正計算が 「Value Add」の定義されている優先度の前で一旦計算し、計算後の値に対して値の加算が行われます。

補正値の種類 補正値 適用優先度
Rate Add 0.2 1
Mul 1.5 2
Value Add 2 3
Rate Add 0.2 4

この場合、まずは Value Add が出現する直前までの補正値の計算が実行されます。

1.0 + 0.2 = 1.2
1.2 * 1.5 = 1.8

そして、入力値に一旦この補正値を適用します。例えば入力が 10 の場合、1.8倍して補正後の値は 18 となります。 補正後の値に対して「Value Add」の +2 が適用され、補正後の値は 20 となります。

続けて Value Add が出現した直後からの補正値の計算が実行されます。

1.0 + 0.2 = 1.2

そして、入力値に一旦この補正値を適用します。入力が 10 の場合、1.2倍して補正後の値は 12 となります。 「Value Add」 後の補正値にこの値を加算します。

20 + 12 = 32

これで、入力が 10 の場合の最終的な補正後の値は 32 となります。

全体の式をまとめると以下のようになります。入力値を x としています。

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

補正対象の設定

バフによる補正対象は大きく2種類あり、「モデル」と「アクション」があります。 どのようなモデルやアクションを設定できるかは各マイクロサービスのバフに関するドキュメントを参照してください。

モデル

モデルの適用対象の例には以下のようなものがあります。

  • GS2-Experience のランクキャップ
  • GS2-Stamina のスタミナ最大値
  • GS2-Showcase の入手アクション
  • GS2-Showcase の消費アクション

アクション

アクションの適用対象の例には以下のようなものがあります。

  • GS2-Experience の経験値加算量
  • GS2-Stamina のスタミナ回復量
  • GS2-Stamina のスタミナ消費量

補正適用条件の設定

GS2-Showcase に適用するとして、どの DisplayItem に補正値を適用するのか? GS2-Experience に適用するとして、どの Status に補正値を適用するのか? といった適用条件を設定するのがこのパラメーターです。

各バフに対してどのような適用条件が設定できるかは各マイクロサービスのバフに関するドキュメントを参照してください。

モデルとGRN

適用条件にはモデルとGRNを指定します。バフによっては複数のモデルを指定できる場合があります。 例えば、GS2-Showcase であれば、Showcase 内の全ての DisplayItem に補正を適用するために、Showcase の GRN を指定するパターンと Showcase 内の特定の DisplayItem にのみ補正を適用するために DisplayItem の GRN を指定するパターンがあります。

バフには複数の適用条件を設定でき、いずれかの条件に該当すると補正値が適用されます。 つまり、1つのバフエンティティに複数の DisplayItem を適用条件に設定することで、1つのバフエンティティで複数の DisplayItem に対する補正値を定義できます。

補正の適用方法

GS2-Buff の ApplyBuff API を呼び出すと 「コンテキストスタック」 が応答されます。 GS2 が提供するあらゆるAPIにはコンテキストスタックを設定可能なインターフェースが用意されています。 GS2-Buff が応答した コンテキストスタック を各APIの呼び出し時に指定することでバフを適用できます。

ゲームエンジン向けのSDKのような高レベルなSDKでは、コンテキストスタックの指定はラップされ明示的に指定する必要がないケースがあります。

sequenceDiagram
  participant Player as プレイヤー
  participant Buff as GS2-Buff
  participant Other as 他のマイクロサービス
  Player->>Buff: ApplyBuff
  Buff-->>Player: コンテキストスタック
  Player->>Other: API 呼び出し (コンテキストスタック付与)
  Other-->>Player: バフ適用済みの値

補正の適用範囲

バフの適用範囲は広範囲で、マスターデータの取得APIでもバフが適用されます。 コンテキストスタックを指定した状態でマスターデータ取得APIを呼び出すと、バフがかかった状態の値が応答されます。 ゲーム内でバフがかかっていない状態の値を併記したい場合は、コンテキストスタックを付与しないAPIアクセスを組み合わせて表示する必要があります。

バフエンティティと GS2-Schedule の連携

コンテキストスタック内のバフ情報は有効期間を保持します。 つまり、バフエンティティに有効期間として GS2-Schedule のイベントが設定されている場合、イベント期間外になった際には自動的にバフは適用されなくなります。

ただし、新しくバフの適用条件が変更になったり、新しいバフが追加された場合は改めて ApplyBuff を呼び出してバフを反映する必要があります。

コンテキストスタックの有効期限

コンテキストスタックには有効期限が設定されています。 ApplyBuff を呼び出した時点から24時間を経過するとコンテキストスタックは効力を失います。

ApplyBuff は条件に変更がなくとも24時間以内に再度実行するようにしてください。

スクリプトによるレート上書き

applyBuffScript の同期スクリプトの戻り値として OverrideBuffRate (namerate のペア) を返すことで、バフ適用時に該当バフのレートを動的に上書きできます。 プレイヤーの状態や時間帯、所持装備に応じて細かくバフのレートを変動させたい場合に活用できます。

スクリプトトリガー

バフ適用の前後に GS2-Script を呼び出すイベントトリガーを設定できます。トリガーは同期・非同期の実行方式を選択でき、doneTriggerTargetType により Amazon EventBridge などへの完了通知も可能です。

設定できる主なイベントトリガーとスクリプト設定名は以下の通りです。

  • applyBuffScript(完了通知: applyDone): バフ適用の前後。スクリプトの戻り値でバフの適用レートを動的に上書きすることも可能です。

実装例

バフを適用

ApplyBuff を呼び出すと、Gs2 オブジェクト自体がバフ適用後のコンテキストを保持した新しいインスタンスに切り替わります。 返却された Gs2 オブジェクトを以降のアクセスで使用することで、バフが適用された状態で各マイクロサービスを利用できます。

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

    // 新しい gs2 オブジェクトを通してアクセスするとバフがかかった値で処理される
    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();

    // 新しい Gs2 オブジェクトを通してアクセスするとバフがかかった値で処理される

登録済みのバフエンティティ一覧の取得

ゲーム内のキャンペーン一覧表示などのために、現在登録されているバフエンティティを取得できます。

    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());
    }

特定のバフエンティティの取得

    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();

他のマイクロサービスとの組み合わせ

GS2-Buff は単体ではなく他のマイクロサービスと組み合わせて利用します。主な連携先と対応する補正対象の例は以下の通りです。

連携先 補正対象の例
GS2-Experience 経験値取得量、ランクキャップ
GS2-Stamina スタミナ最大値、回復量、消費量
GS2-Showcase DisplayItem の販売価格、入手数量
GS2-Money2 入金量、消費量
GS2-Inventory アイテムの取得数量
GS2-Quest クエスト報酬の取得数量
GS2-Enhance 強化素材の消費数

各マイクロサービスがどのモデル名・アクション名に対するバフを受け付けるかは、それぞれのマイクロサービスのドキュメントを参照してください。

詳細なリファレンス