Писать моды для RTS: это вам не конфиги дергать

О чем статья

Я расскажу вам о своем пути в моддинге игры, о применении геймдизайна в разработке контента и о технических подробностях игрового движка. А также дам советы по созданию своего контента в любой игре!

Я правда очень люблю роботов

Я правда очень люблю роботов

Planetary Annihilation — хорошая игра

Planetary Annihilation — моя первая RTS, в которую я осознанно играю на протяжение года. Стратегия завлекла меня своими круглыми картами и большим количеством юнитов на поле боя.

Уже в процессе познавания азов ведения боя, я приметил наличие множества крупных модификаций, созданных сообществом и разработчиками игры. Да, не удивляйтесь. Разработчики сами выпускали полезные моды, которые не вошли в основную сборку, так называемую ваниллу, но были выложены в общий доступ.

Спустя месяц я понял, что играть в базовую версию игры мне не интересно. А новая фракция и крупное дополнение так и манили меня новым контентом! «Хорошо, заряжу игру по максимуму и посмотрю как всё это играется вместе» — подумал я в сильном предвкушении.

Оказывается не всё так хорошо

Поиграв со свежими для меня модификациями я увидел серьезную проблему. Да, в игре есть новый контент от сообщества, но ни один мод не интегрирован полностью с другими модами. Это ведет к тому, что страдает баланс, пользовательский опыт и поддержка. Ведь ничтожно мало моддеров задумывается о геймдизайне в целом!

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

Естественным образом возник вопрос «Почему самый популярный контент до сих пор имеет проблемы с игровым процессом?»

«Ждать крупных изменений год и более — это норма, всегда так было» — группа текущих моддеров

Что мешает сделать всё «правильно»? Причины на самом деле банальные.

Некоторые авторы могут уходить в отпуск или терять интерес к игре и проектам соответственно. Кто-то считает себя волком одиночкой и категорически не коммуницирует с другими авторами. Кому-то не хватает навыков и на руках есть лишь бомбическая идея

Ко всему этому можно добавить, что даже при желании никто не сможет просто так внести изменения в чужой контент без согласия автора, который удалил все свои соцсети и начал жить в горах (не шутка)!

И всё это приводит к следующим трагичным последствиям:

  • Модификации имеют проблемы

  • Люди создают модификации решающие проблемы других модификаций

  • Модификации не интегрируются друг с другом и в конечном счете проблемы не решаются

Как я дошел до этого сам не понимаю. А главное зачем?!

Как я дошел до этого сам не понимаю. А главное зачем?!

Остались только голоса

Хорошо, Я тут и готов решать проблемы! У меня за спиной 1000 часов в игре и о разработке игр что-то знаю. Имею право

«Документация по моддингу PA — это в основном оральная традиция» — группа активных моддеров

Документации нет и не было никогда. Все знания передаются оральным способом. За всё время существования игры никто так и не собрал полную документацию по всем техническим аспектам. Я не уверен есть ли она у команды разработки, ведь ведущие разработчики это отдельный разговор.

За 10 лет у игры сменился владелец и три команды разработчиков: оригинальные авторы, супер продуктивный мужик с характером и тихая группа поддержки. Последняя в свою очередь по некоторым причинам, вдаваться в которые значит погружаться в бездну интриг, работает с около нулевой базой и большую часть времени пытается разобраться как запускается эта волшебная игра. Звучит не очень привлекательно для начинающего мододела, правда?

И хотя стартовые условия выглядели удручающе, однако луч света, а в месте с ним и надежда, оставались! В сообществе всё ещё есть древние мастера и носители знаний. Изучая их творения, я примерно понял как функционирует игра и её механизм поддержки модификаций. И только я собрался делать моды, как осознал что могу сделать большее чем очередной мод! Но что?

0000000000000000000000000000000110000000000000000000000 - build_pattern

0000000000000000000000000000000110000000000000000000000 — build_pattern

Я — Reverse Engineer?

Если Я собрался решать проблемы, то до создания модификаций ещё полно дел, требующих внимания! Первостепенно нужно соединить все потерянные фрагменты информации в единый том документации, дабы постичь магию движка и передать знания потомкам НЕ оральным способом. Хорошая идея, как исполнять?

Грандиозная работа состояла из постоянных пингов опытных ребят, просмотра клиентской
части игрового движка и расшифровки записей json-конфигов.

Planetary Annihilation использует свой супер-дупер кастомный движок 2008–2013 годов, написанный на языке C++, это то что касается серверной, backend, части. А вот для отрисовки всего интерфейса применяется Knockout.js, который возможно был приемлемым решением в те годы, однако сейчас эта технология головная боль и для моддеров, и для текущей команды разработчиков.

