Перейти к основному содержимому

Преобразование Java в Bedrock

ResourcePackManager может преобразовать объединённый Java-пак ресурсов в пак Bedrock, чтобы клиенты GeyserMC видели поддерживаемое пользовательское содержимое из Java-пака. По умолчанию функция включена.

Когда запускается преобразование​

Преобразование привязано к наличию Bedrock-цели. RSPM считает, что цель присутствует, если выполняется любое из этих условий:

  1. Geyser-Spigot установлен на этом бэкенде (Bedrock-игроки попадают на Geyser локально).
  2. Floodgate установлен на этом бэкенде (типичная настройка прокси-бэкенда — Floodgate работает локально, Geyser где-то ещё).
  3. Сетевой режим активен — RSPM обнаружил, что он находится за прокси Velocity / BungeeCord. Бэкенд производит свой Bedrock-пак и выставляет его на небольшом HTTP-сервере, чтобы прокси-плагин мог его забрать.

Преобразование также должно быть включено через bedrockConversionEnabled. Если оно отключено или цели нет, RSPM отзывает предыдущий вывод Bedrock и пропускает преобразование. /rspm status сообщает, почему пак не был создан.

Что преобразуется​

Конвертер не зависит от пространства имён. Он обходит каждый файл assets/<namespace>/items/**/*.json в формате определений предметов 1.21.4+, рекурсивно и включая пространство имён minecraft.

Выбор плоского или 3D-представления​

Для каждой листовой модели конвертер решает, какой из двух конвейеров использовать. Модели, укоренённые в minecraft:item/generated или minecraft:builtin/generated, остаются на плоском пути. Для любой другой цепочки родителей модель идёт по 3D-конвейеру только тогда, когда объединённая модель несёт непустой массив elements; модель без геометрии — это 2D-спрайт.

  • Плоское: текстура layer0 модели копируется в textures/items/<hash>.png и регистрируется как иконка Geyser. Bedrock использует этот слой как 2D-спрайт в инвентаре и руке. Произвольные дополнительные слои и ветви Java-модели при этом не сохраняются.
  • 3D — конвертер сшивает атлас текстур, преобразует Java-параллелепипеды в Bedrock-геометрию, генерирует анимации удержания/головы, программно рендерит иконку инвентаря 64×64 и записывает один attachable на каждый маппинг (модель × базовый предмет × определение предмета × форма предиката).

Почему проверка геометрии важна: плоский ручной инструмент (родитель minecraft:item/handheld только с текстурой layer0 и без elements) — это всё равно 2D-спрайт. Более ранние версии проталкивали плоские ручные предметы в 3D-конвейер, где они падали на шаге геометрии и исчезали на Bedrock или откатывались к ванильной иконке базового предмета. Особенно это било по пакам ItemsAdder, которые поставляют много плоских ручных предметов. Поскольку elements читается из объединённой цепочки родителей, не-generated модель, наследующая геометрию от родителя, по-прежнему направляется в 3D.

RSPM выводит идентификатор Bedrock для каждого маппинга (модель × базовый предмет × определение предмета × форма предиката). Это разделяет варианты одной модели меча с разными базовыми предметами и предикатами, а два определения предметов, использующие одну модель, получают отдельные идентификаторы. Имена файлов используют короткие хеши исходных идентификаторов, а не содержимого файлов, чтобы избежать предупреждения Geyser о путях длиной от 80 символов.

Поддерживаемые ветви моделей предметов​

Преобразование поддерживает узлы model, condition, range_dispatch и select, с префиксом minecraft: или без него. Другие типы, включая composite и special, пропускаются. Корректный вид Java-пака не доказывает, что все его ветви можно представить в Bedrock.

УзелПоддерживаемые свойства и запасное поведение
conditionbroken, damaged, fishing_rod_cast, has_component, custom_model_data. Для using_item сохраняется только on_false как модель покоя. У других неподдерживаемых условий пропускаются обе ветви.
range_dispatchdamage, count, bundle_fullness, custom_model_data. Для use_duration и других неподдерживаемых свойств сохраняется только fallback, если он есть.
selectcharge_type, trim_material, context_dimension, custom_model_data. Для display_context сохраняется случай gui, а при его отсутствии используется запасная ветвь. Для других неподдерживаемых свойств сохраняется только запасная ветвь.

