squad-proto/CLAUDE.md
z.kirill 3ebd1f96fc Дерево улучшений вместо четырёх кнопок (M32)
Четыре строки покупок (патроны, переноска, обзор, живучесть) удалены
целиком. Выбора в них не было: купить в итоге можно было всё, порядок ни
на что не влиял, и через две вылазки экран превращался в кнопку
"продолжить".

Дерево: пять ветвей по восемь узлов, у каждого пять уровней. Ветви - это
пять способов закрыть разрыв из закона масштаба: стволы, клинки, стихии,
снабжение, отряд. Ветвь открывается цепочкой - узел доступен, когда взят
предыдущий в этой же ветви. Свободная сетка читалась бы как список;
цепочка читается как путь.

Ни один узел не заводит нового канала влияния: каждый кладёт своё число
туда, куда уже кладут снаряжение и аффиксы. Дерево будет расти, и первый
же "особенный" узел со своей веткой в коде превратил бы SyncLoadout в
свалку.

ЭКОНОМИКА. --tool economy поймал, что первая версия дерева стоит 9%
одного прохода 1..100: опыт растёт с глубиной квадратично, а дерево с
фиксированными ценами выкупается целиком за половину глубокого прохода, и
выбор кончается к сороковому этажу навсегда.

Введено общее удорожание: каждая вложенная точка поднимает цену всех
следующих (цена = база · 1.5^уровень · (1 + 0.15 · вложено)). Полное
дерево стоит 34 млн против 41 млн, заложенных в дизайне, то есть около
шести с половиной полных проходов.

Старые покупки из профиля читаются, но не применяются: потраченный на них
опыт возвращается в банк. Молча съесть чужие двадцать часов нельзя.

Проверка меряет ПРОВОДКУ по всем пяти ветвям, а не таблицу узлов:

  дерево: куплено уровней 45, закрытый узел закрыт
          урон ствола 12.0 -> 14.4, здоровье 100 -> 150, скорость 1.06 -> 1.22
          парирование 0.34 -> 0.49, свет 420 -> 620

Попутно: в проекте hollow бегуны и хваты уехали с первых этажей глубже -
там одиночка с ножом гиб на первом же этаже по той же причине, по которой
это было в основном проекте.

Формат профиля 7: строки tree.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-16 19:24:50 +03:00

16 KiB
Raw Blame History

CLAUDE.md — оглавление

Этот файл — только навигация. Содержание живёт в docs/, по одному файлу на тему. Читай нужный раздел, а не весь проект.

Документация

Файл О чём Когда открывать
docs/00-overview.md что это за прототип, границы задачи первое знакомство
docs/01-build-and-run.md сборка, запуск, управление, dev-режимы CLI собрать и потыкать
docs/02-architecture.md карта модулей, порядок шага симуляции, правила зависимостей перед любой правкой кода
docs/03-rendering.md софтверный фреймбуфер, изометрия, сортировка, спрайты рендер, камера, спрайты
docs/04-world.md тайлмап, планировка уровня, DDA-рейкаст, коллизии, мишени карта, LOS, коллизии
docs/05-squad-ai.md ядро: LaneClear, решатель огневых позиций, резерв линий, стрельба поведение отряда
docs/06-debug-and-tuning.md оверлей F1F4, метрики, runtime-тюнинг, --set отладка и балансировка
docs/07-milestones.md журнал вех M0M6: что сделано и чем проверено история и статус
docs/08-decisions.md отклонения от спека и почему, с замерами «почему тут не как в ТЗ»
docs/09-acceptance.md критерии приёмки (спек 11) и их текущие цифры приёмка
docs/10-atmosphere.md хоррор-слой: свет, туман войны, трассеры, напряжение картинка и атмосфера
docs/11-melee.md ближний бой: сектор удара, три фазы, свой круг, дуга клинки, классы оружия
docs/12-assets.md ассеты: конвейер SpriteForge, манифесты, загрузчик, hot reload добавить или пересобрать спрайт
docs/13-combat.md бой: каталог оружия, твари, снаряжение, меню и HUD оружие, враги, инвентарь, UI
docs/14-monsters.md твари-ассеты: Blender-риг на пять морфологий, листы, проверки нарисовать или пересобрать тварь
docs/15-engine-and-editor.md движок и редактор: три цели сборки, каталог сущностей, формат комнат, генератор уровней делать комнаты, менять генерацию, трогать границу движка
docs/16-descent.md спуск: глубина как первичное понятие, бюджет опасности, лут, кривая сложности менять сложность, добавлять тварей и лут
docs/17-extraction.md экстракшен: эвакуация, профиль и схрон, чекпоинты, что теряется правила забега, снаряжение между вылазками
docs/18-engine.md Tile2D: границы движка, проекции 2D, формат проекта, второй проект трогать движок, заводить проект, добавлять вид отображения
docs/19-agent.md движок и ЛЛМ: инструменты --tool, скиллы, терминал в редакторе работать над проектом через claude/codex
docs/20-gdd.md дизайн игры: акты, петли, рост отряда, закон масштаба, 200 часов что и зачем строим дальше
docs/21-damage.md урон: семь стихий, статусы, реакции, формулы, триггеры боевая математика
docs/22-loot.md добыча: редкости, аффиксы, артефакты, зачарования, материалы предметы и экономика
docs/23-endgame.md лейтгейм: Бездна, мутации, лидерборды, 262 ачивки всё после сотого этажа

