Pull to refresh

Непостмортем игры «Roads of Rome» («Дороги Рима»)

Reading time10 min
Views4.8K
В данной статье я хочу кратко рассказать о разработке казуальной игры «Roads of Rome» («Дороги Рима»).
Возможно это будет интересно тем, кто только собирается заняться разработкой игр. Собственно о программировании будет мало, больше о том, что использовалось в процессе разработки.


Кратко об игре

«Roads of Rome» — это казуальная игра жанра клик-менеджер/стратегия. Основная цель — построение дороги. Попутно придется разбирать завалы, ремонтировать/строить/улучшать здания.
В разработке игры использовался PopCap Framework.


Кратко о себе

Сразу уточню, что я не начинающий разработчик. Ранее я работал в компании, занимающейся разработкой игр. Именно там я увидел и прочувствовал на себе процесс создания игр. И этот опыт мне очень пригодился. Многие вещи кажутся неважными до тех пор, пока сам с ними не столкнешься. Поэтому перед началом разработки рекомендую вдумчиво поразмыслить над самыми различными проблемами и решениями этих проблем, над выбором инструментов, с которыми собираетесь работать, над тем, какие требования предъявляются к вашей игре издателем и т.д.

О роли в проекте

В данном проекте я участвовал в роли программиста в составе команды Whiterra. Арт, музыка, дизайн уровней и т.д. выполнялись другими людьми. Разработка велась в удаленном режиме и заняла примерно полгода календарного времени.

Разработка

Коммуникации в проекте велись в основном через Skype, иногда Jabber.
Список задач велся в Google Docs. Расшаренный документ, в котором нумерованный список, а приоритеты задач определяются цветом фона строки.

Несмотря на мой первичный скептицизм, данный метод работы оказался не так уж и плох. Даже в чем-то удобен (вот еще бы проритеты выставлять одним кликом). Да, никакой истории багов и фич, но зато работает довольно быстро и просто и не нужно держать свой сервер. Для проекта такого уровня с одним программистом этого вполне хватает.
Код и арт я храню в бесплатном SVN-хранилище (там квота в 500Мб, мне хватает).

Проект мультиязычный, существует русская и английская версии. Текст задается во внешнем XML (стандартно для PopCap Framework), поэтому для русской версии просто заменяется текст и некоторый арт с названием игры. Но т.к. иконки в ресурсах и текст, отображаемый в свойствах файла, разные, то есть два типа сборки для этих целей: Release (английская) и ReleaseRus (русская).

Финальная сборка проекта делается с помощью MSBuild. Он идет с .NET Framework, я использую версию из .NET 4 (версия из 2-ого .NET не захотела работать с '.sln' от Visual C++ 2008 Express). Делается это так:

msbuild Game.sln /t:rebuild /p:Configuration=Release
msbuild Game.sln /t:rebuild /p:Configuration=ReleaseRus


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

Еще есть необходимость отправлять исходники. Чтобы упростить данную задачу был написан скриптик на Python (который я только начал изучать и уже рекомендую к ознакомлению как очень полезный, простой и удобный инструмент), который упаковывает в ZIP-архив файлы из указанной директории, предварительно отделив зерна от плевел по фильтру файлов и папок.

Программирование

