GS2-SeasonRating SDK for Game Engine API リファレンス

モデル

EzSeasonModel

シーズンモデル

GS2 ではレーティングアルゴリズムとして Glicko-2 を採用しています。
Glicko-2 には複数のパラメータがありますが、GS2-Matchmaking ではそれらを総合的に表す ボラティリティ という1つのパラメータに集約しています。
ボラティリティ は変化の大きさを表すパラメータで、値が大きいほどレーティングの値の変動量が大きくなります。

必須デフォルト値の制限説明
seasonModelIdstring~ 1024文字シーズンモデルGRN
namestring~ 128文字シーズンモデル名
metadatastring~ 128文字メタデータ
tiersList<EzTierModel>1 ~ 100 itemsティアーリスト
experienceModelIdstring~ 1024文字経験値モデルGRN

EzTierModel

ティアーモデル

必須デフォルト値の制限説明
metadatastring~ 128文字メタデータ
raiseRankBonusint~ 10000ランク昇格時にすぐにランク降格を防ぐために加算するボーナスポイント
minimumChangePointint~ -1負けた際に変動するレート値の最小値
maximumChangePointint1 ~ 99999999勝った際に変動するレート値の最大値

EzGameResult

対戦結果

必須デフォルト値の制限説明
rankint~ 2147483646順位
userIdstring~ 128文字ユーザーID

EzBallot

投票用紙

必須デフォルト値の制限説明
userIdstring~ 128文字ユーザーID
seasonNamestring~ 128文字レーティング計算に使用するシーズン名
sessionNamestring~ 128文字投票対象のセッション名
numberOfPlayerint2 ~ 10参加人数

EzSignedBallot

署名付の投票用紙

必須デフォルト値の制限説明
bodystring~ 1024文字投票用紙の署名対象のデータ
signaturestring~ 256文字投票用紙の署名

メソッド

getSeasonModel

シーズン名を指定してシーズンモデルを取得

Request

必須デフォルト値の制限説明
namespaceNamestring~ 128文字ネームスペース名
seasonNamestring~ 128文字シーズンモデル名

Result

説明
itemEzSeasonModelシーズンモデル

実装例

    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    ).SeasonModel(
        seasonName: "mode1"
    );
    var item = await domain.ModelAsync();
    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    ).SeasonModel(
        seasonName: "mode1"
    );
    var future = domain.Model();
    yield return future;
    var item = future.Result;
    const auto Domain = Gs2->SeasonRating->Namespace(
        "namespace-0001" // namespaceName
    )->SeasonModel(
        "mode1" // seasonName
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
値の変更イベントハンドリング
    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    ).SeasonModel(
        seasonName: "mode1"
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.Subscribe(
        value => {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    domain.Unsubscribe(callbackId);
    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    ).SeasonModel(
        seasonName: "mode1"
    );
    var future = domain.Model();
    yield return future;
    var item = future.Result;
    const auto Domain = Gs2->SeasonRating->Namespace(
        "namespace-0001" // namespaceName
    )->SeasonModel(
        "mode1" // seasonName
    );
    
    // イベントハンドリングを開始
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::SeasonRating::Model::FSeasonModel> value) {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    Domain->Unsubscribe(CallbackId);

listSeasonModels

シーズンモデルの一覧を取得

Request

必須デフォルト値の制限説明
namespaceNamestring~ 128文字ネームスペース名

Result

説明
itemsList<EzSeasonModel>シーズンモデルのリスト

実装例

    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    );
    var items = await domain.SeasonModelsAsync(
    ).ToListAsync();
    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    );
    var it = domain.SeasonModels(
    );
    List<EzSeasonModel> items = new List<EzSeasonModel>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }
    const auto Domain = Gs2->SeasonRating->Namespace(
        "namespace-0001" // namespaceName
    );
    const auto It = Domain->SeasonModels(
    );
    TArray<Gs2::UE5::SeasonRating::Model::FEzSeasonModelPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }
値の変更イベントハンドリング
    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.SubscribeSeasonModels(
        () => {
            // リストの要素が変化した時に呼び出される
        }
    );

    // イベントハンドリングを停止
    domain.UnsubscribeSeasonModels(callbackId);
    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    );
    var it = domain.SeasonModels(
    );
    List<EzSeasonModel> items = new List<EzSeasonModel>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }
    const auto Domain = Gs2->SeasonRating->Namespace(
        "namespace-0001" // namespaceName
    );
    
    // イベントハンドリングを開始
    const auto CallbackId = Domain->SubscribeSeasonModels(
        []() {
            // リストの要素が変化した時に呼び出される
        }
    );

    // イベントハンドリングを停止
    Domain->UnsubscribeSeasonModels(CallbackId);

createVote

投票用紙を作成

Request

必須デフォルト値の制限説明
namespaceNamestring~ 128文字ネームスペース名
seasonNamestring~ 128文字シーズンモデル名
sessionNamestringUUID~ 128文字セッション名
accessTokenstring~ 128文字ユーザーID
numberOfPlayerint2 ~ 10参加人数
keyIdstring“grn:gs2:{region}:{ownerId}:key:default:key:default”~ 1024文字暗号鍵GRN

