aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/appendices/knowledge-boundaries.md26
-rw-r--r--docs/appendices/script-vm.md40
-rw-r--r--docs/tomes/06-behavior.md37
3 files changed, 78 insertions, 25 deletions
diff --git a/docs/appendices/knowledge-boundaries.md b/docs/appendices/knowledge-boundaries.md
index ee10d40..e8bdb42 100644
--- a/docs/appendices/knowledge-boundaries.md
+++ b/docs/appendices/knowledge-boundaries.md
@@ -351,11 +351,24 @@ MSH-часть проверки подтверждает начальный сн
Control. Обработанное количество при ней остаётся прежним. Отдельный
`update_loaded_mission_control_node_stage` реализует наследование parent ratio
и stage, ceiling-арифметику, CPU visible stage и копию processed amount.
-Обход потомков `0x11130` пока не перенесён. Нужные lifecycle/visibility/FX
-callbacks дают явные ошибки до записи; `update_effects = true` поддержан
-только без фактической смены стадии. Licensed двухстадийный узел шахты
-подтверждает отдельный переход `0 → 1` при доле `0.5`, без FX и window path. Гибель root/critical узла и неизвестные flags/aggregate дают явную
-ошибку до записи; неподдержанные численные диапазоны тоже отклоняются.
+Отдельная `propagate_loaded_mission_control_node_stage` переносит `0x11130`:
+после обновления строки она сканирует более поздние provider-строки и обходит
+найденные поддеревья в native depth-first порядке. Для родителей
+`[-1, 0, 0, 1, 3]` порядок — `1, 3, 4, 2`. Переносит унаследованный Control
+ratio/stage, флаги `0x80/0x100` и drain количества; маска `0x140` пропускает
+только перезапись flags, не drain и рекурсию. Ухудшение определяется ростом
+стадии либо флагом истощения `0x10` уже обновлённого родителя. Отдельный
+`update_loaded_mission_control_node_stage` сохраняет одиночную семантику
+`0x11220`.
+
+Пропагация клонирует Control provider-таблицу и публикует её только после
+успешного обхода. Неизвестная parent-связь в просматриваемом суффиксе,
+lifecycle/visibility/FX callback или неподдержанное численное значение дают
+ошибку без частичных изменений. `update_effects = true` отклоняется, если
+стадия любого обработанного узла меняется и требуются неисполненные FX/host
+callbacks. Licensed двухстадийный узел шахты подтверждает переход `0 → 1` через
+новый API при доле `0.5`, без FX и window path. Гибель root/critical узла и
+неизвестные flags/aggregate также остаются явными ошибками.
Rust query обращается к загруженному объекту и поддерживает `0xe00` только для
текущего descriptor tag `26` с factory tag `26`; другие активные typed tags и
@@ -364,7 +377,8 @@ Licensed `min_l_n1.dat` подтверждает изменение `0xe00` и B
`1.0` до `0.5` после явного уменьшения количества вдвое; это ещё не
автоматический бюджетный цикл.
Native oracle проверил изолированные пути распределения, обновления класса `4`,
-стадийную арифметику `0x11220`, обход дочерних provider-строк `0x11130` и
+стадийную арифметику `0x11220`, обход дочерних provider-строк `0x11130` на
+interleaved parents `[-1, 0, 0, 1, 3]` с callback-порядком `1, 3, 4, 2` и
visibility transition `0x11920` с исходными AniMesh callbacks. Отдельный
бюджетный вектор исполняет `0x2d340` → `0x2dca0` → tag 15 `0x22bb0` →
`0x10ba0`: подтверждены коэффициенты `0.5` и `1`, точные amount/ratio и
diff --git a/docs/appendices/script-vm.md b/docs/appendices/script-vm.md
index bd363e5..60d15e1 100644
--- a/docs/appendices/script-vm.md
+++ b/docs/appendices/script-vm.md
@@ -695,8 +695,8 @@ provider остаётся с заданным тестом значением `0
текущего Control stage/sentinel. Неизвестный узел даёт ошибку без частичной
записи; callback отражён в CPU-проекции, но GPU/window path ещё не подключён.
Delta API не вызывает стадийный проход. Отдельный single-node API для
-`0x11220` описан в разделе о стадиях; обход `0x11130`, видимость и FX остаются
-вне этого исполнения.
+`0x11220` и отдельный API обхода потомков `0x11130` описаны в разделе о
+стадиях; видимость и FX callbacks остаются вне этого исполнения.
Истощение корня или критического узла возвращает `UnsupportedNodeLifecycle`
до записи: состояние владельца `+0x550`, отложенная гибель и сопутствующие
callbacks ещё не реализованы. Отсутствие MSH flags, provider aggregate,
@@ -964,15 +964,33 @@ Native oracle и Rust-тест также проверяют двухстадиÐ
стадии и отсутствие такого обновления при защищённом раннем выходе. Licensed
тест повторяет отдельный переход `0 → 1` на двухстадийном узле настоящего
`min_l_n1.dat`, с `update_effects = false`. Полный игровой вызов не подменяется
-этим режимом: FX, lifecycle, видимость и обход потомков ещё требуют реализации.
-
-После перехода родительского ряда `FUN_10011130` находит более поздние строки
-с его индексом в поле parent. Обход идёт в глубину: сначала ребёнок и всё его
-поддерево, затем следующий ребёнок. Рост стадии или истощение родителя снимает
-количество с дочерних строк; защитные флаги `0x40` и `0x100` меняют часть
-обработки флагов, но не останавливают снятие количества и обход потомков в
-проверенных входах. Нативный тест задал родителя с дочерними рядами, снял их
-количество и проверил порядок вызовов и значение stage snapshot.
+этим режимом: FX, lifecycle и видимость всё ещё требуют реализации; обход
+потомков доступен отдельным CPU API и пока не подключён к игровому циклу.
+
+`FUN_10011130` сохраняет старую стадию, вызывает `0x11220`, затем сохраняет
+обновлённые flags родителя для всего прохода. В исследованной сборке
+`0x11130` вызывает `0x11220` по RVA `0x11156`; caller-ы `0x11130` находятся в
+`0x10ba0`, `0x12a40`, `0x12ce0`, `0x13180` и в самой рекурсивной функции.
+`0x10f30` вызывает `0x11220` напрямую по RVA `0x1110f`.
+
+Затем `0x11130` сканирует provider-строки с большим индексом и выбирает строки,
+у которых parent равен текущему ключу. Обход идёт в глубину: сначала ребёнок и
+всё его поддерево, затем следующий ребёнок. Для parents `[-1, 0, 0, 1, 3]`
+порядок callbacks равен `1, 3, 4, 2`. Если стадия родителя выросла или у него
+стоит флаг истощения `0x10`, Control снимает количество с ребёнка. При флагах
+родителя `0xc0` дочернему ряду ставится `0x80`; в обычной ветви ставится `0x100`
+при ухудшении и очищается `0x80`. Дочерний mask `0x140` запрещает только
+перезапись его flags: количество всё равно снимается, и обход продолжается.
+Стадии детей пересчитываются, даже если родитель не ухудшился.
+
+Rust API `propagate_loaded_mission_control_node_stage` выполняет этот обход
+отдельно от single-node `update_loaded_mission_control_node_stage`. Он работает
+с копией provider-таблицы и публикует её только после успешной обработки всех
+потомков. Если в проверяемом суффиксе отсутствуют mesh metadata и поэтому нельзя
+установить parent-связи, либо потомку требуются lifecycle, FX или visibility
+callbacks, API возвращает ошибку и оставляет исходную таблицу без изменений.
+Native oracle использует синтетические NDP/Node38-строки и исходные
+Control/AniMesh callbacks; это не полное исполнение или сравнение миссии.
Переход между обычной стадией и sentinel `stage == count` вызывает
`Control.dll!FUN_10011920`, только если у строки не установлен флаг `0x02`.
diff --git a/docs/tomes/06-behavior.md b/docs/tomes/06-behavior.md
index 9dddc71..777caf1 100644
--- a/docs/tomes/06-behavior.md
+++ b/docs/tomes/06-behavior.md
@@ -997,22 +997,43 @@ clock Control.
даёт `[14, 28, 10]`. При вычитании последовательный способ начинает с последней
строки. Так одна таблица описывает и текущее значение, и то, как оно меняется.
-У строк есть и связи с родительскими узлами. Когда стадия родителя меняется,
-Control пересчитывает дочерние строки в глубину: ребёнка вместе со всем его
-поддеревом, затем следующего ребёнка. Для числа вариантов `count` внутренняя
-стадия вычисляется как `count - ceil(f32(count * ratio))`, а видимое значение
-ограничивается диапазоном модели. Например, при трёх стадиях доли
+У строк есть и связи с родительскими узлами. Нативный `Control.dll` сначала
+обновляет запрошенную строку через `0x11220`, затем `0x11130` ищет её детей
+среди строк с большим индексом. Каждый найденный ребёнок обновляется вместе со
+своим поддеревом, и только потом обход продолжается со следующим соседом.
+Например, для родителей `[-1, 0, 0, 1, 3]` порядок строк становится
+`1 → 3 → 4 → 2`: сначала весь первый участок дерева, затем его сосед.
+
+Стадия увеличивается, когда доля ресурса уменьшается. Для числа вариантов
+`count` внутренняя стадия вычисляется как `count - ceil(f32(count * ratio))`,
+а видимое значение ограничивается диапазоном модели. Например, при трёх стадиях доли
`[0.1, 0.4, 0.5, 1, 0]` дали `[2, 1, 1, 0, 3]`; последнее значение — sentinel
истощения, а в модель передаётся индекс не выше `count - 1`. Нативные проверки
-подтвердили порядок обхода и передачу состояния в AniMesh.
+подтвердили арифметику и порядок обхода.
+
+После обновления родителя Control сравнивает его старую стадию с новой и
+проверяет флаг истощения `0x10`. Если стадия выросла либо строка истощена,
+количество каждого ребёнка полностью уменьшается тем же путём, что и обычная
+добавка ресурса. Для ребёнка без защитной маски родительские флаги `0xc0`
+задают флаг `0x80`; в обычной ветви переход ставит `0x100` при ухудшении и
+очищает у ребёнка `0x80`. Маска `0x140` запрещает только изменение этих флагов:
+уменьшение количества и рекурсивный вызов всё равно выполняются. Дочерние
+стадии пересчитываются и тогда, когда родитель не ухудшился.
Выбранная стадия также задаёт, какие данные MSH попадают в пересчёт видимости.
У одного синтетического узла первый слот давал `[42, 330]`, а слот другой стадии —
`[102, 570]`. В проверенных векторах одинаковые данные при скрытии и повторном
включении восстановили суммы; переходы с разными слотами — нет. Эти проверки
исполняют исходные DLL на тестовых строках, но не являются запуском Control на
-полной миссии. Rust выполняет отдельный стадийный шаг в подтверждённой области,
-но обход потомков, пересчёт видимости и остальные callbacks ещё не подключены.
+полной миссии.
+
+В Rust `update_loaded_mission_control_node_stage` сохраняет отдельный шаг одной
+строки, а `propagate_loaded_mission_control_node_stage` обновляет строку и её
+поддерево в том же порядке, что native `0x11130`. Весь снимок provider-таблицы
+публикуется только после успешной обработки всех потомков. Если позже по обходу
+понадобится неизвестная связь узлов, lifecycle, FX или пересчёт видимости,
+операция сообщает об этом и оставляет снимок без изменений. Эта CPU-проекция
+ещё не подключена к игровому Control clock или выводу модели в окно.
Прямой путь изменения количества остаётся отдельной операцией.
Подробные границы приведены в [техническом приложении](../appendices/script-vm.md#родители-стадии-и-видимость-provider-узлов).