Пост о воплощении мечты и о создании игры с нуля. И о граблях разной величины.
0. Дано
Когда-то, во времена не столь от нас отдаленные, когда интернет в Уфе был ещё с помегабайтной оплатой, я занимался созданием и разработкой локальных «фришных» серверов Lineage и WoW. Но вот появились безлимитные тарифы, а локальные сервисы начали терять свою актуальность и я ушёл в вебразработку.
В некотором роде, как хобби я даже сохранил своё отношение в Геймдеву, правда, с другой стороны – разработка ботов и всего такого.
Шли года, а мысль написать что-нибудь свое, с преферансом и поэтессами не переставала меня терзать. В какой-то момент я понял, что либо сейчас, либо уже никогда.
1. Идея и Прототип
С чего начинается разработка? C прототипа. А прототип — с идеи. Для первого проекта стоит создать что-то небольшое и простое. Питая любовь к головоломкам и пошаговым стратегиям, я увлекся мыслью, что нужно сделать какую-нибудь пошаговую головоломку. Поразмыслив, вспомнил одну интересную игру времён Спектрума (стоит отметить, что автор не так стар, как может показаться) идея которой была прекрасна в своей простоте. Игрок ходит на 1 клетку, обходя препятствия, а враги его преследуют и ходят на 2 клетки, но препятствия не обходят.
Если взять ситуацию “A,” то мы можем спокойно ходить вверх и вниз, а монстр просто будет упираться в стену. В ситуации “B” монстр находится в загончике, а мы можем спокойно ходить справа, сверху и снизу от него. Поскольку игра у нас детерминированная, то существуют два типа монстров, которые отличаются по цветам и алгоритму поиска пути. Это для того чтобы не было неопределённости куда пойдёт монстр, когда он стоит наискосок. Красный всегда сначала сокращает расстояние до нуля по оси X ситуация “C”, в ней монстр зайдёт в загончик и упрётся в стенку. Фиолетовый же по оси Y ситуация “D”, в ней монстр пойдёт вниз, а потом уже направо и съедает главного героя.
Тут ещё мог бы быть большой абзац про выбор «движка» для написания игры. Но, пожалуй, можно обойтись и парой слов; перед тем как попробовать Unity3D, я поковырялся в нативном Obj-C, Corona SDK, UE, Cocos2d и ещё пару 2D Фреймворках, название которых, так глубоко в стеке памяти, что уже и не откопать.
В итоге, выбор пал на Unity3D, он мне показался оптимальным и я неспешно начал писать. Через месяц появилось вот такое приложение для iPad.
В нём мы играли за мужичка в красном и убегали от мужичков в синем, параллельно собирали сердца – читай звезды. В тот момент мы ещё использовали кубы как стены, но затем для экономии пространства на экране заменили их.
Хотелось бы отметить, что до этого момента, я никогда не писал на C#, но писал на JS, поэтому прототип был написан UnityScript (это такой диалект JS в рамках Unity3D). И это были первые большие грабли, послужившие нам уроком. Пришлось переписывать всё на C# и это заняло пару месяцев.
2. Команда
Как верно то, что я писал на десятке языков, так верно и то, что я не в состоянии нарисовать даже прямую линию. Поэтому после создания прототипа я начал искать художника\3Dшника, для этого я зашёл на сайт по фрилансу и посмотрел первых три сотни человек, с десятком — списался. Найти человека, за долю в довольно рискованном проекте, задача не из легких. Но она разрешилась, и в проекте появился талантливый художник Рамиль; итак – нас стало двое.
Параллельно я искал инвестора. Дело не в отсутствии денег, чтобы купить плагины или устройства для теста, а в том, чтобы создать обязательства, которые помогут не забить (не сложить с себя полномочия) при определенных обстоятельствах. И такой инвестор нашелся, в виде друга, решившего вложить свои кровные, в эту сомнительную, как ему казалось, затею. Итак, нас стало трое. Отмечу, что к моменту запуска, бюджет игры составил всего около 100.000р., при этом, в эту сумму входит покупка нескольких Android устройств для тестирования, плагинов и озвучки.
3. Расширение базовой концепции игры
С самого начала предполагалось, что невзирая на то, что игра будет максимально простой, необходимо будет привнести несколько новых идей в базовую концепцию. Так у нас появились односторонние телепорты (позже станет ботинком), ловушки и одноразовые грибы съедающие тех кто к ним подойдёт.
Основной фишкой игры мы планировали сделать то, что персонаж может вернуться во времени, на несколько ходов назад. Т.е. не отмену хода, а возможность переместиться 1 раз за уровень на клетку, где персонаж был 3 хода назад. Это давало огромное количество вариантов хода, но на первых же тестах выяснилось, что обычные игроки не в состоянии пройти такие уровни. Слишком сложно. Может стоить таки сделать Brainiac Edition?
Также мы много экспериментировали с размером уровней, в итоге остановились на том что весь уровень должен вмещаться на экран, даже на устройствах с небольшим экраном. Так у нас получились уровни 5х8 клеток. Но при этом у нас есть pinch zoom, для большепальцых или уровней 6х10. Кроме сокращения размера уровней, отключения возврата во времени, для упрощения была ещё добавлена отмена хода, до 5 раз за попытку.
4. 2D vs 3D
В какой-то момент наши тестовые билды выглядели так:
Приходило осознание того, что мы не в состоянии сделать картинку, которую мы хотели бы видеть в 3D с нормальным fps. Тестовая сцена для сравнения производительность 2D и 3D показывала не утешительные результаты.
В итоге было принято решение всё переделывать на 2D. Но тут мы совершили ошибку, которую уже потом было не исправить. 2D анимация может быть 2 типов, первый это последовательность кадров, второй это наложение и смещение спрайтов.
Поскольку у нас были 3D модели, мы выбрали первый вариант. В итоге это выльется в большой вес приложения, даже с учётом огромного кол-ва оптимизаций мы не сможем уложиться в 50 мегабайт.
5. Форс-мажоры — это возможность
Не знаю можно ли назвать рождение ребёнка и переезды форс-мажорами, но именно эти события исключили нашего художника из работы над проектом, на несколько месяцев. Эти же обстоятельства сослужили службу и мне. В целях самообучения и познания тонкостей магазинов, я сделал другое небольшое приложение – обычную угадайку фильмов.
На этом приложении я смог протестировать интеграцию с соц. сетями, несколько рекламных сетей, внутреннею аналитику и покупки внутри приложения.
6. Техническая часть
Думаю, настало время поднять градус гиковости. Значимую часть времени разработки заняло создание генератора уровней. Генератор писался на питоне, потому как он был мне духовно близок и numpy позволял быстро оперировать матрицами.
Сам генератор на выходе создавал txt файл(который парсился Юнити для создания сцены) и серию картинок, показывающих пошаговое прохождение уровня.
Сейчас я могу сказать, что писание внешнего генератора на другом языке, это — плохая идея. Главным образом, тем, что игровая логика начинает прописываться в двух разных местах. А это — риск рассинхрона. Особенно, если учесть, что внутри игры, есть такие понятия, как анимация и время её исполнения. И в генераторе, и в игре каждая клетка сама следила за тем, что в ней происходит: кто вошёл, кто вышел, кто умер и т.д. Но клетки, вида телепорт или мухобойка (атакует близлежащие клетки), связывали несколько клеток между собой. И если в генераторе это не вызывало проблем, то в игре повторить то же было сложнее т.к. анимации персонажей из разных клеток должны были засинхронизироваться между собой.
Огромный кусок времени заняла интеграция нативных библиотек. Cкажу прямо: если можно купить готовую реализацию того, что вам нужно, смело покупайте. При этом желательно всё брать у одного продавца, потому как в Unity3D в манифесте (Андроид), есть такая штука как mainactivity и это место где разные плагины могут конфликтовать. Потом для iOS, скорее всего, у вас будут плагины, которые занимаются различным постпроцессингом, это тоже место для конфликтов. В целом нативные либы, это место где вы легко можете получить очень трудно выявляемые ошибки. Поэтому, почти всё, что связанно с нативным кодом, мы покупали у Prime31.
7. Статистика
В релизе около 400кб, написанного мной кода. Ещё 150кб — это генератор и некоторые смежные скрипты.
В самой игре, на данный момент, 3 главы по 16 отобранных уровней. Также есть режим Испытаний, где ещё около 700 уровней, динамически распределённых по сложности.
В среднем уровень без звёзд можно пройти за 25 ходов. Самые сложные уровни со звёздами около 55.
8. Монетизация и продвижение
Пока нет каких то точных цифр, но у нас как и у сайлонов есть план.
На примере угадайки фильмов мы поняли, что на рекламе можно заработать, только если у вас от 300к+ пользователей. Поскольку проект у нас, как ни крути нишевой, думаю это не вариант. Но при этом делать платное приложение для Андроида — самоубийство. В итоге была выбрана стандартная нынче модель: показ рекламы и продажа монет. С любой покупкой монет идёт в комплекте полное отключение рекламы. Монеты даются при прохождении уровней и за них можно узнать идеальное прохождение уровня.
Рекламироваться мы решили через обзоры, потому как покупка установок выходит очень дорого и ROI будет отрицательным.
iOS версия также готова, но по ней пока не принято решение как её выпускать. Может имеет смысл договориться с каким-нибудь издателем.
9. Небольшое ингейм видео.
Правда, в игре портретная ориентация экрана.
0. Дано
Когда-то, во времена не столь от нас отдаленные, когда интернет в Уфе был ещё с помегабайтной оплатой, я занимался созданием и разработкой локальных «фришных» серверов Lineage и WoW. Но вот появились безлимитные тарифы, а локальные сервисы начали терять свою актуальность и я ушёл в вебразработку.
В некотором роде, как хобби я даже сохранил своё отношение в Геймдеву, правда, с другой стороны – разработка ботов и всего такого.
Шли года, а мысль написать что-нибудь свое, с преферансом и поэтессами не переставала меня терзать. В какой-то момент я понял, что либо сейчас, либо уже никогда.
1. Идея и Прототип
С чего начинается разработка? C прототипа. А прототип — с идеи. Для первого проекта стоит создать что-то небольшое и простое. Питая любовь к головоломкам и пошаговым стратегиям, я увлекся мыслью, что нужно сделать какую-нибудь пошаговую головоломку. Поразмыслив, вспомнил одну интересную игру времён Спектрума (стоит отметить, что автор не так стар, как может показаться) идея которой была прекрасна в своей простоте. Игрок ходит на 1 клетку, обходя препятствия, а враги его преследуют и ходят на 2 клетки, но препятствия не обходят.
Если взять ситуацию “A,” то мы можем спокойно ходить вверх и вниз, а монстр просто будет упираться в стену. В ситуации “B” монстр находится в загончике, а мы можем спокойно ходить справа, сверху и снизу от него. Поскольку игра у нас детерминированная, то существуют два типа монстров, которые отличаются по цветам и алгоритму поиска пути. Это для того чтобы не было неопределённости куда пойдёт монстр, когда он стоит наискосок. Красный всегда сначала сокращает расстояние до нуля по оси X ситуация “C”, в ней монстр зайдёт в загончик и упрётся в стенку. Фиолетовый же по оси Y ситуация “D”, в ней монстр пойдёт вниз, а потом уже направо и съедает главного героя.
Тут ещё мог бы быть большой абзац про выбор «движка» для написания игры. Но, пожалуй, можно обойтись и парой слов; перед тем как попробовать Unity3D, я поковырялся в нативном Obj-C, Corona SDK, UE, Cocos2d и ещё пару 2D Фреймворках, название которых, так глубоко в стеке памяти, что уже и не откопать.
В итоге, выбор пал на Unity3D, он мне показался оптимальным и я неспешно начал писать. Через месяц появилось вот такое приложение для iPad.
В нём мы играли за мужичка в красном и убегали от мужичков в синем, параллельно собирали сердца – читай звезды. В тот момент мы ещё использовали кубы как стены, но затем для экономии пространства на экране заменили их.
Хотелось бы отметить, что до этого момента, я никогда не писал на C#, но писал на JS, поэтому прототип был написан UnityScript (это такой диалект JS в рамках Unity3D). И это были первые большие грабли, послужившие нам уроком. Пришлось переписывать всё на C# и это заняло пару месяцев.
2. Команда
Как верно то, что я писал на десятке языков, так верно и то, что я не в состоянии нарисовать даже прямую линию. Поэтому после создания прототипа я начал искать художника\3Dшника, для этого я зашёл на сайт по фрилансу и посмотрел первых три сотни человек, с десятком — списался. Найти человека, за долю в довольно рискованном проекте, задача не из легких. Но она разрешилась, и в проекте появился талантливый художник Рамиль; итак – нас стало двое.
Параллельно я искал инвестора. Дело не в отсутствии денег, чтобы купить плагины или устройства для теста, а в том, чтобы создать обязательства, которые помогут не забить (не сложить с себя полномочия) при определенных обстоятельствах. И такой инвестор нашелся, в виде друга, решившего вложить свои кровные, в эту сомнительную, как ему казалось, затею. Итак, нас стало трое. Отмечу, что к моменту запуска, бюджет игры составил всего около 100.000р., при этом, в эту сумму входит покупка нескольких Android устройств для тестирования, плагинов и озвучки.
3. Расширение базовой концепции игры
С самого начала предполагалось, что невзирая на то, что игра будет максимально простой, необходимо будет привнести несколько новых идей в базовую концепцию. Так у нас появились односторонние телепорты (позже станет ботинком), ловушки и одноразовые грибы съедающие тех кто к ним подойдёт.
Концепт Арт
Основной фишкой игры мы планировали сделать то, что персонаж может вернуться во времени, на несколько ходов назад. Т.е. не отмену хода, а возможность переместиться 1 раз за уровень на клетку, где персонаж был 3 хода назад. Это давало огромное количество вариантов хода, но на первых же тестах выяснилось, что обычные игроки не в состоянии пройти такие уровни. Слишком сложно. Может стоить таки сделать Brainiac Edition?
Также мы много экспериментировали с размером уровней, в итоге остановились на том что весь уровень должен вмещаться на экран, даже на устройствах с небольшим экраном. Так у нас получились уровни 5х8 клеток. Но при этом у нас есть pinch zoom, для большепальцых или уровней 6х10. Кроме сокращения размера уровней, отключения возврата во времени, для упрощения была ещё добавлена отмена хода, до 5 раз за попытку.
4. 2D vs 3D
В какой-то момент наши тестовые билды выглядели так:
Ужас ужас
Приходило осознание того, что мы не в состоянии сделать картинку, которую мы хотели бы видеть в 3D с нормальным fps. Тестовая сцена для сравнения производительность 2D и 3D показывала не утешительные результаты.
Скриншоты из сцены
В итоге на iphone4, слева(3D) было всего 20 кадров в секунду, а справа(2D), стабильные 60. При этом, справа, качество картинки, как вы видите, на порядок лучше. Сейчас конечно если ориентироваться на минимальную производительность уровня iphone5+ и делать специально несколько квадратную графику, кошерные шейдеры + lightmapping + lightp robes, можно и для 3D сделать отличную графику
В итоге на iphone4, слева(3D) было всего 20 кадров в секунду, а справа(2D), стабильные 60. При этом, справа, качество картинки, как вы видите, на порядок лучше. Сейчас конечно если ориентироваться на минимальную производительность уровня iphone5+ и делать специально несколько квадратную графику, кошерные шейдеры + lightmapping + lightp robes, можно и для 3D сделать отличную графику
В итоге было принято решение всё переделывать на 2D. Но тут мы совершили ошибку, которую уже потом было не исправить. 2D анимация может быть 2 типов, первый это последовательность кадров, второй это наложение и смещение спрайтов.
Наглядное сравнение
Поскольку у нас были 3D модели, мы выбрали первый вариант. В итоге это выльется в большой вес приложения, даже с учётом огромного кол-ва оптимизаций мы не сможем уложиться в 50 мегабайт.
5. Форс-мажоры — это возможность
Не знаю можно ли назвать рождение ребёнка и переезды форс-мажорами, но именно эти события исключили нашего художника из работы над проектом, на несколько месяцев. Эти же обстоятельства сослужили службу и мне. В целях самообучения и познания тонкостей магазинов, я сделал другое небольшое приложение – обычную угадайку фильмов.
Для тех кто не понял о чём речь
На этом приложении я смог протестировать интеграцию с соц. сетями, несколько рекламных сетей, внутреннею аналитику и покупки внутри приложения.
6. Техническая часть
Думаю, настало время поднять градус гиковости. Значимую часть времени разработки заняло создание генератора уровней. Генератор писался на питоне, потому как он был мне духовно близок и numpy позволял быстро оперировать матрицами.
Сам генератор на выходе создавал txt файл(который парсился Юнити для создания сцены) и серию картинок, показывающих пошаговое прохождение уровня.
gif анимация
Здесь зеленый квадрат — это игрок, жёлтый — враг, череп- это ловушка, которая убивает игрока, либо усыпляет врага на 3 хода.
Здесь зеленый квадрат — это игрок, жёлтый — враг, череп- это ловушка, которая убивает игрока, либо усыпляет врага на 3 хода.
Сейчас я могу сказать, что писание внешнего генератора на другом языке, это — плохая идея. Главным образом, тем, что игровая логика начинает прописываться в двух разных местах. А это — риск рассинхрона. Особенно, если учесть, что внутри игры, есть такие понятия, как анимация и время её исполнения. И в генераторе, и в игре каждая клетка сама следила за тем, что в ней происходит: кто вошёл, кто вышел, кто умер и т.д. Но клетки, вида телепорт или мухобойка (атакует близлежащие клетки), связывали несколько клеток между собой. И если в генераторе это не вызывало проблем, то в игре повторить то же было сложнее т.к. анимации персонажей из разных клеток должны были засинхронизироваться между собой.
Огромный кусок времени заняла интеграция нативных библиотек. Cкажу прямо: если можно купить готовую реализацию того, что вам нужно, смело покупайте. При этом желательно всё брать у одного продавца, потому как в Unity3D в манифесте (Андроид), есть такая штука как mainactivity и это место где разные плагины могут конфликтовать. Потом для iOS, скорее всего, у вас будут плагины, которые занимаются различным постпроцессингом, это тоже место для конфликтов. В целом нативные либы, это место где вы легко можете получить очень трудно выявляемые ошибки. Поэтому, почти всё, что связанно с нативным кодом, мы покупали у Prime31.
Полный список плагинов и несколько слов о каждом
Prime31 (Android+iOS) Admob 95$ — реклама с большим fillrate, так уж получилось, что не все сети могут показать баннер, когда их просят…
Prime31 (Android+iOS) Flurry 100$ — аналитика + реклама.
Prime31 (Android+iOS) InApp Purchases 130$ — покупки внутри приложения.
Prime31 (Android+iOS) Social 120$ — социальная интеграция Twitter и FaceBook, чтобы можно было запостить результат или просто лайкнуть приложение.
Prime31 (Android+iOS) Etcetera 130$ — нативное окно оценки приложения + всякая мелочь.
Так как речь зашла о плагинах, также был куплен NGUI 50$, лучший плагин для создания интерфейса. В AssetsStore много всяких плагинов для создания GUI, но имхо это самый лучший, к тому же его разработчик сейчас работает в самой команде Unity и на форуме пообещал, что когда выйдет официальный GUI, он постарается упростить миграцию на него. Must Have
2DToolKit 65$ для игровой анимации, сейчас ему появилась альтернатива, встроенная поддержка 2D от Юнити. Но 2DToolKit заточен для работы с последовательностями кадров, к тому же в нём есть несколько очень важных фич. Например, он может разрезать на квадраты большую картинку и сложить их в один атлас, это нужно, если у вас есть какая-то текстура 2048+ на 1ххх пикселей. Это позволит вписать её в текстуру 2048х2048(Ограничение размера андроид текстур). Из коробки в нём есть поддержка x1 x2 x4 мульти атласов. Например, у вас есть персонаж; у него очень много анимаций и они, ну никак, не влезают в текстуру 2048х2048, это позволит автоматически разбить на несколько атласов, которые из кода, вы будете видеть, как одну коллекцию. Must Have.
UniWebView 15$ плагин который позволяет показать браузер и получать с него, нормальные колбеки. Нужен был для того, чтобы общаться с VK api
Также несколько бесплатных плагинов:
Официальный Google Play Games plugin for Unity, для ачивментов, лидербордов и, в дальнейшем, системы синхронизации прогресса между устройствами.
Pushwoosh сервис для посылки пушнотификаций, у которого есть пакет для Unity3D.
Google Play OBB Downloader плагин который позволяет создавать приложения больше 50 мегабайт для Google Play Store. Поставляется с исходниками, был частично переписан для совместимости с другими нативными плагинами.
PoolManager by Path-o-logical Games хороший пуллменеджер, для того чтобы избежать лагов в момент создания объекта.
Audio Toolkit — для работы со звуком.
Prime31 (Android+iOS) Flurry 100$ — аналитика + реклама.
Prime31 (Android+iOS) InApp Purchases 130$ — покупки внутри приложения.
Prime31 (Android+iOS) Social 120$ — социальная интеграция Twitter и FaceBook, чтобы можно было запостить результат или просто лайкнуть приложение.
Prime31 (Android+iOS) Etcetera 130$ — нативное окно оценки приложения + всякая мелочь.
Так как речь зашла о плагинах, также был куплен NGUI 50$, лучший плагин для создания интерфейса. В AssetsStore много всяких плагинов для создания GUI, но имхо это самый лучший, к тому же его разработчик сейчас работает в самой команде Unity и на форуме пообещал, что когда выйдет официальный GUI, он постарается упростить миграцию на него. Must Have
2DToolKit 65$ для игровой анимации, сейчас ему появилась альтернатива, встроенная поддержка 2D от Юнити. Но 2DToolKit заточен для работы с последовательностями кадров, к тому же в нём есть несколько очень важных фич. Например, он может разрезать на квадраты большую картинку и сложить их в один атлас, это нужно, если у вас есть какая-то текстура 2048+ на 1ххх пикселей. Это позволит вписать её в текстуру 2048х2048(Ограничение размера андроид текстур). Из коробки в нём есть поддержка x1 x2 x4 мульти атласов. Например, у вас есть персонаж; у него очень много анимаций и они, ну никак, не влезают в текстуру 2048х2048, это позволит автоматически разбить на несколько атласов, которые из кода, вы будете видеть, как одну коллекцию. Must Have.
UniWebView 15$ плагин который позволяет показать браузер и получать с него, нормальные колбеки. Нужен был для того, чтобы общаться с VK api
Также несколько бесплатных плагинов:
Официальный Google Play Games plugin for Unity, для ачивментов, лидербордов и, в дальнейшем, системы синхронизации прогресса между устройствами.
Pushwoosh сервис для посылки пушнотификаций, у которого есть пакет для Unity3D.
Google Play OBB Downloader плагин который позволяет создавать приложения больше 50 мегабайт для Google Play Store. Поставляется с исходниками, был частично переписан для совместимости с другими нативными плагинами.
PoolManager by Path-o-logical Games хороший пуллменеджер, для того чтобы избежать лагов в момент создания объекта.
Audio Toolkit — для работы со звуком.
7. Статистика
В релизе около 400кб, написанного мной кода. Ещё 150кб — это генератор и некоторые смежные скрипты.
В самой игре, на данный момент, 3 главы по 16 отобранных уровней. Также есть режим Испытаний, где ещё около 700 уровней, динамически распределённых по сложности.
В среднем уровень без звёзд можно пройти за 25 ходов. Самые сложные уровни со звёздами около 55.
8. Монетизация и продвижение
Пока нет каких то точных цифр, но у нас как и у сайлонов есть план.
На примере угадайки фильмов мы поняли, что на рекламе можно заработать, только если у вас от 300к+ пользователей. Поскольку проект у нас, как ни крути нишевой, думаю это не вариант. Но при этом делать платное приложение для Андроида — самоубийство. В итоге была выбрана стандартная нынче модель: показ рекламы и продажа монет. С любой покупкой монет идёт в комплекте полное отключение рекламы. Монеты даются при прохождении уровней и за них можно узнать идеальное прохождение уровня.
Рекламироваться мы решили через обзоры, потому как покупка установок выходит очень дорого и ROI будет отрицательным.
iOS версия также готова, но по ней пока не принято решение как её выпускать. Может имеет смысл договориться с каким-нибудь издателем.
9. Небольшое ингейм видео.
Правда, в игре портретная ориентация экрана.