Pular para o conteúdo principal

Conversão Java-para-Bedrock

O ResourcePackManager pode converter o resource pack Java unificado em um resource pack Bedrock, para que clientes do GeyserMC vejam o mesmo conteúdo personalizado que clientes Java. Esse recurso vem habilitado por padrão.

Quando a Conversão Roda

A conversão é condicionada à presença de um alvo Bedrock. O RSPM considera que há um alvo presente se qualquer uma destas condições for verdadeira:

  1. O Geyser-Spigot está instalado neste backend (jogadores Bedrock chegam pelo Geyser localmente).
  2. O Floodgate está instalado neste backend (configuração típica de proxy-backend — o Floodgate roda localmente, o Geyser está em outro lugar).
  3. O modo de rede está ativo — o RSPM detectou que está por trás de um proxy Velocity / BungeeCord / Waterfall. O backend produz seu pack Bedrock e o expõe em um pequeno servidor HTTP, para que o plugin do proxy possa buscá-lo.

Se nenhuma dessas condições for atendida, o conversor é puro overhead e é pulado silenciosamente. /rspm status explica exatamente o porquê quando o pack não foi gerado.

O Que é Convertido

O conversor é agnóstico de namespace. Ele percorre todo arquivo assets/<namespace>/items/*.json no formato de definição de itens 1.21.4+. Para cada modelo folha, ele:

  • emite um ícone de inventário Bedrock plano (para minecraft:item/generated simples e parentes flat-builtin semelhantes), ou
  • emite geometria Bedrock, um attachable, um arquivo de animação e um ícone de inventário 2D renderizado por software (para modelos 3D propriamente ditos).

Um identificador Bedrock único é gerado por par (modelo × item base), então um único modelo de espada registrado contra múltiplos itens base não colide do lado do Geyser.

Conjuntos de armadura personalizada são detectados quando existe um irmão assets/<namespace>/equipment/<material>.json. O conversor cria um attachable de armadura que combina a geometria de armadura vanilla com a textura Java como camada visível, para que os jogadores Bedrock vejam a textura de armadura correta ao usar o item.

Os UUIDs de header/módulo do manifest do pack Bedrock são derivados determinísticamente da string de versão do plugin (sementes rspm_bedrock_header:<pluginVersion> e rspm_bedrock_module:<pluginVersion>), de modo que permanecem estáveis entre reconstruções da mesma versão do plugin e só mudam quando a versão do plugin muda. O nome do pack em si é usado apenas para header.name, não para o UUID. O trio de versão é incrementado por build a partir de um token cache-bust derivado de um digest de conteúdo SHA-256 do pack Bedrock preparado — conteúdos idênticos produzem a mesma versão (para que reconstruções sem mudanças não afetem o cache do Geyser), enquanto mudanças reais de conteúdo invalidam o cache de pack do Bedrock, que é chaveado por (uuid, version). O tempo de build (System.currentTimeMillis()) só é usado como fallback quando o digest de conteúdo não pode ser computado.

Serviço Ao Vivo Por Sessão (Standalone)

Quando o Geyser-Spigot é detectado no mesmo backend, o RSPM registra um subscriber de SessionLoadResourcePacksEvent. Cada jogador Bedrock que entrar após uma nova mescla recebe o pack Bedrock mais recente servido diretamente do disco — sem necessidade de reiniciar o servidor para edições de textura ou modelo em itens já existentes.

Os mappings de itens personalizados do Geyser (o JSON em custom_mappings/) ainda são congelados na inicialização, então adicionar novos itens personalizados ou remover existentes exige reinício do servidor antes que clientes Bedrock vejam essas mudanças. O RSPM pré-implanta o arquivo de mapeamento da execução anterior no início da inicialização para que o registro de itens personalizados do Geyser no boot o detecte automaticamente.

Jogadores Bedrock atualmente conectados mantêm o pack que receberam quando entraram — isso é uma restrição do protocolo Bedrock, não algo que o plugin possa contornar em meio à sessão.

Como Funciona no Modo Proxy

Em uma rede com proxy, o próprio backend não registra um subscriber de SessionLoadResourcePacks (não há Geyser local ao qual se inscrever). Em vez disso:

  1. O backend produz output/ResourcePackManager_Bedrock.zip + output/rspm_geyser_mappings.json normalmente.
  2. O backend inicia um pequeno servidor HTTP (porta auto-derivada, mcPort + 1 por padrão) expondo as rotas /bedrock.zip e /mappings.json, que leem o arquivo atualizado a cada requisição, e anuncia ao proxy a porta exata em que se vinculou.
  3. O plugin do proxy faz polling a cada 5 segundos via If-Modified-Since, baixa as saídas de cada backend quando elas mudam e aguarda a caixa de entrada estabilizar.
  4. O plugin do proxy une o pack Bedrock de cada backend em um único pack válido para toda a rede e o serve a clientes Bedrock por meio do Geyser do proxy.
  5. Se o proxy não conseguir alcançar diretamente a porta HTTP de um backend (comum em hospedagem compartilhada/gerenciada, onde portas adjacentes são bloqueadas pelo firewall), o backend faz push de seus arquivos para um endpoint de relay em magmaguy.com e o proxy os busca por lá.

Veja Redes com Proxy para a configuração. Do lado do proxy, a conversão (bem, a mesclagem) é totalmente automática; não há config do lado do proxy para o pipeline Bedrock.

Arquivos de Saída

Após uma mescla bem-sucedida, os arquivos Bedrock ficam em:

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

Se o auto-deploy estiver ativado e o Geyser tiver sido detectado na mesma JVM, o arquivo de mappings também é copiado para:

<geyser-folder>/custom_mappings/rspm_geyser_mappings.json

O zip do pack Bedrock não é copiado para <geyser-folder>/packs/ — ele é servido ao vivo por sessão em vez disso. O RSPM também remove qualquer cópia legada deixada nessa pasta por versões antigas do plugin, para que o Geyser não acabe servindo o pack duas vezes (UUIDs duplicados confundiriam o cliente Bedrock).

Quando o conversor não encontra nada para converter (nenhuma definição de itens no pack unificado), o RSPM deleta quaisquer saídas Bedrock obsoletas de uma execução anterior, em vez de entregar um pack vazio. A rota /bedrock.zip do backend então retorna 404 de forma limpa, que é o sinal correto para o proxy de que este backend não tem conteúdo Bedrock a contribuir.

Configurações em config.yml

# Alterna por completo a conversão Java-para-Bedrock.
bedrockConversionEnabled: true

# Copia o arquivo de custom mappings do Geyser para o diretório
# custom_mappings/ da pasta Geyser detectada em cada mescla.
bedrockAutoDeployToGeyser: true

# Substituição manual para a pasta de dados do Geyser. Vazio = auto-detecção.
# Pode ser absoluto ou relativo ao diretório plugins/.
bedrockGeyserFolder: ""

# Log detalhado de progresso por item / por osso do pipeline Bedrock.
# Padrão false — uma execução limpa emite um único resumo "Bedrock conversion
# complete: N mappings" em vez de dezenas a centenas de linhas por item.
# Ative ao depurar um problema específico de conversão.
bedrockConverterDebug: false

A auto-detecção da pasta do Geyser observa, nesta ordem:

  1. bedrockGeyserFolder se estiver definido (tratado primeiro como caminho absoluto, depois como caminho relativo a plugins/).
  2. plugins/Geyser-Spigot/
  3. plugins/Geyser-*/ (qualquer variante)
  4. config/Geyser-*/ (para configurações Fabric/NeoForge)

