GS2-Grade

Grade and rarity functions

A common specification for character and equipment development is to provide for upgrading in addition to level-up as a short-term growth goal. Upgrading raises the level cap and makes it possible to develop more powerful characters and equipment.

There are several possible methods of upgrading, some of which can be done by consuming growth materials, and others by synthesizing characters and equipment of the same type. GS2-Grade does not care about the method, but aims to make the operation of the GS2-Experience level cap simpler to implement by setting a level cap for each grade.

Grades

For each grade, you can define the value to be set for the GS2-Experience rank cap.

Initial values for a grade

You can set the initial grade value depending on whether the property ID matches a regular expression. For example, by starting with grade 3 if the name of the ItemModel in GS2-Inventory starts with SSR, or grade 2 if it starts with SR It is possible to change the initial rank cap depending on the type of ItemModel.

Grade raising material determination

In the case of “synthesizing the same kind of character or equipment” as a method of upgrading, a function is provided to support processing to determine if the resource being used as material is “the same kind of character or equipment. This is achieved by using a regular expression to extract parameters from the property ID of the grade, constructing a regular expression, and determining whether the property ID of the resource to be used as material matches.

For example, to determine if an ItemSet in GS2-Inventory is by the same type of ItemModel, the regular expression is set as follows.

propertyIdRegex: grn:gs2:{region}:{ownerId}:inventory:namespace-0001:user:(.*):inventory:character:item:(.*):.*
gradeUpPropertyIdRegex: grn:gs2:{region}:{ownerId}:inventory:namespace-0001:user:$1:inventory:character:item:$2:.*

Now use propertyIdRegex to retrieve the “user ID” and the “ItemModel name”. If the user ID is “user-0001”, the name of the ItemModel is “item-0001”, and the name of the ItemSet is “item-set-0001”, then the GRN (property ID) of the ItemSet is

grn:gs2:{region}:{ownerId}:inventory:namespace-0001:user:user-0001:inventory:character:item:item-0001:item-set-0001

and the replaced value of gradeUpPropertyIdRegex is

gradeUpPropertyIdRegex: grn:gs2:{region}:{ownerId}:inventory:namespace-0001:user:user-0001:inventory:character:item:item-0001:.*

. This allows for expressions that allow the same kind of item to be specified as a material.

Example implementation

Grade addition

Grade addition cannot be handled by the SDK for game engines.

Use GS2-Exchange to add grades as a reward for consuming enhancement materials or for enhancing GS2-Enhance.

Get a list of grades

    var items = await gs2.Grade.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).StatusesAsync(
        gradeName: "grade-0001"
    ).ToListAsync();
    const auto It = Gs2->Grade->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Statuses(
        "grade-0001" // gradeName
    );
    TArray<Gs2::UE5::Grade::Model::FEzStatusPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

Get the grade

    var item = await gs2.Grade.Namespace(
        namespaceName: "namespace-0001"
    ).GradeModel(
        gradeName: "grade-0001"
    ).ModelAsync();
    const auto Future = Gs2->Grade->Namespace(
        "namespace-0001" // namespaceName
    )->GradeModel(
        "grade-0001" // gradeName
    )->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

Synchronize rank caps in GS2-Experience

When a grade changes, GS2-Experience will automatically reflect the change in the rank cap. However, when the grade model is updated and the value of the rank cap at a specific grade is updated, the updated rank cap can be applied by explicitly calling the following synchronization API.

    var result = await gs2.Grade.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        gradeName: "grade-0001",
        propertyId: "property-0001"
    ).ApplyRankCapAsync(
    );
    var item = await result.ModelAsync();
    const auto Future = Gs2->Grade->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Status(
        "grade-0001", // gradeName
        "property-0001" // propertyId
    )->ApplyRankCap(
    );
    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();

detailed reference