В своем докладе Дэн Голдстейн поделился опытом работы над игрой Dungeon Punks, вышедшей на Xbox One, Playstation 4, Playstation Vita, PC (доступна в Steam) и веб (Flash-версия), а также рассказал о проблемах, с которыми он и его команда столкнулись в процессе портирования и выпуска игры на консолях.
Как всегда видеоверсия доклада доступна на сайте Haxe.
Dungeon Punks - Action RPG с локальным кооперативом. Это первая игра на Haxe, выпущенная на консолях.
Dungeon Punks является своего рода продолжением игры ShadowTale - web MMO на Flash, выпущенной в 2008 году. Поначалу предполагалось, что Dungeon Punks будет Free to Play мультиплеерной игрой для веб, но в процессе разработки прототипа было оказалось, что игра лучше подходит для локального коопа на консолях.
Прототип изначально писался на AS3 и использовал код из ShadowTale, но спустя 3 года разработки (где-то в январе 2015) игру перевели на Haxe, что позволило собирать игру под Flash и под Unity, благодаря чему удалось выйти и на консолях.
Трейлер игры - https://www.youtube.com/watch?v=ySOnHvQamiE
Flash-версия игры сильно урезана, в ней доступно только несколько первых уровней, а также используются текстуры низкого разрешения и сильно сжатые звуки.
Flash-версия выступает как демо для продвижения полноценного релиза в Steam.
В основном над игрой работало 2 человека: программист (в этой роли выступал Дэн) и геймдизайнер. Но на этом их роли, конечно же, не ограничивались, им приходилось заниматься и другими задачами.
Для того, чтобы игру можно было собирать под Flash и под Unity, была написана легковесная обертка для минимального набора используемых функций (графики, звука и т.д.). При этом Unity использовался не совсем стандартно - не как игровой движок и не как игровой редактор (для этого уже были написаны собственные инструменты), а как библиотека для поддержки кросс-платформы.
Все данные игры собираются в JSON, а затем для сборки билда они собираются в бинарные файлы, таким образом отпадает необходимость в парсинге данных, обеспечивается компактность и высокая скорость их загрузки.
Перед портированием имеющегося AS3 кода в Haxe сначала был переработан механизм отрисовки графики со стандартного Flash API на Stage3D API, для чего была написана обертка над Stage3D для реализации основных функций отрисовки 2D графики.
Затем с помощью AS3HX имеющийся код был сконвертирован в Haxe, при этом потребовалось множество доработок получившегося кода. Однако по мнению Дэна AS3HX является крайне полезным инструментом, и справляется со своей работой в 95% случаев.
После конвертации кода в Haxe была написана реализация библиотеки-обертки для Unity (работа с графикой, звуками и т.д.).
Так как большая часть процесса разработки игры осуществлялась под Flash (прототипирование и отладка), то одним из требований было обеспечение переносимости данных игры - они должны быть читаемыми и во Flash и в Unity.
Использование Flash в разработке имело такие преимущества как:
Однако большой проблемой было ограничение по объему видеопамяти, доступной для работы в Stage3D - всего 340 Мб. Из-за чего для flash-версии пришлось использовать текстуры низкого разрешения, а также идти на различные ухищрения в процессе разработки.
Дэн отметил, что сейчас вместо Flash он бы использовал HashLink, т.к. обладая всеми перечисленными достоинствами Flash, он избавлен от его недостатков.
Как уже упоминалось, для игры написан легковесный движок, в котором для каждой из поддерживаемых платформ реализованы следующие системы:
Для подготовки данных для игры (тексты, данные о внутриигровых предметах, цены и т.д.) использовался Excel. Перевод данных в JSON осуществлялся с помощью написанного с использованием библиотеки ExcelDNA экспортера.
Преимуществами Excel по мнению Дэна являются: простота использования (при этом не нужно быть программистом), наличие системы навигации по данным, возможность использования формул, быстрого редактирования больших объемов данных. Также если использовать xml-формат для сохранения Excel-файлов, то такие файлы можно хранить в системе управления версий.
Хранение формул в Excel позволяет не “зашивать” их в исполняемый файл, а парсить на лету, при этом отпадает необходимость постоянной перекомпиляции клиента (при каждом изменении формулы, подгонке коэффициентов в ней) и сокращается время, потраченное на баланс игры.
Для управления JSON-файлами, полученными на выходе из Excel (а также написанными вручную), был написан “компилятор данных” (написан на Haxe, скомпилирован в Adobe AIR). Данный инструмент выполняет следующие функции:
Кроме того была создана система автоматической сборки данных игры, которая поддерживает данные в актуальном состоянии, постоянно обновляя и контролируя наличие в них ошибок. Данный инструмент позволил еще больше сократить время на баланс игры.
Кроме того преимуществами использования формата JSON является то, что:
В итоге JSON используется для хранения всех возможных данных:
Валидатор данных, которые хранятся в JSON, почти полностью написан на Haxe (собирается как Adobe AIR приложение), за исключением небольшого приложения на C++, которое отслеживает изменения в файлах и запускает проверку данных, если изменения имели место.
Как уже упоминалось, этот валидатор данных используется системой сборки данных игры, который кроме проверки данных осуществляет их подготовку к использованию в игре, упаковку текстур и т.д.
Для того, чтобы избежать относительно медленного процесса парсинга JSON’ов, используются собственные сериализаторы / десериализаторы данных, способные сохранять и читать данные в бинарном формате.
Кроме того, так как чтение с жесткого диска консоли также происходит довольно медленно, то бинарные данные упаковываются не как попало, а объединяются логически. Например, подготавливаются отдельные паки данных, используемые при запуске игры, при начале каждого уровня, при старте кат-сцены и т.д. Таким образом, эти паки данных можно быстро загружать и выгружать из памяти только тогда, когда они действительно необходимы.
Использование Unity в качестве библиотеки для поддержки консолей возможно благодаря работе Caue Waneck, который добавил в Haxe возможность генерации кода в C#, а также написал библиотеку UniHX. Эта библиотека анализирует dll-файлы редактора Unity и генерирует extern’ы для классов Unity, таким образом появляется возможность работы с этими классами в Haxe коде (при этом доступны проверка типов и автодополнение).
К сожалению работа над библиотекой прекращена, так как Caue переключился на Unreal Engine, но ее текущая версия вполне работоспособна, и Дэну практически ничего не нужно было изменять в генерируемом коде.
При работе с Unity из Haxe Дэн столкнулся с проблемами, связанными с Generic-классами (в C# и Haxe работа с Generic’ами отличается), например, при загрузке ассетов. Однако эти проблемы не были нерешаемыми, и для них были найдены обходные пути.
При написании библиотеки-обертки для API их игрового движки также возникли затрудения, связанные с тем, что в Unity не всегда есть прямые аналоги требуемых методов, а если они есть, то они могут оказаться не самыми производительными из доступных методов. Например, в Unity есть CommandBuffer API, которое дает доступ к списку команд для отрисовки графики. Но на тот момент, когда Дэн пробовал им воспользоваться (примерно в середине 2016 года), он показал крайне низкую производительность, поэтому от его использования пришлось отказаться.
Кроме того, когда вы нашли казалось бы подходящее вам API, которое показывает хорошие результаты на вашей машине, то не следует радоваться раньше времени, т.к. этот же код может работать гораздо медленнее на консолях, поэтому необходимо проверять производительность выбранного API везде, где его планируется использовать. Этот опыт проб и ошибок при подборе нужного API оказался наиболее болезненным в разработке игры, которая должна работать в веб, на PC, стационарных и мобильных консолях.
В качестве еще одного примера поиска подходящего решения для отрисовки графики Дэн привел реализацию цветовых трансформаций объектов, они хорошо работают во Flash, прекрасно реализуются, если вы работаете с низкоуровневым 3d API (например, в OpenGL), но в случае Unity это приводило к крайне низкой производительности. И для решения этой проблемы в Unity пришлось использовать кеширование множества объектов (материалов) в огромных пулах, где каждый объект немного отличался от других степенью градации цвета.
Кроме этого, в случае PS Vita, как наиболее слабой консоли, было необходимо ограничивать общее число draw call’ов (это актуально и для других мобильных платформ).
Дэн также отметил, что отладка C# кода, сгенерированного из Haxe, возможна, но это не самое приятное занятие, особенно если сравнивать с отладкой Flash. Поэтому он старался избегать этого :)
Кроме описанных проблем, связанных с использованием Haxe, также есть проблемы, связанные непосредственно с Unity:
Далее Дэн поделился опытом взаимодействия с платформодержателями и описал процесс сертификации игры, а также перечислил проблемы, связанные с производительностью игры на консолях.
Все подробности рассказать он не смог, так как они находятся под NDA (соглашение о неразглашении), однако, его доклад дает общее представление о процессе разработки под консоли. Если вам интересна эта тема, то могу посоветовать еще один доклад с о портировании игр, написанных на Unity.
У компаний-платформодержателей (Microsoft, Sony, Nintendo, Valve) разный подход к взаимодействию с разработчиками, но Дэн дал ряд общих советов по этой теме:
Далее Дэн рассказал о деталях процесса сертификации. Не пройдя сертификацию вы не сможете получить доступ к SDK и DevKit’ам, то есть не сможете даже приступить к портированию игры.
Процесс сертификации подразумевает оформление множества документов и заполнения огромного количества форм на веб-сайтах платформ.
Для того, чтобы получить доступ к SDK и DevKit’ам необходимо пройти предварительное одобрение, для которого необходимо подготовить дизайн документ, описание игры и возможно прототип. Этот процесс может занять несколько месяцев, но если ваша игра уже вышла на другой платформе и оказалась очень популярной, то это может ускорить процесс одобрения.
Для оформления заявки также понадобятся всевозможные идентификаторы: игры, издателя, сервисов, которые игра использует и т.д. Эту информацию необходимо как-то хранить и отслеживать.
Для того, чтобы вашу игру смогли оценить, нужно предоставить не только ее, но и сохранения, позволяющие продолжить игру с определенного места.
Если в игре реализованы достижения (на некоторых платформах, например в Steam, они не обязательны, но иметь их крайне желательно), то нужно иметь в виду, что на разных платформах к достижениям предъявляются разные требования (размеры и вид изображений, количество очков, которые дает достижение, количество всех достижений в игре, даже список действий, которые могут считаться достижением).
Когда игра близка к релизу понадобится подготовить материалы для ее размещения в сторах:
Кроме того, вам может потребоваться подготовить ключи для прессы, причем часто для каждого региона нужно предоставить отдельные ключи. А для того, чтобы можно было подготовить ключи для прессы, необходимо чтобы игра уже была сертифицирована.
Важно помнить, что всю эту работу нужно проделать для каждой платформы, на которой вы собираетесь выпустить игру, а иногда даже для каждого региона!
Для релиза на консолях необходимо, чтобы игре был назначен возрастной рейтинг, при этом в разных регионах действуют разные системы рейтинга с разными требованиями. Например, для того, чтобы подать заявку на получения рейтинга PEGI (европейская рейтинговая система), необходимо сначала пройти тест.
В США рейтинг можно получить бесплатно, заполнив анкету на сайте агентства. В остальных регионах для этого придется заплатить и потратить больше времени.
Также одна и та же игра может получить разные возрастные ограничения в разных регионах, это также нужно учитывать. В Dungeon Punks, например, пришлось удалить всю кровь для европейской версии игры.
И конечно вам потребуется предоставить рейтинговым организациям материалы для оценки:
Для того, чтобы игра прошла сертификацию, необходимо чтобы она соответствовала множеству требований, которые предъявляют платформодержатели. При этом эти требования охватывают все возможные аспекты:
Списки этих требований насчитывают тысячи пунктов и у каждого платформодержателя они свои. Некоторые требования простые, другие очень строгие, некоторые могут не иметь для вас смысла, а в некоторых случаях вы даже не сможете сразу понять, распространяются ли эти требования на вашу игру или нет.
Для проверки соответствия этим требованиям имеются автоматизированные инструменты.
Так как требований, предъявляемых к игре, множество, то сам процесс сертификации может занять длительное время - с первого раза пройти его обычно не удается. И это также необходимо учитывать. В качестве примера Дэн рассказал о разработчике, с которым он встретился на выставке PAX East - для него процесс сертификации игры на Xbox One растянулся на целых 8 месяцев, хотя сама игра технически была готова и оттестирована.
Дэн посоветовал воспользоваться следующим приемом, чтобы выяснить какие проблемы есть в игре в отношении сертификации: попробовать послать на сертификацию не полностью готовый, но рабочий билд игры. Так вы сможете хотя бы примерно узнать список требований, которым ваша игра не соответствует.
Далее Дэн рассказал о проблемах с производительностью в C# коде, сгенерированном из Haxe:
Для нахождения этих слабых мест использовался Unity-профайлер, который помог решить большинство проблем. Но так как в результате игра запускается не на PC, на котором осуществлялся профайлинг, а на консоли, то всех проблем решить с его помощью все-таки не удалось.
Также Дэн отметил, что к сожалению C# код компилируется в разы дольше, чем Flash.
При разработке под консоли на Unity также нужно иметь в виду следующие моменты:
Подводя итоги, Дэн отметил, что несмотря на все перечисленные проблемы, использование Unity очень сильно помогло при разработке игры под консоли. После того, как у него на руках были билды игры для Playstation 4 и Vita, ему с первого раза удалось запустить игру и на Xbox One.
Также на форумах Unity вам могут помочь в решении часто возникающих проблем.
Однако, если у вас возникла очень специфичная проблема, то решить ее скорее всего придется самому, возможно написав для этого плагин на С++.
И конечно же при использовании Unity придется потратить много времени на оптимизацию игры, особенно в отношении генерации мусора и потребления памяти.
Главные моменты, которые необходимо иметь в виду при разработке игры на Haxe под консоли:
Говоря о следующем проекте, Дэн предположил, что использовал бы для него связку HashLink и Heaps, так как эта комбинация обладает следующими плюсами: