Перейти к содержимому

Из чего состоит игровой движок

  • автор:

Разработка собственного движка, напутствие

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

АТЕНШОН, МНОГА ТЕКСТА НЕТ ПИКЧ

Предостережение

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

Поясню — что бы написать минимально рабочую игру, тебе нужно: обработка ввода, вывод графики и игровой цикл с логикой. Можно сказать — «всего 3 компоненты и ты уже можешь делать свои крестики-нолики или тетрисы!». Но для звания «великого игрового движка», при мысли о котором ты возбуждаешься, явно не хватает всего 3х компонент. Различные механизмы подгрузки данных, гибкие системы рендера, система скриптов, встроенные редакторы уровней — всё это требует времени на реализацию, и чем больше ты хочешь, тем больше времени у тебя уйдёт на разработку «движка с 0», а сколько времени потратится на написание самой игры?

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

А как писать?

Для начала нужно подвести черту между двумя кардинально разными подходами в написании этих ваших «движков». Я обозвал их так.

  • «Динамические движи», это те в которых вся игровая логика содержится внутри объектов, которые можно передать в другие бинарные модули. (Прим — .dll библиотеки)
  • «Статические движки», это те в которых вся логика содержится внутри самого движка и определяется на этапе компиляции.

Какие нюансы я обнаружил при такой классификации?
«Статические движки»

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

«Динамические движки»

  • Требуют глубокого понимания матчасти, из-за виртуализации объектов.
  • Код можно разбить на независимые модули и подключать буквально на лету. В некоторых играх есть моды которые реализуют «движок в движке», которые используют другие подключаемые модули.
  • Большинство инструментов для отладки придётся писать самому, если это не встроено в сам язык. То есть, если ты не пишешь на .NET/JAVA/Lua?
  • «Скрипты» могут быть реализованы в виде скомпилированных бинарников обёрнутого в объекты, от чего «потанцевал» при добавлении контента может быть больше (в плане производительности).

Большинство «индюшачьих» игровых движков описаны как «статические». Их гораздо проще писать и ещё проще поддерживать. Использование «динамического» подхода, даст тебе ненужную модульность. Возможно написание своего крутого интерфейса для аллокатора памяти хорошая затея, но ты бы мог потратить это время делая игру, а не натирать цепь разобранного велосипеда.
*** Рекомендация — пиши «статику»
*** Самый наивный способ сделать «динамику» — писать классы с виртуальными методами или их аналогами.

Кроссплатформенность

Это боль. (вся глава моё нытьё. )
Первая мысль которая должна посетить твою голову — как распространить игру на максимально широкую аудиторию.
Ты можешь использовать кроссплатформенные библиотеки, но их функционал крайне ограничен, так как они пытаются создать абстракцию которая «будет жить на любой платформе». Ты конечно можете написать свою библиотеку. Но вот в чомъ мем
Проблема в том, что платформы достаточно сильно отличаются даже в самых базовых вещах. Как пример — Windows при старте программы не имеет потоков ввода-вывода и для этого ей нужно создавать консоль, но консоль можно создать 2 различными способами и у каждого способа есть куча параметров, для лююююбых потребностей. В Linux же всё проще, у тебя со старта приложения есть потоки ввода-вывода и что бы «увидеть их» нужно просто перенаправить их в файл или создать окно-терминал. КАК ты даже ТАКУЮ простую проблему будешь решать, я не представляю. (я это уже сделал)
Чего уже говорить о создании графического контекста.

Вот ты пытался в OpenGL на Windows? Знаешь что на официальном сайте написано использовать GetDC() при связывании контекста окна и OpenGL? А ты знал что это DC на самом деле может быть принтером? Может быть целым монитором? Видеокартой? Просто окном? «Ресурсом менеджера окон»? А то что в Linux ты должен ручками выбрать нужный тебе монитор для запуска? Всякие драйверы-сервера запускать? И не один. И это надо как-то собрать в одну единую абстракцию и непринуждённо дёргать по воле случая.

Не страдай хернёй, я просто пытаясь понять как это всё работает не одну неделю убил —> используй готовые библиотеки. Их качество оставляет желать лучшего, но это избавит тебя от большой части головняка, который ты можешь себе вообразить, и позволит тебе сконцентрироваться на написании самой игры. (не исключается наличие багов в самих библиотеках)***

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

