OpenGoW
GameDev.ru / Сообщества / OpenGoW / OpenGoW: Прогресс за ноябрь

OpenGoW: Прогресс за ноябрь

Автор:

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

Структура движка


Как и у большинства других прослоек между играми и игроками, в God Of War (Kinetica, Jak II+3+X, The Getaway, SOCOM I+II, FantaVision - другие игры на этом движке) движок поделён на сущности. А этими сущностями управляют их соответствующие центральные классы со своими гигантскими методами Update. Так вот тут эти классы называются серверами (упоминания слово "сервер" как паттерна я не нашел. Ближайшим аналогом являются Manager классы из библии авторства Jason Gregory), по своей сути являются они смесью одиночки и фабрики.
+ На самом деле все немного сложнее

Так-же у каждого сервера есть свой уникальный id (индекс в глобальном массиве серверов). Используются id, например, при загрузке данных из архивов (каждый файл внутри архива содержит id), чтобы понять, метод Unmarshal какого сервера нужно вызвать чтобы загрузить этот файл.
Привожу список некоторых серверов. Имена у большинства взяты из бинарника:
  • Master Server
    Управляет другими серверами, его метод Update вызывает обновление всех остальных серверов (остальные сервера являются экземплярами этого сервера).
    Что тут говорить, если основной цикл игры выглядит примерно так:
    while(true) {
        g_pMasterServer->Update();
        g_pTimer->AdjustTime();
    }
  • GameObject Server
    Хранит игровые объекты с ссылками на подчиненные партиклы/модели/коллайдеры.
    Группирует объекты в чанки карты (cxt).
  • Animation Server
    Управляет анимацией, при этом оперирует малейшими примитивами (matrix4, vector2), умеет интерполировать между временными промежутками.
  • Script Server
    Логика игры. Кстати, все игровое меню сделано через него и лежит в одном файлике.
  • GFX_CLUT Server
    Управляет буферами, подготавливает пакеты для передачи их в графический процессор.
  • Texture Server
    Инстансы этого сервера связывают буферы CLUT(Color lookup table или палитра) и GFX(индексы для палитры). Также экземпляры текстур могут "наследоваться" друг от друга, это, например, используется для "mip" текстур, в данном случае маленькая текстура наследует палитру большей.
  • Material Server
    Очевидно что инстансы этого сервера содержат ссылки на разные текстуры (отражений/цвета), цвет, параметры освещения, тип смешивания.
  • RenderMaster Server
    Сервер создает несколько подопечных серверов, вот некоторые из них:
    • Particle Render Server
    • Flash Render Server
    • Shadow Render Server
    • Static triangle strip Render Server
      Все они в сумме работают над одной задачей - подготовить в памяти один большой пакет, который в итоге отрисует один кадр. В нем будут все модели/матрицы/программы для векторного процессора/переключения контекста/текстуры. Это все делали для того чтобы dmac контроллер шины разбирая этот большой пакет занимался отрисовкой текущего кадра, когда мы сможем готовить новый пакет для следующего кадра. При этом получается максимальное распараллеливание, когда 4 устройства: центральный процессор, контроллер шины, векторный процессор и графический процессор работают параллельно. Ну не совсем прям параллельно, например локи синхронизации между векторным процессором и графическим, чтобы первый не начал рисовать модель, когда её текстура еще не загружена, и в таком роде. Но вот лучше не придумаешь. При этом картинка страдает в задержке (пакет текущего N кадра формируется в памяти, N-1 кадр рисуется в swap-buffer, N-2 кадр на экране) в сравнении с привычной нам схемой (N кадр рисуется в swap-buffer, N-1 на экране), но выигрывает в пропускной способности.
  • Epilogue Server
    Prologue Server
    Пролог сервер отрабатывает свой Update раньше остальных, при этом создает разные буферы для "отрисовки" кадра.
    Эпилог сервер обновляется последним, при этом инициирует swap буферов и обработку пакета со следующим кадром dma контроллером.
  • Collision Server
    Управляет физикой. Содержит глобальную переменную гравитации, что не раз помогало в исследовании работы движка.
    Так-же влияет на подгрузку чанков карты. Точнее каждый чанк карты содержит инстанс статичной коллизии, привязанный к этом чанку. И определение на принадлежность игрока к чанку как-раз определяется через коллизию.
    + Фотография рабочего места разработчика, с отображением статичной коллизии чанка уровня в редакторе

  • Кроме всего этого из заметных классов есть виртуальная файловая система, но она (вроде) не является отдельным сервером, хотя используется буквально везде.

    Итог


    Игровой движок в роликах о создании игры позиционировался как очень гибкий. Что мы и видим, ведь, допустим, заменив привязанные к железу сервера, можно с минимум последствий перенести игру на другую платформу (соответствующие ресурсы придется перекомпилировать), что мы и скорее-всего и наблюдали при перевыпуске gow на ps3 и ps4. Еще заявлялось о гибкости для гейм-дизайнеров и художников, что видимо вытикает в то что большая часть игры (за исключением требовательных к скорости мест) лежит в игровых архивах.

    Благодарности


    Большое спасибо nonamezerox за помощь и наводки в нужном направлении.

    А так же в разборе наследования классов мне помогает компилятор, которым пользовались разработчики. Он вежливо переопределяет таблицу виртуальных методов класса в конструкторе и деструкторе этого экземляра класса, а так как деструкторы/конструкторы класса почти всегда вызывают соответствующие конструкторы/деструкторы своих родителей, тем самым можно извлечь древо наследования (часто мешает inline подстановка).
    Кроме того компилятор очень аккуратно расставляет указатель на таблицу виртуальных методов сразу после полезных данных структуры экземпляра класса, из чего мы можем делать вывод о размере этой структуры данных (работает только для самых корневых (не детей, а от которых наследуются) классов).
    Так же если он видит вложенную структуру, то перед там как поработать с ней, любезно высчитывает указатель на эту структуру, а потом уже начинает работать с ней (из этого можно судить о наличии этих вложенных структур и их смещение относительно основных).
    Конечно у него есть и минусы, но я его прощаю, ведь они присущи всем компиляторам с флагом -O2, а именно сплошь и рядом подстановка функций (inline), что заставляет разбирать похожие места кода лишь чтобы убедиться что они делают то-же самое.

    todo


    Основными целями сейчас исследование внутренностей. В идеале нужно разобрать форматы файлов от младшего к старшему (GFX > TXR > MAT > MDL), но пока выходит не очень ладно из-за наличия второстепенных классов и кучи интересных особенностей приставки ps2

24 ноября 2016

#god, #god of war, #opensoure, #PS2, #reverse, #движки

2001—2017 © GameDev.ru — Разработка игр