--WALL. Новый прогон отвечает на вопрос, появившийся вместе с чекпоинтами через пятьдесят этажей: растёт ли достижимая глубина от вылазки к вылазке. Отряд из одного, трёх и пяти, одетый по глубине, ставится в скопление тварей и живёт полторы минуты без управления. Первая стена: одиночка D7, трое D30, пятеро D30 - петля работает. И он же нашёл настоящую ошибку: PlaceSquad воскрешал ВСЕ пять слотов, в том числе незанятые. Строка писалась, когда отряд всегда был впятером; после появления ростера одиночка выходил на этаж с четырьмя невидимыми телохранителями. Из-за них прежний замер "одиночка выжил на первом этаже, 100 -> 41" был боем впятером. ЛИЧИНКИ. С исправленным замером выяснилось, что одиночка с ножом проигрывает двум бредущим: 210 здоровья против ножа это девять секунд работы под ответным уроном. Первые этажи населены личинками (55 здоровья, 7 урона, медленные), бредущий уехал на третий этаж, бегун на четвёртый. Новый ВИД, а не ослабленный бредущий с множителем: глубина в этой игре меняет, кто выходит, а не числа у одного и того же. ПАРИРОВАНИЕ. Отдельная характеристика клинка, и чем оружие легче, тем она выше: нож 34%, сабля 20%, тесак 8%. Не выведена из веса намеренно - её двигает аффикс PARRY, и лёгкий тесак обязан быть возможен как находка. Отбить можно, только если удары СОПРИКОСНУЛИСЬ: боец сам должен быть в замахе или в ударе. Иначе клинок стал бы щитом, работающим, пока стоишь. Удавшийся отбив снимает урон, бьёт тварь ударом бойца целиком и запускает повторную атаку с начала фазы, НЕ сбрасывая откат. Последнее и есть суть размена: сбрасывай отбив откат, выгоднее было бы подставляться под удары. Плевок отбивается тоже: летит назад и несёт урон бойца, а не твари. Это его удар, просто по летящей цели. Проверка меряет размен целиком, включая обратную половину правила: "стоя столбом не отбивает". Без неё условие про соприкосновение существовало бы только в комментарии. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
14 KiB
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=<путь>. Сам CLIsfнужен только чтобы пересобирать ассеты (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 |
--ui-check |
пункты меню без окна: каждый ведёт куда-то, выходит только QUIT |
--wall N |
до какой глубины доходит отряд из 1/3/5 бойцов (нужен --rooms) |
--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 / upgrade / workshop |
--rooms [проект] |
играть в проект (по умолчанию свой, descent) вместо захардкоженной карты |
--project <имя> |
то же явно: имя каталога в projects/ или путь к нему |
--view <iso|topdown> |
перебить вид отображения из манифеста проекта (отладочное) |
--seed N |
сид сборки уровня (по умолчанию 1) |
--depth N |
начать не с первого этажа (для проверок) |
--descend N |
прогон забега на N этажей без окна: спуск, сумки, вес, свет, эвакуация, профиль |
--tool <команда> |
балансовые инструменты без окна: weapons, enemies, ttk, reactions, economy, drops, affix, craft |
--profile <файл> |
где лежит профиль: схрон, снаряжение, чекпоинты |
--no-profile |
не читать и не писать профиль |
--rooms на приёмку не влияет: --accept и --headless проект не подключают
вообще и меряют на прежней карте (15-engine-and-editor.md).
Примеры:
squad_proto.exe --accept
squad_proto.exe --ui-check
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 # доход опыта против цены дерева
squad_proto.exe --tool drops 1 100 # кривая редкости находок по глубине
squad_proto.exe --tool affix 40 # бюджет предмета и потолок аффиксов
squad_proto.exe --tool craft 80 # материалы: доход за вылазку против цены доводки
Редактор комнат — отдельное приложение с собственными ключами:
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.