Ресурсы

Ресурсы — это весь игровой контент, начиная с иконок и заканчивая исполняемым кодом. Они находятся в открытом доступе и в сыром виде, т.е. игра их не упаковывает и не сжимает как это сделано, например, в unity.

Исходные файлы одного из внутриигровых экранов

Исходные файлы одного из внутриигровых экранов

Весь клиентский код, интерфейс, написан на JavaScript и свободен для редактирования, впрочем как и любой другой файл. Игра даже пропустит вас в рейтинговый матч с измененными исходниками. Для разметки интерфейса используются HTML и CSS файлы.

Изображения и иконки

Изображения и иконки

Основной и единственный формат для изображений — это PNG. Можно заменить существующие иконки или картинки на свои.

Исходный текст и локализованный вариант

Исходный текст и локализованный вариант

Файлы локализации используют формат JSON для сопоставления исходного текста и локализованного варианта. Сделано всё очень прямолинейно. Каждая строчка текста — это отдельное поле/свойство в json-объекте. Все эти поля при инициализации загружаются в единый «словарь» и достать их можно путем вызова метода LOC («исходный текст»). Разделение на языки происходит путем перемещения файла в папку с названием языка, например »/locales/en/…; /locales/ru/…; /locales/cz/…».

Часть кода шейдера для освещения

Часть кода шейдера для освещения

Шейдеры все аккуратно сложены в одной папке и могут быть отредактированы для желаемого эффекта. Они написаны на языке HLSL и хранятся в двух файлах каждый. Первый файл отвечает за fragment_shader (*.fs), второй — за vertex_shader (*.vs). Многие профессиональные игроки редактируют шейдер обломков, чтобы лежащий на земле металл подсвечивался ярким желтым цветом.

Json-конфиг юнита

Json-конфиг юнита

Юниты, постройки, вооружение, эффекты и биомы определяются в JSON файлах. Игра сама определяет какую модель данных описывает json-конфиг. Также не возникает проблем с тем что файл может лежать в случайной папке, ведь при загрузке каталоги просматриваются до последней папки, в глубину.

Интерфейс

Cтоит отметить, что основное преимущество веб‑интерфейса в игре — это полная кастомизация любого UI элемента. Приятным бонусом идет возможность применять изменения на ходу, прямо во время матча. Достаточно нажать заветную кнопку F5 и вот вы уже совершенно с другим интерфейсом!

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

Один из моддеров даже написал бота, управляющего юнитами и заводами игрока, отдающего приказы войскам и имеющего план действий. Встроен этот бот в интерфейс, т.е. он работает с помощью JavaScript кода и похож по механике на Selenium. Правда, такая разработка остается в архиве у автора по понятным причинам.

Юниты, оружие и боеприпасы

Особенностью настройки игрового контента является система наследования у JSON файлов. Это значит, что, чтобы изменить какой-то параметр у юнита, достаточно указать базовый json-конфиг и затем отредактировать требуемое поле. Это очень помогает при наличии более сотни видов вооружения, боеприпасов и юнитов, многим из которых достаточно переопределить базовые поля для полного функционирования.

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

Поддержка модификаций

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

В игре есть встроенный Workshop. Он позволяет моддерам загружать моды на Github, что очень удобно. Причем достаточно загрузить лишь исходные файлы проекта, без надобности в создании архивов! Уже в самой игре workshop скачает мод с github и упакует как ему пожелается.

Также присутствует поддержка локальных модов, что помещены в специальные папки: «server_mods» и «client_mods». Однако стоит учитывать неспособность игры воспринимать кириллицу в пути к файлам.

Приоритет загрузки нужен для определения главенства в редактировании контента. Два мода не могут одновременно применить изменение к одному файлу. Это, кстати, ведет к тому что моды, затрагивающие один и тот же файл будут перезаписывать друг друга. Однако, JavaScript кода это не касается — игра будет соединять его в один большой файл.

Получив базовое понимание работы движка игры и её ресурсов, Я приступил к следующему шагу. А именно написанию документации по каждому аспекту моддинга! Естественно завершить всё хотелось за неделю с минимальными жертвами…

Оптимистично, правда?

Зачем?

Зачем?

Я — Технический писатель?

Ох, каким крутым Я чувствовал себя, приступая к работе! Никто до меня не додумался собрать все знания в одном месте, вот глупцы! На второй день настроение резко изменилось и появилась осознанность происходящего. Это не люди глупые, а Я — джуль.

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

Выключаться на больше чем две недели я не мог и не хотел и поэтому принял следующие важные решения:

  • Определить приоритет знаний по используемости в моддинге

  • Найти контакт со всеми продвинутыми моддерами

  • Оптимизировать процесс выявления поведения у свойств объектов