Делаем игры, наивно

В начале статьи я ввёл понятие «компонента». На самом деле я называю так любую штуку «которая делает что-то другое» )))

Любой код можно разбить на некое число компонент-модулей. Самое примитивное приложение состоит всего из 3 модулей

  • Обработка ввода
  • Вывод изображения
  • Логика (зачастую на стейт машинах)

Уже это позволяет писать тебе довольно простые игры. Скажем крестики нолики или «давилку мух»? Давай вместе представим как оно может работать.

  • Загружаем нужные ресурсы
  • — В цикле.
  • Рисуем: фон > картиночки
  • Обрабатываем ввод
    — Если нажата мышка, проверяем хитбоксы объектов
    — Если прошли проверку, меняем «игровое состояние»
  • (для «давилки мух») Раз в Х циклов запускаем новую муху по некоторой траектории. И обрабатываем перемещение живых мух.

И это уже можно назвать игрой. «Погоди» — скажешь ты — «Но фактически тут 4 модуля, загрузка ресурсов!!». Хах, но если ты чуть-чуть разбираешься в линковке приложения, то ты можешь вшить данные в бинарник) И тебе не нужно будет загружать никаких данных. Поведение мух, также, вшито в движок и относится к логике, потому фактически тут именно 3 модуля.

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

Я бы сказал так — «движок занимается обработкой пользовательских данных и может иметь изменяемую логику»

Из такого определения давай же опишем некий «сферический движок для платформера».
Для начала, тебе потребуется описать больше чем один модуль, а логика самого движка будет гораздо сложнее.

  • Конкретная загрузка ресурсов
  • Обработка ввода, который конвертируется в абстракции
  • Вывод изображения, который обходит множество объектов
  • Игровая логика, которая уже разбита на несколько частей
    — Обработка загрузки-переходов уровней
    — Информация о сцене
    — Нахождение коллизий и проверки на триггеры
    — Обработка поведения ИИ?
    — Обработка ввода от игрока
    — Скриптовый процессор

Теперь, как прошлый раз, давай разберём поэтапно, что и как движок должен делать.
— Для начала опишем «минимальную» логику.

  • Информация о сцене (уровне)
    — Какой фон
    — Набор тайлсетов (2D матрица)
    — Предметы
    — Юниты
    *** Всё кроме фона должно иметь информацию о себе, типа — «текстура», «какие-то свойства», есть ли «триггер», «скрит» или «поведение»
  • Вшитые в движок «примитивы»
    — Триггеры (какие бывают, что проверяют, что вызывают. прим — если хибоксы пересекаются — запускает смену уровня)
    — Поведение (хардкодное поведение, что делает объект. прим — триггернутый предмет увеличивает свойство Х, у объекта который триггернул. Объект Х движется в одну сторону и случайное время меняет направление. Это можно оформить в виде «функций» для скриптового языка. )
    — Свойства (Что за свойства, определяемые скриптами свойства)
    — Процессор скриптов
  • Обработка передвижений-триггеров-физики?

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

  • Загружаем информацию об уровне (описание уровня)
  • Загружаем нужные ресурсы (текстуры и скрипты)
  • — В цикле.
  • Рисуем: фон > тайлест > предметы > юниты
  • Обрабатываем ввод
    — Абстрагируемся от кнопок и просто передаём «Идти влево»
  • Обрабатываем логику
    — Проходимся по всем единицам со скриптами
    — Проходимся по тем, у кого базовое поведение
    — Что-то делаем с игроком?
    — Проверяем коллизии-физику? (вызываем триггеры если что-то нашли)
    — Двигаем юнитов-предметы

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

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

