Записки велосипедиста #2 - Внутренности игровых движков

Добавлен , опубликован

Записки велосипедиста #2 - Внутренности игровых движков

Здравствуй, %username%!
Этот ресурс - продолжение цикла познавательных "Записок велосипедиста", в котором я рассказываю про свои "приключения" и даю ссылки на интересные материалы для домашнего изучения.

Дисклеймер

Если Ваши grammar Nazi's чувства не позволяют вам наблюдать жаргонизмы и некоторые случайные орфографические или пунктуационные ошибки - немедленно крикните три раза "Ко-ко-ко", позвоните по номеру 03, сообщите своё текущее местонахождение и объясните прибывшим специалистам суть Вашей проблемы.

Вступление

Доброго времени суток!
Сегодняшний номер, как я и обещал, будет более практикоориентирован.
Кода не будет, так как нефиг, рано ещё код смотреть! Батя в вашем возрасте кушал кислоту и тыкал иглой в перфокарты, а о коде мог только мечтать! Так что нефиг, рано ещё!
Сегодня мы поговорим о программных внутренностях игровых движков. Итак, приступим.

На кой мне сдался ты, товарищ?

Собственно. Игровой движок - инструмент, который облегчает процесс создания в первую очередь технической части игр.
Из чего состоит эта техническая часть? Мы можем понять это исходя из того, что умеет любая игра:
  1. Узнавать о том что игрок нажал клавишу на клавиатуре, кликнул кнопку на мышке или использовал любой другой источник ввода.
  1. Обрабатывать эту информацию, переводя непонятные для игры события, в понятные. Например: игра не понимает что значит "Ctr + 1", но обработав это сочетания в соответствии с контекстом мы можем получить то, что понимает игра: "Выбрать войска на карте, принадлежащие к группе 1".
  1. Исполнять действия, связанные с этим событием. Например, в соответствии с предыдущим событием, игра убирает текущее выделение, получает все войска, входящие в группу 1, каждого выделяет и переносит фокус камеры на одного из них.
  1. Исполнять всякие другие действия, предусмотренные замыслом игры. Например менять день на ночь или обрабатывать столкновения объектов в игровом мире.
  1. Уведомлять игрока о событиях, произошедших в игровом мире. Это рендеринг (прорисовка) мира на экран монитора, звуки из колонок, вибрация на геймпаде и прочее, из чего игрок получает информацию от игры.
Именно постоянное чтение ввода и вывод делают игру интерактивной.
И с каждым из пунктов, игровой движок может оказать вам неоценимую помощь, взяв на себя большую часть, а то и полностью автоматизировав и унифицировав то, что лежит в основе этих пунктов, предоставляя вам каркас, который содержит всё, для того, чтобы сделать процесс разработки игры легче!

И что это за магия?

Для выполнения своей миссии, игровые движки организуют в той или иной мере обособленные системы, из которых очень часто можно выделить следующий список:
  1. Контроллер игрового процесса (ядро) - организует работу пользователя с движком, определяет ход выполнения игровой программы, управляет работой других систем.
  2. Система событий - используется другими системами движка для общения между собой.
  3. Система отладки, профилирования и обработки ошибок - записывает системные события, ошибки и осуществляет мониторинг памяти и прочих ресурсов, используемых движком.
  4. Система ввода - получает события от устройств ввода, обрабатывает и передаёт их в систему событий.
  5. Система ассетов - управляет загрузкой и выгрузкой в память любых ресурсов. Облегчает работу с этими ресурсами.
  6. Менеджер сцены - управляет сценами и игровыми объектами/сущностями на этих сценах.
  7. Физический движок - симулирует физические явления игрового мира, управляя игровыми объектами.
  8. Система анимаций - позволяет анимировать модели, текстуры и в идеале что угодно.
  9. Звуковой движок - позволяет воспроизводить любые виды музыки и звуковых эффектов, симулирует физические явления, связанные со звуком в игровом мире.
  10. Визуализатор - превращает сцену, на которую он смотрит с определённого ракурса, в картинку, которая затем, например, попадает на экран монитора.
  11. Сетевой движок - позволяет использовать сетевые подключения для создания многопользовательских игр.
  12. Скриптовый движок - интерпретирует маленькие DSL-программы (скрипты) и применяет описанную в них логику в контексте игры.
  13. Система игрового ИИ - облегчает работу с игровым ИИ.
