Майстерня швидких MVP: Як побудувати конвеєр з розробки мобільних ігор
Всім привіт, мене звати Євгеній Ратушний, я Lead Unity Developer у студії APPSULOVE. 5 серпня я виступатиму на конференції Games Gathering Kyiv 2023 з доповіддю «Майстерня швидких MVP: Як побудувати конвеєр з розробки якісних мобільних ігор» і на базі цієї лекції підготував блог.
Що таке темплейт і які задачі він вирішує
Template (внутрішня назва проєкту) — це шаблон проєкту. Можна сказати, що фактично це навіть на 90% готовий проєкт, в якому відсутній ігролад. Та він має заздалегідь продуману архітектуру і функціонал, які включають: аналітику, споти (офери, реклама), локалізацію, магазин, налаштування, конфігурації, доставку контенту, усі необхідні SDK та ще безліч всього. А найголовніше — «гейм луп», яким регламентовано усі можливі варіанти розвитку подій з усіма можливими кейсами. І все це встановлюється і налаштовується буквально за одну годину. Хоча ми прагнемо ще більше прискорити цей процес.
Все з чого він складається є ретельно протестованим на рівні розробки, що також економить багато часу під час роботи над проєктами на його основі, оскільки тестувати потрібно лише ігролад та проєктні фічі.
Інтеграція
Наш темплейт завантажується, як сабмодуль до Git репозиторію. Під’єднується він як пекедж через маніфест і в собі вже містить сабмодуль Core, який своєю чергою приєднаний до нього також, як пекедж. І той своєю чергою містить в собі усі SDK та тулзи, які ми використовуємо. Таким чином виходить ось така «матрьошка»:
- Template:
- Core:
- Own tools:
- profiles;
- configs;
- sounds;
- UI;
- billing;
- subscriptions;
- localizations;
- resource managment;
- CI;
- etc;
- Gandalf SDK:
- campaigns;
- analytics;
- remote features;
- remote config;
- access to MiddleEarth -> Sauron, Frodo, Galadriel... (our frameworks);
- etc;
- ThirdParty SDKs:
- ApplovinMa;x
- Flurry;
- Adjust;
- Firebase;
- Facebook;
- etc;
- Other:
- Zenject;
- UniTask;
- UniRx;
- DoTween;
- a lot of editor tools;
- etc.
В середині сабмодуля темплейту ми маємо набір усіх модулів, панелей, контролерів та візуальних елементів, які будуть використовуватися в прототипі. Окрім того, там є демопроєкт, що містить повний приклад реалізації проєкту за допомогою перелічених вище дефолтних сутностей і дуже простої ігрової механіки. Усі опціональні SDK знаходяться за межами пекеджу і під’єднуються через маніфест, щоб без необхідності вони не потрапляли до білда. Усі наші сервіси, через які ми працюємо з цими SDK, мають закриті в дефайни шматки коду, що вмикаюся лише за наявності цих SDK в маніфесті.
Архітектура
Core, наш внутрішній SDK для Unity-проєктів, вже регламентує частину архітектури будь-якої гри, де він використовується. Тому ми просто екстраполювали його основу на базову архітектуру проєкту, а саме:
Скелетом для усього став Zenject. Ми використовуємо інсталери модулів: перший з них «Starter», який залишається адитивною сценою, тому існує весь час існування нашого контексту (він і виконує функцію проєктного інсталеру); також є ще два модулі — «Menu» та «Gameplay».
Все починається зі сцени «Starter». Тут ініціалізуються кор та контейнери (у нас їх тут декілька). На цій сцені також знаходяться декілька камер і канвасів — весь UI відображається саме тут. Також тут знаходиться деяка кількість системних контролерів. Загалом цей модуль типовий для Core і всіх Unity-проєктів в нашій компанії.
Далі у нас йде два модулі: «Menu» і «Gameplay». За назвою зрозуміло що в них відбувається. Кожен з них має свою сцену, на якій за замовчуванням знаходяться виключно інсталер та контролер цього модуля темплейту. За необхідності на рівні проєкту є можливість розмістити тут свої додаткові інсталери, ігроладні об’єкти тощо.
В кожному модулі є свій контролер:
- модуль завантажується доти, доки завантажуються усі необхідні панелі та візуальні елементи;
- контролер модуля описує той самий гейм луп, викликає весь необхідний UI та обробляє реакцію користувача, відправляє аналітику, викликає певні споти Гендальфа за якими можуть при необхідності показатись певні кампанії, записує в профайл певні дані.
Усі панелі, контролери, візуальні елементи зазначаються у нашій системі конфігів. Таким чином, заводячи на рівні проєкту варіанти наших префабів і вказуючи їх у наших конфігах, у розробників майбутнього проєкту на базі темплейту є можливість кастомізувати весь візуал, вказувати нащадків наших контролерів замість базових класів, при цьому доповнюючи їх певним додатковим функціоналом.
Від конкретного темплейту до абстрактного ігроладу
Для того, щоб все було реалізовано правильно, розробники повинні забіндити умовний контролер механіки. Він заінжектить собі GameplayController з API якого відбувається комунікація на рівні проєкту, а далі, якщо необхідно, потрібно підписатись на кілька реактивних проперті, таких як перезапуск рівня чи його пауза.
Контролер ігроладу повинен сповістити GameplayController після того, як гравець почав грати в цей рівень, а після того, як ігролад отримає свій результат — сповістити GameplayController про те чи програв він, чи виграв.
Таким чином реалізація ігроладної частини та контролеру модуля знаходяться в постійній комунікації між собою, реагуючи на зміни один одного.
Зменшуємо кастомізацію — пришвидшуємо розробку
Через певний час існування темплейту та після релізу декількох проєктів стало зрозуміло, що дизайн прототипів часто вимагає великої кількості кастомізацій не ігроладних частин, які подовжують розробку прототипів. Ідея темплейту полягала не в створенні універсального SDK-конструктора, а саме в створенні шаблону проєкту, який на 90% відповідає вимогам компанії та максимально пришвидшує доставку в стор ідеї з геймдизайн документу. Ці два твердження суперечать одне одному і ми вирішили зменшити можливість кастомізувати модулі темплейту (помічаючи класи salted і зменшуючи кількість віртуальних методів мінімально необхідною). Це було потрібно для того, щоб обмежити розробників у можливості кастомізувати заздалегідь спланований сценарій. Ми дозволяємо це робити виключно в необхідних бізнесу місцях.
Коли геймдизайн вимагає зробити зміну яка не передбачена темплейтом, то ми зазвичай ставимо питання — «Ця зміна може вплинути на метрики проєкту?»:
- Так — ми у наступній версії додаємо можливість кастомізувати цей момент;
- Ні — воно не потрібно в темплейті, це тільки уповільнить вихід проєкту в продакшн.
Цикл розробки, версійність, майбутнє проєкту
Наразі проєкт «Template» потроху завершує фазу активної розробки та переходить у стадію підтримки. Загалом розробка зайняла близько 9 місяців невеликою командою в середньому десь 1,5 людини. Вже випущено близько 10 проєктів на його основі, що дало змогу зекономити понад два роки розробки. Це при тому, що перші проєкти на базі темплейту почали виходити всього кілька місяців тому.
Проєкт пережив досить багато змін від перших MVP до нашого часу. Більшість з них пов’язана з обмеженням можливостей кастомізації в одному місці та додаванням такої опції в іншому, а також покращенню візуальної частини, оптимізації та уподібненню «геймлупу» стандартам компанії, які б влаштовували більшість стейкхолдерів.
Склад і терміновість випуску нової версії темплейту залежить від фіч, які замовили інші проєкти і хеди відділів, а також від того, чи прив’язана вона до оновлень Core.
Фреймворк
Core — це SDK, яке має величезний набір функцій та допомагає працювати усім нашим проєктам. Водночас це обгортка над усіма сторонніми та внутрішніми SDK. Майже весь спільний функціонал, який може бути перевикористаний на декількох проєктах одночасно має претензію на додавання в Core.
Робота над Core відбувається надзвичайно відповідально та обережно, усі нові фічі та зміни в тих, що вже існують проходять валідацію і ретельне тестування. Будь-які зміни функціонала нашого ядра можуть вплинути на працездатність наших проєктів. Це один з найважливіших і відповідальних проєктів компанії.
Core поділений на величезну кількість сервісів, кожен з яких виконує власну функцію. Взаємодіє з якимось стороннім чи внутрішнім SDK, обробляє певні дії користувача, відповідає за доставку і обробку контенту, реалізує певні абстрактні фічі, збирає і обробляє певну інформацію (профайли чи аналітика). Деякі з цих сервісів існують виключно в ітернал доступі, з деякими можна взаємодіяти на рівні проєкту, додавши їх до інжекту в будь-який клас.
Одна з функцій Core це робота з іншим нашим SDK — Gandalf. Він загальний для усіх наших проєктів. Не тільки для Unity, а і для великої кількості нативних. Саме через API Gandalf ми отримуємо доступ до інших частин нашого бекенд-фреймворку, або так званого «братства кільця». Brotherhood — сукупність бекенд сервісів (Frodo, Sauron, Galadriel, Sam тощо). Це адмінки, сховища, аналітичні та інші сервіси нашої компанії через які user acquisition отримує інформацію про дії користувачів, конфіг-менеджери можуть змінити баланс і налаштувати сегментацію, а продакти можуть проаналізувати перспективи й поточний стан проєкту.
Препродакшн
Препродакшн — така стадія де, насправді, я тільки в загальних рисах можу описати, що відбувається. В першу чергу через те, що я займаюсь розробкою на іншому фронті, але всеж таки оминути таку важливу стадію не маю можливості.
Для того, щоб конвеєр з розробки працював (розробка це не тільки робота девелоперів — насправді, це тільки верхівка айсберга), це ще і бекстейдж. Він повинен поставляти готові ідеї та розробляти контент у величезній кількості. До того як розробники створять репозиторій проєкту вже має існувати ідея, вона повинна пройти певну кількість стейкхолдерів і отримати підтримку. По цій ідеї має бути розроблений концепт, сформована ігрова механіка, створений дизайнерський документ, розрахований баланс і монетизація.
Після цього, або паралельно з цим інші команди розробляють візуальний стиль, дизайн інтерфейсів (ми маємо дефолтний інтерфейс в темплейті, який задовольняє більшість проєктів, але є виключення), графіку для ігрової механіки та анімують все, що повинно анімувати. Копірайтери та креативники мають підготувати тексти, локалізатори повинні все локалізувати. Маркетинг і UA мають побудувати план розвитку проєкту і залучення нових користувачів. Формується перелік рекламних мереж та інтеграцій, які можуть бути розміщені в проєкті.
Завдяки добре налагодженим процесам ми можемо розробляти проєкти в таких швидких темпах.
Розробка ігроладу та реліз
На етапі розробки ігрової механіки більшість роботи насправді вже зроблено, готовий весь контент: арт, анімації, текст з локалізацією, іноді вже зібрана більшість префабів (у нас цю функцію виконує окрема команда). Створені проэкти на сторах платформ з усіма необхідними ключами та зареєстрована більшість необхідних сервісів. Є повністю сформований геймдизайн документ, розписані рівні для MVP. Вже є готові креативи для закупівлі трафіку та продуманий план запуску. Деякі з цих процесів можуть відбуватися пізніше паралельно з розробкою ігрової механіки. Також не можна забувати, що більша частина гри вже сформована і відтестована.
Ось степи з яких починається розробка у девелоперів:
- створити новий репозиторій;
- клонувати його;
- під’єднати до GIT репозиторію сабмодуль;
- імпортувати демопроєкт;
- імпортувати контент;
- вказати у конфігах необхідні ключі для сторонніх сервісів;
- під’єднати Ci.
Займає все це (при умові, що розробник знає що робить) близько однієї людино-години.
Після цього починається активна стадія розробки ігроладу. Ця фаза може зайняти від декількох днів до декількох тижнів. Механіки зазвичай не складні ГК-подібні. Поки що рекорд релізу проєкту становить два тижні. Це проєкт SUSHI SORT, а також його рескін SWEET SORT, який зайняв ще тиждень. Якщо цікаво можете оцінити що з цього вийшло.
Після тестування та підтвердження всіх стейкхолдерів робиться фінальний білд з версією 1.0.0. Прямо з Cі ми можемо вказати на який енвайромент буде дивитись наш білд, чи будуть в ньому доступні дебажні функції та вказати місцем призначення стор. Проєкт проходить валідацію в сторі приблизно добу і після цього в нього потроху починають трафік.
Що відбувається якщо проєкт виявився життєздатним
Темплейт разом зі своєю зручністю і простотою приносить в проєкт деякі обмеження. На рівні проєкту часто практично неможливо (або за допомогою дуже складних милиць) змінити ті частини гри, які не належать до ігроладу або які ми спеціально зробили захищеними від змін (щоб пришвидшити розробку).
Але якщо проєкт показує гарні показники з монетизації, то ми від’єднуємо його від темплейту і це дає більше гнучкості та можливостей для реалізації продуктозалежних фіч.
Розробники складають усі необхідні ресурси та скрипти з пекеджу темплейту в теку ассетів, від’єднують від свого GIT репозиторію сабмодуль Template, приєднуючи при цьому окремо сабмодуль Core, підтримка якого необхідна в будь-якому разі.
Відбувається випуск проєкту у вільне плавання.
Що це дало бізнесу
Згідно зі статистикою, кожен десятий наш проєкт вистрілює і показує досить непогані показники, деякі з них навіть фічяряться на сторах. Втім, процес перебору комбінацій ігроладу та візуального стилю витрачав досить багато ресурсів компанії. Для порівняння, раніше стадія активної розробки займала біля трьох місяців в середньому. Зараз цей процес займає два, іноді три тижні. Це на кожному десятку проєктів (звісно, все це дуже умовно) може зекономити приблизно два с половиною роки розробки. До того ж кожен десяток проєктів (знову, дуже умовно) дає змогу знайти ту саму комбінацію, яка може вистрілити.
Загалом бізнесу це дало просто неймовірно крутий інструмент для пошуку вдалої комбінації візуального стилю та механіки. При цьому витрачаються на це мінімум ресурсів компанії.
Якщо вам цікаво більше дізнатися про досвід побудови конвеєра з розробки якісних мобільних ігор, то запрошую на конференцію Games Gathering Kyiv 2023. Лекція відбудеться в AIR HALL з 11:00 до 12:00 у суботу, 5 серпня.
2 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів