Система достижений мобильной игры: архитектура, синхронизация, retention
Мы сталкивались с ситуацией, когда система достижений была «слеплена на коленке»: прогресс хранился локально, после переустановки игры достижения пропадали, а игроки писали негативные отзывы. Правильно спроектированная система достижений — это не просто список «убей 100 врагов». Она управляет retention: игрок возвращается, потому что хочет закрыть ачивку, которая требует 7 дней подряд входить в игру или убить конкретного босса. Достижения дают долгосрочные цели пользователям, прошедшим основной контент. По нашим данным, внедрение продуманной системы Streak-достижений повышает дневную активность на 20–30%. Наша команда имеет 5+ лет опыта в разработке мобильных игр и реализовала более 30 систем достижений для игр разных жанров.
Почему достижения важны для retention?
Достижения создают микроцели, которые превращают короткие сессии в привычку. Например, ачивка «Входи в игру 7 дней подряд» мотивирует игрока возвращаться ежедневно. Без таких механик игрок быстро теряет интерес после прохождения основного сюжета. Исследования показывают, что игры с системами достижений имеют на 40% более высокий 30-дневный retention (по данным GameAnalytics report).
Какие типы достижений мы используем?
| Тип | Описание | Пример | Влияние на retention |
|---|---|---|---|
| OneTime | Однократное выполнение | Убить первого босса | Низкое |
| Counter | Прогрессивное накопление | Убить 100 врагов | Среднее |
| Streak | Серия подряд | Входить 7 дней подряд | Высокое |
| Cumulative | Накопительное за всё время | Набрать 10000 очков | Среднее |
Streak-достижения особенно эффективны — они формируют привычку ежедневного захода. Для их реализации требуется аккуратная обработка временных зон с использованием UTC.
Архитектура: локальная vs серверная
Для большинства мобильных игр архитектура выглядит так:
| Компонент | Рекомендация | Причина |
|---|---|---|
| Прогресс достижений | Клиент + серверная синхронизация (Google Play Games / Game Center / PlayFab) | Защита от потери данных, античит |
| Выдача наград | Только сервер (или Platform SDK с верификацией) | Предотвращение взлома |
| Отображение | Клиент | Минимальная задержка для пользователя |
Хранить прогресс только локально рискованно: переустановка = потеря ачивок = негативный опыт. PlayFab Player Data или Google Play Games Snapshots решают это. Серверная синхронизация лучше локального хранения в 3–5 раз по надёжности и retention.
Модель данных
[Serializable] public class Achievement { public string id; public string titleKey; // локализация public string descriptionKey; public AchievementType type; // Counter, OneTime, Streak public int targetValue; public List<Reward> rewards; public bool isSecret; // скрытые до выполнения public string[] requiredAchievements; // цепочки зависимостей } public enum AchievementType { OneTime, // выполнено или нет Counter, // прогресс 0..targetValue Streak, // N дней подряд Cumulative // накопительно за всё время } [Serializable] public class AchievementProgress { public string achievementId; public int currentValue; public bool isUnlocked; public DateTime? unlockedAt; public bool rewardClaimed; } AchievementsManager
public class AchievementsManager : MonoBehaviour { public static AchievementsManager Instance { get; private set; } private Dictionary<string, AchievementProgress> _progress; private AchievementDatabase _database; // Вызывается из игровой логики public void TrackEvent(string eventType, int value = 1, Dictionary<string, object> context = null) { foreach (var achievement in _database.GetAchievementsByEvent(eventType)) { var progress = GetOrCreate(achievement.id); if (progress.isUnlocked) continue; switch (achievement.type) { case AchievementType.Counter: case AchievementType.Cumulative: progress.currentValue += value; break; case AchievementType.OneTime: progress.currentValue = 1; break; } if (progress.currentValue >= achievement.targetValue) Unlock(achievement, progress); } SaveProgress(); } private void Unlock(Achievement achievement, AchievementProgress progress) { progress.isUnlocked = true; progress.unlockedAt = DateTime.UtcNow; // Уведомление игрока AchievementPopupUI.Instance.Show(achievement); // Аналитика GameAnalytics.NewDesignEvent($"Achievement:Unlocked:{achievement.id}"); // Синхронизация с платформой SyncWithPlatform(achievement); } } Метод TrackEvent — единственная точка входа из геймплея. Это значит, что добавление нового достижения не требует изменений в боевой логике, системе квестов или магазине — только новая запись в AchievementDatabase.
Как проектировать Streak-достижения?
Серия входов подряд — один из лучших retention-инструментов. Требует аккуратной обработки дат:
public void RecordDailyLogin() { var lastLogin = PlayerPrefs.GetString("last_login_date", ""); var today = DateTime.UtcNow.Date.ToString("yyyy-MM-dd"); var yesterday = DateTime.UtcNow.Date.AddDays(-1).ToString("yyyy-MM-dd"); if (lastLogin == today) return; // уже засчитано сегодня int streak = PlayerPrefs.GetInt("login_streak", 0); streak = (lastLogin == yesterday) ? streak + 1 : 1; // сброс если пропустил день PlayerPrefs.SetString("last_login_date", today); PlayerPrefs.SetInt("login_streak", streak); TrackEvent("daily_login_streak", streak); } Важно использовать UTC, а не локальное время — иначе игрок в UTC+12 может получить двойной бонус при смене дня.
Система наград и их баланс
Каждое достижение может выдавать один или несколько типов наград: внутриигровая валюта, предметы, косметика, скины. Важно настроить баланс — награда должна быть ценной, но не нарушать экономику игры. Мы используем серверную верификацию, чтобы предотвратить повторное получение наград через взлом клиента. Свяжитесь с нами для консультации по вашему проекту.
Интеграция с платформенными достижениями
Google Play Games и Game Center имеют собственные ачивки, которые видны в платформенном интерфейсе:
// Google Play Games (Play Games Services v2) PlayGamesPlatform.Instance.UnlockAchievement("CgkI6ISmlocOEAIQAQ"); // Game Center (iOS) GKAchievement achievement = new GKAchievement("first_boss_killed"); achievement.percentComplete = 100; GKAchievement.Report(new[] { achievement }, (error) => { }); Синхронизируем только те достижения, которые имеют смысл на платформе. Не нужно дублировать все 100 внутриигровых ачивок в Game Center — только ключевые milestone.
Процесс работы
- Аналитика и прототипирование — определяем цели (retention, монетизация), выбираем типы достижений.
- Проектирование базы данных — создаём модель
Achievement, настраиваем связи и зависимости. - Реализация ядра —
AchievementsManager,TrackEvent, сохранение прогресса. - Интеграция с платформами — подключаем Google Play Games, Game Center, настраиваем синхронизацию.
- UI и визуализация — список достижений, прогресс-бары, popup при разблокировке.
- Система наград — выдача валюты, предметов, косметики с серверной верификацией.
- Аналитика и балансировка — настраиваем события, тестируем сложность, корректируем.
- Деплой и мониторинг — интеграция с App Store Connect и Google Play Console.
Что входит в работу
- Проектирование схемы достижений и системы событий
- Реализация
AchievementsManagerс типами Counter/OneTime/Streak - Синхронизация прогресса с PlayFab / Google Play Games / Game Center
- UI: список достижений, прогресс-бары, popup при разблокировке
- Система наград: валюта, предметы, косметика
- Аналитика разблокировок для балансировки сложности
- Локализация заголовков и описаний
Сроки
Базовая система без платформенной интеграции: 4–6 дней. Полная система с синхронизацией, UI и наградами: 1,5–2,5 недели. Закажите проектирование системы достижений под вашу игру — мы подберём оптимальную архитектуру с учётом жанра и целевой аудитории. Получите консультацию по интеграции с платформами.







