S.T.A.L.K.E.R. на движке Doom 2. Начало
В связи с происходящими событиями верным фанатам серии S.T.A.L.K.E.R. не остается ничего, кроме как ждать у моря погоды и надеяться на нормализацию геополитической обстановки.
А ведь может случиться, что мы никогда не увидим Heart of Chornobyl. Учитывая времена, в которые возвращается наш Мир, предлагаю вооружиться инструментарием для модификации Doom 2 и создать свой собственный S.T.A.L.K.E.R., с маслинами и монолитовцами.
Сразу скажу, что я не буду подробно останавливаться на процессе создания уровней или работе со Slade3, так как это уже сделали за меня.
Нам потребуется:
В этой статье я расскажу о том, с какими трудностями столкнулся уже спустя десять минут после начала процесса, и объясню, как добавлять в Doom новые объекты.
X-Ray SDK
Eсли с моддингом Doom я давно знаком, то с моддингом S.T.A.L.K.E.R. сталкивался только в качестве потребителя контента. Первым делом я решил распаковать все необходимые данные из архивов S.T.A.L.K.E.R. Shadow of Chernobyl, то есть текстуры, модели и звуки.
Программу для распаковки архивов я нашел довольно быстро. Называется она Unpacker for Steam by E1nher1. Как видно из названия, работает эта программа только со Steam версией игры.
Все архивы лежат в корневой папке S.T.A.L.K.E.R. Shadow of Chernobyl с расширениями от db0 до dbd. В этих архивах хранятся текстуры, звуки, музыка, модели, скрипты, файлы конфигурации и данные уровней. Я распаковал их в одну папку. Это потребуется в будущем для работы с X-Ray SDK.
Нам нужны следующие разделы:
- textures (все текстуры хранятся в формате dds. Для преобразования этих файлов в png я использовал программу XnView);
- meshes (модели в формате ogf. О них чуть позже);
- levels (для работы с уровнями нужно настроить X-Ray SDK);
- sounds (звуки и музыка в формате ogg).
После этого начался длительный и мучительный поиск рабочей версии X-Ray SDK. Я облазил десятки форумов, руководств в Steam и просмотрел несколько YouTube-роликов, прежде чем мне помогли. В этом ролике парень подробно объясняет, как установить и настроить X-Ray SDK, а также, как преобразовать игровые уровни в понятный редактору формат. Дело в том, что официальная версия X-Ray SDK была выложена GSC аж в 2007 году. Соответственно, на современных системах она работать отказывается.
Для распаковки уровня потребуется утилита converter. В дополнение к сказанному в видео скажу, что в BAT-файле необходимо прописать наименование исходного уровня и его название при распаковке. А в файле converter.ini прописать абсолютные пути к папкам levels и gamedata. Подробная информация лежит здесь.
Уровень распакован и лежит в папке maps. Открываем его в редакторе уровней.
Управление в редакторе нестандартное. В обычном режиме перемещение камеры по X и Y осуществляется с помощью SHIFT + LMB, по Z — SHIFT+RMB, а поворот камеры — SHIFT+LMB+RMB. Для дальнейших действий это не очень полезная информация, но если хочется изучить карту и использовать ее в качестве референса — это хороший вариант.
Кроме того, редактор уровней позволяет найти на карте нужный объект и посмотреть его имя. Об этом ниже.
Blender
Если с текстурами для геометрии уровня все просто: конвертируем dds из папки textures в png, предварительно просмотрев больше тысячи файлов и отделив нужные, то что же делать со спрайтами оружия и окружения?
GZDoom поддерживает три варианта:
- Плоские спрайты в формате png;
- Воксельные модели;
- Полигональные модели.
Изначально я пошел по первому пути, для чего потребовался Blender. Я решил, что буду рендерить модели из S.T.A.L.K.E.R. покадрово с разных сторон.
Чтобы экспортировать модели из S.T.A.L.K.E.R. в Blender, можно воспользоваться плагином blender-xray. Процесс установки описан в readme.
В S.T.A.L.K.E.R. cуществует два вида моделей:
- Модели, которые используют физический движок, в формате ogf. Они находятся в папке meshes. Это и персонажи, и коробки с патронами, и оружие, и разнообразные модели окружения (лампы, ящики, бочки), и даже вырезанный из игры транспорт;
- Модели, из которых состоит уровень (aka лоды), в формате object. К ним относятся здания, сломанный транспорт, мосты, поезда и прочее. Эти модели лежат в папке rawdata/objects. Ради этих моделей мы и конвертировали уровень.
В первом случае все просто. Открываем Blender, импортируем объект из папки meshes в формате ogf, и вот он наш Камаз.
С моделями на уровне все немного сложнее. Сперва надо найти название нужного объекта в редакторе уровней S.T.A.L.K.E.R. Для этого подлетаем к нему, правой кнопкой мыши открываем параметры и смотрим на поле name. В данном случае этот автобус называется l01_escape_lod0060
Возвращаемся в Blender, импортируем объект в формате object из папки rawdata\levels\l01_escape и любуемся ржавым автобусом в нормальном редакторе.
В принципе, на этом можно и закончить. Конвертируем автобус в формат obj и засовываем его в Doom. Более подробно я расскажу об этом в соответствующем разделе. Но мы ведь не ищем легких путей, верно?
Создание спрайтов автобуса
Все спрайтовые объекты в Doom могут быть плоскими (например, взрывающиеся бочки) или иметь 8 или 16 ракурсов (например, монстры). Этот автобус мы отрендерим с 16 позиций. Это можно сделать вручную, перемещая камеру по координатам, а можно поступить более хитро. Сразу скажу, что я мало что понимаю в 3D моделировании, поэтому могу ошибаться в своих решениях.
Выставляем камеру на нужную позицию, туда же добавляем источник света и направляем его на модель. После этого создаем Bezier Circle и делаем его родителем камеры и источника света с параметром Path Following (Ctrl + P). В настройках Bezier Circle нужно включить Path Animation и установить 16 фреймов анимации.
После этого в настройках рендера включаем прозрачность и нажимаем Render Animation (Ctrl + F12). Получится 16 изображений. Их надо обрезать, чтобы занимали чуть меньше места.
Сразу скажу, что такой способ лучше использовать для маленьких или симметричных моделей (лампы, бочки, патроны и т.д.), потому что вот такой автобус будет выглядеть очень нелепо при переносе в Doom. Для примера, конечно, сойдет. Как я и говорил, его лучше импортировать в Doom в виде обычной 3D модели, чем мы вскоре и займемся.
Перенос автобуса в Doom в виде спрайтов
Открываем Slade3 и создаем новый архив формата pk3. Дело в том, что такой архив позволит хранить файлы упорядоченно. Классический wad файл этого не позволяет. Подробно о хранении ресурсов в архиве pk3 можно прочитать здесь.
Прежде чем переносить файлы в архив, нужно их переименовать. Наименования спрайтов в Doom состоят из 6 символов в формате AAAA X N, где AAAA — название спрайта, X — название анимационного фрейма (от A до Z и /), N — номер спрайта при смене ракурса, при этом N меняется от 1 до 8 при восьми ракурсах и от 1 до G при 16 ракурсах (ноль — если объект плоский и не меняет спрайты при смене ракурса). Более подробная информация.
Получается следующее:
Переносим эти спрайты в архив и приступаем к созданию объекта. Первым делом нужно идентифицировать параметры спрайтов. Для этого выбираем все спрайты и правой кнопкой добавляем в файл (или ламп) textures. В корне архива будет создан новый файл с параметрами текстур.
После этого открываем редактор текстур и меняем тип каждого изображения на Sprite, а потом уменьшаем изображения в размерах. Придется поэкспериментировать, чтобы объект не выглядел огромным или слишком маленьким. Помимо этого нужно расположить каждый спрайт над уровнем «земли», то есть настроить offsets.
Код новых объектов находится в лампе decorate. По сути своей это набор классов, которые называются Actors. При этом можно наследовать новые классы от уже имеющихся в Doom. Decorate должен находиться в корне архива. Создаем Actor нового автобуса.
Каждый Actor имеет поля, флаги и состояния (states). Мы создаем самый простейший Actor, поэтому он содержит всего одно состояние — Spawn, в которое объект переходит при появлении на уровне. Число 30000 после названия определяет номер этого объекта в редакторе уровней.
Про поля и флаги говорить особо нечего. Radius определяет радиус объекта, а Height — высоту. Чтобы сквозь автобус нельзя было пройти, добавляем ему флаг Solid. После этого прописываем состояние Spawn. BUS1 — это название спрайтов, A — единственный кадр, а (-1) — это количество времени, которое показывает, сколько наш объект будет отображать кадр A. Так как это число равно (-1), то меняться кадр не будет. Stop означает, что после отрисовки единственного кадра, объект не будет возвращаться в начало состояния Spawn.
Если бы у нас был анимированный автобус (например, с моргающими фарами), то код выглядел бы так:
Слово Loop означает, что объект зацикливает состояние Spawn, и в каждой итерации меняет последовательно два кадра с задержкой в 8 тиков. Один тик равен 1/35 секунды.
Создаем в Ultimate Doom Builder простенький уровень. Помещаем на этот уровень автобус.
Заметили, насколько странно это выглядит. Поэтому я и говорил, что большие и длинные объекты должны оставаться полноценными моделями, а не спрайтами. Сейчас мы исправим это недоразумение.
Перенос автобуса в Doom в виде полигональной модели
Процесс переноса 3D моделей в GZDoom может показаться запутанным, но на самом деле все не так сложно.
Первым делом нужно экспортировать модель из Blender в формат obj, но при этом полученный файл нужно немного модифицировать.
Для этого открываем файл любым текстовым редактором, удаляем строчку, которая начинается c mtllib, а также удаляем все строчки, которые начинаются c usemtl. Это нужно для того, чтобы Doom при запуске уровня не пытался обратиться к несуществующим файлам материалов. Сразу оговорюсь, что это нужно делать не всегда. Если модель покрывают несколько материалов (читай, текстур), то в строках usemtl нужно прописать абсолютный путь к этим текстурам.
Находим нужную текстуру в папке с ресурсами из S.T.A.L.K.E.R.
В архиве создаем папку models, внутри нее папку busmdl и помещаем туда файл obj и текстуру в формате png. Дальше начинается самое интересное.
Сперва нужно занести данные о модели в ламп modeldef, который также всегда создается в корне архива.
Path — это путь до папки с моделью. Model — имя файла obj. При этом моделей может быть несколько. За номер модели отвечает индекс перед названием файла. Таким же образом прописываются текстуры — Skin определяет имя файла. Scale отвечает за размер модели. Так как в S.T.A.L.K.E.R. используется система измерения, основанная на реальной метрической системе, а в Doom — собственная система, то модель необходимо увеличить в 32 раза (в данном случае).
Useactorpitch и Useactorroll подстраивают наклон и поворот будущего объекта под поворот и наклон модели.
FrameIndex определяет наименование нашей модели, которое будет использоваться при создании объекта (читай, имя спрайта). BUS2 — наименование спрайта, A — имя кадра. Первый нуль отвечает за номер модели, а второй — за номер кадра.
После того, как мы идентифицировали модель, нужно создать игровой объект в файле decorate.
Объект модели создается точно также, как и обычный спрайтовый объект. В глаза сразу бросается, что радиус автобуса составляет всего 8 пунктов. Это связано с тем, что объекты в Doom всегда имеют квадратную коллизию, а автобус довольно длинный. Поэтому будет проще поместить автобус на уровень и ограничить движение игрока отдельными линиями с присвоением им флага impassable. Из-за этого не нужно добавлять флаг solid, как мы делали в предыдущем случае.
В состоянии Spawn нужно прописать то название модели, которое мы вносили в файл modeldef, то есть BUS2.
Добавляем автобус на уровень и смотрим, что получается.
Как вы видите, использовать модели для таких больших объектов намного предпочтительнее. Мало того, что игра не подтормаживает от постоянной смены спрайтов, так и выглядит модель более аутентично.
На сегодня можно заканчивать. В следующий раз, если будем живы, еще больше углубимся в процесс создания новых объектов для Doom на примере S.T.A.L.K.E.R. Я расскажу про различные состояния объектов, мы создадим новое оружие (склоняюсь к двустволке, потому что это намного интереснее, чем делать банальный ПМ) и патроны к нему.
Всем Мира!
Неплохо, хороший хабар.
Сталкер 2 возможно не выйдет поэтому мы перенесем ТЧ НА ДВИЖОК ВТОРОГО ДУМА НАХУЙ.
Комментарий недоступен
Мы не ищем лёгких путей:)
фар край последний прошел уже?
Для торрента нужно что бы игра вышла, про это и цитата.
О! Вот это очень годно! Аж прям самому захотелось что-то сделать на движке. Но вот вопрос, как движок рассчитывает освещение на таких моделях? Просто берет значение освещенности с пола как в Кваке, или там какой-то продвинутый алгоритм?