test(runtime): verify native Control provider updates
Docs Deploy / Build and Deploy MkDocs (push) Successful in 33s

This commit is contained in:
Valentin Popov committed 2026-10-23 12:32:49 +04:00
1 parent 7c909ea67b
commit ce8e65c8ae
4 files changed
+312 -26

No files matched your search

+20 -7
View File
@@ -859,13 +859,26 @@ tag-26 ряда получается `1.0` provider × `1.0` coefficient × `1.0
`1.0`. Эти запросы используют начальные provider-значения после конструкторов,
а не результаты живого игрового тика.
Поведение provider-строк меняется и после загрузки: например,
`Control.dll!FUN_10010f30` (RVA `0x10f30`) обновляет и ограничивает текущее
значение, а соседние процедуры распространяют его между связанными строками.
Эти изменения пока не отражены в Rust-снимке. Поэтому запрос Control `0xe00` и
Behavior selector `0x1002`, который его суммирует, используют исходное состояние
полной загрузки. Selector `0x1005` прямо возвращает загруженную ставку профиля.
Ни один из них пока не исполняет Control tick или последующие изменения профиля.
После загрузки количество в строках может меняться. Контроллер распределяет
добавку либо пропорционально свободному месту, либо по очереди: при максимумах
`[30, 60, 50]`, текущих значениях `[10, 20, 0]` и добавке `22` первый способ
даёт `[14, 28, 10]`. При вычитании последовательный способ начинает с последней
строки. Так одна таблица описывает и текущее значение, и то, как оно меняется.
Для точного повтора важен порядок округления. При исходных значениях `[2^24, 2]`
и запросе `-1` оригинал сначала складывает общий итог с изменением, затем
вычитает прежний итог. Из-за округления фактическое изменение получается `-2`.
Нативная проверка подтвердила это поведение; Rust пока использует начальный
снимок provider-строк и не исполняет их дальнейшее распределение.
Отдельный путь объекта класса `4` умножает интервал на контактный коэффициент и
передаёт изменение строке. В проверенном примере коэффициент `1`, интервал `2`,
и значение строки уменьшается на `2`; этот коэффициент не является ставкой
производства из профиля. Проверка времени охватывает только начальную ветвь:
активную ветвь не запускали, а источник времени и полный порядок вызовов в игре
пока не установлены. Поэтому запросы Rust `0xe00` и `0x1002` используют
начальные снимки provider-строк, а `0x1005` — загруженную ставку профиля.
Точные нативные векторы и открытые границы описаны в [приложении](../appendices/script-vm.md#изменение-provider-состояния-control).
На x87 control word `0x007f` каждое умножение округляет мантиссу до 24 бит,
но промежуточная степень может выйти за диапазон `f32` и вернуться в него при