GS2 Blog

Game Server Services(https://gs2.io/) の最新情報をお届けします

GS2-Account の認証時のスクリプトに前回ログインからの経過時間が渡るようになりました

はじめに

GS2-Account はゲームが必要とする認証機能を提供するサービスです。

機能追加の背景

「久しぶりゲームを再開してくれたプレイヤーにカムバックボーナスを付与したい」というようなニーズがあります。
このようなニーズを満たすために認証時のスクリプトに前回ログインからの経過時間を渡すようにし、スクリプトから GS2-Schedule のカムバック用のイベントを開始状態にすることで、カムバック時にのみ得られる報酬を設定できます。

追加された機能の詳細

namespace = args.namespace
account = args.account
elapsedHours = args.elapsedHours

result = {
}

GS2-Account の認証時のスクリプトの引数に「elapsedHours」が追加されました。
この値を使って判定してください。

GS2の各種パラメーターに補正値を適用する GS2-Buff が公開されました

はじめに

GS2 はさまざまなマスターデータやユーザーデータを取り扱います。
イベントやサブスクリプションの特典として、各種パラメーターに補正値を適用したいことがあります。

例えば、イベント期間中は「スタミナ消費量半減」「クエスト報酬2倍」「スタミナ最大値2倍」というようなことです。

新サービス追加の背景

これまではこのような補正値を適用する手段がなく、マスターデータをイベント期間のみ差し替えるような対応が必要でした。
しかし、マスターデータの更新は予約することができないため、メンテナンス期間をとってメンテナンスとしてマスターデータの更新作業を行うようなオペレーションが必要でした。

新サービスの詳細

GS2のさまざまなパラメーターに対して補正値を適用できるようになり、なおかつ補正値は GS2-Schedule が管理するイベントの期間と連動させることができます。
これにより、メンテナンス期間をとったりマスターデータを更新するオペレーションをすることなく、値の補正を行えるようになりました。

バフエンティティ

各マイクロサービスに加える補正の単位です。 基礎値を 1.0 として、各パラメータに対してどの程度増減させるかを定義します。 補正値の定義方法は「Add」と「Mul」が用意されており、Add 1.5 とすると補正値は2.5倍に、Mul 1.5 とすると補正値は1.5倍になります。

適用優先度

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

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

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

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

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

補正の適用範囲

バフの適用範囲は広範囲で、マスターデータの取得APIでもバフが適用されます。

バフの適用方法

    gs2 = await gs2.Buff.Namespace(
        "buff"
    ).Me(
        GameSession
    ).Buff().ApplyBuffAsync();

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

詳細は以下のドキュメントを参考にしてください

docs.gs2.io

GS2-Inventory の巨大インベントリのアイテム入手・消費時のスクリプトを実装できるようになりました

はじめに

GS2-Inventory はアイテムの所持数量を管理するマイクロサービスです。
なかでも巨大インベントリは 64bit整数値 の範囲を超えるアイテムの所持数量を管理するマイクロサービスです。

クッキークリッカーを代表するインフレ系ゲームのようなゲームでクッキーの所持数量を管理するために利用できます。

今回の更新で解消された課題

これまで巨大インベントリのアイテム入手・消費時のスクリプトは設定できませんでした。

追加された機能の詳細

新しく巨大インベントリのアイテム入手・消費時のスクリプトを設定できるようになりました。
スクリプトの戻り値では、処理を継続するかに加えて、入手量・消費量の対して倍率による補正をかけられるようになりました。

result = {
  permit=true,
  rate=1.5
}

のようにスクリプトを設定することで、報酬の量を1.5倍にすることができます。
ただし、巨大インベントリが扱う値の性質上若干の計算誤差が生じます。

GS2-Quest でクエスト失敗時の報酬量調整が可能となりました

はじめに

GS2-Quest はインゲームの挑戦料・報酬・クリア状況を管理するためのマイクロサービスです。

今回の更新で解消された課題

GS2-Quest はクエストごとに報酬として「クリア時に得られる報酬」「初めてクリアした時に得られる報酬」「失敗した時に得られる報酬」の3種類を設定できます。

一番直感から外れるのが今回改善が行われた「失敗した時に得られる報酬」でしょう。
元々、クエストに失敗した場合に開始時に消費したスタミナを返却するような用途を想定して機能を実装していました。

クリア時の報酬はインゲームで宝箱を開け損ねたりした時のためにマスターデータに定義するのは入手可能な最大量で、クエストの終了報告APIでマスターデータで定義された報酬を最大量として、それ以下であれば任意の数量に結果を変更することができるようにしていました。
しかし、前述の通り失敗時の報酬はスタミナの返却を想定していたため、失敗報告をした際にマスターデータに定義された全数量を報酬として入手する仕様としてました。

しかし、利用者のさまざまなユースケースを伺っているうちに「失敗時にスタミナを返却しない代わりにインゲーム内で入手したゴールドだけは入手できるようにしたい」というような当初想定していなかった仕様があることがわかりました。

追加された機能の詳細

エストの終了報告APIに失敗報告する際にも数量報告が可能となりました。
そのため、さきほどのゴールドの仕様であれば「クリア時に得られる報酬」「失敗した時に得られる報酬」にそれぞれゴールドの入手可能最大量を指定しておき終了報告にはクエストの成功・失敗に関わらずインゲームで入手したゴールドの量を報告することで一部の報酬を得ることができるようになりました。

docs.gs2.io

GS2-Exchange の非同期交換に待機時間の部分スキップ機能が追加されました

はじめに

GS2-Exchange はなんらかの対価としてプレイヤーが所持するリソースを消費して、何らかのリソースを入手するための交換処理を実装するためのマイクロサービスです。

GS2-Exchange の交換には即時交換と、非同期交換の2モードが存在し非同期交換モードでは交換APIを呼び出してから現実時間で一定時間経過後にリソースの入手が行えます。
遠征や合成などゲーム内にリアル時間の経過を求める機能を実装するために活用できます。

これまで有していた課題

交換の待機時間を短縮する仕組み自体はありましたが、即座に受け取り可能とするもののみで「4時間の待機時間のうち2時間を短縮する」「待機時間の50%を短縮する」といった操作は行えませんでした。

追加された機能の詳細

新しく GS2-Exchange の入手アクションに SkipByUserId が追加されました。
https://docs.gs2.io/ja/api_reference/exchange/stamp_sheet/#gs2exchangeskipbyuserid

このアクションではスキップの方法として4つの方式を用意しています。

complete 即座に受け取り可能な状態にする
minutes スキップする絶対分数を指定して待機時間を短縮する
totalRate 待機時間全体における割合を指定して待機時間を短縮する
remainRate 残りの待機時間における割合を指定して待機時間を短縮する

この機能を利用することで 「待機時間の5分スキップチケット」 といったアイテムを実装することが可能となります。

時刻補正が可能なAPIの種類が追加されました

はじめに

運営型のゲームにおいてイベントのような時刻に関わる処理は重要な要素です。
プロジェクトによってはQAのためにメンテナンスモードにしてプレイヤーを追い出し、サーバーの時刻設定を変更して動作確認するという話すら聞いたことがあり、時刻が関わる処理はデバッグやQAがしづらいという問題があります。

GS2ではこのような問題を解決するために、アクセストークン発行時に時刻のオフセットを指定できるようにしています。
そのため、QAスタッフは1週間進んだタイムゾーンで動作確認できたり、ユニットテストですぐさま1時間後のアクセスとしてAPIを呼び出すようなことができるようになっています。

これまでの課題

時刻オフセットはアクセストークンに含まれているため、アクセストークンを使用しないユーザーIDを直値で指定するようなアクセスでは時刻オフセットを適用できない課題がありました。
これは、時刻オフセットを適用するためにいちいちアクセストークンを作成してAPIを呼び出す必要があり、しかもアクセストークンを使ったアクセス手段のないAPIには時刻オフセットを適用できない課題がありました。

追加された機能

新しく「時刻オフセットトークン」が追加されました。
時刻オフセットトークンはアクセストークンに非常に似た機能でユーザー認可機能をもたず、時刻補正のみを担うトークンでアクセストークン同様 GS2-Auth を使って発行できます。

~ByUserId のようなユーザーIDを指定してAPIを呼び出せるインターフェースに時刻オフセットトークンを指定するパラメーターが追加されており、ここに時刻オフセットトークンを指定することで時刻補正が可能となります。

docs.gs2.io

シーズンレーティング機能の提供を開始しました

はじめに

近年のPvPゲームではシーズンごとにランクマッチが実施され、ブロンズ→シルバー→ゴールド→プラチナ のように昇格していくスタイルが一般化しました。
GS2 も元々レーティング機能は持っていましたが、シーズンで区切ることはできず、ランクではなくレート値の増減のみで表現するレートマッチのみの提供でした。

そこで、近年増えてきたランクマッチ用に GS2-SeasonRating 機能の提供を開始しました。

機能の概要

まずはシーズンを定義します。シーズンにはランクごとの情報を表す複数ティアーと、開催期間を設定します。
ティアーには勝負によって変動するポイントの増減量のレンジと、ティアーに昇格した際に得られるボーナスポイントを持つことができます。
また、ティアーごとに試合に参加するだけでポイントが減算される参加料を設定することも可能です。
ポイントは GS2-Experience の経験値として管理され、ティアーの閾値も GS2-Experience のランクアップ経験値閾値をつかって管理します。

つまり、GS2-SeasonRating は GS2-Experience の経験値を試合結果に応じて増減するインターフェースということになります。

機能の詳細

API仕様は従来のレーティング機能と対して変わりません。
プレイヤーは対戦開始時に投票用紙(Ballot)を取得し、対戦終了時に Ballot を使って投票(Vote)します。

全員の試合結果投票を受け付けるか、最初の投票を受け付けてから5分が経過すると集計処理が実行されます。
集計処理は受け付けた試合結果の内容を多数決で判定し、多数派が報告した結果を採用します。

結果に応じて ティアーの変動幅を参加人数(順位のパターン数)で均等に分け、各プレイヤーの順位に基づいてポイントの変動量を決定し、GS2-Experience の経験値を加減算します。

使い方

ランクマッチを開始

GS2-Matchmaking のネームスペース設定に GS2-SeasonRating との連携設定が増えています。
ここを有効化し、対象となる GS2-SeasonRating のネームスペースを設定することで、マッチメイキング完了時に GS2-SeasonRating に GS2-Matchmaking のギャザリング名と同じ名前でランクマッチセッションが作成されます。

以降は GS2-Matchmaking のギャザリング名を sessionName として指定してAPIを呼び出してください。

投票用紙を取得

    var item = await gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Ballot(
        seasonName: "rating-0001",
        sessionName: gathering.Name,
        numberOfPlayer: 4
    ).ModelAsync();
    
    var body = item.Body; // 投票用紙本体
    var signature = item.Signature; // 投票用紙の妥当性を検証する署名

投票を実行

    var result = await gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    ).VoteAsync(
        ballotBody: ballot.Body, // 投票用紙本体
        ballotSignature: ballot.Signature, // 投票用紙の妥当性を検証する署名
        gameResults: new List<Gs2.Unity.Gs2SeasonRating.Model.EzGameResult> {
            new Gs2.Unity.Gs2SeasonRating.Model.EzGameResult() {
                Rank = 1,
                UserId = "user-0001",
            },
            new Gs2.Unity.Gs2SeasonRating.Model.EzGameResult() {
                Rank = 2,
                UserId = "user-0002",
            },
            new Gs2.Unity.Gs2SeasonRating.Model.EzGameResult() {
                Rank = 2,
                UserId = "user-0003",
            },
            new Gs2.Unity.Gs2SeasonRating.Model.EzGameResult() {
                Rank = 3,
                UserId = "user-0004",
            },
        }
    );

レート値の変化のハンドリング

GS2-Experience のステータスを Subscribe して判定できます。

    var item = await gs2.Experience.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        experienceName: "rating",
        propertyId: seasonModel.SeasonModeld,
    ).Subscribe(
      changedStatus => {
        var experienceValue = changedStatus.ExperienceValue; // ランクポイント
        var experienceValue = changedStatus.RankValue; // ランク
      }
    );

参考情報

docs.gs2.io

docs.gs2.io

(C) Game Server Services, Inc.