diff options
Diffstat (limited to 'docs/appendices')
| -rw-r--r-- | docs/appendices/knowledge-boundaries.md | 20 | ||||
| -rw-r--r-- | docs/appendices/script-vm.md | 43 |
2 files changed, 63 insertions, 0 deletions
diff --git a/docs/appendices/knowledge-boundaries.md b/docs/appendices/knowledge-boundaries.md index 07ba5d7..59b2ffd 100644 --- a/docs/appendices/knowledge-boundaries.md +++ b/docs/appendices/knowledge-boundaries.md @@ -262,6 +262,26 @@ Behavior (`Behavior.dll`, RVA `0x3600`) вызывает `World3D!stdGetGameMode с реальными интерфейсами ArealMap, нужными `FUN_10019e80`; полный Behavior tick flow и общий dispatcher событий также остаются открытыми. +`loaded_mission_behavior_control_groupings` публикует только начальную +группировку подготовленной Control-таблицы. Ветка с меткой `2` исходного +`Behavior.dll!FUN_1001be10` (RVA `0x1be10`) дополнительно вызывает +`FUN_1001b4b0` и обращается к свойствам через QI `0x204`, включая запросы с +номерами `0x700`, `6` и `0x400`. Результат `0x700` попадает в строку кандидата +по смещению `+0x3c`, результат `6` — в `+0x40`, а `0x400` может обнулить второе +поле. Их доменный смысл, множитель `0x700`, агрегаты Behavior QI `0x204` и +прочие числовые поля кандидата не восстановлены. Rust не подставляет множитель +`0x700`, нулевые агрегаты, выбранный индекс или эффект. Список для метки `30` не +встречается в ресурсах AutoDemo и проверяется только на искусственном наборе. + +Игнорируемая проверка AutoDemo сравнивает порядковые номера записей начальной +группировки, отдельно выведенные по снимку текущих меток дескрипторов, с +состоянием Rust после полной загрузки. Это подтверждает согласованность разбора +подготовленной таблицы и правила группировки на этих ресурсах, но не является +захватом состояния Behavior оригинала и не устанавливает, когда список +прикрепляется или обновляется в живом объекте. Полный штатный путь загрузки и +запуска, агрегаты Behavior QI `0x204`, обновление после изменений Control, +`Handler(43)` и полный игровой цикл остаются отдельными границами. + Начальные свойства `CurrentOre`/`MaximumOre` восстановлены отдельно от регулярного обмена. В проверенных `Behavior.dll` (SHA-256 `ddfbdbde07832358fe6e35e01c8dba9b58e7313789498b6049ed51d4ed9baf99`) RVA diff --git a/docs/appendices/script-vm.md b/docs/appendices/script-vm.md index 26ac234..790729b 100644 --- a/docs/appendices/script-vm.md +++ b/docs/appendices/script-vm.md @@ -763,6 +763,49 @@ tie-векторов подтверждает реакцию `FISTP`, но не одного numeric literal; остальные формы инструкции и содержимое `.scr` сохраняются reader-ом, но остаются вне этого исполнения. +### Начальная группировка подготовленных Control-дескрипторов + +В проверенной GOG `Behavior.dll` (SHA-256 +`ddfbdbde07832358fe6e35e01c8dba9b58e7313789498b6049ed51d4ed9baf99`) +`FUN_1001be10` (RVA `0x1be10`) получает список через QI с кодом `0x202` от +`owner+0x5c`. Слоты `+0x50` и `+0x1c` этого интерфейса возвращают число строк и +код-различитель для строки; цикл обрабатывает порядковые номера строк +`0..count-1` по возрастанию. Метки `1`, `2` и `30` начинают группу, добавляют +кандидата и добавляют отдельный элемент к последней группе соответственно. +Запись с меткой `2` до первого заголовка попадает в отдельный вектор; метка `30` +без группы игнорируется, как и все остальные метки. + +Для источника списка проверена пара GOG DLL. В `Control.dll` SHA-256 +`bcb86318089028548a178b03a21accdce15df0cc85ddd91674cf3c2f55012c6e` запрос с +кодом `0x202` отдаёт интерфейс `owner+8`; его методы-обёртки переходят к методам +чтения канонического QI `0x204`, receiver которого равен `owner+0x0c`. Метод +`Control.dll` RVA `0x8830` читает число из `[receiver+0x5b4]`, то есть +`[owner+0x5c0]`; таблица указателей находится в `[receiver+0x5b0]`, то есть +`[owner+0x5bc]`. Поле `[owner+0x5b4]` — отдельный указатель кэша, а не число +строк. Метод чтения `Control.dll` RVA `0x2c390` выбирает указатель `table[index]`, +разыменовывает указатель на дескриптор из записи `+0x48` и возвращает DWORD по +адресу этого дескриптора. Загрузчик `FUN_10021d50` (RVA `0x21d50`) сохраняет там +указатель текущего дескриптора, поэтому код-различитель — его текущая метка, а +не неизменная метка фабрики. + +В оригинальном Behavior внешняя строка имеет шаг `0x34`; её `+4` получает +порядковый номер заголовка. Строка-кандидат имеет шаг `0x58`, а её `+8` хранит +порядковый номер кандидата. Номера строк с меткой `30` добавляются в отдельный +вектор последней внешней строки. Rust публикует только эти начальные номера: +`MissionBehaviorControlGroup` и +`MissionBehaviorControlGrouping` группируют строки из уже подготовленной +Control-таблицы в её исходном порядке. `MissionBehaviorControlGroupingState` +сохраняет `original_id`, `ObjectHandle` и либо результат, либо исходную причину +недоступности Control-таблицы. Полная загрузка создаёт проекцию перед публикацией +`LoadedMissionState`; предварительный просмотр возвращает пустой список. Проверки +`behavior_control_grouping_uses_current_tags_and_table_ordinals` и игнорируемый +`full_load_builds_initial_behavior_control_groupings_for_autodemo` покрывают +искусственные граничные случаи и сохранённые номера строк AutoDemo соответственно. + +Это начальное разложение подготовленного списка, а не реконструкция полной +инициализации Behavior: отдельные свойства строки-кандидата, её числовые поля, +эффекты и обновление списка после изменений Control здесь не моделируются. + ### Изменение provider-состояния Control Для `Control.dll` (SHA-256 |
