メインコンテンツまでスキップ

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 が正確に説明します。

変換される対象

コンバーターはネームスペース非依存です。1.21.4以降のアイテム定義形式である assets/<namespace>/items/*.json ファイルをすべて走査します。各リーフモデルに対して、次のいずれかを出力します:

  • フラットなBedrockのインベントリアイコン(素朴な minecraft:item/generated などのフラットなビルトイン親を持つモデル向け)。
  • Bedrockのジオメトリ、アタッチャブル、アニメーションファイル、そしてソフトウェアレンダリングされた2Dインベントリアイコン(真の3Dモデル向け)。

ユニークなBedrock識別子は (モデル × ベースアイテム) のペアごとに生成されます。これにより、たとえば1本の剣モデルが複数のベースアイテムに登録されていても、Geyser側で衝突しません。

カスタム防具セットは、姉妹ファイルとして assets/<namespace>/equipment/<material>.json が存在する場合に検出されます。コンバーターは、バニラの防具ジオメトリにJavaのテクスチャを可視レイヤーとして組み合わせる防具アタッチャブルを構成し、アイテムを装備したBedrockプレイヤーに正しい防具テクスチャが表示されるようにします。

Bedrockパックのマニフェストのヘッダー/モジュールUUIDは、プラグインのバージョン文字列から決定論的に導出されます(シードは rspm_bedrock_header:<pluginVersion>rspm_bedrock_module:<pluginVersion>)。そのため、同じプラグインバージョンの再構築をまたいでも安定し、プラグインバージョンが変わったときだけ変化します。パック名自体は header.name にのみ使われ、UUIDには使われません。バージョントリプレットは、ステージングされたBedrockパックのSHA-256コンテンツダイジェストから導出されたキャッシュバスト用トークンに基づき、ビルドごとにバンプされます — 内容が同一なら同じバージョンになり(何も変わらない再構築でGeyserのキャッシュが無駄に更新されません)、内容が実際に変われば、Bedrockの (uuid, version) をキーとするパックキャッシュが無効化されます。ビルド時刻(System.currentTimeMillis())は、コンテンツダイジェストを計算できないときのフォールバックとしてのみ使われます。

セッション単位のライブ配信(スタンドアロン)

同じバックエンドにGeyser-Spigotが検出されると、RSPMは SessionLoadResourcePacksEvent のサブスクライバーを登録します。新しいミックス後に参加したすべてのBedrockプレイヤーには、最新のBedrockパックがディスクから直接配信されます。既存アイテムのテクスチャやモデルの編集にサーバーの再起動は不要です。

ただし、Geyserのカスタムアイテムマッピングcustom_mappings/ 配下のJSON)は依然として起動時に固定されるため、新規のカスタムアイテムの追加や既存アイテムの削除はサーバー再起動が必要です。RSPMは前回実行時のマッピングファイルを起動の早い段階で事前にデプロイするため、Geyserの起動時カスタムアイテム登録に自動的に取り込まれます。

すでに接続中のBedrockプレイヤーは、自分が参加した時点で受け取ったパックをそのまま保持します。これはプラグインで上書きできるものではなく、Bedrockプロトコルの制約です。

プロキシモードでの仕組み

プロキシネットワークでは、バックエンド自身は SessionLoadResourcePacks のサブスクライバーを登録しません(購読すべきローカルのGeyserがないため)。代わりに:

  1. バックエンドは通常どおり output/ResourcePackManager_Bedrock.zipoutput/rspm_geyser_mappings.json を生成します。
  2. バックエンドは小さなHTTPサーバー(自動導出されるポート、既定は mcPort + 1)を起動し、リクエストごとにファイルを新しく読む /bedrock.zip/mappings.json ルートを公開し、実際にバインドした正確なポートをプロキシに通知します。
  3. プロキシプラグインは If-Modified-Since を使って5秒ごとにポーリングし、変更があった場合は各バックエンドの出力をダウンロードし、インボックスが安定するのを待ちます。
  4. プロキシプラグインはすべてのバックエンドのBedrockパックを1つのネットワーク全体パックにマージし、プロキシのGeyserを通じてBedrockクライアントに配信します。
  5. プロキシがバックエンドのHTTPポートに直接到達できない場合(共有/マネージドホスティングで隣接ポートがファイアウォールで遮断されているケースなど)、バックエンドはファイルを magmaguy.com のリレーエンドポイントにプッシュし、プロキシはそこ経由でファイルを取得します。

セットアップはプロキシネットワークを参照してください。プロキシ側では、変換(厳密にはマージ)は完全に自動で、Bedrockパイプライン用のプロキシ側設定はありません。

出力ファイル

ミックスが成功すると、Bedrock関連のファイルは次の場所に置かれます:

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

自動デプロイが有効で、同じJVM内にGeyserが検出された場合、マッピングファイルは次の場所にもコピーされます:

<geyser-folder>/custom_mappings/rspm_geyser_mappings.json

Bedrockパック本体は <geyser-folder>/packs/ にはコピーされず、代わりにセッション単位でライブ配信されます。RSPMは古いプラグインバージョンがそのフォルダーに残したかもしれないコピーも削除します。これは、Geyserが同じパックを二重に配信してしまう(同一UUIDの重複でBedrockクライアントが混乱する)のを防ぐためです。

コンバーターが変換すべきものを何も見つけなかった場合(マージされたパックにアイテム定義がない場合)、RSPMは空のパックを出荷する代わりに前回実行時のBedrock出力を削除します。バックエンドの /bedrock.zip ルートはその後きれいに404を返し、これは「このバックエンドにはBedrockコンテンツとして提供するものがない」という正しいシグナルをプロキシに伝えます。

config.yml 設定

# Java から Bedrock への変換そのものを切り替えます。
bedrockConversionEnabled: true

# 各ミックス時に、検出されたGeyserフォルダーの custom_mappings/ ディレクトリへ
# Geyserのカスタムマッピングファイルをコピーします。
bedrockAutoDeployToGeyser: true

# Geyserデータフォルダーの手動上書き。空 = 自動検出。
# 絶対パスか、plugins/ ディレクトリからの相対パスを指定できます。
bedrockGeyserFolder: ""

# Bedrockパイプラインからのアイテム単位/ボーン単位の詳細な進捗ログを出力します。
# 既定はfalse — クリーンに完了した実行ではアイテムごとの数十〜数百行ではなく、
# 1行の「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は、Javaの一人称/三人称トランスフォームとは異なる基本姿勢を持つ親ボーン経由で持ち物アイテムを描画します。そのため、アルゴリズムによる変換では、Javaモデルの display トランスフォームが指定するものに加えてベースオフセットを適用する必要があります。既定のオフセットは典型的な右利きのJavaモデル向けに調整されていますが、特殊なケースではチューニングが必要になることがあります。

一人称と三人称は完全に独立したBedrockのレンダーパス(親ボーンも基本姿勢も異なる)になっているため、それぞれに独自の6個のつまみがあります。一方を調整しても他方には影響しません。

# ===== 一人称(右手、所持者が見るビュー) =====
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をライブリロードします。Bedrockのテストクライアントがログイン中なら、値を変更して /rspm reload を実行すれば、次のBedrock参加(あるいは場合によっては、すでに接続中のプレイヤーがワールド内でアタッチャブルを再バインドする小さなアクションを行った後)で新しいオフセットが反映されます。良さそうな見た目になるまで繰り返してください。

デバッグログ

2種類のデバッグ出力が利用できます:

  • バックエンドconfig.ymlbedrockConverterDebug: true にすると、コンバーターからアイテム単位/アタッチャブル単位/マッピング単位のログ行が有効になります。特定のアイテムがBedrockパックに入らなかった理由を知りたいときに便利です。
  • プロキシ(VelocityとBungeeCord)/rspm debug bedrock on でプロキシの GeyserBinder が出力する [RSPM-BedrockDebug] ログストリームを切り替えます。Bedrockプレイヤーがプロキシに参加してもパックが見えない場合の調査に便利です。設定はプロキシ再起動でオフにリセットされるため、誤って付けっぱなしになることはありません。

制限事項と既知の挙動

  • 3DのインベントリアイコンはJavaモデルの display.gui トランスフォームからソフトウェアレンダリングされます。仕上がりはおおむね妥当ですが、ピクセル単位で完全とは限りません。アイコンがおかしい場合、もっとも多い原因はモデルが参照しているテクスチャファイルの欠落や名前の食い違いです。
  • アイテムアイコンとして使用されるフリップブックテクスチャはフレーム0にトリミングされます。Bedrockの item_texture.json はアニメーションするアイコンに対応しておらず、アニメーションは flipbook_textures.json 経由でブロック/地形テクスチャにのみ使えます。
  • アタッチャブルのジオメトリフォーマットバージョンは 1.21.0 に固定されています。インストール環境がそれを解析できない場合はGeyserを更新してください。
  • レガシーなバニラのアイテムモデルオーバーライドファイル(assets/minecraft/models/item/ 配下のすべて。shield.jsoncrossbow.json を含む)は、1つのパックに完全に勝たせるのではなく、パックをまたいでマージされます。overrides 配列のみが結合され(オーバーライドキーで重複排除)、オーバーライド以外のフィールドは引き続き最優先のパックが勝ちます。特別扱いされるファイルは1つもありません。
  • 参照されているテクスチャやモデルファイルをコンバーターが解決できない場合、そのリーフはスキップされ、[BedrockConverter] の警告がログに出力されます(bedrockConverterDebug がオフの場合はデバッグ行になります)。残りのパイプラインはそのまま継続します。
  • マージされたパックに変換可能なアイテムが1つもない場合、Bedrockパックは一切生成されず、前回実行の出力も削除されます。RSPMは、プロンプト付きの役に立たない約22KBの空パックを出荷しません。