Поясню за скрипты — для многих это будет открытием, но скрипты можно делать и в виде виртуальной машины-процессора. Твоя задача будет — написать парсер текста, описать виртуальную машину и придумать как именно получать информацию о сцене-объектах. В качестве примера, можно использовать многострадальные стековые процессоры, по типу forth. Они очень легко делаются, но к их логике нужно привыкать. По сути это единственный выход написать «быстро» ваш собственный «скриптовый процессор».
*** Обязательно сделай вывод логов при сборке скрипта, или при его работе.
*** Старайся избегать логики типа [INT a += «Lord»]. Писать нетипизрованный код опасно, но можно выделить отдельные команды для работы с конкретными типами.
*** ДА, ТЫ БУДЕШЬ ПИСАТЬ СКРИПТЫ НА АССЕМБЛЕРЕ.
*** Для написания простого ассемблера, хватит и знаний типа — Sting.indexof(«ADD»); и подобного говнокода. Но что бы написать нормально, или хотя бы простенький язык, вам нужны знания о «регулярных выражениях» или «парсерных комбинаторах».
*** Не надо упарываться в «полноценный язык», посмотрите как писались языки программирования в бородатых 80х, даже тот же Pascal. Они работают просто и честно, такие реализации займут у вас в разы меньше времени, чем описание «очередного» . C\Rust\Haskell.

Типа канец?

В целом написать некий «движок в вакууме» не такая сложная задача, как кажется. На ранних этапах большинство поведений-абстракций можно вшивать в движок. Да и в целом, большинство вещей работают довольно просто, и требуют от вас лишь знаний и понимания. Но я напомню, написать свой движок для игры — плохо. Это отнимает огромное количество времени, которое вы можете потенциально потратить на разработку самой игры. А любая гордость проходит, после осознания того, что ты делал свою игру примерно 20% времени пока писал код.

Изначально, решился написать эту статью, ради привлечения инвестиций, на время разработки своей «базовой +18 новеллы». (инициатива друга)
Так что ты это, кнопочку то нажми, а?

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

  • Как лучше работать с памятью-данными.
  • Проблемы STL библиотек. (C++)
  • Детали виртуализации объектов, микро рекомендации.
  • Как можно делать «моды».
  • Профилирование и Логирование, почему это важно.
  • Что нужно знать о многопотоке, вводные-подводные.
  • Асинхронно или параллельно? Как это работает?
  • Работа с текстом-кодировками, и почему это настоящий ад.

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

PS — Под конец получилось немного сумбурно, ибо я писал всё за один заход. В целом я описал лишь поверхностно многие вещи. Если будет спрос, могу углубится.
PPS — Мне тут говорят что бы я сделал бусти и публиковался впредь там, раз в месяцок публикуя «фри контент». Может в следующий раз? Я просто не знаю о чём там можно писать, лол.
PPPS — «Статья слишкам длинная устал читать, пиши кароче»

Как и зачем создавать собственный игровой движок

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

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

Зачем?

Начнем с главного вопроса, который стоит задать себе, если вы решили разработать собственный движок: зачем это вам?

Резонными причинами могут быть, например, такие:

  • Хотите создать игру с использованием новой технологии, которую не поддерживают другие движки. Или поддерживают, но реализация слишком сложна и костыльна. Это может быть масштабная симуляция (Factorio), нестандартный проект, который не вписывается в готовые шаблоны (Noita, Miegakure), и множество других идей. В таких случаях нет иного выхода кроме как писать собственный движок под проект.
  • Хотите оптимизировать рабочий процесс под игры, которые создаете. Если для проекта не нужен полный объем возможностей коммерческого движка, есть смысл создать кастомизированный вариант с подходящими для конкретной игры редакторами и функциями. Если движок не затачивается под конкретный проект, стоит задуматься, так ли нужно самописное решение или все-таки достаточно готовых вариантов?
  • Не хотите в долгосрочной перспективе зависеть от чужих технологий. Если вы хотите иметь полный контроль над проектом, готовы самостоятельно исправлять ошибки (а не сидеть в ожидании багфикса от создателей) и не бояться, что очередное обновление сломает игру, то собственный движок — подходящий вариант! И не придется зависеть от прихотей крупных корпораций
  • Вам интересно разобраться, как устроены и работают игровые движки. Это отличная причина — по правде говоря, самый веский повод заняться разработкой собственного движка.

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

  • Вам кажется, что вы придумаете движок покруче, чем Unity или Unreal (или Godot, или GameMaker). Не выйдет. Разработать подходящий для специфических нужд софт можно (см. предыдущий список), но в одиночку или маленькой командой невозможно создать универсальный движок, который будет конкурировать с известным универсальным ПО. Особенно при первой попытке.
  • Думаете, что иначе вы «ненастоящий программист»? Использование готового движка не делает гейм-разработчика хуже. Для того они и придуманы! Это просто инструмент для создания игр. 99% проектов можно разработать при помощи уже существующего софта — в этом нет ничего постыдного. Ведь главное — это сама игра!
  • Если вы хотите таким образом сэкономить время или деньги — забудьте! Создавать движок с нуля долго, а время = деньги. Использовать готовый софт выгоднее, чем пытаться разработать собственный. В долгосрочной перспективе это может стать выигрышной стратегией, но только если движок будет основой для нескольких прибыльных проектов, и при этом значительно удобнее в работе, чем коммерческие. Такое ПО разработать сложно, особенно если это первый опыт (и почти невозможно, если речь о 3D).

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

