Statistics
1. Overview
Statistics is a service that helps you to store and track player or global statistics. By default, Statistics is also a major data source of the Leaderboard service.
To read this chapter, you will learn the key mechanism and how to set up and use statistics.
2. Key Concepts
2.1 Stat
A Stat is essentially a data map to store statistical data. Each data item in it has the following key fields:
- Key: This is a unique string used to identify the data item. What the key should be depends on your scenario. For example, you can set as the PlayerID to track the player's kill counts or set as the TeamID to track the team's score.
- Value: The data item's value is a double type, with the default being 0.
- Secondary Value: This is an optional data item value, also in double type and with a default of 0. It is used for multi-value sorting in the Leaderboard service. If you don't require multi-value sorting, you can ignore this field.
- Tags: Tags can be added to the data item. This field is used to configure and construct sub-leaderboards in the Leaderboard service. You can also use it to store arbitrary strings to tag the data item.
You can update the data item in Stat with a specific aggregate type. The mechanism for this is outlined in the following table:
Aggregate Type | Value | Secondary Value | Tags |
---|---|---|---|
Override | Overwrite | Overwrite | Overwrite |
Sum | the sum of the new value and the existing one | Overwrite | Overwrite |
Max | Overwrite if the new value is higher than the existing one | Overwrite if the value is updated | Overwrite if the value updated |
Min | Overwrite if the new value is lower than the existing one | Overwrite if the value is updated | Overwrite if the value updated |
2.2 Cycle
To keep track of statistics data within a specific time frame, you can use the Cycle feature. When you bind a Stat with a Cycle, the PGOS backend automatically updates the Cycle data whenever you update the Stat data. Once the cycle time frame ends, the data is reset, for example, allowing players to start a new competition. For instance, the game can track daily kill counts or the best game session score of the season.
There are different cycle types to choose from, including Daily, Weekly, Monthly, and Seasonal (custom-defined). You can determine the reset time clock for each cycle type. For Seasonal cycles, you can define the reset time clock for every period, such as 90 days for a game season lasting 90 days.
A Stat can be bound with multiple Cycles, and a Cycle can be bound with multiple Stats.
Please note that data is updated into the Cycle after binding, and existing Stat data before binding is not transferred to the Cycle.
Stat not bound with Cycle: There is only a persistent data map in it, shown below chart:
Stat bound with Cycle: There is an extra cycle data map for every bound Cycle. Each cycle data is stored separately from the persistent data, shown below chart:
3. Manage on Portal
3.1 Stats
3.1.1 Add New Stat
Log in to the web portal, enter the console, and go to Statistics > Stat:
Field description:
- Stat Name: The name of the new stat. It can only contain letters, numbers, and underscores, and must start with a letter.
- Min Value (optional): Minimum value for Stat item value. Enable and specify a limit value if there is a need to restrict the item minimum value.
- Max Value (optional): Maximum value for Stat item value. Enable and specify a limit value if there is a need to restrict the item's maximum value.
- Description (optional): The description of the stat.
If everything is ok then you will get a new stat:
3.1.2 Edit Stat
If you want to edit a stat, click the Edit link button in the stat list:
Modifications to the Max limit and Min limit only affect subsequent update operations and will not change the existing data.
3.1.3 Delete Stat
If you want to remove a stat, click the Delete link button in the stat list:
Once a stat is deleted, its data can no longer be accessed through the PgosSDK
or HTTP API.
3.1.4 Manage Stat Items
Click the stat name to start managing stat items:
After the stat name clicking, you will see a recently updated item list:
If you want to search for a specific item, input the item key and click the Search button:
If you want to search multiple items at the same time, enable the multi-keys checkbox, and input multiple item keys in the search box.
If you want to add/update the stat item, click the Add/Update Data button:
Fill in the fields and click the OK button, Then:
- If the item key exists, the item will be updated.
- If the item key does not exist, the item will be added.
3.2 Cycles
3.2.1 Add New Cycle
Log in to the web portal, enter the console, and go to Statistics > Cycles:
Field description:
- Name: The name of the new cycle. It can only contain letters, numbers, and underscores, and must start with a letter.
- Type: The cycle type, which represents the data reset period, including Daily, Weekly, Monthly, and Seasonal (custom-defined).
- Reset Time: The time indicates when to reset the cycle data.
- Start Date Time: The time indicates when the cycle starts to work.
- End Date Time: The time indicates when the cycle stops working.
- Description (optional): The description of the cycle.
If everything is okay then you will get a new cycle:
3.2.2 Edit Cycle
If you want to edit a cycle, click the Edit link button in the cycle list:
3.2.3 Delete Cycle
If you want to remove a cycle, click the Delete link button in the cycle list:
3.2.4 Bind Stat to Cycle
If you want a stat to have cycle data, you need to bind the stat to a cycle., click the Cycle Name to want to bind to in the cycle list:
After the cycle name clicking, you will see a view below:
Click the Bind Stat button, you can bind stats to the cycle:
You can select the stats you want bind to the cycle. After that, the stats you selected will be in the bound stats list:
If you want to unbind a stat from the cycle, click the Delete link button in the bound stats list:
3.2.5 View Cycle Data
Once the stat is bound to a cycle, you will be able to simultaneously obtain the corresponding cycle data when updating the stat item data in the future. If you want to view the cycle data in the console, please enter the Manage Stat Items page, click the drop-down arrow next to the item key, then you can view the cycle data:
4. Boundary Cases
When using Stat and Cycle, the following boundary cases may be encountered, please be aware of them.
4.1 Stat Min/Max Limitations
When configuring the min or max limit for stat, if the result of the value using the following aggregate types may exceed the min or max limit, PGOS will handle it as shown in the table below.
Aggregate Type | Value Result |
---|---|
Override | Values greater than the max limit will be set to the max limit itself, while values less than the min limit will be set to the min limit itself. |
Sum | If the sum of values exceeds the max limit, the value will be set to the max limit itself. If the sum of values is less than the minimum limit, the value will be set to the min limit itself. |
Max | When comparing the current value with a value greater than the max limit, the value will be set to the max limit itself. |
Min | When comparing the current value with a value less than the minimum limit, the value will be set to the min limit itself. |
Let's take min: 0 max: 100
limitations for example:
Aggregate Type | Old Value | Value In Request | Result Value |
---|---|---|---|
Override | 75 | 150 | 100 |
Override | 75 | -100 | 0 |
Sum | 75 | 30 | 100 |
Sum | 75 | -100 | 0 |
Max | 75 | 150 | 100 |
Min | 75 | -100 | 0 |
4.2 Cycle First Reset Period
Under certain circumstances, the first reset cycle of the Cycle may be shorter than the preset reset cycle. This can occur in the following examples:
Daily Cycle
Cycle Type | Reset Time | Start Date |
---|---|---|
Daily | 10:00 | 2023-09-01 00:00:00 |
The first reset time will be 2023-09-01 10:00:00, which is 10 hours after the cycle starts instead of 24 hours. The Next reset time will be 2023-09-02 10:00:00, and so will the following ones.
Weekly Cycle
Cycle Type | Reset Time | Reset Weekday | Start Date |
---|---|---|---|
Weekly | 10:00 | Tuesday | 2023-01-01 00:00:00 (Let's assume this day is Monday) |
The first reset time will be 2023-01-02 10:00 (which is Tuesday), the next reset time will be 2023-01-09 10:00 and so will the following ones.
Monthly Cycle
Cycle Type | Reset Time | Reset Monthday | Start Date |
---|---|---|---|
Monthly | 10:00 | 5 | 2023-01-01 00:00:00 |
The first reset time will be 2023-01-05 10:00 (which is Tuesday), the next reset time will be 2023-02-05 10:00 and so will the following ones.
As you can see, in the above scenes, the first reset period is typically less than the period configured in the cycle type. If this situation occurs, please note that it is as expected.
4.3 Cycle Monthly Reset Boundary Case
When using the monthly cycle, if the reset day exceeds the maximum number of days in the current month, it will default to the last day of the month.
Cycle Type | Reset Time | Reset Monthday | Start Date |
---|---|---|---|
Monthly | 10:00 | 31 | 2024-02-01 00:00:00 |
The first reset time will be 2024-02-28 10:00:00, which is the last day of that month.
5. Access via SDK
5.1 For Game Client
The game can query stat data on the game client through PgosSDK
.
API | Description |
---|---|
GetStatPersistentInfo | Query the persistent info of the specified stat item. |
BatchGetStatPersistentInfo | Query item persistent info with specified stat names and keys in batches. |
GetStatCycleInfo | Query the cycle info of the specified stat item for the current cycle round. |
BatchGetStatCycleInfo | Query item cycle info with specified stat names and keys for the current cycle round in batches. |
BatchGetStatCycleRoundInfo | Query the current round infos of cycles in batches. |
5.1.1 GetStatPersistentInfo Client API
Query the persistent info of the specified stat item.
Interface prototype:
/**
* Query the persistent info of the specified stat item.
*
* @param Params Request structure for querying persistent info.
*/
void GetStatPersistentInfo(
const FGetStatPersistentInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FStatItem* Data)> Callback) const;
struct FGetStatPersistentInfoParams {
/** Stat name. */
FString stat_name;
/** Stat item key. */
FString key;
};
Example Code:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetClientStatisticsAPI();
if (Statistics)
{
FGetStatPersistentInfoParams Params;
Params.stat_name = TEXT("EnemyKills");
Params.key = TEXT("p456792");
Statistics->GetStatPersistentInfo(Params, [](const FPgosResult& Ret, const FStatItem* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetStatPersistentInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetStatPersistentInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
5.1.2 BatchGetStatPersistentInfo Client API
Query persistent info with specified stat names and keys in batches.
Interface prototype:
/**
* Query item persistent info with specified stat names and keys in batches.
* For example: stat_names=["s1", "s2"], keys=["k1", "k2"],
* then you will get a batch of items:[("s1", "k1"), ("s1", "k2"), "s2", "k1"), ("s2", "k2")]
* It will ignore non-existing (stat_name + key) combination items.
*
* @param Params Request structure for querying item persistent infos.
*/
void BatchGetStatPersistentInfo(
const FBatchGetStatPersistentInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FBatchGetStatPersistentInfoResult* Data)> Callback) const;
struct FBatchGetStatPersistentInfoParams
{
/** Stat names. */
TArray<FString> stat_names;
/** Stat item keys. */
TArray<FString> keys;
};
Example Code:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetClientStatisticsAPI();
if (Statistics)
{
FBatchGetStatPersistentInfoParams Params;
Params.stat_names.Add(TEXT("EnemyKills"));
Params.stat_names.Add(TEXT("PlayerDeaths"));
Params.keys.Add(TEXT("p456791"));
Params.keys.Add(TEXT("p456792"));
Statistics->BatchGetStatPersistentInfo(Params, [](const FPgosResult& Ret, const FBatchGetStatPersistentInfoResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatPersistentInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatPersistentInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
5.1.3 GetStatCycleInfo Client API
Query the cycle info of the specified stat item for the current cycle round.
Interface prototype:
/**
* Query the cycle info of the specified stat item for the current cycle round.
*
* @param Params Request structure for querying the cycle info.
*/
void GetStatCycleInfo(
const FGetStatCycleInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FGetStatCycleInfoResult* Data)> Callback) const;
struct FGetStatCycleInfoParams
{
/** The stat name. */
FString stat_name;
/** The stat item key. */
FString key;
/** The stat cycle name. */
FString cycle_name;
};
Example Code:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetClientStatisticsAPI();
if (Statistics)
{
FGetStatCycleInfoParams Params;
Params.stat_name = TEXT("EnemyKills");
Params.key = TEXT("p456792");
Params.cycle_name = TEXT("Daily");
Statistics->GetStatCycleInfo(Params, [](const FPgosResult& Ret, const FGetStatCycleInfoResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetStatCycleInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetStatCycleInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
5.1.4 BatchGetStatCycleInfo Client API
Query item cycle info with specified stat names and keys for the current cycle round in batches.
Interface prototype:
/**
* Query cycle info with specified stat names and keys for the current cycle round in batches.
* For example: stat_names=["s1", "s2"], keys=["k1", "k2"],
* then you will get a batch of items:[("s1", "k1"), ("s1", "k2"), "s2", "k1"), ("s2", "k2")]
* It will ignore non-existing (stat_name + key) combination items.
*
* @param Params Request structure for querying item cycle infos.
*/
void BatchGetStatCycleInfo(
const FBatchGetStatCycleInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FBatchGetStatCycleInfoResult* Data)> Callback) const;
struct FBatchGetStatCycleInfoParams
{
/** The stat names. */
TArray<FString> stat_names;
/** The stat item keys. */
TArray<FString> keys;
/** The stat cycle name. */
FString cycle_name;
};
Example Code:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetClientStatisticsAPI();
if (Statistics)
{
FBatchGetStatCycleInfoParams Params;
Params.stat_names.Add(TEXT("EnemyKills"));
Params.stat_names.Add(TEXT("PlayerDeaths"));
Params.keys.Add(TEXT("p456791"));
Params.keys.Add(TEXT("p456792"));
Params.cycle_name = TEXT("Daily");
Statistics->BatchGetStatCycleInfo(Params, [](const FPgosResult& Ret, const FBatchGetStatCycleInfoResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatCycleInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatCycleInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
5.1.5 BatchGetStatCycleRoundInfo Client API
Query the current round infos of cycles in batches.
Interface prototype:
/**
* Query the current round infos of cycles in batches.
*
* @param Params Request structure for querying current round infos.
*/
void BatchGetStatCycleRoundInfo(
const FBatchGetStatCycleRoundInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FBatchGetStatCycleRoundInfoResult* Data)> Callback) const;
struct FBatchGetStatCycleRoundInfoParams
{
/** The stat cycle names. */
TArray<FString> cycle_names;
};
Example Code:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetClientStatisticsAPI();
if (Statistics)
{
FBatchGetStatCycleRoundInfoParams Params;
Params.cycle_names.Add(TEXT("Daily"));
Params.cycle_names.Add(TEXT("Weekly"));
Statistics->BatchGetStatCycleRoundInfo(Params, [](const FPgosResult& Ret, const FBatchGetStatCycleRoundInfoResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatCycleInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatCycleRoundInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
5.2 For Game Server
The game can query and update stat data on the game server through PgosSDK
.
API | Description |
---|---|
GetStatPersistentInfo | Query the persistent info of the specified stat item. |
BatchGetStatPersistentInfo | Query item persistent info with specified stat names and keys in batches. |
GetStatCycleInfo | Query the cycle info of the specified stat item for the current cycle round. |
BatchGetStatCycleInfo | Query item cycle info with specified stat names and keys for the current cycle round in batches. |
UpdateStatItem | Update the specified stat item. |
BatchUpdateStatItem | Update the stat items in batches. |
BatchGetStatCycleRoundInfo | Query the current round infos of cycles in batches. |
5.2.1 GetStatPersistentInfo Server API
Query the persistent info of the specified stat item.
Interface prototype:
/**
* Query the persistent info of the specified stat item.
*
* @param Params Request structure for querying persistent info.
*/
void GetStatPersistentInfo(
const FGetStatPersistentInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FStatItem* Data)> Callback) const;
struct FGetStatPersistentInfoParams {
/** Stat name. */
FString stat_name;
/** Stat item key. */
FString key;
};
Example Code:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetServerStatisticsAPI();
if (Statistics)
{
FGetStatPersistentInfoParams Params;
Params.stat_name = TEXT("EnemyKills");
Params.key = TEXT("p456792");
Statistics->GetStatPersistentInfo(Params, [](const FPgosResult& Ret, const FStatItem* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetStatPersistentInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetStatPersistentInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
5.2.2 BatchGetStatPersistentInfo Server API
Query persistent infos with specified stat names and keys in batches.
Interface prototype:
/**
* Query item persistent infos with specified stat names and keys in batches.
* For example: stat_names=["s1", "s2"], keys=["k1", "k2"],
* then you will get a batch of items:[("s1", "k1"), ("s1", "k2"), "s2", "k1"), ("s2", "k2")]
* It will ignore non-existing (stat_name + key) combination items.
*
* @param Params Request structure for querying item persistent infos.
*/
void BatchGetStatPersistentInfo(
const FBatchGetStatPersistentInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FBatchGetStatPersistentInfoResult* Data)> Callback) const;
struct FBatchGetStatPersistentInfoParams
{
/** Stat names. */
TArray<FString> stat_names;
/** Stat item keys. */
TArray<FString> keys;
};
Example Code:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetServerStatisticsAPI();
if (Statistics)
{
FBatchGetStatPersistentInfoParams Params;
Params.stat_names.Add(TEXT("EnemyKills"));
Params.stat_names.Add(TEXT("PlayerDeaths"));
Params.keys.Add(TEXT("p456791"));
Params.keys.Add(TEXT("p456792"));
Statistics->BatchGetStatPersistentInfo(Params, [](const FPgosResult& Ret, const FBatchGetStatPersistentInfoResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatPersistentInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatPersistentInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
5.2.3 GetStatCycleInfo Server API
Query the cycle info of the specified stat item for the current cycle round.
Interface prototype:
/**
* Query the cycle info of the specified stat item for the current cycle round.
*
* @param Params Request structure for querying the cycle info.
*/
void GetStatCycleInfo(
const FGetStatCycleInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FGetStatCycleInfoResult* Data)> Callback) const;
struct FGetStatCycleInfoParams
{
/** The stat name. */
FString stat_name;
/** The stat item key. */
FString key;
/** The stat cycle name. */
FString cycle_name;
};
Example Code:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetServerStatisticsAPI();
if (Statistics)
{
FGetStatCycleInfoParams Params;
Params.stat_name = TEXT("EnemyKills");
Params.key = TEXT("p456792");
Params.cycle_name = TEXT("Daily");
Statistics->GetStatCycleInfo(Params, [](const FPgosResult& Ret, const FGetStatCycleInfoResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetStatCycleInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetStatCycleInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
5.2.4 BatchGetStatCycleInfo Server API
Query item cycle info with specified stat names and keys for the current cycle round in batches.
Interface prototype:
/**
* Query cycle infos with specified stat names and keys for the current cycle round in batches.
* For example: stat_names=["s1", "s2"], keys=["k1", "k2"],
* then you will get a batch of items:[("s1", "k1"), ("s1", "k2"), "s2", "k1"), ("s2", "k2")]
* It will ignore non-existing (stat_name + key) combination items.
*
* @param Params Request structure for querying item cycle infos.
*/
void BatchGetStatCycleInfo(
const FBatchGetStatCycleInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FBatchGetStatCycleInfoResult* Data)> Callback) const;
struct FBatchGetStatCycleInfoParams
{
/** The stat names. */
TArray<FString> stat_names;
/** The stat item keys. */
TArray<FString> keys;
/** The stat cycle name. */
FString cycle_name;
};
Example Code:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetServerStatisticsAPI();
if (Statistics)
{
FBatchGetStatCycleInfoParams Params;
Params.stat_names.Add(TEXT("EnemyKills"));
Params.stat_names.Add(TEXT("PlayerDeaths"));
Params.keys.Add(TEXT("p456791"));
Params.keys.Add(TEXT("p456792"));
Params.cycle_name = TEXT("Daily");
Statistics->BatchGetStatCycleInfo(Params, [](const FPgosResult& Ret, const FBatchGetStatCycleInfoResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatCycleInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatCycleInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
5.2.5 UpdateStatItem Server API
Interface prototype:
/**
* Update the specified stat item.
*
* @param Params Request structure for updating the specified stat item.
*/
void UpdateStatItem(
const FServerUpdateStatItemParams& Params,
TFunction<void(const FPgosResult& Ret, const FServerStatItemAfterUpdate* Data)> Callback) const;
struct FServerUpdateStatItemParams
{
/** The stat item to update. */
FStatItem item;
};
struct FStatItem
{
/** Stat name. */
FString stat_name;
/** Stat item key. */
FString key;
/**
* The meaning of the value varies in different scenarios:
* 1. Get stat item persistent value: it is item persistent value.
* 2. Get stat item cycle value: it is item cycle value.
* 3. Update stat item value: it is the value to be aggregated into the stat item.
*/
double value = 0.0;
/** Stat item secondary value. It will overwrite the old one when updated. */
double secondary_value = 0.0;
/** Stat item tags. It will overwrite the old one when updated. */
TArray<FString> tags;
/** The method to aggregate. */
EAggregateType aggregate_type = EAggregateType::Overwrite;
};
Example Code:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetServerStatisticsAPI();
if (Statistics)
{
FServerUpdateStatItemParams Params;
Params.item.stat_name = TEXT("EnemyKills");
Params.item.key = TEXT("p456792");
Params.item.value = 2;
Params.item.aggregate_type = EAggregateType::Sum;
Statistics->UpdateStatItem(Params, [](const FPgosResult& Ret, const FServerStatItemAfterUpdate* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("UpdateStatItem Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("UpdateStatItem Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
5.2.6 BatchUpdateStatItem Server API
Interface prototype:
/**
* Update the stat items in batches.
*
* @param Params Request structure for updating the stat items in batches.
*/
void BatchUpdateStatItem(
const FServerBatchUpdateStatItemParams& Params,
TFunction<void(const FPgosResult& Ret, const FServerBatchUpdateStatItemResult* Data)> Callback) const;
struct FServerBatchUpdateStatItemParams
{
/** The stat items to update. */
TArray<FStatItem> items;
};
Example Code:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetServerStatisticsAPI();
if (Statistics)
{
FStatItem item1;
item1.stat_name = TEXT("EnemyKills");
item1.key = TEXT("p600001");
item1.value = 2;
item1.aggregate_type = EAggregateType::Sum;
FStatItem item2;
item2.stat_name = TEXT("EnemyKills");
item2.key = TEXT("p600002");
item2.value = 5;
item2.aggregate_type = EAggregateType::Sum;
FServerBatchUpdateStatItemParams Params;
Params.items.Add(item1);
Params.items.Add(item2);
Statistics->BatchUpdateStatItem(Params, [](const FPgosResult& Ret, const FServerBatchUpdateStatItemResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchUpdateStatItem Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchUpdateStatItem Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
5.2.7 BatchGetStatCycleRoundInfo Server API
Query the current round infos of cycles in batches.
Interface prototype:
/**
* Query the current round infos of cycles in batches.
*
* @param Params Request structure for querying current round infos.
*/
void BatchGetStatCycleRoundInfo(
const FBatchGetStatCycleRoundInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FBatchGetStatCycleRoundInfoResult* Data)> Callback) const;
struct FBatchGetStatCycleRoundInfoParams
{
/** The stat cycle names. */
TArray<FString> cycle_names;
};
Example Code:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetServerStatisticsAPI();
if (Statistics)
{
FBatchGetStatCycleRoundInfoParams Params;
Params.cycle_names.Add(TEXT("Daily"));
Params.cycle_names.Add(TEXT("Weekly"));
Statistics->BatchGetStatCycleRoundInfo(Params, [](const FPgosResult& Ret, const FBatchGetStatCycleRoundInfoResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatCycleInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatCycleRoundInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
5.3 Error Handling
Error Code | Relevant API | Handling Suggestion |
---|---|---|
kBackendStatItemMissingCriticalFields | GetStatPersistentInfo Client API BatchGetStatPersistentInfo Client API GetStatCycleInfo Client API BatchGetStatCycleInfo Client API GetStatPersistentInfo Server API BatchGetStatPersistentInfo Server API GetStatCycleInfo Server API BatchGetStatCycleInfo Server API UpdateStatItem Server API BatchUpdateStatItem Server API | Missing critical fields such as stat_name , key |
kBackendStatKeysNoData | GetStatPersistentInfo Client API BatchGetStatPersistentInfo Client API GetStatCycleInfo Client API BatchGetStatCycleInfo Client API GetStatPersistentInfo Server API BatchGetStatPersistentInfo Server API GetStatCycleInfo Server API BatchGetStatCycleInfo Server API | Found no data for specific stat and cycle |
kSdkNetworkError | All Network API | network error, check error msg for detail. |