Ajustando a Exibição de Itens Segurados: bedrock_display_offsets.yml

O Bedrock renderiza o item segurado por meio de um osso pai cuja pose de descanso difere das transformações de primeira e terceira pessoa do Java, então a conversão algorítmica precisa aplicar um offset base sobre o que quer que a transformação display do modelo Java especifique. Os offsets padrão funcionam para modelos Java típicos destros, mas casos atípicos podem precisar de ajuste.

Primeira pessoa e terceira pessoa são duas passagens de renderização Bedrock completamente separadas (ossos pais diferentes, poses de descanso diferentes), então cada uma tem seu próprio conjunto independente de seis parâmetros. Ajustar uma não afeta a outra.

# ===== Primeira pessoa (mão direita, vista pelo portador) =====
firstPersonBaseRotationX: -90.0 # pitch (inclinação na direção da câmera/contrária). O padrão cancela a rotação do pai.
firstPersonBaseRotationY: 0.0 # yaw (rotação em torno da linha vertical)
firstPersonBaseRotationZ: 0.0 # roll (em torno do eixo frente-câmera)
firstPersonBasePositionX: 0.0 # vertical na tela (positivo = para cima)
firstPersonBasePositionY: 12.5 # profundidade (positivo = mais adentro da cena)
firstPersonBasePositionZ: 0.0 # horizontal na tela (positivo = para a direita)