Я начинал с флэш-игр в 90-00х, и ни один движок того времени не поддерживал импорт флэш-анимаций. Единственным выходом было создать собственный софт. Намного приятнее и быстрее закидывать swf-файлы в папку с ресурсами и сразу использовать анимации в игре без промежуточных шагов типа экспорта в списки спрайтов.

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

Что?

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

Разные движки выполняют за вас разное количество работы. Некоторые просто отображают графику на экране (Flash, Pico-8). Другие сами по себе — целая игра с возможностью кастомизации или узко заточены под определенный жанр (RPGMaker, Ren’Py). А между ними — бесчисленное количество вариантов.

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

Базовые функции движка.

Это основы, необходимые для того, чтобы начать создавать игры.

Инициализация системы.

Приводит программу в боевую готовность после запуска — открывает окно, загружает данные. С этим (и не только!) справится стандартная библиотека SDL, проще ее и использовать.

Контроль частоты кадров

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

Ввод

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

Рендеринг

Большинство (ну как минимум 75%) игр так или иначе используют графику, и за нее отвечает как раз движок. В 2D-игре минимальному рендеру достаточно отображать на экране текстурированные четырехугольники. Шейдеры, буферы вершин, однобуферная прорисовка, меши, материалы и так далее — это прекрасные опции, которые можно добавить позднее, если понадобится. Если хочется заморочиться с OpenGL или Vulkan и кастомизировать рендерер — на здоровье! Но помните, нет ничего постыдного в том, чтобы использовать для рендеринга готовые библиотеки типа Ogre3D. Выбор зависит от целей и потребностей разработчика, а также от того, какие задачи интереснее решать самостоятельно.

Математические и прочие утилиты

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

Дополнительные функции

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

Управление игровыми объектами и сценами

Можно кодить и вручную, но практичнее предусмотреть систему для обработки отдельных игровых объектов и коллекций. Это один из ключевых механизмов в движке, ведь он управляет логикой игры. Из каких компонентов состоят объекты, на какие типы событий реагируют, как происходит взаимодействие, что со структурой памяти, используется ECS? (Кстати, «чистый» неадаптированный ECS лучше применять только для специфических кейсов.) Эти и не только вопросы должна покрывать система управления объектами и сценами. Для таких задач доступны готовые библиотеки (особенно для чистого ECS), но, поскольку эта структура сильнее остальных влияет на игровой код, я склоняюсь к принципу «сделай сам». Использование существующего решения вынудит постоянно думать о том, как вписать логику игры в рамки. А надо наоборот — адаптировать движок под выражение задуманной игровой логики.

Аудио

Звуковые эффекты и музыка здесь разделены, хотя и прячутся под одним названием. Основные необходимые функции — это запуск и остановка звуковых циклов и воспроизведение звуковых эффектов от начала до конца. Этим аудио не ограничивается, но даже с двумя базовыми опциями можно далеко продвинуться. Минус в том, что стандартные звуковые фреймворки (FMod and Wwise) — коммерческие и с кучей лицензионных ограничений. Однако большинство ресурсов с открытым кодом раздражают неудобством (передаю привет OpenAL). Сам я использую FAudio — на мой вкус, простая и комфортная в использовании база для построения сложных звуковых механик.

Загрузка и управление файлами

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

Нетворкинг

Окей, нетворкинг (онлайн-мультиплеер) — это ОЧЕНЬ опционально. Если не планируется режим p2p, то и не заморачивайтесь. Однако эту систему чрезвычайно сложно встроить в движок, который разработан не с расчетом на многопользовательские игры. Поэтому, если вы планируете или допускаете добавление мультиплеера, подготовьте почву заранее, потому что иначе придется переделывать все системы.

