15 KiB
Каталог, формы и единые пакеты MVP
Встроенный каталог фактически извлечён из Minecraft Java 26.2, DataVersion = 4903: 1 196 блоков, 32 366 состояний, 158 типов сущностей. Проверка сравнивает полные множества состояний, числовые ID источника, состояния по умолчанию, свойства и типы сущностей с отдельной проекцией официальных отчётов. Дополнительно зарегистрирован собственный shacraft:trampoline: всего 1 197 блоков и 32 367 состояний.
Числовой minecraft_id — только идентификатор источника. Сервер отдельно регистрирует канонические строки в WorldStore; внутренний BlockId зависит от истории конкретного хранилища. Нельзя использовать minecraft_id в операциях редактирования мира. Для собственного состояния значение minecraft_id = u32::MAX означает отсутствие ID Minecraft.
Происхождение и воспроизведение
Источник: официальный server.jar Java 26.2. SHA-1 823e2250d24b3ddac457a60c92a6a941943fcd6a, размер 60 894 273 байта. Полные SHA-256, версия Java, команды и контрольные суммы отчётов находятся в crates/shacraft-content/data/provenance.json.
Генератор проверяет закреплённые размер и SHA-1 перед использованием JAR:
python3 scripts/catalog_generate.py --java /path/to/java25/bin/java
python3 scripts/catalog_assets.py
cargo test -p shacraft-content
cargo run -p shacraft-content --example catalog_report
Нужен установленный JDK 25 или новее, включая javac. Проверенный локальный runtime: Microsoft OpenJDK 25.0.1+8-LTS. Скрипт не меняет системную Java. --reuse-reports позволяет повторно упаковать уже полученные локальные отчёты; полное воспроизведение выполняют без него. Gzip имеет фиксированный mtime=0; содержимое каталога детерминировано. В provenance меняется время запуска.
Фактически проверена точка входа:
java -Xmx1G -DbundlerMainClass=net.minecraft.data.Main -jar server.jar --reports --output generated
catalog_extract.java — собственная небольшая программа, вызывающая публичные API реестров и коллизий 26.2. Она не содержит декомпилированного кода. Генератор данных и измерения не запускают игровой сервер, не создают eula=true, не принимают соглашений. JAR, распакованные библиотеки, отчёты и Java-классы остаются в игнорируемом artifacts/catalog-cache; в дистрибутив входят только минимальные фактические данные совместимости и авторский код.
Что проверено у форм
Для каждого из 32 366 состояний получен getCollisionShape официального исполняемого API. Измерение не использует текстуры или визуальные модели. Все измерения завершились без ошибок; после дедупликации осталось 326 различных наборов прямоугольных объёмов.
Базовый контекст измерения — BlockPos.ZERO, соседи air, отсутствие сущности (CollisionContext.empty()). Дополнительно сравнены каменные соседи и CollisionContext.positionContext(+10/-10): различия обнаружены у 32 состояний scaffolding. Помимо них явно помечены классы с зависимостью от сущности/блочной сущности/динамического состояния: powder snow, shulker box, moving piston и big dripleaf. Поэтому покрытие коллизий разделено:
- 32 187 состояний:
measured-empty-context— измерена форма в описанном контексте. - 179 состояний:
approximate-context— геометрия базового контекста доступна, полной эквивалентности динамических условий нет. - 1 собственное состояние:
authored-exact.
Первое значение не утверждает эквивалентность во всех произвольных контекстах. Положение игрока, специальные экипировки, поршневые блочные сущности, открывание shulker box, обновление связей соседей, AI, редстоун и течения жидкостей не следуют из каталога. Сервер реализует собственную симуляцию и явно ограниченные модули.
Отдельные регрессионные проверки подтверждают верхнюю/нижнюю плиту, объём и направления лестниц, открывание двери, пустую коллизию воды, коллизию забора высотой 1.5, контекстную пометку scaffolding/powder snow, валидность границ всех форм. Геометрия коллизий может выходить за клетку: нельзя безусловно ограничивать Y диапазоном [0,1].
Авторское отображение
render и collision — разные наборы Aabb { min, max }, координаты относительно блока. Рендерер использует собственные процедурные формы и палитру Shacraft. Встроенные PNG, звуковой WAV и GLSL написаны/сгенерированы в этом репозитории; оригинальных ресурсов Minecraft нет.
Семейства плит, лестниц, дверей, люков, панелей, сундуков и многих сложных твёрдых блоков используют измеренные объёмы как основу самостоятельной геометрии. Для заборов, стен, открытых калиток, знаков, рельсов, жидкостей, растений, кнопок, рычагов, ковров и других нетвёрдых форм предусмотрены отдельные параметрические шаблоны. Забор рисуется до Y=1, при этом коллизия достигает Y=1.5. У наклонного рельса ступенчатая геометрия; изогнутый рельс — угловая аппроксимация из прямоугольников. Это читаемый авторский стиль, а не копия визуальной точности Minecraft.
Покрытие: 32 317 состояний authored-procedural и 50 intentionally-invisible (включая воздух, технический light/barrier/structure void и moving piston без исходной динамической блочной сущности). Универсальных визуальных кубов-заглушек для неизвестных семейств встроенного каталога сейчас нет. При этом каждая декоративная деталь, текст надписей, анимация, waterlogged-жидкость внутри модели и световая симуляция не воспроизводятся автоматически по факту наличия состояния.
Для 158 типов сущностей извлечены начальные width/height/eye height, fixed dimensions, категория, summonable/serializable/fire immune, tracking/update interval и все доступные базовые числовые attributes. Эти свойства находятся в EntityDefinition.properties. Модели относительно ног — авторские семейства biped, quadruped, aquatic, winged, boat, cart, dragon, arthropod и другие. Служебные marker/interaction/area effect cloud/lightning bolt намеренно невидимы. Display-сущности имеют явно указанную зависимость от свойств экземпляра. Размеры возраста/позы/масштаба и произвольный NBT сохраняются слоем экземпляров; каталог хранит размеры по умолчанию. Наличие модели не означает наличие ванильного AI.
Rust API
Catalog::load_builtin() -> Result<Catalog>: полный встроенный каталог и trampoline.catalog.state(canonical_or_block_name),catalog.entity(name),catalog.default_state(name).catalog.palette(): 12 удобных канонических состояний для тестового клиента.catalog.sampler(): 1 197 образцов по умолчанию в сетке 32 столбца с шагом 3; отдельные клетки относительно пола Y=0, X/Z в пределах ±64. Создание пола и запись в мир — ответственность сервера.catalog.summary(): количества, раздельное покрытие, версия и ограничения.canonical_state(name, properties): сортировка ключей и ограниченная валидация без потери неизвестных свойств.- Все публичные определения реализуют
Clone,Serialize,Deserialize. После десериализации целогоCatalogследует вызватьrebuild_indexes()перед поиском.
Хранение бинарного встроенного каталога занимает около 246 KiB gzip; при загрузке он распаковывается и создаёт строки/геометрию и индексы. Размер файла не равен RAM каталога. Полные строки 32 тысяч состояний и реестр WorldStore нужно учитывать отдельно в RSS измерениях процесса.
Единый формат пакета v1
Каждый подкаталог packages/ содержит manifest.json:
{
"schema": 1,
"id": "shacraft.trampoline",
"version": "1.0.0",
"license": "MIT OR Apache-2.0",
"dependencies": [{"id": "shacraft.base", "version": "1.0.0"}],
"capabilities": ["blocks.define", "client.texture", "client.style", "server.on_jump"],
"resources": [{
"path": "server/trampoline.wasm", "scope": "server", "role": "wasm-on-jump",
"sha256": "<64 lowercase hexadecimal characters>", "size": 40
}]
}
Пример иллюстрирует схему; действительные размеры и хеши берутся из сгенерированных манифестов. Версии зависимостей точные. load_packages(root) проверяет весь граф до выдачи ресурсов: схему, уникальность, зависимости, совпадение версий, циклы, допустимые capabilities, пути, размеры и SHA-256 всех объявленных ресурсов. Один ресурс ограничен 16 MiB, весь пакет — 64 MiB; symlink и traversal в ресурсных путях отвергаются. read_resource повторно проверяет хеш и размер при чтении.
Scopes: common — общие определения; client — ресурсы клиента; server — внутренние данные и код сервера. PackageManifest::client_manifest() исключает серверные ресурсы и capabilities. Package::public_resource(path) отказывает для server scope; HTTP-маршрут обязан использовать именно этот метод. Статический сервер не должен раздавать весь каталог packages/ напрямую.
shacraft.base включает описание каталога, собственный 64×64 текстурный шум и клиентский стиль. shacraft.trampoline включает общее определение блока, 32×32 текстуру сетки, клиентский визуальный эффект, короткий авторский звук, необязательную функцию GLSL и исполняемый серверный WebAssembly-модуль. Его экспорт on_jump() -> f32 возвращает скорость 10 блоков/с; импортов, памяти и внешних системных вызовов нет. WAT-исходник находится рядом. Сервер исполняет бинарный модуль в ограниченной среде; контракт предусматривает лимит топлива 10 000, памяти 1 страницу, проверку диапазона результата. Клиент использует встроенный эффект bounce по данным пакета, не произвольный JavaScript из сети. Произвольная среда клиентского кода и полноценная модовая экосистема не объявляются реализованными.
python3 scripts/catalog_assets.py детерминированно пересоздаёт все авторские ресурсы и хеши. Ресурсы пакетов доступны на условиях MIT OR Apache-2.0, как собственный код проекта. Генерация ничего не скачивает.