Разработка игры велась под Windows на известном и хорошо зарекомендовавшем себя PopCap Framework.
В качестве IDE выбрана Visual Studio 2008 Express (C# и C++ версии). На С++ разрабатывалась сама игра, на C# тулсет к ней (редактор уровней, редактор комиксов и мелкие утилиты).
Редактор делался в спешке, поэтому мог быть и получше, но, что имеем, то и жнём.
Уровни хранятся само собой в XML, удобно, учитывая, что создаются уровни в C#, а читаются в C++.
Почему C#? Потому что разработка на нем быстрее, компиляция быстрее (в сравнении с C++), визуальный редактор удобен, есть собственные старые наработки. Ну и строже язык, не дает выстрелить себе в ногу случайно.


В игре активно используются контейнеры STL (в основном это vector, map и hash_map из STLPort). Boost не хотел использовать принципиально, может быть и зря.


Касательно самих игровых сущностей интересна, наверное, дорога — она рисуется по кривой-сплайну. Кривая строится по опорным точкам, затем относительно нее (по нормалям в каждой точке) строится «лента из треугольников». А потом данная лента текстурируется. Таким образом получается, что текстура для дороги небольшая и подходит для нескольких уровней. В процессе разработки выяснилось что данный вариант смотрится не очень хорошо, т.к. свет в игре на все объекты падает всегда из одной точки, а вот повернутая текстура не вписывается в данную картину. Чтобы решить проблему пришлось сделать программный предрасчет освещения по карте высот дороги (обычный олдскульный бампмаппинг) и вторым проходом рисовать правильное освещение на дороге. И никаких шейдеров (а откуда им взяться в DirectX 7).

Вода сделана совсем просто. Сначала рисуем «дно», затем протяжку текстуры воды, затем по маске рисуем сушу.

Погодные явления (дождь/снег/песчаная буря) создаются обычными самописными 2D-частицами.

Землетрясение сделано тоже довольно просто — часть уровня отрисовывается в отдельный буфер (к сожалению программно) и после накладывается с полупрозрачностью на экран, смещая координаты отрисовки по синусу в некотором диапазоне. Вместе с соответствующим звуком получается довольно хорошее дрожание поверхности.

Само игровое поле поделено на клетки 16x16 пикселей, по которым происходит поиск пути, перемещение юнитов, расположение игровых элементов. Кстати про поиск пути. Для поиска пути юнитов используется A* (библиотека указана ниже). Для определения доступности игровых элементов используется волновой алгоритм (простейшая ромбовидная волна). Просто и удобно.

Для удобной работы с контролами в диалогах пришлось написать обертку, которая контролы, их положение и параметры грузит из XML. Из-за этого пришлось немного перетряхнуть систему контролов PopCap Framework (избавиться от int идентификаторов и перейти на string идентификаторы). Но оказалось удобно, жаль времени написать редактор не было, но это всеравно удобнее, чем положение кнопок в коде менять, а потом каждый раз перекомпилировать.

Для удобной настройки твининг эффектов (плавные движения с замеделением/ускорением) сделал их настройку тоже во внешних XML.

По собственному опыту скажу — старайтесь максимум настроек выносить во внешние файлы, чтобы, изменяя что-то мелкое, не приходилось запускать компиляцию проекта (это отъедает от 30 секунд до 10 минут времени в зависимости от проекта и характера изменений). И очень желательно, чтобы в игре можно было перезагружать внешние настройки, не перезапуская игру (экономия от 20 секунд до минуты в зависимости от количества изображений в игре). Это кажется мелочи, но когда приходится раз 5-10 отредактировать какой-то параметр (хорошо, если один), то очень быстро натекает существенное время, да и постоянные паузы в работе не способствуют хорошему настроению.
Прикрутить скрипты не успел, правда в начале проекта не было понятно что именно нужно скриптовать, а в конце проекта уже не было времени на это.

Сторонние библиотеки

В редакторе использован Grid-контрол SourceGrid. А чуть позже была задействована библиотека OpenTK (кстати недавно вышла версия 1.0).

В самой игре использовались:
  • STLPort — в представлении не нуждается
  • MicroPather — поиск пути, очень понравился, работает великолепно. OpenSource (zlib/libpng License)
  • PugiXML — быстрый XML-парсер. Удобен и прост в использовании. OpenSource (MIT License)
  • yasper — «A non-intrusive reference counted pointer». Спас меня от поиска большинства возможных утечек памяти. OpenSource (zlib-license)
  • CppTweener — удобный твинер, подобный функционал понравился еще в ActionScript, и раньше очень не хватало аналога в C++. OpenSource (MIT License)
  • PopCap framework — комментарии ниже. OpenSource (своя лицензия)
  • Pyro effects — движок для эффектов частиц. Proprietary, платная (бесплатно для первой игры)
  • Bass.dll — звуки и музыка. Proprietary, платная

Думаю интересно будет написать немного про каждую библиотеку отдельно, ибо есть чего.

PopCap Framework

Данный старожил был выбран по нескольким причинам. Во-первых так хотел заказчик, потому что уже имел опыт работы с данным фреймворком. Во-вторых я сам имел достаточный опыт работы с ним и знал что это за зверь и с чем его едят.
Не слушайте школоту, которая говорит, что такой фреймворк пишется за месяц работы. Данный фреймворк предоставляет вам множество удобств: менеджер ресурсов, загрузка ресурсов в отдельном потоке, система виджетов и контролов, отслеживание утечек памяти, система рендеринга битмап-шрифтов, упаковка множества ресурсов в один PAK-файл, встроенный XML-парсер, встроенный профайлер, stack-trace, простой и удобный API, код фреймворка учитывает множество «особых» ситуаций и много-много чего еще.
Конечно, не все в нем идеально. Чтобы работать с русскими символами — придется немного «пропатчить и заапдейтить» (©«Магазинчик Бо»). Встроенный парсер имеет ошибки, их тоже придется исправлять. Ну и самое плохое, что PopCap перестал обновлять данный фреймворк. Впрочем, есть неофициальная версия фреймворка 1.34 — в ней исправлены некоторые недочеты (как минимум парсер и русские символы). Но остается самый главный недостаток: фреймворк написан для DirectX 7, и Windows Vista/7 имеет некоторые особенности при работе с таким антиквариатом. К тому же ATI/AMD и NVidia в своих драйверах поддерживают DX7 по остаточному принципу и из-за этого у многих пользователей возникают проблемы. Одно время на ATI-картах вообще было невозможно играть (отображался черный экран), потом, правда, вышел нормальный драйвер. На NVidia с какой-то версии драйверов (в Vista/7) перестала определяться поддержка 3D, поэтому игра шла в Software-mode и, соответственно, сильно тормозила. Поэтому на данный момент я вынужден констатировать, что разрабатывать на PopCap Framework больше нельзя — круг неразрешимых разработчиком проблем слишком широк.
Для интересующихся замечу, что существует неофициальный форум по PopCap Framework.
Так же существует версия фреймворка, являющаяся оберткой над движком Kanji, называется SexyKanji и имеет схожий на 98% API. В ней решены проблемы устаревания (т.к. работает на DirectX 8/9 или OpenGL). К тому же фреймворк кроссплатформенный, что не может не радовать. Сама надстройка SexyKanji по прежнему OpenSource, но движок Kanji платный (что-то около 300$). SexyKanji хорош, но при переходе на него некоторые вещи придется «допиливать». Так же появилась информация, что движок продан другой компании и теперь, равная по функционалу версия, будет стоить уже 1000$ (к тому же это только на одно рабочее место).
Есть еще версия PopCap Framework, для работы на платформах, отличных от Windows — это TuxCap Framework, но пока времени не было его посмотреть, если кто использовал — опишите свой опыт в комментариях.

Возможные бесплатные альтернативы для разработки игр:
  • HGE — из плюсов: DirectX8. Из минусов: DirectX8 — будут проблемы на Vista/7, не кроссплатформенный, слишком низкоуровневый (ИМХО), вроде тоже давно не обновляется, мне не нравится :)
  • Playground SDK — из плюсов: обновляется, кроссплатформенный, навороченный. Из минусов всего один, зато какой: исходный код самого движка закрыт и если вы наткнетесь на какой-то баг в движке, то вам остается только ждать исправления, сами вы решить проблему вряд ли сможете