Поэтому стадии натяжения Java-лука и отдельные модели для разных контекстов отображения не сохраняются автоматически. Включите bedrockConverterDebug, чтобы увидеть пропущенные узлы и свойства, и проверьте предмет на клиенте Bedrock.

Устаревшие паки до 1.21.4​

Сканер старого формата читает JSON-файлы непосредственно в assets/minecraft/models/item/ и создаёт определения диапазонов из переопределений с числовым predicate.custom_model_data. Он не обходит вложенные папки старого формата и не сохраняет другие предикаты переопределения. Например, условие натяжения лука будет потеряно. Число предметов старого формата выводится только при включённом bedrockConverterDebug. Для поддерживаемых паков используйте формат определений предметов 1.21.4+ и сверяйте его ветви с таблицей выше.

Базовые предметы​

Geyser сопоставляет каждый пользовательский предмет с одним или несколькими базовыми предметами Java. RSPM выбирает их так:

  • Файл переопределений старого формата и корневое определение assets/minecraft/items/<item>.json сопоставляются с этим ванильным предметом.
  • Остальные определения сопоставляются по имени файла. Слова, обозначающие оружие и инструменты, сопоставляются с родственными ванильными предметами: sword — с шестью мечами, pickaxe — с шестью кирками, wand или staff — с minecraft:stick, spear — с minecraft:trident и так далее. Для брони используется файл экипировки пространства имён или слова слотов, такие как helmet и boots. Всё остальное использует запасной набор: бумагу, палку, бирку, компас и шесть мечей.
  • Определения в пространстве имён freeminecraftmodels также сопоставляются с minecraft:leather_horse_armor — предметом, которым FreeMinecraftModels отображает кости моделей.
  • Плагин-поставщик может объявить настоящие базовые предметы в assets/<namespace>/rspm_item_bases/<path>.json, где <path> соответствует items/<path>.json. Файл содержит {"base_items": ["minecraft:blaze_rod"]}. Читаются только ID minecraft:, и они добавляются к выбору по имени файла. FreeMinecraftModels записывает такой файл для каждого пользовательского предмета с материалом, указанным в его конфиге, поэтому жезл на BLAZE_ROD отображает свою модель в Bedrock.

Предметы только для Java​

Плагин-поставщик может исключить предметы из преобразования, поместив файл в assets/<namespace>/rspm_item_java_only/<path>.json. Важно только наличие файла. Он исключает items/<path>.json и все определения предметов в items/<path>/, поэтому такие предметы не получают маппинга Geyser, иконки или attachable. FreeMinecraftModels использует это для предметов-спрайтов своих эффектов частиц, которые используют только item display на Java; игроки Bedrock вместо этого видят нативную частицу. Пак, все предметы которого предназначены только для Java, не вызывает предупреждения о старом формате.

Комплекты Bedrock-сущностей, написанные вручную​

Плагин может включить нативные ресурсы сущностей Bedrock в assets/<namespace>/rspm_bedrock_pack/ своего Java-пака. RSPM импортирует файлы в создаваемый пак Bedrock. Допускаются только каталоги сущностей: entity, models/entity, animations, animation_controllers, render_controllers, materials, particles, textures/entity. Поэтому плагин не может заменить манифест или атлас иконок. Поддерживаемые пути длиной от 80 символов сокращаются, а точные JSON-ссылки на них внутри того же комплекта обновляются. Остальные файлы копируются как есть. Если два пространства имён создают разные байты по одному выходному пути, возникает ошибка.

Именно этот механизм стоит за настоящими кастомными Bedrock-сущностями — см. Расширение Geyser и кастомные сущности. Пак, содержащий только комплекты сущностей и ноль маппингов предметов, всё равно выпускается.

Преобразование надетой брони выполняется на пути плоских предметов для базового предмета брони или элитр. Конвертер получает <material> из имени файла определения предмета, удалив распознанный суффикс слота, затем ищет assets/<namespace>/equipment/<material>.json в пространстве имён листовой модели. Используется первый слой текстуры из humanoid, для поножей из humanoid_leggings, а для элитр из wings, если он присутствует. Соответствующий PNG должен быть в объединённом паке. Созданный attachable использует ванильную геометрию брони Bedrock. Один файл экипировки, дополнительные слои текстуры или несвязанный идентификатор ресурса экипировки не гарантируют преобразование брони.