Result

説明
itemEzBallot投票用紙
bodystring署名対象のデータ
signaturestring署名データ

実装例

    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Ballot(
        seasonName: "rating-0001",
        sessionName: "gathering-0001",
        numberOfPlayer: 4,
        keyId: "key-0001"
    );
    var item = await domain.ModelAsync();
    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Ballot(
        seasonName: "rating-0001",
        sessionName: "gathering-0001",
        numberOfPlayer: 4,
        keyId: "key-0001"
    );
    var future = domain.Model();
    yield return future;
    var item = future.Result;
    const auto Domain = Gs2->SeasonRating->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Ballot(
        "rating-0001", // seasonName
        "gathering-0001", // sessionName
        4, // numberOfPlayer
        "key-0001" // keyId
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
値の変更イベントハンドリング
    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Ballot(
        seasonName: "rating-0001",
        sessionName: "gathering-0001",
        numberOfPlayer: 4,
        keyId: "key-0001"
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.Subscribe(
        value => {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    domain.Unsubscribe(callbackId);
    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Ballot(
        seasonName: "rating-0001",
        sessionName: "gathering-0001",
        numberOfPlayer: 4,
        keyId: "key-0001"
    );
    var future = domain.Model();
    yield return future;
    var item = future.Result;
    const auto Domain = Gs2->SeasonRating->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Ballot(
        "rating-0001", // seasonName
        "gathering-0001", // sessionName
        4, // numberOfPlayer
        "key-0001" // keyId
    );
    
    // イベントハンドリングを開始
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::SeasonRating::Model::FBallot> value) {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    Domain->Unsubscribe(CallbackId);

vote

対戦結果を投票します。

投票は最初の投票が行われてから5分以内に行う必要があります。
つまり、結果は即座に反映されず、投票開始からおよそ5分後または全てのプレイヤーが投票を行った際に結果が反映されます。
5分以内に全ての投票用紙を回収できなかった場合はその時点の投票内容で多数決をとって結果を決定します。
各結果の投票数が同一だった場合は結果は捨てられます(スクリプトで挙動を変更可)。

結果を即座に反映したい場合は、勝利した側の代表プレイヤーが投票用紙を各プレイヤーから集めて voteMultiple を呼び出すことで結果を即座に反映できます。

Request

必須デフォルト値の制限説明
namespaceNamestring~ 128文字ネームスペース名
ballotBodystring~ 1024文字投票用紙の署名対象のデータ
ballotSignaturestring~ 256文字投票用紙の署名
gameResultsList<EzGameResult>~ 10 items投票内容。対戦を行ったプレイヤーグループ1に所属するユーザIDのリスト
keyIdstring“grn:gs2:{region}:{ownerId}:key:default:key:default”~ 1024文字暗号鍵GRN

Result

説明
itemEzBallot投票用紙

実装例

    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    );
    var result = await domain.VoteAsync(
        ballotBody: "ballotBody",
        ballotSignature: "ballotSignature",
        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",
            },
        },
        keyId: "key-0001"
    );
    var item = await result.ModelAsync();
    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    );
    var future = domain.VoteFuture(
        ballotBody: "ballotBody",
        ballotSignature: "ballotSignature",
        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",
            },
        },
        keyId: "key-0001"
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.Model();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;
    const auto Domain = Gs2->SeasonRating->Namespace(
        "namespace-0001" // namespaceName
    );
    const auto Future = Domain->Vote(
        "ballotBody", // ballotBody
        "ballotSignature", // ballotSignature
        []
        {
            auto v = MakeShared<TArray<TSharedPtr<Gs2::UE5::SeasonRating::Model::FEzGameResult>>>();
            v->Add(
                MakeShared<Gs2::UE5::SeasonRating::Model::FEzGameResult>()
                ->WithRank(TOptional<int32>(1))
                ->WithUserId(TOptional<FString>("user-0001"))
            );
            v->Add(
                MakeShared<Gs2::UE5::SeasonRating::Model::FEzGameResult>()
                ->WithRank(TOptional<int32>(2))
                ->WithUserId(TOptional<FString>("user-0002"))
            );
            v->Add(
                MakeShared<Gs2::UE5::SeasonRating::Model::FEzGameResult>()
                ->WithRank(TOptional<int32>(2))
                ->WithUserId(TOptional<FString>("user-0003"))
            );
            v->Add(
                MakeShared<Gs2::UE5::SeasonRating::Model::FEzGameResult>()
                ->WithRank(TOptional<int32>(3))
                ->WithUserId(TOptional<FString>("user-0004"))
            );
            return v;
        }(), // gameResults
        "key-0001" // keyId
    );
    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();

voteMultiple

対戦結果をまとめて投票します。

