Files
shacraft-core/docs/COMPATIBILITY.md
T

105 lines
23 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Совместимость с Minecraft Java 26.2
Дата проверки источников: 14 сентября 2026 года. Это план и критерии приёмки; наличие этого документа не означает, что конвертер или полный каталог уже реализованы.
## Цель и границы
Shacraft остаётся самостоятельным движком на Rust. Совместимость означает полный каталог идентификаторов блоков, их допустимых состояний и типов сущностей целевой версии, отдельное покрытие форм, а также обмен пользовательскими мирами и постройками с сохранением исходных данных. Совпадение всей симуляции Minecraft — редстоуна, генератора мира, поведения мобов, жидкостей и команд — требует собственных модулей и не следует автоматически из наличия каталога.
Целевая версия действительно существует: Mojang выпустила Java 26.2 16 июня 2026 года. В ней добавлены, среди прочего, sulfur/cinnabar и sulfur cube; поэтому каталог более ранней версии нельзя выдавать за 26.2. [Официальный релиз](https://www.minecraft.net/en-us/article/minecraft-java-edition-26-2).
Первый рабочий срез может иметь небольшой демонстрационный каталог, однако в интерфейсе, README и отчётах он должен называться именно демонстрационным. Требование полного каталога остаётся незакрытым до проверки против зафиксированного источника.
## Зафиксированный источник данных
При проверке [официального launcher manifest](https://piston-meta.mojang.com/mc/game/version_manifest_v2.json) получена запись `id=26.2`, `type=release`, `releaseTime=2026-06-16T12:03:33+00:00`. Она ссылается на [метаданные версии](https://piston-meta.mojang.com/v1/packages/bc42e43dfe43d65a2f6c2c1dbb322c75134e51fe/26.2.json):
- SHA-1 JSON метаданных: `bc42e43dfe43d65a2f6c2c1dbb322c75134e51fe`.
- Java runtime: major version `25`.
- [Официальный server.jar](https://piston-data.mojang.com/v1/objects/823e2250d24b3ddac457a60c92a6a941943fcd6a/server.jar): размер `60894273` байта, SHA-1 `823e2250d24b3ddac457a60c92a6a941943fcd6a`.
SHA-1 здесь фиксирует артефакт по метаданным Mojang. Наш файл происхождения дополнительно должен содержать вычисленный SHA-256, дату, команду извлечения, Java version и хеш каждого итогового отчёта.
План получения каталога:
1. Скачать этот JAR в локальный игнорируемый кэш, проверить размер и хеш. Не включать его в репозиторий и дистрибутив Shacraft.
2. Проверить доступную точку входа и `--help` генератора данных именно этого артефакта, затем получить отчёты блоков и реестров. Команда для старых версий не считается проверенной командой для 26.2. Сам факт существования `blocks.json` в генераторе подтверждён Mojang; его структура меняется, что видно уже в [изменениях 26.3 Snapshot 2](https://www.minecraft.net/en-us/article/minecraft-26-3-snapshot-2).
3. Из отчёта блоков извлечь resource location, свойства, допустимые значения, все перечисленные состояния и состояние по умолчанию. Из реестров — типы сущностей, block entities, биомы и прочие необходимые для конвертации ключи. Если нужного поля нет в отчёте, пометить пробел и сделать отдельное воспроизводимое извлечение из исполняемого API целевой версии.
4. Получить `DataVersion` из целевого артефакта/мира, сохранить в манифесте. Номер ещё не извлечён в рамках этого исследования; не подменять его номером datapack/resource pack.
5. Хранить минимальный производный каталог и собственные правила адаптации. Текстуры, звуки, модели, шейдеры и декомпилированный код Minecraft в него не входят. Визуальные ресурсы Shacraft создаются отдельно либо подключаются из локальных ресурсов пользователя отдельным адаптером.
Полнота проверяется равенством множеств канонических состояний и типов сущностей с отчётами, а не ожидаемым числом из статьи или ручного списка. Количества блоков/состояний/сущностей появятся только после фактического извлечения.
## Контракт каталога и форм
В `WorldStore` используется каноническая строка `namespace:block[key=value,...]`, где ключи свойств отсортированы. Числовой `BlockId` — внутренний идентификатор Shacraft; он не равен числовому идентификатору Minecraft и не переносится между независимыми реестрами без явной таблицы соответствия. `air` остаётся ID 0 по `CONTRACT.md`.
Для совместимости необходимы разные признаки покрытия:
- `identity`: идентификатор и все состояния известны и проверены.
- `render`: собственная геометрия отображает состояние; заглушка обозначена явно.
- `collision`: проверена форма столкновений для этого состояния и контекста.
- `behavior`: установлен модуль поведения, если он реализован.
- `roundtrip`: данные можно вернуть в конкретную версию и формат.
Один флаг `supported` скрывал бы различия. Нельзя получать коллизию автоматически из текстур или из визуальной модели. Формы могут зависеть от соседей, сущности и состояния мира; лестницы, плиты, двери, заборы, стены, растения, жидкости и динамические блоки требуют раздельных тестов. Начать с собственных параметрических форм, затем сравнивать их с выборкой поведения целевой версии. Формы со сложным контекстом сохраняют статус `approximate` до проверки.
Сущность может быть известна по идентификатору и полностью сохраняться для экспорта, даже если в Shacraft она пока отображается маркером и не имеет AI. В интерфейсе это должно быть видно. Неизвестный блок сохраняет исходную строку и NBT; отображение заглушкой не должно заменять его на `air` в хранилище.
## Форматы и порядок поддержки
**NBT — слой сериализации, а не единый формат мира.** Для Java нужен типизированный big-endian NBT. Типы чисел, массивов и списков необходимо сохранять: преобразование к обычному JSON теряет информацию для обратной записи. Это различие прямо показано в [API Prismarine NBT](https://github.com/PrismarineJS/prismarine-nbt), который можно использовать как независимый тестовый декодер, не как зависимость Rust runtime.
**Sponge `.schem` v3 — первый полноценный адаптер построек.** Поддержать блоки и состояния, block entities, entities, 3D-биомы, размеры, offset, metadata и DataVersion. Спецификация предусматривает эти контейнеры и палитры; точный порядок байтов и кодирование брать из [первичной спецификации Sponge v3](https://github.com/SpongePowered/Schematic-Specification/blob/master/versions/schematic-3.md). Затем добавить v2 как отдельную ветку декодера. Старый MCEdit `.schematic` не считать тем же форматом и не распознавать по одному похожему расширению.
**Vanilla structure `.nbt` — отдельный адаптер.** Нужно зафиксировать схему 26.2 на файлах, сохранённых structure block: размеры, палитра/альтернативные палитры, блоки, относительные координаты, block entity NBT и сущности. Сырой NBT-декодер не равен поддержке этой схемы. Неподдерживаемые альтернативные палитры нельзя молча свести к первой.
**Anvil world directory — потоковый адаптер миров.** Обрабатывать `level.dat`, измерения, region-файлы, секции/палитры, биомы, block entities, отдельные файлы сущностей и POI, а также остальные файлы сохранения. Извлекать разделы по мере необходимости, с ограничением кэша, сохраняя оригинал на диске. Проверять chunk `DataVersion` наряду с версией мира.
Существующая реализация [WorldEdit AnvilChunk18](https://github.com/EngineHub/WorldEdit/blob/dca10737fe81bd81bb6a096e1801cc2d94f1793b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java) подтверждает практическую работу с секционными палитрами `Name`/`Properties`; [McRegionReader](https://github.com/EngineHub/WorldEdit/blob/dca10737fe81bd81bb6a096e1801cc2d94f1793b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/McRegionReader.java) полезен для проверки контейнера. Эти реализации — независимые ориентиры, не доказательство полного соответствия 26.2. Код не копировать в ядро без отдельного решения о лицензии.
Нужно явно проверить варианты сжатия, внешние chunk payload и крупные chunks на целевых fixtures. Поддержкой одного zlib нельзя объявлять поддержку всех Anvil-файлов: возможность LZ4-сжатия регионов описана в [официальном релизе Java 1.20.5](https://www.minecraft.net/es-es/article/minecraft-java-edition-1-20-5). Неизвестное сжатие даёт диагностируемый отказ, а не пустой chunk.
## Режимы экспорта и сохранение оригинала
**`exact` — проверенная точность данных.** По умолчанию используется та же версия и тот же формат, что у источника. Исходные файлы помещаются в неизменяемое дисковое хранилище с хешами; изменения Shacraft хранятся отдельно. Нетронутые файлы копируются побайтно. В изменённых файлах переписываются только поддерживаемые данные; остальные типизированные NBT-поля сохраняются. Контракт точности — семантическое равенство NBT за исключением явных правок и заранее объявленных производных полей, а не одинаковое сжатие и размещение секторов.
При неизвестной версии, некорректной палитре, неподдерживаемой операции, несовместимой сущности, неразрешённом преобразовании metadata или отсутствии необходимых исходных данных `exact` прекращает экспорт до публикации результата. Особенно проверять замену блока с block entity, инвентари, пассажиров и UUID, а также зависимости от света, heightmaps, POI и scheduled ticks. Нельзя оставить заведомо неверные производные данные и назвать экспорт точным. Правило пересчёта/инвалидации каждого такого поля должно быть проверено целевым Minecraft.
**`best-effort` — преобразование с отчётом.** Разрешает только явно заданные правила замены. Формирует `conversion-report.json`: версия источника/назначения, формат, координата/UUID, код причины, исходное значение, действие, количество и тяжесть. Неизвестные данные остаются в сопровождающем архиве, однако это не означает, что целевой Minecraft сможет их использовать. Отчёт различает `preserved`, `approximated`, `dropped`, `unsupported`.
Для мира, созданного в Shacraft без Minecraft-оригинала, экспорт в `.schem` доступен после проверки всех данных на представимость. Создание полноценного Anvil-мира потребует отдельного генератора корректного окружения сохранения; одной записи массива блоков в `.mca` недостаточно.
Исходный мир никогда не редактируется конвертером на месте. Вывод готовится во временном каталоге и переименовывается после успешной проверки. Прерванный импорт можно возобновить по журналу chunks и хешам. Экспорт получает согласованный снимок мира; параллельные игровые правки не должны давать смесь ревизий.
## Необходимые дополнения к текущему API
`CONTRACT.md` покрывает блоки и ревизии. В нём пока нет durable API произвольного NBT, биомов, сущностей и provenance. До заявления о lossless-конвертации добавить версионируемый compatibility sidecar со ссылками на неизменяемые blobs, типизированными NBT и изменениями по chunk/UUID. Он должен участвовать в атомарной фиксации ревизии вместе с блоками.
Не перегружать строковый реестр блоков всем NBT мира и не держать sidecar целиком в RAM. Экспортёр/импортёр — отдельная библиотека/CLI над ядром; Java используется для получения эталонных данных и интеграционной проверки, но не для работы Shacraft-сервера.
## Приёмочные проверки
1. **Каталог:** равенство множеств всех состояний/типов целевому отчёту, один default на блок, канонизация независимо от порядка properties, сохранение неизвестного namespace, стабильность таблицы ID после перезапуска.
2. **NBT:** все типы, пустые списки, 64-битные значения, массивы, Unicode, неизвестные поля. Проверка encode/decode независимым декодером; обычный JSON не выступает эталоном.
3. **Палитры:** один блок на всю секцию, границы размера палитры и битовой упаковки, секции из воздуха, отрицательные X/Z/Y, границы chunks/regions, отсутствующие данные и повреждённые индексы.
4. **Без правок:** Minecraft/WorldEdit fixture → Shacraft → исходный формат. Нетронутые файлы побайтно идентичны; пересобранные структуры семантически равны по типизированному NBT. Третий декодер подтверждает результат.
5. **С правками:** поменять одно состояние, сломать контейнер, поставить лестницу/дверь, переместить поддерживаемую сущность. После экспорта меняются только предусмотренные данные; metadata, прочие inventories/entities/biomes и неизвестные теги сохраняются либо дают точный отказ.
6. **Открытие:** отдельная копия экспортированного мира открывается целевым Java 26.2 без ошибок декодирования/утраты chunks; фиксируются хеш JAR, логи и проверяемые координаты. Одного собственного roundtrip недостаточно — одинаковая ошибка в reader/writer может остаться незамеченной.
7. **Версии/потери:** unsupported DataVersion, модифицированный namespace, отсутствующая модель, неподдерживаемое NBT и cross-format export проверяют отказ `exact` и полный отчёт `best-effort`.
8. **Ресурсы:** большие sparse-миры, высокоэнтропийные секции, большие payload, повреждённые длины и сильное сжатие. Ограничить распакованный размер, глубину NBT, очередь и кэш; измерить пик RAM. Прерывание/повтор импорта и сбой финальной записи не повреждают исходник и сохранённые ревизии.
Fixtures должны быть собственными маленькими мирами/постройками без сторонних карт и ассетов. Для версии и сжатия, которых нет в fixtures и внешней проверке, не ставить статус `verified`.
## Этапы и условия завершения
1. **Происхождение:** зафиксированный источник 26.2, воспроизводимый генератор, DataVersion, хеши и точные количества; отсутствие этих результатов оставляет полный каталог незавершённым.
2. **Реестр:** все состояния и entity IDs загружаются в Shacraft, сохраняются и ищутся; формы и behavior имеют отдельную карту покрытия.
3. **NBT + `.schem` v3:** типизированные данные и архив оригинала, оба направления, отчёт потерь, независимые roundtrip-тесты.
4. **Structure NBT + `.schem` v2:** схемы разделены и проверены на эталонах, включая offset/повороты только там, где они реализованы.
5. **Anvil 26.2:** потоковый импорт, возврат исходного мира, затем проверенные правки и создание новых экспортируемых миров; тесты с целевым Minecraft.
6. **Полное покрытие форм:** все состояния имеют проверенную визуальную форму и отдельно коллизию либо явный незакрытый дефект. Завершение списка ID само по себе не закрывает этот этап.
7. **Расширение версий:** добавлять другие DataVersion только через отдельные адаптеры/миграции и fixtures. Не обещать автоматический downgrade и произвольные модифицированные миры.
Главные технические риски: дрейф схем между версиями, скрытые связи block entities/POI/ticks, формы с зависимостью от контекста, полная пересборка мира из частично поддерживаемых данных и непредсказуемые пики RAM при распаковке. Каждый риск выше привязан к конкретному отказу или приёмочному тесту, чтобы он не превратился в молчаливую потерю пользовательского мира.