Розробка системи лідербордів мобільної гри
Лідерборди — соціальний механізм, який перетворює одиночний прогрес у змаганння. Для casual-ігр достатньо простого глобального рейтингу. Для mid-core і competitive — потрібні сегментовані лідерборди: серед друзів, по регіону, щотижневий, по конкретному рівню. Розбіжність у реалізації — принципова.
Вибір бэкенду
| Рішення | Коли підходить | Обмеження |
|---|---|---|
| Google Play Games Leaderboards | Простий глобальний рейтинг, Android | Тільки Android, обмежені типи |
| Game Center Leaderboards | iOS, простий глобальний/друзі | Тільки iOS |
| PlayFab Leaderboards | Крос-платформа, гнучко | Платний при високій нагрузці |
| Firebase Realtime DB / Firestore | Гнучко, real-time | Потрібна кастомна індексація |
| Custom backend | Повний контроль | Розробка й підтримка |
Для більшості мобільних ігор PlayFab — оптимальний вибір: не потрібно писати серверну логіку, є вбудований anti-cheat для очків.
PlayFab Leaderboards
// Запис очків
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())
);
}
// Отримання топ-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())
);
}
// Позиція поточного гравця
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 => { }
);
}
Сегментовані лідерборди
Тижневий скидання — PlayFab підтримує автоматичний скидання статистики по розписанню. Налаштовується в PlayFab Game Manager → Statistics → Reset interval. Weekly або Monthly.
Лідерборд серед друзів — PlayFab Friends API:
public void GetFriendsLeaderboard(string leaderboardName, Action<List<LeaderboardEntry>> callback)
{
PlayFabClientAPI.GetFriendLeaderboard(
new GetFriendLeaderboardRequest
{
StatisticName = leaderboardName,
StartPosition = 0,
MaxResultsCount = 50
},
result => { /* обробка */ },
error => { }
);
}
Лідерборд по рівню — окремий statistic для кожного рівня або використання версіонування статистики (Version-based leaderboards в PlayFab).
Антифрод та валідація очків
Клієнтський score без валідації — це прямий шлях до читерства через Memory Editor або Cheat Engine. Варіанти захисту:
Серверний розрахунок очків — клієнт відправляє eventi (убив ворога, зібрав предмет), сервер рахує підсумковий score. PlayFab Cloud Script:
handlers.EndLevel = function(args) {
var events = args.events; // eventi рівня
var calculatedScore = calculateScore(events); // серверний розрахунок
server.UpdatePlayerStatistics({
PlayFabId: currentPlayerId,
Statistics: [{ StatisticName: "global_score", Value: calculatedScore }]
});
return { score: calculatedScore };
};
Plauз-чек — якщо максимально можливий score за рівень довжиною 3 хвилини — 10 000, а гравець надсилає 50 000 — запис відхиляється або помічається для ревю.
Google Play Games та Game Center
Для платформенних лідербордів, які видні в інтерфейсі магазину:
// Google Play Games v2 (через 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 */ }
);
Платформенні лідерборди хороші для discovery — гравець видить рейтинг прямо в Google Play без запуску гри. Але обмежений контроль над дизайном й немає cross-platform.
UI-паттерни
Хороший лідерборд відображає:
- Позицію й очки поточного гравця завжди видні (закріплені вгору чи внизу)
- Гравці навколо поточного (±5 позицій) — GetLeaderboardAroundPlayer
- Топ-3 виділені
- Аватари (з PlayFab Profile або платформеного аккаунта)
Пагінація або бесконечний скролл з GetLeaderboard(startPosition: offset) — для доступу до нижніх строк.
Що входить у роботу
- Настройка PlayFab Statistics з потрібними іменами й правилами скидання
- Реалізація submit, get top, get around player
- Лідерборд серед друзів
- Серверна валідація очків (Cloud Script)
- Платформена інтеграція (Google Play Games / Game Center)
- UI: список, позиція гравця, аватари, фільтри (global/friends/weekly)
Терміни
Глобальний лідерборд на PlayFab: 2–4 дні. Повна система з сегментацією, серверною валідацією й UI: 1–2 тижні. Вартість розраховується індивідуально.







