Skip to main content

Track player and game wide global statistics

Last updated on April 1, 2024

Overview

To start tracking user statistics and game wide global statistics, you will first need to create a statistics configuration that consists of several rules and definitions.

In this document you will learn how to set up a statistics configuration, for tracking user and game-wide global statistics.

Goals

  • Provide an overview of the statistics configuration
  • Explain how to configure stats for user statistics and global statistics
  • Explain how to use statistics using the AccelByte SDK, including how to utilize the multiple update functionality

Prerequisites

You will need access to:

  • An AccelByte Admin Portal
  • The AccelByte Unreal or Unity SDK
  • The AccelByte statistics API documentation for further reference

Configure User and Global Statistics

It is very important for a game to have persistent statistics tracking for users, so that user progress can be tracked consistently.

You can set up a statistics configuration from the Admin Portal by following the steps below.

  1. In the Admin Portal, go to the Game Management section, expand the Statistics section, and select the Configurations menu.

  2. In the Statistic Configurations window, click the Add Configuration button.

  3. The Add New Configuration form will appear.

    From the form above, you will be required to:

    • Fill in the Stat Code using the allowed formats, and also the statistic Name to make it easier for you to identify the stats in the future. You can also put an optional Description to provide extra information about the statistic you created.

    • Enter the optional Min. Value and Max. Value for extra server side validation, to make sure you can prevent users from exceeding the allowed numbers. You also need to add the mandatory Default Value to determine the starting number, or value, of a statistic for each user.

  4. There are also some additional configurations that you can set up to make sure you utilize the statistics feature fully. Refer to the following forms.

    • You can choose to prevent a statistic value from decreasing by setting Increment to true. This feature provides you extra server side validation, to make sure users take advantage of a certain game mechanic for their own benefit.

    • To track a global accumulated value of the statistic from all of the contributing users, make sure Set as Global is set to true. This way, the system will not only track an individual user statistic, but also the accumulated statistics from all users that contribute to a global statistic.

    • You can also add validation to make sure that only the game server can update the statistics, by setting the Set By field to Server. This way, users will get rejected from updating the statistics from the game client directly. This is also a good way to prevent cheating or game client tampering.

    • You can optionally configure tags for the statistics, to make it easier for you to group and organize the statistics from the game.

Using Statistics from a Game

Once the statistics are configured in the Admin Portal, you can use then from the game directly, referring to the example explained in this section.

Note that you can also do server authoritative statistics management by following the guide in here.

Updating Statistics from a Game

This update functionality can be called directly from the game client, and is suitable for a non-competitive genre such as single player or peer to peer multiplayer that don't utilize any game server.

There are several update strategies supported, as listed in the table below:

Update StrategyUsageExample Implementation
OVERRIDEThe update will replace the existing value of your statistic with the latest oneThis is suitable if you have your own calculation, such as ELO or MMR. You can pass the latest value, for the service to store.
INCREMENTThe update will add or subtract the new value to the existing value, depending if the new value is (+) or (-)This is suitable to track experience points gained in the battle. This way, you can pass the points directly, and the service will handle the increment.
MAXThis will only update the statistic if the value is higher than the existing oneThis is suitable to track best/highest scores such as Kills or Damage dealt. The service will ignore the update if the score is lower than the existing one.
MINThis will only update the statistic if the value is lower than the existing one.This is suitable to track the smallest score such as best racing lap or fastest round. The service will ignore the update if the score is higher than the existing one.

Update Single User Stats

FApiClientPtr ApiClient = FMultiRegistry::GetApiClient();

FString AdditionalKey = " Your additional key";
FString StatCode = " Your stat code ";

FAccelByteModelsPublicUpdateUserStatItem UserStatItem{};
UserStatItem.UpdateStrategy = EAccelByteStatisticUpdateStrategy::OVERRIDE;
UserStatItem.Value = 100.0f;

