105 lines
8.1 KiB
Markdown
105 lines
8.1 KiB
Markdown
# CLAUDE.md
|
||
|
||
Заметки для агентов, работающих с этим репозиторием.
|
||
|
||
## Что это за проект
|
||
|
||
Двумерная игра с видом сбоку на Godot 4.7. Референс — Fallout Shelter: разрез убежища,
|
||
комнаты в сетке, жители. **Игра полностью 2D.** Новые игровые сцены — на `Node2D`/`Control`;
|
||
3D-узлам в проекте места нет. Рендерер при этом Forward+ — так решил владелец проекта,
|
||
не переключайте его без явной просьбы.
|
||
|
||
## Работа через MCP, а не через файлы
|
||
|
||
В проекте включён плагин `addons/godot_ai`, редактор Godot обычно запущен и подключён.
|
||
Сцены и ресурсы правьте инструментами MCP (`scene_manage`, `ui_manage`, `node_create`,
|
||
`theme_manage`, `resource_manage`), а не редактированием `.tscn` руками — иначе открытый
|
||
редактор перезапишет изменения при сохранении.
|
||
|
||
Скрипты — через `script_create` / `script_patch`: они возвращают диагностику парсера сразу.
|
||
|
||
Проверять результат — `project_run` + `editor_screenshot(source="game")`. Ввод в запущенную
|
||
игру шлётся через `game_manage(op="input_key")`; **`input_action` не двигает фокус Control-ов**,
|
||
для навигации по UI нужны настоящие события клавиш.
|
||
|
||
### Известные особенности
|
||
|
||
- `node_set_property` не принимает целочисленный `0` — используйте `batch_execute`
|
||
с командой `set_property`.
|
||
- Правка скрипта, который зарегистрирован автозагрузкой, даёт в ответе
|
||
`GDScript reload failed with error code 43`. Это неудачная горячая перезагрузка в редакторе,
|
||
а не ошибка разбора: проверяйте `logs_read(source="editor")`, игра при этом запускается чисто.
|
||
- `project_manage(op="settings_set")` отказывается менять `application/run/main_scene`.
|
||
- Большие `ui_manage(op="build_layout")` иногда не доезжают целиком — стройте дерево
|
||
несколькими вызовами поменьше.
|
||
- Запуск из редактора отдаёт встроенное окно: `Embedded window can't be resized` в логе — норма.
|
||
|
||
## Конвенции кода
|
||
|
||
- Отступы — табы (см. `.editorconfig`), статическая типизация везде, где возможно.
|
||
- Комментарии и весь UI-текст — по-русски; имена узлов, файлов, методов, сигналов — по-английски.
|
||
- Комментарий объясняет **почему**, а не пересказывает код.
|
||
- Приватные члены — с подчёркиванием: `_card`, `_focus_first_button()`.
|
||
- Документирующие комментарии `##` — на классах, сигналах и неочевидных методах.
|
||
|
||
## Архитектура UI
|
||
|
||
- Единая тема `themes/main_menu.theme.tres` на корне каждого экрана. Цвета в узлах не хардкодим.
|
||
- Экран = сцена со своим скриптом, наружу торчат `open()` / `close()` и сигнал `closed`.
|
||
- Оверлеи центрируются `CenterContainer`, а **не** пресетом `center`: пресет ставит левый
|
||
верхний угол карточки в центр экрана. Та же ловушка у `bottom_wide` — он прижимает к нижнему
|
||
краю *верх* панели, и она уезжает за экран; для нижней панели используйте `MarginContainer`
|
||
во весь экран + `HBoxContainer` с `size_flags_vertical = SIZE_SHRINK_END` у содержимого.
|
||
- Контейнеры не раскладывают скрытые узлы — после `visible = true` нужен
|
||
`await get_tree().process_frame`, прежде чем читать `size` (например, для `pivot_offset`).
|
||
- Наведение мышью делается фокусом (`mouse_entered` → `grab_focus`), чтобы у мыши и клавиатуры
|
||
была одна подсветка.
|
||
|
||
## Игровой слой
|
||
|
||
Файлы в `scripts/game/` разделены по принципу «данные и правила отдельно, отрисовка отдельно».
|
||
|
||
Модель и правила — без узлов и без `_draw()`:
|
||
|
||
- `vault_grid.gd` — сетка и комнаты. Сюда идут типы комнат, размещение, ресурсы.
|
||
Вертикальное смещение бункера под землю — константа `DEPTH`, её учитывают и
|
||
`cell_rect()`, и `cell_at()`, поэтому картинка и попадание мышью не разъезжаются.
|
||
- `game_clock.gd` — игровые дата и время, скорость, своя пауза. Такт наружу — сигнал
|
||
`minute_passed`; темп задаётся `MINUTES_PER_SECOND`.
|
||
- `weather_system.gd` — тип погоды, матрица переходов и плавная смена параметров.
|
||
Такт берёт у часов, поэтому стоит вместе с паузой.
|
||
- `sky_cycle.gd` — палитра неба по часу суток, положение солнца и луны. Чистые вычисления.
|
||
|
||
Отрисовка — только `_draw()`, читают модель и ничего не решают:
|
||
|
||
- `sky_view.gd` — градиент неба, звёзды, светила.
|
||
- `surface_view.gd` — поверхность: горы, холмы, деревья, облака, осадки.
|
||
- `vault_view.gd` — разрез: порода, корпус, шахта, комнаты, будка входа.
|
||
|
||
`vault_scene.gd` связывает всё это с камерой и HUD и держит контракт сохранения.
|
||
|
||
Новый тип комнаты добавляется одной записью в `VaultGrid.KINDS`: кнопка в панели строительства
|
||
и подсчёт ресурсов подхватятся сами. Новый тип погоды — записью в `WeatherSystem.KINDS`
|
||
плюс строкой в `TRANSITIONS`.
|
||
|
||
### Текстуры фона
|
||
|
||
`background/` — набор Kenney Background Elements. Два стиля, и они не взаимозаменяемы:
|
||
`PNG/Flat/*` — бледные, почти белые силуэты, их место на дальних планах, где цвет всё равно
|
||
задаётся тонировкой; `PNG/*` — цветные спрайты для ближнего плана. Перепутать легко: деревья
|
||
из Flat на переднем плане выглядят выцветшими.
|
||
|
||
## Автозагрузки
|
||
|
||
`GameSettings` (`GameSettingsService`) и `SaveManager` (`SaveManagerService`).
|
||
У обеих есть `class_name`: константы, перечисления и типы берём через него, экземпляр —
|
||
через `get_node("/root/...")`. Имя автозагрузки редактор не резолвит без перезапуска проекта.
|
||
|
||
Контракт сохранения игровой сцены описан в [README.md](README.md).
|
||
|
||
## Проверка
|
||
|
||
Изменения в UI считаются сделанными только после запуска и скриншота. Логи смотреть в обоих
|
||
источниках: `logs_read(source="game")` и `logs_read(source="editor")` — ошибки загрузки скриптов
|
||
попадают только во второй.
|