Statistics & leaderboards
Increment a stat once and get daily, weekly, monthly and lifetime leaderboards for free. The hub keeps the rolling windows.
You write one line when something happens. The hub keeps four rolling leaderboards from it - daily, weekly, monthly and lifetime - and hands them all back on every increment.
// A win happened. One call, every window moves at once.
hive.player()
.incrementStatistic(player.uuid(), "wins", "skywars", 1)
.thenAccept(now -> {
// now: { DAILY: 3, WEEKLY: 11, MONTHLY: 40, LIFETIME: 512 }
player.sendMessage("Win #" + now.get("LIFETIME"));
}); That single +1 updated four windows at once. No cron jobs, no nightly rollups,
no “reset the weekly board” task. You never schedule anything:
| Period | Counts | Resets |
|---|---|---|
DAILY | today (UTC) | midnight UTC |
WEEKLY | this week | Monday |
MONTHLY | this month | the 1st |
LIFETIME | all time | never |
Scoped to your game
A stat lives under its game mode,
so "wins" in "skywars" and "wins" in "bedwars" are different numbers that
never touch each other. Same stat name, separate boards, zero coordination
between games.
Reading them back
getStatistic(name, period) pulls a single window - the weekly board, the
lifetime total, whatever you need:
// "This week's top players" is one read.
hive.player()
.getStatistics(player.uuid(), "skywars")
.thenAccept(stats -> {
StatisticValue weekly = stats.getStatistic("wins", PeriodType.WEEKLY);
long wins = weekly != null ? weekly.getValue() : 0;
}); Each StatisticValue carries its periodType, the periodStart it belongs to,
the value, and when it was last updated - so a leaderboard is just “read this
stat, this period, top N.”
Stat or namespace? Counters you want ranked or counted over time →
incrementStatistic. Structured state that’s just yours → namespaces. Don’t hand-roll a leaderboard in a JSON blob - that’s what stats are for.
Next
- Currencies - network-wide balances on the player.
- Namespaces - your game’s private JSON store.
- Match scoring - wins and kills land here automatically.