# ===== Terceira pessoa (mão direita, vista por outros jogadores / F5) =====
thirdPersonBaseRotationX: 90.0 # pitch como os observadores veem
thirdPersonBaseRotationY: 0.0 # yaw
thirdPersonBaseRotationZ: 0.0 # roll em torno do eixo longitudinal do item
thirdPersonBasePositionX: 0.0 # horizontal em relação ao corpo do portador (positivo = para fora)
thirdPersonBasePositionY: 12.5 # vertical (positivo = eleva o modelo)
thirdPersonBasePositionZ: 0.0 # profundidade em relação ao portador (positivo = para frente)

Os valores de posição são em pixels, onde 1 pixel = 1/16 de bloco. As rotações são em graus.

O cliente Bedrock recarrega ao vivo o JSON de attachable sem precisar reiniciar. Se um cliente Bedrock de teste estiver logado, altere o valor, execute /rspm reload, e o próximo join Bedrock (ou, em alguns casos, o mesmo jogador conectado após uma pequena ação no mundo que faça o re-bind do attachable) mostra o novo offset. Itere até ficar certo.

Log de Debug

Há duas superfícies de debug disponíveis:

  • Backend: bedrockConverterDebug: true no config.yml ativa as linhas de log por item, por attachable e por mapping do conversor. Útil quando você precisa saber por que um item específico não entrou no pack Bedrock.
  • Proxy (Velocity e BungeeCord): /rspm debug bedrock on alterna o stream de log [RSPM-BedrockDebug] emitido pelo GeyserBinder do proxy. Útil quando jogadores Bedrock entram no proxy mas não veem o pack. A configuração volta a desligada no restart do proxy, então não pode ser deixada ligada por acidente.

Limitações e Comportamentos Conhecidos

  • Ícones de inventário 3D são renderizados por software a partir da transformação display.gui do modelo Java. A renderização é razoável, mas não pixel-perfect; se o ícone parecer errado, a causa mais comum é um arquivo de textura ausente/com nome incorreto referenciado pelo modelo.
  • Texturas de flipbook usadas como ícones de itens são cortadas ao frame 0 — o item_texture.json do Bedrock não suporta ícones animados, apenas texturas animadas de bloco/terreno via flipbook_textures.json.
  • A versão de formato da geometria de attachable está fixada em 1.21.0; atualize o Geyser se sua instalação não conseguir analisá-la.
  • Arquivos legados de override de modelo de item vanilla (qualquer coisa em assets/minecraft/models/item/, incluindo shield.json e crossbow.json) são mesclados entre packs em vez de deixar um pack vencer por completo: apenas os arrays overrides são combinados (deduplicados pela chave de override), enquanto campos que não são de override seguem o critério de maior-prioridade-vence. Nenhum arquivo recebe tratamento especial isolado.
  • Se o conversor não conseguir resolver um arquivo de textura ou modelo referenciado, essa folha é pulada e um aviso [BedrockConverter] é registrado (ou uma linha de debug se bedrockConverterDebug estiver desligado); o restante do pipeline continua.
  • Quando o pack unificado contém zero itens convertíveis, nenhum pack Bedrock é emitido e qualquer saída de execução anterior é deletada. O RSPM não entrega um pack vazio inútil de ~22 KB junto com um prompt.