From f35c9ec1f09ec55f52563a8ba6a70cc4e2e1583d Mon Sep 17 00:00:00 2001 From: Valentin Popov Date: Thu, 29 Oct 2026 16:35:50 +0400 Subject: test(runtime): verify randomized Control resource cadence --- docs/appendices/script-vm.md | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) (limited to 'docs/appendices/script-vm.md') diff --git a/docs/appendices/script-vm.md b/docs/appendices/script-vm.md index 173721b..9ff358f 100644 --- a/docs/appendices/script-vm.md +++ b/docs/appendices/script-vm.md @@ -771,9 +771,44 @@ DLL. Экспорт `InitializeSettings` (RVA `0x32260`) регистрируе до `0x42206666`, долю до `0x3ecd4fdf`; mock-генератор получает `dt = 0.5` ровно один раз. После вызова dirty равен `1`, а агрегат `+0x588` ещё не пересчитан: бюджетное изменение происходит после предшествующего `0x12a40`. -Событие активации проверено отдельно выше. Ненулевые состояния RNG, -принудительный цикл по `+0xd4`, движение и непустые очереди остаются отдельными -границами. +Событие активации проверено отдельно выше. + +Условие срока не использует сохранённый deadline. Машинные инструкции +`0xc74a..0xc7c1` на каждом дошедшем до этой точки вызове изменяют RNG +`Control.dll+0x43228` и заново вычисляют порог. Два 16-битных слова состояния +обновляются по правилу `low' = u16(low << 1) XOR high`, +`high' = (high >> 1) XOR low'`. При периоде `P` четверть периода равна +`q = P * 0.25`, коэффициент случайного вклада — `q / 65536`, а порог имеет вид +`(high' * (q / 65536) - q * 0.5) + P + last_resource_time`. +Порядок этих x87 операций существенен; отдельное сохранение коэффициента в +`f32` видно по RVA `0xc78e`. Это RNG данного модуля, его нельзя подменять +LCG планировщика Behavior. + +При `P = 500`, исходных `+0xe4 = +0xec = 0` и seed `0x12345678` проверены +следующие последовательные вызовы. Таблица устройств здесь пуста: вектор +изолирует cadence после отдельной проверки настоящего бюджетного изменения. + +| Время | RNG после проверки срока | Последний ресурсный clock `+0xec` | +| --- | --- | --- | +| `0.5` | `0x12345678`, без изменения | `0` | +| `500` | `0xb7debec4` | `0` | +| `501` | `0x91b9ca56` | `0` | +| `502` | `0x4dc90515` | `502` | +| `503` | `0x610747e3` | `502` | + +Оба первых принятых вызова пропускают ресурсный шаг, но всё равно расходуют +RNG. На третьем порог меняется и шаг выполняется раньше прежних порогов. +Поэтому предварительно выбрать один случайный deadline до следующего +ресурсного шага означало бы другую модель времени. + +Отдельный seed `0xffff0000` после одного перехода даёт `0x8000ffff` и порог +ровно `500`: равенство снова пропускается. Вызов `501` получает +`0x3ffe7ffe` и обновляет ресурсный clock. Затем `+0xd4 = 2` принуждает вызов +`502` выполнить ещё один цикл, несмотря на новый порог; RNG становится +`0xdffdc002`, а счётчик уменьшается до `1`. Если после этого снять `+0xe0`, +вызов `503` синхронизирует `+0xec`, но сохраняет RNG и принудительный счётчик. +Движение, непустые очереди и исполнение всего этого пути в миссии остаются +отдельными границами. #### Доставка игровых часов в Control -- cgit v1.2.3