Движок Doom

Материал из Викитропов
Перейти к навигации Перейти к поиску

Движок Doom (Doom engine, позднее названный id Tech 1) — один из двух легендарных псевдотрёхмерных движков для стрелялок от первого лица. До появления конкурента, Build, он был самым продвинутым движком и образцом для подражания. И ранним образцом игрового middleware: несколько игр сделаны сторонними фирмами.

Перестрелка Doom превосходила таковую у Duke Nukem 3D (основная тактика «Дюка» — обложиться чем-то взрывчатым и кемперить[1]), а редакторов было много и все они очень просты — так что движок точно остался в сердцах геймеров.

Возможности

✅ превосходит Build; 〰️ на уровне с Build; 🟡 несколько отстаёт от Build; ❌ серьёзно отстаёт от Build; ➰ несравнимо

  • Общие:
    ➰ Автор: Джон Кармак (id Software)
    〰️ Жанр игр: FPS
    🟡 Написан на языке Си, игровая логика пишется на нём же. ✅ В Hexen — часть логики уровня может писаться байт-кодом, язык для этого байт-кода был реконструирован хакерами.
    〰️ Сложный звук со стерео, изменчивой скоростью проигрывания и приоритетом одних звуков над другими. Микшированием занимается внешняя библиотека: DMX в оригинале и Allegro в большинстве DOS-портов. ✅ Поддерживался динамик, благодаря той же DMX. ❌ В части игр стерео и изменчивая скорость из-за глупой ошибки не работают. 🟡 К каждому объекту привязан ровно один играющий звук, из-за чего появился известный баг — «глушить BFG».
    〰️ Собственный дисковый кэш/подкачка.
    🟡 256-цветная графика. Штатно предусматривалось разрешение 320×200, и переделки под SVGA требуют много работы и над меню, и над рендерером.
    ✅ Системные требования на 320×200 — старшие 80386, 4 мегабайта (минимальные Doom), младшие Pentium или разогнанные 5×86, 8 мегабайт (оптимальные).
    ❌ Системные требования на 640×480 — значительно выше, чем у Duke Nukem 3D.
    〰️ Обзора вверх-вниз изначально (в Doom) не было, но пишется за день — в двухточечной (не полностью перспективной) проекции. Физика стрельбы выше-ниже существовала изначально (с некоторыми багами). Но: Образ греха, последний уровень Doom II, полагается на то, что стрелять можно только прямо, и с обзором вверх-вниз проходится на халяву.
    〰️ Стрельба традиционными методами — хитсканом и снарядами.
    〰️ Демо-запись на командах управления.
    〰️ Мультиплеер архитектуры «равный с равным», на передаче команд управления, без всякой защиты от читерства или долгого пинга. Вступление в начатую игру невозможно.
    ✅ Скорость игры — 35 тактов в секунду (половина штатной частоты VGA, у Duke Nukem 3D всего 30). В портах для приставок пришлось снижать до 30 и пересчитывать скорости.
  • Геометрия уровня:
    🟡 Горизонтальные полы и потолки, вертикальные стены. Один этаж. Крыши имитируются «небесными» секторами. Скатов и зачаточной многоэтажности нет ни в одной игре.
    〰️ Примитивное освещение, постоянное для каждого сектора. Чтобы сделать световое пятно, надо сделать несколько секторов друг в друге.
    ❌ Геометрия может только менять высоту пола/потолка (Doom/Heretic), отсюда знаменитые подъёмные двери Doom. В Hexen так называемые полиобъекты могут минимально двигаться по X/Y.
    ✅ Однако секторные эффекты разнообразные и красивые: сектор может утонуть в лаве (или, наоборот, подняться из лавы), могут построиться ступеньки. В портах Doom штатным эффектом сделали даже кабину лифта, когда пол с потолком поднимаются-опускаются синхронно.
    ❌ Масштаб текстур постоянный; рост игрока — 56 текселей. Поворот текстур пола/потолка невозможен; в Heretic и Hexen реализовали сдвиг. С текстурами стен всё значительно свободнее.
    ❌ Следы пуль и крови отсутствуют.
  • Объекты:
    〰️ Объекты — спрайты, 1 или 8 поворотов у каждого, задаётся для каждого кадра анимации по отдельности.
    〰️ Объекты двигаются свободно по всем трём осям. Хитбокс каждого — параллелепипед со сторонами, параллельными осям X/Y/Z. В Doom в некоторых ситуациях хитбокс имеет бесконечную высоту.
    ➰ В Heretic/Hexen существовала простейшая табличная полупрозрачность. Отдельные порты Doom делали до пяти разных уровней прозрачности, и даже специальную для факелов: огонь прозрачный, а палка нет.
  • Разное:
    🟡 Спрайты, текстуры стен и пола/потолка принципиально разные и не могут использоваться друг вместо друга.
    ➰ Методы экономии места в архиве: объединение дублирующихся файлов (в играх не применяется); составные текстуры, состоящие из меньших частей; один спрайт может быть зеркальным отражением другого: например, кадр A поворот 8 может быть зеркальной копией того же кадра A с поворотом 2.
    ❌ Рендеринг окружения — программный, от ближних к дальним, с помощью двоичного разбиения пространства. Одновременно находит видимые объекты и рисует 64 ближайших от дальних к ближним. Из-за такого рендерера WYSIWYG-редактирование невозможно.
    〰️ Поле зрения не превышает 90°.
    🟡 В ассемблерных функциях вписано горизонтальное разрешение экрана. Разные порты поступают по-разному: самомодифицирующийся код (Doom Legacy); несколько функций для разных разрешений (Smack My Marine Up)…
    〰️ Изначально (в DOS-версии) передача данных идёт через внешний драйвер и можно написать эти драйверы для необычных способов передачи данных вроде TCP/IP и цепочки COM-кабелей.
    ✅ Существовало множество сторонних редакторов, в том числе крайне дружественных.
    〰️ Современная лицензия: GPL2

Что на нём написано

  • Doom (1993) — id Software. Аддоны и продолжения:
    • Doom II: Hell on Earth (1994)
    • Ultimate Doom (1995)
    • Master levels for Doom II (1995)
    • Final Doom (1996)
  • Heretic (1994) — Raven Software. Единственный аддон:
    • Heretic: Shadow of Serpent Riders (1996)
  • Hexen: Beyond Heretic (1995) — Raven Software. Единственное продолжение:
    • Hexen: Deathkings of the Dark Citadel (1996)
  • Strife: Quest for the Sigil (1996) — Rogue Entertainment

Технические подробности

Поскольку в конце 1998 года Doom (в версии Final Doom, слегка несовместимой по демо-роликам и с Hell on Earth, и с Ultimate Doom) был выпущен в открытый доступ (сначала под образовательной лицензией, а потом, после потери исходников одним из моддеров, и под GPL), технические подробности хорошо известны.

WAD

Формат архива WAD представляет собой простейшую файловую систему с короткими 8-символьными именами без расширений и каталогов. Никакого сжатия нет, однако если вдруг в игре оказываются несколько одинаковых файлов, несколько имён могут указывать на один отрезок данных. В Doom действительно были одинаковые файлы (повторяющиеся мелодии Doom II, часть символов шрифта), но с повторами не справлялись никак, они просто занимали лишнее место.

Однако, в отличие от нормальной файловой системы, порядок файлов в архиве иногда играет роль — для уровней, спрайтов, текстур пола/потолка и другого.

Сборка мелких файлов в большие архивы приветствовалась задолго до Doom (например, Dune II) — небольшой спрайт мог отнимать 1 или 2 килобайта. При 2-килобайтном кластере диска «хвосты» кластеров могут занимать столько же, сколько сама игра! Игры вроде Ecstatica, где тысячи мелких файлов никак не собирались в архив, геймеры недолюбливали.

Точная расшифровка аббревиатуры WAD неизвестна. Наиболее правдоподобная — Where’s All Data, а любимая фанатская — Where’re All Demons. По-русски никакая расшифровка не требуется: да-да, именно туда.

Зонная память

Зонная память (zone memory) — примитивный менеджер памяти/дисковый кэш/подкачка данных, оптимизированный под нужды игры. Он умел всего две вещи.

  1. Загрузить файл в память и сказать: больше не выгружай.
  2. Загрузить файл в память и отметить, что при желании его можно выгрузить.

Несмотря на примитивность, эта штука оказалась настолько эффективной, что авторы рекомендовали выключить дисковые кэши вроде SmartDrive в пользу DPMI-памяти: зонная память работает лучше.

Уровень

Уровень (в Doom) состоит из одиннадцати файлов примитивной файловой системы. Вот они все, не по порядку:

  • Маркер уровня (E1M1 или MAP01). Изначально пуст, в портах в него могут поместить свойства уровня.
  • Пять файлов, которые редактируются редактором: THINGS, LINEDEFS, SIDEDEFS, SECTORS, VERTEXES.
  • Пять файлов, строящихся автоматически при компиляции уровня: SEGS, SSECTORS, NODES, REJECT, BLOCKMAP.

Идеология уровня субтрактивная: пространство заполнено непроходимой материей, и конструктор уровня прорубает в этой материи туннели.

Уровень представляет собой двухмерную карту из вершин (VERTEXES) и отрезков (LINEDEFS). Отрезки бывают односторонними и двусторонними, информация о сторонах хранилась в отдельном файле SIDEDEFS. Замкнутый многоугольник из сторон, не обязательно связный или выпуклый, назывался сектором (SECTORS). THINGS — это разбросанные по уровню точки, которые могут быть как техническими маркерами (одиночный, кооперативный или deathmatch-старт), так и командами для создания настоящих игровых объектов (mobjs = map objects).

Можно связать отрезок с сектором, используя тэги: если у отрезка эффект «открыть дверь многократно при нажатии» и тэг 42, то его активация откроет сектор-дверь, чей тэг 42. Отдельным эффектам не требовался тэг: например, эффект «дверь многократная» говорит, что дверь рядом, со второй стороны отрезка. В отдельных уровнях используются зарезервированные тэги 666 и 667 — условие активации и эффект прописаны в коде игры и привязаны к конкретным уровням.

Вся информация хранится в файлах уровня с точностью до текселя (грубо 3 см). Точность координат в игре значительно выше — 165536 текселя. Стандартные дробные числа с плавающей запятой не используются: например, тригонометрия была по таблице.

Углы ориентации объектов хранятся в файлах уровня с точностью до градуса, но при загрузке огрубляются до 45°. В игре — 1 оборот = 232, но многие расчёты идут грубее: например, в тригонометрических таблицах всего 8192 цифры.

Оптимизации

Чтобы это чудо ухитрялось как-то работать на старших 386, существует множество оптимизаций. И простейшая из них — BLOCKMAP: уровень делится на блоки 128×128 текселей (2×2 телепорта, грубо 4×4 метра). Для каждого блока указывается, какие отрезки через него проходят, это сокращает проверку столкновений.

REJECT — битовая матрица n×n, где n — количество секторов. Если в матрице 0 — монстр в секторе X, возможно, видит игрока в секторе Y, и нужно делать более сложную проверку видимости. Если 1 — точно не видит. Очень немногие программы строили хоть какой-то REJECT, наиболее известные — ZenNode и RMB (Reject Map Builder). Для перестрелки REJECT не нужен — монстров нет.

Главное же происходит, когда рисуется геометрия уровня. Уровень разбит прямой линией на две части, для каждой указан охватывающий прямоугольник. Каждая часть также разбита на две, и так пока в каждой из частей не окажется один выпуклый подсектор — это и есть двоичное разбиение пространства (NODES, SEGS, SSECTORS).

  1. Поскольку поле зрения не превышает 90°, можно найти гарантированно невидимую полуплоскость. Например, если камера смотрит от северо-запада до северо-востока — это будет южная полуплоскость. Если охватывающий прямоугольник целиком в этой полуплоскости — не рисовать!
  2. После этого происходит более точная проверка, попадает ли кусок уровня в сектор обзора. Если не пересекается — не рисовать!
  3. Если кусок уровня — это один подсектор…
    • Проверяем ориентацию каждой его стороны, и если она смотрит на камеру, рисуем, обходя уже зарисованные части экрана.
      • Если подсектор небесный, он рисуется чуть по-другому, но также по столбцам.
      • Если сторона является глухой стеной, или проход выше/ниже поля зрения, или проход схлопнулся до нуля, объявляем столбец полностью зарисованным (стены в нём рисоваться больше не будут). Если окажется, что все столбцы зарисованы, рендеринг прекращается.
  4. Если кусок уровня — это две меньших части…
    • Находим, в какой из них камера. Рисуем рекурсивно сначала эту, потом другую. Другими словами, рисование геометрии идёт приблизительно от ближних к дальним.

Во время этого прохода запоминаются участки пола и потолка (visplanes), объекты и решётки. Если геометрия уровня была слишком сложной, Doom мог вылететь с ошибкой not enough visplanes (порты обычно имеют более крупный массив, или даже расширяют, если заполнится). Они рисуются после.

Графика

Doom имел два формата графики: текстуры пола/потолка (flats) и всё остальное.

Текстура пола/потолка — простой массив 64×64 текселя.

«Всё остальное» — специальный формат графики с хранением по столбцам. Прозрачные тексели не хранятся совсем: взамен указывается, что столбец идёт, например, от Y=2 до Y=20.

Текстуры стен сборные, то есть могут состоять из нескольких графических файлов: например, стена, а поверх неё выключатель. Или световая стена получена размножением одного прямоугольного светильника. Долгий (больше минуты на 5×86) init Doom refresh daemon… в начале игры именно что создавал базу сборных текстур: какие столбцы берутся прямо из текстуры, какие вычисляются на лету и кэшируются. Текстуры глухих стен размножаются только с шагом 128, текстуры решёток (а также фальшивых стен, которые те же решётки) не размножаются и не могут содержать два разных файла в одной строке — потому есть четыре вида текстур, и это надо помнить новоиспечённому конструктору.

  • Высота 128, без дыр, в каждой колонке ровно один графический файл (несколько бок о бок стоять могут). Это самая универсальная текстура; её можно ставить куда угодно — и на глухие стены, и на решётки.
  • Высота 128, без дыр, хоть в одной колонке несколько графических файлов. Их можно ставить только на глухие стены. Если ставить на решётки, будет так называемый эффект Медузы — «кругом змеи, и игра превращается в камень» (начинает жестоко тормозить).
  • С дырами, в каждой колонке ровно один графический файл. Их можно ставить только на решётки, иначе будет эффект тутти-фрутти — рисуются случайные тексели, игра работает быстро. (Из-за зонной памяти и ограничений DPMI ничего не вылетает.) Решётки не размножаются по вертикали.
  • Высота менее 128, без дыр. Их можно ставить только на стены соответствующей высоты и чётко выравнивать, иначе будет то самое «тутти-фрутти». Ну или вместо решёток, если в каждой колонке ровно один файл — так можно сделать ограждение ленточкой.

Многие из портов давно избавлены от эффекта Медузы и тутти-фрутти.

Ещё один знаменитый артефакт Doom — зеркальный зал (в кадровом буфере остаются следы предыдущих кадров), но это просто нет текстуры там, где должна быть (реже — глюк двоичного разбиения). Настоящий Doom для DOS (в отличие от большинства портов, основанных на Linux-версии) использует 4-страничный X-режим, и там «зеркальный зал» ещё и мигает.

Текстура неба имеет разрешение 256×128 и покрывает угол в 90°, но ничего не мешает сделать текстуру 1024×128 на все 360°.

Затемнение происходит командой «нарисовать затемнённый столбец/строку», простой таблицей преобразования, коих в Doom больше десятка от самой светлой до совсем тёмной.

SVGA

У Doom были такие проблемы касательно SVGA:

  1. Код рисования столбцов содержал жёстко закодированную ширину экрана. Doom Legacy использовал самомодифицирующийся код, Smack My Marine Up — две версии под 320 и 640.
  2. Рисование текстур пола и потолка быстро пробивало точность фиксированной запятой и уже на 800×600 смотрелось дрянь.
  3. Метод рисования через двоичное разбиение был значительно менее масштабируемый, чем портальный у Build. Если под 320×200 Doom работает лучше Duke, то под 640×480 нужен минимум Pentium II.
  4. Код меню вообще не рассчитывался под SVGA и требовал полного переписывания.
  5. Перевод освещения в true color требует серьёзной переработки движка.

Демо-запись и мультиплеер

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