UUID заголовка/модуля в манифесте Bedrock-пака детерминированно выводятся из строки версии плагина (сиды rspm_bedrock_header:<pluginVersion> и rspm_bedrock_module:<pluginVersion>), поэтому они остаются стабильными между пересборками одной и той же версии плагина и меняются только при смене версии плагина. Видимое имя заголовка — это фиксированное ResourcePackManager Bedrock Pack; оно не участвует в формировании UUID. Тройка версии увеличивается при каждой сборке от cache-bust токена, выводимого из SHA-256 дайджеста содержимого подготовленного Bedrock-пака — идентичное содержимое даёт ту же версию (поэтому холостые пересборки не «дёргают» кеш Geyser), а реальные изменения содержимого инвалидируют кеш пака Bedrock с ключом (uuid, version). Время сборки (System.currentTimeMillis()) используется только как запасной вариант, когда дайджест содержимого не удаётся вычислить.

Раздача при подключении на отдельном сервере​

При включённом преобразовании и Geyser-Spigot на том же отдельном бэкенде RSPM подписывается на SessionLoadResourcePacksEvent. Каждому подключающемуся игроку он предлагает с диска последний разрешённый к публикации пак Bedrock. Правки текстур или геометрии могут поступить при следующем подключении без перезапуска сервера, если зарегистрированные маппинги предметов не изменились. Бэкенды в сетевом режиме оставляют раздачу прокси, даже если Geyser-Spigot установлен и локально.

Маппинги кастомных предметов Geyser, JSON в custom_mappings/, фиксируются при запуске. Добавление или удаление предметов, изменение ссылки на модель или предикатов могут потребовать новых маппингов и перезапуска. При включённом автоматическом развёртывании RSPM размещает предыдущий разрешённый файл маппингов в начале запуска. После первого успешного преобразования перезапустите Geyser для загрузки новых маппингов, затем переподключите клиент Bedrock.

Игроки Bedrock, подключённые в данный момент, остаются с тем паком, который получили на своём входе, — это ограничение Bedrock-протокола, плагин не может его переопределить посреди сессии.

Как это работает в режиме прокси​

В прокси-сети сам бэкенд не регистрирует подписчика SessionLoadResourcePacks (нет локального Geyser, на который можно подписываться). Вместо этого:

  1. Бэкенд производит output/ResourcePackManager_Bedrock.zip, а когда есть маппинги предметов — и output/rspm_geyser_mappings.json.
  2. Бэкенд запускает небольшой HTTP-сервер (порт выводится автоматически, по умолчанию mcPort + 1) с маршрутами /bedrock.zip и /mappings.json, которые читают файл свежим при каждом запросе, и объявляет прокси точный порт, на который он привязался.
  3. Прокси-плагин опрашивает каждые 5 секунд, предпочитая строгие ETag через If-None-Match и сохраняя совместимость с If-Modified-Since для более старых бэкендов. Он скачивает вывод каждого бэкенда при изменении и ждёт, пока инбокс стабилизируется.
  4. Прокси-плагин объединяет Bedrock-пак каждого бэкенда в единый общесетевой пак и раздаёт его Bedrock-клиентам через Geyser прокси.
  5. Если прокси не может достучаться до HTTP-порта бэкенда напрямую (обычное явление на shared / managed-хостингах, где соседние порты блокируются файрволом), бэкенд пушит свои файлы на endpoint ретранслятора magmaguy.com, и прокси забирает их оттуда.

См. Прокси-сети для настройки. Объединение на стороне прокси происходит автоматически и не имеет переключателя включения. В конфиге прокси всего две настройки: network-http-offset-v2 — запасное смещение порта, используемое до того, как доступно объявление endpoint'а бэкенда, и geyser-extension-auto-install — эквивалент geyserExtensionAutoInstall на стороне прокси.

Выходные файлы​

После успешной сборки файлы Bedrock находятся в:

plugins/ResourcePackManager/output/ResourcePackManager_Bedrock.zip
plugins/ResourcePackManager/output/rspm_geyser_mappings.json # only when item mappings exist

Если авто-развёртывание включено и была обнаружена локальная папка данных Geyser, файл маппингов также копируется в:

<geyser-folder>/custom_mappings/rspm_geyser_mappings.json

Сам zip Bedrock-пака не копируется в <geyser-folder>/packs/ — вместо этого он раздаётся вживую посессионно. Если более старая версия RSPM оставила ResourcePackManager_Bedrock.zip в папке паков Geyser, текущий плагин не удаляет его, пока Geyser работает: Geyser уже просканировал этот путь и может всё ещё держать файл в памяти. RSPM пропускает регистрацию живого провайдера на эту загрузку и печатает точный путь к устаревшему файлу. Полностью остановите сервер, удалите только этот устаревший файл и запустите сервер снова. /reload для этого недостаточно.