Это базовый набор систем, которые входят в игровой движок. Другие варианты типа обнаружения столкновений, физики, сериализации, анимации и UI уже опциональны. Они распространены, поэтому входят в большинство движков, но для создания игр не обязательны. Например, предотвращение столкновений можно обеспечить при помощи математических утилит и прописать алгоритм в коде игры. Простейшую гравитацию и ускорение можно настроить без физических движков типа Box2D or Bullet. А полная сериализация вообще лишняя, если нужно попросту сохранить чекпойнт.

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

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

Как?

Итак, вы взвесили за и против, поняли, чего хотите, и решили все-таки взяться за создание движка. И как же это сделать?

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

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

Не программируйте того, что не нужно. Если единственный UI в игре — кнопка Play в главном меню, поздравляю! Не придется создавать мудреный пользовательский интерфейс. В The End Is Nigh нет ни физического движка, ни детектора столкновений. Там даже нет камеры, потому что она там не нужна. Я использовал электронную таблицу .csv, чтобы собрать карту мира, вместо всяких сложных редакторов. Делается легко и нормально работает.

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

Что касается языков программирования — выбирайте, каким лучше владеете. Разработка движка — сама по себе непроста, а если делать это параллельно с изучением С++, обе эти задачи станут в два раза сложнее. C# идеально подойдет для создания движка. Медленнее, чем на С++, но не критично. Более медленный язык типа Python может вызвать затруднения, если в игре много движущихся объектов… но для некоторых игр пойдет. Используйте, что удобно.

И еще — с первой попытки идеально не получится. Моей первой игрой на самописном движке стала Closure, и в ней полный бардак (забавно, что ее номинировали на награду «Техническое совершенство» на фестивале независимых игр в 2010 году). Системы рендеринга и обновления вдвоем обрабатывали всю игру. Добавлять новые объекты было крайне трудоемко, приходилось дописывать кучу кода и работать с кривыми редакторами анимации, так что в итоге осталось с дюжину интерактивных предметов. У некоторых из них было несколько вариаций, кардинально менявших поведение объекта — это было проще, чем добавлять новые. Так что прожекторы, зеркала и турели по сути один и тот же объект!

Но с ошибками приходит и опыт. Движок Closure написан кое-как, но оказался достаточно хорош, чтобы запустить игру на PS3. Идея переписать некоторые части движка была заманчивой, но это лишь отложило бы выход игры. Вместо этого я писал заметки о том, что получилось плохо, чтобы учесть ошибки в следующий раз. Особенно о том, что мешало непосредственно созданию игры. То же и с The End is Nigh. В ее движке (который, кстати, НАМНОГО лучше, чем в Closure) все равно была куча ошибок, которые я решал, стиснув зубы. Как только игра вышла, я сразу начал улучшать движок для следующего проекта, исправлять раздражающие баги и добавлять новые функции.

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

Не стал вдаваться в технические подробности, как внедрить в движок каждую отдельную систему. Это зависит от конкретных вариантов использования, есть сотни способов — и каждый из них правильный. Понять, что вам подходит — ВОТ в чем суть разработки движка, с таким настроем стоит браться за создание собственных проектов.

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

Как разобраться в игровых движках

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

Что такое игровой движок

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

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

Какие виды игровых движков бывают

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

Касательно внутреннего устройства игровые движки делятся на:

  • Полноценное ПО — это такая специальная программа, которая может собрать игру воедино за вас, а вам предоставляет полноценный редактор.
  • Фреймворк — это набор полезных классов и функций, которые вы можете использовать при создании своей игры с нуля. Игру вам придётся собирать самостоятельно, но зато у вас будет больше контроля за процессом.

Если мы говорим о фреймворках, то игра пишется на том же языке, на котором написан фреймворк. Если же мы говорим о полноценном ПО, то программировать в них можно на:

  • Полноценный язык программирования. Такими языками могут быть C++, C#, Javascript, Lua.
  • Адаптированный скриптовый язык. Обычно за основу берётся какой-нибудь скриптовый язык, а его синтаксис и возможности расширяются, чтобы им было проще пользоваться в контексте разработки игр. Тут нет универсальных решений, но чаще всего эти языки очень похожи друг на друга.
  • Визуальный интерфейс. Это абсолютно такой же процесс программирования, но вместо написания строк кода вы соединяете узлы действий между собой. Это ещё проще, чем писать код вручную, но процесс программирования всё равно изучать придётся. А ещё в узлах сложнее ориентироваться из-за их громоздкости.