Демо-ролик в Doom пишется в заранее выделенный буфер памяти со скоростью 4 байта/такт, 8400 байт/минуту. Как только буфер заполнится, игра вылетает — разумеется, записав результат в файл. Для экономии памяти повороты в режиме демо-записи сделали более грубыми (256 позиций/оборот). Метки для перемотки отсутствуют; чтобы посмотреть ролик ещё раз, надо запустить его с начала. С другой стороны, из-за такого формата демо-роликов легко обнаруживается TAS — пользование «роботами» для быстрого прохождения, сплайсинг — объединение двух пробегов, когда модифицированная игра сначала повторяет старый пробег, а потом отдаёт управление игроку.

Мультиплеер происходит так: игра посылает управление всем остальным машинам. Как только управление от всех машин придёт, игра проделывает такт. При этом единственная разница между «ведущим» (первым игроком) и «ведомым» — ведомые подстраиваются под тактовую частоту ведущего (пропускают или ускоряют такты).

У такого мультиплеера очень низкие задержки, можно без вопросов играть по телефонному модему даже через все США. Зато есть три неустранимых недостатка:

  1. Каждый связывается с каждым, что в интернете и в игре более чем ввосьмером очень нехорошо.
  2. Отсутствует авторитарный ведущий, с которым можно посоветоваться, если что. Потому невозможно войти в начатую игру. Единственный способ выйти одному игроку — оставить неподвижного персонажа. Точно так же при рассинхронизации невозможно получить подобие сохранёнки, чтобы всё исправить.
  3. Никакой защиты от жульничества: каждый компьютер всегда знает, где соперники.

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

В DOS-версии передачей данных занимается внешний драйвер. Это позволяет писать собственные драйверы и запускалки, подчас под необычные методы передачи — параллельный кабель LapLink или цепочку COM-кабелей.

Случайность — по таблице из 256 чисел, при этом существуют два указателя: синхронный (для геймплея) и асинхронный (для спецэффектов звука и меню). Причём эта таблица — не перестановка из чисел от 0 до 255, а рандомные 256 чисел. Так что некоторые вероятности отличаются от заявленных.

Моддерство

Doom — одна из первых игр, заточенных под моддерство. Но не всё можно модифицировать.

  • Модифицируются без вопросов
    • Уровни — только как замена имеющимся: например, в Doom II тридцать основных уровней и два секретных.
    • Текстуры стен, в том числе совершенно новые (не замена имеющимся)
    • Звуки — только как замена имеющимся
    • Музыка — даже если мелодии уровней одинаковые, ничего не мешает сделать разные, авторы намеренно продублировали файлы. Есть отличные конвертеры из MIDI, многие порты принимают MIDI.
    • Детали интерфейса, в том числе графические названия уровней — если, конечно, удастся вписаться в имеющиеся схемы комплексов Doom 1
    • Раскладки инструментов для MIDI-платы Gravis Ultrasound. Но порты ими не пользуются, да и мало у кого есть дорогущий «гусь».
    • Палитровые эффекты (например, от темноты или скафандра)
  • Модифицируются через глюки
    • Текстуры пола/потолка, в том числе совершенно новые
  • Модифицируются только в формате total conversion
    • Основная 256-цветная палитра — ведь на неё завязана вся графика
    • Спрайты
  • Модифицируются только через патч EXE-файла
    • Свойства и поведение объектов: величины урона, анимационные последовательности, звуки, ссылки на функции…
    • Свойства уровней: патчи на поведение звуков (например, особо подчёркнуты шипящие какодемоны на MAP10), только на MAP30 монстры могут делать телефраг, работа специальных тэгов 666 и 667, на какой уровень переходить после основного/секретного выхода, какую из небесных текстур брать, наличие/отсутствие текстовой вставки
    • Свойства текстур: анимации, выключатели. Интересно поступили в TNT: Evilution (одной из частей Final Doom): сделали длиннющие текстуры выключателей, и выравниванием влево-вправо подставляли нужный кусок.
    • Схемы комплексов Doom 1: анимации, положение указателей «вы тут», строящаяся Вавилонская башня…
    • Тексты, в том числе текстовые названия уровней

Существовала прога DEHACKED, которая занималась именно что патчем EXE-файла.

Многие из портов без вопросов позволяют менять всё из этого — кроме той самой палитры, на которую завязана вся графика.

