GS2-Exchange

In-game resource exchange functionality

This is one of the most widely used microservice functions provided by GS2. It is responsible for converting the resources of any microservice into the resources of a completely different microservice.

There are many game specifications related to resource exchange, and each time this happens, GS2-Exchange comes into play.

Examples of resource exchange

Conversion of enhancement materials

Exchange 10 ★1 enhancement materials managed by GS2-Inventory for 1 ★2 enhancement material also managed by GS2-Inventory.

You can get an item once every 6 hours.

Exchange 1 Stamina, which is restored once every 6 hours, managed by GS2-Stamina, for an item managed by GS2-Inventory.

Sell item

Exchange items managed by GS2-Inventory for in-game currency also managed by GS2-Inventory.

Types of exchange

GS2-Exchange offers two types of exchanges: direct exchanges, in which items are exchanged immediately at the exchange rate specified in the master data, and Asynchronous exchange, where the result of the exchange can be obtained after a certain amount of time has elapsed in real time after the exchange is performed. A cost-informed exchange, in which the cost increases with each purchase.

When using asynchronous exchange, the price is consumed at the time the exchange is executed, and an await object is created instead of obtaining a reward. When the exchange waiting time defined in the master data elapses from the creation time of the Await object, the reward is received.

Example of Asynchronous Exchange

Strengthening Bases

After consuming resources to build a base in a city-building game After 8 hours, the base’s experience is actually added to the base.

Expedition

After 3 hours of organizing a party and going on an adventure, the party will receive a reward as a result of the adventure.

Skipping asynchronous exchanges

It is possible to skip waiting for asynchronous exchanges by paying additional compensation. In general, when such a specification is included, it is often implemented as a monetization feature, but By consuming in-game currency managed by GS2-Money, which is purchased with cash, it is possible to implement a specification that can reduce the latency.

Example of cost-increasing exchange

Reinforcement (Inflation Game)

Each time an item is enhanced, the amount of gold required to enhance it increases

Stamina recovery cost increases

Each time stamina is purchased, the consumption of the charged currency required to purchase it increases. The number of purchases is reset daily

Calculation of cost increase

Three modes of cost increase exist and are specified in the IncrementalRateModel.

linear

baseValue + (coefficientValue * number of exchanges)

Example

baseValue = 100, coefficientValue = 50

Number of exchangesCost
0100
1150
2200
3250
4300

power

`coefficientValue * (number of replacements + 1) ^ 2

Example

coefficientValue = 50

Number of exchangesCost
050
1200
2450
3800
41250

gs2_script

Calculated based on the results of GS2-Script execution. This can be used when you want to calculate costs based on complex conditions.

Example

currentExchangeCount = args.currentExchangeCount
quantity = quantity

cost = 100
for i = 1 , quantity do
	cost = cost + (i + currentExchangeCount - 1) * 50
end

result = {
    cost=cost
}
number of exchangescost
0100
1150
2200
3250
4300

Example of implementation

Executing an exchange

    var result = await gs2.Exchange.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Exchange(
    ).ExchangeAsync(
        rateName: "rate-0001",
        count: 1,
    );
    const auto Domain = Gs2->Exchange->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Exchange(
    );
    const auto Future = Domain->Exchange(
        "rate-0001",
        1,
        nullptr // config
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;

Get list of Await

    var items = await gs2.Exchange.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).AwaitsAsync(
    ).ToListAsync();
    const auto Domain = Gs2->Exchange->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    );
    const auto It = Domain->Awaits( // rateName
    );
    TArray<Gs2::UE5::Exchange::Model::FEzAwaitPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

Await Receive reward after wait time has elapsed

    var result = await gs2.Exchange.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Await(
        rateName: "material_n_to_r",
        awaitName: "await-0001"
    ).AcquireAsync(
    );
    const auto Domain = Gs2->Exchange->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Await(
        "await-0001", // awaitName
        "material_n_to_r" // rateName
    );
    const auto Future = Domain->Acquire(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;

Await skip wait time.

    var result = await gs2.Exchange.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Await(
        rateName: "material_n_to_r",
        awaitName: "await-0001"
    ).SkipAsync(
    );
    const auto Domain = Gs2->Exchange->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Await(
        "await-0001", // awaitName
        "material_n_to_r" // rateName
    );
    const auto Future = Domain->Skip(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;

Perform cost-increasing exchange.

    var result = await gs2.Exchange.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Exchange(
    ).IncrementalExchangeAsync(
        rateName: "rate-0001",
        count: 1,
    );
    const auto Domain = Gs2->Exchange->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Exchange(
    );
    const auto Future = Domain->IncrementalExchange(
        "rate-0001",
        1,
        nullptr // config
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;

Detailed Reference