Быстрые факты

  • Исходный спек: SQUAD_PROTOTYPE_SPEC.md — источник истины по правилам.
  • Сборка: cmake -S . -B build && cmake --build build --config Release. Целей три: tile2d (библиотека), build/bin/squad_proto.exe (игра), build/bin/tile2d_editor.exe (редактор комнат).
  • Инструментов две группы, и делятся они по предмету: squad_proto --tool — баланс (урон, сопротивления, экономика), tile2d_editor --tool — содержимое (комнаты, каталог, этажи). Редактор не линкуется с sim/ и правил боя не видит, поэтому смешать их нельзя.
  • Содержимое щупают инструментами, а не глазами: tile2d_editor --tool help. Правка делается файлами (комнаты и каталог — текст), последствия читаются командой: --tool validate, --tool floor, --tool map (19-agent.md). Код возврата 1 = поломка.
  • В редакторе снизу терминал (клавиша `): те же инструменты, git, сборка и запросы к claude/codex прямо оттуда. Открытый проект уходит потомкам переменной TILE2D_PROJECT.
  • Самопроверка: squad_proto.exe --accept печатает PASS/FAIL по всем измеримым критериям. Содержимое проверяется отдельно: tile2d_editor.exe --check (комнаты и покрытие глубин), squad_proto.exe --descend 8 (спуск, эвакуация, круговой прогон профиля), squad_proto.exe --ui-check (пункты меню: каждый куда-то ведёт).
  • У кнопки тоже есть код возврата. Пункт UPGRADES четыре вехи закрывал игру вместо открытия экрана: в обработчике стоял default: quit, а новый пункт добавили четвёртым. Все прогоны меряли симуляцию, меню не проверял никто — теперь проверяет --ui-check, и новый экран обязан появиться в нём.
  • Ставка — на ВЕЩИ, а не на опыт. Опыт платится за убийства и сразу; вынести надо добычу. Вайп оставляет около половины (редкое роняется чаще), достигнутая глубина не теряется никогда (17-extraction.md).
  • Оперативников НАХОДЯТ, а не покупают. Капсула на этаже — примерно раз в сто этажей и не чаще раза в двадцать. Кнопки «нанять» в меню нет намеренно (17-extraction.md).
  • NUM_AGENTS — это вместимость, а не размер отряда. Сколько слотов занято, говорит Squad::roster, а занят ли конкретный — Agent::present. Правила боя читают только alive (пустой слот и павший для них одно), а рендер, HUD и профиль обязаны смотреть на present: иначе у одинокого оперативника вокруг появятся четыре чужих трупа (17-extraction.md).
  • Таймера в игре нет и не заводить. Фонарь тратит заряд за ПРОЙДЕННЫЙ ПУТЬ, а не за время: стоять и думать бесплатно, дорого — обшарить этаж целиком. Расход со dt вместо пути — это таймер, и --descend его ловит (17-extraction.md).
  • Закон масштаба: угроза растёт квадратично, сила отряда — линейно с затуханием, разрыв закрывается ЗНАНИЕМ (стихии, реакции, порядок целей). Числа не должны спасать — иначе хоррор кончается на сороковом этаже (20-gdd.md).
  • Предмет — это ЭКЗЕМПЛЯР, а не вид. ItemInstance неявно приводится к ItemId, и это удобно ровно до того места, где вещь копируют: присваивание в ItemId молча теряет редкость и аффиксы. Подбор, перекладывание и запись профиля обязаны работать с экземпляром целиком (22-loot.md).
  • Материал добывается только в своей полосе. Био-ядра — с плотских этажей, крио — с мёрзлых, и это единственная причина возвращаться на средние глубины после рекорда. Протечка полос убивает весь контент, кроме последнего акта (22-loot.md).
  • Журнал событий (sim/events.h) правила боя НЕ читают. Это канал «симуляция → эффекты», и в headless его нет вовсе: начни от него зависеть — игра станет вести себя по-разному с окном и без. Триггеры срабатывают в месте урона, а не по журналу (21-damage.md).
  • Дерево улучшений — данные, а не код. Сорок узлов лежат таблицей в sim/tree.h, и каждый кладёт своё число в УЖЕ существующий канал (статы бойца, множители оружия, ресурсы вылазки). Узел, которому нужен свой канал, в дерево не берут, пока канал не появился сам (17-extraction.md).
  • Ни одного чистого улучшения. Артефакт без цены становится обязательным, а обязательный предмет — это вырезанный слот (22-loot.md).
  • Глубина — первичное понятие. Вся кривая сложности живёт в одной функции DescribeFloor (engine/progression.h); размазывать её по генератору, каталогу и рендеру нельзя (16-descent.md).
  • Редактор линкуется только с движком. Обращение из editor/ к sim/, ai/ или ui/ — ошибка сборки, и так задумано (15-engine-and-editor.md). Редактор принадлежит движку: он открывает любой проект (--project <имя>) и ни одной игры по имени не знает.
  • Тексты НА ЭКРАНЕ — латиницей: встроенный шрифт raylib кириллицы не знает и рисует её вопросами. Комментарии и вывод в консоль остаются русскими.
  • Числа игры — в src/tuning.h, размеры движка — в engine/config.h. Магических констант по коду быть не должно.
  • src/ai/ не знает про рендер, изометрию и ввод. Это правило не нарушать.
  • Правило «не бить своих» одно на все классы оружия: у ствола это отрезок, у клинка — сектор. Ослаблять его нельзя нигде.
  • RenderGame принимает const Game& — эффекты физически не могут влиять на симуляцию.
  • Приёмка меряется в ПЕСОЧНИЦЕ: Game::combatMode выключен, в мире мишени, на бойцах нет снаряжения. Ломать это нельзя — иначе --accept меряет другое.

Ассеты

Спрайты собирает внешний CLI SpriteForge (C:\Users\uuu\Documents\spriteforge). Полный порядок работы — в docs/12-assets.md, здесь только запреты:

  • игра хранит манифесты assets/manifests/, исходники assets/sources/ и сгенерированный generated/spriteforge_assets.h; собранное лежит в build/sprites/ и в git не попадает;
  • не открывать build/sprites/*.sfa, .sfcache/, сгенерированные PNG и contact sheet: проверка только текстом — sf list, sf describe, sf ascii, sf validate, sf stats;
  • строковых ID ассетов в C++ нет — только константы SF_ASSET_*;
  • не править репозиторий SpriteForge ради одной игровой сущности.

Agent sprite production

For ANY request to create, change, replace, or add game art, follow .claude/commands/sprite.md (the /sprite workflow) automatically even when the user did not type the slash command. Never satisfy an art request with a one-off procedural runtime drawing.

When asked to create an agent, armor, or weapon sprite, use /agent-sprite and assets/agents/catalog.yaml; do not draw a one-off procedural humanoid. Agent art is an aligned paper-doll: body, armor and held weapon are separate 70x90, eight-direction layers sharing one rig and pivot. Run tools/build_agent_assets.ps1 after ingestion. Start the game with --sf-agents (or --sf) to see the generated layers. Blender is installed at C:\Program Files\Blender Foundation\Blender 5.2\blender.exe.

Monster sprite production

Enemies do NOT go through the agent paper-doll. They have their own Blender-first pipeline: assets/monsters/catalog.yaml, tools/blender/monster_rig.py, tools/monster_assets.py (monster-init, monster-render, monster-render-all, validate, sync). Five kinds, five distinct morphologies — never one humanoid recoloured five times. Asset ids are <kind>_<animation>; renaming them breaks tools/asset_coverage.py. Full rules in docs/14-monsters.md.