Mobile Game Leaderboard System Development
Leaderboards—social mechanic converting solo progress into competition. Casual games need simple global rating. Mid-core and competitive need segmented leaderboards: friends, by region, weekly, by level. Implementation difference is principal.
Backend Choice
| Solution | When Fits | Limits |
|---|---|---|
| Google Play Games Leaderboards | Simple global, Android | Android only, limited types |
| Game Center Leaderboards | iOS, simple global/friends | iOS only |
| PlayFab Leaderboards | Cross-platform, flexible | Paid at high load |
| Firebase Realtime DB / Firestore | Flexible, real-time | Need custom indexing |
| Custom backend | Full control | Development and maintenance |
For most mobile games PlayFab is optimal: no backend logic, built-in anti-cheat for scores.
PlayFab Leaderboards
// Submit score
public void SubmitScore(int score, string leaderboardName = "global_score")
{
PlayFabClientAPI.UpdatePlayerStatistics(
new UpdatePlayerStatisticsRequest
{
Statistics = new List<StatisticUpdate>
{
new StatisticUpdate
{
StatisticName = leaderboardName,
Value = score
}
}
},
result => Debug.Log("Score submitted"),
error => Debug.LogError(error.GenerateErrorReport())
);
}
// Get top 100
public void GetLeaderboard(string leaderboardName, Action<List<LeaderboardEntry>> callback)
{
PlayFabClientAPI.GetLeaderboard(
new GetLeaderboardRequest
{
StatisticName = leaderboardName,
StartPosition = 0,
MaxResultsCount = 100,
ProfileConstraints = new PlayerProfileViewConstraints
{
ShowDisplayName = true,
ShowAvatarUrl = true
}
},
result =>
{
var entries = result.Leaderboard.Select(entry => new LeaderboardEntry
{
PlayFabId = entry.PlayFabId,
DisplayName = entry.DisplayName,
Score = entry.StatValue,
Rank = entry.Position + 1,
AvatarUrl = entry.Profile?.AvatarUrl
}).ToList();
callback?.Invoke(entries);
},
error => Debug.LogError(error.GenerateErrorReport())
);
}
// Current player rank
public void GetPlayerRank(string leaderboardName, Action<int> callback)
{
PlayFabClientAPI.GetLeaderboardAroundPlayer(
new GetLeaderboardAroundPlayerRequest
{
StatisticName = leaderboardName,
MaxResultsCount = 1
},
result =>
{
var playerEntry = result.Leaderboard.FirstOrDefault(e => e.PlayFabId == PlayFabSettings.staticPlayer.PlayFabId);
callback?.Invoke(playerEntry?.Position + 1 ?? 0);
},
error => { }
);
}
Segmented Leaderboards
Weekly reset — PlayFab auto-resets stats per schedule. Configured in PlayFab Game Manager → Statistics → Reset interval. Weekly or Monthly.
Friends leaderboard — PlayFab Friends API:
public void GetFriendsLeaderboard(string leaderboardName, Action<List<LeaderboardEntry>> callback)
{
PlayFabClientAPI.GetFriendLeaderboard(
new GetFriendLeaderboardRequest
{
StatisticName = leaderboardName,
StartPosition = 0,
MaxResultsCount = 50
},
result => { /* handle */ },
error => { }
);
}
Level leaderboard — separate statistic per level or version-based leaderboards in PlayFab.
Anti-Cheat and Score Validation
Client score without validation is direct path to cheating via Memory Editor or Cheat Engine. Protection options:
Server-side score calc — client sends events (defeated enemy, collected item), server calculates final score. PlayFab Cloud Script:
handlers.EndLevel = function(args) {
var events = args.events; // level events
var calculatedScore = calculateScore(events); // server calc
server.UpdatePlayerStatistics({
PlayFabId: currentPlayerId,
Statistics: [{ StatisticName: "global_score", Value: calculatedScore }]
});
return { score: calculatedScore };
};
Plausibility check — max possible score for 3-minute level is 10,000, player sends 50,000—reject or flag for review.
Google Play Games and Game Center
For platform leaderboards visible in store UI:
// Google Play Games v2 (via Unity SDK)
PlayGamesPlatform.Instance.ReportScore(
score,
GPGSIds.leaderboard_global_score,
success => Debug.Log($"Score reported: {success}")
);
PlayGamesPlatform.Instance.LoadScores(
GPGSIds.leaderboard_global_score,
LeaderboardStart.TopScores,
100,
LeaderboardCollection.Public,
LeaderboardTimeSpan.AllTime,
data => { /* data.Scores */ }
);
Platform leaderboards good for discovery—player sees rating in Google Play without launching. But limited design control and no cross-platform.
UI Patterns
Good leaderboard displays:
- Player rank and score always visible (pinned top or bottom)
- Players around current (±5 positions)—GetLeaderboardAroundPlayer
- Top-3 highlighted
- Avatars (from PlayFab Profile or platform account)
Pagination or infinite scroll with GetLeaderboard(startPosition: offset) for lower ranks.
What's Included
- PlayFab Statistics setup with names and reset rules
- Submit, get top, get around player implementation
- Friends leaderboard
- Server-side score validation (Cloud Script)
- Platform integration (Google Play Games / Game Center)
- UI: list, player position, avatars, filters (global/friends/weekly)
Timeline
Global leaderboard on PlayFab: 2–4 days. Full system with segmentation, validation and UI: 1–2 weeks. Cost calculated individually.







