GS2-Mission

ミッション・実績機能

ゲーム内の蓄積した行動に基づいて、プレイヤーに報酬を与えるための仕組みです。 一般的に 実績・トロフィー・ミッション と呼ばれる機能を実現するための機能です。

ミッションカウンター

プレイヤーの行動に基づく回数を数えるためのエンティティです。 「クエストをクリアした回数」「キャラクターを強化した回数」「ガチャを引いた回数」といったゲーム内の行動回数をカウントするためのカウンターを用意します。

カウンターにはスコープを設定できます。 スコープには以下の値を設定可能です。

スコープの種類スコープの内容
リセットしないゲームプレイ開始からの総計
毎日X時にリセット当日実行した回数
毎週X曜日X時にリセット今週実行した回数
毎月X日X時にリセット今月実行した回数
一定日数ごとにリセット基準時刻から指定日数ごとにリセット
検証アクションにマッチした時だけカウントアップverifyAction の実行結果に基づいてカウンターを上昇

カウンターの値は各スコープで管理され、ミッションの達成条件には各スコープの値を利用できます。

検証アクションによるスコープ制御

scopeType=verifyAction を利用すると、conditionName と condition により任意条件を定義し、 他のマイクロサービスの検証結果に応じてカウンターを上昇するかの制御ができます。 これにより、特定のイベント期間だけカウンターを上昇するスコープや、特定のキャラクターを編成している状態でのみ上昇するスコープを作ることができます。

チャレンジ期間

CounterModel には challengePeriodEventId を設定でき、GS2-Schedule のイベント GRN を指定してカウンター操作期間を制限できます。 指定期間外はカウンターを更新できないため、期間限定イベントなどで使用する際に有効です。

ミッションタスク

プレイヤーに提示する目標を定義するマスターデータです。

「ミッションカウンター」 と 「スコープ」 と「目標値」、そしてその目標を達成した時に得られる「報酬」を設定します。 たとえば以下のような設定ができます。

ミッションカウンタースコープの種類目標値報酬
クエストをクリアした回数毎日X時にリセット10アイテムA
クエストをクリアした回数毎週X曜日X時にリセット50アイテムB
キャラクターを強化した回数毎日X時にリセット5アイテムC

検証アクションを使用した達成判定

verifyCompleteTypeverifyActions を指定することで、他のマイクロサービスの検証アクションを満たしているかでタスクの達成判定が可能です。 この機能を利用する場合、GS2-Mission が提供する Complete オブジェクトによる達成判定は利用できませんので達成状態はクライアントで計算した上で受け取りUIを制御する必要があります。

チャレンジ期間

MissionTaskModelchallengePeriodEventId により、達成可能期間を GS2-Schedule のイベントで制限できます。 達成済みのタスクは期間を過ぎても受け取ることが可能ですが、ミッションタスクにリセット間隔が設定されている場合はリセットタイミングを迎えると受け取りができなくなります。

ミッショングループ

複数のミッションタスクを束ねるエンティティです。 ミッショングループには報酬の受け取りフラグのリセット周期を設定できます。

ミッションカウンタースコープの種類目標値報酬
クエストをクリアした回数毎日X時にリセット10アイテムA
キャラクターを強化した回数毎日X時にリセット5アイテムC

これらのミッションタスクを一つのミッショングループに関連付けて、ミッショングループの報酬の受け取りフラグのリセット周期にも「毎日X時にリセット」を設定することで ミッションタスクを毎日達成すると、毎日報酬を受け取れるようになります。

任意日数でのリセット

resetTypedays を指定することで、anchorTimestamp で指定した起点時刻から指定日数ごとに報酬受取フラグをリセットできます。 例えば、イベント開始から3日ごとにリセットする、といった運用が可能です。

スクリプトトリガー

ネームスペースに missionCompleteScriptcounterIncrementScriptreceiveRewardsScript を設定すると、ミッション達成やカウンター上昇、報酬受け取りの前後でカスタムスクリプトを呼び出せます。スクリプトは同期/非同期の実行方式を選択でき、非同期では GS2-Script や Amazon EventBridge 経由の外部連携にも対応します。

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

  • missionCompleteScript(完了通知: missionCompleteDone): ミッション達成の前後
  • counterIncrementScript(完了通知: counterIncrementDone): カウンター上昇の前後
  • receiveRewardsScript(完了通知: receiveRewardsDone): 報酬受取の前後

プッシュ通知

設定できる主なプッシュ通知と設定名は以下の通りです。

  • completeNotification: ミッションタスク達成時に通知

オフライン端末へのモバイルプッシュ転送にも対応し、報酬受取を促すことができます。

マスターデータ運用

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

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

  • CounterModel: カウント対象とリセット周期
  • MissionGroupModel: グループごとの報酬リセット設定
  • MissionTaskModel: 達成条件と報酬

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

GS2-Buff 連携

GS2-Buff と連携すると、ミッションタスクモデルの completeAcquireActions をバフで補正し、イベントなどに応じて報酬量を柔軟に調整できます。

実装例

ミッションカウンターを上昇

ミッションカウンターを上昇はゲームエンジン用の SDK では処理できません。

GS2-Quest のクリア報酬や、GS2-Lottery の抽選報酬としてカウンターを上昇するといった方法で実装してください。

ミッションタスクの達成状況・報酬受け取り情報を取得

    var item = await gs2.Mission.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Complete(
        missionGroupName: "mission-group-0001"
    ).ModelAsync();
    const auto Domain = Gs2->Mission->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Complete(
        "mission-group-0001" // missionGroupName
    );
    const auto item = Domain.Model();

ミッション達成報酬を受け取り

    var result = await gs2.Mission.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Complete(
        missionGroupName: "mission-group-0001"
    ).ReceiveRewardsAsync(
        missionTaskName: "mission-task-0001"
    );
    const auto Domain = Gs2->Mission->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Complete(
        "mission-group-0001" // missionGroupName
    );
    const auto Future = Domain->ReceiveRewards(
        "mission-task-0001"
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;

ミッションカウンターの値を取得

    var item = await gs2.Mission.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Counter(
        counterName: "quest_complete"
    ).ModelAsync();
    const auto Domain = Gs2->Mission->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Counter(
        "quest_complete" // counterName
    );
    const auto item = Domain.Model();

ミッションの目標値を取得

    var items = await gs2.Mission.Namespace(
        namespaceName: "namespace-0001"
    ).MissionGroupModel(
        missionGroupName: "mission-group-0001"
    ).MissionTaskModelsAsync(
    ).ToListAsync();
    const auto Domain = Gs2->Mission->Namespace(
        "namespace-0001" // namespaceName
    )->MissionGroupModel(
        "mission-group-0001" // missionGroupName
    );
    const auto It = Domain->MissionTaskModels(
    );
    TArray<Gs2::UE5::Mission::Model::FEzMissionTaskModelPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

詳細なリファレンス