squad-proto/docs/01-build-and-run.md
z.kirill 0fb6e31c2b Свет как расходник: заряд тратится за путь, а не за время (M23)
Второй ресурс вылазки после патронов. Фонарь садится, погас — обзор падает
до 35%, а твари замечают отряд в 1.35 раза дальше: отряд не слепнет, он
меняется с тварями местами. Батарея встаёт сама, как бинт.

Главное решение — расход за ПРОЙДЕННЫЙ ПУТЬ, а не за время. Первая версия
считала по секундам, то есть была таймером, которого в игре нет по прямому
требованию к жанру: садящийся сам собой фонарь торопил бы игрока ровно как
секундомер, только без циферблата, и думать над этажом стало бы дорого.
За расстояние получается тот же размен, что и с весом, но с другой стороны:
вес делает дорогим «унести всё», свет — «обшарить всё».

Заряд общий на отряд и едет вниз вместе с ним: обновляйся он на этаже, это
был бы ресурс этажа, а не вылазки, и никуда бы не гнал. Чем глубже, тем
дороже шаг, а этажи внизу длиннее — глубина жмёт на свет дважды.

Проверка в --descend меряет правило целиком, и первая её строка не про
баланс, а про жанр: заряд на стоянке обязан стоять. Сам измеритель тоже
был неправ — делил потраченное на смещение отряда, а не на пройденный
путь, и показывал 1.55 за тайл при 1.10 в каталоге.

  свет: стоянка 0.2, ход 1.10 за тайл при 1.10 в каталоге
        глубина 8: заряда на 383 тайла, это 4.0 прямых пути до спуска
        обзор 1.00 -> 0.35 в темноте, батарея встала сама

Хватает ли заряда на этаж считается в этажах и по средней длине забега:
путь до спуска скачет вдвое от сида, и порог по одному этажу ловил бы
удачу, а не баланс.

--accept PASS без изменений: в песочнице света бесконечно, как и патронов.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 22:12:05 +03:00

14 KiB
Raw Blame History

01 — Сборка, запуск, управление

Требования

  • CMake 3.16+
  • Компилятор с C++17. Проверено на MSVC 14.44 (Visual Studio 2022, x64).
  • Интернет при первой конфигурации: raylib 6.0 качается через FetchContent. Если в системе уже стоит raylib 6.x, find_package(raylib 6) возьмёт её и ничего не качает.
  • Репозиторий SpriteForge рядом с игрой (../spriteforge): из него берётся один заголовок include/sfa.h. Лежит в другом месте — передать путь при конфигурации: cmake -S . -B build -DSPRITEFORGE_DIR=<путь>. Сам CLI sf нужен только чтобы пересобирать ассеты (12-assets.md).

Сборка

cmake -S . -B build            # разово; тянет и собирает raylib (~1-2 мин)
cmake --build build --config Release --parallel

Бинарников три, все в build/bin при любом генераторе, включая multi-config:

Цель Что это
squad_proto.exe игра Descent — один из проектов движка
tile2d_editor.exe редактор комнат: инструмент ДВИЖКА, открывает любой проект (15-engine-and-editor.md)
tile2d_walk.exe пример на движке: открыть проект, собрать этаж, походить (18-engine.md)

Третья цель, tile2d, — сам движок (18-engine.md), статическая библиотека, на которой стоят обе. Собрать что-то одно: cmake --build build --config Release --target tile2d_editor.

Debug-сборка (--config Debug) кладёт бинарник туда же и идёт в 60 fps, так что проверять правки стоит именно в ней: MSVC включает проверки итераторов и ловит выходы за границы, которых в Release не видно.

В VS Code: F5 — конфигурация Run (Release) из .vscode/launch.json, сборка идёт задачей build release. Есть также задачи accept и headless 180s.

Makefile в корне остался от исходного шаблона raylib-vscode и не используется — он ссылается на C:/raylib/w64devkit. Актуальная сборка только через CMake.

Если CMake ругается на генератор

CMake Error: Error: generator : Visual Studio 17 2022
Does not match the generator used previously: Visual Studio 18 2026

Каталог build/ привязан к конкретному генератору, и на машине с несколькими Visual Studio его легко получить несогласованным: обычный cmd.exe и Developer Command Prompt выбирают разные версии по умолчанию. Лечится сносом каталога — он целиком производный, в нём нет ничего своего:

rmdir /s /q build          # cmd
rm -rf build               # bash
cmake -S . -B build

Чтобы зафиксировать версию явно, передай генератор при первой конфигурации:

cmake -S . -B build -G "Visual Studio 17 2022" -A x64

Дальше cmake -S . -B build без -G будет переиспользовать генератор из кэша. build/ намеренно в .gitignore — в репозитории его быть не должно.

Управление

Клавиша Действие
WASD движение диска (якоря отряда) в экранных осях
Shift (удерж.) рывок (базовый шаг намеренно медленный)
Space переключить режим ручного прицеливания
/ в ручном режиме — поворот вектора прицела
Tab сменить назначенную цель (внутри конуса прицела)
1 / 2 / 3 строй: клин / линия / кольцо
F спуститься глубже (стоя на зелёном кольце)
E эвакуироваться: забег окончен, добыча в схроне (голубое кольцо)
Esc пауза (из меню — выход)
I экран отряда: снаряжение и сумки
F11 окно / безрамочный на весь экран
F1 оверлей вкл/выкл
F2 линии огня
F3 кандидаты решателя и их оценки
F4 метрики
F5 выключить хоррор-слой (свет/туман/пост)
F6 показать диски обзора
[ / ] выбрать параметр тюнинга
- / = изменить выбранный параметр
R пересобрать ТОТ ЖЕ этаж заново

