Преобразование Java в Bedrock
ResourcePackManager может преобразовать собранный Java-пак ресурсов в ресурс-пак Bedrock, чтобы клиенты GeyserMC видели то же пользовательское содержимое, что и клиенты Java. По умолчанию эта функция включена.
Когда запускается преобразование
Преобразование привязано к наличию Bedrock-цели. RSPM считает, что цель присутствует, если выполняется любое из этих условий:
- Geyser-Spigot установлен на этом бэкенде (Bedrock-игроки попадают на Geyser локально).
- Floodgate установлен на этом бэкенде (типичная настройка прокси-бэкенда — Floodgate работает локально, Geyser где-то ещё).
- Сетевой режим активен — RSPM обнаружил, что он находится за Velocity / BungeeCord / Waterfall прокси. Бэкенд производит свой Bedrock-пак и выставляет его на небольшом HTTP-сервере, чтобы прокси-плагин мог его забрать.
Если ни одно из этих условий не выполняется, конвертер — чистый накладной расход, и он молча пропускается. /rspm status объясняет ровно почему, когда пак не был сгенерирован.
Что преобразуется
Конвертер не зависит от пространства имён. Он обходит каждый файл assets/<namespace>/items/**/*.json в формате определений предметов 1.21.4+, рекурсивно и включая пространство имён minecraft.
Маршрутизация flat против 3D
Для каждой листовой модели конвертер решает, какой из двух конвейеров использовать. Модели, укоренённые в minecraft:item/generated или minecraft:builtin/generated, остаются на плоском пути. Для любой другой цепочки родителей модель идёт по 3D-конвейеру только тогда, когда объединённая модель несёт непустой массив elements; модель без геометрии — это 2D-спрайт.
- Flat — текстура
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.
Уникальный Bedrock-идентификатор генерируется для каждого маппинга (модель × базовый предмет × форма предиката), поэтому одна модель меча, зарегистрированная для нескольких базовых предметов или ветвей предикатов, не конфликтует на стороне Geyser. Генерируемые имена файлов — это короткие хеши содержимого, а не читаемые имена, потому что полные имена «пространство имён + путь» регулярно превышали лимит Geyser в 80 символов на путь в паке.
Устаревшие паки до 1.21.4
Паки, которые всё ещё используют старый формат assets/minecraft/models/item/*.json + overrides[].predicate.custom_model_data, тоже подхватываются и синтезируются в современную форму range-dispatch. Это делается по мере возможности: консоль отмечает, сколько предметов использовали устаревший формат, поскольку они часто отображаются на Bedrock некорректно. Настоящее решение — миграция исходного пака на формат определений предметов 1.21.4+.
Комплекты Bedrock-сущностей, написанные вручную
Плагин может поставлять нативные ассеты Bedrock-сущностей напрямую, поместив их в assets/<namespace>/rspm_bedrock_pack/ своего Java-пака. RSPM копирует эти файлы дословно в генерируемый Bedrock-пак. Принимаются только каталоги, связанные с сущностями (entity, models/entity, animations, animation_controllers, render_controllers, materials, textures/entity), чтобы участвующий плагин не мог перекрыть манифест пака или атлас иконок. Слишком длинные пути автоматически сокращаются, а JSON-перекрёстные ссылки переписываются соответственно, поэтому ссылки на геометрию и текстуры продолжают разрешаться. Запись двумя пространствами имён разных байтов в одно и то же место назначения — это жёсткая ошибка, а не молчаливая перезапись.
Именно этот механизм стоит за настоящими кастомными Bedrock-сущностями — см. Расширение Geyser и кастомные сущности. Пак, содержащий только комплекты сущностей и ноль маппингов предметов, всё равно выпускается.
Кастомные комплекты брони обнаруживаются при наличии соседнего файла assets/<namespace>/equipment/<material>.json. Конвертер собирает броневый attachable, который комбинирует ванильную геометрию брони с Java-текстурой в качестве видимого слоя, чтобы игроки 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, подключающийся после свежей сборки, получает последний Bedrock-пак, раздаваемый прямо с диска, — перезапуск сервера для правок текстур или моделей существующих предметов не нужен.
Маппинги кастомных предметов Geyser (JSON в custom_mappings/) по-прежнему «замораживаются» при загрузке, поэтому добавление новых или удаление существующих кастомных предметов требует перезапуска сервера, прежде чем клиенты Bedrock увидят эти изменения. RSPM заранее раскладывает файл маппингов от предыдущего запуска на ранней стадии старта, чтобы регистрация кастомных предметов Geyser при загрузке автоматически его подхватила.
Игроки Bedrock, подключённые в данный момент, остаются с тем паком, который получили на своём входе, — это ограничение Bedrock-протокола, плагин не может его переопределить посреди сессии.
Как это работает в режиме прокси
В прокси-сети сам бэкенд не регистрирует подписчика SessionLoadResourcePacks (нет локального Geyser, на который можно подписываться). Вместо этого:
- Бэкенд производит
output/ResourcePackManager_Bedrock.zip, а когда есть маппинги предметов — иoutput/rspm_geyser_mappings.json. - Бэкенд запускает небольшой HTTP-сервер (порт выводится автоматически, по умолчанию
mcPort + 1) с маршрутами/bedrock.zipи/mappings.json, которые читают файл свежим при каждом запросе, и объявляет прокси точный порт, на который он привязался. - Прокси-плагин опрашивает каждые 5 секунд, предпочитая строгие ETag через
If-None-Matchи сохраняя совместимость сIf-Modified-Sinceдля более старых бэкендов. Он скачивает вывод каждого бэкенда при изменении и ждёт, пока инбокс стабилизируется. - Прокси-плагин объединяет Bedrock-пак каждого бэкенда в единый общесетевой пак и раздаёт его Bedrock-клиентам через Geyser прокси.
- Если прокси не может достучаться до 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 удаляет любой устаревший вывод Bedrock от предыдущего запуска, а не отправляет пустой пак. Маршрут бэкенда /bedrock.zip тогда корректно возвращает 404, что является правильным сигналом для прокси, что этому бэкенду нечего вносить в Bedrock-контент. Паки, состоящие только из сущностей, по-прежнему публикуются.
Настройки в 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 проверяет, по порядку:
bedrockGeyserFolder, если задан (сначала используется как написано, поэтому относительные пути разрешаются от рабочего каталога сервера; если такого пути нет, он пробуется относительноplugins/). Абсолютные пути тоже работают.plugins/Geyser-Spigot/plugins/Geyser-*/(любой вариант)config/Geyser-*/(для установок Fabric/NeoForge)
Настройка отображения предмета в руке: bedrock_display_offsets.yml
Bedrock рендерит предмет в руке через родительскую кость, чья rest-поза отличается от Java-трансформаций от первого и третьего лица, поэтому алгоритмическое преобразование должно применять базовое смещение поверх того, что задаёт Java-модельная трансформация display. Значения по умолчанию подходят для типичных праворуких Java-моделей, но в нестандартных случаях может потребоваться настройка.
Виды от первого и третьего лица — это два полностью отдельных Bedrock-прохода рендеринга (разные родительские кости, разные rest-позы), поэтому у каждого есть свой независимый набор из шести параметров. Настройка одного не влияет на другой.
# ===== First-person (right hand, seen by the holder) =====
firstPersonBaseRotationX: -60.0 # pitch (tipping toward/away from camera)
firstPersonBaseRotationY: 123.0 # yaw (spinning around vertical line)
firstPersonBaseRotationZ: 170.0 # roll (around camera-forward axis)
firstPersonBasePositionX: -8.0 # vertical on screen (positive = up)
firstPersonBasePositionY: 7.5 # depth (positive = further into the scene)
firstPersonBasePositionZ: -5.0 # horizontal on screen (positive = right)
# ===== Third-person (right hand, seen by other players / F5) =====
thirdPersonBaseRotationX: 90.0 # pitch as observers see it
thirdPersonBaseRotationY: 0.0 # yaw
thirdPersonBaseRotationZ: 0.0 # roll around the item's long axis
thirdPersonBasePositionX: 0.0 # horizontal across the holder's body (positive = outward)
thirdPersonBasePositionY: 6.0 # vertical (positive = raises the model)
thirdPersonBasePositionZ: -10.0 # depth relative to holder (positive = forward)
Значения позиций — в пикселях, где 1 пиксель = 1/16 блока. Повороты — в градусах.
Измените значение, выполните /rspm reload и переподключите тестовый Bedrock-клиент, чтобы при следующем входе он получил пересобранный пак. Итерируйте, пока предмет в руке не будет выглядеть правильно.
Debug-логирование
Доступны две 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: ..., вместо того чтобы тихо выдать частичный пак. Пак, который раньше преобразовывался «в основном», теперь сообщает вам, что не преобразовался. - Базовые предметы «знамя» и «редстоун» пропускаются. Кастомные предметы, чьей базой является один из 16 окрашенных знамён или
minecraft:redstone, не получают маппинг кастомного предмета Geyser, потому что Geyser выводит из этих баз некорректный block-placer. Bedrock показывает для них ванильную иконку. Консоль называет затронутые предметы, когда это происходит. - Преобразование кооперативно прерываемо:
/rspm reloadили выключение на полпути прерывают его чисто, вместо того чтобы оставить наполовину записанный вывод. Файл маппингов Geyser публикуется только после успешной сборки zip пака, поэтому вы никогда не получите новый пак в паре с устаревшими маппингами. - Когда в собранном паке нет ни преобразуемых маппингов предметов, ни разрешённых файлов комплектов сущностей, Bedrock-пак не выдаётся, и вывод предыдущего запуска удаляется. Пак, состоящий только из сущностей, при этом валиден и выдаётся даже при нулевом количестве маппингов предметов.
Оптимизация размера пака
Перед публикацией Bedrock-пака RSPM дедуплицирует побайтово идентичные файлы текстур с одинаковым расширением и переписывает точные JSON-ссылки на текстуры на оставленный файл. Он намеренно сохраняет псевдонимы, когда ссылка неоднозначна, встроена в более длинную строку или найдена в некорректном/непрозрачном JSON, чтобы оптимизация молча не ломала ссылки на ресурсы.