STLPort

Замена MS STL. Зачем? Затем, что работает быстрее, памяти потребляет меньше. Стабилен и не вызывает никаких нареканий. Рекомендую.
Настолько с ним свыкся, что чуть не забыл написать про STLPort.

Micropather

В самом начале работы над проектом на форуме, посвященном PopCap Framework, была найдена библиотека для поиска пути: AStar Library.
Возможно у меня руки кривые, но нормально работать я ее заставить не мог. Она находила путь, но уж очень он был не оптимален. Решено было искать другой «пасфайндер». Таковым стал Micropather. Сначала были проблемы из-за кэширования пути, но возможно это я где-то забывал сбрасывать кэш. Но после отключения кэша все заработало как ожидалось. Библиотека простая, нужно подключить только заголовочный файл. Рекомендую.

PugiXML

Я использую этот парсер, чтобы считывать все свои XML (кроме тех, что стандартны для PopCap Framework). Не использую встроенный, т.к. он не очень удобен и я не уверен, что в нем нет еще каких-либо ошибок. Ну и к тому же PugiXML — один из самых быстрых парсеров, а скорость — это хорошо :)

CppTweener

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

Yasper

Просто хороший и очень умный указатель. Главное перекрестных ссылок не делать, иначе не сработает, проверено :) Но PopCap об этом напишет в mem_leaks.txt (в Debug режиме).

