Разработка Android-игры с Claude Code: idle-кликер от ТЗ до релиза в Google Play за месяц
Проект «Дерден»: хакерский кликер по мотивам «Бойцовского клуба», собранный без единой написанной вручную строчки кода
Одна сессия в Claude Design, одна — в Claude Code, 161 промпт, 66 коммитов, APK на 4 Мбайта. Разбор того, как теперь делаются мобильные игры, и расчёт экономики кликера так, чтобы она не развалилась на второй день.
Первое правило бойцовского клуба известно всем. Первое правило вайб-кодинга скромнее: нейросеть не сделает игру за разработчика. Она сделает игру вместе с ним — и это, как выяснилось, совсем другая работа.
С 30 мая по 24 июня был собран и выложен в Google Play idle-кликер HACK CLUB: восемь сюжетных глав, 29 модулей прокачки, пять валют, рейды, престиж, Battle Pass, 19 языков локализации, AdMob и Google Play Billing. Руками за это время не написано ни одной строчки Kotlin. Зато агенту ушло 194 сообщения, из которых 161 — содержательные промпты (остальное — «го», «продолжи» и «запуши»). Вот эти сто шестьдесят промптов и были настоящей разработкой.
Проект прошёл через две большие сессии. Первая — в Claude Design (claude.ai/design): из текстового ТЗ родился дизайн-кит на 18 экранов, диздок и таблица баланса на 152 предмета. Вторая — в Claude Code в терминале: дизайн превратился в приложение, приложение — в релиз. Логи второй сессии занимают на диске 120 Мбайт JSONL — почти шесть тысяч ответов агента. Дальше обе сессии разобраны по костям, а заодно — как считать экономику кликера, где в ней прячутся эксплойты и как всё это монетизировать.
Идея: должник, который взламывает банк
Жанр idle-кликера выбран холодным расчётом: это самый дешёвый в производстве жанр с готовой психологической петлёй («цифры растут — мозгу приятно»), и он идеально ложится на офлайн-игру без сервера. Но голый кликер про печеньки в 2026 году никому не нужен — нужен сюжет.
Сюжет нагло позаимствован у Паланика. Герой — хакер, утонувший в долге $48 200. Первый тап в игре — взлом собственного банка. Дальше подпольная сеть HACK CLUB, наставник GHOST, который зовёт героя в тайную ячейку — Проект «Дерден» (привет, Тайлер). В шестой главе — твист: GHOST оказывается ORACLE, искусственным интеллектом, которого игрок сам пробудил в главе 2. А финал экранизации — обрушение зданий кредитных компаний, обнуляющее долги человечества, — здесь превращается в… механику престижа. Revolution Reset: сбрасываешь весь прогресс, стираешь долговые базы и начинаешь заново с перманентным множителем. (У Паланика, кстати, подрыв срывается — рассказчик сам его саботирует; эффектный обвал башен придумал Финчер.) Сюжет и кор-механика жанра совпали настолько точно, что до сих пор удивительно, почему так никто не сделал раньше.
Трюк, который стоит запомнить: в кликере сброс прогресса — самая ненавистная игроку механика. Если сюжет объясняет сброс (революция циклична, каждая итерация проходит быстрее), игрок перестаёт воспринимать его как наказание.
Сессия первая: ТЗ → дизайн
В Claude Design проект пришёл с текстовым ТЗ на пару абзацев: киберпанк-кликер про хакеров, оммаж «Бойцовскому клубу», полностью офлайн, без аккаунтов и лидербордов, вёрстка под Pixel 3a (393×808 dp), вся графика векторная или процедурная — никаких ассетов из стоков.
Дальше классическая итерация с дизайнером, только дизайнер не спит и не обижается. Сервис предложил визуальные направления, из них был выбран вариант «Holo»: спокойный тёмный фон, зелёный неон как основной цвет, янтарь для премиума, красный для опасности. Из этого выросла дизайн-система (tokens.css, общие компоненты) и 18 экранов: главный HACK-экран, магазин, карта мира, крю, события, Battle Pass, сюжет, престиж, подписки, онбординг, инвентарь, настройки и так далее.
Экраны из UI-кита: главный экран в трёх концепциях (Holo, HUD, Terminal), магазин, карта мира и рейд
Но самое ценное в той сессии — не пиксели. Claude Design сгенерировал два документа, которые потом кормили всю разработку.
Первый — Story Bible (gdd.jsx). Диздок, в котором сюжет связан с системами: каждая из восьми глав вводит ровно одну механику, одну валюту, одно событие и новых персонажей. Глава 2 «Даркнет» открывает крипту и кейсы — и в ней же игрок пробуждает ORACLE. Глава 4 «Сопротивление» открывает крю и миссии — и в ней GHOST раскрывает Проект «Дерден». Прогресс игрока и развитие сюжета — одна кривая. Это не украшательство: когда через три недели агент в другой сессии запутался в именах событий, именно этот документ стал арбитром.
Story Bible — единая канва: каждая глава сюжета вводит одну механику, одну валюту и одно событие
Второй — таблица баланса (balance.jsx) на 152 предмета. Причём сгенерирована она не списком, а процедурно — кривыми:
const BCATS = [
{ id: 'hw', name: 'Железо', n: 28, incBase: 50, incG: 1.62, costBase: 200, costG: 1.92 },
{ id: 'sw', name: 'Софт', n: 28, incBase: 35, incG: 1.66, costBase: 140, costG: 1.96 },
{ id: 'srv', name: 'Серверы', n: 26, incBase: 220, incG: 1.70, costBase: 900, costG: 2.00 },
// ... дроны, ИИ-модули, защита
];
Здесь важно не перепутать оси. incG и costG описывают, как растут доход и цена от предмета к предмету внутри категории: двадцать восьмое «железо» и мощнее, и дороже первого на несколько порядков. Цена при этом растёт быстрее дохода (costG > incG) — поэтому поздние предметы окупаются дольше и игрок не может «купить всё». Отдельная от этого история — как растут доход и цена при прокачке одного предмета; к ней вернёмся в разделе про экономику, там формулы совсем другие. Если раньше балансировать кликер не приходилось: вот это соотношение двух показателей степени и есть половина всего геймдизайна жанра.
Балансная таблица: 152 предмета в шести категориях — не выдуманы поштучно, а посчитаны кривыми
Кроме экранов и диздока, сессия выдала вещи, которые обычно заказывают отдельным подрядчикам. Звуковой манифест — JSON с шинами микшера (music/ambient/sfx/ui, у каждой свой gain), десятью музыкальными темами по главам с описанием настроения («глава 5, рейды — dark aggressive electronic») и семнадцатью SFX с триггерами и примечаниями вида «питч +2…+5 по комбо». Самих файлов там нет — только спецификация и ссылки на CC0-паки Kenney и Pixabay, откуда их брать. Интерактивный прототип — кликабельная HTML-версия игры, по которой можно пройтись пальцем до всякого кода. И манифест шрифтов: Russo One для дисплейных заголовков, Exo 2 для UI, JetBrains Mono для цифр и терминала — все под открытой лицензией OFL.
В конце дизайн-сессия выгружает handoff-бандл: README с инструкцией для кодящего агента («сначала прочитай транскрипты чатов — интент там, а не в HTML»), сами чаты и папку project с JSX-прототипами. Ключевая мысль из README, которую стоит повесить на стену: прототипы — это спецификация, а не код. Агент должен воспроизвести картинку, а не портировать реактовский исходник в Android.
Дизайн-сессия отработала и скучные UX-состояния: замки, «нет валюты», офлайн-доход, пустые списки. Именно на них обычно спотыкается вайб-кодинг
Важный нюанс: дизайн-сессия не умерла после хендоффа. Поток шёл в обе стороны — в неё загружались готовые strings.xml из кодового проекта (для локализации маркетинговых страниц) и скриншоты с реального устройства, а она отдавала обновления дизайна, которые кодовая сессия забирала по ссылке и диффала против локальной копии. Дизайн и код существовали как два репозитория с синхронизацией, а не как «нарисовали и забыли».
Чем ещё рисовать по промпту
Claude Design — не единственный способ получить дизайн из текста. Короткий обзор инструментов той же породы, чтобы было с чем сравнивать:
Pencil.dev — самый интересный вариант для тех, кто пишет код: это бесконечный дизайн-канвас, которым управляет ИИ-агент через MCP. Дизайн хранится файлами прямо в репозитории рядом с кодом, а Claude Code подключается к канвасу как к инструменту — тот же агент, что пишет Kotlin, рисует и правит макеты, не выходя из сессии. Умеет импорт из Figma копипастой и вектор руками. На момент написания — бесплатен в early access, чем грех не пользоваться.
Google Stitch (переваренный Google’ом стартап Galileo AI) — генерирует экраны мобильных и веб-приложений по текстовому описанию на моторе Gemini, отдаёт экспорт в Figma и HTML/CSS. Бесплатных генераций в месяц хватает на «пощупать». Хорош для быстрых концептов отдельных экранов; целостную дизайн-систему на 18 экранов из него придётся вытягивать клещами.
v0 от Vercel — промпт превращается в React-компоненты на Tailwind и shadcn/ui, качество вёрстки — одно из лучших на рынке. Но он всей душой про веб: для Android-проекта его выдача — референс, а не хендофф.
Figma Make — prompt-to-prototype внутри самой Figma, умеет наследовать существующую дизайн-систему и встраиваться в привычный для дизайнеров процесс. Логичный выбор, если в команде уже есть Figma-workflow и платные места; соло-разработчику ради него заводить подписку смысла мало.
Figma + MCP — отдельный сюжет для тех, у кого дизайн уже лежит в Figma и нужно скормить его кодовому агенту. MCP-сервер Figma отдаёт агенту структуру фреймов, стили и токены прямо из макета — но лимиты у этого канала скромные и по числу запросов, и по объёму: большой экран в JSON-представлении сжирает контекст на глазах, а на бесплатном тарифе потолок наступает за пару итераций. Рабочий обходной манёвр — не таскать графику через MCP вообще: REST API Figma на запрос GET /v1/images/{file_key}?ids=… возвращает не байты, а ссылки на CDN (S3-хранилище Figma), и дальше все ассеты выкачиваются обычным curl пачкой, не тратя ни лимиты MCP, ни токены контекста. Агенту достаточно дать file key и персональный токен — скрипт выгрузки он напишет сам, а MCP остаётся для того, в чём он незаменим: структура, размеры, цвета.
Lovable и Bolt.new — это уже prompt-to-app: генерируют работающее приложение целиком (фронт, роутинг, местами бэкенд), дизайн получается как побочный продукт. Годятся, чтобы за вечер проверить продуктовую гипотезу веб-версией; в пайплайн «дизайн → нативный код» встраиваются плохо — они хотят делать всё сами.
Uizard — ветеран жанра: текст или даже скриншот/фото салфеточного скетча превращает в редактируемый макет. Выдача попроще и пошаблоннее, чем у перечисленных, зато порог входа нулевой — черновик экрана быстрее сделать негде.
Критерий выбора после этого проекта простой: смотреть надо не на красоту генераций, а на формат хендоффа. От дизайн-инструмента здесь нужны были не картинки, а бандл со спецификациями, чатами-транскриптами и GDD, который кодовый агент прочитает и поймёт. Красивый мокап без передаваемого контекста — это открытка, а не дизайн.
Сессия вторая: дизайн → код
Кодовая «сессия» — формально три файла логов (контекстное окно не бесконечно, агент дважды продолжал работу через авторезюме), но фактически один непрерывный проект с 30 мая по 24 июня. Немного статистики из JSONL:
| Метрика | Значение |
|---|---|
| Ответов агента | ~5800 |
| Сообщений человека | 194 (содержательных промптов — 161) |
| Вызовов Edit | 758 |
| Вызовов Bash | 1146 |
| Чтений файлов | 625 |
| Коммитов в git | 66 |
| Итоговая версия | 1.0.15 |
Первый промпт сессии стоит процитировать целиком, потому что он задал всю архитектуру: «Делаем андроид кликер, архитектура сингл активити и вью, адмоб, инапы. Вот тут дизайн попозже дам, пока этот проект причеши». Всё. Дальше в топе реплик — «го» (восемнадцать раз), «продолжи» (восемь) и «запуши». Расшифровка для тех, кто ещё не пробовал: агент заканчивает кусок работы и останавливается с планом следующего шага, а человек либо корректирует, либо говорит «го». Код пишет не он — он принимает работу.
Battle Pass, крю, главы сюжета и диалоги — всё это кодовая сессия воспроизводила по HTML-прототипам, не видя ни одного PNG
Архитектура: война за мегабайты
Требование к архитектуре было одно, зато жёсткое: минимальный размер APK. Это не перфекционизм, а конверсия: гиперказуальную игру ставят импульсивно, и каждый лишний мегабайт между кнопкой «Установить» и первым тапом — это отвалившиеся игроки. Google в исследовании «Shrinking APKs, growing installs» приводил зависимость «−1% установочной конверсии за каждые ~6 Мбайт», а на развивающихся рынках — для кликера это ядро аудитории — эффект вдвое сильнее: минус 10 Мбайт там коррелируют с ростом конверсии примерно на 2,5%. Из этого требования вытекло всё остальное.
View вместо Compose. Не из ретроградства. View-стек лежит в самой операционке и стоит приложению ноль байт; Compose — это библиотека внутри APK: компилятор, рантайм и вагончик зависимостей, которые даже после R8 оставляют в dex лишние мегабайты и удлиняют холодный старт. Главный козырь Compose — скорость написания UI — в этой схеме обесценен: UI пишет агент, ему без разницы, во что верстать. Остаётся честный размен: платить мегабайтами за декларативность, которой никто не пользуется? Нет, спасибо.
Single activity. Одна активити в манифесте, экраны — фрагменты, навигация — самописный Navigator в MainActivity (открытие вкладок, бэкстек, скрытие нижнего меню) на сотню строк. Jetpack Navigation с его graph’ами и SafeArgs не подключён вовсе: для игры с пятью вкладками это стрельба библиотекой по воробьям. Состояние игры — один синглтон GameState, который переживает любые повороты и пересоздания фрагментов, потому что не привязан к их жизненному циклу.
Диета на зависимостях. Полный блок dependencies умещается в шесть строк: базовый androidx, корутины, реклама с UMP, биллинг и Tracer. Ни Room — сейв это SharedPreferences с версией схемы; ни Glide/Coil — грузить нечего; ни Retrofit — сети в игре нет вообще; ни Lottie — анимации рисуются руками. Каждая невзятая библиотека — это минус dex, минус методы, минус транзитивные сюрпризы в ProGuard-правилах.
Процедурная графика. В проекте нет ни одного PNG с артом. Вся вёрстка собирается программно через хелперы Widgets.kt (panel(), neonButton(), currencyBar(), meter() — дизайн-система из Claude Design, переписанная в Kotlin-функции), а всё «художественное» — карта с гексами, портреты двенадцати персонажей, сцены восьми глав, эквалайзер — кастомные вьюхи, рисующие на Canvas по детерминированному сиду. Портрет хакера в капюшоне занимает не 200 Кбайт текстуры, а полкилобайта кода, и при этом резиновый под любую плотность экрана. Иконки — VectorDrawable, шрифты — три TTF на 556 Кбайт.
Итог после R8 с minify + shrinkResources: весь код, вся графика и строки на 19 языках — около 4 Мбайт. А потом к ним добавляются ещё 34 Мбайт ресурсов, и это… музыка. Итого сборка тянет примерно 38 Мбайт, где почти девять десятых — саундтрек. И вот тут начинается отдельная история.
Музыка: 90 % веса приложения
Саундтрек — 15 фоновых треков Kevin MacLeod (incompetech.com) под CC BY 4.0: бесплатно при указании авторства, атрибуция лежит в MUSIC_CREDITS.md и в настройках игры. Дизайн-сессия, кстати, предлагала в звуковом манифесте паки Pixabay и Kenney под CC0 — там атрибуция не нужна вовсе; выбор по вкусу, но лицензию файла надо проверять до релиза, а не после письма правообладателя.
Раз уж зашла речь — шпаргалка по бесплатному звуку для коммерческой игры:
| Источник | Лицензия | Что брать |
|---|---|---|
| incompetech.com (Kevin MacLeod) | CC BY 4.0 — обязательна атрибуция | сотни готовых треков по жанрам, выбор этого проекта |
| pixabay.com/music и /sound-effects | своя, коммерция ОК, без атрибуции | музыка и SFX, самый простой вариант |
| kenney.nl | CC0 | геймдев-паки UI/sci-fi звуков, идеально для SFX |
| freesound.org | разные! фильтровать по CC0 | полевые записи, эмбиенты, шумы серверной |
| opengameart.org | CC0/CC-BY вперемешку | музыка и SFX, лицензию смотреть на каждом ассете |
С нейрогенерацией «бесплатно» надо быть внимательнее, там мина под каждым тарифом. У Suno и Udio бесплатные планы дают только некоммерческое использование — трек из фри-тарифа в игре с рекламой это нарушение условий; коммерческие права начинаются с платной подписки. Для честной бесплатной генерации остаются локальные открытые модели: Stable Audio Open крутится на своей видеокарте, и её Community License разрешает коммерческое использование, пока годовая выручка меньше миллиона долларов (инди-кликеру хватит с запасом). А вот MusicGen от Meta — обманка для невнимательных: код открыт, но веса опубликованы под CC-BY-NC, только некоммерческое. Читать надо лицензию весов, а не название репозитория.
Для SFX генерация ещё доступнее: классические генераторы ретро-эффектов Bfxr, jsfxr и ChipTone бесплатны, работают в браузере, права на результат остаются у автора; «пиу» для тапа и «дзынь» для награды делаются за минуту. В этом проекте вариант ещё аскетичнее: все четыре эффекта (тап, покупка, награда, ошибка) синтезированы ffmpeg-осцилляторами, весят килобайты и играются через SoundPool — ни одного стороннего файла.
Первое, что нужно сделать с любой фоновой музыкой в мобильной игре, — пережать. Стерео и 320 kbps в кармане у казуального игрока не слышит никто: ffmpeg -ac 1 -b:a 96k — моно, 96 kbps, и первые пять треков ужались с 33 до 11 Мбайт без слышимой на телефонном динамике разницы. Плеер — свой Music.kt на голом MediaPlayer: плейлист по кругу, пауза в onPause, громкость слайдером из настроек, реальные длительности через MediaMetadataRetriever. ExoPlayer/Media3 для проигрывания mp3 по кругу — снова мегабайты зависимостей ради ничего.
А теперь ложка дёгтя, которая появилась сама собой: по ходу разработки «добавь ещё треков» превратило 5 композиций в 15, и даже пережатые они весят 34 Мбайт — девять десятых приложения. Игра весит как саундтрек, к которому приложили игру. Лечится это не удалением музыки, а следующим разделом.
Доставка контента: пусть ассеты лежат у Google
Тяжёлые ресурсы не обязаны сидеть в APK — их можно докачивать с серверов Google после установки. Механизм называется Play Asset Delivery (PAD), работает поверх AAB и не требует своего CDN, аккаунтов и вообще какого-либо бэкенда: паки ассетов хранит и раздаёт сам Play, бесплатно. Три режима доставки:
- install-time — пак ставится вместе с приложением (размер скачивания не экономит, но обходит лимиты размера и делит бандл логически);
- fast-follow — приложение ставится маленьким и запускается сразу, пак докачивается фоном следом;
- on-demand — качается в рантайме по явному запросу через
AssetPackManager.
Для музыки кликера идеальна связка: базовый APK на 4–5 Мбайт с одним стартовым треком, остальной саундтрек — fast-follow (игрок уже тапает, пока музыка доезжает), а можно и хитрее — on-demand по главам: в дизайн-манифесте треки и так привязаны к главам, тема «Войны долгов» не нужна игроку, который час как в «Подвале». Технически переезд несложный: треки перекладываются из res/raw в отдельный Gradle-модуль ассет-пака (assetPackName + deliveryType в его build-файле), а MediaPlayer вместо R.raw.* получает AssetFileDescriptor от AssetPackManager. Лимиты там гигабайтные — для 34 Мбайт музыки запас на порядки.
Для докачки кода (не ассетов) есть соседний механизм — Play Feature Delivery с dynamic feature modules, но для медиа он избыточен: PAD проще и создан ровно под это.
Честная оговорка: в релиз игра вышла ещё с музыкой внутри APK — PAD висит первым пунктом в RELEASE_CHECKLIST.md на следующую версию. Но порядок действий стоит повторить: сначала du -sh по ресурсам и понимание, что именно весит (здесь — 34 из 38 Мбайт музыка), и только потом выбор механизма. Выносить в PAD векторные иконки на 200 Кбайт — работа ради работы.
И последнее архитектурное решение — не про код, а про процесс, но рекомендовать его можно любому, кто затевает длинный проект с ИИ-агентом: канонические документы в репозитории. Их три: STORY.md (сюжет, персонажи, связи, граф твиста), BALANCE.md (все формулы и таблицы баланса) и GOOGLE_PLAY_PRODUCTS.md (товары, цены, чек-лист консоли). Контекст сессии конечен, память агента между сессиями дырява, а документ в git — нет. Когда в интерфейсе всплыл ивент Corporate War, «которого после унификации не существует», разборка шла именно против STORY.md — и выяснилось, что документ прав, а код врёт.
Субагенты: переводчик и плейтестер
Два приёма из этой сессии экономят больше всего денег и времени.
Первый — делегирование дешёвой модели. Локализация 614 строковых ключей на 18 языков (плюс английский источник — итого 19 локалей) — работа объёмная, но тупая. Её делали субагенты на Sonnet: главный агент готовил английский источник и глоссарий брендов (Credits, Crypto, Black Tokens, названия событий не переводятся), субагенты писали переводы, главный сливал и проверял. Промпт звучал буквально так: «что можно отдать на более простую модель — то отдай».
Второй приём — агент-плейтестер. В какой-то момент возник вопрос: «можешь сделать простого субагента, который будет играть в игру на эмуляторе и давать фидбэк?» Через полчаса появился отдельный агент с описанием роли: запускает сборку на эмуляторе, тапает, ходит по вкладкам, покупает модули, смотрит рекламу, скриншотит и пишет структурированный отчёт по багам и UX. Его отчёты превратились в реальные коммиты: диалог выхода по Back вместо тихого закрытия, разные иконки на карточках миссий, дизейбл кнопки CLAIM после получения награды. А самое крупное его последствие — из игры вообще выпилили тосты: все события пишутся в игровой журнал, награды показываются диалогом с деталями «было 100 → стало 200». Системный Toast в неоновом киберпанке смотрелся как ценник из «Пятёрочки» на смокинге.
Плагины и MCP под мобильный конвейер
Плейтестер и работа с Play Console собирались руками, но к середине 2026-го почти всё это уже есть готовыми плагинами и MCP-серверами. Что стоит поставить тому, кто повторяет путь:
- google-play-mcp — MCP-сервер Play Console: листинги, товары, подписки, картинки, деплой в треки. Именно через него в этом проекте заливались стор-листинги на 19 языков и AAB в бету; подключение —
.mcp.jsonв корне проекта с путём к ключу сервис-аккаунта. - Maestro MCP — у мобильного тест-фреймворка Maestro с февраля 2026-го встроенный MCP-сервер: агент сам поднимает эмулятор, ставит сборку, проходит все экраны, тапает кнопки и возвращает отчёт. По сути тот же самодельный плейтестер, только из коробки и с настоящим UI-тест-движком под капотом.
- claude-in-mobile и Android-MCP — обёртки над adb (первая заодно над simctl для iOS): скриншоты, тапы, запуск приложений, чтение логов устройства естественным языком. Легковесная альтернатива Maestro, когда полный тест-фреймворк избыточен.
- Context7 — подкладывает агенту актуальную документацию библиотек по запросу. Лечит главную беду любой LLM — устаревшие API из обучающих данных: Billing Library и AdMob SDK меняются быстрее, чем переучиваются модели, и без свежей доки агент уверенно пишет прошлогодний код.
- Playwright MCP — браузер под управлением агента. Нужен для того немногого, на что у Google нет API: первичное создание приложения в консоли, анкеты Data Safety и рейтинга контента. В этой сессии ровно для этого писалась отдельная инструкция браузерному агенту.
Правило то же, что и с библиотеками в APK: ставить только то, что закрывает реальный шаг конвейера. Каждый MCP-сервер добавляет описания своих инструментов в контекст — зоопарк из двадцати плагинов съест токены быстрее, чем grep, с которым боролись врезкой выше.
Чем ещё вайб-кодить
Для симметрии с обзором дизайн-инструментов — конкуренты Claude Code на кодовой стороне, на случай если описанный сетап не по душе или не по карману.
Codex CLI от OpenAI — ближайший аналог: опенсорсный терминальный агент, работает по подписке ChatGPT (вход дешевле — с Plus за $20). Код пишет плотно и инструкциям следует жёстко, но экосистема вокруг — субагенты, скиллы, MCP-интеграции — пока беднее; трюк с плейтестером и переводчиками там пришлось бы собирать руками.
Gemini CLI от Google — главный аргумент «попробовать вайб-кодинг бесплатно»: опенсорс, щедрый дневной лимит запросов просто за гугл-аккаунт и контекст на миллион токенов, в который средний Android-проект влезает целиком, без ухищрений с каноническими документами.
Cursor — не CLI, а редактор (форк VS Code) с агентом внутри; модели на выбор — Claude, GPT, Gemini. Силён в интерактивной работе «выделил — попросил — посмотрел дифф»; длинные автономные сессии, где агент час гоняет эмулятор, — не его жанр.
GitHub Copilot — агентный режим в VS Code за $10 плюс ревью пул-реквестов. Самый консервативный и корпоративно-приглаженный вариант: хорош как второй пилот, слаб как прораб.
aider — опенсорс-ветеран для тех, кто хочет платить только за токены по своему API-ключу. Спартанский интерфейс, зато образцовая git-дисциплина: каждое изменение — отдельный коммит с внятным сообщением.
Критерий тот же, что и с дизайном: не бенчмарки, а длинные автономные сессии с инструментами. Агенту в этом проекте приходилось часами держать в руках Gradle, adb, эмулятор, ffmpeg и REST API Google Play одновременно — выбирать стоит тот инструмент, который в конкретном стеке умеет так же.
Экономика кликера: расчёт вместо интуиции
Теперь самое интересное — то, что обычно остаётся за кадром статей про «сделал игру с ИИ». Баланс. Вот ядро экономики целиком, оно умещается в несколько строк:
// Economy.kt
const val COST_GROWTH = 1.18
fun incomeAtLevel(def: ItemDef, level: Int) = def.baseIncome * level
fun costForNext(def: ItemDef, level: Int) =
def.baseCost * Math.pow(COST_GROWTH, level.toDouble())
// GameState.kt
perTap = 1.0 + idle * 0.005 // тап масштабируется от пассивки
fun permanentMult() = prestigeMult * subMult() * repMult() * crewMult()
fun globalMult() = boostMult() * permanentMult()
fun effectivePerSec() = perSec * globalMult()
Здесь та самая вторая ось, обещанная в разделе про дизайн-сессию: baseIncome и baseCost каждого предмета берутся из балансной таблицы, где они растут геометрически от предмета к предмету, а вот внутри одного предмета доход линеен по уровню, цена же растёт экспоненциально. Классика жанра: одна кривая разводит предметы между собой, вторая заставляет упираться в потолок при прокачке любого из них.
Все множители (буст ×2 за рекламу, престиж, подписка, репутация, крю) собраны в одну функцию globalMult(), и это принципиально: когда все бонусы сходятся в одной точке, всегда понятно, что именно умножается и на что. Размазанные по коду бонусы — прямая дорога к эксплойтам.
Симулятор находит эксплойты
Главный урок: баланс кликера нельзя проверить игрой и нельзя прикинуть в голове. Экспоненты не поддаются интуиции. Проверяется он только симуляцией.
Агент написал на Python greedy-симулятор: виртуальный игрок каждую секунду покупает модуль с лучшим отношением «доход/цена», тапает с заданной частотой, забирает награды глав. Прогон даёт время достижения каждой главы. Первый же запуск нашёл эксплойт, который руками искался бы неделями: сила тапа была привязана к пассивному доходу с коэффициентом 0.05, тап масштабировался вместе со всей экономикой, и активный игрок пробегал всю игру за 4,2 часа. Для idle-проекта, рассчитанного на недели, — приговор.
Лечение: коэффициент тапа 0.05 → 0.005 (тап — это бутстрап на старте и тактильное удовольствие, а не источник дохода), рост цены 1.15 → 1.18, пороги поздних глав — вчетверо. После пары итераций «сим → тюнинг → сим» таблица встала на целевые рельсы:
| Глава | Порог ₵ | 3 тапа/с | Чистый idle |
|---|---|---|---|
| 1 | 2 000 | 2 мин | 2,4 мин |
| 3 | 1M | 12,6 мин | 13 мин |
| 5 | 1,6B | 55 мин | 56 мин |
| 6 | 40B | 1,93 ч | 1,98 ч |
| 7 | 1T | 8,2 ч | 8,4 ч |
То есть 8,2–8,4 часа «идеального» greedy-прохождения до седьмой главы; восьмая в таблицу уже не влезла. Реальный игрок с офлайн-капом 8 часов (12 — для VIP) и заходами по 10 минут растянет это на неделю с лишним — ровно та календарная длительность, которая и заказывалась. Стоит обратить внимание: колонки «3 тапа/с» и «idle» почти совпали — после фикса тап честно перестал решать.
Хронометраж из дизайн-сессии: ~6,3 ч активной игры до финала истории, ~10 дней до первого престижа, 150–200 ч полного контента. Это плановая оценка, сделанная до ребаланса, — симулятор после фикса тапа дал цифры выше
Из симуляции же родилось правило для наград: кредитная награда главы ≈ 3 минуты дохода на её этапе. Меньше — игрок не заметит, больше — награда сломает кривую цен. А премиум-валюта в наградах должна быть согласована с ценником стоков: миссии дают 10–800 крипты, кейсы стоят 120–340 — то есть достижения оплачивают несколько кейсов, но не позволяют не покупать их вообще.
Антипаттерн: фиксированные цифры в экспоненциальной экономике
Рейд на сервер MOLOCH изначально имел фиксированные 7 миллиардов HP. На ранней игре тап наносил ~5000 урона — полоска не двигалась вообще, 0.00007% за клик. В эндгейме те же 7 миллиардов выносились бы за секунды. Вывод, который стоит запомнить: в экономике, растущей экспоненциально, любая захардкоженная константа сломана всегда — либо уже, либо скоро.
Правильный рейд масштабируется от силы игрока:
fun raidDamage() = effectivePerTap() * 10 + perSec + 2000
fun nextRaidMax() = raidDamage() * 30 * (1 + raidKills * 0.12)
Первый рейд — ровно ~30 осмысленных тапов, и так на любом этапе игры, потому что и урон, и порог считаются от текущей силы. Дальше множитель от числа побед планку поднимает: после десяти рейдов это уже 66 тапов, после двадцати пяти — 120. Эскалация линейная и без потолка, так что кап на числе побед в этой формуле напрашивается — в текущей версии его нет. Слагаемое +2000 в raidDamage() — единственная захардкоженная константа во всей связке, и она здесь сознательно: это пол урона для самого начала игры, когда perTap ещё измеряется единицами. На втором часу игры она теряется в округлении.
Той же логике подчиняется престиж — очки считаются от корня из дохода, чтобы каждый следующий сброс требовал заметно большего прогресса:
fun prestigePoints() = floor(sqrt(perSec / 50.0)).toInt()
fun prestigeMultGain() = prestigePoints() * 0.1 // перманентный множитель
fun blackGain() = prestigePoints().toLong() // премиум-валюта за сброс
Валюты: у каждой должен быть сток
Пять валют — это не жадность, а разделение контуров, чтобы прогресс в одном не обесценивал другой. Но валюта без стока — мусор в интерфейсе. В какой-то момент аудит показал, что репутация копится и не тратится никуда — пришлось придумывать вербовку операторов. Итоговая матрица:
| Валюта | Источники | Стоки |
|---|---|---|
| Credits ₵ | тап, idle, награды | модули магазина |
| Crypto ◈ | реклама, IAP, награды | кейсы, уровни Battle Pass |
| Intel ❖ | daily, главы | скрипт-атака рейда, прокачка крю |
| Rep ✦ | главы, босс карты | вербовка операторов |
| Black ◆ | рейд, престиж, IAP | премиум-кейс |
И последний балансовый капкан — бесплатные действия. Кнопка «Атаковать башню» на карте сначала выдавала награду мгновенно и без лимита: спам-фарм в чистом виде. Лечится кулдауном (8 часов), а награда за ожидание масштабируется от дохода. Каждое бесплатное действие в игре стоит проверять вопросом «что будет, если жать это 1000 раз подряд?».
Монетизация: реклама
Схема стандартная для жанра — AdMob в три формата, — но дьявол в мелочах.
Баннер — adaptive anchored (не фиксированный 320×50), сидит в контейнере над нижним меню, персистентный AdView: один экземпляр на сессию, не пересоздаётся при навигации — иначе он мигает после возврата с фуллскрин-рекламы и ловит лишние no-fill. При ошибке загрузки — ретраи с экспоненциальным бэкоффом; в референсных сэмплах Google задержка считается как 2^min(6, номер попытки) секунд, то есть 2, 4, 8… с потолком в 64. Но если в консоли AdMob включён auto-refresh — свои ретраи не нужны, рефреш повторит сам. Interstitial показывается при переключении вкладок с кулдауном 120 секунд. Официальные рекомендации AdMob на этот счёт качественные — показывать в естественных точках перехода, не на запуске и не на выходе; в отрасли же принято считать комфортным интервал 3–5 минут и 1–3 показа за сессию, так что 2 минуты — нижняя граница наглости, дальше смотреть по удержанию. Rewarded — главный формат для кликера, и вот тут была основная продуктовая итерация. Сначала точка показа была одна (бустер «Перегрузка»: ×2 дохода на 15 минут плюс крипта). После взгляда на цифры агенту ушёл вопрос: «подумай, как мотивировать пользователя смотреть rewarded, оно сейчас вообще работает?» Итог — семь точек:
- Перегрузка: ×2 доход + 20 ◈ (Home);
- удвоение награды главы, миссии и daily — после получения базовой;
- удвоение офлайн-дохода при входе;
- мгновенное завершение 4-часовой операции крю;
- сброс кулдауна штурма башни.
Паттерн «удвоение» важен психологически: базовая награда уже выдана, видео — чистый бонус, отказ ничего не отнимает. И защита от фарма: суммарная длительность ×2-буста капнута двумя часами.
Технический минимум, без которого сейчас никуда: UMP-согласие (GDPR) до инициализации SDK — requestConsentInfoUpdate → loadAndShowConsentFormIfRequired → и только при canRequestAds вызывается MobileAds.initialize(). Форма, кстати, покажется только после того, как в консоли AdMob опубликовано GDPR-сообщение — без него флоу молча пропускается, и на тестах кажется, что «всё работает». Тестовые ID рекламы в debug-сборке, боевые — в release через BuildConfig и manifestPlaceholders, чтобы физически нельзя было накликать себе бан на боевых ID. Для фуллскрин-форматов в edge-to-edge приложении — setImmersiveMode(true) перед показом, иначе системные бары лягут поверх рекламы. Ну и app-ads.txt на домене разработчика.
Вся реклама гейтится одной функцией hasNoAds() — и это мостик к следующему разделу, потому что отключение рекламы здесь продаётся подпиской.
Монетизация: покупки и подписки
Каталог — 7 расходуемых товаров (четыре пака крипты, два пака премиум-валюты и стартер-пак) и 3 подписки:
| Продукт | Цена | Содержимое |
|---|---|---|
| crypto_100…3000 | $1.99–29.99 | паки крипты, бонус +10…35% к номиналу |
| black_25 / black_120 | $3.99 / 12.99 | премиум-валюта |
| starter_pack | $7.99 (вместо обычных $19.99) | 500 ◈ + 3 кейса + VIP на 7 дней |
| vip_hacker | $2.99/мес | доход ×1.1, без рекламы, офлайн 12 ч, daily ×2 |
| underground_elite | $5.99/мес | ×1.25, всё из VIP + премиум Battle Pass |
| shadow_council | $12.99/мес | ×1.5, всё из Elite + легендарные награды |
Экраны вокруг денег: ежедневный вход, тиры подписок, престиж. Всё это было нарисовано до первой строчки Kotlin
Несколько решений, которые стоит скопировать.
Стартер-пак обязан выдавать то, что обещает. Сначала он выдавал только крипту, а в описании значились кейсы и VIP — классический баг «купил, а половины нет», который убивает рейтинг мгновенно. Теперь grantStarterPack() выдаёт всё, включая временный VIP через starterVipUntil — он честно учитывается в общем effectiveSubTier(). И отдельная осторожность с зачёркнутой ценой: если товар по $19.99 никогда реально не продавался, перечёркнутый ценник — это уже зона правил Play о вводящих в заблуждение промо. Скидка должна быть настоящей, а не декоративной.
Подписки-тиры: Play сам ничего не разрулит. Важная деталь, которую путают все, кто пришёл из iOS: «subscription groups» — термин Apple, в Google Play их нет. Каждый тир — отдельный subscription-продукт со своим base plan, и Play спокойно позволит юзеру купить VIP и Elite одновременно — платить он будет за оба, а разбираться с возвратом придётся разработчику. Апгрейд и даунгрейд между тирами — обязанность приложения: при активной подписке в биллинг-флоу передаётся BillingFlowParams.SubscriptionUpdateParams со старым purchaseToken и ReplacementMode (например, CHARGE_PRORATED_PRICE) — тогда Play заменит подписку с перерасчётом. В этой сборке параметр пока в TODO: subscribe() запускает голый флоу, а от задвоения страхует только restorePurchases(), который выдаёт в игре старший из активных тиров. Страховка от кривого стейта — да; от двойного списания у клиента — нет. Повторять не стоит, лучше делать сразу.
Цены — только из ProductDetails. Захардкоженные цены в UI — исключительно фолбэк для сборки без Play Services. Реальную локализованную цену отдаёт биллинг, и она же уходит в purchase-sheet — нижний лист подтверждения покупки с составом пака и футером «Оплата через Google Play». Кстати, о базовой валюте: изначально цены ставились в рублях, потом стало очевидно, что основная аудитория не RU, и вся сетка была пересчитана от долларовой базы через API pricing:convertRegionPrices сразу на 173 региона.
restorePurchases() при каждом старте. queryPurchasesAsync по INAPP и SUBS: довыдать незавершённые покупки, синхронизировать тир подписки с реальностью, снять его при истечении. Плюс consumeAsync для расходников и acknowledgePurchase для остального — забудешь подтвердить, и Play вернёт деньги через три дня.
Дебаг-меню для тестирования покупок. Пять тапов по версии билда в настройках (только в debug-сборке) — тумблер debugPurchases, при котором покупки выдаются локально без оплаты, плюс кнопки «+1M кредитов» и сброс прогресса. Тестировать флоу выдачи наград нужно до того, как товары оживут в консоли.
Отдельного абзаца заслуживает работа с Play Console. Руками там почти ничего не создавалось: сервис-аккаунт с доступом к androidpublisher — и агент через API создал товары, подписки и локализованные листинги скриптами. Пара граблей для гуглящих: старый эндпоинт inappproducts для новых приложений мёртв (403 «migrate to the new publishing API»), нужен новый Monetization API с ручками oneTimeProducts/subscriptions в camelCase; и почти любой запрос к нему требует параметр regionsVersion.version — актуальное значение 2022/02, оно не менялось с момента появления Monetization API и инкрементируется только при существенном изменении списка поддерживаемых регионов. Если API ругнётся, он подскажет ожидаемое значение в тексте ошибки. Релиз-ноты на 19 языках и заливка AAB в бету — тоже через API, промптом «собери релизный AAB и выложи в beta». А на случай, когда локальной машины под рукой нет, в репозитории лежит codemagic.yaml — облачный CI с двумя workflow (debug и подписанный release) собирает APK на маковском раннере по кнопке; бесплатных минут Codemagic соло-разработчику хватает.
Что честно осталось в TODO: серверная валидация покупок. Сейчас выдача чисто клиентская, то есть игра ломается Lucky Patcher’ом на раз. Для офлайн-сингла без PvP это осознанно сочтено приемлемым на старте — читер портит игру только себе, — но галочка в чек-листе висит.
A/B-тест иконки: наука вместо вкусовщины
Иконка — самый недооценённый элемент монетизации: это первое, что видит человек в выдаче, и CTR иконки умножает собой всю воронку до последнего доллара. Спорить о том, «какая красивее», бессмысленно — в Play Console для этого есть штатный инструмент: Store listing experiments (Магазин → Эксперименты со страницей приложения). Работает так: к текущей иконке-контролю добавляется до трёх вариантов, задаётся доля трафика, и Play сам делит посетителей листинга и считает метрику — первичные установки, причём отдельно показывает удержанных (retained installers), чтобы кликбейтная иконка, которую сносят через час, не выиграла нечестно. Результат отдаётся с доверительным интервалом: пока интервал варианта не оторвался от контроля — победителя нет, надо ждать трафика. Google советует держать эксперимент минимум неделю, чтобы захватить и будни, и выходные, а на малых объёмах он может висеть неделями. Поэтому иконку тестируют первой, пока остальные элементы листинга заморожены: одна переменная за раз, иначе не понять, что сработало.
Отдельная страница в дизайн-проекте называется «Релиз», и это заготовка ровно под такой эксперимент. Сначала — таблица конкурентов из выдачи Google Play по запросу «симулятор хакера» с разбором, что у каждого на иконке: у лидера — фигура в капюшоне на фоне кода, у второго — 3D-рендер рабочего места, дальше терминалы, матрица, роботы-талисманы. По этим типажам сгенерированы 17 кандидатов: контрольный череп плюс 16 концептов, закрывающих всю карту гипотез — «капюшон со скан-лучом» (ответ лидеру), терминал с ACCESS GRANTED (типаж ОС-симуляторов), мультяшный хакер с +99 (казуальная аудитория), монета с бинарной гравировкой (мотив тайкуна), кибер-маска как единственное светлое пятно в зелёной выдаче. В слоты эксперимента 17 штук не влезут — тестировать придётся раундами по три, начиная с самых непохожих друг на друга гипотез: сперва выясняется выигрышный типаж, потом гоняются вариации внутри него. Каждый кандидат уже разложен на слои adaptive icon (background без альфы, foreground с альфой, ключевой объект в безопасной зоне под маски лаунчеров) — то, что раньше заказывалось дизайнеру на неделю, теперь побочный продукт вечерней итерации.
Первый раунд — самые непохожие гипотезы: молния в гексе, терминал, монограмма и череп (выбран контролем)
Финальный раунд: два «капюшона со скан-лучом» (ответ лидеру выдачи) против контрольного черепа
Графика бесплатными нейросетями
Здесь нужно проговорить разделение труда, которое нащупалось на этом проекте. Claude — языковая модель, и графику он делает кодом: SVG, Canvas, процедурные генераторы — блестяще (вся внутриигровая графика HACK CLUB, от гексов карты до портретов персонажей, — его работа). А вот растр он не рисует в принципе: попросишь картинку — получишь код, который её рисует. Его прямые конкуренты формально умеют больше: у ChatGPT есть GPT Image, у Gemini — собственная мультимодальная генерация изображений (плюс отдельная линейка Imagen), и обе выдают готовые пиксели прямо в чате. Но это именно диффузионная часть системы, а не талант самой LLM — код той же Imagen не напишет. Отсюда честный пайплайн: процедурное и векторное — кодовому агенту, растровое — картиночным моделям. Эталоны растра — Midjourney и GPT Image — платные; но сторовых ассетов (иконка 512×512, feature graphic, промо) нужно штук десять, и на этот объём хватает бесплатного зоопарка. Иконки для HACK CLUB сделала сама дизайн-сессия, но если собирать пайплайн из отдельных инструментов, картина такая.
Локальные модели — единственный по-настоящему бесплатный вариант без звёздочек: Stable Diffusion XL и FLUX.1 [schnell] крутятся на своей видеокарте, у schnell лицензия Apache 2.0 — коммерция разрешена без оговорок. Внимание на грабли, знакомые по музыкальному разделу: FLUX.1 [dev] — та же модель пожирнее, но веса некоммерческие. Читать надо лицензию весов, а не название репозитория.
Из облачных: Recraft — самый известный генератор, который отдаёт настоящий SVG, а не растр, — для иконок и плоской графики это киллер-фича (вектор потом руками правится в любом редакторе); бесплатный тариф есть, но публичность работ и права надо смотреть в актуальных условиях. Вектор сегодня умеют и другие — Adobe Firefly, Text to Vector в Illustrator, — но у них это часть платной экосистемы. Ideogram традиционно силён в леттеринге внутри картинки — пригодится для feature graphic с названием игры; правда, разрыв уже не тот, что пару лет назад: и GPT Image, и нативная генерация Gemini текст сейчас рисуют прилично. Copilot / Bing Image Creator и Gemini — самый низкий порог входа с дневными лимитами. Общее правило для любого фри-тарифа облачного генератора: права на коммерческое использование — не дефолт, а пункт условий, который надо прочитать до релиза.
Feature graphic для листинга — тот случай, когда леттеринг критичен. У HACK CLUB он процедурный, из дизайн-сессии; в диффузионном пайплайне за такое отвечал бы Ideogram
И два практических фильтра, которые отсеивают 90% сгенерированной красоты. Первый: иконку надо смотреть в масштабе 48×48 пикселей — в выдаче она размером с ноготь, и детализированный шедевр превращается в грязное пятно; выживает крупный силуэт с одной идеей. Второй: генераторы не знают про adaptive icon и его безопасную зону — просить фон и ключевой объект отдельными изображениями или готовиться резать слои руками, иначе круглая маска лаунчера отрежет хакеру полголовы.
Глаза на проде: крэши и аналитика
Есть отдельная ирония в том, что в проекте, где код писал не человек, крэш-репортинг нужен ещё сильнее обычного: нет даже той иллюзорной уверенности «я это писал, я знаю, где может упасть».
Для крэшей взят Tracer (ru.ok.tracer) — открытый крэш-репортинг от VK, который они гоняют на своих приложениях с сотнями миллионов установок. Подключение — Gradle-плагин плюс пара конфигураций в Application:
class App : Application(), HasTracerConfiguration {
override val tracerConfiguration: List<TracerConfiguration>
get() = listOf(
CoreTracerConfiguration.build { },
CrashReportConfiguration.build { },
CrashFreeConfiguration.build { enabled = true },
)
}
Чем он удобнее Crashlytics: не тянет за собой весь Firebase (когда весь код после R8 — 4 Мбайта, это аргумент), плагин сам заливает mapping.txt при сборке — стектрейсы minify-сборки приходят уже деобфусцированными, — и из коробки считает crash-free users, главную метрику здоровья релиза. Плюс для разработчика из ru-региона он просто работает, без плясок с доступностью консоли. Окупился мгновенно: те самые крэши поворота экрана и градиента из врезки выше чинились по готовым стектрейсам с беты, а не по отзывам «вылетает, одна звезда».
Продуктовой аналитики в игре пока нет, и это осознанный следующий шаг, а не забывчивость. План — AppMetrica: у бесплатного тарифа суточный потолок 3 250 000 кастомных событий (около 100 миллионов в месяц), что для кликера запас на порядки, а события покупок, подписок и ad revenue в этот лимит не входят вовсе — то есть revenue-отчёты по Play, когорты и retention достаются даром. Альтернатива — Firebase Analytics, если проект и так в экосистеме Google. Но какой бы SDK ни был выбран, для кликера набор событий один, и он важнее выбора инструмента:
- шаги онбординга и первая покупка модуля — здесь умирает больше всего игроков;
- достижение каждой главы — это реперные точки симулятора: разница между расчётной кривой и реальной покажет, где баланс врёт;
- каждая точка показа rewarded — какие из семи работают, а какие мертвы;
- престиж, IAP, отмены подписок.
В BALANCE.md висит TODO «проверить пороги на реальном плейтесте». Без аналитики этот пункт не закрывается никогда: симулятор считает идеального игрока, а живые люди бросают игру в местах, которые ни один greedy-алгоритм не предскажет.
И финальный штрих, о который спотыкаются на ревью в Play: и крэш-репортинг, и аналитика, и AD_ID — это сбор данных, который обязан быть задекларирован в Data Safety консоли. Форма занудная, но несоответствие между ней и реальным трафиком SDK — повод для реджекта.
Вместо заключения
Что показал этот месяц — тезисно, без мотивационного сиропа.
Сто шестьдесят промптов — это и есть разработка. ИИ снял с человека набор кода, но не снял ни одного решения: выбор архитектуры, целевая длительность игры, цена ошибки в стартер-паке, «тосты — это плохо» — всё это по-прежнему работа того, кто понимает, что делает. Изменился инструмент, а не профессия.
Документы-каноны в git важнее памяти агента. STORY.md и BALANCE.md пережили три переполнения контекста и не дали проекту расползтись.Начинать долгий проект с агентом стоит с заведения таких файлов в первый день.
Баланс считается симулятором. Эксплойт «вся игра за 4,2 часа» не находится плейтестом и не виден в коде глазами. Сим пишется один раз, гоняется после каждого ребаланса, таблицы хранятся рядом с формулами.
Самый полезный промпт — «поищи ещё заглушки и сделай рабочими». Сгенерированный по красивому дизайну интерфейс полон нарисованных цифр и мёртвых кнопок. Этот промпт прогонялся раз пять, и каждый раз агент находил очередной хардкод «LV 24» или кнопку без onClick.
Агент, играющий в собственную игру, окупается за день. Плейтестер на эмуляторе — самый дешёвый QA-отдел из возможных.
Принесёт ли всё это деньги — станет ясно через пару месяцев: у Google Play своё мнение о любой экономике, и никакой симулятор его не предскажет. Про «Злых птичек», выстреливших с 52-й попытки, знают все. С тех пор изменилось одно: попытки стали стоить месяц вместо года. А значит, их можно позволить себе пятьдесят две.
Такие дела. Первое правило Проекта «Дерден» — рассказать о Проекте «Дерден».