ApiClient->Statistic.UpdateUserStatItemsValue(StatCode
, AdditionalKey
, UserStatItem
, THandler<FAccelByteModelsUpdateUserStatItemValueResponse>::CreateLambda([](FAccelByteModelsUpdateUserStatItemValueResponse Result)
{
// Do something if UpdateUserStatItemsValue been successful
})
, FErrorHandler::CreateLambda([](int32 ErrorCode, FString ErrorMessage)
{
// Do something if UpdateUserStatItemsValue has an error
}));

Update Multiple Stats for One User

FApiClientPtr ApiClient = FMultiRegistry::GetApiClient();

FString AdditionalKey = " Your additional key";

FAccelByteModelsUpdateUserStatItemWithStatCode UserStatItem1{};
UserStatItem.StatCode = " Your 1st stat code ";
UserStatItem.UpdateStrategy = EAccelByteStatisticUpdateStrategy::OVERRIDE;
UserStatItem.Value = 100.0f;

FAccelByteModelsUpdateUserStatItemWithStatCode UserStatItem2{};
UserStatItem.StatCode = " Your 2nd stat code ";
UserStatItem.UpdateStrategy = EAccelByteStatisticUpdateStrategy::INCREMENT;
UserStatItem.Value = 50.0f;

TArray<FAccelByteModelsUpdateUserStatItemWithStatCode> BulkUpdateUserStatItems = { UserStatItem1, UserStatItem2 };

ApiClient->Statistic.BulkUpdateUserStatItemsValue(AdditionalKey
, BulkUpdateUserStatItems
, THandler<TArray<FAccelByteModelsUpdateUserStatItemsResponse>>::CreateLambda([](TArray<FAccelByteModelsUpdateUserStatItemsResponse> Result)
{
// Do something if BulkUpdateUserStatItemsValue been successful
})
, FErrorHandler::CreateLambda([](int32 ErrorCode, FString ErrorMessage)
{
// Do something if BulkUpdateUserStatItemsValue has an error
}));

Retrieving User Statistics from a Game

Retrieving user statistics is straightforward, you can display user stats as part of the user profile or anywhere within the game UI. You can also choose to list all user statistics, display some statistics by statcodes or simply display statistics by the tags that you configured through the admin portal before.

To use the SDK functionality, refer to the snippets below

Get Current and Other User Statistics

FApiClientPtr ApiClient = FMultiRegistry::GetApiClient();

FString UserId = "Player User Id";
TArray<FString> StatCodes = { "Stat Code 1", "Stat Code 2" };
TArray<FString> Tags = { "Tag 1", "Tag 2", "Tag 3" };
int32 Offset = 0;
int32 Limit = 20;

ApiClient->Statistic.GetUserStatItems(UserId
, StatCodes
, Tags
, THandler<FAccelByteModelsUserStatItemPagingSlicedResult>::CreateLambda([](FAccelByteModelsUserStatItemPagingSlicedResult Result)
{
// Do something if GetUserStatItems has been successful
})
, FErrorHandler::CreateLambda([](int32 ErrorCode, FString ErrorMessage)
{
// Do something if GetUserStatItems has an error
})
, Offset
, Limit);

Retrieving Global Statistics from a Game

Similar to the user statistics, you can also display global statistics anywhere within the game UI easily. You can choose to display all of the global statistics that you have or choose a specific stat using the statcode.

To use the SDK functionality, refer to the snippets below.

Get Global Stats Using a Statcode

FApiClientPtr ApiClient = FMultiRegistry::GetApiClient();

FString StatCode = "Your Global Statistic Code";

ApiClient->Statistic.GetGlobalStatItemsByStatCode(StatCode
, THandler<FAccelByteModelsGlobalStatItemValueResponse>::CreateLambda([](FAccelByteModelsGlobalStatItemValueResponse Result)
{
// Do something if GetGlobalStatItemsByStatCode has been successful
})
, FErrorHandler::CreateLambda([](int32 ErrorCode, FString ErrorMessage)
{
// Do something if GetGlobalStatItemsByStatCode has an error
}));