From be4031cb54d9bd88d1bad9cf993d27f914c767fa Mon Sep 17 00:00:00 2001 From: Valentin Popov Date: Thu, 29 Oct 2026 17:55:55 +0400 Subject: feat(runtime): propagate Control node stage changes --- docs/tomes/06-behavior.md | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'docs/tomes/06-behavior.md') 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-узлов). -- cgit v1.2.3