aboutsummaryrefslogtreecommitdiff
path: root/docs/tomes
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2026-10-20 07:44:10 +0300
committerValentin Popov <valentin@popov.link>2026-10-20 07:44:10 +0300
commitcaef8f8e6c0ae81b46fcab39cd4f2b74e1b29235 (patch)
tree89a28698cca49bebc7dfb5865248f76122d9fecc /docs/tomes
parentecc46ed17772816d6f0de565a0a1605d0299a1dd (diff)
downloadfparkan-caef8f8e6c0ae81b46fcab39cd4f2b74e1b29235.tar.xz
fparkan-caef8f8e6c0ae81b46fcab39cd4f2b74e1b29235.zip
feat(runtime): register mission objects with clan distributors
Diffstat (limited to 'docs/tomes')
-rw-r--r--docs/tomes/04-world.md20
-rw-r--r--docs/tomes/06-behavior.md58
2 files changed, 66 insertions, 12 deletions
diff --git a/docs/tomes/04-world.md b/docs/tomes/04-world.md
index dcd53b2..1123bc7 100644
--- a/docs/tomes/04-world.md
+++ b/docs/tomes/04-world.md
@@ -215,6 +215,26 @@ MissionObjectDraft {
`fparkan-world` не подтверждено. Смещения, условия версий и контрольные суммы исследованных
сборок приведены в [справочнике TMA](../reference/tma.md).
+Это слово влияет не только на сценарий. Успешно загруженный пакет клана
+публикует его `SuperAI` в таблице `GetSuperAI`; World3D передаёт первый DWORD
+дескриптора создания через Behavior, где он выбирает тот же номер таблицы.
+Поэтому при создании полного мира можно отнести объект к конкретному клановому
+диспетчеру, если его номер лежит в диапазоне `0..63` и сценарий этого клана
+загружен. Rust хранит такую связь отдельно от владельца объекта:
+
+```text
+TMA raw_after_resource = 1
+ -> GetSuperAI[1] доступен после загрузки script bundle клана 1
+ -> запись объекта относится к distributor клана 1
+```
+
+Для объектов с Unit DAT используется старший бит DWORD по смещению `+4` от
+начала DAT как общий признак, по которому оригинальный World3D создаёт
+registration key для Behavior. Это второе 32-битное слово заголовка. Из него
+нельзя вывести сторону или тип владельца. В AutoDemo это связывает поля TMA,
+class word из Unit DAT и выбранный клановый AI, не меняя `OwnerId` и хеш
+игрового состояния.
+
Свойства хранятся как ordered property bag:
```text
diff --git a/docs/tomes/06-behavior.md b/docs/tomes/06-behavior.md
index cd08969..b30bc7d 100644
--- a/docs/tomes/06-behavior.md
+++ b/docs/tomes/06-behavior.md
@@ -204,11 +204,47 @@ SuperAI для записей кланов, затем обновляет Behavi
не воспроизводит аргумент обратного вызова в `AI+0x3fc`, защиту от повторного
входа `AI+0x78`, одноразовую метку `AI+0x8a8` или обновления Behavior на игровых
тиках. При этом один конкретный шаг Behavior — распределение ресурсов — уже
-исполнен на исходной DLL с искусственными объектами; FParkan пока не вызывает
-его, потому что игровой мир Rust ещё не предоставляет нужные ресурсные
-интерфейсы. Runtime также не подменяет очередь оригинала: вызывающая сторона
-сама передаёт время, а локальный генератор Rust пока учитывает только случайные
-числа восстановленного стартового шага.
+исполнен на исходной DLL с искусственными объектами. Rust пока не вызывает
+регулярный шаг: игровой мир ещё не предоставляет нужные ресурсные интерфейсы.
+При полной загрузке Rust уже восстанавливает членство объектов в клановых
+списках Behavior, но сами записи распределителя и их доли пока не моделирует.
+Runtime также не подменяет очередь оригинала: вызывающая сторона сама передаёт
+время, а локальный генератор Rust пока учитывает только случайные числа
+восстановленного стартового шага.
+
+### Откуда берутся объекты распределителя
+
+Для каждого клана Iron3D создаёт AI независимо от того, найден ли его `.scr`.
+Таблица `GetSuperAI` получает указатель только для клана, чей пакет сценария
+успешно загружен. У размещённого объекта первое DWORD после имени ресурса
+выбирает индекс этой таблицы; второй соседний DWORD для этой цели не используется.
+World3D получает индекс через дескриптор создания объекта и передаёт его в
+Behavior. Отдельно DWORD по смещению `+4` от начала Unit DAT задаёт class word
+объекта. Это второе 32-битное слово файла; его старший бит приводит к созданию
+registration key, который проходит защиту Behavior вместе с проверками AI и
+distributor.
+
+Для обычной полной загрузки Rust сохраняет по одной записи состояния на клан.
+Каждый размещённый объект с известным Unit DAT и установленным старшим битом
+получает существующий `ObjectHandle` и попадает в список только при точном
+совпадении индекса `raw_after_resource` с доступной записью `GetSuperAI`. Индекс
+не перенумеровывается: например, пакет клана 1 остаётся слотом 1 даже если
+пакет клана 0 отсутствует. Preview сохраняет свои статические данные, но не
+создаёт эти связи.
+
+В лицензированной AutoDemo это даёт четыре членства: TMA объекты 4 и 6 идут
+в слот 0, а объекты 5 и 7 — в слот 1. У парных записей первого клана raw
+селектор равен 0, у второго — 1; классы из Unit DAT равны `0x80000010` для
+`wor_l_n1.dat` и `0x80000002` для `gener01.dat`. Тот же обычный путь в исходном
+Behavior добавил четыре ключа `0x80000003..0x80000006` в два distributor-а.
+Rust-тест повторно читает лицензированную миссию, связывает результаты с её
+TMA-записями и проверяет реальные `ObjectHandle`, но помечен `#[ignore]`, чтобы
+не требовать оригинальных ресурсов от остальных разработчиков.
+
+Это пока только перечень участников. Оригинальный `Behavior.dll!Add` создаёт для
+каждого участника запись размером `0x1c` с долей `1 / count`, после чего
+нормирует прежние доли. Rust ещё не хранит эти поля и не исполняет их регулярный
+обмен ресурсами. Поля не выводятся из TMA-соседнего слова или `OwnerId`.
### Регулярная передача ресурсов
@@ -227,13 +263,11 @@ Resource Distributor работает со списком зарегистрир
исходной `Behavior.dll`, но объекты и ответы интерфейсов заданы тестом; это ещё
не воспроизведение реальной миссии.
-Пока мы знаем точные границы интерфейсных запросов и некоторые ветви классов
-объектов, но не все доменные значения полей записи и не происхождение реальных
-строк списка. Загрузчик FParkan не должен создавать такие строки из похожих
-полей миссии: сначала нужно доказать путь регистрации и связать его с типами
-ресурсных объектов. Технические идентификаторы и численные векторы приведены
-в [приложении о сценарной машине](../appendices/script-vm.md), а оставшиеся
-вопросы перечислены в [границах знания](../appendices/knowledge-boundaries.md).
+Членство списка связано с реальным путём регистрации, но выполнение этой
+миссии не сравнивалось с тем, как исходная DLL заполняет поля записи `0x1c` и
+нормирует доли. Rust пока не хранит эти поля, а игровому миру ещё не хватает
+ресурсных интерфейсов ArealMap для регулярного шага. Открытые вопросы и границы
+проверки приведены в [границах знания](../appendices/knowledge-boundaries.md).
Первый часто встречающийся table entry с side effect — `Handler(2)` (176
records в corpus). Он берёт active instruction, разрешает семь slots через