Я зробив гру для сина на React Native. Лікарю, у нас тут пацієнт з Expo

Ну і шо ви про все це думаєте як прочитали заголовок? Знову черговий де**л засунув JS туди, куди йому не місце? Чи може подумали про кул-сторі в стилі X, як AI за вечір створив додаток який приніс автору мільйони? Нє, все набагато прозаїчніше. Ця історія про перший досвід розробки гри очима JS full-stack девелопера: тестування, Android як платформа, з якими труднощами зіштовхнувся від ідеї до релізу, а також поради та висновки. Якщо ви в процесі запуску свого інді-проєкту — ця історія для вас.

Передмова. Можна скіпати

Я ще з дитинства мріяв створювати ігри, але як казав Танос: «Реальність часто розчаровує», тому почав я створювати не ігри, а програмувати на HTML 😅. Минали роки, в моєму житті настав такий період, коли мені не потрібно вчити новий-прикольний-модний-супер фреймворк, щоб отримувати більше $$$, бо я і фронт зроблю, і бекенд накидаю, і в базу щось там виконаю — потрібно лише працювати та обростати досвідом.

Цей період співпав з дорослішанням моєї дитини, яка почала активно грати у свої перші ігри на планшеті. Коли я подивився на ті додатки — я був дещо здивований. Ці ігри, а-ля ферма покорми коровку, максимально прості в плані механік, але при цьому якщо хочеш розблокувати всі рівні — плати. Набридла реклама — знову плати. Ба більше, на основі тих самих спрайтів та асетів студії створюють дві ато й три окремі гри схожі між собою! Я зрозумів, що я також можу створити просту гру для мого сина, яка буде враховувати те, що він любить. А бекграунд фронта класичного привила якесь мінімальне відчуття прекрасного.

Сильно поринати в щось максимально нове мені не дуже хотілось, потрібно мати баланс між новим стеком для тебе та можливістю в принципі закінчити проєкт. Тож для створення своєї першої мобільної дитячої гри я обрав React Native. З останнього мого знайомства Expo вже встиг стати мейнстрімом, пройшовши шлях від якоїсь херні для запуску Hello Error до цілої екосистеми. Тож було прийняте рішення взяти і його в обойму. Хоча відчуття, що Expo це фреймворк для запуску іншого фреймворку мені не імпонує, але це так по-фронтовому.

Ідея

Отже, у нас є React Native та Expo, але немає найголовнішого — фінальної ідеї, а будь-що починається саме з неї. За ідею я взяв мобільний дитячий телефон, де дитина натискає на кнопку та чує як «кажуть» тварини, вимовляються кольори, літери, цифри тощо.

Чому саме дитячий телефон? Це популярно та просто. В Play Market є купа таких додатків по 50k, 100k та навіть лям інсталів. Для першого проєкту, як на мене, не поганий мікс. Також я використав стилізовані фотографії свого сина для іконки додатка та всередині самої гри. Мені просто здалося, щоб було не погано зробити такого собі маскота в стилі хлопчика зі згущеного Первомайського молока (привіт з Первомайська).

Assets

Далі нам потрібні асети: картинки, звуки, музика тощо. Я точно не знав чи зможу я довести до релізу проєкт, а тому сильно вкладатися фінансово не дуже хотілося. Бо коли є проєкт та користувачі — його можна розвивати. Добре, що існують безліч сайтів з royalty-free, завдяки чому можна зліпити проєкт, а в процесі вже оновлювати. Мені в нагоді стали наступні сайти:

Але не зажди можна обійтися free asset-ами. Наприклад, маємо безкоштовну «Х», у «Й» доступ платний. У мене так було з картинками. На допомогу мені прийшов знайомий, який за символічну плату доробив бракуючі картинки.

Перші труднощі

Фреймворк — є. Ідея — є. Де взяти безкоштовні асети — також є. Що ми забули? Правильно — Design Document або Технічне завдання. Ви запитаєте: а нащо це для такої простої гри? Чому не можна вирішувати проблеми в міру їх появи? Відповідь проста — щоб не перероблювати дизайн декілька разів та не рухати щодня кнопки на пару пікселів вниз. Ви не уявляєте, яку кількість абсолютно тупих комітів я зробив, щоб просто змінити тіні або колір, бо мені сьогодні здалося, що так буде краще.

Я, наприклад, годинами підбирав картинку на фон, тестуючи декілька варіантів. Ви могли б написати: так звернись до дизайнера. Ви знаєте, якось важко ставити задачу людині, коли ти сам не розумієш як повинна виглядати гра: де розташовуватись кнопки навігації, яка кольорова гама тощо. Ось, наприклад, як виглядала гра на початку:

Мабуть, не варто було писати, що фронт привив мені відчуття прекрасного...

Через деякий час я допер, що ChatGPT зі слів та референсу досить класно генерує приклади дизайну. Тож я почав перероблювати загальний стиль гри (тільки чогось GPT весь час обрізав картинку):

Коли ти в соло створюєш щось, тебе просто рве від думок як краще зробити. І моя вам порада: якщо ти сумніваєшся — запитай, бо: «краще — ворог хорошого». В погоні за ідеальним дизайном чи фіксом всіх багів на світі можна просто вигоріти ще до релізу. Тож я запитав дружину, що вона думає про дизайн та яким він взагалі повинен бути. Художньої школи ще у дитинстві було достатньо, щоб підказати в якому напряку рухати дизайн. Зійшлися на тому, що темні кольори — не для малечі, потрібно щось яскраве, кричуще. Помучавши на цей раз вже Sora, я зібрав по шматочкам фінальний дизайн:

Далі обкатав його на моєму головному тестувальнику та натхненню — сину, я зрозумів, що це ідеальний варіант. Ви знаєте, це таке дивне відчуття, коли твоя дитина грає в гру, яку ти їй створив. Дивишся та одразу розумієш подобається їй чи ні, скільки часу проводить в грі, чи повертається знову закриваючи інші ігри. Тож порада наступна: завжди тестуйте продукт на ЦА ще до фінального релізу, коли ще все можна переграти.

React Native

Окремим пунктом хотів поговорити про обраний фреймворк. Дозволю собі переіначити назву старої дореволюційної (причому буквально) української телепередачі: «не все так добре у нашому домі».

Я чогось думав, що це буде легка подорож, а виявилось, що фреймворк не без проблем. Коли ти виходиш за рамки стандартних RN компонентів або бібліотек для UI — починаєш натикатися на нюанси. Порада: зважано підбирайте інструменти для роботи та робіть це ще на березі. Варто додати, що це мій перший повноцінний досвід роботи з React Native та Expo, можливо я щось робив не правильно, якщо так — буду чекати на вас в коментарях. Отже, поїхали:

Splash screen

Є таке поняття як splash screen — це те, що бачить користувач, коли завантажується ваш додаток. В RN встановити його дуже просто, для цього в app.json пишемо:

Формат картинки — лише png. Бо я перший раз провтикав, бахнувши webp, і тільки після команди expo prebuild, яка впала з помилкою, побачив проблему. До речі, щоб побачити як саме відображається твій скрін, потрібно зробити білд, бо в live preview ти бачиш лише заглушку від Expo. Бувало таке, що ти оновив сплеш скрін, а після білду виявилось, що виглядає не дуже — колір не той чи ще якась причина, приходиться фіксити і ребілдиться. Я не знаю як там справи з цим в Kotlin чи Flutter, але все що ти можеш зробити на RN — це просто додати картинку та встановити background color — все.

Градієнти

Тут вони працюють не так, як на фронті. Хочеш лінійні градієнти — ставиш лібу та працюєш як зі звичайними React-компонентами. Хочеш радіальні — ставиш іншу лібу, а стоп, у неї лише 3 992 weekly downloads? Ну-у-у, можна тоді закостилити через SVG. Формально вважається, що лінійних градієнтів в RN немає. Чого я виніс це в окремий пункт? Тому що у мене були на них плани, а виявилось, що в стилях їх не заюзати.

SVG

Потрібна векторна графіка — ставиш лібу. Вбудованої підтримки немає. Для гнучкої роботи (зміна fill або stroke на льоту) потрібно конвертувати SVG в React-компонент. Добре, що хоч все вже зроблено до нас, сервіс https://react-svgr.com швидко конвертує одне в інше.

Height

Немає динамічного height для картинок. Ти не можеш як у вебі бахнути height: auto і все саме підлаштується. Коли мені потрібно було кудись замостити картинку, я юзав такий костиль:

У зв’язку з цим всім я поняття не маю як той Пейсбук засунув Інсту в RN. Наприклад є ціла стаття як зробити такий самий splash screen як в Instagram, але наразі вона не актуальна — це більше не працює. Схоже, що RN там працює як обв’язка для фронта, а бек додатку на JAVA. Було ще декілька речей, які потріпали нерви, але це більше як дрібниці. Наприклад, вбудований компонент Modal в react-native виходить з immersive режиму при появі модалки. Також я не зміг оновитися на останню версію SDK (54) через те, що деприкейтнулась ліба для аудіо (expo-av), а переписувати код якось не хотілось, тож прийшлось відкотитися.

Проблема передостання: Google тебе ненавидить

Річ в тім, що я для себе не прояснив одну важливу деталь: Android — це окремий всесвіт, який працює за власними правилами які постійно змінюються. Якщо ти хочеш створювати апки на JS під Anrdoid, то тобі не достатньо просто вивчити RN. Google постійно вводить нові правила які впливають на сумісність.

Наприклад я в процесі вияснив, що тепер для великих дисплеїв (>= 600dp) не можна просто взяти та заблокувати зміну орієнтації у своєму додатку. Вияснив я це випадково коли тестив застосунок на планшеті. Я навіть на Reddit встиг сходити: How can I lock the orientation to portrait mode on Android? В пості є посилання на деталі. На телефоні з цим все ОК.

Якщо оновлення Expo SDK просто потріпало нерви, то коли я вже був готовий переходити до фінального етапу: створювати акаунт в Google Play Console, проходити верифікацію та модерацію додатка, то тут почалося справжнє жабагадюцтво, що сильно вдарило по моралі. Під кінець я вже просто ненавидів свій додаток і молився Богу, щоб нарешті все скінчилося і мій додаток прийняли.

Квест «Закрите тестування»

Суть проблеми: для нових акаунтів розробника Google вимагає, щоб ваш додаток пройшов закрите тестування перш ніж ви зможете подати його на остаточний розгляд. Тестування має відповідати наступним критеріям:

  • 12 тестувальників
  • 14 днів тестування

Звучить просто, але для соло-розробника у якого може не бути мережі друзів, знайти 12 людей, які погодяться встановити ваш додаток і не видаляти його протягом двох тижнів — може стати проблемою. Перший раз я залучив родичів та друзів, а також накрутив тестерів зі своїх лівих Google-акаунтів, бо ChatGPT сказав, що так також можна (спойлер: не можна). Типу лише потрібно натиснути кнопку «Прийняти участь». Як результат — reject без зрозумілої причини в стилі бла-бла-бла тестуйте ще. Важливо: якщо у вас реальні тестери, то потрібно, щоб вони і погоджувались на участь у тестуванні, і качали додаток з одно й того самого акаунта, бо може не зарахувати.

Мене врятував сервіс Testers Community. Я про нього вже трохи писав у своєму Linkedin. Це спеціалізована платформа яка допомагає пройти закрите тестування. Працює у двох режимах: безоплатний та платний. В безплатному об’єднує розробників, яким потрібні тестувальники, з такими самими як ви. Тобто ви «тестуєте» додатки один одного. Гарантії успішного проходження немає.

У платному тарифі ви сплачуєте 499 грн і гарантовано проходите закрите тестування. Я заплатив і протягом доби в консолі з’явилися 14+ стабільних тестувальників. Це була інвестиція в збереження мого часу та нервів. В кінці я отримав детальний фідбек. Деякі його пункти були шаблонні в стилі зробити ASO оптимізацію (App Store Optimization) чи додати Privacy Policy та Terms of Service. Були й відносно нормальні поради: додати темну тему чи підказки. Тобто додаток як мінімум відкривали. Окремим документом вони радять як заповнювати форму при подачі заявки на робочий білд. Прям буквально що писати в кожне поле, бо на цьому етапі це суперважливо.

Google Play App Information Request

Через декілька днів на пошту прийшов лист від самого Google з додатковими питаннями. Цього пункту немає в Google Console. Чомусь вони вирішили задати мені додаткові питання для продовження. Питання прості, а відповідь обов’язкова. Відповів, завантажив відео роботи застосунку — нічого складного, просто FYI, як то кажуть.

Support 16 KB page sizes

