Тактический отряд с автоматическим огнём в изометрии, собственный софтверный растеризатор (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>
55 lines
6.4 KiB
Markdown
55 lines
6.4 KiB
Markdown
# 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).
|