• Nikitos's avatar
    §9: мелкие дефекты и мёртвый код закрыты; страж нашёл ещё два Math.random
    · 8b72592c
    Nikitos создал
    Разобран весь §9 — восемь пунктов.
    
    ИСПРАВЛЕНО:
    * installControls — мёртвый код (живой def('controls') в ядре): функция и
      импорт удалены;
    * Math.random() в rig таймлайна (дыхание и фаза героев) — заменён на fxRandom:
      он сеется движком, поэтому воспроизводимость при --seed/--fixed-dt и реплеи
      ($.replay) больше не ломаются;
    * ui.on съедал слот обработчика ДО проверки успеха: неудачная подписка выжигала
      слот вместе с JS-функцией, и на 256-й такой попытке движок падал с
      InternalError, хотя обработчиков было меньше лимита. Теперь слот занимается
      только после успешной подписки, а функция освобождается при отказе;
    * visit_mark в BSP: поле и выделение удалены — память выделялась на каждый рост
      дерева и не использовалась;
    * комментарий «engine.width замирает при старте» в widgets.js исправлен (все три
      источника обновляются при resize).
    
    СТРАЖ НАШЁЛ БОЛЬШЕ, ЧЕМ АУДИТ: добавленная проверка «ни один модуль API не зовёт
    Math.random» сразу поймала ещё два места, которых в §9 не было:
    * steps.js — выбор файла шага и разброс высоты тона шли через Math.random
      (четыре вызова), теперь fxRandom;
    * soundbank.js — выбор варианта и разброс громкости/тона (три вызова). Здесь
      важна тонкость: чистые помощники (pickBankFile/bankVolume/bankPitch) без
      переданного генератора теперь возвращают ПРЕДСКАЗУЕМЫЙ результат, а не
      «случайный по умолчанию»: чистая функция обязана быть проверяемой, а разброс
      игре даёт переданный fxRandom.
    
    r2d_physics_is_awake и KEY_NAMES в §9 были помечены мёртвыми ошибочно: первый
    используется в engine.isAwake/$.world.awake, второй заполняется через
    engine.keyName (исправлено в прошлых раундах). §9 переписан как таблица «что
    было → чем закрыто».
    
    Проверка: полный набор qjs (28 файлов), агентские тесты, r2d_bsp_test (11),
    doc_coverage, doc_claims, duplicate_keys (включая нового стража Math.random),
    быстрый набор — зелёные.
    8b72592c