Прототип Unreal Tournament 1999 на Rust. Программа читает оригинальные пакеты UE1 и позволяет пройтись по картам GOTY. В игровом окне Direct3D 11 рисует геометрию, оружие и HUD в разрешении окна. Текстуры карты используют mipmap-уровни и анизотропную фильтрацию. Команды экспорта BMP используют программный растеризатор.
Вывод кадров синхронизирован с частотой монитора через DXGI. F3 показывает FPS, частоту выбранного Windows монитора, разрешение и режим D3D11. F11 разворачивает окно на весь монитор.
Для запуска нужны Windows x64 и оригинальные данные Unreal Tournament GOTY. После клонирования соберите проект по инструкции ниже и передайте программе путь к карте из своей установки. Для музыки положите libopenmpt.dll и её зависимости в корень установки, рядом с каталогом Maps. Библиотеку можно получить на сайте libopenmpt.
При локальной установке в local/goty запустите Play Deck16.cmd или UT99 Port.exe. Игра воспроизводит пролёт камеры CityIntro с оригинальной музыкой и озвучкой. Esc или клик пропускает заставку. После неё открывается рабочий стол с оригинальной темой Ice. Play сразу запускает одиночную разминку на Deck16][. Чтобы открыть другую карту напрямую, перетащите файл .unr на Play Deck16.cmd.
Для заставки и меню требуются пакеты оригинальной установки GOTY, включая Maps/CityIntro.unr, Maps/UT-Logo-Map.unr, System/UMenu.u и Textures/UWindowFonts.utx. При отсутствии пакетов заставка пропускается, а меню использует доступные ресурсы. Камера использует четырёхточечную интерполяцию UE1 и монтажные переходы карты. Музыка, озвучка, анимации персонажей, ключи движения декораций и текстуры свечения читаются из игровых пакетов. Титры находятся в отдельной карте UTCredits.
Сверка кадров с GOTY выявила оставшиеся различия в тайминге сцен, освещении, дыме и эффектах фар. Меню использует ресурсы темы Ice. Полный набор пунктов главного меню и настроек UWindow остаётся в работе.
В Options доступны оконный и полноэкранный режимы, размер окна, VSync, FOV, масштаб HUD, FPS, заставка, громкость звука и музыки, чувствительность, инверсия мыши и переназначение основных клавиш. Изменения сохраняются в UT99-Rust.ini рядом с каталогом Maps. Esc во время игры открывает меню, Resume продолжает текущую разминку. В режиме прямого просмотра view Esc освобождает курсор, повторное нажатие закрывает окно.
Для OBS есть Play Deck16 (OBS).cmd. Он открывает игру сразу в разрешении монитора и использует режим DXGI, совместимый с захватом окна через BitBlt. В OBS выберите окно UT99. Если целый кадр игры виден только в углу холста, выделите источник и нажмите Ctrl+F («Подогнать под экран»). Размер источника на холсте задаёт OBS.
| Управление | Действие |
|---|---|
| WASD | Ходьба |
| Клик по игровому окну | Захват мыши |
| Мышь или стрелки | Осмотр |
| ЛКМ / ПКМ | Основной / альтернативный выстрел |
| F | Основной выстрел с клавиатуры |
| 1–0 / колесо мыши | Выбор оружия |
| Пробел | Прыжок |
| W / S под водой | Плыть вперёд / назад по направлению взгляда |
| Пробел или Ctrl под водой | Подняться к поверхности |
| F2 | Свободный полёт / возврат к ходьбе |
| F3 | FPS, герцовка и разрешение |
| F8 | Поставить неподвижную мишень и выдать все пушки для проверки |
| F11 | Полноэкранное окно |
| Пробел / Ctrl в полёте | Вверх / вниз |
| M / N | Выключить или включить весь звук / только музыку |
| Shift | Медленная ходьба / ускорение в полёте |
| Двойное нажатие W, A, S или D | Рывок в выбранном направлении |
| Tab / R | Следующая точка появления / возрождение с начальным оружием |
| Esc | Пропустить заставку или открыть меню в игре |
В режиме ходьбы работают разгон, торможение, управление в воздухе, рывок, прыжок, ступени и столкновения с BSP. Скорость, разгон, управление в воздухе, прыжок и высота камеры берутся из классов игрока GOTY. Гравитация, трение и предельная скорость падения учитывают текущую зону BSP. Есть оригинальные звуки шагов, прыжка и приземления, качание камеры и пороги урона от падения. В жидкостях включается плавание с трением и плавучестью. Слизь наносит урон в зависимости от глубины погружения, под водой можно задохнуться. Точная сверка выхода на уступ, эффекты погружения и звуки входа и выхода из жидкости остаются в работе. Свет рассчитывается из сохранённых масок карты и её цветных источников. Небо рисуется из геометрии SkyZone, палитровые текстуры поддерживают прокрутку и кадры AnimNext. Звуки окружения читаются из соседнего каталога Sounds и смешиваются с учётом расстояния и направления. Лифты Deck16][ и Liandri используют штатный режим StandOpenTimed и начинают движение, когда игрок встаёт на платформу. Локальные телепорты сопоставляют URL и Tag из карты.
На картах видны оригинальные модели оружия, аптечек, брони и декораций. Движок читает унаследованные настройки классов из соседнего каталога System. Модели пока отображаются в первом кадре. Жидкости используют исходные изображения и положения источников ряби, огонь — палитру и записанные параметры искр. Эти эффекты используют приближённую симуляцию.
Подвижные кисти поддерживают два положения и режимы StandOpenTimed, BumpOpenTimed и TriggerOpenTimed. Остальные состояния и события требуют исполнения UnrealScript. В одиночной разминке игрок начинает с Enforcer и Impact Hammer. Подбор оружия, боеприпасов, здоровья и брони отражается в HUD. Собранные предметы появляются снова по таймеру. Для стрельбы используются оригинальные модели и доступные звуки оружия. Баллистика, интервалы выстрелов и урон взрывов пока приближённые. Игровой цикл разминки реализован в Rust, исполнение игровых классов запланировано для локального Deathmatch.
Музыка берётся из поля Song карты и соседнего каталога Music. Библиотека libopenmpt и её DLL-зависимости находятся в корне локальной установки рядом с каталогом Maps. На Deck16][ играет Godown.
Чтобы выполнить комбо Shock Rifle, подберите пушку, выстрелите плазмой через ПКМ и попадите в летящий шар лучом через ЛКМ. Оба выстрела расходуют по одному патрону. При комбо игра дополнительно списывает два патрона, если они есть. Стены блокируют луч, урон и толчок от взрыва. Близкий взрыв отбрасывает игрока и может поднять его над полом. Для плазмы, луча и взрыва используются текстуры, модели и звуки GOTY. Динамический свет и следы взрывов на стенах пока в работе.
ПКМ у Pulse Gun удерживает луч, который расходует заряд примерно каждые 0,24 секунды. При начале стрельбы, удержании и отпускании используются последовательности BoltStart, BoltLoop и BoltEnd из GOTY. Начальная часть луча использует StarterBolt. При попадании в стену появляются PlasmaHit и след BoltScorch. Enforcer на ПКМ поднимает пистолет в боковой хват перед выстрелом и возвращает его после очереди. В обоих режимах вспышка следует за дулом, а гильза появляется у затвора. ПКМ у Sniper Rifle плавно приближает изображение. Отпустите кнопку, чтобы оставить выбранное приближение, и нажмите снова для выхода из прицела.
Enforcer, Minigun и Sniper Rifle наносят урон в момент выстрела. У Minigun каждый четвёртый выстрел с дистанцией до попадания больше 250 единиц выпускает оригинальный декоративный трассер MTracer. Гильзы, дым, искры, звуки попаданий и следы пуль Pock загружаются из пакетов GOTY. Следы обрезаются по границам неподвижных поверхностей BSP. Срок их отображения ограничен таймером, точная симуляция гильз остаётся в работе.
ЛКМ у Pulse Gun запускает плазменные снаряды. У Rocket Launcher удержание ЛКМ загружает ракеты для залпа, а ПКМ загружает гранаты, которые отскакивают от поверхности и взрываются по таймеру. У Bio Rifle обычный выстрел оставляет каплю геля на поверхности, а ПКМ заряжает более крупную каплю, которая при ударе разбрызгивает гель. Flak Cannon стреляет рикошетящими осколками или разрывным снарядом, а Ripper стреляет отражающимися или взрывными дисками.
Impact Hammer заряжается при удержании ЛКМ. Отпустите кнопку, целясь в пол, чтобы проверить отбрасывание. ПКМ отклоняет летящие снаряды перед игроком. Rocket Launcher захватывает видимую мишень примерно за 1,25 секунды. У Redeemer ЛКМ выпускает обычную ракету, а ПКМ переключает на камеру ракеты. Управляйте мышью и повторно нажмите огонь после первой секунды полёта, чтобы подорвать ракету. Клавиша F8 позволяет проверить оба режима всех пушек на одной карте без ботов.
Урон сопровождается звуком боли и вспышкой. При смерти камера показывает одну из оригинальных анимаций солдата. После паузы нажмите ЛКМ или F для возрождения. Стандартный прыжок GOTY выполняется с земли. Прыжковые ботинки увеличивают высоту прыжка.
В каталоге проекта, под Windows x64 с установленными Rust MSVC и средствами сборки Visual Studio:
cargo +stable-x86_64-pc-windows-msvc build --locked --release
.\target\release\ut99-rust.exe view 'local\goty\Maps\DM-Deck16][.unr' 12
.\target\release\ut99-rust.exe map-info 'local\goty\Maps\DM-Liandri.unr'
.\target\release\ut99-rust.exe capture 'local\goty\Maps\DM-Deck16][.unr' 'local\deck16.bmp' 12Для своей установки GOTY передайте путь к карте из каталога Maps. Загрузчик ищет .utx рядом с картой и в каталоге Textures. Команда inspect <package> выводит версию, размеры таблиц и список импортируемых пакетов. Число после пути к карте при просмотре и после пути к снимку при экспорте выбирает точку появления, начиная с 1.
Проверенные карты: Deck16][, Liandri и Facing Worlds. Каталог local исключён из Git. Оригинальные игровые пакеты, DLL и готовые сборки в репозиторий не входят.
Оригинальная игра и данные GOTY служат эталоном. Полный порт включает исходные анимации, текстуры и процедурные материалы, отрисовку, физику, UnrealScript, игровые режимы, ботов и сетевой протокол. Требования зафиксированы в AGENTS.md.
В текущей сборке HUD использует атласы HudElements1 и HUDWeapons из Botpack. Кадры выстрела, доставания и убирания для поддерживаемых последовательностей загружаются из игровых мешей. Растеризатор интерполирует вершины между кадрами. При смене оружия используется штатный звук, при стрельбе — оригинальные текстуры вспышки, если они заданы в классе оружия. Положение и масштаб оружия, стартовый боезапас, его предел и время появления предметов берутся из свойств оригинальных классов при наличии этих данных. Остаются остальные переходы и анимации персонажей, совместимость материалов и освещения, точная физика и исполнение игрового UnrealScript.
| Этап | Что можно запустить | Критерий завершения |
|---|---|---|
| 1. Просмотр карты | Готово. Открывается Deck16][ с оригинальной геометрией и палитровыми текстурами. | Камера перемещается по карте и переключает оригинальные точки появления. |
| 2. Прогулка по уровню | Сборка доступна. Ходьба, прыжки, свет, небо, звук, оригинальные модели и телепорты. | Проверены три карты GOTY, включая лифт Deck16][. Расширенная совместимость триггеров и подвижных объектов зависит от исполнения UnrealScript. |
| 3. Одиночная разминка | Промежуточная сборка. Deck16][ с HUD, музыкой, звуками, оружием и подбором предметов. | Один игрок свободно перемещается, стреляет, меняет оружие и собирает предметы. |
| 4. Локальный Deathmatch | Из меню запускается матч на Deck16][ с ботами. | Работают бой, навигация ботов, счёт, возрождение и завершение матча. |
| 5. Одиночный UT99 | Доступны штатные карты и режимы GOTY, тренировки и турнир. | Работают Deathmatch, Team Deathmatch, CTF, Domination, Assault и Last Man Standing. |
| 6. Сетевой клиент и сервер | Два клиента Rust играют на выделенном Rust-сервере. | Работают репликация, смена карт и переподключение. Отдельно проверяется совместимость с протоколом UT99. |
| 7. Релиз | Запускается самостоятельный клиент Rust с оригинальными данными GOTY. | Штатные карты и режимы проходят приёмочную проверку по оригинальному клиенту. |
- Публичная часть исходников UT99 v432 и патчи OldUnreal описывают интерфейсы и версии. Полный исходный код оригинального движка в этих репозиториях отсутствует.
- SurrealEngine использовался как справочник по порядку полей UE1. Просмотрщик написан на Rust и не загружает библиотеки этого проекта.
- Карты извлечены из образа UT99 GOTY в Internet Archive. Текстуры взяты из того же образа через Internet Archive и зеркало OldUnreal. Для подготовки карт использована утилита распаковки из FullGameInstallers. Во время просмотра она не требуется.
- libopenmpt декодирует оригинальные трекерные модули из UMX.
- Экспорт UnrealScript UT99 используется как справочник по отрисовке ChallengeHUD и анимациям оружия.