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

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

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

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

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

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

Если ни одно из этих условий не выполняется, конвертер — чистый накладной расход, и он молча пропускается. /rspm status объясняет ровно почему, когда пак не был сгенерирован.

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

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

  • выдаёт плоскую иконку инвентаря Bedrock (для обычных minecraft:item/generated и подобных flat-builtin родителей), либо
  • выдаёт Bedrock-геометрию, attachable, файл анимации и программно отрендеренную 2D-иконку инвентаря (для настоящих 3D-моделей).

Уникальный Bedrock-идентификатор генерируется для каждой пары (модель × базовый предмет), поэтому одна модель меча, зарегистрированная для нескольких базовых предметов, не конфликтует на стороне Geyser.

Кастомные комплекты брони обнаруживаются при наличии соседнего файла assets/<namespace>/equipment/<material>.json. Конвертер собирает броневый attachable, который комбинирует ванильную геометрию брони с Java-текстурой в качестве видимого слоя, чтобы игроки Bedrock видели правильную текстуру брони при её ношении.

UUID заголовка/модуля в манифесте Bedrock-пака детерминированно выводятся из строки версии плагина (сиды rspm_bedrock_header:<pluginVersion> и rspm_bedrock_module:<pluginVersion>), поэтому они остаются стабильными между пересборками одной и той же версии плагина и меняются только при смене версии плагина. Само имя пака используется только для header.name, а не для 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, на который можно подписываться). Вместо этого:

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

См. Прокси-сети для настройки. На стороне прокси преобразование (точнее, объединение) полностью автоматическое; для Bedrock-конвейера нет конфига на стороне прокси.

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

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

plugins/ResourcePackManager/output/ResourcePackManager_Bedrock.zip
plugins/ResourcePackManager/output/rspm_geyser_mappings.json

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

<geyser-folder>/custom_mappings/rspm_geyser_mappings.json

Сам zip Bedrock-пака не копируется в <geyser-folder>/packs/ — вместо этого он раздаётся вживую посессионно. RSPM также удаляет любую устаревшую копию, оставленную старыми версиями плагина в этой папке, чтобы Geyser в итоге не раздавал пак дважды (дублирующиеся UUID путали бы Bedrock-клиент).

Когда конвертеру нечего преобразовывать (в собранном паке нет определений предметов), RSPM удаляет любой устаревший вывод Bedrock от предыдущего запуска, а не отправляет пустой пак. Маршрут бэкенда /bedrock.zip тогда корректно возвращает 404, что является правильным сигналом для прокси, что этому бэкенду нечего вносить в Bedrock-контент.

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

# Полностью включает/выключает преобразование Java в Bedrock.
bedrockConversionEnabled: true

# Копирует файл кастомных маппингов Geyser в обнаруженную папку Geyser в
# каталог custom_mappings/ при каждой сборке.
bedrockAutoDeployToGeyser: true

# Ручное переопределение для папки данных Geyser. Пусто = авто-определение.
# Может быть абсолютным или относительным к каталогу plugins/.
bedrockGeyserFolder: ""

# Подробное логирование прогресса по каждому предмету / каждой кости от Bedrock-конвейера.
# По умолчанию false — чистый прогон выдаёт одну итоговую строку «Bedrock conversion complete:
# N mappings» вместо десятков или сотен строк по каждому предмету. Включайте при отладке
# конкретной проблемы преобразования.
bedrockConverterDebug: false

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

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

Настройка отображения предмета в руке: bedrock_display_offsets.yml

Bedrock рендерит предмет в руке через родительскую кость, чьи rest-позы отличаются от Java-трансформаций от первого и третьего лица, поэтому алгоритмическое преобразование должно применять базовое смещение поверх того, что задаёт Java-модельная трансформация display. Значения по умолчанию подходят для типичных праворуких Java-моделей, но в нестандартных случаях может потребоваться настройка.

Виды от первого и третьего лица — это два полностью отдельных Bedrock-прохода рендеринга (разные родительские кости, разные rest-позы), поэтому у каждого есть свой независимый набор из шести параметров. Настройка одного не влияет на другой.

# ===== Вид от первого лица (правая рука, видит держащий) =====
firstPersonBaseRotationX: -90.0 # тангаж (наклон к/от камеры). По умолчанию отменяет родительский поворот.
firstPersonBaseRotationY: 0.0 # рыскание (вращение вокруг вертикальной оси)
firstPersonBaseRotationZ: 0.0 # крен (вокруг оси «вперёд от камеры»)
firstPersonBasePositionX: 0.0 # вертикаль на экране (положительное = вверх)
firstPersonBasePositionY: 12.5 # глубина (положительное = дальше в сцену)
firstPersonBasePositionZ: 0.0 # горизонталь на экране (положительное = вправо)

# ===== Вид от третьего лица (правая рука, видят другие игроки / F5) =====
thirdPersonBaseRotationX: 90.0 # тангаж, как его видят наблюдатели
thirdPersonBaseRotationY: 0.0 # рыскание
thirdPersonBaseRotationZ: 0.0 # крен вокруг длинной оси предмета
thirdPersonBasePositionX: 0.0 # горизонталь поперёк тела держащего (положительное = наружу)
thirdPersonBasePositionY: 12.5 # вертикаль (положительное = поднимает модель)
thirdPersonBasePositionZ: 0.0 # глубина относительно держащего (положительное = вперёд)

Значения позиций — в пикселях, где 1 пиксель = 1/16 блока. Повороты — в градусах.

Bedrock-клиент перечитывает JSON attachable вживую без перезапуска. Если тестовый Bedrock-клиент в игре, измените значение, выполните /rspm reload, и следующий вход с Bedrock (а в некоторых случаях тот же подключённый игрок после небольшого действия в мире, которое заново привяжет attachable) покажет новое смещение. Итерируйте, пока не будет выглядеть правильно.

Debug-логирование

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

  • Бэкенд: bedrockConverterDebug: true в config.yml включает строки лога конвертера по каждому предмету, каждому attachable, каждому маппингу. Полезно, когда нужно понять, почему конкретный предмет не попал в Bedrock-пак.
  • Прокси (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 полей действует «побеждает наивысший приоритет». Ни один файл не выделяется для особого обращения.
  • Если конвертер не может разрешить файл текстуры или модели, на который есть ссылка, этот лист пропускается и записывается предупреждение [BedrockConverter] (или debug-строка, если bedrockConverterDebug выключен); остальной конвейер продолжает работать.
  • Когда в собранном паке ноль преобразуемых предметов, Bedrock-пак вообще не выдаётся, и вывод предыдущего запуска удаляется. RSPM не отправляет бесполезный пустой пак на ~22 КБ с запросом к игроку.