# Object Registry (`objects.rlb`) `objects.rlb` - это не архив с готовыми мешами. Это реестр игровых прототипов, который связывает логический идентификатор объекта (`r_h_01`, `s_tree_04`, `fr_m_brige`, ...) с набором реальных ресурсов в других архивах. Документ описывает формат и runtime-контракт на высоком уровне, без привязки к внутренним именам/адресам из дизассемблера. Связанные страницы: - [Missions](missions.md) - [NRes](nres.md) - [MSH core](msh-core.md) - [Wear (`WEAR`)](wear.md) - [Material (`MAT0`)](material.md) - [Render pipeline](render.md) ## 1. Роль в пайплайне При загрузке миссии движок работает так: 1. Из `data.tma` получает `resource_name` объекта: - либо прямой ключ (`s_tree_04`); - либо путь к `*.dat` (например `UNITS\\UNITS\\HERO\\tut1_p.dat`). 2. Для `*.dat` читает заголовок и получает: - `archive_name` (в retail-корпусе всегда `objects.rlb`); - `model_key` (например `R_H_02`). 3. В `objects.rlb` по ключу (`model_key`/`resource_name`) ищет запись прототипа. 4. Из записи прототипа резолвит фактический `*.msh` и архив, где лежит геометрия. 5. Дальше запускается стандартная цепочка: `MSH -> WEAR -> MAT0 -> Texm`. ## 2. Контейнер `objects.rlb` сам является обычным `NRes`-архивом. Практические наблюдения на retail-корпусе: - формат заголовка/каталога полностью совпадает с `NRes`; - payload каждой записи прототипа кратен `64` байтам; - имя entry в каталоге - это логический ключ объекта (например `r_h_01`, `s_tree_04`). ## 3. Формат payload записи прототипа Payload состоит из массива фиксированных записей: ```c struct ObjectRef64 { char archive_name[32]; // C-строка (CP1251/ASCII) char resource_name[32]; // C-строка (CP1251/ASCII) } ``` Интерпретация: - `archive_name`: архив-источник (`bases.rlb`, `static.rlb`, `fortif.rlb`, `effects.rlb`, ...). - `resource_name`: имя ресурса в этом архиве (`*.msh`, `*.wea`, `*.cpt`, `*.ctl`, `*.bas`, ...). Важно: - после первого `NUL` в 32-байтовом поле могут встречаться служебные байты; для runtime-резолва используется только C-строка до первого `NUL`; - неизвестные хвостовые байты должны сохраняться 1:1 при writer/roundtrip-редактировании. ## 4. Runtime-резолв геометрии Канонический порядок выбора меша: 1. Найти запись прототипа по ключу в `objects.rlb`. 2. Прочитать список `ObjectRef64`. 3. Если есть ссылка на `*.msh`: - взять первую валидную ссылку; - открыть указанный архив; - загрузить этот `*.msh`. 4. Если `*.msh` нет, но есть `*.bas`: - взять stem от `*.bas` (`fr_m_brige.bas` -> `fr_m_brige`); - искать `.msh` в том же архиве (`fortif.rlb`). 5. Если нет ни `*.msh`, ни `*.bas`, объект трактуется как не-геометрический (пример: солнечный/системный объект) и в 3D-проход не попадает. ## 5. Типовые примеры `r_h_01`: - `bases.rlb :: r_h_01.msh` - `bases.rlb :: r_h_01.wea` - `bases.rlb :: r_h_01.cpt` - ... `s_tree_04`: - `static.rlb :: s_tree_0_04.msh` - `static.rlb :: s_tree_0_04.wea` - ... `fr_m_brige`: - прямого `*.msh` в записи нет; - есть `fortif.rlb :: fr_m_brige.bas`; - меш резолвится как `fortif.rlb :: fr_m_brige.msh`. `sun_01`: - ссылки на `*.sun`/effect-ресурсы; - 3D-меш отсутствует. ## 6. Инварианты для reader/writer Reader: - payload записи прототипа должен быть кратен `64`; - каждая запись читается как две независимые C-строки фиксированной длины; - поиск в архивах должен быть case-insensitive по ASCII. Writer/editor: - сохранять порядок `ObjectRef64` без перестановок; - сохранять неизвестные служебные байты полей 1:1; - не нормализовать имена, если это не требуется задачей. ## 7. Валидация Проверено на retail-корпусе `testdata/Parkan - Iron Strategy`: - все `590` записей `objects.rlb` имеют payload, кратный `64`; - `554` записей имеют прямую ссылку на `*.msh`; - `34` записи используют ветку через `*.bas`; - `2` записи не содержат геометрии (системные/sun). Интеграционные тесты в Rust подтверждают резолв: - `r_h_01 -> bases.rlb :: r_h_01.msh` - `s_tree_04 -> static.rlb :: s_tree_0_04.msh` - `fr_m_brige -> fortif.rlb :: fr_m_brige.msh` ## 8. Статус покрытия и что осталось до 100% Закрыто: 1. Формат payload записи прототипа (`ObjectRef64`) и правила чтения. 2. Runtime-алгоритм выбора меша (`*.msh` напрямую и fallback через `*.bas`). 3. Корпусная проверка структуры и интеграционные тесты резолва. Осталось: 1. Полная field-level семантика служебных байтов после `NUL` в `resource_name[32]`. 2. Формальная семантика всех категорий ссылок (`*.ctl`, `*.cpt`, `*.ndp`, `*.sun`) в терминах систем движка (не только render-пути). 3. Writer-спецификация уровня "authoring new prototype from scratch" с гарантией runtime-паритета.