Если говорить о лицензии, то тут тоже есть несколько вариантов:

  • Платные движки — за использование этих программ придётся платить, иногда даже каждый месяц.
  • Бесплатные для использования — эти движки вы можете спокойно скачать и использовать для разработки, но чтобы продавать игры, сделанные на нём, придётся отчислять процент владельцам движка.
  • Движки с открытым исходным кодом — эти движки вы можете спокойно скачать и использовать с минимумом ограничений.

Возможности, которые может предоставлять или не предоставлять игровой движок (список неокончательный):

  • Система уровней
  • Физика
  • Система частиц
  • Навигация
  • Двумерная анимация
  • Трёхмерная анимация
  • Карты тайлов
  • Редактор местности (terrain)
  • Воспроизведение звука
  • Источники освещения и тени
  • Шейдеры
  • Диалоговая система

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

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

Типичное устройство игры внутри игрового движка

Игровой мир состоит из игровых объектов (GameObject). К этой базовой категории можно практически отнести всё, что находится в игре, в том числе игрока, его инвентарь, камеру, землю под ногами, каждый отдельный кустик и даже небо. Не стоит думать, что все объекты обязательно должны быть видимы — всякие триггеры (объекты, вызывающие события при прикосновении), барьеры, источники освещения и даже части интерфейса являются такими же объектами. Все игровые объекты обладают несколькими базовыми свойствами: положение в пространстве (Transform), включены ли они (Active), какой у них родительский объект и есть ли он (Parent).

Игровые объекты так же могут быть дополнены поведением (Behaviour или Component). Поведение — это отдельный код, который привязан к объекту и выполняется при определённых условиях. Условия могут быть самыми разными, а количество поведений, привязанных к объекту, ничем не ограничено. В таком коде вы например можете двигать объект по движению мыши или перекрашивать его цвет. А ещё у каждого поведения могут быть свои отдельные параметры (выраженные в переменных).

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

Помимо своих собственных поведений в игровом движке есть несколько стандартных типов поведений: форма столкновения (Bounding Box/Sphere/Capsule/…), физическое тело (Rigidbody), отрисовщик (Renderer), камера (Camera), создатель частиц (Particle Manager), аниматор (Animator) и ещё десятки других типов. Всеми этими поведениями вы можете управлять на лету.

Очень важным концептом является событие (Event). Это сигнал, который возникает при соблюдении каких-то условий. Поведения объектов в игре могут порождать эти события и реагировать на них. Например, столкновение — это событие, причём одно из самых частых по использованию. Именно на событиях строится основной игровой процесс, разработчик игры может навешивать действия (Action) одних поведений на события других и так, например, делать кнопки, рычаги, точки сохранений и так далее.

Но это и не единственный способ заставить игру работать, ещё есть раздел Update, в который можно написать код и который будет выполняться постоянно, в каждый игровой тик (tick). Тик — это самая минимальная единица времени, которую игра может обеспечить. Обычно тик составляет 16 миллисекунд, но если у вас плохо с оптимизацией, то он увеличится. Без этой функции не обойтись, и некоторые вещи, например плавное передвижение и проверка столкновений, пишутся именно там. Но чем меньше кода написано в этой секции — тем лучше.

Место, в котором находятся игровые объекты, называется уровень или сцена (Level или Scene). Уровни можно менять в любой момент, а в некоторых движках ещё и совмещать между собой. Ваши игровые объекты будут распределены по уровням, чтобы друг другу не мешать. Например это будут локации и их наполнение. Но определённые универсальные для всех уровней объекты, например главный персонаж или интерфейс, лучше хранить в отдельном месте.

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

