diff options
| author | Valentin Popov <valentin@popov.link> | 2026-10-29 15:55:09 +0300 |
|---|---|---|
| committer | Valentin Popov <valentin@popov.link> | 2026-10-29 15:55:09 +0300 |
| commit | acdf635ffb3868eee4fa383303cac75fdeea8e23 (patch) | |
| tree | a4e910a968ed5b5beb126f6bfed6e408aea51860 /docs/appendices/script-vm.md | |
| parent | f35c9ec1f09ec55f52563a8ba6a70cc4e2e1583d (diff) | |
| download | fparkan-acdf635ffb3868eee4fa383303cac75fdeea8e23.tar.xz fparkan-acdf635ffb3868eee4fa383303cac75fdeea8e23.zip | |
feat(runtime): update live Control provider amounts
Diffstat (limited to 'docs/appendices/script-vm.md')
| -rw-r--r-- | docs/appendices/script-vm.md | 52 |
1 files changed, 44 insertions, 8 deletions
diff --git a/docs/appendices/script-vm.md b/docs/appendices/script-vm.md index 9ff358f..314d86f 100644 --- a/docs/appendices/script-vm.md +++ b/docs/appendices/script-vm.md @@ -653,7 +653,41 @@ oracle вызывает оригинальные `FUN_10010ba0` (RVA `0x10ba0`), через `FUN_10012ce0`. Бюджетная часть активной ветви проверена на ограниченном хосте класса `10`, как описано ниже. Источник входного времени и порядок его доставки до обработчика установлены статически; -Rust продолжает читать начальные provider snapshots и не моделирует эти изменения. +Rust ещё не вызывает этот бюджетный цикл; отдельно перенесён прямой путь +изменения одной строки `0x10f30`, описанный ниже. + +#### Прямое изменение одной строки в Rust + +`apply_loaded_mission_control_node_delta(engine, handle, key, delta)` моделирует +`0x10f30` с нулевым четвёртым аргументом: накопление анимационного изменения +`+0x10` и detached-ветвь сюда не входят. Максимум читается из исходной NDP +строки при подтверждённых единичных множителях Unit DAT. Сначала складываются +`f32` amount и delta, результат ограничивается `0..maximum`; при изменении +native `+0x590` получает `max(0, total + (new - old))`, `+0x14` — долю +`new / maximum`, а `+0x598` становится dirty. Флаг `+0x28 & 0x10` отмечает +истощение и снимается при пополнении. Количество `+0x0c` этим методом не +обновляется: native записывает его позже в `0x11220`. Конструктор владельца +`0x6bf0` начинает с `+0x598 = 1`, а `0xf940` оставляет этот dirty-флаг: +первый агрегатный проход нужен даже до новой добавки. Rust loader сохраняет +это начальное значение. + +Rust сохраняет начальные и текущие поля отдельно. Возвращаемая +`ControlNodeProviderPublication` содержит ключ и значение для обязательного +callback узла с selector `0x200`; автоматической доставки в AniMesh пока нет. +Полный пересчёт стадии `0x11130`/`0x11220`, видимости и FX также не вызывается. +Истощение корня или критического узла возвращает `UnsupportedNodeLifecycle` +до записи: состояние владельца `+0x550`, отложенная гибель и сопутствующие +callbacks ещё не реализованы. Отсутствие MSH flags, provider aggregate, +неподдержанный численный диапазон или неверный handle тоже дают явную ошибку +без частичных изменений. + +Rust-тест повторяет native последовательность количества +`40 → 60 → 50 → 100 → 0 → 10` при максимуме `100`, проверяет публикации, +неизменное обработанное количество и новые результаты `0xe00`/`0x1002`. +Native oracle отдельно подтверждает сохранение `+0x0c = 40` и снятие флага +истощения при последнем пополнении. Для amount `-0.0` с отрицательной добавкой +native записывает биты `+0.0`, но сравнение количеств считает их равными: +доля, флаги, итог и callback остаются прежними. Этот случай сохранён и в Rust. #### Бюджет и обновление устройства tag 15 @@ -972,8 +1006,8 @@ Runtime временно собирает mesh-состояния в порядÐ их с уже упорядоченными NDP provider-строками по общему ordinal. Избыточная NDP строка или отсутствующий MSH asset получают `initial_mesh_state = None`; совпадение по `(component_index, source_row_index)` не выполняется. Состояние -также не меняет существующий `0xe00` query: он читает начальное type-1 поле -`+0x14` provider-строки, равное `1.0` после нативного конструктора. +не меняет правило `0xe00` query: он читает текущее type-1 поле `+0x14` +provider-строки, которое после нативного конструктора равно `1.0`. ### Начальное количество строки provider @@ -1005,15 +1039,17 @@ callback-и пришли в порядке `[0, 1, 2, 3]`. Отдельный п `0x8310` имеет ветку установки scale. AniMesh constructor (`AniMesh.dll`, SHA-256 `65659bf67f20e5be77d67a5b2f59968f61b94293143807fa59ca451c560c4f7e`, RVA `0x68a0`) читает три DLL scale globals, которые после LoadLibrary в oracle -равны `1.0`. В Rust одна `initial_amount_bits` запись -сохраняет это общее начальное количество; полный update, который меняет -amount и обработанное предыдущее значение, пока не моделируется. +равны `1.0`. В Rust `initial_amount_bits` сохраняет это общее начальное +количество отдельно от текущего и последнего обработанного. Прямой delta API +меняет только текущее количество; стадийный update пока не перенесён. Licensed full-load regression `full_load_builds_effective_control_device_table_for_mine_unit_dat` проверяет значения настоящего `min_l_n1.dat`: корневой provider row `0` даёт `1.0`, а row `1` примонтированного `EXTO` (общий ordinal `22`) даёт `6000.0`. -Проверка использует исходные CTL/NDP/MSH и не делает выводов о динамическом -изменении этих строк. +Проверка использует исходные CTL/NDP/MSH, затем явно уменьшает количество +строки tag-26 устройства вдвое. Rust `0xe00` и `0x1002` дают `0.5`, и обычный +шаг runtime сохраняет эту долю. Это вызов прямого API, а не полный живой +Control tick или автоматическая публикация изменения в AniMesh. Native-часть этих ABI проверок воспроизводит `behavior_distributor_tick_native_oracle.cs` на синтетически выделенной памяти |
