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.
Type | Require | Default | Limitation | Description | |
---|---|---|---|---|---|
seasonModelId | string | ✓ | ~ 1024 chars | Season Model GRN | |
name | string | ✓ | ~ 128 chars | Season Model Name | |
metadata | string | ~ 128 chars | metadata | ||
tiers | List<EzTierModel> | ✓ | 1 ~ 100 items | List of Tier | |
experienceModelId | string | ✓ | ~ 1024 chars | Experience Model GRN |
EzTierModel
Tear model
Type | Require | Default | Limitation | Description | |
---|---|---|---|---|---|
metadata | string | ~ 128 chars | metadata | ||
raiseRankBonus | int | ✓ | ~ 10000 | The bonus points added to prevent immediate rank demotion when the rank is promoted. | |
minimumChangePoint | int | ✓ | ~ -1 | Change point minimum value when losing | |
maximumChangePoint | int | ✓ | 1 ~ 99999999 | Change point maximum value when winning |
EzGameResult
Match Results
Type | Require | Default | Limitation | Description | |
---|---|---|---|---|---|
rank | int | ✓ | ~ 2147483646 | Rank | |
userId | string | ✓ | ~ 128 chars | User Id |
EzBallot
Ballot Paper
Type | Require | Default | Limitation | Description | |
---|---|---|---|---|---|
userId | string | ✓ | ~ 128 chars | User Id | |
seasonName | string | ✓ | ~ 128 chars | Rating name used for rating calculations | |
sessionName | string | ✓ | ~ 128 chars | Name of MatchSession to be voted | |
numberOfPlayer | int | ✓ | 2 ~ 10 | Number of participants |
EzSignedBallot
Ballot with signatures
Type | Require | Default | Limitation | Description | |
---|---|---|---|---|---|
body | string | ✓ | ~ 1024 chars | Data for ballot signature targets | |
signature | string | ✓ | ~ 256 chars | Signature |
Methods
getSeasonModel
Get a rating model by specifying a rating name
Request
Type | Require | Default | Limitation | Description | |
---|---|---|---|---|---|
namespaceName | string | ✓ | ~ 128 chars | Namespace name | |
seasonName | string | ✓ | ~ 128 chars | Season Model Name |
Result
Type | Description | |
---|---|---|
item | EzSeasonModel | Season 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);
Warning
This event is called when the value in the local cache that the SDK has is changed.
The local cache will only be changed by executing the SDK’s API, or by executing a stamp sheet via GS2-Distributor with GS2-Gateway notification enabled, or by executing a GS2-JobQueue with GS2-Gateway notification enabled. GS2-Gateway notification enabled.
Therefore, callbacks will not be invoked if the value is changed in any other way.
listSeasonModels
Get list of rating models
Request
Type | Require | Default | Limitation | Description | |
---|---|---|---|---|---|
namespaceName | string | ✓ | ~ 128 chars | Namespace name |
Result
Type | Description | |
---|---|---|
items | List<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);
Warning
This event is called when the value in the local cache that the SDK has is changed.
The local cache will only be changed by executing the SDK’s API, or by executing a stamp sheet via GS2-Distributor with GS2-Gateway notification enabled, or by executing a GS2-JobQueue with GS2-Gateway notification enabled. GS2-Gateway notification enabled.
Therefore, callbacks will not be invoked if the value is changed in any other way.
createVote
Prepare a ballot
Request
Type | Require | Default | Limitation | Description | |
---|---|---|---|---|---|
namespaceName | string | ✓ | ~ 128 chars | Namespace name | |
seasonName | string | ✓ | ~ 128 chars | Season Model Name | |
sessionName | string | ✓ | UUID | ~ 128 chars | Session Name |
accessToken | string | ✓ | ~ 128 chars | User Id | |
numberOfPlayer | int | ✓ | 2 ~ 10 | Number of participants | |
keyId | string | ✓ | “grn:gs2:{region}:{ownerId}:key:default:key:default” | ~ 1024 chars | encryption key GRN |
Result
Type | Description | |
---|---|---|
item | EzBallot | Ballot |
body | string | Data to be signed |
signature | string | Signature |
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);
Warning
This event is called when the value in the local cache that the SDK has is changed.
The local cache will only be changed by executing the SDK’s API, or by executing a stamp sheet via GS2-Distributor with GS2-Gateway notification enabled, or by executing a GS2-JobQueue with GS2-Gateway notification enabled. GS2-Gateway notification enabled.
Therefore, callbacks will not be invoked if the value is changed in any other way.
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
Type | Require | Default | Limitation | Description | |
---|---|---|---|---|---|
namespaceName | string | ✓ | ~ 128 chars | Namespace name | |
ballotBody | string | ✓ | ~ 1024 chars | Data for ballot signature targets | |
ballotSignature | string | ✓ | ~ 256 chars | Signature | |
gameResults | List<EzGameResult> | ~ 10 items | List of Results | ||
keyId | string | ✓ | “grn:gs2:{region}:{ownerId}:key:default:key:default” | ~ 1024 chars | encryption key GRN |
Result
Type | Description | |
---|---|---|
item | EzBallot | Ballot |
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
Type | Require | Default | Limitation | Description | |
---|---|---|---|---|---|
namespaceName | string | ✓ | ~ 128 chars | Namespace name | |
signedBallots | List<EzSignedBallot> | ~ 10 items | List of Ballot with signatures | ||
gameResults | List<EzGameResult> | ~ 10 items | List of Results | ||
keyId | string | ✓ | “grn:gs2:{region}:{ownerId}:key:default:key:default” | ~ 1024 chars | encryption key GRN |
Result
Type | Description | |
---|---|---|
item | EzBallot | Ballot |
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();