Bass.dll

В самом начале жизни проекта использовалась Audiere.dll. Бесплатна, держит необходимый функционал, позже даже нашел AudiereMusicInterface для полной интеграции с PopCap Framework. Все бы хорошо, но на некоторых хитрых конфигурациях падает. Просто и внезапно падает. У меня на Athlon 64 X2 и Windows XP иногда падало. Решено было перейти на платный Bass.dll. Работает вроде хорошо (есть один не фатальный бажок, но его можно терпеть). Использую версию 2.3.0.3 — предыдущие имеют серьезные баги, а для более новых нужно переписывать поддержку библиотеки в PopCap Framework.
Данная библиотека бесплатна для некоммерческого использования.

Pyro Effects

Сначала для эффектов решено было прикрутить эффекты от другого OpenSource фреймворка — от HGE. Основной мотив — существование стороннего порта движка эффектов на PopCap (SexyHGEparticles) и бесплатного редактора эффектов от HGE. Практически сразу стало ясно, что нормально использовать ЭТО нельзя. Редактор нестабилен, да и сделать в нем что-либо сложное невозможно. А порт движка эффектов работает не так, как в редакторе, в результате чего эффекты вели себя странным образом, словно у них гравитация в игре слабее, однако исправить это сходу не получилось.
Так длилось некоторое время. В какой-то момент без нормальных эффектов было уже нельзя продолжать работу, поэтому я занялся изучением других библиотек и редакторов эффектов к ним. Что нам было нужно: простая интеграция в PopCap Framework и возможность создавать сложные эффекты.
Сначала был рассмотрен Magic Particles. Вроде мощный редактор, большая база сэмплов с довольно сложными эффектами. Начал я его прикручивать. Не помню уже почему я полез смотреть как он грузит изображения. Но когда увидел, что при создании эффекта он сначала сохраняет изображение на диск, и лишь затем загружает его в память (это верно для PopCap Framework, с другими движками все может быть иначе)… От такого решения я сразу отказался, ну не доверяю я таким «хакам», а писать нормальную поддержку у меня не было ни сил, ни желания. Хотя редактор выглядел интересно.
Следующий испытуемый Pyro. Прикрутить систему эффектов оказалось довольно просто, тем более, существовал небольшой враппер для PopCap Framework. Редактор тоже вполне себе. Но в результате использования выяснилось следующее: не все эффекты в игре выглядят так же, как и в редакторе (визуально — что-то не так с опциями сложения цвета), не все эффекты работают в игре, несмотря на то, что они работают в редакторе (может и я что-то не так делал, но включение некоторых опций в эффекте приводит к неотображению эффекта в игре). Т.к. возиться времени больше не было, и Pyro нам больше подходил, чем не подходил, решили остановиться на нем.

SPARK. Есть еще такой движок для эффектов частиц. К нему в сети даже есть OpenSource редактор. Но нашел я его много позже (да и вышел он позже, чем мне требовалось). Использовать пока не удалось, редактор сходу не скомпилился (каких-то dll не хватало). Если кто использовал — расскажите как оно вам.

Для эффектов дождя/снега/песчаной бури использовались свои собственные частицы, так оно оказалось проще и универсальнее.

Вместо заключения

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

Ну и ссылка на саму игру.
Tags:
Hubs:
+83
Comments79

Articles