Skip to main content

Leaderboards

Real-time and historical ranking systems with multiple scoring models.


Purpose

Leaderboards track player performance within a season, league, or event. They serve two functions:

  1. During competitive period — show live standings, drive engagement
  2. At settlement — determine reward distribution and achievement eligibility

Scoring Models

ModelDescriptionBest For
ELOChess-style rating that adjusts based on opponent strength1v1 games, skill-based matchmaking
Total WinsSimple win countEvents, casual modes
Win RateWin percentage (with minimum games requirement)Short events where consistency matters
PointsConfigurable point system (win = X, loss = Y, draw = Z)Team games, complex scoring
CompositeWeighted combination of multiple metricsGames with multiple competitive dimensions

ELO Configuration

{
scoring_model: "elo",
initial_rating: 1200,
k_factor: 32, // how much each match affects rating
k_factor_new_player: 64, // higher K for first N games
new_player_game_threshold: 20, // games before K normalizes
floor: 100 // minimum rating
}

Points Configuration

{
scoring_model: "points",
points_per_win: 3,
points_per_draw: 1,
points_per_loss: 0,
bonus_points: {
streak_3: 1, // bonus for 3-win streak
streak_5: 2, // bonus for 5-win streak
perfect_game: 1 // bonus for specific achievement
}
}

Leaderboard Types

Global Leaderboard

All players across all leagues, ranked by a single metric (e.g., ELO).

League Leaderboard

Players ranked within their current league tier. Used for promotion/relegation decisions.

Event Leaderboard

Temporary, scoped to a specific event or tournament. Reset when the event ends.

Historical Leaderboard

Past season rankings, preserved for reference. Can be queried for achievement verification.


On-Chain vs Off-Chain

ComponentLocationReason
Live standingsOff-chainUpdated per match, too frequent for chain
Final season rankingsOn-chainDetermines reward distribution
Event resultsOn-chainDetermines prize pool claims
Achievement thresholdsOff-chain check, on-chain mintServer verifies, contract trusts signed attestation
Historical archivesOff-chain (DB)Chain storage too expensive for full history

Data Structure

// Leaderboard entry (server-side)
{
player_id: "user_123",
wallet_address: "0x1234...", // null until wallet linked
season_id: 1,
league_id: "gold",

stats: {
rating: 1847,
wins: 62,
losses: 28,
draws: 3,
games_played: 93,
win_rate: 0.667,
current_streak: 4,
best_streak: 12
},

rank: 15, // position in league
global_rank: 142, // position overall
updated_at: "2026-05-15T14:30:00Z"
}

API Endpoints

GET /api/v1/leaderboard/{season_id}
?league={league_id}
&page={page}
&limit={limit}
&sort={rating|wins|win_rate}

Response:
{
season_id: 1,
league_id: "gold",
total_players: 847,
entries: [
{ rank: 1, player_id: "...", rating: 2150, wins: 87, ... },
{ rank: 2, player_id: "...", rating: 2050, wins: 80, ... },
...
]
}

Integration Guide

  1. Choose a scoring model — ELO, points, or custom
  2. Implement rating updates — calculate after every match on your server
  3. Expose leaderboard API — for your game client to query and display
  4. Persist history — store per-season standings for archival and achievement verification
  5. Submit final rankings — at season/event end, submit to chain for settlement