From 85f6897365b8d4717d8670808d2223c3024d247f Mon Sep 17 00:00:00 2001 From: user-penguin Date: Sat, 3 Oct 2026 13:20:50 +0700 Subject: [PATCH] init --- .gitignore | 1 + minecraft_modpack_platform_PLAN.md | 1677 ++++++++++++++++++++++++++++ 2 files changed, 1678 insertions(+) create mode 100644 .gitignore create mode 100644 minecraft_modpack_platform_PLAN.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..222b181 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*Zone.Identifier \ No newline at end of file diff --git a/minecraft_modpack_platform_PLAN.md b/minecraft_modpack_platform_PLAN.md new file mode 100644 index 0000000..7e0e36b --- /dev/null +++ b/minecraft_modpack_platform_PLAN.md @@ -0,0 +1,1677 @@ +# Платформа для Minecraft-модпаков — план реализации + +## 1. Цель + +Создать local-first платформу для создания, версионирования, упаковки, развёртывания и сопровождения воспроизводимых Minecraft-модпаков для небольшой группы игроков. + +Платформа должна быть оптимизирована под: + +- Prism Launcher как клиентский лаунчер. +- Docker Compose как серверный runtime. +- удалённый доступ к серверу по SSH. +- Git как источник истины для описания сборки и конфигурации. +- обычные читаемые файлы на диске вместо непрозрачных Docker volumes. +- простую установку, удаление и обновление модов. +- воспроизводимые сборки. +- простой rollback. +- минимум собственной логики там, где задача уже хорошо решена существующими инструментами экосистемы. + +Сама платформа должна в первую очередь выступать как orchestration-слой вокруг: + +- packwiz +- Modrinth `.mrpack` +- Prism Launcher +- `itzg/minecraft-server` +- Docker Compose +- Git +- SSH / rsync + +Не разрабатывать собственный resolver зависимостей Minecraft-модов без реальной необходимости. + +--- + +# 2. Основная архитектура + +Система состоит из четырёх концептуальных слоёв. + +```text +┌──────────────────────────────────────────┐ +│ 1. ИСХОДНИК МОДПАКА │ +│ │ +│ packwiz │ +│ mods / configs / datapacks / resources │ +│ Minecraft + версии loader │ +└────────────────────┬─────────────────────┘ + │ + build + │ + ┌──────────┴──────────┐ + ▼ ▼ +┌──────────────────┐ ┌──────────────────┐ +│ 2. CLIENT PACK │ │ 3. SERVER PACK │ +│ │ │ │ +│ Modrinth .mrpack │ │ Modrinth .mrpack│ +│ Prism Launcher │ │ itzg installer │ +└──────────────────┘ └─────────┬────────┘ + │ + ▼ + ┌──────────────────┐ + │ 4. SERVER STATE │ + │ │ + │ world │ + │ logs │ + │ backups │ + │ whitelist │ + │ server runtime │ + └──────────────────┘ +``` + +Ключевое правило: + +> Git source является источником истины для желаемого состава сборки и управляемой конфигурации. Runtime является источником истины для текущего мира и прочего persistent state. Сгенерированные артефакты фиксируют конкретный релиз, но не заменяют его исходники. + +--- + +# 3. Выбор технологий + +## Обязательные компоненты + +### packwiz + +Использовать packwiz для: + +- метаданных зависимостей модов; +- фиксации точных версий модов; +- интеграции с Modrinth; +- интеграции с CurseForge там, где это необходимо; +- metadata о client/server side; +- индексирования конфигов и ресурсов; +- генерации `.mrpack`. + +### Modrinth `.mrpack` + +Основной формат распространяемого артефакта. + +Причины: + +- Prism Launcher импортирует его напрямую. +- Формат поддерживает client/server side metadata. +- Он переносим. +- Хорошо работает с packwiz. +- Может использоваться серверным tooling для установки сборки. + +### Prism Launcher + +Основной клиентский лаунчер. + +Платформа должна генерировать артефакты, которые Prism может использовать без необходимости вручную изменять созданный instance. + +### Docker Compose + +Оркестрация сервера. + +### itzg/minecraft-server + +Контейнерный runtime Minecraft-сервера. + +По возможности использовать конфигурацию через environment variables и bind-mounted директории. + +### Git + +Git отслеживает: + +- metadata модпака; +- определения модов; +- конфиги; +- скрипты; +- server compose-файлы; +- конфигурацию платформы. + +Git не должен отслеживать: + +- миры; +- логи; +- большие backups; +- runtime cache; +- секреты. + +### SSH + rsync + +Основной транспорт deployment для первой версии. + +В v1 не требовать Kubernetes, Docker Registry, серверных агентов или CI/CD-инфраструктуры. + +--- + +# 4. Структура репозитория + +Начальная структура репозитория: + +```text +minecraft-platform/ +├── README.md +├── PLAN.md +├── Makefile +├── .gitignore +│ +├── platform/ +│ ├── config.yaml +│ └── schemas/ +│ +├── pack/ +│ ├── pack.toml +│ ├── index.toml +│ ├── mods/ +│ ├── config/ +│ ├── defaultconfigs/ +│ ├── resourcepacks/ +│ ├── shaderpacks/ +│ ├── datapacks/ +│ └── kubejs/ +│ +├── server/ +│ ├── compose.yaml +│ ├── compose.override.yaml.example +│ ├── server.properties +│ ├── config/ +│ └── .env.example +│ +├── scripts/ +│ ├── build +│ ├── deploy +│ ├── rollback +│ ├── backup +│ ├── doctor +│ └── console +│ +├── dist/ +│ └── .gitkeep +│ +└── runtime/ + └── .gitkeep +``` + +`runtime/` используется только для локального development-runtime и должен быть добавлен в `.gitignore`, кроме `.gitkeep`. + +Удалённый сервер должен использовать аналогичную структуру runtime-директорий. + +--- + +# 5. Конфигурация платформы + +Добавить единый высокоуровневый конфигурационный файл платформы. + +Рекомендуемый начальный формат: + +```yaml +schema_version: 1 + +pack: + directory: ./pack + +build: + output_directory: ./dist + +server: + host: minecraft + directory: /srv/minecraft/friday + memory: 8G + port: 25565 + +deploy: + transport: ssh + healthcheck_timeout: 120 +``` + +Рекомендуемый файл: + +```text +platform/config.yaml +``` + +Этот файл является manifest верхнего уровня для платформы. + +packwiz остаётся источником истины для metadata отдельных модов. + +Имя, версия сборки, Minecraft, loader и его версия читаются из `pack/pack.toml`. Не дублировать их и версии модов в `config.yaml`. Примеры версий в плане иллюстративны; совместимую комбинацию выбрать и проверить в Phase 0. + +--- + +# 6. Правила источников истины + +Необходимо явно зафиксировать зоны ответственности. + +## Platform config отвечает за + +- версию схемы конфигурации; +- серверные значения по умолчанию; +- deployment target; +- схему именования релизов. + +## packwiz отвечает за + +- имя и версию сборки в `pack.toml`; +- Minecraft, тип и точную версию loader в `pack.toml`; +- моды; +- версии модов; +- side metadata; +- downloads; +- pack indexes; +- правила включения на client/server. + +## Серверная конфигурация отвечает за + +- `server.properties`; +- начальные шаблоны whitelist и operators; +- server-specific overrides конфигурации модов; +- настройки Docker runtime. + +## Runtime отвечает за + +- действующие whitelist и operators (шаблоны применяются только при первом запуске); +- persistent данные модов, в том числе вне world; +- world; +- logs; +- cache; +- временные downloads; +- сгенерированное runtime-состояние. + +Никогда не считать `runtime/mods` источником истины. + +--- + +# 7. Дизайн CLI + +В перспективе user-facing интерфейс должен быть одной командой. + +Пример имени: + +```text +mcpack +``` + +Точный язык реализации можно выбрать позже. + +В v1 допустимо реализовать всё shell-скриптами или Makefile. + +Ожидаемые команды в долгосрочной перспективе: + +```bash +mcpack init + +mcpack add create +mcpack add sodium --client +mcpack remove create + +mcpack update create +mcpack update --all + +mcpack check +mcpack doctor + +mcpack build +mcpack release + +mcpack deploy +mcpack restart +mcpack status +mcpack logs +mcpack console + +mcpack backup +mcpack rollback +``` + +CLI должен оставаться тонким orchestration-слоем. + +По возможности команды должны напрямую делегировать работу packwiz, Docker Compose, SSH и rsync. + +--- + +# 8. Процесс сборки + +Канонический flow: + +```text +source pack + server config + pinned toolchain +→ validation +→ временная копия source +→ packwiz refresh + packwiz modrinth export в копии +→ dist/-/ +``` + +Build не меняет tracked source. Если refresh выявляет устаревший исходный индекс, release прекращается с инструкцией явно обновить и закоммитить его. + +Состав релиза: + +```text +dist/friday-minecraft-0.4.0/ +├── friday-minecraft-0.4.0.mrpack +├── server/ +│ ├── compose.yaml +│ ├── server.properties +│ └── config/ +├── manifest.json +└── SHA256SUMS +``` + +Manifest обязателен: schema version, имя и версия, Minecraft, loader и его версия, Git commit, признак dirty build, версия packwiz, image digest и список управляемых файлов. SHA256SUMS покрывает все файлы релиза кроме самого SHA256SUMS. Секреты и deployment target в релиз не включаются. + +Prism получает .mrpack, сервер — весь каталог релиза. Общий .mrpack — начальный вариант; отдельная серверная трансформация допустима по результатам spike и должна быть воспроизводимой. + +Локальный development build допускает dirty worktree и явно помечается. Release и deployment требуют чистый worktree. Готовые релизы сохраняются для deployment и rollback без повторной сборки. + +--- + +# 9. Валидация сборки + +`mcpack check` должен как минимум проверять: + +- platform config успешно парсится; +- версия Minecraft указана; +- loader входит в комбинации, подтверждённые spike; +- версия loader зафиксирована; +- packwiz-файлы существуют; +- metadata packwiz внутренне консистентны; +- отсутствуют очевидные дубликаты определений модов; +- необходимые server-файлы существуют; +- output directory доступна для записи; +- известные пути секретов не отслеживаются Git (это не гарантия обнаружения всех секретов); +- pack может быть успешно экспортирован; +- Java образа соответствует выбранному Minecraft/loader; +- manifest и checksums согласованы. + +Позже можно добавить: + +- проверку совместимости client/server dependencies; +- обнаружение несовместимого loader; +- duplicate mod IDs; +- неподдерживаемые версии Minecraft; +- расширенную проверку совместимости Java runtime; +- schema validation конфигов. + +--- + +# 10. Распространение клиентской сборки + +Основной клиентский артефакт: + +```text +*.mrpack +``` + +Ожидаемый flow для пользователя: + +```text +Prism Launcher +→ Add Instance +→ Import +→ выбрать .mrpack +→ launch +``` + +Игрок не должен вручную устанавливать: + +- loaders; +- отдельные моды; +- config-файлы. + +Корректная side-разметка обязательна и проверяется на клиенте и сервере. Разметка модов не определяет установку произвольных config/resource/datapack-файлов: их стороны и целевые пути проверить в spike. + +Для v1 начать с Modrinth. Перед добавлением CurseForge или внешних JAR проверить скачивание и право распространения: packwiz может включить JAR непосредственно в архив. См. [документацию packwiz](https://packwiz.infra.link/tutorials/hosting/modrinth/). + +Для обновления в v1 игрок импортирует новый релиз в отдельный instance. Автоматическое обновление прежнего instance не обещается; личные настройки и saves не входят в релиз. + +Примеры: + +- Sodium: client-side; +- server performance mods: server-side; +- gameplay/content mods: обе стороны, если это требуется. + +--- + +# 11. Server runtime + +Использовать itzg/minecraft-server с закреплённым image digest и подходящей Java. + +Пример контракта Compose (placeholders заменить при реализации): + +```yaml +services: + minecraft: + image: itzg/minecraft-server:PINNED_TAG@sha256:PINNED_DIGEST + restart: unless-stopped + ports: + - "${MC_PORT:-25565}:25565" + environment: + EULA: "${MC_EULA:?Set MC_EULA after accepting the Minecraft EULA}" + MEMORY: "${MC_MEMORY:-8G}" + TYPE: MODRINTH + MODRINTH_MODPACK: /modpack/friday-minecraft-0.4.0.mrpack + volumes: + - ${MC_ROOT:?Set absolute server root}/runtime:/data + - ${MC_RELEASE_DIR:?Set absolute release directory}:/modpack:ro +``` + +Compose входит в релиз; абсолютные bind paths не зависят от cwd. Все операции явно передают одно стабильное Compose project name. Глобальный container_name не требуется. + +Локальный .mrpack поддерживается [itzg](https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/modrinth-modpacks/). Выбранный loader, очистку старых модов, side filtering и перезапись overrides проверить на закреплённом образе в Phase 0. + +Критичные изменяемые данные хранятся в runtime на host, без named volumes. Первичная настройка включает UID/GID, принятие EULA и локальный файл секретов .env. + +--- + +# 12. Процесс deployment + +mcpack deploy применяет готовый неизменяемый релиз. Если его нет, сначала выполняется build из чистого worktree. + +1. Проверить source, релиз и checksums. +2. Подключиться к host с установленными Docker, Compose, rsync, tar и zstd. +3. Получить общую remote-блокировку для deploy/backup/rollback. +4. Проверить права, свободное место, состояние предыдущей операции и конфликты конфигов. +5. Загрузить релиз во временный каталог, проверить checksums на host и атомарно опубликовать каталог releases/-. +6. Если этот релиз уже активен и healthy, завершить без restart. +7. Корректно остановить сервер и убедиться в завершении процесса. +8. Создать и проверить backup существующего persistent state. +9. Записать deployment state и применить новый релиз. +10. Запустить контейнер и дождаться healthcheck. +11. Только после успеха атомарно обновить active-release и previous-release. + +При первом запуске с пустым runtime backup не требуется; этот случай фиксируется явно. Любая смена релиза существующего сервера требует backup, включая изменения конфигурации. + +Ошибка загрузки не останавливает сервер. Ошибка backup запрещает запуск нового релиза; прежний можно запустить, если runtime ещё не менялся. При ошибке после применения нового релиза остановить сервер, вернуть non-zero и сохранить failed deployment state с инструкциями восстановления. Автоматически запускать старый pack на потенциально изменённом мире нельзя. + +Одинаковая версия с другим содержимым отклоняется. Прерывание оставляет читаемый state: этап, исходный и целевой релизы, checksums, backup ID. Повторный запуск проверяет state и не начинает новую операцию поверх незавершённой. + +--- + +# 13. Структура удалённого сервера + +```text +/srv/minecraft/friday/ +├── .env +├── active-release +├── previous-release +├── deployment-state.json +├── releases/ +│ ├── friday-minecraft-0.3.0/ +│ └── friday-minecraft-0.4.0/ +├── runtime/ +└── backups/ +``` + +active-release содержит имя каталога последнего успешно запущенного релиза. Compose и серверные overrides берутся из этого релиза. Host settings и секреты остаются в .env; rollback их не меняет. + +Указатели обновляются атомарно. Deployment state различает последний успешный и фактически применяемый релизы во время перехода. Все операции используют одну remote-блокировку. + +--- + +# 14. Стратегия серверной конфигурации + +Разделить конфигурацию на три класса. + +## Конфигурация уровня модпака + +Хранится в: + +```text +pack/config/ +pack/defaultconfigs/ +pack/kubejs/ +``` + +Это часть релиза модпака. + +## Конфигурация уровня сервера + +Хранится в: + +```text +server/ +``` + +Примеры: + +- базовый `server.properties`; +- Compose-конфигурация; +- шаблоны server-specific config. + +## Runtime-generated конфигурация + +Хранится в: + +```text +runtime/ +``` + +Порядок применения: pack defaults → server overrides → runtime generation для неуправляемых файлов. У каждого управляемого пути один владелец; пересечения разрешаются явно как overrides, иначе validation прекращается. + +Manifest содержит управляемые пути. Удалять только файлы прежнего релиза; неизвестные файлы не удалять молча. Для конфигов, изменяемых самим runtime, определить в spike политику replace, seed-only или preserve. Проверить defaultconfigs и datapacks на существующем мире. + +Не коммитить runtime-generated файлы автоматически. + +В будущем добавить явную команду для переноса полезных runtime-изменений обратно в source. + +Например: + +```bash +mcpack config import server +``` + +--- + +# 15. Ручное редактирование runtime-файлов + +Одно из требований — администратор должен иметь возможность вручную править файлы через SSH. + +Например: + +```bash +ssh minecraft + +cd /srv/minecraft/friday/runtime + +vim config/example.toml +vim server.properties +``` + +Эта возможность должна сохраняться. + +Перед deployment сравнивать управляемые конфиги с ожидаемым состоянием прежнего релиза. При ручных изменениях показать diff и прекратить применение до явного выбора: перенести правки в source либо разрешить замену. Известные runtime-generated изменения обрабатывать по политике раздела 14. Это обязательная минимальная проверка конфликтов v1; неуправляемые persistent файлы сохраняются. + +Будущее улучшение: + +```bash +mcpack diff-runtime +``` + +Команда сравнивает server runtime config с конфигами под Git. + +--- + +# 16. Backups + +Перед сменой релиза существующего сервера обязателен backup после корректной остановки. mcpack backup использует ту же блокировку и в v1 также останавливает сервер, затем возвращает его в прежнее состояние работы после успешного backup. + +Начальный вариант — архивировать весь runtime, кроме явно установленных disposable logs/cache/downloads. Исключения подтвердить в spike. Сохранять данные модов вне world, конфиги, server.properties, whitelist и operators. Releases и backups не входят в архив runtime. + +Каждый snapshot имеет уникальный timestamp + ID, архив tar.zst и metadata JSON: исходный и целевой релизы, checksums релиза и архива, исключения и время. + +Писать временный архив, проверить завершение tar/zstd и читаемость архива, затем публиковать атомарно. Ошибка блокирует deployment. + +В v1 обязательна проверенная инструкция восстановления в отдельную директорию вместе с соответствующим сохранённым релизом. Backup не удаляется автоматически. Off-host копии и retention policy — последующее улучшение. + +--- + +# 17. Rollback + +В v1 различать явные операции: + +```bash +mcpack rollback-pack 0.3.0 +mcpack rollback --backup +``` + +rollback-pack меняет релиз без восстановления persistent state и требует явного подтверждения совместимости с текущим миром. SemVer не доказывает совместимость. Команда rollback без указания режима показывает план и ничего не меняет. + +rollback --backup восстанавливает snapshot и связанный с ним исходный релиз, явно сообщая о потере прогресса после снимка. В v1 эта операция может оставаться документированной ручной процедурой, проверенной на практике. + +Обе операции используют блокировку, останавливают сервер и сначала сохраняют текущее состояние отдельным backup. Целевой релиз и snapshot проверяются до изменения runtime. Восстановление — в отдельный каталог с последующей заменой runtime; распаковка поверх существующих файлов запрещена. + +Откат возвращает .mrpack, server overrides и Compose/image исходного релиза. Host secrets остаются прежними. Указатели обновляются только после healthcheck. Старый pack не запускается автоматически на мире, изменённом неудачным deployment. + +--- + +# 18. Health checks + +Deployment успешен, когда контейнер стабильно работает и Minecraft status query подтверждает готовность отвечать по игровому протоколу. Использовать штатный healthcheck itzg, проверив его на закреплённом образе. + +Container state и TCP connect — диагностические проверки, недостаточные для подтверждения готовности. Crash, restart loop и timeout возвращают non-zero с указанием logs и recovery state. + +Timeout настраиваемый; 120 секунд — пример, не универсальный предел. Первый запуск с загрузкой dependencies учитывать отдельно. Реальное подключение клиента и состав модов проверяются в spike. + +--- + +# 19. Логи и консоль + +Предоставить wrappers: + +```bash +mcpack logs +mcpack logs --follow +mcpack console +``` + +Ожидаемый mapping: + +```bash +ssh host docker compose logs +``` + +и: + +```bash +ssh -t host docker exec -it rcon-cli +``` + +Не реализовывать собственный протокол Minecraft console. + +--- + +# 20. Версионирование + +Использовать semantic versioning для самого модпака: + +```text +MAJOR.MINOR.PATCH +``` + +Предлагаемая семантика: + +SemVer описывает масштаб изменений, но не гарантирует безопасность мира; совместимость отката оценивается отдельно. + +## PATCH + +- исправления конфигурации; +- небольшие compatibility fixes; +- server tuning; +- безопасные patch-update модов. + +## MINOR + +- добавление модов; +- удаление некритичных модов; +- gameplay additions; +- значимые изменения конфигурации. + +## MAJOR + +- миграция версии Minecraft; +- крупная миграция loader; +- намеренно world-breaking изменения; +- существенная переработка сборки. + +Не выводить версию Minecraft из semantic version самого модпака. + +--- + +# 21. Требования к воспроизводимости + +Для: + +```bash +git checkout v0.4.0 +``` + +проект должен воспроизвести ту же эффективную сборку при доступности внешних downloads. Побайтово одинаковый ZIP не обещается: timestamps и порядок упаковки могут отличаться. Idempotency deployment определяется checksum сохранённого релиза, а не повторным export. + +Git и .mrpack не гарантируют вечную доступность downloads. Готовые релизы хранить; offline cache/mirror — отдельная будущая возможность. + +Избегать: + +```text +latest +recommended +newest +automatic unpinned loader versions +``` + +Фиксировать: + +- версию Minecraft; +- loader; +- моды; +- digest container image и версию Java; +- версию или commit packwiz и других инструментов, влияющих на build. + +Toolchain зафиксировать уже в spike; формат lock file уточнить после него. + +Пример: + +```yaml +packwiz: "..." +itzg_image: "..." +platform_schema: 1 +``` + +--- + +# 22. Git strategy + +Отслеживать: + +```text +platform/ +pack/ +server/ +scripts/ +Makefile +README.md +PLAN.md +``` + +Игнорировать: + +```gitignore +dist/* +!dist/.gitkeep + +runtime/* +!runtime/.gitkeep + +server/.env + +*.log + +backups/ +``` + +Создавать Git tags для релизов: + +```bash +git tag v0.4.0 +``` + +Потенциальный будущий release flow: + +```bash +mcpack release 0.4.0 +``` + +который: + +1. валидирует дерево; +2. требует clean working copy; +3. обновляет версию; +4. выполняет build; +5. при ошибке восстанавливает прежнюю версию; +6. коммитит изменение версии в pack.toml; +7. собирает финальный release из чистого commit и генерирует checksums; +8. создаёт tag только после успешного build. При ошибке финального build tag не создаётся, состояние явно выводится. + +Не выполнять Git push автоматически в v1. + +--- + +# 23. Секреты + +Никогда не хранить в Git: + +- SSH private keys; +- RCON passwords; +- server secrets; +- API tokens; +- CurseForge credentials, если они потребуются; +- credentials backup repository. + +Использовать: + +```text +.env +environment variables +SSH config +``` + +Предоставить: + +```text +.env.example +``` + +--- + +# 24. SSH configuration + +Предполагать, что администраторы могут определить: + +```sshconfig +Host minecraft + HostName example.org + User minecraft + IdentityFile ~/.ssh/minecraft_ed25519 +``` + +Тогда platform config достаточно: + +```yaml +server: + host: minecraft +``` + +Не требовать хранить SSH username или путь до private key в config, если это не нужно. + +--- + +# 25. Обработка ошибок + +Команды должны падать рано и с понятной диагностикой. + +Плохо: + +```text +deployment failed +``` + +Хорошо: + +```text +ERROR: packwiz export failed + +Command: + packwiz modrinth export + +Exit status: + 1 + +No files were uploaded to the server. +``` + +Этапы deployment должны быть явно видны. + +Например: + +```text +[1/7] Validate pack +[2/7] Build release +[3/7] Upload and verify release +[4/7] Stop server and backup state +[5/7] Apply release +[6/7] Start and healthcheck +[7/7] Record active release +``` + +--- + +# 26. Dry run + +Важная будущая возможность: + +```bash +mcpack deploy --dry-run +``` + +Команда должна показать: + +- какой локальный release будет собран; +- destination host; +- какие файлы будут загружены; +- какой backup будет создан; +- какое Compose-действие будет выполнено; +- переход между active versions. + +Dry run не должен изменять локальное или удалённое состояние. + +Желательно предусмотреть эту возможность архитектурно с самого начала. + +--- + +# 27. Команда doctor + +Реализовать: + +```bash +mcpack doctor +``` + +Проверять локальное окружение: + +- packwiz установлен; +- Docker установлен, если используются локальные server tasks; +- SSH установлен; +- rsync установлен; +- Git repository корректен; +- config валиден. + +Опциональные remote checks: + +```bash +mcpack doctor --remote +``` + +Проверять: + +- SSH connectivity; +- доступность Docker; +- доступность Docker Compose; +- права на remote directory; +- свободное место на диске. + +--- + +# 28. Этапы разработки + +## Phase 0 — Spike + +Цель: + +Вручную проверить интеграцию компонентов экосистемы. + +Задачи: + +- создать минимальный packwiz pack; +- добавить один Modrinth-мод; +- экспортировать `.mrpack`; +- импортировать `.mrpack` в Prism; +- запустить совместимый modded server через `itzg/minecraft-server`; +- установить тот же pack на серверной стороне; +- проверить, что клиент может подключиться; +- проверить bind-mounted runtime и сохранение мира при recreate; +- проверить client-only мод и его отсутствие на сервере; +- обновить релиз, удалить мод и проверить отсутствие старого JAR; +- проверить pack config, server override и ручные правки; +- проверить defaultconfigs/datapacks на существующем мире; +- создать backup остановленного сервера и восстановить его с прежним релизом; +- проверить healthcheck и startup failure. + +Результат: + +```text +docs/spike-results.md +``` + +Не писать основной CLI до подтверждения integration path. Минимальные скрипты, Compose и каркас для spike допустимы. Prism import и подключение требуют реальной GUI-сессии и учётной записи игрока: при их отсутствии отметить проверки pending, а не passed. + +Acceptance criteria: + +- Prism импортирует сгенерированный pack; +- сервер успешно запускается; +- modded client подключается к серверу; +- runtime-файлы существуют как обычные host-файлы. + +--- + +## Phase 1 — Оформление каркаса после spike + +Создать: + +- структуру репозитория; +- `platform/config.yaml`; +- `.gitignore`; +- первоначальный packwiz pack; +- первоначальный Compose-файл; +- `.env.example`. + +Acceptance criteria: + +```bash +git clone +packwiz refresh +packwiz modrinth export +docker compose config +``` + +выполняются успешно. + +--- + +## Phase 2 — Build command + +Реализовать: + +```bash +mcpack build +``` + +или первоначально: + +```bash +make build +``` + +Ответственность: + +- парсинг platform config; +- валидация pack; +- создание `dist`; +- экспорт `.mrpack`; +- детерминированное переименование артефакта; +- генерация SHA-256; +- генерация release manifest. + +Acceptance criteria: + +```text +dist/-/-.mrpack +dist/-/server/ +dist/-/SHA256SUMS +dist/-/manifest.json +``` + +существуют после build. + +--- + +## Phase 3 — Управление модами + +Предоставить тонкие wrappers: + +```bash +mcpack add +mcpack remove +mcpack update +mcpack update --all +``` + +Не скрывать без необходимости сообщения об ошибках packwiz. + +Acceptance criteria: + +- добавленные моды появляются в metadata packwiz; +- удаление мода корректно меняет source; +- build остаётся валидным. + +--- + +## Phase 4 — Server runtime + +Создать Docker runtime, который: + +- использует pinned Minecraft version; +- использует pinned loader; +- использует host bind mounts; +- загружает сгенерированный pack; +- сохраняет world между restart/recreate. + +Acceptance criteria: + +```bash +docker compose up -d +``` + +запускает сервер с пустой runtime directory после явной настройки EULA, host env, прав и путей согласно разделу 11. + +--- + +## Phase 5 — Backups и восстановление + +До remote deployment реализовать раздел 16: блокировку, остановку, backup и проверенную процедуру восстановления. + +Acceptance criteria: ошибка backup блокирует применение; snapshot восстанавливается в отдельный каталог; данные модов вне world сохраняются. + +--- + +## Phase 6 — Healthcheck + +Реализовать раздел 18. Успешный старт возвращает 0; crash, restart loop и timeout — non-zero с указанием logs. + +--- + +## Phase 7 — SSH Deployment + +Реализовать полный flow раздела 12 с готовыми backup и healthcheck. + +Acceptance criteria: + +- первый релиз устанавливается на host с готовыми зависимостями; установка Docker и cloud provisioning вне scope; +- повторный deploy healthy релиза не перезапускает сервер; +- та же версия с другим содержимым отклоняется; +- world сохраняется; +- параллельная операция блокируется; +- сбой передачи, backup или startup оставляет восстановимое состояние; +- ручные конфликты конфигов выявляются до замены файлов. + +--- + +## Phase 8 — Rollback + +Реализовать rollback предыдущего release. + +Acceptance criteria: + +```bash +mcpack rollback +``` + +без указания режима ничего не меняет. Явный rollback использует сохранённый полный релиз без повторного build; pack-only требует подтверждения совместимости. + +Восстановление persistent snapshot может оставаться ручным, но процедура обязательна и проверяется на практике. + +--- + +## Phase 9 — Release workflow + +Реализовать: + +```bash +mcpack release +``` + +Проверки: + +- Git worktree чистый; +- version валидна и ещё не занята релизом или tag; +- версия явно обновляется в pack.toml согласно разделу 22; +- build успешен; +- checksum создан; +- Git tag создан. + +Публикация остаётся вне scope первой версии. + +--- + +# 29. Выбор языка реализации + +Не принимать решение преждевременно. + +Начать с: + +```text +Makefile + shell +``` + +если этого достаточно. + +Перейти к полноценному CLI, когда orchestration станет сложным. + +Возможные варианты: + +## Go + +Преимущества: + +- один binary; +- отличный CLI tooling; +- удобно работать с SSH/process orchestration; +- простая cross-platform distribution; +- strong typing. + +Предпочтительный вариант, если платформа станет переиспользуемым инструментом. + +## Python + +Преимущества: + +- быстрая разработка; +- хорошая экосистема YAML/TOML; +- удобно писать automation. + +Недостаток: + +- управление runtime/environment. + +## Shell + +Преимущества: + +- минимум начального кода; +- прозрачность. + +Недостатки: + +- error handling; +- portability; +- сложное state management; +- тестирование. + +Рекомендация: + +Для integration spike использовать shell/Makefile. + +Если проект переживёт spike и deployment-логика начнёт расти, реализовать основной CLI на Go. + +--- + +# 30. Предлагаемая структура Go CLI + +Если выбран Go: + +```text +cmd/ +└── mcpack/ + └── main.go + +internal/ +├── config/ +├── packwiz/ +├── build/ +├── deploy/ +├── backup/ +├── health/ +├── ssh/ +├── docker/ +├── release/ +└── cli/ +``` + +Ключевое правило: + +Integration packages должны оборачивать внешние инструменты, а не переписывать их функциональность. + +Например: + +```text +internal/packwiz +``` + +должен вызывать packwiz и переводить только релевантный платформе результат. + +Он не должен реализовывать Modrinth dependency resolver. + +--- + +# 31. Абстракция выполнения команд + +При переходе к Go создать executor по требованиям реальных вызовов; spike не требует этой абстракции. + +Концепция: + +```go +type Executor interface { + Run(ctx context.Context, name string, args ...string) error +} +``` + +Позже реализовать: + +- local executor; +- SSH executor; +- dry-run executor. + +Это даст: + +- testability; +- command logging; +- dry runs; +- единообразные ошибки. + +--- + +# 32. Модель состояния + +Не использовать скрытую database платформы в v1. + +Предпочитать state, представленный через: + +```text +Git +filesystem +release manifest +active-release +``` + +Remote state: + +```text +releases/ +active-release +previous-release +deployment-state.json +backups/ +runtime/ +``` + +Состояние должно намеренно оставаться inspectable и repairable без binary самой платформы. + +--- + +# 33. Idempotency + +Команды должны нормально переносить повторный запуск. + +Например: + +```bash +mcpack build +``` + +может заменять локальный development artifact. Финализированный release неизменяем: совпадающие checksums дают no-op, другое содержимое требует новой версии. Сборка выполняется во временном каталоге. + +```bash +mcpack deploy +``` + +должен сверять checksums всего релиза и различать uploaded, applied и healthy active state. + +```bash +mcpack backup +``` + +должен создавать уникальные timestamped backups. + +Не полагаться на одноразовое hidden initialization state, которое нельзя восстановить. + +--- + +# 34. Стратегия тестирования + +## Unit tests + +Для внутреннего кода платформы: + +- config parsing; +- validation; +- release naming; +- version parsing; +- command generation; +- manifest generation. + +## Integration tests + +Использовать временные директории для: + +- pack build; +- release layout; +- атомарного переключения `active-release` после healthcheck; +- backup archive и восстановления в отдельный каталог; +- блокировок, interrupted deployment и отказа при несовпадении checksums; +- конфликтов управляемых конфигов и сохранения неизвестных файлов. + +## External integration tests + +Ручные или opt-in: + +- packwiz; +- Docker; +- SSH; +- реальный запуск Minecraft. + +Не требовать запуск Minecraft-сервера при каждом unit test run. + +--- + +# 35. Fixtures + +Создать небольшие test fixtures. + +Например: + +```text +testdata/ +├── minimal-pack/ +├── invalid-config/ +├── valid-config/ +└── fake-runtime/ +``` + +Fixtures должны быть минимальными. + +Не коммитить Minecraft binaries или крупные mod jars в test data. + +--- + +# 36. Observability + +CLI должен выводить достаточно информации для диагностики проблем. + +Для всех внешних команд предусмотреть verbose logging. + +Например: + +```bash +mcpack deploy --verbose +``` + +Возможный output: + +```text +remote host: minecraft +remote path: /srv/minecraft/friday +release: 0.4.0 +artifact sha256: ... +``` + +Никогда не выводить секреты. + +--- + +# 37. Будущая возможность: hosting сборок + +Позже можно добавить optional HTTP publication. + +Возможная архитектура: + +```text +build + │ + ├── .mrpack + └── packwiz files + │ + ▼ +static HTTP host +``` + +Возможные сценарии: + +- Prism import по URL; +- автоматические packwiz updates; +- сервер сам забирает pack; +- release index. + +Не входит в v1. + +--- + +# 38. Будущая возможность: автообновление клиентов + +Потенциальное решение: + +- разместить packwiz files по HTTP; +- использовать Prism-compatible bootstrap/update mechanism; +- игрок импортирует pack один раз; +- pack обновляется автоматически перед launch. + +Не реализовывать до стабилизации базового release/deployment flow. + +--- + +# 39. Будущая возможность: CI/CD + +Потенциальный pipeline: + +```text +git push + │ + ▼ +validate + │ + ▼ +build + │ + ▼ +publish artifact + │ + ▼ +optional deploy +``` + +Возможные провайдеры: + +- GitHub Actions; +- GitLab CI; +- Gitea Actions; +- self-hosted CI. + +Не делать CI обязательным. + +Локальные команды остаются каноническими. + +--- + +# 40. Будущая возможность: несколько серверов + +В будущем конфигурация может поддерживать: + +```yaml +servers: + survival: + host: mc-prod + directory: /srv/minecraft/survival + + test: + host: mc-test + directory: /srv/minecraft/test +``` + +Тогда: + +```bash +mcpack deploy survival +mcpack deploy test +``` + +Не реализовывать, пока deployment на один сервер не станет стабильным. + +Config schema нужно проектировать так, чтобы такое расширение оставалось возможным. + +--- + +# 41. Будущая возможность: profiles + +Возможные profiles: + +```text +client +server +performance-client +performance-server +optional-content +``` + +Но сначала использовать side metadata packwiz. + +Не вводить собственную систему profiles без реального use case. + +--- + +# 42. Не-цели для v1 + +Не реализовывать: + +- собственный Minecraft launcher; +- собственный mod repository; +- собственный dependency solver; +- web UI; +- поддержку Kubernetes; +- автоматический public hosting; +- database; +- multi-user authentication; +- cloud provisioning; +- автоматическую миграцию world; +- автоматическое разрешение конфликтующих модов; +- автоматический Git push; +- dynamic container orchestration. + +v1 должна оставаться максимально простой и предсказуемой. + +--- + +# 43. Definition of Done для v1 + +Первая полезная версия готова, когда следующий flow работает надёжно: + +```bash +git clone + +mcpack doctor + +mcpack add create + +mcpack build + +# друг импортирует сгенерированный .mrpack в Prism + +mcpack deploy + +mcpack logs +``` + +И выполняются следующие свойства: + +- client artifact импортируется в Prism; +- сервер запускается из того же определения сборки; +- клиент может подключиться; +- моды версионируются через packwiz; +- server files хранятся как обычные директории на host; +- world переживает recreation контейнера; +- deployment выполняется через SSH; +- pack можно пересобрать из Git; +- перед любой сменой релиза существующего сервера создаётся проверенный backup; +- предыдущий полный release и его persistent snapshot можно восстановить; +- удаление мода, конфликт конфигов и failed deployment проверены; +- для критичных данных не требуется Docker named volume. + +--- + +# 44. Первая задача для Codex + +Codex должен начать с integration spike, а не с реализации финального CLI. + +Задача: + +```text +Реализуй только Phase 0. + +Создай минимально возможный рабочий репозиторий, который доказывает: + +1. packwiz может описывать модпак. +2. packwiz может экспортировать Modrinth .mrpack. +3. Prism Launcher может импортировать этот артефакт. +4. itzg/minecraft-server может запустить сервер на основе той же сборки. +5. Состояние сервера хранится в bind-mounted директории. +6. Модифицированный клиент Prism может подключиться к серверу. +7. Обновление удаляет старые моды и предсказуемо применяет конфиги. +8. Backup и восстановление persistent state с прежним релизом работают. + +Недоступные GUI-проверки отметить pending; Phase 0 не считать завершённой +до фактического импорта и подключения. + +Пока не реализовывай mcpack CLI. + +Задокументируй все команды, предположения, точные версии инструментов, +обнаруженные проблемы и любые необходимые изменения архитектуры +в docs/spike-results.md. + +Не добавляй generated runtime data в Git. +``` + +--- + +# 45. Принципы реализации для Codex + +При реализации проекта: + +1. Предпочитай простые и прозрачные механизмы. +2. Не дублируй функциональность, которую надёжно предоставляют packwiz или Docker. +3. Не вводи скрытое mutable state без веской причины. +4. Любой deployment должен быть восстановим. +5. Фиксируй версии. +6. Сохраняй возможность человеку напрямую работать с исходными файлами. +7. Разрушительные операции должны быть явными. +8. Делай backup перед изменением persistent Minecraft state. +9. Считай world более ценным, чем application runtime. +10. Client и server artifacts должны происходить из одного source pack. +11. По возможности держи код платформы независимым от конкретного modpack. +12. Не исправляй и не изменяй пользовательскую конфигурацию молча. +13. Команды должны возвращать осмысленные exit codes. +14. Ошибки внешних команд должны содержать полезный контекст. +15. Предпочитай deterministic output paths и имена артефактов. + +--- + +# 46. Ближайшие шаги + +Выполнять в таком порядке: + +```text +1. Создать каркас репозитория. +2. Установить и зафиксировать версию packwiz. +3. Выбрать одну версию Minecraft. +4. Выбрать один loader. +5. Добавить минимальный заведомо совместимый набор модов. +6. Экспортировать .mrpack. +7. Импортировать его в Prism. +8. Создать Docker Compose для сервера. +9. Запустить сервер с bind-mounted runtime. +10. Подключиться к серверу из Prism. +11. Проверить обновление, удаление мода, конфиги, backup/restore и healthcheck. +12. Записать результаты spike и pending проверки. +13. После подтверждения критериев начинать разработку mcpack CLI. +``` + +Главный архитектурный вопрос, который необходимо проверить во время spike: + +> Может ли один и тот же source pack чисто порождать и Prism client experience, и Dockerized server runtime без ручного расхождения между ними? + +Если да — сохранить эту архитектуру. + +Если нет — задокументировать минимально необходимый слой трансформации между client/server до разработки дополнительного tooling.