Это очень сжатое описание основных подсистем движка. Каждая из этих систем, в свою очередь может состоять из множества других. Некоторые из систем работают каждую итерацию игрового цикла (тик) (физический движок к примеру), некоторые - работают при смене сцены или других событиях (например система ассетов).
Кроме того отдельно можно выделить утилиты, являющиеся в некотором роде библиотеками. Их назначение - облегчить некоторые операции, но в отличии от систем движка, утилиты можно не использовать вообще. Например: класс, содержащий методы, упрощающий какие-то вычисления. Движок может его не использовать, а разработчик в свою очередь может им воспользоваться.

Многабукаф, но я осилил. Что дальше?

Я тоже. А дальше...
Дальше только ещё больше букаф. А вы что предполагали?
Теперь мы плавно подъехали к вопросу: как же эти системы взаимодействуют между собой в игре?
На этот простой вопрос, у каждого движка может быть свой ответ.
Однако в целом, мы можем заметить сходства каждого движка. Они заключаются в порядке исполнения итоговой игровой программы (и на этом очень часто заканчиваются):
  • Игрок запускает игру
  • Из кода игры (или сразу) запускается ядро, которое сразу же инициализирует системы движка
  • Управление возвращается в код игры для инициализации систем самой игры
  • Ядро заканчивает инициализацию систем и запускает игровой цикл
  • Каждый тик:
    • Система ввода получает события ввода от устройств ввода, а также обновления состояния от сетевого движка.
    • Управление возвращается в код игры и в скриптовый движок для выполнения необходимых операций
    • Движок передаёт управление физическому движку, системе анимаций и прочему вычисляющему сброду
    • На основе нового состояния, движок при помощи звукового движка и визуализатора, выдаёт результат работы игроку
  • После того как игровой цикл был остановлен, управление передаётся коду игры для того, чтобы игра могла остановить свои системы
  • Затем происходит остановка систем движка и возвращение в код игры (где уже завершается программа)
Это простейший алгоритм работы клиентской версии игры. Для серверной версии нет необходимости выводить что-либо на экран. Только получать от программ-клиентов данные, обрабатывать и отсылать им своё состояние.

Вроде не сложно...

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

Линк тайм