Если нет преобразуемых маппингов и допустимых файлов сущностей, RSPM отзывает публикацию и пытается удалить предыдущие локальные результаты и свой маппинг, размещённый в Geyser. Оставшийся заблокированный файл больше не разрешён к раздаче. Маршрут бэкенда /bedrock.zip возвращает 404, сообщая, что бэкенд не предоставляет содержимого Bedrock. Паки только с сущностями продолжают публиковаться. Простые замены текстур Java-блоков или ванильных текстур не создают преобразованный пак; для них нужен отдельно подготовленный пак Bedrock.

При согласовании после отключения bedrockAutoDeployToGeyser RSPM удаляет ранее размещённый им маппинг. Изменение bedrockGeyserFolder также очищает предыдущий путь, которым управлял RSPM. Эти действия не меняют маппинги, уже загруженные работающим Geyser. Перезапустите Geyser, чтобы применить новый набор.

Настройки в config.yml​

# Toggles Java-to-Bedrock conversion altogether.
bedrockConversionEnabled: true

# Copies the Geyser custom mappings file into the detected Geyser folder's
# custom_mappings/ directory on each mix.
bedrockAutoDeployToGeyser: true

# Manual override for the Geyser data folder. Empty = auto-detect.
# Relative values are tried from the server working directory first, then
# relative to plugins/. Absolute paths work directly.
bedrockGeyserFolder: ""

# Installs and updates the universal ResourcePackManager.jar in Geyser's
# extensions/ folder, which is what makes custom Bedrock ENTITIES render
# instead of armor stands. Separate from pack conversion above — items,
# textures and models convert and serve normally either way.
# Setting this false stops future installation and update staging; it does NOT
# remove an extension jar that is already installed. Delete that by hand while
# Geyser is stopped. See the Geyser extension page.
geyserExtensionAutoInstall: true

# Verbose per-item / per-bone progress logging from the Bedrock pipeline.
# Default false — a clean run emits a single "Bedrock conversion complete: N
# mappings" summary instead of dozens to hundreds of per-item lines. Flip on
# when debugging a specific conversion issue.
bedrockConverterDebug: false

Авто-определение папки Geyser проверяет, по порядку:

  1. bedrockGeyserFolder, если задан (сначала используется как написано, поэтому относительные пути разрешаются от рабочего каталога сервера; если такого пути нет, он пробуется относительно plugins/). Абсолютные пути тоже работают.
  2. plugins/Geyser-Spigot/
  3. plugins/Geyser-*/ (любой вариант)
  4. config/Geyser-*/ (для установок Fabric/NeoForge)

Позы предмета в руке​

Каждый 3D attachable получает анимации от первого лица, от третьего лица и на голове. Позы в руке берутся из трансформаций Java-модели display.firstperson_righthand и display.thirdperson_righthand. RSPM переносит каждую трансформацию через ванильный риг игрока Bedrock, поэтому модель в руке оказывается там же, где её рисует Java, с той же позицией, ориентацией и масштабом по осям. Слот, который модель не задаёт, использует единичную трансформацию Java. Анимация на голове берётся из display.head.

Настраивать здесь нечего. Чтобы изменить положение предмета в руке, измените трансформации display Java-модели; тогда Java и Bedrock используют одни и те же значения. Риг использует широкую руку (Стива), поэтому со скинами с тонкими руками Bedrock может отличаться от Java на полпикселя.

Более ранние версии добавляли вручную подобранные смещения из plugins/ResourcePackManager/bedrock_display_offsets.yml. Этот файл и его настройки firstPerson* и thirdPerson* больше не читаются, а RSPM пересобирает кешированные паки Bedrock после обновления. Старую копию файла можно удалить.

Частицы предметов в руке​

Плагин-поставщик может прикрепить частицы к 3D-предмету в руке с помощью служебного файла assets/<namespace>/rspm_item_particles/<model path>.json, где <model path> — путь Java-модели предмета в руке (display/wand для freeminecraftmodels:display/wand). Файл сопоставляет имена эффектов с идентификаторами частиц, которые плагин поставляет в своём комплекте сущностей, перечисляет локаторы в пикселях Java-модели и содержит зацикленную временную шкалу частиц. RSPM добавляет локаторы в геометрию предмета и воспроизводит временную шкалу как дополнительную анимацию attachable, поэтому клиенты Bedrock рисуют частицы у руки от первого и от третьего лица. FreeMinecraftModels записывает такие файлы для предметов с эффектами частиц. Нечитаемый служебный файл пропускается с предупреждением.

