Подробнее о разработке движка для ролевой игры Knights of Frontier Valley

Подробнее о разработке движка для ролевой игры Knights of Frontier Valley.

Разработчик ролевой игры Knights of Frontier Valley рассказал о причинах создания собственного движка, его разработке, основных компонентах и управлении неигровыми персонажами в игре.

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

Всё это (и не только) работает благодаря собственному, разработанному специально для Knights of Frontier Valley движку. В примерах выше время захода солнца управляется «Менеджером времени» — компонентом, отвечающим за течение времени в игровом мире и освещение окружения. Осадки и качающиеся на ветру деревья возможны благодаря «Менеджеру погоды», а снежинки отрисовываются рендерером карты с использованием системы частиц. Передвижение персонажей по карте осуществляется по специально разработанному алгоритму поиска пути.

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

[Knights of Frontier Valley] На скриншоте: Погодные эффекты.
Закат солнца в Долине.

Мотивация

Начнём с вопроса «Зачем». Создание игрового движка с нуля для такой игры — амбициозное начинание. Возможности движка включают отрисовку изометрического вида (2.5D), продвинутое управление памятью, процедурную генерацию различных типов карт, обработку сложного поведения персонажей и их взаимодействий, сохранение состояния игры (для последующей загрузки), пошаговые механики и в реальном времени, собственный алгоритм поиска пути и многое другое. Такого объёма работ хватит на несколько лет.

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

Когда я начал работать над игрой в 2016 году, то вдохновлялся первопроходцами индустрии, такими как Ричард Гэрриот, Сид Мейер и Питер Молиньё, разработавшими первые игры в золотой век RPG в 80-х и 90-х годах. Тогда они не использовали сторонние движки, и на мой взгляд пройти по их стопам означало написать игру с нуля. Мне не нравилась идея делать игру на основе чужого, не до конца понятного мне кода, который я не смогу полностью адаптировать под свои задачи. Кроме того, я подумал, что это весьма увлекательно (и в целом так и есть).

Хотя Knights of Frontier Valley — мой первый игровой проект, за плечами у меня двадцатилетняя карьера в разработке ПО для настольных компьютеров, интернет-сайтов, встраиваемых систем и мобильных устройств. В Кремниевой долине я занимался программами для работы с GPS, разрабатывал софт под первые iPhone и оригинальный iPad, а также информационно-развлекательные системы и автопилот для Tesla.

Итак, программировать я умею, но разработка игр — совершенно другое направление, и мне предстояло многому научиться. Я начал делать игру, вкалывая на основной работе, поэтому занимался этим лишь по вечерам и в выходные. Примерно через три месяца у меня появился прототип с основным игровым циклом, где персонаж мог ходить по карте и выполнять простейшие действия. Прототип работал, но я понял, что с таким подходом никогда не создам игру с интересной визуальной составляющей. Используемые технологии попросту не подходили для игровой разработки, поэтому я всё бросил и начал заново — используя libGDX, упрощающий рендеринг OpenGL и некоторые другие игровые функции открытый Java-фреймворк. Я выбрал Java и OpenGL, поскольку хорошо знал язык, а ещё эти технологии использовались в успешных играх вроде Minecraft и RuneScape.

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

[Knights of Frontier Valley] Карта мира.
Карта мира: текущая версия и ранние прототипы.

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

Основы движка

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

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

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

Основной цикл — это выполняемая несколько раз в секунду функция. На каждом проходе обновляется весь игровой мир, и на экране отрисовывается отображающий актуальное его состояние кадр. В идеале основной цикл должен выполняться минимум 60 раз в секунду (= 60 FPS), чего достаточно для старых мониторов с соответствующей частотой обновления изображения (= 60 Герц). Сегодня это число зачастую выше, обычно 144 Гц.

Если ваша система недостаточно мощна для 60 FPS (узким местом обычно является GPU), можно заметить задержки и прерывистую анимацию. Но с Knights of Frontier Valley волноваться о видеокарте не придётся: графика в основном предварительно отрендерена, так что GPU может «пойти отдохнуть». Я не вижу тормозов даже на своё старом ноуте со встроенной графикой.

Мой движок состоит из:

  • Основной цикл
  • Конечный автомат
  • Управление памятью
  • Обработчик сохранений
  • Рендереры для карты и объектов
  • Систему воспроизведения видео
  • Вывод звука
  • Обработку ввода мыши/клавиатуры
  • Сетевые функции
  • Управление игровым временем
  • Поиск пути
  • Моделирование карт
  • Моделирование погоды
  • Моделирование персонажей и очередей действий
  • Моделирование перемещения персонажей

Не входит в движок:

  • Всё связанное с сюжетом и квестами
  • Графические ресурсы, музыка и звуковые эффекты
  • Пользовательский интерфейс
  • Логика процедурного построения карт
  • Специфичные для игры персонажи, объекты и предметы
  • Поведение NPC
  • Специфика конкретной игры, в том числе создание персонажа, боевая механика, спецэффекты (например, магия), пользовательские шейдеры, мини-игры и многое другое

О двух модулях я расскажу подробнее: моделировании персонажей (и связанных с ним очередях действий) и компоненте управления перемещениями NPC. Дополнительные подробности — в дневниках разработки о поиске пути и рендеринге на сайте проекта.

