151 lines
11 KiB
Markdown
151 lines
11 KiB
Markdown
|
|
# 06 — Оверлей, метрики, тюнинг
|
|||
|
|
|
|||
|
|
## Оверлей
|
|||
|
|
|
|||
|
|
[src/debug/overlay.cpp](../src/debug/overlay.cpp). Рисуется примитивами raylib **поверх**
|
|||
|
|
уже отмасштабированного кадра. Это единственное исключение из «вся сцена софтверная»,
|
|||
|
|
и оно dev-only: `F1` его убирает.
|
|||
|
|
|
|||
|
|
| Клавиша | Что показывает |
|
|||
|
|
|---|---|
|
|||
|
|
| `F1` | оверлей целиком |
|
|||
|
|
| `F2` | линии огня |
|
|||
|
|
| `F3` | кандидаты последнего прогона решателя |
|
|||
|
|
| `F4` | метрики |
|
|||
|
|
| `F5` | выключить хоррор-слой целиком (свет, туман, пост) |
|
|||
|
|
| `F6` | показать диски обзора |
|
|||
|
|
|
|||
|
|
Всегда (при включённом `F1`): якорь отряда, **два** круга когезии (синий —
|
|||
|
|
стрелков, оранжевый — клинков), слоты строя, подпись над каждым агентом
|
|||
|
|
`индекс, класс (R/M), состояние (A/H), id цели` и у клинка фаза удара
|
|||
|
|
(`wind` / `HIT` / `rec`), выбранная огневая позиция `postPos` кружком.
|
|||
|
|
|
|||
|
|
**Сектор клинка**: кольцо досягаемости и две границы дуги, цвет по фазе —
|
|||
|
|
жёлто-оранжевый на замахе, белый на ударе, серый на восстановлении. В покое цвет
|
|||
|
|
говорит, почему не бьём: жёлтый — свой в дуге, синий — просто ждёт.
|
|||
|
|
|
|||
|
|
**Цвета линий огня (`F2`)**:
|
|||
|
|
|
|||
|
|
| Цвет | Значение |
|
|||
|
|
|---|---|
|
|||
|
|
| зелёный | линия чиста, агент стреляет |
|
|||
|
|
| жёлтый | цель есть, линию перекрыл свой |
|
|||
|
|
| красный | линию перекрыла стена |
|
|||
|
|
|
|||
|
|
**Кандидаты (`F3`)**: точками, цвет по оценке (синий низкая → белый высокая),
|
|||
|
|
отбракованные — тусклым красным, выбранный обведён белым кругом.
|
|||
|
|
Показывается последний прогон решателя, поэтому у агентов, у которых линия есть,
|
|||
|
|
там пусто — решатель для них не запускался, так и задумано.
|
|||
|
|
|
|||
|
|
В ручном режиме дополнительно рисуется вектор прицела, границы конуса ±20°
|
|||
|
|
и обводка назначенной цели.
|
|||
|
|
|
|||
|
|
## Метрики (`F4`)
|
|||
|
|
|
|||
|
|
[src/debug/metrics.h](../src/debug/metrics.h).
|
|||
|
|
|
|||
|
|
| Метрика | Как считается | Смысл |
|
|||
|
|
|---|---|---|
|
|||
|
|
| **FRIENDLY_HITS** | накопительный счётчик попаданий пуль по своим | главная метрика корректности, должна быть 0 |
|
|||
|
|
| **FIRE UPTIME** | доля шагов с валидной линией за окно 10 с; среднее — **только по стрелкам** | насколько отряд «в деле» |
|
|||
|
|
| **MELEE reach** | доля шагов с целью в зоне удара, среднее по клинкам | то же самое для ближнего боя |
|
|||
|
|
| `swings / hits / aborted` | взмахов начато, попаданий лезвием, взмахов оборвано своим в дуге | `aborted` — видимая цена скученности, не баг |
|
|||
|
|
| **SETTLE TIME** | от перехода в `HOLDING` до момента, когда ≥4 агента «в бою» | как быстро расходится веером |
|
|||
|
|
| fps, `sim ms/frame` | время симуляции за кадр | бюджет 16.6 мс |
|
|||
|
|
|
|||
|
|
«В бою» для стрелка — валидная линия, для клинка — выбранная цель. Смешивать
|
|||
|
|
доли времени двух разных занятий в одно среднее бессмысленно, поэтому
|
|||
|
|
`FIRE UPTIME` и `MELEE reach` считаются раздельно: у клинка линии огня не бывает
|
|||
|
|
по определению, и его ноль занижал бы метрику стрельбы.
|
|||
|
|
|
|||
|
|
Реализация `FIRE UPTIME` — кольцевой буфер на 600 сэмплов на агента с
|
|||
|
|
инкрементальными счётчиками, пересчёт O(1) за шаг.
|
|||
|
|
|
|||
|
|
**Журнал попаданий по своим**: каждое попадание пишется в `Metrics::hitLog`
|
|||
|
|
(время, стрелок, жертва, координаты, состояние жертвы). Без него `FRIENDLY_HITS != 0`
|
|||
|
|
нечем объяснить — именно журнал показал, что жертва всегда была `ADVANCING`,
|
|||
|
|
и вывел на настоящую причину (см. [08-decisions.md](08-decisions.md)).
|
|||
|
|
|
|||
|
|
### Как читать цифры
|
|||
|
|
|
|||
|
|
- `FIRE UPTIME` считает «нет живой цели в радиусе» как простой. Поэтому на
|
|||
|
|
переходах между комнатами и после зачистки кучки метрика честно падает — это не
|
|||
|
|
дефект ИИ. Критерий приёмки 11.8 относится к **стоячему бою рядом с мишенями**.
|
|||
|
|
- `SETTLE TIME` по той же причине растёт, если отряд остановился там, где стрелять
|
|||
|
|
не по чему. Сценарий `--accept` меряет его в правильной обстановке.
|
|||
|
|
|
|||
|
|
## Runtime-тюнинг
|
|||
|
|
|
|||
|
|
Все числа живут в [src/tuning.h](../src/tuning.h) в структуре `Tuning`.
|
|||
|
|
Магических констант по коду нет — если нужно новое число, оно добавляется туда.
|
|||
|
|
|
|||
|
|
Часть параметров вынесена в таблицу `TUNABLES` и крутится на ходу:
|
|||
|
|
|
|||
|
|
- `[` / `]` — выбрать параметр, текущее имя и значение видно в оверлее;
|
|||
|
|
- `-` / `=` — изменить с шагом параметра (с зажатием работает автоповтор).
|
|||
|
|
|
|||
|
|
Те же параметры можно задать из командной строки без пересборки:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
squad_proto.exe --headless 300 --set safetyMargin=0.25 --set laneReserve=2.0
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Список параметров смотри прямо в `TUNABLES` — там имя, поле, шаг и границы.
|
|||
|
|
|
|||
|
|
Самые содержательные для ощущения:
|
|||
|
|
|
|||
|
|
| Параметр | На что влияет |
|
|||
|
|
|---|---|
|
|||
|
|
| `safetyMargin` | запас к «телу в линии»; шире → реже стреляют, но безопаснее |
|
|||
|
|
| `laneReserve` | во сколько раз резерв линии шире порога блокировки; отвечает за «текучесть» |
|
|||
|
|
| `wLaneAvoid` | насколько нагло агент выдавливается из чужого сектора |
|
|||
|
|
| `hysteresis` | насколько лучше должна быть новая позиция, чтобы агент переехал |
|
|||
|
|
| `commitTime` | сколько держится решение; меньше → живее и дёрганее |
|
|||
|
|
| `sDistCost` / `sCohesionCost` | готовность отбегать далеко ради выстрела |
|
|||
|
|
| `postLeash` | жёсткая граница огневой позиции от диска; ниже — отряд плотнее |
|
|||
|
|
| `anchorSpeed` / `anchorLeash` | отзывчивость диска и насколько он может оторваться от отряда |
|
|||
|
|
|
|||
|
|
Ближний бой (подробности — [11-melee.md](11-melee.md)):
|
|||
|
|
|
|||
|
|
| Параметр | На что влияет |
|
|||
|
|
|---|---|
|
|||
|
|
| `meleeReach` / `meleeArc` | размер сектора удара; шире → чаще задевает нескольких, но и своих |
|
|||
|
|
| `meleeWindup` / `meleeStrike` / `meleeRecover` | ритм удара: читаемость замаха против скорострельности |
|
|||
|
|
| `meleeInterval` / `meleeDamage` | DPS клинка |
|
|||
|
|
| `meleeLunge` / `meleeKnock` | вес удара: рывок бойца и отдача мишени |
|
|||
|
|
| `meleeCohesion` | СВОЙ, больший круг клинка вокруг диска |
|
|||
|
|
| `meleeAllyMargin` / `meleePredict` | строгость дисциплины сектора; выше → меньше оборванных взмахов и меньше взмахов вообще |
|
|||
|
|
| `meleeReserve` | насколько широко клинок отжимает своих со своей дуги |
|
|||
|
|
| `meleeShake` | отдача камеры на попадание лезвием |
|
|||
|
|
|
|||
|
|
Хоррор-часть (подробности — [10-atmosphere.md](10-atmosphere.md)):
|
|||
|
|
|
|||
|
|
| Параметр | На что влияет |
|
|||
|
|
|---|---|
|
|||
|
|
| `sightRadius` / `sightCone` | как далеко и как широко видит отряд |
|
|||
|
|
| `sightPersonal` | круговой ореол вокруг агента, спасает от клаустрофобии |
|
|||
|
|
| `fogMemory` | насколько тускло помнится уже увиденное |
|
|||
|
|
| `fogReveal` | при каком свете показывается тело мишени |
|
|||
|
|
| `lightGamma` / `lightGain` | форма затухания света; **перепекают таблицу рампы** |
|
|||
|
|
| `flashPower` | насколько вспышка выстрела освещает окружение |
|
|||
|
|
| `fxIntensity` / `tracerLength` | яркость и длина трассеров |
|
|||
|
|
| `grainTense` / `vigDepthTense` | зерно и виньетка на пике напряжения |
|
|||
|
|
| `dreadRadius` | с какой дистанции мишень начинает пугать |
|
|||
|
|
| `shakePerShot` | отдача камеры |
|
|||
|
|
|
|||
|
|
`F5` — аварийный тумблер: мгновенно возвращает прежний кадр без света и тумана.
|
|||
|
|
Полезен, когда непонятно, баг это или просто темно.
|
|||
|
|
|
|||
|
|
## Dev-тумблеры ядра
|
|||
|
|
|
|||
|
|
`--no-solver` и `--no-laneavoid` выключают решатель и расступание. Это A/B-проверка
|
|||
|
|
ценности ядра, цифры за 60 с на одном маршруте:
|
|||
|
|
|
|||
|
|
| Конфигурация | FRIENDLY_HITS | FIRE UPTIME |
|
|||
|
|
|---|---|---|
|
|||
|
|
| ядро выключено | 1 | 13.6 % |
|
|||
|
|
| ядро включено | 0 | 88 % (на стоянке у мишеней) |
|
|||
|
|
|
|||
|
|
`sim`/`render` в оверлее показывают время шага симуляции и время кадра рендера
|
|||
|
|
раздельно: 2 мкс против 1.4–3.5 мс при бюджете 16.6 мс.
|