# Leaderboards for PlayDrop games

Declare leaderboards in catalogue.json, submit scores with sdk.leaderboards and show top ranks and the player's neighbors. Score types, limits and update rules.

Source: https://www.playdrop.ai/create/learn/leaderboards

Leaderboards give players a reason to replay and a rank to share. PlayDrop stores each player's best score per leaderboard and shows it on the game.

## Declare a leaderboard

Add it to the app in [catalogue.json](https://www.playdrop.ai/create/learn/catalogue-json):

```json
{
  "leaderboards": [
    { "key": "high-score", "displayName": "High score", "description": "Most points in one run",
      "scoreType": "INTEGER", "sort": "DESC", "unitLabel": "pts" },
    { "key": "best-time", "displayName": "Fastest run", "description": "Time to reach the flag",
      "scoreType": "TIME_MS", "sort": "ASC" }
  ]
}
```

- `key`: 3 to 64 characters, starting with a lowercase letter, then lowercase letters, digits, `_`, `.` or `-`.
- `scoreType` and `sort` come in two pairs: `INTEGER` with `DESC` (higher wins, scores of 0 or more) or `TIME_MS` with `ASC` (lower wins, positive milliseconds).
- `unitLabel` is optional display text.

Once published, a key cannot be removed and its `scoreType` and `sort` cannot change. Stop using one with `"status": "RETIRED"`. Leaderboards need a [package](https://www.playdrop.ai/create/learn/packaging).

## Submit and read scores

```js
const result = await sdk.leaderboards.submitScore("high-score", 1200);
// { accepted, improved, previousBestScore, bestScore, rank, previousRank, bestScoreAt, leaderboard }
if (result.improved) showNewBest(result.bestScore, result.rank);

const { leaderboard } = await sdk.leaderboards.get("high-score", { top: 10, aroundMe: 3 });
// leaderboard: { definition, top, player, playerEntry, aroundPlayer }

const { leaderboards } = await sdk.leaderboards.list();
```

- Scores are safe integers. Only a better score replaces the best.
- `top` accepts 1 to 100 entries and `aroundMe` 1 to 20 on each side of the player.
- `list({ includeRetired: true })` also returns retired boards.

Submit at the end of a run, not every frame, and only in the `play` phase. Handle rejected calls like any network call; keep the game playable.

## Guests and offline

You can submit without checking sign-in. With no player session at all, a submission resolves without being stored. Hosts that advertise device-data support, such as offline-capable PlayDrop apps, keep a score made offline and sync it later; their offline reads show only the player's own best, with no rank. Elsewhere a submission needs a connection.

## What leaderboards do not do

There are no regions, scheduled resets, seasons or automatic weekly prizes in the SDK. For a weekly board, include the week in your own design, for example a new key per season declared in a new version.

Related: [achievements](https://www.playdrop.ai/create/learn/achievements), [cloud saves](https://www.playdrop.ai/create/learn/cloud-saves), [sharing a score](https://www.playdrop.ai/create/learn/social).

## Related guides

- [Achievements](https://www.playdrop.ai/create/learn/achievements): Declare standard and incremental achievements with icons in catalogue.json, unlock them and report progress with sdk.achievements.
- [Cloud saves](https://www.playdrop.ai/create/learn/cloud-saves): Save and load player progress with sdk.me.appData and updateAppData, for guests and signed-in players, with the rules for writes, previews and offline play.
- [catalogue.json](https://www.playdrop.ai/create/learn/catalogue-json): The catalogue.json fields PlayDrop games use: identity, listing, play modes, surfaces, sign-in, Instant, preloading, media, translations, scores and servers.