Моделирование персонажей и очереди действий

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

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

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

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

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

[Knights of Frontier Valley] Список персонажей.
Список персонажей на текущей карте города вне зданий в режиме разработчика.

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

У каждого персонажа есть «очередь» — список действий, которые он выполнит по порядку. В них входят «движение по траектории», «взаимодействие с объектом», «разговор», «атаку», «исполнение музыки», «чтение свитка» и так далее, а иногда это просто «ожидание». Когда персонаж не занят выполнением действия, из очереди берётся верхнее действие и запускается. Только если очередь пуста, персонаж действительно бездействует.

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

Если во время выполнения NPC своей очереди происходит что-то непредвиденное (например, атак игрока), очередь очищается, а поведение пересматривается: в качестве ответной реакции создаются новые действия. Когда игра сохраняется, очереди действий также сохраняются и восстанавливаются при загрузке, так что все персонажи продолжают прямо с того места, где и остановились.

[Knights of Frontier Valley] Список действий.
В режиме разработчика очередь действий персонажа можно вывести на экран. В этом примере игровой персонаж подойдёт к знатной даме, повернётся к ней, после чего остановит движение, и наконец вступит с ней во взаимодействие типа «Общение».

Модуль перемещения персонажей

При моделировании NPC персонажи могут перемещаться в реальном времени в любое место, даже через не загруженные в память карты. «Модуль перемещения» чётко определяет необходимые для путешествия действия и помещает их в очередь лидера группы. Например, для перемещения с чердака дома в подвал другого дома в другом городе потребуется выполнить следующие действия:

  • Запустить соответствующую анимацию движения (ходьба, бег или полёт... в других сценариях, возможно, также верховая езда или плавание)
  • Подойти к лестнице вниз
  • Спуститься по лестнице до входного уровня здания
  • Подойти к входной двери
  • Взаимодействовать с дверью для выхода из здания
  • Подойти к точке выхода из города
  • Покинуть город
  • Идти по миру ко входу в город назначения
  • Войти в город
  • Пройти требуемые городские кварталы и добраться до нужного дома
  • Подойти ко входу в дом
  • Взаимодействовать с дверью для входа в здание
  • Спуститься по лестнице в подвал
  • Дойти до точки назначения в подвале

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

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

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

Это не реальный расчёт, а приближение и своего рода «подделка» части путешествия. Но она отлично работает, и игроки никогда не узнают, что части маршрута не обсчитывались в реальном времени, МУАХАХАХАХА. Ладно, ну, ВЫ теперь знаете об этом — считайте это наградой за чтение до конца. Ваша способность удерживать внимание достойна восхищения, и у вас, вероятно, есть всё необходимое для написания собственного движка.

CC0
Вы можете копировать, изменять, распространять и исполнять данное произведение, даже в коммерческих целях, не спрашивая разрешения.

Поиск по сайту

Сообщения на форуме | новые

[В разработке] Starfinder: Afterlight на форуме Всё остальное | Инди.
Последнее сообщение оставил Архивариус (2025-08-02 в 23:09). Ответов: 3.
Sacred 2 на форуме Ролевые боевики.
Последнее сообщение оставил Crashwall (2025-08-02 в 22:12). Ответов: 20.
[В разработке] Fatekeeper на форуме Ролевые боевики.
Последнее сообщение оставил QweSteR (2025-08-02 в 21:57). Ответов: 5.
[В разработке] Titan Quest 2 на форуме Ролевые боевики.
Последнее сообщение оставил S1pr7eKy3xPE7Oz (2025-08-02 в 17:44). Ответов: 18.
[В разработке] Gothic Remake на форуме Gothic.
Последнее сообщение оставил S1pr7eKy3xPE7Oz (2025-08-02 в 17:03). Ответов: 38.
[ЛКИ] Жанр в разрезе: Ролевые игры на форуме Обсуждение статей.
Последнее сообщение оставил FromLeftShoulder (2025-08-02 в 13:32). Ответов: 5.
Надеюсь, эту боевую систему перестанут использовать в RPG на форуме Обсуждение статей.
Последнее сообщение оставил Чума (2025-08-02 в 13:04). Ответов: 128.
HeistGeist на форуме Карточные.
Последнее сообщение оставил Бобёр (2025-08-02 в 11:06). Ответов: 11.
[В разработке] MENACE на форуме Тактические и стратегические.
Последнее сообщение оставил ma1k0vich (2025-08-02 в 10:35). Ответов: 58.
Neverwinter Nights 2 на форуме Neverwinter Nights 2.
Последнее сообщение оставил FromLeftShoulder (2025-08-02 в 10:17). Ответов: 471.

Ожидаемое | таблица

Новости C.O.R.E.

Статьи C.O.R.E.

Новости RPG Codex

Новости RPG Watch

Новости RPG Nuke

Случайная цитата

Nobody will try to figure out if you’re made of glass or of metal. When you’ll show your strength, you’ll find company of those who want to steal it from you; but your weakness, you’ll be all alone with it.

Weaver Okhr, Winter Voices

Оставьте свой отзыв: QR-код для отзывов в «Яндексе».