ゲームに勝利した側が他プレイヤーの投票用紙を集めてまとめて投票するのに使用します。
『勝利した側』としているのは、敗北した側が自分たちが勝ったことにして報告することにインセンティブはありますが、その逆はないためです。
負けた側が投票用紙を渡してこない可能性がありますが、その場合も過半数の投票用紙があれば結果を通すことができます。

Request

必須デフォルト値の制限説明
namespaceNamestring~ 128文字ネームスペース名
signedBallotsList<EzSignedBallot>~ 10 items署名付の投票用紙リスト
gameResultsList<EzGameResult>~ 10 items投票内容。対戦を行ったプレイヤーグループ1に所属するユーザIDのリスト
keyIdstring“grn:gs2:{region}:{ownerId}:key:default:key:default”~ 1024文字暗号鍵GRN

Result

説明
itemEzBallot投票用紙

実装例

    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    );
    var result = await domain.VoteMultipleAsync(
        signedBallots: new List<Gs2.Unity.Gs2SeasonRating.Model.EzSignedBallot> {
            new Gs2.Unity.Gs2SeasonRating.Model.EzSignedBallot() {
                Body = "aaa",
                Signature = "bbb",
            },
            new Gs2.Unity.Gs2SeasonRating.Model.EzSignedBallot() {
                Body = "aaa",
                Signature = "bbb",
            },
            new Gs2.Unity.Gs2SeasonRating.Model.EzSignedBallot() {
                Body = "aaa",
                Signature = "bbb",
            },
            new Gs2.Unity.Gs2SeasonRating.Model.EzSignedBallot() {
                Body = "aaa",
                Signature = "bbb",
            },
        },
        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",
            },
        },
        keyId: "key-0001"
    );
    var item = await result.ModelAsync();
    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    );
    var future = domain.VoteMultipleFuture(
        signedBallots: new List<Gs2.Unity.Gs2SeasonRating.Model.EzSignedBallot> {
            new Gs2.Unity.Gs2SeasonRating.Model.EzSignedBallot() {
                Body = "aaa",
                Signature = "bbb",
            },
            new Gs2.Unity.Gs2SeasonRating.Model.EzSignedBallot() {
                Body = "aaa",
                Signature = "bbb",
            },
            new Gs2.Unity.Gs2SeasonRating.Model.EzSignedBallot() {
                Body = "aaa",
                Signature = "bbb",
            },
            new Gs2.Unity.Gs2SeasonRating.Model.EzSignedBallot() {
                Body = "aaa",
                Signature = "bbb",
            },
        },
        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",
            },
        },
        keyId: "key-0001"
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.Model();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;
    const auto Domain = Gs2->SeasonRating->Namespace(
        "namespace-0001" // namespaceName
    );
    const auto Future = Domain->VoteMultiple(
        []
        {
            auto v = MakeShared<TArray<TSharedPtr<Gs2::UE5::SeasonRating::Model::FEzSignedBallot>>>();
            v->Add(
                MakeShared<Gs2::UE5::SeasonRating::Model::FEzSignedBallot>()
                ->WithBody(TOptional<FString>("aaa"))
                ->WithSignature(TOptional<FString>("bbb"))
            );
            v->Add(
                MakeShared<Gs2::UE5::SeasonRating::Model::FEzSignedBallot>()
                ->WithBody(TOptional<FString>("aaa"))
                ->WithSignature(TOptional<FString>("bbb"))
            );
            v->Add(
                MakeShared<Gs2::UE5::SeasonRating::Model::FEzSignedBallot>()
                ->WithBody(TOptional<FString>("aaa"))
                ->WithSignature(TOptional<FString>("bbb"))
            );
            v->Add(
                MakeShared<Gs2::UE5::SeasonRating::Model::FEzSignedBallot>()
                ->WithBody(TOptional<FString>("aaa"))
                ->WithSignature(TOptional<FString>("bbb"))
            );
            return v;
        }(), // signedBallots
        []
        {
            auto v = MakeShared<TArray<TSharedPtr<Gs2::UE5::SeasonRating::Model::FEzGameResult>>>();
            v->Add(
                MakeShared<Gs2::UE5::SeasonRating::Model::FEzGameResult>()
                ->WithRank(TOptional<int32>(1))
                ->WithUserId(TOptional<FString>("user-0001"))
            );
            v->Add(
                MakeShared<Gs2::UE5::SeasonRating::Model::FEzGameResult>()
                ->WithRank(TOptional<int32>(2))
                ->WithUserId(TOptional<FString>("user-0002"))
            );
            v->Add(
                MakeShared<Gs2::UE5::SeasonRating::Model::FEzGameResult>()
                ->WithRank(TOptional<int32>(2))
                ->WithUserId(TOptional<FString>("user-0003"))
            );
            v->Add(
                MakeShared<Gs2::UE5::SeasonRating::Model::FEzGameResult>()
                ->WithRank(TOptional<int32>(3))
                ->WithUserId(TOptional<FString>("user-0004"))
            );
            return v;
        }(), // gameResults
        "key-0001" // keyId
    );
    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();