API Reference of GS2-SeasonRating SDK for Game Engine

Model

EzSeasonModel

Season Model

GS2 uses Glicko-2 as its rating algorithm. Glicko-2 has several parameters, but GS2-Matchmaking aggregates them into a single parameter, volatility, which represents the totality of the parameters. Volatility is a parameter that expresses the magnitude of change; the larger the value, the greater the change in the rating value.

TypeRequireDefaultLimitationDescription
seasonModelIdstring~ 1024 charsSeason Model GRN
namestring~ 128 charsSeason Model Name
metadatastring~ 128 charsmetadata
tiersList<EzTierModel>1 ~ 100 itemsList of Tier
experienceModelIdstring~ 1024 charsExperience Model GRN

EzTierModel

TypeRequireDefaultLimitationDescription
metadatastring~ 128 charsmetadata
raiseRankBonusint~ 10000The bonus points added to prevent immediate rank demotion when the rank is promoted.
minimumChangePointint~ -1Change point minimum value when losing
maximumChangePointint1 ~ 99999999Change point maximum value when winning

EzGameResult

TypeRequireDefaultLimitationDescription
rankint~ 2147483646Rank
userIdstring~ 128 charsUser Id

EzBallot

TypeRequireDefaultLimitationDescription
userIdstring~ 128 charsUser Id
seasonNamestring~ 128 charsRating name used for rating calculations
sessionNamestring~ 128 charsName of MatchSession to be voted
numberOfPlayerint2 ~ 10Number of participants

EzSignedBallot

TypeRequireDefaultLimitationDescription
bodystring~ 1024 charsData for ballot signature targets
signaturestring~ 256 charsSignature

Methods

getSeasonModel

Get a rating model by specifying a rating name

Request

TypeRequireDefaultLimitationDescription
namespaceNamestring~ 32 charsNamespace name
seasonNamestring~ 128 charsSeason Model Name

Result

TypeDescription
itemEzSeasonModelSeason Model

Implementation Example

    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;
    }
Value change event handling
    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    ).SeasonModel(
        seasonName: "mode1"
    );
    
    // Start event handling
    var callbackId = domain.Subscribe(
        value => {
            // Called when the value changes
            // The "value" is passed the value after the change.
        }
    );

    // Stop event handling
    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
    );
    
    // Start event handling
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::SeasonRating::Model::FSeasonModel> value) {
            // Called when the value changes
            // The "value" is passed the value after the change.
        }
    );

    // Stop event handling
    Domain->Unsubscribe(CallbackId);

listSeasonModels

Get list of rating models

Request

TypeRequireDefaultLimitationDescription
namespaceNamestring~ 32 charsNamespace name

Result

TypeDescription
itemsList<EzSeasonModel>List of Season Model

Implementation Example

    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());
    }
Value change event handling
    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    );
    
    // Start event handling
    var callbackId = domain.SubscribeSeasonModels(
        () => {
            // Called when an element of the list changes.
        }
    );

    // Stop event handling
    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
    );
    
    // Start event handling
    const auto CallbackId = Domain->SubscribeSeasonModels(
        []() {
            // Called when an element of the list changes.
        }
    );

    // Stop event handling
    Domain->UnsubscribeSeasonModels(CallbackId);

createVote

Prepare a ballot

Request

TypeRequireDefaultLimitationDescription
namespaceNamestring~ 32 charsNamespace name
seasonNamestring~ 128 charsSeason Model Name
sessionNamestringUUID~ 128 charsSession Name
accessTokenstring~ 128 charsUser Id
numberOfPlayerint2 ~ 10Number of participants
keyIdstring“grn:gs2:{region}:{ownerId}:key:default:key:default”~ 1024 charsencryption key GRN

Result

TypeDescription
itemEzBallotBallot
bodystringData to be signed
signaturestringSignature

Implementation Example

    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;
    }
Value change event handling
    var domain = gs2.SeasonRating.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Ballot(
        seasonName: "rating-0001",
        sessionName: "gathering-0001",
        numberOfPlayer: 4,
        keyId: "key-0001"
    );
    
    // Start event handling
    var callbackId = domain.Subscribe(
        value => {
            // Called when the value changes
            // The "value" is passed the value after the change.
        }
    );

    // Stop event handling
    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
    );
    
    // Start event handling
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::SeasonRating::Model::FBallot> value) {
            // Called when the value changes
            // The "value" is passed the value after the change.
        }
    );

    // Stop event handling
    Domain->Unsubscribe(CallbackId);

vote

Vote on the results of the matchups.

Voting must take place within 5 minutes of the first vote being cast. This means that the results will not be reflected immediately, but approximately 5 minutes after the start of voting or when all players have cast their votes. If all ballots are not collected within 5 minutes, the result will be determined by a majority vote based on the votes cast at that time. If the number of votes for each result is the same, the result will be discarded (the behavior can be changed by script).

If you want to reflect the result immediately, the representative player of the winning side can collect ballots from each player and call voteMultiple to reflect the result immediately.

Request

TypeRequireDefaultLimitationDescription
namespaceNamestring~ 32 charsNamespace name
ballotBodystring~ 1024 charsData for ballot signature targets
ballotSignaturestring~ 256 charsSignature
gameResultsList<EzGameResult>~ 10 itemsList of Results
keyIdstring“grn:gs2:{region}:{ownerId}:key:default:key:default”~ 1024 charsencryption key GRN

Result

TypeDescription
itemEzBallotBallot

Implementation Example

    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

Vote on the results of the matchups together.

The side that wins the game collects the ballots of other players and uses them to vote collectively. We say ’the winning side’ because there is an incentive for the losing side to report that they won, but not vice versa. It is possible that the losing side will not hand in their ballots, but even in that case, if there is a majority of ballots, the results can still be passed.

Request

TypeRequireDefaultLimitationDescription
namespaceNamestring~ 32 charsNamespace name
signedBallotsList<EzSignedBallot>~ 10 itemsList of Ballot with signatures
gameResultsList<EzGameResult>~ 10 itemsList of Results
keyIdstring“grn:gs2:{region}:{ownerId}:key:default:key:default”~ 1024 charsencryption key GRN

Result

TypeDescription
itemEzBallotBallot

Implementation Example

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