Самыми приоритетными областями оказались оружие, юниты и здания. Огромным плюсом оказалось то, что все эти игровые объекты модифицируются через JSON. Это значит, что я могу с легкостью проверять какое-либо поведение, изменяя параметры в конфиге и наблюдая за новым поведением в игре. Правда?

Нет не правда! Мне было впадлу ожидать запуска игры и матча для проверки каждого свойства объекта. К тому же многие параметры названы так, что по имени можно лишь догадываться что произойдет.

Discord мне в помощь, а вместе с ним и древнейшие из моддеров, что познали тайны глубинные и создали не один десяток модов. Ох, как же я долбил их по каждому свойству. За день от меня могло прилететь по 5–10 пингов и личных сообщений. Но ради великой цели можно и потерпеть!

Ребята очень сильно мне помогли в наполнении документации и объяснении «неожиданных» поведений. Как оказалось в игре присутствуют баги и глюки, пережившие всех разработчиков.

Насколько я понял, люди иногда уходят спать, есть или просто отключаются из сети. В это время я один и спрашивать что-либо можно только у самого себя. Приходилось самому читать json-конфиги и «получать понимание» о природе параметров.

Самое время упомянуть, что у меня есть опыт разработки игр и опыт анализа исходников разных проектов

Для «получения понимания» у меня было всего два способа: по названию параметра и по названию параметра. Первый был легок, ведь достаточно было прочесть название и всё сразу становилось понятно. Второй был сложен, но интересен своим подходом! Нужно было по названию параметра представить о чем думал разработчик и найти всевозможные пути его мысли. Как Доктор Стрендж продумывал вариации будущего, также и Я воображал что творилось в голове у разработчика десять лет назад!

Завершить первый том самой проверенной и протестированной документации удалось за недели две. И хотя вам могло показаться, что часть информации я выдумал лишь бы хоть как-то объяснить поведения, однако на практике ошибки были всего у двух параметров!

Теперь, с багажом знаний, можно и моды создавать, так ведь?

Да я выкрутил насыщенность на 100%

Да я выкрутил насыщенность на 100%

Я — Моддер?

Напомню изначальную проблему, решать которую я собрался.

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

Новая битва - новая планета! (да, next и new)

Новая битва — новая планета! (да, next и new)

Генерация карт и UX

Первым делом для получения практики я решил переписать древний мод на генерацию планет прямо в лобби игры, перед стартом матча. Для этого мне понадобилось разобраться в работе Knockout.js, благо у меня был опыт разработки приложений на WPF.

Капельку покрутив пальцем у виска на автора генератора карт, я вычистил 90% кода, отвечавшего за супер крутые вычисления баланса ресурсов. Тут нужно учитывать, что для контроля генерации ресурсов используется всего два параметра. Они же в свою очередь по своей природе основаны на случайных значениях. И как ты ни меняй значения, как ни вычисляй — всё сводится к тому что мы можем лишь ожидать плюс-минус требуемого результата.

Также оригинальная версия имела множество параметров для генерации в интерфейсе, которые можно было настраивать вручную с помощью полей ввода.

Но! Массовому пользователю все это НЕ НУЖНО! Пользователь не хочет думать над настройками карты, он хочет просто нажать на большую кнопку и получить крутую планету!

Названия шаблонов всё же нужно изменить на small-medium-large

Названия шаблонов всё же нужно изменить на small-medium-large

Именно поэтому я убрал весь старый интерфейс с настройками и заменил его на более дружелюбный и удобный вариант с большими кнопками, которые сгенерируют планету по шаблону. За пользователя уже все придумали и продумали! Ему не нужно самому тыкать кучу параметров.

На оригинальной генерации можно было заспавниться в изоляции и куковать без ресурсов

На оригинальной генерации можно было заспавниться в изоляции и куковать без ресурсов

Также я почистил ландшафт от генерации множества гор и скал, заменив их платформами и переходами с точками интереса. Так удалось увеличить время до просадки скорости симуляции (игра замедляется, когда на карте много юнитов и препятствий).

Древний мод получил новое представление и нормальный промоушен. Что дальше?

90% контента на изображении из мастерской

90% контента на изображении из мастерской

Фракции, юниты и баланс

Главным шагом в решении проблем игры стало объединение самых популярных модификаций в единый проект. Только так можно достичь качественного и целостного геймплея и полноты баланса!

Целостность геймплея означает отсутствие лишних и пересекающихся элементов. Юниты должны иметь четкие роли и специализации. Разные фракции должны учитывать друг друга, ведь это самое ужасное когда они вроде имеют техническую поддержку друг друга, но в то же время снимают с себя обязательства по балансу!

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

