aboutsummaryrefslogtreecommitdiff
path: root/docs/appendices
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2026-10-31 10:26:32 +0300
committerValentin Popov <valentin@popov.link>2026-10-31 10:26:32 +0300
commit0b2184429ff9da457662bf094d88b048595b3ec8 (patch)
tree3e6bf7b7c9b97fe76eea632e48b9ad1710f96b3d /docs/appendices
parent8c403ab4f7370f0833b1bd6b09f1aaef27447162 (diff)
downloadfparkan-0b2184429ff9da457662bf094d88b048595b3ec8.tar.xz
fparkan-0b2184429ff9da457662bf094d88b048595b3ec8.zip
feat(runtime): initialize per-clan AI record slots
Diffstat (limited to 'docs/appendices')
-rw-r--r--docs/appendices/knowledge-boundaries.md28
1 files changed, 28 insertions, 0 deletions
diff --git a/docs/appendices/knowledge-boundaries.md b/docs/appendices/knowledge-boundaries.md
index b313375..9f77c86 100644
--- a/docs/appendices/knowledge-boundaries.md
+++ b/docs/appendices/knowledge-boundaries.md
@@ -184,6 +184,34 @@ core и `ResearchCandidateSet::refresh_selection`: последний получ
создаёт владельца живого контекста, не передаёт реальные AI candidates и не
выбирает результат Handler(43). Это не общий dispatcher и не загрузка игры.
+Начальный массив слота AI `+0x38` теперь восстановлен отдельно от этого
+исследовательского пути. В `iron3d.dll` SHA-256
+`d1dc4ea8535e2069b0a05c9e8be2724dd438ba44cca7a83007d8b2e50f9e35fa`
+`FUN_100392e0` (RVA `0x392e0`) вызывает слот для каждого значения счётчика
+`second_resource.tag`. В `ai.dll` SHA-256
+`c19cd6cd31cd2896f8c4ba0f0e700dd3408aec8182daaf4863d98a7d233a2abc` метод
+RVA `0x2010` передаёт `AI+0x83c` в `FUN_10002980` (RVA `0x2980`), где
+`FUN_100048f0` (RVA `0x48f0`) добавляет переданный DWORD. Вызывающая сторона
+повторно передаёт `0xffffffff`; эта функция не записывает значение обратно.
+Поэтому подтверждён только начальный массив sentinel-слов. Неизвестно, какие
+поздние обработчики читают эти ячейки и заменяет ли кто-либо их ID. В начальном
+массиве нет назначенных ID объектов; дальнейший смысл этих слов пока не
+установлен. Сам массив не является списком
+`BehaviorDistributorState.registered_objects` и не определяет владельца
+контекста исследований.
+
+Rust хранит этот снимок как `MissionAiStartupState` в состоянии загруженной
+миссии. Полная загрузка проходит по всем TMA-кланам, включая кланы без пакета
+сценария и без пути таблицы исследований; при предпросмотре список состояний AI
+остаётся пустым. Знаковое поле `second_resource.tag` читается по сырым битам как
+`u32`. Бюджет в 1 000 000 DWORD на миссию и выделение памяти с обработкой ошибки
+защищают только память Rust; это ограничение не приписывается оригинальному
+движку. Искусственные Rust-тесты проверяют обе формы TMA-клана, индекс клана,
+независимые массивы, пустой путь сценария, предпросмотр, чтение тега как
+беззнакового числа, лимит и откат при ошибке. Проверка на оригинальных ресурсах
+для `Single.01` подтверждает состояния обоих кланов (`9/9`) до выполнения
+`Init`; это не полный запуск миссии и не исполнение исходных DLL.
+
Для GOG-сборки также найден статический host call path в `Init`. В
`iron3d.dll!FUN_1005ff40` (RVA `0x5ff40`) одна ветвь сначала проходит записи
кланов и вызывает для них `FUN_100392e0`, затем вызывает `FUN_10039440` (RVA