FRD Limit: расширение ограничений трасс в NFS4
Конус, который можно сбить, кажется небольшой деталью трассы. Но для Need for Speed: High Stakes это не просто полигон. Игре необходимо хранить его состояние, рассчитывать столкновения и определять, какие участки дороги должны быть видимы.
Оригинальный движок использует для части этих данных массивы фиксированного размера. Поэтому при создании больших и насыщенных объектами трасс авторы сталкиваются не только с ограничениями производительности и времени загрузки, но и с пределами, заложенными непосредственно в коде игры.
frd_limit устраняет несколько таких ограничений, заменяя фиксированные хранилища динамически выделяемой памятью. Патч предварительно проверяет структуру FRD, определяет необходимые размеры и выделяет память в соответствии с содержимым конкретной трассы. После её выгрузки выделенные страницы освобождаются.
Для демонстрации была подготовлена специальная версия трассы GT1. На дороге размещена семиярусная пирамида из 140 ящиков, окружённая тремя кольцами из 336 конусов.
Всего 476 динамических физических объектов, что примерно в 3,72 раза превышает оригинальный лимит в 128 объектов.

Какие ограничения удалось расширить
| Хранилище | Оригинальный лимит | Защитный предел патча по умолчанию |
|---|---|---|
| Блоки трассы | 300 | 32 768 |
| Динамические тела, например сбиваемые конусы | 128 | 32 768 |
| Состояния воздействия на объекты | 512 | 32 768 |
Кроме того, патч переносит таблицу видимых блоков и изменяет размер списка столкновений в зависимости от количества динамических тел.
Для глобальных объектов FRD также предусмотрен отдельный защитный предел в 32 768 записей.
Важно: указанные значения являются пределами проверки и резервирования памяти. Они не гарантируют, что любая трасса с таким количеством объектов сможет загрузиться и работать с приемлемой производительностью.
Как работает патч
При запуске FRD Limit резервирует пять областей виртуального адресного пространства.
Резервирование не означает немедленного выделения соответствующего объёма физической памяти. На этом этапе за патчем закрепляются диапазоны виртуальных адресов, которые впоследствии используются для хранения данных трассы.
Постоянные базовые адреса необходимы, поскольку обращения оригинального кода перенаправляются в новые области памяти. Эти адреса должны оставаться неизменными при переключении между трассами.
Процесс загрузки выглядит следующим образом:
- Патч читает файл FRD до запуска оригинального загрузчика.
- Проверяет структуру файла, размеры, счётчики и некоторые внутренние ссылки.
- Рассчитывает необходимый объём памяти по фактическому количеству блоков, динамических тел и состояний объектов.
- Выделяет физически обеспеченные страницы памяти в ранее зарезервированных виртуальных областях.
- Передаёт уже проверенный FRD оригинальному загрузчику без повторного чтения файла.
- После штатной очистки сцены освобождает выделенные страницы, сохраняя виртуальные адреса для следующей трассы.
Если файл не проходит проверку или памяти недостаточно, загрузка прерывается, а причина записывается в n4patch.log.
Предварительная проверка позволяет обнаруживать ряд повреждённых и обрезанных FRD-файлов. Однако она не заменяет полноценную проверку геометрии, текстур, анимации и всех вторичных ссылок.
Неожиданные зависимости внутри движка
Увеличение количества объектов требует расширения списка столкновений
Одним из наиболее интересных ограничений оказался список столкновений, используемый на каждом шаге физического расчёта.
В оригинальной игре этот список рассчитан на 154 указателя:
- 128 динамических тел.
- 26 слотов автомобилей.
При этом запись в список не проверяет его границы.
Если увеличить только массив динамических тел, оставив список столкновений прежнего размера, то уже 155-я запись начнёт перезаписывать соседнюю область памяти, в которой находится счётчик.
Поэтому FRD Limit отдельно переносит список столкновений и выделяет для него место в зависимости от количества динамических тел трассы, добавляя ещё 16 указателей для пула гоночных автомобилей.
Это хороший пример скрытой зависимости: недостаточно увеличить один массив, если другие части движка продолжают предполагать его первоначальный размер.
Практический тест: 476 физических объектов в одной сцене
Для проверки использовалась модифицированная трасса GT1 с пирамидой из ящиков и кольцами конусов.
Все 476 объектов загружаются как динамические тела и участвуют в физических расчётах.

Фрагмент журнала загрузки:
[frd_limit] blocks=104 global=0 bodies=476 impact-states=5
[frd_limit] FRD=1491303 committed=434176 vertices=38249 polygons=34059 references=95
Значение bodies=476 подтверждает количество загруженных динамических тел.
Это не декоративные копии моделей и не объекты, добавленные исключительно для визуального эффекта.

Какие ограничения остаются
FRD Limit расширяет несколько важных внутренних хранилищ, но не снимает все ограничения оригинального движка.
Таблица соседних видимых блоков
Формат по-прежнему предусматривает 300 записей соседей видимости на каждый блок трассы.
При этом общее количество блоков может превышать 300, а идентификаторы соседних блоков могут быть больше 299.
Патч ограничивает перебор фактическим размером таблицы, не отбрасывая корректные идентификаторы блоков с большими значениями.
Разрядность индексов
В некоторых структурах продолжают использоваться знаковые 16-битные индексы, где -1 обозначает отсутствие ссылки.
Также остаются отдельные 8-битные ссылки.
Поэтому предел в 32 768 элементов означает допустимые индексы от 0 до 32 767, а не возможность использовать индекс 32 768.
Ограничения памяти и производительности
Игра остаётся 32-битным приложением с ограниченным виртуальным адресным пространством.
Кроме того, существуют ограничения временных буферов рендерера, системы эффектов и производительности физического движка.
Корректность трассы
Успешная структурная проверка FRD не гарантирует, что вся геометрия, текстуры, анимации и остальные данные трассы корректны.
Она также не гарантирует, что трасса будет пригодна для полноценной гонки.
Комментарии
Пока нет комментариев.
Войдите, чтобы оставить комментарий и оценить. Войти