aboutsummaryrefslogtreecommitdiff
path: root/docs/appendices/script-vm.md
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2026-10-29 16:08:08 +0300
committerValentin Popov <valentin@popov.link>2026-10-29 16:08:08 +0300
commit6eb1dcaf7036e4e1702de15d0dd02181a3577852 (patch)
treeab0e2969e599227810e4de670f5cd1cf4b6729f7 /docs/appendices/script-vm.md
parentacdf635ffb3868eee4fa383303cac75fdeea8e23 (diff)
downloadfparkan-6eb1dcaf7036e4e1702de15d0dd02181a3577852.tar.xz
fparkan-6eb1dcaf7036e4e1702de15d0dd02181a3577852.zip
feat(runtime): publish provider values into model node state
Diffstat (limited to 'docs/appendices/script-vm.md')
-rw-r--r--docs/appendices/script-vm.md27
1 files changed, 24 insertions, 3 deletions
diff --git a/docs/appendices/script-vm.md b/docs/appendices/script-vm.md
index 314d86f..6f52556 100644
--- a/docs/appendices/script-vm.md
+++ b/docs/appendices/script-vm.md
@@ -672,8 +672,28 @@ native `+0x590` получает `max(0, total + (new - old))`, `+0x14` — до
это начальное значение.
Rust сохраняет начальные и текущие поля отдельно. Возвращаемая
-`ControlNodeProviderPublication` содержит ключ и значение для обязательного
-callback узла с selector `0x200`; автоматической доставки в AniMesh пока нет.
+`ControlNodeProviderPublication` содержит ключ и значение уже применённого
+callback selector `0x200` в CPU-проекции узла. У `AniMesh.dll` с SHA-256
+`65659bf67f20e5be77d67a5b2f59968f61b94293143807fa59ca451c560c4f7e`
+primary vtable RVA `0x2057c`, slot `+0x34`, указывает на `0x5750`.
+Этот stdcall-обработчик принимает четыре DWORD: owner, ordinal, selector,
+raw float value. Только selector `0x200` записывает float в
+`owner[+0x1a8] + ordinal * 0x130 + 0x124`. Видимая стадия `+0x1c` при этом не
+меняется. Конструктор строки RVA `0x123e0` задаёт начальные `+0x124 = 1.0`
+и `+0x1c = 0`.
+
+Native live-provider oracle использует оригинальный конструктор этих строк и
+передаёт callback `Control+0x10f30` в исходный `AniMesh+0x5750` через
+прозрачную записывающую трассу обёртку. Проверены значения `0.6` и `0.1`,
+отсутствие записи у соседнего узла и прежняя стадия `77` у целевого узла;
+selector `0x201` ничего не меняет. При signed-zero no-publication случае
+provider остаётся с заданным тестом значением `0.25`, а модель сохраняет
+последнее опубликованное `0.1`. Ещё один native вектор показывает, что
+стадийное наследование доли родителя тоже не переписывает `+0x124` модели.
+Поэтому Rust хранит `mesh_state.type1_value_bits` отдельно от
+`current_type1_value_bits` provider, а `mesh_state.visible_stage` — отдельно от
+будущего Control stage/sentinel. Неизвестный узел даёт ошибку без частичной
+записи; callback отражён в CPU-проекции, но GPU/window path ещё не подключён.
Полный пересчёт стадии `0x11130`/`0x11220`, видимости и FX также не вызывается.
Истощение корня или критического узла возвращает `UnsupportedNodeLifecycle`
до записи: состояние владельца `+0x550`, отложенная гибель и сопутствующие
@@ -1049,7 +1069,8 @@ Licensed full-load regression `full_load_builds_effective_control_device_table_f
Проверка использует исходные CTL/NDP/MSH, затем явно уменьшает количество
строки tag-26 устройства вдвое. Rust `0xe00` и `0x1002` дают `0.5`, и обычный
шаг runtime сохраняет эту долю. Это вызов прямого API, а не полный живой
-Control tick или автоматическая публикация изменения в AniMesh.
+Control tick. Проекция поля модели `+0x124` также получает `0.5`, а её видимая
+стадия остаётся `0`; GPU/window path этим тестом не исполняется.
Native-часть этих ABI проверок воспроизводит
`behavior_distributor_tick_native_oracle.cs` на синтетически выделенной памяти