96 lines
6.2 KiB
Markdown
96 lines
6.2 KiB
Markdown
# Архитектура
|
|
|
|
Документ описывает, как устроен проект: какие есть слои, кто кому имеет право
|
|
звонить и как данные ходят по системе. Структура папок — прямое отражение этих
|
|
слоёв, см. [README](../README.md#структура-репозитория).
|
|
|
|
## Слои и правила зависимостей
|
|
|
|
Стрелка «→» читается как «может знать о». Всё, что не указано, — запрещено.
|
|
|
|
```
|
|
main ──→ autoload ──→ core
|
|
│
|
|
├───→ ui ────────→ core, data
|
|
├───→ world ─────→ core, data, entities
|
|
├───→ systems ───→ core, data
|
|
├───→ entities ──→ core, data
|
|
└───→ debug ─────→ (всё, только для разработки)
|
|
```
|
|
|
|
| Слой | Зачем | Чего в нём быть не должно |
|
|
| --- | --- | --- |
|
|
| `core` | Утилиты, базовые типы, математика сетки | Ссылок на конкретные сцены и геймплей |
|
|
| `data` | Описания контента: схемы (`Resource`) и их экземпляры (`.tres`) | Логики поведения — только данные |
|
|
| `systems` | Симуляция мира: время, климат, погода, экономика | Прямого доступа к нодам сцены |
|
|
| `world` | Визуализация и взаимодействие с убежищем | Правил симуляции — они в `systems` |
|
|
| `entities` | Жители, предметы; их состояние и поведение | Знания о конкретном UI |
|
|
| `ui` | Экраны, HUD, контролы | Изменения состояния мира напрямую |
|
|
| `debug` | Дев-консоль, оверлеи, читы | Кода, от которого зависит релизная логика |
|
|
|
|
Ключевое правило: **`ui` и `world` не меняют состояние мира сами** — они шлют
|
|
намерение (сигнал/вызов системы), а изменение делает `systems`. Обратно
|
|
`systems` не дёргает ноды: он сообщает об изменении сигналом.
|
|
|
|
## Данные и рендер разделены
|
|
|
|
Симуляция не должна зависеть от того, нарисовано ли что-то на экране.
|
|
|
|
- **Данные** (`systems`, `data`) — чистая логика: считаются от `delta`, полностью
|
|
сериализуемы, тестируются без дерева сцены.
|
|
- **Рендер** (`world`, `ui`) — читает данные и отображает, подписавшись на сигналы.
|
|
|
|
Практический критерий: любой класс из `systems` должен работать в юнит-тесте,
|
|
где никакой сцены нет.
|
|
|
|
## Обмен сообщениями
|
|
|
|
Три способа, в порядке предпочтения:
|
|
|
|
1. **Сигнал вверх, вызов вниз.** Родитель знает о детях и вызывает их методы;
|
|
ребёнок о родителе не знает и только испускает сигналы.
|
|
2. **Ссылка на систему**, полученную из автозагрузки — когда нужен ответ здесь и
|
|
сейчас (запрос состояния, валидация постройки).
|
|
3. **Глобальная шина (`EventBus` в `autoload`)** — только для событий, которые
|
|
слушают несколько несвязанных слоёв (например, «время перескочило»,
|
|
«погода сменилась»). Не превращать её в свалку: каждый сигнал документируем.
|
|
|
|
## Контент — это ресурсы, а не код
|
|
|
|
Новая комната, предмет или тип породы добавляются как `.tres` в `data/tables/`
|
|
по схеме из `data/resources/`, без правки кода. Если для добавления контента
|
|
приходится менять `.gd` — схема неполная, чинить надо схему.
|
|
|
|
## Автозагрузки
|
|
|
|
Автозагрузка — дорогая вещь: она живёт всю сессию и её видно отовсюду. Заводим
|
|
только для того, что действительно глобально и одно на игру. Каждая новая
|
|
автозагрузка регистрируется через *Project Settings → Autoload* и упоминается
|
|
здесь.
|
|
|
|
Сейчас в проекте:
|
|
|
|
| Автозагрузка | Что делает |
|
|
| --- | --- |
|
|
| `EventBus` (`src/autoload/event_bus.gd`) | Глобальная шина событий, пока пустая |
|
|
| `_mcp_game_helper` | Служебная, часть плагина `godot_ai`; к игре отношения не имеет |
|
|
|
|
## Точка входа
|
|
|
|
`src/main/main.tscn` — главная сцена проекта:
|
|
|
|
```
|
|
Main (Node2D) # main.gd: только сборка, никаких игровых правил
|
|
├── World (Node2D) # убежище: порода, сетка, комнаты, жители
|
|
└── UI (CanvasLayer) # интерфейс поверх мира, не зависит от камеры
|
|
```
|
|
|
|
`World` и `UI` разделены слоями сразу, чтобы интерфейс не ездил вместе с
|
|
камерой убежища и не масштабировался вместе с зумом.
|
|
|
|
## Решения
|
|
|
|
Существенные развилки (выбор подхода к сохранению, к сетке, к тайм-степу)
|
|
фиксируем как ADR в [`adr/`](adr/) — короткая заметка «контекст → решение →
|
|
последствия». Это дешевле, чем через полгода восстанавливать мотивацию по коду.
|