22 KiB
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.
Фактически выполнено
- Получены точные версии из официальных GitHub, Fabric и Modrinth API.
- Скачан официальный packwiz из привязанного к commit workflow run;
SHA-256 архива и binary закреплены в
toolchain.lock.env. - Установлен Docker в WSL (
pacman -S --needed --noconfirm docker), daemon запущен командойsystemctl start docker, без enable при загрузке. - Скачан и проверен SHA-256 официального Compose v5.6.0 в
.tools/. - Создан source pack и добавлены закреплённые моды через packwiz.
- Для Text Placeholder API сторона явно изменена с both на client: здесь библиотека нужна только client-only Mod Menu.
- Обновлён source index, выполнен export в временной копии source.
- Проверены содержимое ZIP, версии dependencies и env каждой записи.
scripts/spike-server.sh config --quietиbash -n scripts/*.shуспешны.- После явного принятия EULA пользователем выставлен MC_EULA=TRUE в игнорируемом server/.env.
- Первый запуск, status healthcheck, side filtering и bind mounts проверены на реальном сервере.
- Проверены recreate, смена версии мода, удаление модов, конфиги и datapack на существующем мире.
- Startup с отсутствующим mrpack вернул 1; hash level.dat при ошибке не изменился.
- Исходный snapshot восстановлен в отдельный каталог; world/config совпали до запуска, сервер 0.0.1 снова healthy.
git diff --checkуспешен; .tools, артефакты, world, backups и .env игнорируются Git.
Артефакт:
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/:
../.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:
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 артефакта выполняется из его каталога:
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-аккаунт не требуется.
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 выполняется при остановленном сервере:
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):
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.
Официальные источники:
Уточнение цели пользователем
Собирать пользовательские модпаки NeoForge/Forge, распространять клиентский артефакт и запускать сервер без проверки аккаунтов. ONLINE_MODE=false, ENFORCE_SECURE_PROFILE=false. Смена auth режима предварена backup phase0-before-offline-mode. Проверка Microsoft login не входит в acceptance criteria.