test(runtime): verify native Control node stage transitions
Docs Deploy / Build and Deploy MkDocs (push) Successful in 32s
Docs Deploy / Build and Deploy MkDocs (push) Successful in 32s
This commit is contained in:
4 files changed
+527
-9
No files matched your search
@@ -342,12 +342,20 @@ Rust query обращается к загруженному объекту и п
|
||||
factory paths остаются явными границами. Этот запрос возвращает начальный
|
||||
type-1 provider value (`1.0`); дальнейшее изменение provider amount в Rust не
|
||||
реализовано.
|
||||
Native oracle проверил изолированные пути распределения, обновления класса `4`
|
||||
и начальную ветвь таймера. Активную clock-ветвь не запускали; внешний источник
|
||||
времени и порядок вызовов остаются незакрытыми. Источник контактного коэффициента
|
||||
прослежен статически, но не исполнен; синтетические provider-строки не имеют
|
||||
родителей, а родительская логика и lifecycle истощения не проверены. Подробные
|
||||
векторы и статические границы приведены в
|
||||
Native oracle проверил изолированные пути распределения, обновления класса `4`,
|
||||
стадийную арифметику `0x11220`, обход дочерних provider-строк `0x11130` и
|
||||
visibility transition `0x11920` с исходными AniMesh callbacks. Эти сценарии
|
||||
используют синтетические NDP/Node38-строки; они подтверждают локальные переходы
|
||||
и порядок вызовов, но не полную загрузку или выполнение Control на миссии. Вызовы
|
||||
`0x11220` используют `updateEffects = false`, что исключает ветвь Control FX и
|
||||
`0x11af0`; в отдельном сценарии класса `9` `0xfca0` возвращается сразу после
|
||||
смены видимости, поэтому связанное с ним движение не проверено. Хотя у строки
|
||||
Control выставлен flag `0x102`, слово флагов ANI `+0x14` и производные байты
|
||||
`+0x111..+0x113` изначально равны нулю. Вызовы AniMesh `0x93c0` и `0xa2a0` обновляют производную геометрию и
|
||||
видимость, это отдельная непроверенная граница, а не FX callbacks. Активную
|
||||
clock-ветвь не запускали; внешний источник времени и порядок вызовов в игре
|
||||
остаются незакрытыми. Источник контактного коэффициента прослежен статически,
|
||||
но не исполнен. Подробные векторы и статические границы приведены в
|
||||
[техническом подразделе о provider-состоянии Control](script-vm.md#изменение-provider-состояния-control).
|
||||
|
||||
Отдельный API `advance_loaded_mission_resources` принимает явное время очереди
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -897,6 +897,23 @@ row `1` в общей позиции `22` со значением `6000.0`.
|
||||
даёт `[14, 28, 10]`. При вычитании последовательный способ начинает с последней
|
||||
строки. Так одна таблица описывает и текущее значение, и то, как оно меняется.
|
||||
|
||||
У строк есть и связи с родительскими узлами. Когда стадия родителя меняется,
|
||||
Control пересчитывает дочерние строки в глубину: ребёнка вместе со всем его
|
||||
поддеревом, затем следующего ребёнка. Для числа вариантов `count` внутренняя
|
||||
стадия вычисляется как `count - ceil(f32(count * ratio))`, а видимое значение
|
||||
ограничивается диапазоном модели. Например, при трёх стадиях доли
|
||||
`[0.1, 0.4, 0.5, 1, 0]` дали `[2, 1, 1, 0, 3]`; последнее значение — sentinel
|
||||
истощения, а в модель передаётся индекс не выше `count - 1`. Нативные проверки
|
||||
подтвердили порядок обхода и передачу состояния в AniMesh.
|
||||
|
||||
Выбранная стадия также задаёт, какие данные MSH попадают в пересчёт видимости.
|
||||
У одного синтетического узла первый слот давал `[42, 330]`, а слот другой стадии —
|
||||
`[102, 570]`. В проверенных векторах одинаковые данные при скрытии и повторном
|
||||
включении восстановили суммы; переходы с разными слотами — нет. Эти проверки
|
||||
исполняют исходные DLL на тестовых строках, но не являются запуском Control на
|
||||
полной миссии; Rust пока сохраняет только начальное состояние provider-строк.
|
||||
Подробные границы приведены в [техническом приложении](../appendices/script-vm.md#родители-стадии-и-видимость-provider-узлов).
|
||||
|
||||
Для точного повтора важен порядок округления. При исходных значениях `[2^24, 2]`
|
||||
и запросе `-1` оригинал сначала складывает общий итог с изменением, затем
|
||||
вычитает прежний итог. Из-за округления фактическое изменение получается `-2`.
|
||||
|
||||
Reference in new issue
Block a user