И последнее, про графику. Объекты в игре могут выглядеть самым разным способом. И дело даже не в отдельный настройках, а в самом способе их отображения на экране. Это могут быть 2D-объекты, например различные простейшие геометрические формы (Shape) или картинки (Sprite). А могут и 3D-объекты, которые состоят из 3D-модели (Mesh). Все видимые объекты в игре обязаны иметь материал (Material) — набор параметров, влияющий на отображение объекта. Такими параметрами могут являться текстуры (Texture), цвета (Color) и обычные числа (Float). Некоторые движки дают доступ ограниченный доступ материалу, давая лишь задать текстуру и цвет окрашивания, другие же дают полный доступ. В основе материала лежит шейдер (Shader) — особая программа, которая проводит математические вычисления и проецирует объекты в пространстве на плоский экран камеры.

Ну и маленький список движков с классификацией

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

Самые простые

Construct 3 — настоящий ветеран индустрии. Используется для создания 2D-игр и достаточно популярен. У движка больше настроек, с недавних пор есть версия для браузера, очень много примеров и шаблонов. Логика на визуальном интерфейсе. Но большинство возможностей скрыто за крайне дорогой лицензией. Бесплатная версия ограничена.

Stencyl — ещё один движок для создания 2D-игр. Имеет открытый исходный код и и приятный интерфейс. Логика на визуальном интерфейсе. Мало известен, но полностью бесплатен (платно только публикация на ПК).

GDevelop — другой движок для создания 2D-игр, набирающий огромную популярность. Так же имеет открытый исходный код и приятный интерфейс. Логика на визуальном интерфейсе. Полностью бесплатен.

RPG Maker — очень популярный движок для создания пиксельных RPG. Именно для RPG движок и заточен, но он подойдёт и для похожих жанров. Много встроенных ассетов и настроек для персонажей. Есть бесплатный 30-дневный пробник, дальше придётся платить.

Средние по сложности

Game Maker Studio — очень популярный движок для разработки 2D-игр. Позволяет программировать логику на адаптированном Lua и даёт много возможностей. Есть бесплатный 30-дневный пробник, дальше придётся платить.

