feat(runtime): update Control node stages
Docs Deploy / Build and Deploy MkDocs (push) Successful in 38s
Docs Deploy / Build and Deploy MkDocs (push) Successful in 38s
This commit is contained in:
6 files changed
+497
-18
No files matched your search
@@ -347,8 +347,14 @@ MSH-часть проверки подтверждает начальный сн
|
||||
соответствующего узла модели. Исходный `AniMesh.dll+0x5750` подтверждён в
|
||||
связке с `Control+0x10f30`: меняется только поле узла `+0x124`, а стадия и
|
||||
соседние узлы сохраняются. Эта проекция ещё не подключена к GPU/window path
|
||||
и не выполняет пересчёт стадий, видимости, FX или время Control. Поэтому обработанное количество остаётся
|
||||
прежним. Гибель root/critical узла и неизвестные flags/aggregate дают явную
|
||||
и сама delta-операция не выполняет пересчёт стадий, видимости, FX или время
|
||||
Control. Обработанное количество при ней остаётся прежним. Отдельный
|
||||
`update_loaded_mission_control_node_stage` реализует наследование parent ratio
|
||||
и stage, ceiling-арифметику, CPU visible stage и копию processed amount.
|
||||
Обход потомков `0x11130` пока не перенесён. Нужные lifecycle/visibility/FX
|
||||
callbacks дают явные ошибки до записи; `update_effects = true` поддержан
|
||||
только без фактической смены стадии. Licensed двухстадийный узел шахты
|
||||
подтверждает отдельный переход `0 → 1` при доле `0.5`, без FX и window path. Гибель root/critical узла и неизвестные flags/aggregate дают явную
|
||||
ошибку до записи; неподдержанные численные диапазоны тоже отклоняются.
|
||||
|
||||
Rust query обращается к загруженному объекту и поддерживает `0xe00` только для
|
||||
|
||||
@@ -692,9 +692,11 @@ provider остаётся с заданным тестом значением `0
|
||||
стадийное наследование доли родителя тоже не переписывает `+0x124` модели.
|
||||
Поэтому Rust хранит `mesh_state.type1_value_bits` отдельно от
|
||||
`current_type1_value_bits` provider, а `mesh_state.visible_stage` — отдельно от
|
||||
будущего Control stage/sentinel. Неизвестный узел даёт ошибку без частичной
|
||||
текущего Control stage/sentinel. Неизвестный узел даёт ошибку без частичной
|
||||
записи; callback отражён в CPU-проекции, но GPU/window path ещё не подключён.
|
||||
Полный пересчёт стадии `0x11130`/`0x11220`, видимости и FX также не вызывается.
|
||||
Delta API не вызывает стадийный проход. Отдельный single-node API для
|
||||
`0x11220` описан в разделе о стадиях; обход `0x11130`, видимость и FX остаются
|
||||
вне этого исполнения.
|
||||
Истощение корня или критического узла возвращает `UnsupportedNodeLifecycle`
|
||||
до записи: состояние владельца `+0x550`, отложенная гибель и сопутствующие
|
||||
callbacks ещё не реализованы. Отсутствие MSH flags, provider aggregate,
|
||||
@@ -928,6 +930,42 @@ provider-состояния в реальной миссии. Ограничен
|
||||
`AniMesh.dll!FUN_10005810` передаётся только видимое значение
|
||||
`min(stage, count - 1)`.
|
||||
|
||||
Rust API `update_loaded_mission_control_node_stage(engine, handle, key,
|
||||
update_effects)` переносит отдельный вызов `0x11220` в пределах подтверждённой
|
||||
арифметики и CPU-модели. Он читает текущие flags, count и parent, копирует долю
|
||||
родителя по `4` и его Control stage по `8`, записывает изменённую видимую стадию
|
||||
по правилу исходного `AniMesh+0x5810`, ставит flag `0x200` при переходе и
|
||||
сохраняет текущее количество в `processed_amount_bits`. Начальные снимки не
|
||||
меняются. Возвращаемый bool означает только смену Control stage: при неизменной
|
||||
стадии обработанное количество всё равно обновляется. Модельный `+0x124` при
|
||||
наследовании доли не переписывается.
|
||||
|
||||
Flags `0x1c0` вместе с `0x10` и `0xc0` дают нативный ранний выход до чтения
|
||||
mesh metadata и обновления `+0x0c`. Когда эти же flags требуют lifecycle
|
||||
callback, API возвращает `UnsupportedNodeLifecycle`. Переход при
|
||||
`update_effects = true` требует не только создания FX, но и host notifications
|
||||
через `0x11af0`; пока он возвращает `UnsupportedNodeEffects`. Если стадия не
|
||||
меняется, нативный код пропускает эту ветвь и такой вызов поддержан.
|
||||
Переход через sentinel при снятом flag `2` требует `0x11920` и возвращает
|
||||
`UnsupportedNodeVisibility`. Неверные parent/count, неизвестное состояние
|
||||
модели и неподдержанные доли также отклоняются. Все эти ошибки сохраняют
|
||||
прежнее состояние, включая ещё не скопированную долю родителя.
|
||||
|
||||
Здесь поддержаны конечные нормальные доли `0..1` и ноль. У инструкции `FILD`
|
||||
целый count остаётся точным до `FMUL`; предварительный cast count в `f32`
|
||||
может изменить ответ. Native вектор `count = 16777217`, `ratio = 0.75` получает
|
||||
Control/visible stage `4194304`; ранний cast давал бы `4194305`. Rust умножает
|
||||
целый count на 24-битную мантиссу доли в `u64`, округляет произведение один раз
|
||||
и точно масштабирует его степенью двойки. Это проверка арифметики с
|
||||
искусственным большим count, а не число стадий в игровых ресурсах.
|
||||
|
||||
Native oracle и Rust-тест также проверяют двухстадийный случай `ratio = 0.5`
|
||||
со стадией `1`, обновление только обработанного количества при неизменной
|
||||
стадии и отсутствие такого обновления при защищённом раннем выходе. Licensed
|
||||
тест повторяет отдельный переход `0 → 1` на двухстадийном узле настоящего
|
||||
`min_l_n1.dat`, с `update_effects = false`. Полный игровой вызов не подменяется
|
||||
этим режимом: FX, lifecycle, видимость и обход потомков ещё требуют реализации.
|
||||
|
||||
После перехода родительского ряда `FUN_10011130` находит более поздние строки
|
||||
с его индексом в поле parent. Обход идёт в глубину: сначала ребёнок и всё его
|
||||
поддерево, затем следующий ребёнок. Рост стадии или истощение родителя снимает
|
||||
@@ -1061,7 +1099,8 @@ SHA-256 `65659bf67f20e5be77d67a5b2f59968f61b94293143807fa59ca451c560c4f7e`,
|
||||
RVA `0x68a0`) читает три DLL scale globals, которые после LoadLibrary в oracle
|
||||
равны `1.0`. В Rust `initial_amount_bits` сохраняет это общее начальное
|
||||
количество отдельно от текущего и последнего обработанного. Прямой delta API
|
||||
меняет только текущее количество; стадийный update пока не перенесён.
|
||||
меняет только текущее количество; отдельный стадийный API обновляет
|
||||
обработанное и текущую стадию в подтверждённой области.
|
||||
|
||||
Licensed full-load regression `full_load_builds_effective_control_device_table_for_mine_unit_dat`
|
||||
проверяет значения настоящего `min_l_n1.dat`: корневой provider row `0` даёт
|
||||
@@ -1070,7 +1109,9 @@ Licensed full-load regression `full_load_builds_effective_control_device_table_f
|
||||
строки tag-26 устройства вдвое. Rust `0xe00` и `0x1002` дают `0.5`, и обычный
|
||||
шаг runtime сохраняет эту долю. Это вызов прямого API, а не полный живой
|
||||
Control tick. Проекция поля модели `+0x124` также получает `0.5`, а её видимая
|
||||
стадия остаётся `0`; GPU/window path этим тестом не исполняется.
|
||||
стадия этого ресурсного узла остаётся `0`. Затем другой, двухстадийный узел
|
||||
получает долю `0.5` и отдельный stage API переводит его из `0` в `1`.
|
||||
GPU/window path этим тестом не исполняется.
|
||||
|
||||
Native-часть этих ABI проверок воспроизводит
|
||||
`behavior_distributor_tick_native_oracle.cs` на синтетически выделенной памяти
|
||||
|
||||
@@ -362,8 +362,10 @@ CollObject, Control и PhysicalModel, пропуская отсутствующ
|
||||
[техническом разборе](../appendices/script-vm.md#доставка-игровых-часов-в-control).
|
||||
Статическая цепочка ещё не доказывает исполнение активного Control update на
|
||||
миссии. Rust сохраняет исходные и текущие provider-поля отдельно. Прямой delta
|
||||
API меняет строку и значение соответствующего CPU-узла модели, но описанный
|
||||
clock/budget-путь и вывод этого состояния в окно пока не подключены.
|
||||
API меняет строку и значение соответствующего CPU-узла модели; отдельный
|
||||
стадийный API обновляет его видимую стадию и обработанное количество в
|
||||
подтверждённой области. Описанный clock/budget-путь и вывод этого состояния
|
||||
в окно пока не подключены.
|
||||
|
||||
В текущем runtime `step_headless` и `frame` получают время очереди явным
|
||||
аргументом `u32`. По нему запускается представленный ресурсный планировщик
|
||||
|
||||
@@ -915,8 +915,9 @@ initial_mesh_state: Option<MissionControlNodeInitialMeshState>
|
||||
|
||||
Внутри снимка хранятся родительский индекс, переведённые флаги Control и число
|
||||
начальных стадий. Узлы корневой модели добавляются все, а присоединённая `EXTO`
|
||||
начинает с локального узла `1`. Это описывает исходную настройку: код пока не
|
||||
переключает стадии в ходе игры и не исполняет полный Control tick.
|
||||
начинает с локального узла `1`. Это описывает исходную настройку. Отдельный
|
||||
API уже пересчитывает стадию одного узла, но полный игровой Control tick
|
||||
пока не исполняется.
|
||||
|
||||
На той же начальной стадии Control вычисляет количество строки по NDP
|
||||
`max_volume`. Для загрузки Unit DAT проверенные множители равны `1.0`, поэтому
|
||||
@@ -964,6 +965,26 @@ Native oracle соединяет исходные `Control+0x10f30` и `AniMesh+
|
||||
с критическим флагом `1` пока возвращает ошибку без изменения состояния:
|
||||
эта ветвь требует полного lifecycle объекта, а не только нового количества.
|
||||
|
||||
Стадия пересчитывается отдельным вызовом
|
||||
`update_loaded_mission_control_node_stage`. Для трёх состояний доли `1`, `0.5`
|
||||
и `0.1` выбирают стадии `0`, `1` и `2`. Нулевая доля даёт служебную стадию
|
||||
Control `3`, но в модель записывается последняя видимая стадия `2`. Поэтому
|
||||
`current_stage` и `mesh_state.visible_stage` хранятся отдельно. Флаги `4` и `8`
|
||||
могут брать соответственно долю или стадию родителя; доля самой модели этим
|
||||
пересчётом не переписывается.
|
||||
|
||||
После успешного вызова обработанное количество становится равным текущему,
|
||||
даже если стадия осталась прежней. Истощённые защищённые узлы сохраняют
|
||||
нативный ранний выход и не обновляют этот снимок. Неизвестные parent/count,
|
||||
неподдержанные lifecycle-вызовы, FX и пересчёт геометрии на границе истощения
|
||||
возвращают ошибку до записи. Аргумент `update_effects` сохраняет нативный смысл:
|
||||
его нельзя молча отключать при включении полноценного игрового цикла.
|
||||
|
||||
На настоящем двухстадийном узле `min_l_n1.dat` тест уменьшает количество вдвое,
|
||||
явно вызывает стадийный API без FX и получает Control stage `1`, видимую стадию
|
||||
модели `1` и обновлённое обработанное количество. Это проверка отдельной
|
||||
операции на ресурсах, а не переключение кадра в игровом окне.
|
||||
|
||||
На исходном `min_l_n1.dat` прямое уменьшение количества строки ресурсного
|
||||
устройства вдвое меняет ответы `0xe00` и Behavior `0x1002` с `1.0` на `0.5`.
|
||||
Обычный последующий шаг runtime сохраняет это состояние. Это воспроизводимый
|
||||
@@ -990,7 +1011,8 @@ Control пересчитывает дочерние строки в глубин
|
||||
`[102, 570]`. В проверенных векторах одинаковые данные при скрытии и повторном
|
||||
включении восстановили суммы; переходы с разными слотами — нет. Эти проверки
|
||||
исполняют исходные DLL на тестовых строках, но не являются запуском Control на
|
||||
полной миссии; Rust пока не выполняет эти переходы стадий и видимости.
|
||||
полной миссии. Rust выполняет отдельный стадийный шаг в подтверждённой области,
|
||||
но обход потомков, пересчёт видимости и остальные callbacks ещё не подключены.
|
||||
Прямой путь изменения количества остаётся отдельной операцией.
|
||||
Подробные границы приведены в [техническом приложении](../appendices/script-vm.md#родители-стадии-и-видимость-provider-узлов).
|
||||
|
||||
|
||||
Reference in new issue
Block a user