# 07 — Журнал вех Порядок из раздела 10 спека: после каждой вехи сборка и запуск, потом следующая. | Веха | Что сделано | Чем проверено | |---|---|---| | **M0** | CMake + raylib через FetchContent, фреймбуфер 480×270, ×3 апскейл, fixed timestep, изометрическая сетка | сборка MSVC x64, окно открывается, текстура 480×270 RGBA8 создаётся | | **M1** | тайлмап 48×48, генерация уровня, процедурные спрайты пола и стен, камера за якорем, сортировка по глубине | скриншот: ромбы пола шахматкой, кубы стен перекрывают друг друга правильно | | **M2** | 5 агентов, движение якоря в экранных осях, три строя, separation, коллизии со стенами | скриншот: пятеро в клину, цвета различимы, стены не проходятся | | **M3** | мишени с респавном, DDA-рейкаст, `LaneClear`, авто-огонь, пули-снаряды, дружественный урон, `FRIENDLY_HITS` | `--headless 60 --no-solver --no-laneavoid`: 1 попадание по своим, uptime 13.6 % — то есть проблема, которую должно решать ядро, воспроизводится | | **M4** | решатель огневых позиций, гистерезис и коммит, реестр линий и расступание | то же 60 с с включённым ядром: 0 попаданий, uptime 88 % на стоянке у мишеней | | **M5** | ручное прицеливание, конус ±20°, назначенная цель, `Tab` | сценарий `11.7` в `--accept`: 0 попаданий по своим при активной назначенной цели | | **M6** | оверлей F1–F4, метрики, журнал попаданий по своим, runtime-тюнинг `[ ] - =`, `--set` | скриншот боевого кадра: зелёные линии у всех пятерых, FRIENDLY_HITS 0, uptime 99 % | | **M7** | ближний бой: классы оружия, сектор удара, три фазы, свой больший круг, дуга; отзывчивый диск на поводке | `--accept`: M7.1–M7.3 PASS, 81 взмах / 81 попадание / 23 убийства за 30 с, FRIENDLY_HITS 0; все критерии спека 11 по-прежнему PASS | ## Что находилось по ходу и чинилось Прогоны без окна оказались полезнее, чем разглядывание кадра: три дефекта, которые на глаз не видны, нашлись именно так. 1. **Отставшие агенты.** `--probe` показал агента на `y=12`, когда отряд стоял на `y=26`. Причина — залипание в «тени» стены (локальный минимум seek против отталкивания) плюс отсутствие правила «идти к отряду, когда стрелять не по чему». Починено касательным обходом стен и возвратом в слот строя (A5, A6). 2. **Резерв линии, который исчезает, когда нужен.** Линии регистрировались только у реально стреляющих. Стоит кому-то влезть в линию — стрелок теряет линию, отрезок пропадает из реестра, и перекрывшего ничто не выталкивает (A3). 3. **Пуля, летящая за цель.** Последнее упорное попадание по своим (`t=94.49`, воспроизводилось при любых настройках) — снаряд проходил место умершей мишени и находил своего за ней (A1). 4. **Выход за границы в блиттере спрайтов.** `Framebuffer::Blit` вычислял адрес строки спрайта до внутреннего цикла. Если спрайт срезан левым краем экрана больше, чем на свою ширину (`sx0 >= s.w`), индекс уезжал за конец `px`: цикл пустой, разыменования нет, но индекс уже невалиден. Release это молча глотал, Debug валился с `vector subscript out of range`. Починено ранним выходом при пустом диапазоне обрезки. Вывод на будущее: **проверять в Debug-сборке**. В Release такие ошибки не проявляются — там нет проверок итераторов MSVC. 5. **Критерий 11.6 мерил не то, что означал.** Тест требовал, чтобы в коридоре огонь вёл передний, и считал ВСЕ выстрелы. Диагностика показала, что «нарушения» — это хвостовой агент, стреляющий **назад**, в оставленную позади комнату: к правилу «не стрелять сквозь своего» это отношения не имеет, впереди по такой линии никого нет по построению. Теперь считаются только выстрелы по ходу движения, и результат стал строже: 5/0 вместо 12/4. 6. **Двое с клинками на одной мишени.** Взмахи обрывались друг об друга, урона почти не было. Починено ценой цели: 37 взмахов / 31 попадание → 74 / 75. Подробности и замеры по каждому — [08-decisions.md](08-decisions.md). ## Текущий статус Все измеримые критерии раздела 11 проходят: `squad_proto.exe --accept` → «все проверяемые критерии PASS». Цифры — [09-acceptance.md](09-acceptance.md).