diff options
Diffstat (limited to 'docs/tomes/06-behavior.md')
| -rw-r--r-- | docs/tomes/06-behavior.md | 57 |
1 files changed, 47 insertions, 10 deletions
diff --git a/docs/tomes/06-behavior.md b/docs/tomes/06-behavior.md index 9350d94..b4bddb7 100644 --- a/docs/tomes/06-behavior.md +++ b/docs/tomes/06-behavior.md @@ -485,16 +485,53 @@ Tag выбирает конкретное правило. Для tag 1 запиÑ ### TRF и preload-данные -TRF-файлы проходят структурный разбор. `auto.trf`, `data.trf` и tutorial -variants имеют сигнатуру [NRes](../reference/nres.md) и содержат большие -таблицы имён игровых прототипов: оружия, башен, сооружений и других объектов. -Также найдены preload-записи, ANI и SKE resources. - -По содержимому, порядку загрузки и consumers TRF с высокой вероятностью -предоставляет AI/сценарному слою заранее подготовленную таблицу типов и -связанных данных. Framing и имена подтверждены corpus-ом, но полная семантика -каждой TRF-записи ещё не закрыта. Имена должны разрешаться через тот же -resource registry, что и миссионные объекты. +TRF-архивы используют несколько потребителей; один подтверждённый путь ведёт +из `Handler(43)` к вычислению стоимости исследования. В проверенной сборке GOG +`CalcFullResearchCost` из `ArealMap.dll` получает таблицу, загруженную через +`MisLoad.dll`. Для этого пути `TRF0` содержит строки по десять сырых `u32`, +`TRF1` — байты флагов, `TRFB` — пары «смещение имени и номер строки», а +`TRF6` — пул строк с нулевыми окончаниями. Слово 8 строки связывает её с +`TRFB` через младшие 16 бит; старшая половина сохраняется как неизвестное +значение. `TRF2` и `TRF3` образуют упорядоченные списки предварительных +исследований, которые читает этот путь стоимости. `TRF4`/`TRF5` образуют +отдельную пару таблиц, но `CalcFullResearchCost` её не использует. Непрозрачные +`TRF7`–`TRFA` остаются в архиве и требуются загрузчику. + +Модуль `fparkan-assets` разбирает этот профиль в `ResearchTrfDocument` и +вычисляет пару результатов для одного Unit DAT: + +```rust +let table = ResearchTrfDocument::decode(archive_bytes)?; +let cost = calc_full_research_cost(&candidate, &table)?; +``` + +Расчёт проходит компоненты Unit DAT в порядке дерева. Компонент с нулевым +`kind` завершает весь свой участок вместе с потомками. Для остальных ключ +ресурса ищется среди имён `TRFB`; повтор строки добавляется лишь один раз. +После прямых компонентов алгоритм обходит список `TRF2`/`TRF3` в его исходном +порядке, углубляясь сразу в найденные предварительные исследования. Общая +таблица посещений не даёт повторно добавлять узел и завершает циклы. Два бита +флагов `TRF1` управляют включением строки и обходом её зависимостей; остальные +сырые биты и слова не получают игровых имён без отдельного доказательства. + +Результат первого native-выхода подписан в отладочной строке как ore и +суммирует слово 1 `TRF0`, второй подписан как power и суммирует слово 0. Каждое +сложение сохраняется как `f32` в порядке найденной последовательности. В +принятом наборе из 23 синтетических тестов оригинальных DLL проверялись +`CalcFullResearchCost` и два AI-предиката; именно вызовы `CalcFullResearchCost` +подтвердили порядок обхода, дедупликацию, циклы, флаги и отсечение дерева. +Две проверки суммы показали чувствительность округления: одна и та же сумма +`1, 2^24, -2^24` даёт `0`, а в другом порядке `2^24, -2^24, 1` даёт `1`. + +Эта проверка использовала синтетический исследовательский контекст и заданное +для опыта x87-слово управления `0x007f`; она не запускала штатный `Handler(43)`. +Локальный Rust-core принимает таблицу и одного Unit DAT, но пока не выбирает +кандидата в AI-каталоге и не связывает таблицу с владельцем полного старта +миссии. Поэтому `Single.01` всё ещё останавливается на неподдержанном +`Handler(43)`. Разбор с настоящими `scream.trf` и `12hel1.dat` проверяет +совместимость ресурса с API, но сам по себе не сравнивает стоимость с +оригинальным живым контекстом. Проверки границ байтов защищают Rust от плохих +входных данных и не приписываются нативному загрузчику. ### Стабильность AI-слоя |
