Тактический отряд с автоматическим огнём в изометрии, собственный софтверный растеризатор (raylib только окно, ввод и финальный блит). Ядро (спек, раздел 6): - LaneClear: проверка линии огня по своим, стенам и дальности; - решатель огневых позиций с гистерезисом и коммитом; - резервирование линий огня и расступание из чужих секторов; - пули-снаряды, дружественный урон физически возможен. Хоррор-слой (render-only): свет и туман войны с памятью карты, светящиеся трассеры, кровь, виньетка, зерно, напряжение. Ближний бой: сектор удара, три фазы, связка из трёх ударов, своя дисциплина «не бить сквозь своего». Проверка: squad_proto.exe --accept прогоняет критерии приёмки раздела 11 плюс блок M7 по ближнему бою — все PASS, FRIENDLY_HITS = 0 за 3 минуты боя. Сборка: cmake -S . -B build && cmake --build build --config Release raylib 6.0 подтягивается через FetchContent. Документация — CLAUDE.md как оглавление, содержание в docs/. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
6.4 KiB
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 |
Что находилось по ходу и чинилось
Прогоны без окна оказались полезнее, чем разглядывание кадра: три дефекта, которые на глаз не видны, нашлись именно так.
-
Отставшие агенты.
--probeпоказал агента наy=12, когда отряд стоял наy=26. Причина — залипание в «тени» стены (локальный минимум seek против отталкивания) плюс отсутствие правила «идти к отряду, когда стрелять не по чему». Починено касательным обходом стен и возвратом в слот строя (A5, A6). -
Резерв линии, который исчезает, когда нужен. Линии регистрировались только у реально стреляющих. Стоит кому-то влезть в линию — стрелок теряет линию, отрезок пропадает из реестра, и перекрывшего ничто не выталкивает (A3).
-
Пуля, летящая за цель. Последнее упорное попадание по своим (
t=94.49, воспроизводилось при любых настройках) — снаряд проходил место умершей мишени и находил своего за ней (A1). -
Выход за границы в блиттере спрайтов.
Framebuffer::Blitвычислял адрес строки спрайта до внутреннего цикла. Если спрайт срезан левым краем экрана больше, чем на свою ширину (sx0 >= s.w), индекс уезжал за конецpx: цикл пустой, разыменования нет, но индекс уже невалиден. Release это молча глотал, Debug валился сvector subscript out of range. Починено ранним выходом при пустом диапазоне обрезки.Вывод на будущее: проверять в Debug-сборке. В Release такие ошибки не проявляются — там нет проверок итераторов MSVC.
-
Критерий 11.6 мерил не то, что означал. Тест требовал, чтобы в коридоре огонь вёл передний, и считал ВСЕ выстрелы. Диагностика показала, что «нарушения» — это хвостовой агент, стреляющий назад, в оставленную позади комнату: к правилу «не стрелять сквозь своего» это отношения не имеет, впереди по такой линии никого нет по построению. Теперь считаются только выстрелы по ходу движения, и результат стал строже: 5/0 вместо 12/4.
-
Двое с клинками на одной мишени. Взмахи обрывались друг об друга, урона почти не было. Починено ценой цели: 37 взмахов / 31 попадание → 74 / 75.
Подробности и замеры по каждому — 08-decisions.md.
Текущий статус
Все измеримые критерии раздела 11 проходят: squad_proto.exe --accept →
«все проверяемые критерии PASS». Цифры — 09-acceptance.md.