По умолчанию окно разворачивается безрамочно на весь монитор, а кадр 480x270 масштабируется ЦЕЛЫМ множителем и центрируется — остаток уходит в чёрные поля. Дробное растяжение размывало бы пиксель: одни строки удваивались бы, соседние нет.

Стрельба всегда автоматическая, клавиши огня нет ни в одном режиме. Ближний бой тоже: бойцы с клинком сами доходят до цели и бьют, пока она внутри их круга (11-melee.md).

Диск намеренно быстрее бойцов и держится к ним на поводке: команда читается мгновенно, а средняя скорость похода всё равно определяется ногами отряда.

Dev-режимы командной строки

Симуляция детерминирована и не зависит от рендера, поэтому её можно гонять без окна.

Аргумент Что делает
--accept прогоняет сценарии критериев приёмки (спек 11) и печатает PASS/FAIL
--headless <сек> прогон по маршруту без окна + метрики каждые 10 с
--probe к --headless: подробности по каждому агенту на стоянках
--no-solver отключить решатель огневых позиций (A/B сравнение)
--no-laneavoid отключить расступание из чужих линий (A/B сравнение)
--melee N сколько слотов строя держат клинок (по умолчанию 2, 0 = все стрелки)
--set имя=значение подкрутить любой параметр из TUNABLES без пересборки
--shot [кадров] [файл] снять скриншот через N кадров и выйти
--clean стартовать без оверлея — чистый кадр для скриншотов
--sf-tiles пол и стены из библиотеки SpriteForge + hot reload по sf watch
--sf-enemies анимированные твари оттуда же (цикл шага вместо статичного спрайта)
--sf и то, и другое разом
--sprites что загрузчик видит в build/sprites, и выход
--windowed окно 1440x810 вместо безрамочного на весь экран
--sandbox прежняя песочница: мишени вместо тварей, отряд без снаряжения
--ui-shot <экран> снять кадр с menu / squad / pause / defeat
--rooms [проект] играть в проект (по умолчанию свой, descent) вместо захардкоженной карты
--project <имя> то же явно: имя каталога в projects/ или путь к нему
--view <iso|topdown> перебить вид отображения из манифеста проекта (отладочное)
--seed N сид сборки уровня (по умолчанию 1)
--depth N начать не с первого этажа (для проверок)
--descend N прогон забега на N этажей без окна: спуск, сумки, вес, свет, эвакуация, профиль
--tool <команда> балансовые инструменты без окна: weapons, enemies, ttk, economy
--profile <файл> где лежит профиль: схрон, снаряжение, чекпоинты
--no-profile не читать и не писать профиль

--rooms на приёмку не влияет: --accept и --headless проект не подключают вообще и меряют на прежней карте (15-engine-and-editor.md).

Примеры:

squad_proto.exe --accept
squad_proto.exe --headless 300
squad_proto.exe --headless 300 --no-solver --no-laneavoid    # каким прототип был бы без ядра
squad_proto.exe --headless 300 --melee 0                     # чистый отряд стрелков
squad_proto.exe --headless 300 --set safetyMargin=0.25 --set laneReserve=2.0
squad_proto.exe --clean --shot 220 melee.png                 # кадр без отладки
squad_proto.exe --sf-tiles                                   # тайлы из build/sprites
squad_proto.exe --sf                                         # тайлы + анимированные твари
squad_proto.exe --rooms --seed 42                            # уровень из projects/descent/rooms
squad_proto.exe --project hollow                             # второй проект: вид сверху
squad_proto.exe --rooms --view topdown                       # свой проект чужим видом

Инструментов две группы, и делятся они по предмету: squad_proto --tool считает БАЛАНС (урон, сопротивления, экономика), tile2d_editor --tool — СОДЕРЖИМОЕ (комнаты, каталог, этажи). Разделение не по вкусу: редактор линкуется только с движком и правил боя не видит вовсе.

squad_proto.exe --tool ttk        # время убийства и разброс по стихиям
squad_proto.exe --tool enemies    # здоровье и сопротивления тварей
squad_proto.exe --tool reactions  # реакции и три ограничителя
squad_proto.exe --tool economy    # доход опыта против цены дерева

Редактор комнат — отдельное приложение с собственными ключами:

tile2d_editor.exe --project descent          # правка комнат игры
tile2d_editor.exe --project hollow           # другой проект
tile2d_editor.exe --check --project descent  # проверить набор без окна, PASS/FAIL
tile2d_editor.exe --check --project hollow   # то же для второго проекта, ЕГО кривой
tile2d_editor.exe --room arena          # открыть конкретную комнату
tile2d_editor.exe --level 42            # сразу показать сборку уровня по сиду

Без --project редактор берёт единственный найденный проект. Проектов в репозитории уже два, поэтому имя обязательно: молча взятый «первый попавшийся» читался бы как «открылось не то». Игре имя можно не давать — она знает своё (descent), и --rooms открывает именно его.

Ассеты для --sf* собираются отдельной командой и в git не попадают. Палитра у библиотеки общая, поэтому манифесты собираются ВМЕСТЕ — иначе цвета тварей легли бы на палитру, посчитанную по одному полу:

sf build assets/manifests/environment.yaml assets/manifests/enemies.yaml \
  --output build/sprites --cache-dir .sfcache --jobs 8 --rebuild-palette
sf codegen --build-dir build/sprites --output generated/spriteforge_assets.h

Осечка на любом шаге оставляет процедурный набор целиком: полусобранный хуже прежнего. Поэтому --sf — это улучшение картинки, а не условие запуска.

Порядок работы с манифестами — 12-assets.md.

Код прогонов — src/debug/harness.cpp, маршрут и сценарии описаны там же. Что означают цифры в выводе — 06-debug-and-tuning.md.