Files
minecraft-lab/docs/fabric-spike-results.md
T
2026-10-04 00:30:09 +07:00

22 KiB
Raw Blame History

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.

Артефакт:

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.