Реалізація Battle Pass механики мобільної гри
Battle Pass — один з найбільш технічно об'ємних елементів монетизації. Це не просто «показати список наград» — це сезонна система з прогресією, двома треками, таймером, покупкою через IAP та синхронізацією прогресу між пристроями.
Архітектура даних
Модель Battle Pass на сервері включає мінімум три сутності:
Season — поточний сезон з датами start/end, список рівнів (50–100) з наградами для free- та premium-треку.
PlayerSeasonProgress — прогрес конкретного гравця: поточний рівень, накоплений XP, флаг isPremium, список claimedRewards.
SeasonXPTransaction — лог начислень XP: джерело (level_complete, daily_quest, mission), кількість, timestamp. Потрібен для аудиту та anti-cheat.
struct BattlePassLevel: Codable {
let level: Int
let xpRequired: Int
let freeReward: Reward?
let premiumReward: Reward?
}
struct PlayerSeasonProgress: Codable {
let seasonId: String
let currentLevel: Int
let currentXP: Int
let isPremium: Bool
let claimedRewards: [String] // "level_\(n)_free", "level_\(n)_premium"
}
Прогресія XP та балансування
Ключовое запитання: скільки XP на кожен рівень? Flat (однаково на кожен) або scaling (зростаючої стоимість)?
Flat XP простіша реалізація, але створює ситуацію, коли хардкор-гравець проходить весь Battle Pass за першу тиждень і втрачає мотивацію платити. Scaling XP утримує інтерес, але може стати занадто агресивною.
Добре роботає linear scaling з plateau: перші 20 рівнів дешево, рівні 21–80 рівномірно ростуть, 81–100 — фіксована висока стоимість для «перфекціоністів». Casual-гравець без покупки skip-levels доходить до 70–75 рівня до кінця сезону — це правильний баланс.
Таблицю XP проектуємо у spreadsheet: задаємо очікуване кількість XP за різні активності (прохождення рівня, дейли-квест, ивент) та рахуємо, скільки днів потрібно casual-гравцю для прохождення кожного рівня Battle Pass.
IAP: покупка Battle Pass
Battle Pass продається як non-consumable або auto-renewable subscription — залежить від моделі:
- Разова покупка на сезон (non-consumable) — простіша для гравця, легше реалізувати
- Підписка з авторенью — стабільний доход, але вимагає грамотного управління через StoreKit 2
На iOS з StoreKit 2:
let products = try await Product.products(for: ["battle_pass_season_1"])
guard let battlePass = products.first else { return }
let result = try await battlePass.purchase()
switch result {
case .success(let verification):
let transaction = try verification.payloadValue
await transaction.finish()
await unlockPremiumTrack(for: transaction.id)
case .pending: // очікує підтвердження (наприклад, Ask to Buy)
break
case .userCancelled:
break
}
Важливо: валідація транзакції на сервері обов'язкова для premium-контенту. Клієнт передає transactionId, сервер верифікує через App Store Server API або Google Play Developer API.
Skip Levels та Gifting
Skip levels (пропуск рівнів за твердую валюту) — додатковий джерело доходу. Обычно 1 рівень = 100–150 gems, пакет з 10 рівнів з невеликою знижкою. Технічно: consumable IAP або списання gems з кошельку з серверною верифікацією.
Подарити Battle Pass другу — фіча, яку запрашивают часто, але реалізовувают рідко. Вимагает підтримки Gift Purchase від платформи: iOS підтримує через StoreKit, Android — частково через Google Play Gifting API (у beta з 2023).
UI Battle Pass
Стандартний UI — горизонтальний скрол з рівнями, поточний рівень по центру, награди вище/нище для free/premium треків. Кнопка «Отримати» активна тільки для заробленних та не отриманих наград.
Ключові UI-стани для кожного рівня:
- Locked (ще не достигнут)
- Earned, not claimed (достигнут, награда не забрана)
- Claimed (забрана)
- Premium locked (тільки для premium, гравець не купив)
Анімація отримання награди — полноэкранна, з партикалами. Це retention-момент: гравець повинен чути задоволення від прогресу.
Сезонний таймер та закінчення сезону
Таймер зворотного відліку нагнітає urgency. Відображається у головному меню та на екрані Battle Pass. За 3 дні до кінця — push-сповіщення: «До кінця сезону 3 дні, тобі залишилось X рівнів».
По істеченню сезону: прогрес архівується, не отримані награды сгорают (с попередженням за 7 днів), запускається наступний сезон автоматично. Дані попередніх сезонів зберігаємо для історії у профілі.
Терміни та етапи
- Серверна модель даних: Season, PlayerProgress, XPLog
- API endpoints: get season, claim reward, add XP, purchase premium
- IAP інтеграція: StoreKit 2 / Google Play Billing 6
- Серверна верифікація транзакцій
- Клієнтська UI: список рівнів, отримання наград, таймер
- Push-сповіщення за 7/3/1 день до кінця сезону
- Аналітика: events для кожного earned/claimed reward
Базова реалізація (без підписки, без skip levels) — 5 днів. Повна система з підпискою, skip levels, gifting та аналітикою — 2–3 тижні.