По Java ресурсов полно в интернете, что аж блюёт, но рекомендую: Теперь по теме: Если есть дополнения - предлагайте :)
В каждом номере мы будем анализировать существующие подходы и делать то, что уже сделано, но как можно лучше.
Если Вам интересна данная тема - не стесняйтесь и жмите "Мне нравится" :3
Я долго думал насчёт того о чём писать следующий номер и понял, что лучше будет спросить об этом у вас, дорогие друзья!
Опрос: О чём делать следующий номер?
1. 
Подробнее об игровом цикле и взаимодействии компонентов (на примерах)
2. 
Об известных компонентах, используемых во многих игровых движках (Bullet, OpenGL/Direct3D, FMOD, Havok, PhysX и иже с ними)
3. 
Об истории игровых движков (это вообще кому-нибудь интересно?)
4. 
Обо всех перечисленных системах в отдельности
5. 
Написал в комментариях
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
10
8 лет назад
Отредактирован ZLOI_DED
0
prog:
Не упомянуты такие вещи, как Entity System (хотя далеко не все ими пользуются, конечно - сложная штука), многопоточность, система работы с шейдерами (странно видеть отдельно сетевую систему, систему анимаций и систему загрузки ассетов, но не видеть отдельную систему для работы с шейдерами). Кроме того, универсальная система событий далеко не всегда есть в наличии "из коробки", например готовая реализация может использоваться только для обработки пользовательского ввода, а дальше уже как хочешь, так и выкручивайся. Сетевая компонента тоже часто представлена не полноценным движком, а на уровне вспомогательной библиотеки. Также ни слова не сказано про специальные форматы для ассетов, которыми грешат практически все движки.
Вроде все, что с первого раза на глаза попалось, завтра перечитаю еще раз.
Entity System - я подразумевал как часть менеджера сцены. Отдельно обычно не существует.
Многопоточность - относится к устройству контроллера игрового процесса (ядру). Отдельно выделить нельзя.
Система работы с шейдерами - это часть визуализатора.
Про систему событий и сетевой движок... я специально сказал что данный список можно выделить очень часто. Т.е. не все так делают, но большинство.
Про спец. форматы - это обзорный номер. Не знаю почему они ими "грешат", но это так или иначе часть системы ассетов.
Благодарю)
alexprey:
система работы с шейдерами (странно видеть отдельно сетевую систему, систему анимаций и систему загрузки ассетов, но не видеть отдельную систему для работы с шейдерами)
Сперва подумал, что что тут странного, но раз система анимаций вынесена. То вопрос действительно остается открытым.
ZLOI_DED:
Очень интересно узнать про реализацию сетевого движка.
Система анимаций вынесена отдельно, т.к. она занимается не связанной с физ. движком деятельностью.
А вот шейдеры привязаны к визуализатору и поэтому выделить их в отдельную систему не получается.
Хорошо. А что интересно? Как взаимодействуют клиент и сервер, какие протоколы используются, в чём их преимущества или всё сразу?)
Спасибо за фидбек!)
P.S. На самом деле здесь разделение систем даже более теоритическое чем то, какое бы вы делали в действительности. Т.к. смысла например, выносить систему событий из ядра, нет, но по сути это отдельная система, отдельный топик о котором можно говорить. :)
0
24
8 лет назад
0
Entity System - я подразумевал как часть менеджера сцены. Отдельно обычно не существует.
Не имеет прямого отношения к сцене, не путать с аналогичной терминологией в юнити. Речь о data-driven организации игровой логики и соответствующем представлении всех игровых объектов. Сцена с её геометрией строится на основе данных из Entity System, но при этом Entity System может содержать не отображаемые на сцене данные и даже существовать отдельно от сцены в случае сервера. Сливать воедино объекты на сцене и игровую логику это дурной тон и больно кусается при масштабировании проекта - даже в движках позволяющих такое, желательно в объектах сцены оставлять только логику, связанную с отображением, а все остальное выносить отдельно.
Система анимаций вынесена отдельно, т.к. она занимается не связанной с физ. движком деятельностью.
Но ведь система анимаций это, как правило, тоже часть визуализатора, как и шейдеры.
0
29
8 лет назад
0
Хорошо. А что интересно? Как взаимодействуют клиент и сервер, какие протоколы используются, в чём их преимущества или всё сразу?)
Да, интересует именно архитектура взаимодействия)
0
10
8 лет назад
Отредактирован ZLOI_DED
0
prog:
Entity System - я подразумевал как часть менеджера сцены. Отдельно обычно не существует.
Не имеет прямого отношения к сцене, не путать с аналогичной терминологией в юнити. Речь о data-driven организации игровой логики и соответствующем представлении всех игровых объектов. Сцена с её геометрией строится на основе данных из Entity System, но при этом Entity System может содержать не отображаемые на сцене данные и даже существовать отдельно от сцены в случае сервера. Сливать воедино объекты на сцене и игровую логику это дурной тон и больно кусается при масштабировании проекта - даже в движках позволяющих такое, желательно в объектах сцены оставлять только логику, связанную с отображением, а все остальное выносить отдельно.
Система анимаций вынесена отдельно, т.к. она занимается не связанной с физ. движком деятельностью.
Но ведь система анимаций это, как правило, тоже часть визуализатора, как и шейдеры.
Всё что является игровой сущностью должно находится на сцене (не обязательно иметь свойства нужные для отображения и пр.). Поэтому я обобщил в менеджер сцены. Сцена логическая, а не визуальная или физическая или какая-нибудь ещё.
А вообще можно переименовать в менеджер игровых сущностей, да, согласен.
А если система анимаций влияет на что-то кроме визуального результата, возвращаемого игроку? Тут не всё так просто.
alexprey:
Хорошо. А что интересно? Как взаимодействуют клиент и сервер, какие протоколы используются, в чём их преимущества или всё сразу?)
Да, интересует именно архитектура взаимодействия)
Ок, обязательно напишу про это :)
2
24
8 лет назад
2
ZLOI_DED, Entity System в чистом виде штука довольно сложная для восприятия. "Сущность" в ней это всего-навсего числовой идентификатор и связанный с ним контейнер для "компонентов", представленных в виде данных, а весь код вынесен в глобальные "системы", которые выбирают интересующие их сущности по набору компонентов и выполняют с ними различные действия. При этом, например, событие нанесения урона цели тоже может быть сущностью - в компоненты этой сущности заносятся такие параметры как источник урона, тип, количество и, конечно, цель, затем соответствующая система выбирает все сущности с компонентами нанесения урона и применяет этот урон к цели, учитывая компоненты цели, которые могут содержать, например, общую защиту от урона или сопротивляемость какому-то конкретному типу урона. После обработки, естественно, сущность для нанесения урона уничтожается. Это не просто менеджер сцены или какая-то отдельная подсистема, это подход к построению архитектуры всей игровой логики. Я не предлагаю подробно писать об этом, особенно если ты сам с этим еще не сталкивался, но нельзя писать об игровых движках и не упомянуть эту тему.
2
10
8 лет назад
2
prog:
ZLOI_DED, Entity System в чистом виде штука довольно сложная для восприятия. "Сущность" в ней это всего-навсего числовой идентификатор и связанный с ним контейнер для "компонентов", представленных в виде данных, а весь код вынесен в глобальные "системы", которые выбирают интересующие их сущности по набору компонентов и выполняют с ними различные действия. При этом, например, событие нанесения урона цели тоже может быть сущностью - в компоненты этой сущности заносятся такие параметры как источник урона, тип, количество и, конечно, цель, затем соответствующая система выбирает все сущности с компонентами нанесения урона и применяет этот урон к цели, учитывая компоненты цели, которые могут содержать, например, общую защиту от урона или сопротивляемость какому-то конкретному типу урона. После обработки, естественно, сущность для нанесения урона уничтожается. Это не просто менеджер сцены или какая-то отдельная подсистема, это подход к построению архитектуры всей игровой логики. Я не предлагаю подробно писать об этом, особенно если ты сам с этим еще не сталкивался, но нельзя писать об игровых движках и не упомянуть эту тему.
Хорошо написал, мне понравилось)
Я понял о чём ты и это в действительности основывается на менеджменте сцены (всё-таки верну это название... оно правильнее будет), системе событий и устройстве ядра.
Просто я не предполагал управление сущностями вне какого-либо контекста, от которого они зависят, поэтому и поместил их внутрь управления сценой.
Если ты имеешь ввиду подход к построению игровой логики, а не конкретную систему движка, то это материал для ещё одного номера, в котором надо обозреть также и другие подходы, сравнить их, определить преимущества и недостатки каждого и т.п.
Так что благодарю, обязательно упомяну об этом подходе в одном из следующих номеров)
0
33
8 лет назад
0
"Сущность" в ней это всего-навсего числовой идентификатор и связанный с ним контейнер для "компонентов", представленных в виде данных
Это же типа как handle в Варкрафте?
0
24
8 лет назад
0
Кет, сам по себе хендл мало о чем говорит - должны быть все три составляющие - хендл, привязанные к хендлам компоненты-данные и глобальные системы-логика. Я не исключаю, что близы могут пользоваться принципами Entity System, вроде даже даты разработки попадают примерно на времена возникновения этой концепции, но у меня нет совершенно никаких подтверждений тому, что это действительно так.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.