Найти в Дзене
Сделай игру

Архитектура игры

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

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

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

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

Для начала игру можно поделить на несколько этапов:

  • Загрузочный экран [начальная заставка]
  • Экран меню и настроек [выбрать новую игру, загрузиться, настроить параметры видеокарты и звука]
  • Возможно, экран заставки (может быть совмещён с загрузочным или появляться ранее) [погружение в игру]
  • Непосредственно игра [управляемый игровой процесс]
  • Настроечные или промежуточные действия внутри игры [изменить громкость звука, собрать по чертежам новое изделие, переместиться по карте]
  • Экран конца игры [послесловие, приглашение продолжить игру или вернуться]

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

"Непосредственно игра" - это то, ради чего всё задумывалось; без этого этапа все остальные не имеют смысла, поэтому его разберём немного подробней. На данном этапе необходимо:

  • Отслеживать поведение игровых персонажей в окружении, при необходимости корректируя его [столкновение объектов, отслеживание пребывания в среде (в воде, на льду, на шипах), контроль попаданий];
  • Управлять расположением камеры и персонажа через управление игры [поворачивать область обзора, передвигать персонажа];
  • Отрисовывать текущее состояния [отображать на экране картинку, позволяющую предельно эффективно видеть происходящее и иметь наилучший контроль над процессом игры].

К слову, приведённые выше 3 пункта - это классический шаблон MVC (model-view-controller), о котором так любили ещё совсем недавно расспрашивать на собеседованиях, по суди, сводящийся к простому тезису: изоляция уровней функционирования приложения. Это значит, что в любой момент можно сменить обработчик поведения игровых персонажей (с локального на удалённый, сетевой), способ управления (с геймпада от PS4 на контроллеры от Nintendo Switch) или метод отображения (с WebGL на Vulcan) без необходимости менять весь код приложения, заменив только соответствующие модули.

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

Собственно, такой же управляющий нужен для взаимодействия всех блоков (модулей) приложения, для переключения между ними. Это не всегда очевидно и, порой, появляется желание передать эти полномочия одному из модулей, что, неизменно, приводят к проблемам со временем: модуль обработки должен быть всегда загружен в памяти и иметь наивысший приоритет, а модуль какого из этапов (упомянутых выше) достоин этого больше всего? Я думаю - никакой.

Итак, для создания игры следует:

  1. Спланировать модули всех игровых экраны;
  2. Разработать управляющего, отвечающего за межмодульное взаимодействие;
  3. Выбрать технологический стек и обеспечить максимальную изоляцию любого из модулей (даже если это и кажется избыточным поначалу, в дальнейшем такая строгость позволит упростить разработку).

Ну, надеюсь, всё понятно. Потом ещё напишу на эту тему.

Просто картинка для иллюстрации. Не самая удачная, но по теме :-)
Просто картинка для иллюстрации. Не самая удачная, но по теме :-)