Godot — очень многообещающий движок с открытым исходным кодом, который грозится «заменить Unity» в своей распространённости. Godot поддерживает 2D и 3D графику, а так же несколько языков программирования (C++, C# и модификация Python) и имеет свой визуальный скриптинг. Его использование полностью бесплатно.

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

Monogatari — простой движок визуальных новелл на веб-технологиях. Мало известен, но выглядит интересно, к тому же движок на Javascript легче исправить под свои нужды. Код пишется на том же языке. Полностью бесплатен.

Сложные

Unity — самый популярный в мире движок для разработки игр. Поддерживает 2D и 3D графику, имеет в себе невиданное количество вспомогательных модулей, огромный магазин ассетов и поддерживает большинство платформ. К сожалению, с ростом популярности движок становится всё сложнее и тяжелее в освоении, но всё равно очень доступен. Программирование на C#. Использование условно-бесплатное, при превышении определённого порога прибыли придётся платить за лицензию.

Unreal Engine — настоящий гигант, используемый профессионалами в индустрии кино и игр. Имеет самую лучшую графику на рынке, кучу инструментов внутри и ежемесячно раздаваемые бесплатные ассеты на любой вкус. В качестве программирования используется визуальный интерфейс, но есть возможность писать и на C++. Инструмент для профессионалов, поэтому очень просто что-то испортить. Использование бесплатно, но с каждой проданой игры надо отчислять процент.

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

Фреймворки

Cocos2d — популярный фреймворк, портированный на несколько языков (C, Python, JS, Swift, C#). С его помощью сделано много игр в том числе для мобильных устройств.

Phaser — набирающий популярность фреймворк для разработки игр на Javascript.

libGDX — завоевавший доверие фреймворк для разработки игр для Java.

SFML — популярный фреймворк для разработки игр на C++

Что ж, теперь вы знаете, как выбрать движок и какие опции доступны. А теперь дерзайте! Скачивайте, тыкайте, экспериментируйте. На сайтах движков вы можете найти очень много шаблонов и примеров, а на YouTube (особенно английской его версии) можно найти буквально сотни и иногда даже тысячи гайдов по тем или иным сторонам разработки. Ждём ваши работы!

Что такое игровой движок?

Что такое игровой движок?

Если вы регулярно читаете статьи о компьютерных играх, то обязательно сталкивались со словами «игровой движок». И вы знаете, что он может быть быстрым, тормозным, продуманным, неудачным, привычным и так далее. А что это за «движок», который скрывается под красивой оберткой текстур и скриптов компьютерной игры? Это же не двигатель автомобиля. Тогда что? Программный код? Комплекс приложений для программистов и игроков? Разберемся немного подробнее.

Понятие «игрового движка»

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

Впервые этот термин появился в середине 90-х годов прошлого века. Связан он был с играми в жанре «шутер от первого лица», а точнее, с самым популярным на тот момент Doom. Исходный код этой игры был построен очень продуманно, с выделенными основными компонентами: системой трехмерной графики, звуками, расчетами столкновений, скриптами. Это привело к тому, что игровые программисты не стали писать свой код, а использовали наработки разработчиков Doom, внеся в код некоторые изменения: рисовали другие уровни, изменяли графику и внешний вид оружия, корректировали правила и выпускали новые игры, в основе которых оставался все тот же код из Doom.

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

В результате ряд компаний занялся разработкой именно игровых движков, а разработчики игр стали покупать на них лицензии, как это получилось с Unreal Engine или id Tech 3. Стоимость лицензии может составлять от нескольких тысяч до миллионов долларов. Но при этом надо отметить, что для некоммерческого использования многие игровые движки, например, популярные Unity и Unreal Engine 4 доступны бесплатно. Остановимся на этих движках немного подробнее.

Особенности популярных игровых движков Unity и Unreal Engine 4

Движки Unity и Unreal Engine 4 являются самыми популярными в среде разработчиков из-за их удобства, детальной проработки и большого количества дополнительных библиотек, что позволяет настраивать и реализовывать практически любые идеи, приходящие в голову дизайнерам и игроделам.

Unreal Engine 4

Этот движок смело можно назвать легендой. Его разработка началась в 1998 году и с тех пор он постоянно модернизируется, дополняется и совершенствуется. Современный Unreal Engine 4 — это движок, на котором пишут игры для любых платформ и операционных систем, начиная от ОС Windows и заканчивая всеми современными консолями — Playstation 4, Xbox One, а также мобильными платформами, в том числе и iOS.

13 мая 2020 года разработчики из Epic Games анонсировали Unreal Engine 5 и показали демо для консоли Playstation 5. Ожидается, что этот движок выйдет в 2021 году, а пока разработчики продолжают работать с Unreal Engine 4. В настоящее время он бесплатен при условии, что выпущенные приложения приносят прибыль не более $3 000 в квартал. Если сумма прибыли больше, потребуется лицензировать движок и выплачивать его разработчикам процент от прибыли.

Unity

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

Как и Unreal Engine, Unity — кроссплатформенная система. На ней пишут игры для любых платформ и в любых жанрах. На Unity делают как простые аркады и головоломки, так и шутеры от первого лица с достаточно сложным игровым миром. Пример — Dead Trigger. Другой пример — интересная стратегия Endless Legend. Движок бесплатен для некоммерческого использования, а при написании коммерческих игр требуется выплачивать комиссионный сбор авторам движка.

Большой плюс Unity — простота его освоения. Минус — графика в играх, созданных на основе этого движка. Она выглядит проще и не настолько реалистична, как у Unreal Engine. Тем не менее, около половины всех мобильных игр, по заверениям разработчиков, написаны именно на этом движке.

Как создаются игры с помощью игровых движков

Для разработчика игровых приложений движки представляют собой программную среду, в которой он ведет разработку проекта. Ее использование позволяет не заниматься такими рутинными вещами, как описание работы с графикой, звуком и физической моделью. Но это не значит, что программировать не придется ничего. Разработчику все равно потребуется писать скрипты для внутриигровых действий. На Unity, например, потребуется работа с C#, да и на Unreal Engine знание языков программирования не помешает.

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

Использование игровых движков позволяет избавиться от написания кода для очень многих рутинных моментов, так как, кроме самих движков, для них существует огромное количество библиотек и расширений. С их помощью первые простейшие игры на Unity можно создать уже через несколько часов изучения платформы. Специально для начинающих в Unity существует масса проектов вроде Creator Kit и Microgame, предлагающих большое количество исходных материалов для написания простых приложений в 2D и 3D. На Unreal Engine также есть множество библиотек и уроков, позволяющих быстро освоить программную среду и начать писать простые игровые приложения.

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

Так что же такое игровой движок для игрока и разработчика?

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

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *