Saltar al contenido principal

Conversión de Java a Bedrock

ResourcePackManager puede convertir el paquete de recursos Java fusionado en un paquete de recursos de Bedrock para que los clientes de GeyserMC vean el mismo contenido personalizado que los clientes de Java. Está activado por defecto.

Cuándo se ejecuta la conversión

La conversión está condicionada a la presencia de un destino de Bedrock. RSPM considera que hay un destino presente si se cumple cualquiera de estas condiciones:

  1. Geyser-Spigot está instalado en este backend (los jugadores de Bedrock llegan a Geyser localmente).
  2. Floodgate está instalado en este backend (configuración típica de proxy-backend: Floodgate se ejecuta localmente, Geyser está en otro lugar).
  3. El modo de red está activo — RSPM detectó que está detrás de un proxy de Velocity / BungeeCord / Waterfall. El backend produce su paquete de Bedrock y lo expone en un pequeño servidor HTTP para que el plugin del proxy pueda obtenerlo.

Si no se cumple ninguna de estas condiciones, el convertidor es pura sobrecarga y se omite silenciosamente. /rspm status explica exactamente por qué cuando el paquete no se ha generado.

Qué se convierte

El convertidor es agnóstico respecto al namespace. Recorre cada archivo assets/<namespace>/items/*.json en el formato de definición de ítems 1.21.4+. Para cada modelo hoja:

  • emite un icono de inventario plano de Bedrock (para minecraft:item/generated simple y otros padres planos integrados similares), o
  • emite geometría de Bedrock, un attachable, un archivo de animación y un icono de inventario 2D renderizado por software (para modelos verdaderamente 3D).

Se genera un identificador único de Bedrock por cada par (modelo × ítem base), de modo que un único modelo de espada registrado contra varios ítems base no colisione del lado de Geyser.

Los sets de armadura personalizados se detectan cuando existe un archivo hermano assets/<namespace>/equipment/<material>.json. El convertidor cablea un attachable de armadura que combina la geometría de armadura vanilla con la textura Java como capa visible, para que los jugadores de Bedrock vean la textura de armadura correcta al llevar el ítem.

Los UUIDs del header/módulo del manifest del paquete de Bedrock se derivan de forma determinista de la cadena de versión del plugin (semillas rspm_bedrock_header:<pluginVersion> y rspm_bedrock_module:<pluginVersion>), por lo que se mantienen estables entre reconstrucciones de la misma versión del plugin y solo cambian cuando cambia la versión del plugin. El nombre del paquete en sí solo se usa para header.name, no para el UUID. El triplete de versión se incrementa por compilación a partir de un token de invalidación de caché derivado de un resumen de contenido SHA-256 del paquete de Bedrock preparado: contenidos idénticos producen la misma versión (para que las reconstrucciones sin cambios no agiten la caché de Geyser), mientras que los cambios reales de contenido invalidan la caché de paquetes de Bedrock indexada por (uuid, version). El tiempo de compilación (System.currentTimeMillis()) solo se usa como respaldo cuando no se puede calcular el resumen de contenido.

Servicio en vivo por sesión (independiente)

Cuando se detecta Geyser-Spigot en el mismo backend, RSPM registra un suscriptor a SessionLoadResourcePacksEvent. Cada jugador de Bedrock que se conecte después de una nueva mezcla recibe el paquete de Bedrock más reciente servido directamente desde disco, sin necesidad de reiniciar el servidor para ediciones de textura o modelo de ítems existentes.

Las asignaciones de ítems personalizados de Geyser (el JSON en custom_mappings/) siguen congeladas al arrancar, por lo que añadir nuevos ítems personalizados o eliminar los existentes requiere reiniciar el servidor antes de que los clientes de Bedrock vean esos cambios. RSPM predespliega el archivo de mappings de la ejecución anterior al principio del arranque para que el registro de ítems personalizados de Geyser, durante el arranque, lo recoja automáticamente.

Los jugadores de Bedrock actualmente conectados conservan el paquete que recibieron al conectarse — esa es una restricción del protocolo de Bedrock, no algo que el plugin pueda anular a mitad de sesión.

Cómo funciona en modo proxy

En una red proxy, el propio backend no registra un suscriptor a SessionLoadResourcePacks (no hay un Geyser local al que suscribirse). En su lugar:

  1. El backend produce output/ResourcePackManager_Bedrock.zip + output/rspm_geyser_mappings.json como de costumbre.
  2. El backend inicia un pequeño servidor HTTP (puerto autoderivado, mcPort + 1 por defecto) que expone las rutas /bedrock.zip y /mappings.json, las cuales leen el archivo de forma fresca en cada solicitud, y anuncia al proxy el puerto exacto al que se enlazó.
  3. El plugin del proxy sondea cada 5 segundos mediante If-Modified-Since, descarga las salidas de cada backend cuando cambian y espera a que la bandeja de entrada se estabilice.
  4. El plugin del proxy fusiona el paquete de Bedrock de cada backend en un único paquete a nivel de red y lo sirve a los clientes de Bedrock a través del Geyser del proxy.
  5. Si el proxy no puede alcanzar directamente el puerto HTTP de un backend (común en alojamientos compartidos/gestionados donde los puertos adyacentes están bloqueados por el firewall), el backend envía sus archivos a un endpoint de relevo en magmaguy.com y el proxy los obtiene a través de allí.

Consulta Redes proxy para la configuración. Del lado del proxy, la conversión (bueno, la fusión) es totalmente automática; no hay configuración del lado del proxy para la canalización de Bedrock.

Archivos de salida

Tras una mezcla exitosa, los archivos de Bedrock viven en:

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

Si el despliegue automático está activado y Geyser fue detectado en la misma JVM, el archivo de mappings también se copia a:

<geyser-folder>/custom_mappings/rspm_geyser_mappings.json

El zip del paquete de Bedrock no se copia a <geyser-folder>/packs/ — se sirve en vivo por sesión en su lugar. RSPM también elimina cualquier copia heredada que versiones anteriores del plugin hubieran dejado en esa carpeta, para que Geyser no termine sirviendo el paquete dos veces (los UUIDs duplicados confundirían al cliente de Bedrock).

Cuando el convertidor no encuentra nada que convertir (no hay definiciones de ítems en el paquete fusionado), RSPM elimina cualquier salida de Bedrock obsoleta de una ejecución anterior en lugar de entregar un paquete vacío. La ruta /bedrock.zip del backend devuelve entonces un 404 limpio, que es la señal correcta para el proxy de que este backend no tiene contenido de Bedrock que aportar.

Opciones en config.yml

# Activa o desactiva por completo la conversión de Java a Bedrock.
bedrockConversionEnabled: true

# Copia el archivo de mappings personalizados de Geyser al directorio
# custom_mappings/ de la carpeta de Geyser detectada en cada mezcla.
bedrockAutoDeployToGeyser: true

# Sobrescritura manual de la carpeta de datos de Geyser. Vacío = autodetectar.
# Puede ser absoluta o relativa al directorio plugins/.
bedrockGeyserFolder: ""

# Registro de progreso verboso por ítem / por hueso de la canalización de Bedrock.
# Por defecto false — una ejecución limpia emite un único resumen "Bedrock
# conversion complete: N mappings" en lugar de decenas o cientos de líneas por
# ítem. Actívalo al depurar un problema de conversión específico.
bedrockConverterDebug: false

La autodetección de la carpeta de Geyser busca, en orden:

  1. bedrockGeyserFolder si está establecido (se trata primero como ruta absoluta y luego como ruta relativa a plugins/).
  2. plugins/Geyser-Spigot/
  3. plugins/Geyser-*/ (cualquier variante)
  4. config/Geyser-*/ (para configuraciones Fabric/NeoForge)

Ajuste de la visualización del ítem en mano: bedrock_display_offsets.yml

Bedrock renderiza el ítem en mano a través de un hueso padre cuya pose de reposo difiere de las transformaciones de primera/tercera persona de Java, por lo que la conversión algorítmica debe aplicar un desplazamiento base por encima de lo que indique la transformación display del modelo Java. Los desplazamientos por defecto funcionan para modelos Java diestros típicos, pero los casos atípicos pueden necesitar ajustes.

La primera persona y la tercera persona son dos pases de renderizado de Bedrock completamente separados (huesos padre distintos, poses de reposo distintas), por lo que cada uno tiene su propio conjunto independiente de seis parámetros. Ajustar uno no afecta al otro.

# ===== Primera persona (mano derecha, vista por el propio portador) =====
firstPersonBaseRotationX: -90.0 # pitch (inclinación hacia/desde la cámara). Por defecto cancela la rotación del padre.
firstPersonBaseRotationY: 0.0 # yaw (giro alrededor de la línea vertical)
firstPersonBaseRotationZ: 0.0 # roll (alrededor del eje hacia adelante de la cámara)
firstPersonBasePositionX: 0.0 # vertical en pantalla (positivo = arriba)
firstPersonBasePositionY: 12.5 # profundidad (positivo = más adentro de la escena)
firstPersonBasePositionZ: 0.0 # horizontal en pantalla (positivo = derecha)

# ===== Tercera persona (mano derecha, vista por otros jugadores / F5) =====
thirdPersonBaseRotationX: 90.0 # pitch tal como lo ven los observadores
thirdPersonBaseRotationY: 0.0 # yaw
thirdPersonBaseRotationZ: 0.0 # roll alrededor del eje largo del ítem
thirdPersonBasePositionX: 0.0 # horizontal a través del cuerpo del portador (positivo = hacia afuera)
thirdPersonBasePositionY: 12.5 # vertical (positivo = sube el modelo)
thirdPersonBasePositionZ: 0.0 # profundidad relativa al portador (positivo = hacia adelante)

Los valores de posición están en píxeles, donde 1 píxel = 1/16 de bloque. Las rotaciones están en grados.

El cliente de Bedrock recarga en vivo el JSON de attachable sin relanzar. Si tienes un cliente de prueba de Bedrock conectado, cambia el valor, ejecuta /rspm reload, y la siguiente conexión de Bedrock (o, en algunos casos, el mismo jugador conectado tras una pequeña acción en el mundo que vuelva a vincular el attachable) mostrará el nuevo desplazamiento. Itera hasta que se vea bien.

Registro de depuración

Hay dos superficies de depuración disponibles:

  • Backend: bedrockConverterDebug: true en config.yml activa las líneas de log por ítem, por attachable y por mapping del convertidor. Útil cuando necesitas saber por qué un ítem específico no llegó al paquete de Bedrock.
  • Proxy (Velocity y BungeeCord): /rspm debug bedrock on alterna el flujo de log [RSPM-BedrockDebug] emitido por el GeyserBinder del proxy. Útil cuando los jugadores de Bedrock se conectan al proxy pero no ven el paquete. La opción se restablece a off al reiniciar el proxy, de modo que no puede quedarse activada accidentalmente.

Limitaciones y comportamiento conocido

  • Los iconos de inventario 3D se renderizan por software a partir de la transformación display.gui del modelo Java. El renderizado es razonable pero no perfecto a nivel de píxel; si el icono se ve mal, la causa más común es un archivo de textura faltante o con el nombre incorrecto referenciado por el modelo.
  • Las texturas de flipbook usadas como iconos de ítem se recortan al fotograma 0 — el item_texture.json de Bedrock no soporta iconos animados, solo texturas animadas de bloques/terreno mediante flipbook_textures.json.
  • La versión de formato de la geometría de attachable está fijada en 1.21.0; actualiza Geyser si tu instalación no puede analizarla.
  • Los archivos heredados de sobrescritura de modelos de ítems vanilla (cualquier cosa bajo assets/minecraft/models/item/, incluyendo shield.json y crossbow.json) se fusionan entre paquetes en lugar de dejar que un paquete gane por completo: solo se combinan los arrays overrides (deduplicados por clave de override), mientras que los campos que no son de override siguen la regla de que gana la mayor prioridad. Ningún archivo recibe un trato especial.
  • Si el convertidor no puede resolver un archivo de textura o modelo referenciado, esa hoja se omite y se registra una advertencia [BedrockConverter] (o una línea de depuración si bedrockConverterDebug está desactivado); el resto de la canalización continúa.
  • Cuando el paquete fusionado no contiene ningún ítem convertible, no se emite ningún paquete de Bedrock en absoluto y se elimina cualquier salida de la ejecución anterior. RSPM no entrega un paquete vacío inútil de ~22 KB con un aviso.