menu_bookDocumentation

Backend Services - Achievements, Leaderboards, Stats

calendar_today May 3, 2026 schedule ~1 min read person patrickjr verified 50

Backend Services - Achievements, Leaderboards, Stats

Integrate Steam backend services for player progression, competition, and analytics.

Achievements

Track and award player accomplishments:

CSHARP
// Unlock an achievement
Sandbox.Services.Achievements.Unlock("first_win");

// Check if unlocked
bool hasAchievement = Sandbox.Services.Achievements.IsUnlocked("first_win");

// Get all achievements
var achievements = Sandbox.Services.Achievements.All;
foreach (var achievement in achievements)
{
    Log.Info($"{achievement.Name}: {achievement.IsUnlocked}");
}

Achievement Definition

Define achievements in your game settings:

  • ID — Unique identifier (lowercase, no spaces)

  • Name — Display name

  • Description — What the player did to earn it

  • Hidden — Secret until unlocked

  • Icon — Unlocked/locked state images

Leaderboards

Rank players by score, time, or custom metrics:

CSHARP
// Submit a score
await Leaderboards.Submit("high_score", playerScore);

// Submit with replay data
await Leaderboards.Submit("speed_run", timeSeconds, replayData);

// Get top scores
var topScores = await Leaderboards.Get("high_score", 10);
foreach (var entry in topScores)
{
    Log.Info($"{entry.Rank}. {entry.DisplayName}: {entry.Score}");
}

// Get player's friends scores
var friendScores = await Leaderboards.GetFriends("high_score");

// Get scores around player (centering)
var nearbyScores = await Leaderboards.GetCentered("high_score", 5);

Leaderboard Types

TypeUse Case
NumericHigh scores, points, kills
TimeSpeed runs, lap times (lower is better)

Filtering and Aggregation

CSHARP
// Filter by date
var thisWeek = await Leaderboards.Get("score", filter: LeaderboardFilter.ThisWeek);

// By country (ISO 3166-1 alpha-2)
var usScores = await Leaderboards.Get("score", country: "US");

// Aggregation methods
await Leaderboards.Submit("daily_best", score, aggregation: LeaderboardAggregation.Best);

Stats

Track player and global statistics:

CSHARP
// Increment a stat (creates if doesn't exist)
await Stats.Increment("zombies_killed", 5);

// Set absolute value
await Stats.SetValue("total_playtime", hoursPlayed);

// Get current value
int kills = await Stats.GetValue("zombies_killed");

// Get global stats
var globalStats = await Stats.GetGlobal("total_matches_played");

Auth Tokens

Secure API communication:

CSHARP
// Get auth token for web API calls
var token = await Auth.GetTokenAsync();

// Use with your backend
var response = await http.RequestJsonAsync($"https://myapi.com/userdata?token={token}");

Tokens are:

  • Unique per player

  • Time-limited

  • Verifiable against Steam

Web API

Access leaderboards from external services:

CODE
GET https://api.sbox.game/leaderboards/{org}.{game}/{leaderboard_id}
Authorization: Bearer {auth_token}

Response:

JSON
{
  "entries": [
    {
      "rank": 1,
      "steam_id": "76561197991348132",
      "score": 999999,
      "timestamp": "2024-01-15T10:30:00Z"
    }
  ]
}

Best Practices

  1. Progressive achievements — Easy early wins, harder later
  2. Descriptive names — "Kill 100 Zombies" not "Zombie Hunter"
  3. Granular stats — Track everything, analyze later
  4. Handle failures — Services may be unavailable
  5. Batch operations — Submit stats in groups when possible

Rate Limits

  • Achievements: 100 unlocks per minute
  • Leaderboards: 10 submissions per minute
  • Stats: 100 updates per minute
Was this helpful?