Skip to content

Leaderboards and Stats Storage

Leaderboards are backed by a MongoDB stats collection. Each match writes one entry per score + subject at match end.

Storage Model

Stored document fields:

  • matchId
  • minigameId
  • mode
  • map
  • region
  • shard
  • scope.target (global, network, server, gamemode)
  • scope.id (required for non-global scopes)
  • scoreId
  • subjectId (UUID)
  • value
  • endedAt

Indexes

Recommended indexes (created at startup):

  • { scope.target: 1, scope.id: 1, scoreId: 1, minigameId: 1, mode: 1, map: 1, region: 1, endedAt: -1 }
  • { subjectId: 1, scoreId: 1, scope.target: 1, scope.id: 1, endedAt: -1 }
  • { matchId: 1 }

History and rank tracking

Value changes are tracked in stats_history so rank movement can be visualized over time.

History fields:

  • subjectId (UUID)
  • scoreId
  • scope.target
  • scope.id
  • minigameId
  • mode
  • map
  • region
  • shard
  • value
  • rank
  • recordedAt

History entries are appended whenever the aggregated value changes.

Leaderboard Aggregation

Leaderboards can be computed with different aggregation modes:

  • max (default)
  • sum
  • avg
  • last (most recent value)

Sorting uses order (desc or asc) from the score definition.

Configuration

Score definitions are data-driven via the Game Editor and exported into templates:

json
{
  "scoreDefinitions": [
    {
      "id": "kills",
      "displayName": "Kills",
      "mode": "higher",
      "aggregation": "sum",
      "order": "desc"
    }
  ]
}

Mongo config via env:

  • MONGO_URI
  • MONGO_DB (default uebliche_games)