company_banner

Андроидная «Эволюция»: как это было



    Всем привет! Меня зовут Александр Гришин, я работаю в студии IT-Territory (Mail.Ru Group) специалистом по тестированию. Я занимаюсь разработкой Android-версии «Эволюции: Битва за Утопию». iOS-аудитория с интересом встретила новинку весной этого года, и мы уже готовимся к первым впечатлениям Android-юзеров. В статье я расскажу о том, как мы портировали игру на Android и с какими трудностями и нюансами столкнулись в процессе.

    «Эволюция» на iOS

    Если взглянуть на мобильные игры в целом, то сейчас на рынке мало проектов, подобных «Эволюции» — больших, сложных, затратных, требующих для разработки большую команду. Создание игр с таким количеством механик, каждая из которых, по сути, является отдельной миниигрой, процесс долгий и кропотливый: нужно не только их сделать, но потом еще и соединить, притереть друг к другу, сделать так, чтобы все вместе работало как надо и вызывало у пользователя интерес, а не недоумение. Таких игр мало даже на iOS, для которого студии охотнее создают игры, и практически нет на Android.

    Лирическое отступление
    «Эволюция» вышла в России 31 января 2014 года, 19 марта ее представили мировой аудитории на Game Developers Conference, которая проходила этой весной в Сан-Франциско, а 2 апреля состоялся международный релиз. Игра вошла в десятку лучших игр для iPad в 30 странах – и это при том, что «Эволюция» зашла на рынок практически одновременно с Hearthstone студии Blizzard Entertainment, которую с нетерпением ждали фанаты. Сегодня в нашу игру каждый день заходят более 73 000 игроков из 198 стран мира. Более 41% игроков живут в России, более 20% — в США, еще 5,7% приходятся на Великобританию.



    Сложное многообразие

    Android – платформа специфичная. Начать хотя бы с того, что у iOS всего пять разрешений экранов, что, разумеется, делает разработку приложения проще. У Android число разрешений идет на сотни, если не тысячи. С технической точки зрения, когда рисуют графический интерфейс для этой платформы, его привязывают к углам. Но иногда его растягивают, а не рисуют пиксель в пиксель – например, фоны, отчего страдает графика или нарушаются пропорции. В iOS мы всегда знаем, как у нас будет выглядеть картинка; в Android все далеко не так просто.

    На рынке Android-устройств масса различных моделей с различной производительностью, но при этом здесь контролировать установку на различные аппараты проще; например, в iOS сложно ограничить устройства, на которых приложение может запускаться. Вы можете отметить в описании приложения, что iPhone четвертого поколения его не поддерживают. При этом оно запускается на этих устройствах, в него можно играть, но, в принципе, никто не гарантирует, что оно не будет вылетать или делать еще что-то не по плану. В Android можно указывать конкретные девайсы, для которых человек скачивает игру, и выкладывать много дистрибутивов для разных графических чипов.

    Для iOS мы выкладываем один-единственный дистрибутив. Некоторые выкладывают два, один для планшетов и второй для смартфонов. В Android нужны различные дистрибутивы, которые собираются в зависимости от чипа, сжатия текстур и других параметров. В некоторых играх необходимо сделать около 5-6 различных сборок, что, конечно, усложняет процесс деплоймента приложения. Когда делается несколько дистрибутивов под разные GPU, мы загружаем их в Google Play; когда клиент скачивает приложение, цифровой магазин сам подбирает билд под GPU устройства и выдает его.

    Все графические чипы iPhone принадлежат одному семейству PowerVR, поэтому мы всегда можем очень точно предсказать производительность игры. На Android есть четыре распространенных графических чипа, которые работают совершенно по-разному. Мы столкнулись с тем, что приложение на этой платформе настолько тормозило, что пришлось переделывать шейдеры, снижать их качество или вообще отключать. В Android спекуляр считается в вершинном шейдере, а в iOS — в пиксельном. Так что мы воспользовались стандартным методом повышения производительности ценой некоторого ухудшения картинки — переносом расчетов из пиксельного шейдера в вершинный.

    Еще одна сложность, с которой мы столкнулись при портировании «Эволюции»: на Android нет совместимого со всеми устройствами формата сжатия текстур с альфаканалом (ETC1 (4bit) vs PVRTC4/2 (4/2 bit with alpha). Несжатые текстуры – это не только лишняя трата памяти и увеличение размера приложения, но еще и более длительная загрузка приложения, и потеря производительности. С технической точки зрения отсутствие сжатия текстур с альфа-каналом является очень, очень большим ограничением Android-платформы. В стандарте графического API OpenGL ES 2.0. прописан единственный формат ETС1, который уже устарел и не содержит альфа-канал. На iOS есть очень хороший графический чип: помимо того, что текстуры с ним занимают меньше памяти, они еще и быстрее грузятся. Когда вы перегружаете сцены с большим количеством текстур в игре, на iOS это происходит мгновенно, а на Android с заметной задержкой, которая в нашем случае доходила до 1.5 секунд. Увы, пришлось работать с тем, что есть, или использовать форматы сжатия, специфичные для конкретной аппаратной платформы: PVRTC, DXT, ATC, ETC. В принципе, проблему сжатия с альфа-каналом разработчики Android планируют решить в следующем стандарте OpenGL ES 3.0: там появится хороший передовой формат сжатия (ASTC), и всем сразу же станет легче жить.

    Это основные сложности при портировании приложения с iOS на Android. Были и другие проблемы, например, предельный размер APK. У Android этот показатель равен 50 Mb, при том что на iOS ограничения существуют только для cellular загрузки. iOS-версия игры представляет собой один файл размером примерно 420 МБ; на Android игра разбита на маленький APK-файл, который впоследствии догружает большой OBB-файл, в котором находится игра. Впрочем, Unity делает большую часть работы за вас.



    Как это было у нас

    У нас, можно сказать, исторически сложилось, что в первую очередь мы разрабатываем игру для устройств Apple и потом портируем ее. Конечно, можно разрабатывать игру сразу под две платформы, а можно под три. «Джаггернаут: Месть Соверинга» мы, например, выпускали еще и просто под десктопный МАС или OSX.

    Портирование с iOS на Android сильно упрощается, если игра сделана под Unity. Достаточно просто запустить ее на новой платформе – и сразу становится очевидно, где нужно пройтись напильником и что нужно доделать, чтобы результат выглядел нормально. Если игра не под Unity, то у меня плохие новости: по факту вам придется заново ее написать.

    На портирование «Эволюции» на Android у нас ушло около двух месяцев. Как я уже говорил, игра весьма сложная, как для разработки, так и портирования. Дело в том, что в ней объединены как бы несколько различных геймплеев. Персонажи передвигаются по карте, сражаются с монстрами, разгадывают загадки – для каждого из этих занятий есть свой интерфейс, своя механика. И, разумеется, все это добро грузится прямо во время игрового сеанса – то есть для нас было важно, чтобы «Эволюция» продолжала «летать» после перевода на новую платформу.

    Самая большая проблема, с которой мы столкнулись, – выдержать ту же самую производительность в бою, которая была у игры на iOS. Чтобы добиться этого, мы написали новые шейдеры, которые дали необходимый прирост скорости, несильно ухудшив картинку. Нам даже удалось спасти «честные» тени от персонажей! Переделывать графические ассеты (сцены, модели, анимацию) практически не пришлось.

    Вторая большая (и даже более трудоемкая) часть работы – 2D-часть игры, которая в «Эволюции» даже больше, чем 3D. Тысячи разрешений экрана Android (против всего нескольких у iOS) и отсутствие такого замечательного формата сжатия текстур, как PVRTC (доступного на любом устройстве iOS), приводят к большому количеству кропотливой работы. В «Эволюции» десятки экранов, фонов, флипбук-анимаций (flip book) и тысячи спрайтов, упакованных в десятки атласов. Тут пришлось что-то сжимать, что-то растягивать, что-то перепаковывать.

    Со всеми изменениями, которые претерпевает графика во время портации, вес игры меняется – в худшую сторону для Android. На iOS графика сжимается в 8 раз. Там есть совершенно чудесный алгоритм PVRTC4, который позволяет из 32-битной графики с альфа-каналом делать очень пристойного качества 4-х битную. Поскольку не всю графику на Android удается сжать так качественно, как на iOS, то она занимает больше места на диске.

    Много где требовалась ручная настройка; несмотря на то, что мы выбрали некое общее решение, пришлось немало вещей дорабатывать руками. Например, уже упомянутая проблема с различными экранами: пришлось учитывать эту особенность Android и как-то решать ситуацию. Конечно, переписывать все под каждый возможный экранчик не пришлось. На iOS у нас было всего два масштаба, оба кратные двум – именно поэтому у нас не было особых проблем нарушением пропорций и размытием графики. Как правило, в Android берут некое среднее разрешение, и все остальное масштабируют под него. Изменение разрешения в первую очередь сказывается на двухмерной графике: у нас к ней относятся различные элементы интерфейса, кнопки и прочее. Пришлось перебирать эти детали вручную, пережимать текстуры, менять размеры графических элементов в основном интерфейсе.

    Всего для «Эволюции» мы сделали четыре дистрибутива. При этом позже нам пришлось отказаться от одного из них – игра пока не поддерживает Tegra. Вообще портация на Tegra, особенно старых поколений – это целое приключение. Как правило, когда люди могут графически интенсивную 3D-игру портировать на Tegra, они потом едут куда-нибудь на профессиональную конференцию и делают об этом доклад. Это ювелирная и специфичная работа, когда разработчик добивается увеличения fps с 10 до 30, просто поменяв порядок отрисовки разных объектов на экране.



    Современные мобильные GPU с высоты птичьего полета

    Все GPU, представленные на мобильном рынке, работают немного по-разному. Их можно разделить на 3 класса: tile-based deferred rendering (TBDR) — PowerVR; tile-based rendering (TBR) — Adreno, Mali и immediate mode rendering (IMR) — Tegra.

    PowerVR со своим TBDR сильнее всего отличается от IMR, который является обычным решением для десктопов. PowerVR работает так: он разбивает весь экран на маленькие тайлы размером 16х16 пикселов и отрисовывает туда всю геометрию, попавшую в этот тайл. Это происходит в сверхбыстрой памяти, находящейся внутри чипа. В процессе отрисовки он отбрасывает все пиксели, которые не будут видны на финальной картинке (например, перекрытые другими непрозрачными объектами), и потом текстурирует и рассчитывает освещение только для тех пикселей, которые точно будут видны на экране. На сегодняшний день это одно из самых экономичных и быстрых решений, и, хотя у него есть свой набор недостатков, с точки зрения разработчиков мобильных игр он наиболее оптимален. Из очевидных достоинств он очень быстро делает альфа-смешение, антиалиасинг, фильтрацию текстур и совершенно нечувствителен к порядку отрисовки непрозрачных объектов, мип-маппингу и так далее, а замечательный формат сжатия PVRTC еще больше уменьшает нагрузку на память. Другими словами, разработчикам не нужно ничего особенно оптимизировать — нужно просто придерживаться определенного бюджета количества вершин, не злоупотреблять прозрачностью и не использовать альфа-тест, который ломает весь процесс TBDR.

    IMR рисует все, используя лишь приблизительные оптимизации отсечения невидимых поверхностей (Early Z-cull), поэтому очень чувствителен к порядку отрисовки непрозрачных объектов. Unity тут, к сожалению, ничем помочь не может — разработчик должен сам разобраться, какие объекты на сцене будут занимать больше экранного места, и сказать Unity рисовать их в первую очередь (render queue). Поскольку затеняются все пиксели, то пиксельным шейдерам достается больше работы.

    TBR чипы работают примерно так же, как IMR, но разбивают экран на тайлы для уменьшения нагрузки на память.

    NVIDIA продолжает выпускать новые виды, скоро будет уже Tegra K1, так что это вполне интересное направление, но, к сожалению, там совершенно другой подход, и из-за этого все равно будет какая-то разница при портировании. Из мелких деталей: допустим, если в iOS отключить на всех текстурах mipmap, то производительность падает на 2-3 fps. Если это сделать на Android, то производительность падает на целый порядок. Этих тонкостей очень много: если вы собираетесь оптимизировать игру для каждого из чипов, то будьте готовы к штудированию толстенных мануалов по оптимизации от фирм-производителей, долгому профайлингу и экспериментам. Кто-то делает эту работу и читает потом доклад на конференции; мы решили не копать так глубоко, а просто выбрали перечень устройств, для которых собрались разрабатывать дистрибутивы, протестировали результат и залили удачные версии в магазин. Увы, не каждый обладатель Android-устройств сможет поиграть в «Эволюцию», но мы «прикрыли» максимально возможное число устройств. В целом, игру поддерживает приблизительно 1000 мобильных устройств с Android.

    Вот и вся история. Спасибо за внимание, если у вас есть вопросы – задавайте в комментариях, c удовольствием отвечу на них.
    Mail.ru Group
    430,00
    Строим Интернет
    Поделиться публикацией

    Комментарии 37

      +9
      На втором скриншоте меня заклинило — разве «патроны» — это не «боеприпасы»?
        +2
        Патроны есть подмножество боеприпасов.

        Мне непонятно, почему «аптечки» стали боеприпасами.
          0
          Мне непонятно, почему «аптечки» стали боеприпасами.

          Для более удобной сортировки.
            +22
            Это лечебные гранаты, они наносят здоровье.
              +13
              image
              Это белёк. Он причиняет добро.
            +1
            Решили разделить для наглядности, чтобы игрок сразу видел количество своих патрон для всех типов оружия.
              +1
              Боевые припасы (боеприпас, БП) — составная часть вооружения, непосредственно предназначенная для поражения живой силы и военной техники, разрушения сооружений (укреплений), а также, выполнения специальных задач (освещения, задымления, переброски агитационной литературы и так далее).

              Патроны входят в класс «Боеприпасы», это как дельфин в класс «млекопитающее».

              Было бы логичнее назвать это все дело с патронами «Боекомплектом». Ну а если для aid-kitов лень было рисовать отдельную строку, то всяческие «гранаты» можно было бы назвать, например, «разное». В Вашем же случае название третьей строки по определению включает в себя содержание первой, что не есть хорошо и отдает халтурой.
                +2
                чтобы игрок сразу видел количество своих патрон

                http://ru.wiktionary.org/wiki/патрон
                  +2
                  Да, ошибка, прошу прощения, исправить уже нет возможности.
              +1
              Статья хороша, если не привязываться к игре. Игра чрезмерно жадная и достаточно быстро наступает момент, когда без покупок играть невозможно, а аппетит у неё весьма хороший. На iOS есть Boom Beach, вот там баланс покупок, с моей точки зрения, идеален: в игру можно играть и без покупок, но меня они соблазнили, хотя я ярый противник ingame-покупок.
                +4
                это ж мэйл ру
                  0
                  Игра чрезмерно жадная и достаточно быстро наступает момент, когда без покупок играть невозможно

                  Если почитать тематические форумы, то можно заметить, что есть много игроков, которые проходили игру полностью без доната.
                  В нашей игре мы стремимся к тому, что донат не дает преимущества, а экономит время и без него можно играть.
                    +2
                    Но ведь тут нужно обсуждать скорее статью, а не игру...
                    Я прекрасно понимаю и игроков, которые не хотят платить и Mail, который хочет денег. (знаете персонаж Лорд-Бизнес из Lego.Movie?) Но мне кажется, что в последних проектах градус доната заметно снижен и компания идёт навстречу игрокам. Вспомнить тот же Arch Age…
                      –2
                      Не упоминайте всуе этот провал.
                    +1
                    Можно самую малось поподробнее про тени? В частности про
                    Нам даже удалось спасти «честные» тени от персонажей!


                    Какие решения для теней вы использовали?
                      +5
                      Это планарные тени, самый простой алгоритм.
                      –11
                      Из вашей статьи я только понял что для вас Андройд гавно, а iOS это супер.

                      Хотя должно быть интересно решать эти мелкие задачи, ИМХО. А не ныть здесь.
                        0
                        Вы наверное хотели написать
                        «Из вашей статьи я только понял что для вас на Unity3D разработка под Android кара-смертная, а iOS development это награда. И не делиться опытом своих мук вам надобно (дабы другим помочь их избежать), а покаяться в грехах дабы лишь под iOS разрабатывать...»
                        ?
                        Мне вот интересна Unity3D в плане разработки под Android, но на руках только два устройства. А такие статьи помогают узнать что можно ожидать.
                        –5
                        Игру поддерживают 1000 устройств на Android и 7 на iOS.
                        По-моему вполне логично, что для 1000 устройств нужно несколько вариантов дистрибутивов.
                          –7
                          Поставили минус, насрали в карму, героически промолчали.
                          Где в вышеприведенном предложении я в корне неправ? Где я вообще хоть капельку неправ?
                            –1
                            Это хабр детка, тут нет места справедливости)
                          0
                          Как вы организовали поддержку 1к моделей для андроида, составляли какие-то таблицы поддерживаемых технологий для каждой модели и группировали по ним? Или у вас ферма для тестирования из тысячи трубок? Слышал, что в рамках одного коммерческого названия модели может быть целая группа устройств с совершенно разным железом, вы с таким сталкивались?
                            +3
                            Поддержка была организована путем ручной выборки. Есть определенное знание рынка и определенные характеристики, на которых игра работает. После этого были вычеркнуты все No Name устройства (их около 1200 шт) и малоизвестные бренды, затем началась ручная переборка А и В брендов.
                            Такой способ не самый лучший, но на данный момент это лучшее, чем мы располагаем, так же ежедневно открываем все новые и новые устройства по просьбам игроков, если характеристики устройства позволяют комфортно работать игре.
                            0
                            Хорошая статья, спасибо!

                            Начать хотя бы с того, что у iOS всего пять разрешений экранов, что, разумеется, делает разработку приложения проще. У Android число разрешений идет на сотни, если не тысячи.

                            Не могли бы уточнить, чем принципиально сотня разрешений/пропорций отличается от пяти? У вас же логика не на switch'е построена, который требует добавления девяноста пяти case'ов? Это просто параметры в арифметических рассчётах.

                            Но иногда его растягивают, а не рисуют пиксель в пиксель – например, фоны, отчего страдает графика или нарушаются пропорции.

                            Зачем растягивать? Фон рисуется для максимально вытянутой пропорции, всё существенное в фоне находится внутри региона минимально вытянутой пропорции. Потом fit'ится по наименьшему параметру (высота или ширина), clamp'ится вдоль наибольшего.
                              0
                              Не могли бы уточнить, чем принципиально сотня разрешений/пропорций отличается от пяти? У вас же логика не на switch'е построена, который требует добавления девяноста пяти case'ов? Это просто параметры в арифметических рассчётах.


                              У нас один набор ресурсов для ВСЕХ разрешений. Мы не делали под разные разрешения разные по качеству текстуры GUI. В зависимости от разрешения наш GUI скейлится с шагом 2, чтобы не было артефактов фильтрации (другими словами, чтобы картинка не размывалась). Поэтому правильно растянуть кнопки по углам на разных разрешениях бывает не так просто, как может показаться на первый взгляд.

                              Зачем растягивать? Фон рисуется для максимально вытянутой пропорции, всё существенное в фоне находится внутри региона минимально вытянутой пропорции. Потом fit'ится по наименьшему параметру (высота или ширина), clamp'ится вдоль наибольшего.


                              Имеется в виду, что при масштабировании фонов появляются артефакты фильтрации текстур. Вот их мы и пытаемся избежать где это возможно.
                                +1
                                У нас один набор ресурсов для ВСЕХ разрешений. Мы не делали под разные разрешения разные по качеству текстуры GUI. В зависимости от разрешения наш GUI скейлится с шагом 2

                                GUI только даунскейлится; или же он сделан не на максимальном разрешении, и для слишком «чётких» девайсов апскейлится?

                                Для интерфейса использовали NGUI, или другой фреймворк?

                                Поэтому правильно растянуть кнопки по углам на разных разрешениях бывает не так просто, как может показаться на первый взгляд.

                                Учитывали ли вы разные законы масштабирования для разных элементов интерфейса? Возьмём, например, увеличение размера экрана (независимо от разрешения, оно может при этом быть как больше, так и меньше), скажем, переход к планшету вместо смартфона. От фона логично ожидать примерно пропорционального увеличения в размерах; но что с кнопками и расстоянием до них? Ведь с увеличением экрана пальцы пользователя не стали больше и длиннее; так что плохо, если кнопки станут занимать избыточную область экрана, и уползать далеко от краёв.
                                  0
                                  1. GUI апскейлить на больших разрешениях
                                  2. NGUI
                                  3. Мы подбирали пропорции GUI для наименьшего размера/разрешения (iPhone 4). Т.е. вся верстка GUI происходила под разрешение 640х960. На iOS пропорции и расположение элементов нашего GUI не меняются практически ни на одном девайсе, только апскейлятся на айпадах с ретиной. Скейл зависит от РАЗРЕШЕНИЯ, а не от размера девайса. Поэтому на iPhone5, iPhone4 и iPad'ах без ретины масштаб 1:1, на айпадах с ретиной 2:1
                                  На андроиде с масштабированием то же самое, только пришлось эмпирически на некоторых разрешениях/пропорциях править привязки элементов GUI к разным углам/сторонам экрана.
                                  Поэтому на iPhone5, iPhone4 и iPad'ах без ретины масштаб 1:1, на айпадах с ретиной 2:1на андроидах масштабирование отдельных (не всех) элементов не кратно х1 и х2, поэтому отрисовка GUI происходит не пиксель-в-пиксель.
                                    0
                                    Скейл зависит от РАЗРЕШЕНИЯ, а не от размера девайса.

                                    Предположим, на смартфоне кнопка имеет видимую площадь (условно) 2 cm^2, на расстоянии 1 cm от края экрана. Теперь возьмём планшет с тем же разрешением, но вдвое большими размерностями (соответственно, вдвое меньшим dpi). Формально никаких апскейлов не будет, но визуально интерфейс увеличится в два раза. И теперь копка будет иметь конский размер 8 cm^2 (и прячет под собой большой кусок потенциально видимого контента), и находится на расстоянии 2 cm от края (тяжелей дотягиваться фалангой пальца, держа девайс в руках). Я правильно понял?
                                      0
                                      На андроиде масштаб не всегда кратен х2.
                                      Приведеная вами ситуация возможна только на некоторых андроидах, поэтому мы эмперически подгоняем размеры до разумных.
                                        +1
                                        Да не важно, x2, или x1.95, или x2.05. Важно, что размеры некоторых (но не всех) элементов интерфейса завязаны на внешние физические параметры: длина большого пальца, площадь касания. И НЕ завязаны на размер экрана, разрешение, dpi, форм-фактор, пропорции, операционную систему, модель, etc.
                              +4
                              Чорд, я у уж подумал что речь про
                              image

                              :)
                                0
                                Во-о-от! Я тоже был слегка разочарован :-)

                                Была где-то статья о том, что «Космических дальнобойщиков» под Android пилят, и, глядя на заголовок, я уж было обрадовался, что и «Эволюцию» тоже
                                  0
                                  О! Она классная!
                                  0
                                  Взяли UFO, упростили, добавили трехмерности и покупки — вуаля.
                                    +1
                                    Главное, покупки.
                                    –1
                                    Нечем удивить покажи сиськи!!!
                                      0
                                      Печально, но мой MSI Primo 90 на Mali-400 в список не вошел…

                                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                      Самое читаемое