# Team Stats

**URL:** https://heroiclabs.com/docs/hiro/concepts/teams/stats/
**Summary:** Track and manage public and private stats for teams
**Keywords:** stats, statistics, team-stats, teams
**Categories:** hiro, stats, teams

---


# Team Stats

## Overview

Team Stats are for tracking and managing public and private statistics for Teams, such as experience points, available team slots, passive bonuses, and anything else your game requires. This system allows Teams to gather and view data about their performance, progress, and accomplishments.

## Features

- **Tailored to your game**: Create stats that fit your specific game mechanics with custom names, starting values, and metadata properties.
- **Comprehensive tracking**: See current values plus min/max ranges, totals, and submission counts over time.
- **Public and private stats**: Show off accomplishments publicly or keep internal metrics private for team strategy.
- **Different ways to update**: Add to existing values, set new ones, or only update when values are higher or lower.

## Permissions

**Viewing Stats**

- **All Members** can all view both public and private stats for their teams
- Players can only see stats for teams where they hold active membership (not banned or pending approval)
- Public stats are also visible in team listings and search results to non-members

**Updating Stats**

- **Admins Only** can update Team Stats
- Regular members cannot modify stats directly, though their gameplay actions may trigger server-side stat updates

For complete API documentation, see the Team Stats Reference Guide.

## Public vs Private Stats

There are two top-level categories of Team Stats, each with their own access controls.

**Public Stats** are for achievements and metrics that teams want to showcase, for example:

- Level and experience points
- Win/loss records
- Quests or challenges completed
- Tournament rankings

Public stats are stored in the Team's metadata and are available to anyone who can see basic Team information. These stats automatically appear in Team listings.

**Private Stats** are for internal metrics that teams might use for strategy, team management, and anything else that isn't relevant to non-team members:

- Strategic information
- Resource data
- Member performance
- Metrics that shouldn't influence matchmaking

Private stats are stored in separate, access-controlled storage and never appear in public team listings.

## Building with Stats

**Publisher Events**

Every stat update generates detailed events that integrate with Hiro's Publisher system. These events contain comprehensive metadata about the operation, including the stat name, operation type, old and new values, and timestamp. Use these events for:

- Real-time analytics dashboards
- Achievement systems
- Grant exclusive avatars, banners, or equipment at certain stat thresholds

Learn more in the [Publishers](../../publishers/) guide.

**Stats with Rewards**

While Team Stats don't directly grant rewards, they can serve as triggers and conditions for other reward-granting systems:

- Stats can serve as progress metrics for Team Achievements
- Stats can determine team rankings and tier placements for Team Event Leaderboards
- Server-side hooks can monitor stat changes and grant rewards for meeting different conditions, enabling the creation of custom reward logic

<!-- TODO: Needs separate How-to guide for this, too much to put here -->
<!-- ### Example: Level-Up Rewards

When building progression systems, you may want to grant rewards when certain stat thresholds are reached. This example shows how to implement a team level-up flow that automatically increases team slots every 5 levels:

You could extend this same pattern to include other benefits for reaching stat thresholds:

- **Item Rewards**: Grant exclusive avatars, banners, or equipment at milestone levels
- **Event Leaderboard Rank-up**: Use team level as a factor in competitive matchmaking
- **Member Benefits**: Send individual rewards to all members' mailboxes

This approach allows you to create progression systems that enhance both team capabilities and reward individual team members. -->

## What Ifs

_This section describes edge cases and scenarios that may be unintuitive to the developer._

**Stats are removed from the Team Stats config**

When you modify your stats configuration, teams retain their existing values even if those stats no longer appear in your current setup. If you re-add a stat with the same name later, teams will keep their previous progress. To reset all teams to zero for a removed stat, you'll need to clear the stored values manually.

**Updates to Team Stats are made simultaneously by different admins**

If two team admins try to update the same stat at the exact same time, one update may fail and need to be retried. However, if they're updating different stats simultaneously, both operations will succeed. The system prevents conflicts but requires admins to handle retry logic for contested updates.

**An admin performs a stat update but then loses their role**

Permission checks happen when the update request is processed. If an admin loses their role or leaves the team while an update is in progress, that update will fail with a permission error. This prevents former members from manipulating team stats.

## Configuring Team Stats

**Stats Config**

| Property        | Type              | Definition                                 |
| :
-------------- | :---------------- | :----------------------------------------- |
| `stats`         | `object`          | Container for all team stats configuration |
| `stats_public`  | `map[string]Stat` | Public stats visible in team listings      |
| `stats_private` | `map[string]Stat` | Private stats for internal team use        |

**Individual Stat Config**

Each stat is defined by a unique name (the key) and its configuration properties:

| Property                | Type     | Definition                          |
| :---------------------- | :------- | :---------------------------------- |
| `value`                 | `int`    | Default starting value for the stat |
| `additional_properties` | `object` | Custom metadata for the stat        |

### Example: Team Stats JSON

The JSON schema defines a `stats` object which contains `stats_public` and `stats_private` groupings. Within each group, you define individual stat objects for each stat you wish to track. You can configure as few or as many stats as needed for your game.

The following JSON demonstrates how to configure Team Stats:

```json
{
  // ... other Team configs
  "stats": {
    "stats_public": {
      "team_level": {
        "value": 1,
        "additional_properties": {
          "display_name": "Team Level",
          "icon": "level_star"
        }
      },
      "experience_points": {
        "value": 0,
        "additional_properties": {
          "max_display": 10000
        }
      }
    },
    "stats_private": {
      "member_performance_average": {
        "value": 0,
        "additional_properties": {
          "calculation_method": "weighted_average"
        }
      }
    }
  }
}
```
