aboutsummaryrefslogtreecommitdiff
path: root/docs/appendices/script-vm.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/appendices/script-vm.md')
-rw-r--r--docs/appendices/script-vm.md58
1 files changed, 55 insertions, 3 deletions
diff --git a/docs/appendices/script-vm.md b/docs/appendices/script-vm.md
index acb52db..0f5994b 100644
--- a/docs/appendices/script-vm.md
+++ b/docs/appendices/script-vm.md
@@ -640,9 +640,61 @@ oracle вызывает оригинальные `FUN_10010ba0` (RVA `0x10ba0`),
затем `FMUL` с binary32-константой `0.001` (`0x3a83126f`), после чего результат
сохраняется в `f32`. Код вызывает `FUN_10012a40`, затем `FUN_1002d340` и
присваивает `+0xec = +0xe4`. В соседней ветви update packet queue обрабатывается
-через `FUN_10012ce0`. Источник абсолютного времени извне и полный порядок
-вызовов в игре не установлены; эти связи остаются статическим выводом. Rust
-продолжает читать начальные provider snapshots и не моделирует эти изменения.
+через `FUN_10012ce0`. Активную clock-ветвь oracle не запускал: внешний источник
+времени и полный порядок вызовов в игре не установлены. Rust продолжает читать
+начальные provider snapshots и не моделирует эти изменения.
+
+#### Родители, стадии и видимость provider-узлов
+
+`Control.dll` с SHA-256
+`bcb86318089028548a178b03a21accdce15df0cc85ddd91674cf3c2f55012c6e` проверен
+прямыми вызовами исходных `FUN_10011220` (RVA `0x11220`) и
+`FUN_10011130` (RVA `0x11130`). При расчёте стадии `FUN_10011220` может взять
+долю родителя по флагу `0x04` или стадию родителя по `0x08`. Для стадии с
+числом вариантов `count` при проверенных долях `0..1` расчёт имеет вид
+`stage = min(count, count - ceil(f32(count * ratio)))`. Нативное ограничение
+применяется к результату вычитания как к беззнаковому 32-битному значению;
+здесь проверены конечные доли `0..1`. Для отдельного ряда из трёх стадий коэффициенты
+`[0.1, 0.4, 0.5, 1, 0]` дали внутренние значения `[2, 1, 1, 0, 3]`; последнее
+значение равно служебному sentinel `count` и означает истощение. В callback
+`AniMesh.dll!FUN_10005810` передаётся только видимое значение
+`min(stage, count - 1)`.
+
+После перехода родительского ряда `FUN_10011130` находит более поздние строки
+с его индексом в поле parent. Обход идёт в глубину: сначала ребёнок и всё его
+поддерево, затем следующий ребёнок. Рост стадии или истощение родителя снимает
+количество с дочерних строк; защитные флаги `0x40` и `0x100` меняют часть
+обработки флагов, но не останавливают снятие количества и обход потомков в
+проверенных входах. Нативный тест задал родителя с дочерними рядами, снял их
+количество и проверил порядок вызовов и значение stage snapshot.
+
+Переход между обычной стадией и sentinel `stage == count` вызывает
+`Control.dll!FUN_10011920`, только если у строки не установлен флаг `0x02`.
+Функция читает геометрию уже выбранной видимой стадии через
+`AniMesh.dll!FUN_100051f0`.
+Selectors `F` и `10` возвращают одну общую ячейку; второй запрос перезаписывает
+значение первого. Это влияет на агрегаты: один синтетический узел при состоянии `0`
+давал пару `[42, 330]`, а другой слот для состояния `2` — `[102, 570]`. В одном
+тестовом цикле hide/show использовали один и тот же слот, поэтому агрегаты
+вернулись к исходным; во втором цикл скрывал состояние `2`, а показывал состояние
+`0`, и полученные значения уже не были взаимными противоположностями. Отрицательные
+агрегаты во втором векторе — специально выбранные синтетические числа, а не
+утверждение о допустимом состоянии игры.
+
+Эти вызовы исполнены в x86 oracle с Control SHA выше и AniMesh SHA-256
+`65659bf67f20e5be77d67a5b2f59968f61b94293143807fa59ca451c560c4f7e`. Таблицы
+NDP, Node38 и объект хоста синтетические; слот lifecycle проходит через исходный
+`FUN_10005500`, а переход видимой стадии — через исходный `FUN_10005810`. Вызовы
+`FUN_10011220` сделаны с `updateEffects = false`, поэтому ветвь Control FX,
+включая `FUN_10011af0`, ими исключена. В отдельном visibility-сценарии класс `9`
+заставляет `FUN_1000fca0` вернуться сразу после смены видимости, так что связанное
+с ним движение также не проверено. Одна строка Control имеет flags `0x102`, но
+слово флагов ANI `+0x14` и производные байты `+0x111..+0x113` изначально равны
+нулю; поэтому вызовы
+`AniMesh.dll!FUN_100093c0` и `FUN_1000a2a0` (пересчёт производной геометрии и
+видимости) не покрыты. Эти результаты подтверждают локальные переходы и порядок
+callbacks, но не полный Control update реальной миссии. Активная clock-ветвь,
+внешний источник времени и полный игровой порядок вызовов пока не установлены.
### Начальная MSH-часть строки provider