238 lines
22 KiB
Markdown
238 lines
22 KiB
Markdown
# Phase 0 — integration spike
|
||
|
||
Дата: 2026-10-03. Статус: **предварительный Fabric-эксперимент проверен; целевой Phase 0 должен проверить NeoForge/Forge без аккаунтов**.
|
||
GUI-проверки не заменяются проверкой ZIP или Minecraft status query.
|
||
|
||
## Окружение и версии
|
||
|
||
Arch Linux x86_64 в WSL2, kernel `6.18.40.1-microsoft-standard-WSL2`.
|
||
Изначально отсутствовали Linux packwiz, Docker, Compose, Go и Java.
|
||
В Windows обнаружен каталог PrismLauncher; аккаунты и существующие instances
|
||
не читались и не изменялись.
|
||
|
||
| Компонент | Зафиксированное значение |
|
||
| --- | --- |
|
||
| Minecraft | 1.21.1 |
|
||
| Fabric Loader | 0.19.5 |
|
||
| Fabric installer/launcher | 1.1.2, наблюдаемое значение в .fabric-manifest.json |
|
||
| Fabric API | 0.116.17+1.21.1, Modrinth `Mys3P7lK`, both |
|
||
| Mod Menu | 11.0.5, Modrinth `6lgOkclV`, client |
|
||
| Text Placeholder API | 2.4.2+1.21, Modrinth `U5bhVym2`, client в этой сборке |
|
||
| packwiz commit | `ef87d964f8cbd52b3b13ea42453ef322290e2b9e` |
|
||
| packwiz GitHub Actions run | `34043101039`, Linux 64-bit x86 |
|
||
| packwiz binary SHA-256 | `7f8ed641be0c28988895651e3270cc9ad4b40c436e3d5cf9b3bcdb718b4369c6` |
|
||
| Prism Launcher | 11.0.3-main, commit d393323fdc52ef645c48a04ca73aff2bbe24ffc9 (из локального лога) |
|
||
| JVM сервера | Temurin 21.0.12.1+1-LTS |
|
||
| Docker Engine | 29.8.2, storage driver overlayfs |
|
||
| Compose | v5.6.0, локальный официальный binary |
|
||
| itzg image digest | `sha256:99dc8b37f97c3b95915452180bbedf29a7ac8252932e372ce6e5b6e383a5d1e2` |
|
||
| itzg source revision | `beed693663b4c963d1bb4af1101855eccbc6a37b` |
|
||
| itzg image creation | 2026-10-02T12:03:38.864Z |
|
||
|
||
Образ первоначально скачан по тегу java21; Compose использует только digest.
|
||
JVM проверена без запуска Minecraft: Temurin OpenJDK 21.0.12.1+1-LTS.
|
||
Команда: `docker run --rm --entrypoint java <закреплённый-image> -version`.
|
||
|
||
## Фактически выполнено
|
||
|
||
1. Получены точные версии из официальных GitHub, Fabric и Modrinth API.
|
||
2. Скачан официальный packwiz из привязанного к commit workflow run;
|
||
SHA-256 архива и binary закреплены в `toolchain.lock.env`.
|
||
3. Установлен Docker в WSL (`pacman -S --needed --noconfirm docker`),
|
||
daemon запущен командой `systemctl start docker`, без enable при загрузке.
|
||
4. Скачан и проверен SHA-256 официального Compose v5.6.0 в `.tools/`.
|
||
5. Создан source pack и добавлены закреплённые моды через packwiz.
|
||
6. Для Text Placeholder API сторона явно изменена с both на client:
|
||
здесь библиотека нужна только client-only Mod Menu.
|
||
7. Обновлён source index, выполнен export в временной копии source.
|
||
8. Проверены содержимое ZIP, версии dependencies и env каждой записи.
|
||
9. `scripts/spike-server.sh config --quiet` и `bash -n scripts/*.sh` успешны.
|
||
10. После явного принятия EULA пользователем выставлен MC_EULA=TRUE в игнорируемом server/.env.
|
||
11. Первый запуск, status healthcheck, side filtering и bind mounts проверены на реальном сервере.
|
||
12. Проверены recreate, смена версии мода, удаление модов, конфиги и datapack на существующем мире.
|
||
13. Startup с отсутствующим mrpack вернул 1; hash level.dat при ошибке не изменился.
|
||
14. Исходный snapshot восстановлен в отдельный каталог; world/config совпали до запуска, сервер 0.0.1 снова healthy.
|
||
15. `git diff --check` успешен; .tools, артефакты, world, backups и .env игнорируются Git.
|
||
|
||
Артефакт:
|
||
|
||
```text
|
||
dist/minecraft-lab-spike-0.0.1/minecraft-lab-spike-0.0.1.mrpack
|
||
SHA-256: 923fa6e5b54921b7b19925bbe634d91e09b113ccd512f1edaaeab818de3a9338
|
||
```
|
||
|
||
ZIP содержит `modrinth.index.json` и `overrides/config/spike-marker.txt`.
|
||
Fabric API помечен required на обеих сторонах; Mod Menu и Text Placeholder API
|
||
имеют `server: unsupported`. На установленном сервере подтверждено отсутствие обоих client-only JAR.
|
||
Маркер проверяет копирование произвольного конфига; его не читает игровой мод.
|
||
|
||
## Команды создания и воспроизведения
|
||
|
||
Первоначальный init из `pack/`:
|
||
|
||
```bash
|
||
../.tools/packwiz/packwiz --cache ../.tools/packwiz/cache --config ../.tools/packwiz/config.toml init \
|
||
--name minecraft-lab-spike --version 0.0.1 --author minecraft-lab \
|
||
--mc-version 1.21.1 --modloader fabric --fabric-version 0.19.5 -y
|
||
../.tools/packwiz/packwiz --cache ../.tools/packwiz/cache --config ../.tools/packwiz/config.toml modrinth add --project-id P7dR8mSH --version-id Mys3P7lK -y
|
||
../.tools/packwiz/packwiz --cache ../.tools/packwiz/cache --config ../.tools/packwiz/config.toml modrinth add --project-id mOgUt4GM --version-id 6lgOkclV -y
|
||
# Явно изменить side в placeholder-api.pw.toml на client.
|
||
../.tools/packwiz/packwiz --cache ../.tools/packwiz/cache --config ../.tools/packwiz/config.toml refresh
|
||
```
|
||
|
||
В новом checkout достаточно уже закоммиченного source:
|
||
|
||
```bash
|
||
scripts/spike-tools.sh
|
||
scripts/spike-build.sh
|
||
scripts/spike-server.sh config --quiet
|
||
bsdtar -xOf dist/minecraft-lab-spike-0.0.1/minecraft-lab-spike-0.0.1.mrpack modrinth.index.json
|
||
```
|
||
|
||
Для изменения source packwiz запускается из `pack/` с локальными cache/config,
|
||
как в командах выше. Проверка SHA-256 артефакта выполняется из его каталога:
|
||
|
||
```bash
|
||
cd dist/minecraft-lab-spike-0.0.1
|
||
sha256sum -c SHA256SUMS
|
||
```
|
||
|
||
Build v0 не создаёт production release manifest, Git tags или удалённый deployment.
|
||
Игровые версии читаются из pack.toml; выбор MC_PACK — ссылка на готовый артефакт.
|
||
|
||
## Матрица проверки
|
||
|
||
| Проверка | Статус |
|
||
| --- | --- |
|
||
| packwiz описывает и экспортирует сборку | PASS |
|
||
| ZIP содержит закреплённые dependencies и side metadata | PASS |
|
||
| Compose config валиден | PASS |
|
||
| Prism импортирует и запускает pack | PASS: instance 0.0.1, Minecraft/Fabric и три JAR подтверждены |
|
||
| Сервер устанавливает локальный mrpack и становится healthy | PASS: mc-health, 1.21.1, online=0 |
|
||
| На сервере нет client-only JAR | PASS: только fabric-api JAR |
|
||
| World и config находятся в host bind mount | PASS |
|
||
| World переживает recreation контейнера | PASS: level.dat hash до запуска совпал |
|
||
| Обновление удаляет старый mod JAR | PASS: 0.116.17 → 0.116.16; затем удалены все JAR |
|
||
| Конфиги: pack defaults, server override, ручная правка | PASS: override победил; update перезаписал ручную правку |
|
||
| Backup/restore возвращает world и прежний release | PASS: восстановлен baseline и pack 0.0.1 |
|
||
| Startup failure возвращает non-zero | PASS: отсутствующий mrpack, exit 1; world не изменён |
|
||
| Клиент Prism подключается к offline-серверу | PENDING: повторная попытка после online-mode=false |
|
||
| Datapack на существующем мире | PASS: file/phase0 автоматически загружен в 0.0.2 |
|
||
| NeoForge/Forge defaultconfigs | НЕ ПРОВЕРЕНО: другой loader |
|
||
|
||
## Порядок серверных проверок
|
||
|
||
После принятия EULA скопировать `.env.example` в `.env` и выставить MC_EULA=TRUE.
|
||
Сервер изолирован локальным адресом, без публикации RCON. Первоначально ошибочно требовался online-mode=true; по уточнению пользователя переключён на online-mode=false и enforce-secure-profile=false. Microsoft/Mojang-аккаунт не требуется.
|
||
|
||
```bash
|
||
scripts/spike-server.sh up -d --wait --wait-timeout 600
|
||
scripts/spike-server.sh ps
|
||
scripts/spike-server.sh logs --tail 100
|
||
scripts/spike-server.sh exec -T minecraft java -version
|
||
scripts/spike-server.sh exec -T minecraft mc-health
|
||
ls runtime/mods runtime/config runtime/world
|
||
```
|
||
|
||
Затем остановить сервер и записать hash `runtime/world/level.dat`.
|
||
Recreate выполняется при остановленном сервере:
|
||
|
||
```bash
|
||
scripts/spike-server.sh stop
|
||
sha256sum runtime/world/level.dat
|
||
scripts/spike-server.sh create --force-recreate
|
||
sha256sum runtime/world/level.dat
|
||
scripts/spike-server.sh start
|
||
```
|
||
|
||
Два hash до запуска должны совпасть. После старта world может штатно измениться;
|
||
это не потеря данных. Дополнительно проверить UUID/seed и игровой маркер из клиента.
|
||
|
||
Для воспроизведения вариантов на новом checkout после исходного build выполнить `scripts/spike-variants.sh`. Скрипт создаёт source-копии в .tools/repro-variants и артефакты 0.0.2/0.0.3; runtime не меняет. Повторный запуск при существующих каталогах прекращается без перезаписи.
|
||
|
||
0.0.2: Fabric API fpB2VatZ (0.116.16+1.21.1), marker v2, статический datapack из testdata/spike-datapack. 0.0.3: удалены Mod Menu, Text Placeholder API и Fabric API, остаётся loader и config marker. Исходный pack/ всё время оставался на 0.0.1.
|
||
Перед сменой MC_PACK обязательно остановить сервер и создать snapshot.
|
||
Проверить удаление прежнего JAR и фактическое состояние marker.
|
||
Возврат старого pack выполнять вместе с соответствующим snapshot.
|
||
|
||
Минимальная ручная процедура backup (в корне, после stop):
|
||
|
||
```bash
|
||
mkdir -p backups
|
||
task_snapshot="backups/$(date -u +%Y%m%dT%H%M%SZ)-$(date +%s%N).tar.zst"
|
||
tar --exclude=./.gitkeep -C runtime -I zstd -cf "$task_snapshot" .
|
||
tar -I zstd -tf "$task_snapshot" > /dev/null
|
||
sha256sum "$task_snapshot" > "$task_snapshot.sha256"
|
||
# Записать рядом исходный MC_PACK и SHA256SUMS релиза.
|
||
```
|
||
|
||
Restore: сервер остановлен; сначала сохранить текущее состояние. Проверить hash
|
||
архива, распаковать в новый каталог рядом с runtime и проверить файлы.
|
||
Переименовать текущий runtime в сохранённый каталог, новый — в runtime;
|
||
выбрать исходный MC_PACK и запустить с healthcheck. Не распаковывать поверх мира.
|
||
Этот ручной сценарий проверен: snapshot phase0-before-update восстановлен в отдельный каталог, исходный runtime сохранён в .tools/runtime-before-restore, затем запущен pack 0.0.1.
|
||
|
||
Prism: импортировать исходный .mrpack, запустить Minecraft, проверить Mod Menu,
|
||
зайти на localhost:25565, поставить различимый игровой маркер и проверить его
|
||
после recreation. Записать версию Prism, JVM клиента и фактический результат.
|
||
|
||
## Фактические результаты переходов
|
||
|
||
- Первый запуск: Minecraft 1.21.1, Fabric 0.19.5, JVM Temurin 21.0.12.1+1; mc-health отвечает version=1.21.1 online=0 max=20.
|
||
- Docker inspect: /data — rw bind на runtime/, /modpacks — ro bind на dist/. Named volumes отсутствуют.
|
||
- Recreate: до повторного запуска SHA-256 level.dat остался `32832255e84e2d8b4e324527d21b233b0b0cc4615ae17ee0296e7e8c5d4d9728`.
|
||
- Update 0.0.1 → 0.0.2: только fabric-api-0.116.16+1.21.1.jar, старый 0.116.17 удалён; manual-runtime-v1 заменён на pack-default-v2.
|
||
- Datapack: лог «Found new data pack file/phase0, loading it automatically», затем «[Phase0] datapack-v2-loaded».
|
||
- Optional override: `MC_PACK=minecraft-lab-spike-0.0.2/minecraft-lab-spike-0.0.2.mrpack scripts/spike-server.sh -f server/compose.spike-override.yaml up -d --wait --wait-timeout 120`; marker стал server-override-v1.
|
||
- Update → 0.0.3 без override: runtime/mods пуст, управляемые файлы прежнего datapack удалены, unmanaged-probe.txt сохранился.
|
||
- Failure: MC_PACK=missing-phase0.mrpack, Compose --wait вернул 1; контейнер exited(1), hash мира остался прежним.
|
||
- Restore: sha256sum snapshot проверен, распаковка в .tools/runtime-restored, сравнение world/config с baseline успешно; прежний runtime сохранён, восстановленный переименован в runtime. После запуска исходного pack 0.0.1 сервер healthy.
|
||
|
||
Каждый изменяющий тест предварялся корректной остановкой и snapshot. Пять архивов в backups/ имеют SHA-256 и JSON metadata: исходный артефакт, image digest, server override и время; исключений нет. Имена phase0-* относятся к однократному запуску этого эксперимента. Для обычных backups использовать уникальные ID из примера выше.
|
||
|
||
Артефакты тестовых переходов (ZIP timestamps могут отличаться при повторном export):
|
||
|
||
| Релиз | SHA-256 |
|
||
| --- | --- |
|
||
| 0.0.2 | ca10d1faffa8a71ee58431f7f3f2ee88be4c7572e035cac8824331129b701fab |
|
||
| 0.0.3 | ced6fe830055ce3f0ae2d1c4c14e0fb41b5a8580bdaf5cac3010b0bdc8a9ceba |
|
||
|
||
Финальное состояние: сервер запущен с исходным pack 0.0.1 и восстановленным baseline, optional override выключен. Импорт и запуск Prism подтверждены локальными instance metadata и client log. Подключение не завершилось: Failed to log in: The authentication servers are currently not reachable. В client log sessionHost/servicesHost=https://nope.invalid и UnknownHostException: nope.invalid; launcher log содержит четыре -Dminecraft.api.*.host с этим адресом. В pack и instance/global JvmArgs такого override нет, переменные JAVA_TOOL_OPTIONS/JDK_JAVA_OPTIONS/_JAVA_OPTIONS Windows этих overrides не содержат. Для offline-клиента эти параметры не являются ошибкой настройки: изначальное требование online-mode=true противоречило цели пользователя. Требование аккаунта снято; нужен offline-server login. Account files и токены не читались.
|
||
|
||
## Обнаруженные ограничения и изменения архитектуры
|
||
|
||
- packwiz автоматически добавил Text Placeholder API и выставил both, хотя он
|
||
нужен этой сборке только на клиенте. Metadata проекта не заменяет проверку
|
||
конкретного состава зависимостей. Свой resolver не нужен.
|
||
- В Arch package index Compose 5.5.1 ссылался на отсутствующий файл (HTTP 404).
|
||
Не обновлялась вся система: Docker установлен отдельно, Compose скачан локально.
|
||
- В минимальном окружении отсутствует cmp; build сравнивает SHA-256 source и
|
||
refresh-копии вместо дополнительной системной зависимости.
|
||
- Network-вызовы sandbox требуют разрешения. Подстановка latest не используется
|
||
в воспроизводимых командах; закреплены результаты первоначального выбора.
|
||
- GitHub Actions artifacts имеют ограниченный срок хранения. Bootstrap по run ID
|
||
пригоден для spike, но не для долговременного release tooling. Для него нужен
|
||
build packwiz из закреплённого commit или сохранённый binary с checksum.
|
||
- Пакет содержит ссылки на Modrinth downloads, а не все JAR; offline install
|
||
не доказан. Образ также загружает Minecraft и loader при первом старте.
|
||
- Windows Test-NetConnection 127.0.0.1:25565 вернул TcpTestSucceeded=True после восстановления. GET sessionserver hasJoined без сессии возвращает 204 из Windows, WSL и контейнера; GET api.minecraftservices.com/publickeys возвращает 200 из Windows и контейнера. Эти пробы не передавали токены и не подтверждают login, но исключают общую недоступность этих endpoints.
|
||
- Минимальная сборка использует Fabric API, не добавляя новые блоки/предметы. Она доказывает установку loader и модов; сетевую совместимость content-модов понадобится проверить на реальной сборке.
|
||
- Fabric был неверно выбран вместо целевых NeoForge/Forge. Его результаты сохраняются только как предварительный эксперимент. Целевой Phase 0 ещё требует modpack на NeoForge/Forge, defaultconfigs и подключения offline-клиента.
|
||
- При смене mrpack управляемый config заменяется, включая ручную правку. Неуправляемый файл сохраняется. Требуется проверка drift в будущей платформе до применения пакета.
|
||
- Server override через /config с SYNC_SKIP_NEWER_IN_DESTINATION=false применяется после modpack defaults и побеждает их. Это намеренная политика теста, не универсальная политика production.
|
||
- Datapacks нужны в world/datapacks, а не в корневом /data/datapacks. В варианте 0.0.2 проверен путь overrides/world/datapacks/phase0. Это статические исходники datapack, не snapshot мира. Если сохранить предложенный pack/datapacks layout, нужен явный перенос в целевой world path; world name должен учитываться.
|
||
- Важное ограничение воспроизводимости: local mrpack закрепляет loader, но не версию Fabric installer/launcher. В runtime наблюдается 1.1.2. В закреплённом образе TYPE=MODRINTH вызывает install-modrinth-modpack напрямую, не передавая FABRIC_LAUNCHER_VERSION; в help этого helper нет соответствующего параметра. Поэтому простое добавление Fabric env в Compose не доказывает фиксацию installer. Перед production release нужно выбрать проверенный способ фиксировать/сохранять launcher или явно ограничить обещание воспроизводимости. Собственный mod resolver для этого не нужен.
|
||
- Production deployment и автоматический rollback остаются вне scope Phase 0.
|
||
|
||
Официальные источники:
|
||
|
||
- [packwiz installation](https://packwiz.infra.link/installation/)
|
||
- [packwiz Modrinth export](https://packwiz.infra.link/tutorials/hosting/modrinth/)
|
||
- [itzg local mrpack](https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/modrinth-modpacks/)
|
||
- [itzg healthcheck](https://docker-minecraft-server.readthedocs.io/en/latest/misc/healthcheck/)
|
||
- [Modrinth format](https://support.modrinth.com/en/articles/8802351-modrinth-modpack-format-mrpack)
|
||
|
||
## Уточнение цели пользователем
|
||
|
||
Собирать пользовательские модпаки NeoForge/Forge, распространять клиентский артефакт и запускать сервер без проверки аккаунтов. ONLINE_MODE=false, ENFORCE_SECURE_PROFILE=false. Смена auth режима предварена backup phase0-before-offline-mode. Проверка Microsoft login не входит в acceptance criteria.
|