История выпуска Doom в общее пользование

Никто не выкладывал редакторов в общее пользование. Однако форматы были быстро распознаны, и помимо первенца, крайне неудобного DEU, появились и другие редакторы — WADED, DCK…

В 1994 году открыли исходные тексты сетевых драйверов. Началась волна собственных драйверов (PARSETUP — LPT-кабель, HX8 — цепочка COM-кабелей) и запускалок (DOOMATIC мог даже передавать WAD по сети, если он есть у главного).

В декабре 1997 некомпилирующийся Doom для Linux (в версии Final Doom) выложили под несвободной образовательной лицензией. Уже через месяц Doom скомпилировали для DOS: вместо Watcom C взяли DJGPP (версию GCC/G++ для DOS; символ + в DOS запрещён и компилятор назывался GPP, отсюда DJGPP), вместо отсутствовавшей библиотеки DMX взяли открытый Allegro. И после этого пошла волна портов, из которых назову только четырёх первенцев:

  • Boom (Lee Killough) — стал основой для дальнейшего моддинга и стандартом новых секторных эффектов: есть дверь, требующая все шесть ключей, или лифт, где синхронно едут пол и потолок на манер кабины. Серьёзно ускорен по сравнению с Doom.
  • Doom Legacy (Denis Fabrice, Boris Pereira) — один из самых дружественных портов.
  • glDoom (Bruce Lewis) — первая попытка перевести Doom на OpenGL.
  • ZDoom (Marisa Heit и другие) — отходит от полной совместимости со старой игрой, зато вводит новые и новые фичи: прыжки, плавание, рельсотрон, захват флага. Ныне брошен, но есть продолжение GZDoom.

В середине 1998 года разработке glDoom пришёл конец — у Льюиса накрылся жёсткий диск. И тогда в 1999 году id Software перелицензировали Doom под GPL2 — если бы лицензия не была столь жёсткой, у кого-то точно нашёлся бы код. А код действительно в 2010 нашёлся — когда Льюис разгребал компьютер умершего друга.

В январе 1999 компания Raven выложила в открытый доступ Heretic, Hexen и компилятор скриптов для Hexen. Лицензия на исходник была странная и привычная больше для скомпилированных программ — так что программисты обменивались портами на птичьих правах. Только в 2008, после многочисленных петиций, перелицензировали под GPL всё, кроме компилятора.

386-е компьютеры, на которых бегал Doom, были очень ограниченными, а исходный текст — довольно качественным (за исключением меню, переделать под переменное разрешение — та ещё работа). Несмотря на то, что Си — чисто процедурный язык, Doom написан в неплохом объектном стиле и разбит на слои — внешний цикл (G), геймплей (P), рендерер (R), меню (M), ссылки в код из таблиц (A)… Ну и игра сделана без единого компьютерного дробного, в так называемой фиксированной запятой 16,16 (в роли машинной единицы число 65536), что тоже упрощает портацию на маломощные процессоры. Отдельным спортом стал запуск Doom на чём угодно, где есть 32-битный процессор, кнопки и экран: на фотоаппаратах, принтерах, графических калькуляторах, читалках…

В момент создания Doom (1993…94) немалое количество компьютеров из звукоизвлекающих устройств имело только встроенный динамик. К 1999 звуковым контроллером оснащались все ПК, во многих он был распаян на матплате, к тому же библиотека DMX, занимавшаяся, в числе прочего, поддержкой динамика, была выпилена из игры, потому на динамик забили. Формат звука для динамика был совершенно очевиден: какие-то ноты, менявшиеся с частотой в 140 Гц (4·частота тактов), но какая шкала? Около 2007 выяснили: четвертьтоновая (24 единицы = частота вдвое).

Главный недостаток современных истинно трёхмерных версий Doom — спрайты очень плохо совместимы с обзором выше-ниже. Можно сделать полигональные модели, но они в большинстве случаев выглядят крипово. И тут аж в 2022 некто Daniel Peterson сделал Voxel Doom — большая часть объектов заменена воксельными моделями.

Все файлы данных остаются коммерческими, и даже есть FreeDoom (на 2023 неготовый) — попытка создать полностью открытый WAD. Выглядит как последняя перескиновка.

Примечания

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