Коли я нарешті подолав 14-денний квест із тестуванням і був готовий створити робочий білд, я отримав алерт: App does not support 16 KB. Це правило набрало чинності 1 листопада, а публікувався я 12 листопада. «Любила жаба гадюку, а та тихенько сичала», — подумав я. Що це взагалі таке? Це технічна вимога введена Google для покращення продуктивності, якщо коротко.

Мій стек виглядав так: React Native 0.76.9, Expo 52. Єдиний спосіб пофіксити проблему — це оновлення до 0.77 та 53 відповідно. Хоча наче як можна залишитися на 52 версії Експо, навіть стаття є: React Native 0.77 is now available with Expo SDK 52. Чи ні? Бо npx expo-doctor одразу поскаржився на несумісність версій плюс я отримав помилку при запуску проєкту: EarlyJsError: Property 'setImmediate' doesen't exist. Я вже не став в’їзджати чому так, а не інакше. До речі, для фікса помилки навіть окремий костиль є в npm. Тобто те, що мало бути фінальним завантаженням, перетворилося на ще один повноцінний апгрейд стека. Мені пощастило — я оновився за вечір без проблем.

Проблема остання: твій проєкт нікому не всрався

Можливо я колись напишу продовження статті, де розповім як я вклав N доларів та отримав M річних, перетворивши проєкт в стартап і якогось біса переїхавши в Кремнієву долину, але наразі реальність така — без реклами чи сарафанного радіо зайняти свою нішу задача близька до нереальної.

Висновки

Будь-який проєкт повинен нести якісь висновки і у мене їх декілька:

  • Потрібно завжди рости над собою — пробувати щось нове, щось створювати, мати мету та просто рухатись вперед, бо під лежачий камінь вода не тече. Можна зробити N невдалих проєктів, але на N+1 щось та обов’язково вийде. Подібні проєкти — це рух вперед, не кажучи вже про досвід. Можна навіть в Linkedin в розділ «Досвід» бахнути startap owner і затирати про успішний успіх і вчити жити інших;
  • Потрібно чітко продумувати проєкт ще до старту, мати повне його бачення та ТЗ, щоб не вигадувати чи перероблювати на ходу;
  • Потрібно планувати маркетингову стратегію заздалегідь. Мати уяву як ти будеш просувати свій продукт. Бажано мати декілька ідей на цей рахунок. Це найважливий урок який я виніс. Готовий продукт — це 50% роботи, це як в тому фільмі: «Головна подія у вашому житті у вас попереду». Тобто, грубо кажучи, після релізу робота лише починається, але вже у іншій площині.

Дякую, я кінчив. Особисто я зроблю невеличку паузу від Baby Phone, а то щось він мене вимотав, та згодом продовжу реалізовувати заплановані ідеї по проєкту. Наразі мені в око потрапив Unity, тож я вже знаю чим буду займатися в наступному році. А собі та вам я бажаю поставити ціль та рухатись до неї, бо коли я розробляв проєкт, бляха, як же мене гріла лише сама думка, що з цього може вийти щось круте.

👉 Baby Phone в Play Market 👈

Проєкт в цифрах:

  • Перший коміт: 16 грудня 2024 року;
  • Реліз: 15 листопада 2025 року;
  • Кількість комітів: 101 (як правило один на день);
  • Ціна розробки: 2499 грн;
    • 2000 грн за картинки для гри та превью;
    • 499 грн для Testers Community.

Інші посилання варті вашої уваги:

Підписуйтеся на Telegram-канал @gamedev_dou, щоб не пропустити найважливіші статті і новини

👍ПодобаєтьсяСподобалось18
До обраногоВ обраному7
LinkedIn


Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Познаходив у статті пасхалки. Скільки їх всього?

Чесно — не рахував. Просто додавав якщо підходило по сенсу)

дяжу дякую за стаью!
Я довольно опытный, 24 года в Айти, сделали с командой 1000+ проектов, але все равно почерпнул полезного.
До речи, сколько лет вашему сыну? мы делаем проект для детей, самый революционный что можно придумать. Я бы записал его в альфа тестеры (закрытый рели в марте±)
п.с. выбачьте что суржиком, я с Киева но постепенно перехожу на укр мову

Дякую за фідбек! Наразі йому 4, а коли я починав було ще 3

Підписатись на коментарі