Skip to main content

Stats

Talo stats let you track individual player data as well as aggregated global data - like how many items have been crafted or how many deaths a player has.

To create a stat, head over to the dashboard, visit the stats page and create your first stat. Take note of the Internal name as this is how you'll be referring to your stat.

tip

Check out this blog post on how to track player stats in Unity for a detailed walkthrough

Getting stats

read:gameStats

You can list all available stats using Talo.Stats.GetStats(). This will return all the constraint data defined in the dashboard like the defaultValue, maxChange and maxValue. This will also return the global values for global stats:

var res = await Talo.Stats.GetStats();
var internalNames = res.Length > 0 ? string.Join(", ", res.Select((item) => item.internalName)) : "no stats";
// e.g. Stats: gold-collected, health-healed, deaths
Debug.Log($"Stats: {internalNames}");

Fetching individual stats

If you already have the internal name of a stat, you can use Talo.Stats.Find() and pass in the internal name to return data for a single stat.

Tracking stats

write:gameStats

You can track a stat using the Stats API Track() function which takes your stat's internalName and the amount to change the stat by (default 1.0f):

PlayerDeathController.cs
public void OnDeath()
{
Talo.Stats.Track('deaths')
}
PlayerPotionController.cs
private float health;

public void OnHeal(Potion potion)
{
health += potion.amount
Talo.Stats.Track('health-healed', potion.amount)
}

Stat values

After updating a stat using Track(), you can check the updated value for the player stat and global stat:

var res = await Talo.Stats.Track('gold-collected', 104);
Debug.Log($"{res.playerStat.value}, {stat.playerStat.stat.globalValue}")

Find a stat value

read:gameStats

You can also get the current value of a stat for a player using Talo.Stats.FindPlayerStat().

Listing player stat values

read:gameStats

If you need to find all player stat values for the current player, you can use Talo.Stats.ListPlayerStats(). This function returns a list of player stats which include the value and related stat:

var res = await Talo.Stats.ListPlayerStats();
var statsList = res.Length > 0
? string.Join(", ", res.Select((item) => $"{item.stat.internalName} = {item.value}"))
: "none";

Debug.Log($"Player stats: {statsList}"); // Player stats: deaths = 5, health-healed = 200

The function above iterates through the player stats returned by the API and pick out the stat.internalName and value.

Stat history

read:gameStats

You can fetch a history of updates to a stat for the current player using Talo.Stats.GetHistory(). These results are paginated and can be filtered by specific start and end dates:

private async void FetchHistory()
{
try
{
var res = await Talo.Stats.GetHistory(statInternalName);

// e.g. "gold-collected changed by 100, 46, 82, 19, 104"
Debug.Log($"{statInternalName} changed by: {string.Join(", ", res.history.Select((item) => item.change))}");
}
catch (Exception ex)
{
Debug.LogError(ex.Message);
throw ex;
}
}

Filtering stat history

The GetHistory() function accepts the following optional parameters:

  • page: Page number for pagination (default: 0)
  • startDate: Filter to show only changes tracked on or after this date
  • endDate: Filter to show only changes tracked on or before this date
// Get the second page of history
var res = await Talo.Stats.GetHistory(statInternalName, page: 1);

// Get history for September 2025
var startDate = new DateTime(2025, 9, 1);
var endDate = new DateTime(2025, 9, 30);
var res = await Talo.Stats.GetHistory(statInternalName, startDate: startDate, endDate: endDate);

// Get all history since a specific date
var sinceDate = new DateTime(2025, 9, 15);
var res = await Talo.Stats.GetHistory(statInternalName, startDate: sinceDate);

Global stat history

read:gameStats

For global stats, you can also fetch a history of updates from all players using Talo.Stats.GetGlobalHistory(). This API returns metrics about the stat during the filtered time period and can be filtered by player, date range, and pagination:

private async void FetchGlobalHistory()
{
try
{
var res = await Talo.Stats.GetGlobalHistory(statInternalName);
var totalUpdates = res.count;
var globalMetrics = res.globalValue;
var playerMetrics = res.playerValue;

Debug.Log(
$"Total: {totalUpdates}, " +
$"Min: {globalMetrics.minValue}, " +
$"max: {globalMetrics.maxValue}, " +
$"median: {globalMetrics.medianValue}, " +
$"average: {globalMetrics.averageValue}, " + // average global value
$"average change: {globalMetrics.averageChange}, " +
$"average player value: {playerMetrics.averageValue}" // average player value
);
}
catch (Exception ex)
{
Debug.LogError(ex.Message); // e.g. stat isn't global
}
}

Filtering global stat history

The GetGlobalHistory() function accepts the following optional parameters:

  • page: Page number for pagination (default: 0)
  • playerId: Filter to show only changes from a specific player ID
  • startDate: Filter to show only changes tracked on or after this date
  • endDate: Filter to show only changes tracked on or before this date
// Get global history for a specific player
var res = await Talo.Stats.GetGlobalHistory(statInternalName, playerId: "player-123");

// Get global history for September 2025
var startDate = new DateTime(2025, 9, 1);
var endDate = new DateTime(2025, 9, 30);
var res = await Talo.Stats.GetGlobalHistory(statInternalName, startDate: startDate, endDate: endDate);

// Get global history for a specific player in a date range
var res = await Talo.Stats.GetGlobalHistory(statInternalName, playerId: "player-123", startDate: startDate, endDate: endDate);

// Get the second page of global history
var res = await Talo.Stats.GetGlobalHistory(statInternalName, page: 1);