[bug] P1: Unknown в кэше коллизий пропускает дроны и перехватчики сквозь препятствия #61

Closed
opened 2026-10-29 21:11:18 +00:00 by chexit · 1 comment
Owner

🤖 Filed by Codex, AI-агент Владимира (chexit).

Ревью 6f3fc644bc5194311a86baba722bc340215306b7. Продолжение #42/#43 после появления WorldCache: сам DDA умеет вернуть Unknown, но код движения принимает это как отсутствие столкновения. Это сохраняет исходный пользовательский дефект на холодном кэше, после телепорта, появления нового аппарата и при нехватке бюджета.

Причина

  • sim/world.rs::sweep останавливается на первой неизвестной секции. Всё за ней в этом перемещении не проверяется.
  • sim/mod.rs::step_drones сначала подтверждает d.pos += d.vel, потом смотрит только sweep.hit(). Для Unknown без известной heightmap препятствия движение остаётся подтверждённым.
  • step_missiles сразу превращает результат в .hit(): Unknown и Clear становятся одним None. Перехватчик продолжает движение и может проверять радиовзрыватель за неизвестной частью пути.
  • look_ahead — только постановка асинхронного запроса. До первого ответа оно не обеспечивает безопасность уже совершаемого шага. want также не повышает приоритет уже стоящей в ahead секции; при заполненных 512 местах новая urgent-секция вообще отбрасывается.

Выполненное воспроизведение

На отдельной копии исходного мода добавлены characterization-тесты, алгоритмы движения не изменены. Аналог штатного fast_drone_must_not_cross_a_one_block_wall, но без warm: Циркон, Dive, старт (0,100,0), цель (1000,100,0), стена x=[3,4), y=[64,141). После одного тика и обычного ответа provider:

cold drone x=7.425000000000001, alive=true, crashes=0

Стену целиком пересекли до прихода ответа. Её обнаружение следующим sweep уже позади не исправляет результат. Контроль со штатным warm ловит стену. Для PAC-3 с начальной скоростью 6 (она ограничивается spec.speed=5.5) на том же отрезке: blocked=0, радиовзрыватель срабатывает за стеной: remaining=0, blasts=[(5.5,100,0)] (при seed=1 pk дал промах, цель осталась жива). Это нативный тест симуляции, не визуальный прогон игры.

Исправление

Сохранить три состояния до разрешения движения и взрывателя. Не подтверждать непроверенную часть sweep молча: bounded ожидание/двухфазная фиксация движения либо другая явно выбранная консервативная политика. Обрабатывать known_to, старт новых объектов и смену траектории. Для постоянно выгруженного мира нужна явная ограниченная политика и диагностика, без безлимитного force-load и бесконечного зависания всех аппаратов. Повысить приоритет уже queued-секции, если она понадобилась текущему движению; резервировать бюджет urgent-запросам.

Приёмка

Холодный и тёплый кэш дают одинаковое первое столкновение у стены; Cruise/Dive/Ballistic/Falling и перехватчик; неготовая/выгруженная секция и переполненная очередь; никакого перехвата за непроверенной стеной. Добавить тесты с реальным one-tick обменом, без предварительного warm.

🤖 Filed by Codex, AI-агент Владимира (chexit). Ревью `6f3fc644bc5194311a86baba722bc340215306b7`. Продолжение #42/#43 после появления `WorldCache`: сам DDA умеет вернуть Unknown, но код движения принимает это как отсутствие столкновения. Это сохраняет исходный пользовательский дефект на холодном кэше, после телепорта, появления нового аппарата и при нехватке бюджета. ### Причина - `sim/world.rs::sweep` останавливается на первой неизвестной секции. Всё за ней в этом перемещении не проверяется. - `sim/mod.rs::step_drones` сначала подтверждает `d.pos += d.vel`, потом смотрит только `sweep.hit()`. Для Unknown без известной heightmap препятствия движение остаётся подтверждённым. - `step_missiles` сразу превращает результат в `.hit()`: Unknown и Clear становятся одним `None`. Перехватчик продолжает движение и может проверять радиовзрыватель за неизвестной частью пути. - `look_ahead` — только постановка асинхронного запроса. До первого ответа оно не обеспечивает безопасность уже совершаемого шага. `want` также не повышает приоритет уже стоящей в ahead секции; при заполненных 512 местах новая urgent-секция вообще отбрасывается. ### Выполненное воспроизведение На отдельной копии исходного мода добавлены characterization-тесты, алгоритмы движения не изменены. Аналог штатного `fast_drone_must_not_cross_a_one_block_wall`, но **без `warm`**: Циркон, Dive, старт `(0,100,0)`, цель `(1000,100,0)`, стена `x=[3,4), y=[64,141)`. После одного тика и обычного ответа provider: ```text cold drone x=7.425000000000001, alive=true, crashes=0 ``` Стену целиком пересекли до прихода ответа. Её обнаружение следующим sweep уже позади не исправляет результат. Контроль со штатным `warm` ловит стену. Для PAC-3 с начальной скоростью 6 (она ограничивается spec.speed=5.5) на том же отрезке: `blocked=0`, радиовзрыватель срабатывает за стеной: `remaining=0, blasts=[(5.5,100,0)]` (при seed=1 pk дал промах, цель осталась жива). Это нативный тест симуляции, не визуальный прогон игры. ### Исправление Сохранить три состояния до разрешения движения и взрывателя. Не подтверждать непроверенную часть sweep молча: bounded ожидание/двухфазная фиксация движения либо другая явно выбранная консервативная политика. Обрабатывать `known_to`, старт новых объектов и смену траектории. Для постоянно выгруженного мира нужна явная ограниченная политика и диагностика, без безлимитного force-load и бесконечного зависания всех аппаратов. Повысить приоритет уже queued-секции, если она понадобилась текущему движению; резервировать бюджет urgent-запросам. ### Приёмка Холодный и тёплый кэш дают одинаковое первое столкновение у стены; Cruise/Dive/Ballistic/Falling и перехватчик; неготовая/выгруженная секция и переполненная очередь; никакого перехвата за непроверенной стеной. Добавить тесты с реальным one-tick обменом, без предварительного `warm`.
chexit added the priority:P1area:simulationtype:bug labels 2026-10-29 21:11:18 +00:00
Author
Owner

🤖 Agent: сделано в https://gitea.maoniao.team/chexit/airdef/commit/5f8bff3 (запушено в main).

🤖 Agent: сделано в https://gitea.maoniao.team/chexit/airdef/commit/5f8bff3 (запушено в main).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: chexit/airdef#61