aboutsummaryrefslogtreecommitdiff
path: root/docs/appendices/script-vm.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/appendices/script-vm.md')
-rw-r--r--docs/appendices/script-vm.md39
1 files changed, 36 insertions, 3 deletions
diff --git a/docs/appendices/script-vm.md b/docs/appendices/script-vm.md
index d031158..69ea54f 100644
--- a/docs/appendices/script-vm.md
+++ b/docs/appendices/script-vm.md
@@ -573,7 +573,9 @@ Tick-векторы проверяют нулевой шаг, обе ветви
равенство спросу, разные веса и достаточную/недостаточную мощность. Тот же
harness проверяет в оригинальном Control пропорциональное и последовательное
распределение provider amount, коэффициент класса `4` с интервалом `2`, а также
-неактивную временную ветвь с входами `0.5`, `1` и `2`. Вызовы Control используют
+неактивную временную ветвь с входами `0.5`, `1` и `2`. Отдельные векторы
+проверяют активацию класса `4` и бюджетную часть активной ветви класса `10`.
+Вызовы Control используют
синтетические строки и хостовые callbacks; ArealMap тоже получает синтетические
объекты. Harness сверяет SHA-256 всех трёх DLL; ArealMap загружается из
изолированной временной рабочей папки, которую процесс затем удаляет. Эти тесты
@@ -676,6 +678,36 @@ provider getter и изменение количества не подменен
категории и выполнение миссии этим не проверены.
Rust пока не переносит этот изменяемый бюджетный цикл.
+#### Активация и начальные часы
+
+Для Control класса `4` oracle вызывает исходный конструктор RVA `0x31490`
+и обработчик интерфейса RVA `0x31ae0` → `0x314f0` с событием `4` и ненулевым
+DWORD времени. Он выставляет `+0xe0` по условию `class != 0`, копирует матрицу
+хоста в три transform-поля и численно преобразует беззнаковое время в `f32`.
+Поля `+0xe4`, `+0xe8` и `+0xec` получают `time - 100`, а командные часы
+`+0xd8` и `+0xdc` — `time`. Это разные базовые значения:
+
+| Вход DWORD | Абсолютное `f32` | `+0xe4`, `+0xe8`, `+0xec` |
+|---|---|---|
+| `1000` | `1000` | `900` |
+| `33554433` | `33554432` | `33554332` |
+
+Первый вызов при старом `+0xe4 == 0` добавляет начальную команду в очередь;
+повторный вызов в этом векторе сохраняет одну запись. Хост явно подставляет
+identity transform, единичный масштаб и нулевую геометрию. Oracle проверяет
+аргументы и порядок этих callbacks, а функции Control и изменения его часов
+остаются исходными. Таблицы устройств, shapes и дорожек пусты: их активация,
+полный object loader и ветвь события `4` с нулевым payload здесь не исполнены.
+Нулевой payload статически выбирает отдельную фазу связывания интерфейсов,
+поэтому его нельзя считать обычным ненулевым временем активации.
+
+Период ресурсного обновления — поле `+8` глобального объекта настроек
+RVA `0x42478`. Инициализатор RVA `0x6350` и reset-метод RVA `0x6420` задают
+ему `250` миллисекунд (`0x437a0000`); oracle проверяет значение после загрузки
+DLL. Экспорт `InitializeSettings` (RVA `0x32260`) регистрирует объект с ключом
+`0x15` в `World3D::CreateGameSettings`. Это default, а не доказательство
+неизменности настройки во всех игровых режимах.
+
#### Активный ресурсный clock
Тот же native budget-вектор проходит через `Control.dll` RVA `0xbcf0` при
@@ -703,8 +735,9 @@ Rust пока не переносит этот изменяемый бюджет
до `0x42206666`, долю до `0x3ecd4fdf`; mock-генератор получает `dt = 0.5`
ровно один раз. После вызова dirty равен `1`, а агрегат `+0x588` ещё не
пересчитан: бюджетное изменение происходит после предшествующего `0x12a40`.
-Активация через загрузочные события, ненулевые состояния RNG, принудительный
-цикл по `+0xd4`, движение и непустые очереди остаются отдельными границами.
+Событие активации проверено отдельно выше. Ненулевые состояния RNG,
+принудительный цикл по `+0xd4`, движение и непустые очереди остаются отдельными
+границами.
#### Доставка игровых часов в Control