Отладочные журналы​

Доступны две debug-поверхности:

  • Бэкенд: bedrockConverterDebug: true в config.yml включает строки лога конвертера по каждому предмету, каждому attachable, каждому маппингу. Полезно, когда нужно понять, почему конкретный предмет не попал в Bedrock-пак. Это отдельно от verboseLogging, который охватывает объединение паков и хостинг, а не конвейер Bedrock — при проблеме преобразования вам нужен bedrockConverterDebug.
  • Прокси (Velocity и BungeeCord): /rspm debug bedrock on переключает поток лога [RSPM-BedrockDebug], выводимый GeyserBinder прокси. Полезно, когда Bedrock-игроки подключаются к прокси, но не видят пак. Настройка сбрасывается в off при перезапуске прокси, чтобы её нельзя было случайно оставить включённой.

Ограничения и известное поведение​

  • 3D-иконки инвентаря программно рендерятся из Java-модельной трансформации display.gui. Рендер разумный, но не пиксель-в-пиксель; если иконка выглядит неправильно, самая частая причина — отсутствующая или неправильно названная текстура, на которую ссылается модель.
  • Flipbook-текстуры, используемые как иконки предметов, обрезаются до кадра 0 — item_texture.json в Bedrock не поддерживает анимированные иконки, только анимированные текстуры блоков/террейна через flipbook_textures.json.
  • Версия формата геометрии attachable зафиксирована на 1.21.0; обновите Geyser, если ваша установка не может её распарсить.
  • Унаследованные ванильные файлы переопределений модели предмета (всё, что под assets/minecraft/models/item/, включая shield.json и crossbow.json) объединяются между паками, а не отдаются полностью одному паку-победителю: комбинируются только массивы overrides (с дедупликацией по ключу переопределения), тогда как для не-override полей действует «побеждает наивысший приоритет». Ни один файл не выделяется для особого обращения.
  • Если конвертер не может разрешить файл текстуры или модели, на который есть ссылка, этот лист пропускается, а остальной конвейер продолжает работать. Включите bedrockConverterDebug для подробных трассировок разрешения. Обычное предупреждение выдаётся, когда у предмета в итоге вообще нет валидных кастомных текстур или когда JSON модели, на который есть ссылка, не удаётся распарсить.
  • Неразбираемый JSON определения предмета прерывает преобразование с Bedrock conversion failed: .... Корректный JSON без модели или с неподдерживаемым узлом может вместо этого быть пропущен с отладочным сообщением. Проверяйте ошибку и число созданных маппингов, не считая любое пропущенное определение фатальной ошибкой разбора.
  • Базовые предметы «знамя» и «редстоун» пропускаются. Кастомные предметы, чьей базой является один из 16 окрашенных знамён или minecraft:redstone, не получают маппинг кастомного предмета Geyser, потому что Geyser выводит из этих баз некорректный block-placer. Bedrock показывает для них ванильную иконку. Консоль называет затронутые предметы, когда это происходит.
  • Преобразование поддерживает кооперативную отмену. RSPM подготавливает ZIP и маппинги, затем заменяет публикацию целым набором. При сбое или отмене во время замены он пытается восстановить предыдущий набор; ошибка преобразования до замены отзывает старый вывод. Опубликованные хеши и метаданные набора позволяют получателям отклонять устаревшие или смешанные поколения. Наличие ZIP на диске не доказывает, что он сейчас разрешён к раздаче или отображён клиентом Bedrock.
  • Если объединённый пак не содержит преобразуемых маппингов и допустимых файлов сущностей, RSPM отзывает предыдущую публикацию и пытается удалить её результаты. Пак только с сущностями создаётся и при нуле маппингов предметов.

Оптимизация размера пака​

Перед публикацией Bedrock-пака RSPM дедуплицирует побайтово идентичные файлы текстур с одинаковым расширением и переписывает точные JSON-ссылки на текстуры на оставленный файл. Он намеренно сохраняет псевдонимы, когда ссылка неоднозначна, встроена в более длинную строку или найдена в некорректном/непрозрачном JSON, чтобы оптимизация молча не ломала ссылки на ресурсы.