Розробка мобільної RPG-гри
RPG — найбільш об'ємний жанр за кількістю взаємопов'язаних систем. Інвентар, квести, діалоги, прокачка, боєва система, карта світу, save/load — і все це повинно працювати узгоджено, не створюючи суперечливих станів. Саме тут «працює на прототипі, ломається в продакшні» — найчастіша історія.
Проблема узгодженості стану
Візьмімо типовий сценарій: гравець прийняв квест «убити 10 вовків», убив 8, закрив гру, гра крашнулася при збереженні. Лічильник квесту скинувся на 0, але в історії діалогів запис про прийняття квесту залишився. При наступному запуску NPC пропонує квест знову, але з умовою «квест уже прийнято». Це класичний state inconsistency, який в RPG зустрічається повсюдно.
Рішення — Event Sourcing для ігрового прогресу. Замість того щоб зберігати поточний стан (questKillCount: 8), зберігаємо журнал подій: [QuestAccepted(questId=12), WolfKilled, WolfKilled, ...]. Поточний стан завжди відновлюється відтворенням подій. При краші втрачаються лише подіїпісля останнього успішного flush — не усе збереження цілком.
У Unity це реалізується через IGameEvent інтерфейс та EventStore з сериалізацією в локальний SQLite (через SQLite-net-pcl пакет). Flush на кожну важливу подію + фоновий flush кожні 30 секунд через Coroutine або UniTask.
Діалогова система та наратив
Зберігати діалоги в ScriptableObject зручно для 50 рядків. При 5000 рядків діалогів та розгалуженні — потрібна окремена система. Варіанти:
Ink (Inkle Studios) — відкритий язик для наративних ігор, компілюється в JSON, runtime-бібліотека для Unity (ink-unity-integration). Підтримує розгалуження, змінні стану, умови. Нарративний дизайнер пишет в Inky editor, розробник інтегрує готовий скрипт.
Yarn Spinner — альтернатива, більш Unity-native, з візуальним редактором ноді прямо в Unity Editor. Зручніше для невеликих команд, де дизайнер працює всередині Unity.
Обидва рішення підтримують локалізацію: рядки видобуваються в CSV/XLIFF, перекладач працює з таблицями, не торкаючись скрипту.
Інвентар та предмети: архітектурні рішення
Інвентар — місце, де «розумні» рішення найчастіше створюють проблеми. Типова помилка: створити BaseItem клас та успадковувати від нього Sword, Potion, QuestItem. Через 6 місяців з'являється PoisonedQuestSword та ієрархія ломається.
Правильний підхід — Composition over Inheritance через компоненти або Data-Driven дизайн. Кожен предмет — це набір компонентів-даних: DamageComponent, ConsumableComponent, QuestMarkerComponent. Система обробляє компоненти незалежно. Додати новий тип предмета — означає додати новий компонент, не торкаючись існуючого коду.
ScriptableObject як ItemDefinition (статичні дані: назва, іконка, базові стати) + runtime ItemInstance (динамічні дані: модифікатори, durability, користувацька назва). Так можна мати 500 типів предметів в пам'яті як SO-посилання та лише реальні екземпляри в інвентарі як об'єкти.
Боєва система та turn-based механіки
Для пошагової RPG: State Machine на кожного учасника боя (PlayerIdle → PlayerSelectAction → EnemyTurn → AnimatingResult → ...) через паттерн Command для боєвих дій. Кожна дія — об'єкт ICombatAction з методами Execute() та Undo(). Undo() потрібен не лише для «скасування ходу», але й для корректної роботи анімаційних переривань.
Для action-RPG: дивись архітектурні рішення з розділу складних ігор: ECS для симуляції, MonoBehaviour для презентації.
Збереження в хмарі
На iOS — CloudKit через native plugin або Game Center (iCloud saves). На Android — Google Play Saved Games (snapshots API). Обов'язково реалізувати conflict resolution: якщо гравець грав оффлайн на двох пристроях, потрібна стратегія злиття (за timestamp або за прогресом).
Вартість та графік залежать від масштабу: легка RPG з лінійним сюжетом — 6–10 місяців, відкритий світ з кількома класами, крафтом, мультиплеєром — 14–24 місяці. Перший етап — завжди проектування структури даних та схеми збережень. Переділувати це на середину розробки — дорого.
Інструменти розробки, які економлять час
- Odin Inspector — користувацькі редактори для балансування статів прямо в Unity Inspector без написання Editor-коду
- UniTask — async/await без GC allocations в Unity, критично для завантаження розділів та діалогів без фризів
- Addressables + Remote Content Delivery — патчинг контенту без оновлення додатку
- Firebase Crashlytics — символізація крешів з C++ стек-трейсами (IL2CPP)
- Unity Test Framework — PlayMode тесты для боєвої системи та save/load логіки