Простой игрок не вникает в суть вещей и наивно думает, что всё уже учтено. И такое мышление всегда нужно принимать во внимание!

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

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

Каков был мой первый шаг в создании «правильного» мода?

Добавляем фракцию

Добавляем фракцию

Первым делом Я добавил поддержку второй полноценной фракции — Легион. Вышла она ещё с самого старта основной игры. И казалось бы, а что такого можно сделать с этой модификацией, если ей почти 10 лет?

«У Фракции Легион есть некоторые очень маломощные юниты, смешанные с чрезмерно мощными, что приводит к неравномерному геймплею и плоским стратегиям» — профессиональный игрок

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

Начал я с кривой баланса, которую нужно было сделать менее кривой (что?). Юниты должны быть востребованы в равной степени, не должно быть имбовых или бесполезных. А также нельзя допускать пересечения юнитов, когда на одном уровне один воин может быть просто лучше другого. Какой смысл рисовать войска, тратить на проработку время, если часть из них просто не используется игроками?

После завершения работы над устранением перегибов в балансе, я продолжил углублением игрового процесса фракции. Изначально многие юниты не имели уникальных ролей и часто строились игроками с целью «намешать и перемешать — оптимальная стратегия!». Такой вариант не подходил как приемлемый.

Я затеял всё это не ради слов «и так сойдет». Благо оков разработчика на мне не было, и тестировать изменения в закрытом круге мне не пришлось. Чередой проб и ошибок, для юнитов были найдены специализации, их ниши.

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

С фракцией разобрались. Хорошо. Но это ведь ещё не всё?

Добавляем добавление к фракции

Добавляем добавление к фракции

Интеграция одной фракции была далеко не всей работой!

Я добавил поддержку расширения Second Wave. Оно добавляет невероятно полезные и необходимые для нормальной игры постройки и юниты. Около половины игр проходит с участием этого мода.

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

Недостающие эффекты были созданы с нуля, те что уже присутствовали были корректно прописаны в конфигах.

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

При получении и нанесении урона, игрок должен сразу чувствовать импакт! Он должен понимать что юнит получил повреждения от взрыва, а не от того что споткнулся о камень.

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

С дополнениями я разобрался. Вот только осталась в игре ещё одна серьезная проблема

Улучшаем геймплей орбитальных войск

Улучшаем геймплей орбитальных войск

Игра позиционирует себя как RTS на нескольких планетах. Да вот незадача — игроки предпочитают сражаться на картах с одним шаром вместо нескольких!

Моим третьим шагом стала переработка орбитального геймплея.

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

Почему так получилось? Скорее всего разработчики просто хотели уже поскорее выпустить игру в приемлемом виде. Орбита в данном случае оставалась для галочки. В общем орбитальные войны хоть технически и присутствуют однако имеют ужасный уровень адаптации для новичков, да даже средних игроков.

Ещё одной проблемой, фундаментального характера, является механика перемещения войск между планетами — они, грубо говоря, телепортируются с одного шара на другой. Её никак не исправить, но для решение проблемы с глубиной игры вмешательств в исходный код не понадобилось.

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

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

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

программирую программы на программном языке

программирую программы на программном языке

Инструменты

В какой-то момент управлять контентом и помнить все тонкости баланса стало просто невозможно! Срочно понадобились инструменты.

Я сказал стоп самому себе и отбросил работу над контентом и начал писать программы для поддержания баланса игры и порядка в проекте. Были написаны две программы.

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

Второй инструмент получился простым, но не менее важным. Он упорядочивает поля в JSON по заданному шаблону. Унифицированный порядок нужен для скоростного чтения и редактирования json-конфигов. Это сильно чувствуется при работе над десятком файлов от разных авторов.

Сравниватель JSON: Planetary-Annihilation-Fandom/JsonDiffer
Упорядочиватель JSON: Planetary-Annihilation-Fandom/JsonSorter

Кто?

Кто?

Локализация

Если говорить про пользовательский опыт, то сразу же вспоминается локализация на языки. Так как у игры есть живое русское сообщество игроков, то и о них позаботиться тоже нужно!

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

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

В добавок многие авторы модов не воспринимают свой контент в серьез и могут влепить шутки или локальные мемы в, например, описания юнитов…

Поддерживать 707 модов? Не делайте этого!

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

Естественно Я ничего из их просьб не сделал, ведь причина противоречит самой сути конечной цели — Я создаю завершенный проект, предоставляю качественный и цельный контент!

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

Бояться больших изменений? Не делайте этого!

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

Естественно Я ничего из их просьб не сделал, ведь причина противоречит самой сути конечной цели — Я создаю завершенный проект, предоставляю качественный и цельный контент!

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

© Habrahabr.ru