Imported from shpaker/tnk9x (
AGENTS.md). Install upstream withnpx skills add shpaker/tnk9x. Copyright stays with the author.
Правила для AI-агентов
Ремейк Battle City на Go + Ebiten v2. Clean Architecture, модуль github.com/shpaker/tnk9x.
Архитектура
Зависимости направлены только внутрь: внешние слои зависят от внутренних через интерфейсы, Domain не зависит ни от чего. Границы слоёв проверяет depguard (.golangci.yml).
internal/
├── app/ # Composition root — сборка графа, game loop, конфиг
├── types/ # Domain — entity-типы, image_providers; без зависимостей
├── interfaces/ # Контракты между слоями; без движка и рантаймов
├── use_cases/ # Application — бизнес-логика
├── services/ # Application — специализированные сервисы
├── adapters/ # Presentation — рендер, ввод, звук, scripting
├── states/ # Presentation — состояния приложения
└── repositories/ # Infrastructure — доступ к данным
Принципы
- Use cases: stateless, одна ответственность, работают только с интерфейсами. Допустимые поля: единственные на уровень сущности (
StageSessionEntity,MapEntity,HQEntity) и иммутабельная конфигурация. - Все зависимости — через конструктор
New*; сеттеры и nil-проверки зависимостей запрещены: граф гарантирует composition root (internal/app). У каждой реализации — compile-timevar _ interfaces.X = (*Y)(nil). - Экземпляры use cases общие для всех сущностей одного типа; entity передаются как параметры методов.
- Сервисы коллизий (
internal/services/collision_services/) только проверяют коллизии и возвращаютbool; изменения вносят use cases. Универсальная проверка — черезIEntityCollider. - Entity живут только в Domain, поля унифицированы по порядку и смыслу.
GameSessionEntityдопустима только вinternal/app; в стейтах и их use cases —StageSessionEntity(источник данных о прогрессе уровня дляStageState).- Переходы между состояниями — через
types.StateTransition, возвращаемый изUpdate(); контракт стейта определён у потребителя (internal/app). - Runtime-состояние игры (танки, пули, бонусы, анимации, звуковые события) — в
internal/repositories/game, пересоздаётся на каждый уровень. - Отрисовка — только через адаптеры рендера (
*renderer_adapter). - Lua — только в
internal/adapters/scriptingза доменнымIAIScriptEngine.
Именование
- Типы:
*Entity,*UseCases,*Service,*Repository; интерфейсы —I*(ITankCommonUseCases). - Конструкторы —
New*; геттеры —Get*, сеттеры —Set*. - Без сокращений:
selectorUseCases,mapsRepository, а неselUC. - Короткие понятные имена:
Image, а неImageGetter. - Поля — максимально приватные; группировать по типу сущности (Entities, Use Cases, Adapters), группы разделять комментарием.
- Методы группировать по функциональным областям, внутри группы — логический порядок.
Стиль кода
- Стандартные Go conventions; short variable declarations, где уместно.
- Комментарии к бизнес-логике — на русском.
- Документировать интерфейсы и публичные методы, указывать реализуемые интерфейсы.
- Тесты (
*_test.go) — максимально простые и понятные; общие фейки — вinternal/testutil.
Ресурсы
Только через репозитории: прямое чтение файлов и хардкод путей запрещены. Обработанные ресурсы — из internal/repositories/processed/, сырые файлы — только через IFileRepository.
- Шрифты:
IFontsRepository.GetFont("PressStart2P") - Скрипты:
IScriptsRepository.GetScript("enemies") - Карты:
IMapsDataRepository.GetLevel(1) - Тайлсеты:
ITilesetRepository.GetImage("brick")
Запрещено
- Entity с зависимостями от других слоёв; stateful use cases.
- Прямые зависимости в обход интерфейсов; создание use cases внутри других use cases.
- Сеттеры и nil-проверки зависимостей; пост-конструкционная донастройка графа.
- Смешение ответственностей: один use case — одна область.
- Прямой доступ к файловой системе.
- Устаревшие и deprecated API (например,
rand.Seed).
Обязательно
- После правок:
just fmt,just lint,go build ./...; линтер держать чистым. - Покрытие ядра не ниже порога:
just test-coverage-check. - Новые типы размещать в корректном слое.
- При существенных изменениях (новые фичи, use cases, сервисы, адаптеры, состояния, репозитории, типы сущностей) обновлять чеклист Development Status в
README.md: новая фича →[x], часть функциональности → подпункт, изменение архитектуры → разделы Technical Infrastructure.
Git
- Любые записывающие git-операции (commit, push, merge, rebase, reset, tag и т.п.) — только с явного подтверждения пользователя.
- Коммиты — только от лица пользователя; упоминания ИИ (
Co-Authored-By,Generated with ...и т.п.) в сообщениях и метаданных запрещены. - Описание PR/MR — лаконичное, простым текстом без форматирования (заголовков, выделений).
CI/CD
- ОС-зависимости (Linux-пакеты) одинаковы во всех джобах и пайплайнах; при изменении обновлять все использующие их джобы.
Рефакторинг
- Проверять сборку
go build ./...; находить и обновлять все использования изменённых сущностей; обновлять тесты; запускать fmt и линтер.
