Java から Bedrock への変換
ResourcePackManagerは、マージされたJavaリソースパックをBedrockリソースパックに変換できるため、GeyserMCのクライアントもJavaクライアントと同じカスタムコンテンツを見ることができます。これは既定で有効です。
変換が走る条件
変換はBedrockターゲットの存在によってゲートされます。RSPMは、次のいずれかが真であればターゲットが存在するとみなします:
- このバックエンドにGeyser-Spigotがインストールされている(BedrockプレイヤーはローカルのGeyserに接続します)。
- このバックエンドにFloodgateがインストールされている(典型的なプロキシ+バックエンド構成 — Floodgateはローカルで動作し、Geyserは別の場所にあります)。
- ネットワークモードが有効 — RSPMがVelocity/BungeeCord/Waterfallプロキシの背後にあることを検出しています。バックエンドはBedrockパックを生成し、小さなHTTPサーバー経由でプロキシプラグインから取得できるように公開します。
これらの条件のいずれも成立しない場合、コンバーターは単なるオーバーヘッドになるため、サイレントにスキップされます。パックが生成されなかった理由は /rspm status が正確に説明します。
変換される対象
コンバーターはネームスペース非依存です。1.21.4以降のアイテム定義形式である assets/<namespace>/items/**/*.json ファイルを、minecraft ネームスペースも含めて再帰的にすべて走査します。
フラットと3Dの振り分け
コンバーターは各リーフモデルについて2つのパイプラインのどちらを使うかを決定します。minecraft:item/generated または minecraft:builtin/generated を親に持つモデルはフラット経路にとどまります。それ以外の親チェーンでは、マージされたモデルが空でない elements 配列を持つ場合にのみ3Dパイプラインに進みます。ジオメトリを持たないモデルは2Dスプライトです。
- フラット — モデルの
layer0テクスチャがそのままtextures/items/<hash>.pngにコピーされ、Geyserのアイコンとして登録されます。Bedrockでは、Javaでの描画とまったく同じように、インベントリでも手に持ったときでも正しい2Dスプライトが表示されます。 - 3D — コンバーターはテクスチャアトラスを合成し、Javaの直方体をBedrockのジオメトリに変換し、hold/headアニメーションを生成し、64×64のインベントリアイコンをソフトウェアレンダリングし、
(モデル × ベースアイテム × 述語形状)のマッピングごとにアタッチャブルを1つ書き出します。
ジオメトリのチェックが重要な理由:フラットな手持ち道具(親が minecraft:item/handheld で、layer0 テクスチャのみを持ち elements がないもの)も2Dスプライトです。以前のバージョンはフラットな手持ちアイテムを3Dパイプラインに送っていたため、ジオメトリのステップで失敗し、Bedrockでアイテムが消えるか、バニラのベースアイテムのアイコンにフォールバックしていました。これは特に、フラットな手持ちアイテムを多数同梱するItemsAdderのパックに影響していました。elements はマージ済みの親チェーンから読み取られるため、親からジオメトリを継承する非generatedのモデルは引き続き3Dに振り分けられます。
ユニークなBedrock識別子は (モデル × ベースアイテム × 述語形状) のマッピングごとに生成されます。これにより、たとえば1本の剣モデルが複数のベースアイテムや述語ブランチに登録されていても、Geyser側で衝突しません。生成されるファイル名は読める名前ではなく短いコンテンツハッシュです。ネームスペース+パスの完全な名前は、Geyserの80文字というパックパス長の上限を日常的に超えてしまうためです。
1.21.4より前のレガシーパック
旧来の assets/minecraft/models/item/*.json + overrides[].predicate.custom_model_data 形式を今も使っているパックも読み取られ、現代的なレンジディスパッチ形式へ合成されます。これはベストエフォートの処理です。レガシー形式を使ったアイテムはBedrockで正しく描画されないことが多いため、その数がコンソールに記録されます。本当の解決策は、ソースのパックを1.21.4以降のアイテム定義形式へ移行することです。
手書きのBedrockエンティティバンドル
プラグインは、自身のJavaパック内の assets/<namespace>/rspm_bedrock_pack/ 配下にファイルを置くことで、ネイティブのBedrockエンティティアセットを直接同梱できます。RSPMはそれらのファイルをそのまま生成Bedrockパックへコピーします。受け付けられるのはエンティティ関連のディレクトリのみ(entity、models/entity、animations、animation_controllers、render_controllers、materials、textures/entity)なので、提供側のプラグインがパックのマニフェストやアイコンアトラスを上書きすることはできません。長すぎるパスは自動的に短縮され、JSONの相互参照もそれに合わせて書き換えられるため、ジオメトリやテクスチャの参照は解決され続けます。2つのネームスペースが同じ行き先に異なるバイト列を書き込もうとした場合は、静かに上書きするのではなくハードエラーになります。
これが真のカスタムBedrockエンティティを支える仕組みです — Geyser拡張とカスタムエンティティを参照してください。エンティティバンドルのみを含み、アイテムマッピングが1つもないパックでも出荷されます。
カスタム防具セットは、姉妹ファイルとして assets/<namespace>/equipment/<material>.json が存在する場合に検出されます。コンバーターは、バニラの防具ジオメトリにJavaのテクスチャを可視レイヤーとして組み合わせる防具アタッチャブルを構成し、アイテムを装備したBedrockプレイヤーに正しい防具テクスチャが表示されるようにします。
Bedrockパックのマニフェストのヘッダー/モジュールUUIDは、プラグインのバージョン文字列から決定論的に導出されます(シードは rspm_bedrock_header:<pluginVersion> と rspm_bedrock_module:<pluginVersion>)。そのため、同じプラグインバージョンの再構築をまたいでも安定し、プラグインバージョンが変わったときだけ変化します。表示されるヘッダー名は固定の ResourcePackManager Bedrock Pack で、UUIDの一部にはなりません。バージョントリプレットは、ステージングされたBedrockパックのSHA-256コンテンツダイジェストから導出されたキャッシュバスト用トークンに基づき、ビルドごとにバンプされます — 内容が同一なら同じバージョンになり(何も変わらない再構築でGeyserのキャッシュが無駄に更新されません)、内容が実際に変われば、Bedrockの (uuid, version) をキーとするパックキャッシュが無効化されます。ビルド時刻(System.currentTimeMillis())は、コンテンツダイジェストを計算できないときのフォールバックとしてのみ使われます。
セッション単位のライブ配信(スタンドアロン)
同じバックエンドにGeyser-Spigotが検出されると、RSPMは SessionLoadResourcePacksEvent のサブスクライバーを登録します。新しいミックス後に参加したすべてのBedrockプレイヤーには、最新のBedrockパックがディスクから直接配信されます。既存アイテムのテクスチャやモデルの編集にサーバーの再起動は不要です。
ただし、Geyserのカスタムアイテムマッピング(custom_mappings/ 配下のJSON)は依然として起動時に固定されるため、新規のカスタムアイテムの追加や既存アイテムの削除は、Bedrockクライアントに反映されるまでにサーバー再起動が必要です。RSPMは前回実行時のマッピングファイルを起動の早い段階で事前にデプロイするため、Geyserの起動時カスタムアイテム登録に自動的に取り込まれます。
すでに接続中のBedrockプレイヤーは、自分が参加した時点で受け取ったパックをそのまま保持します。これはプラグインがセッション途中で上書きできるものではなく、Bedrockプロトコルの制約です。
プロキシモードでの仕組み
プロキシネットワークでは、バックエンド自身は SessionLoadResourcePacks のサブスクライバーを登録しません(購読すべきローカルのGeyserがないため)。代わりに:
- バックエンドは
output/ResourcePackManager_Bedrock.zipを生成し、アイテムマッピングが存在する場合はoutput/rspm_geyser_mappings.jsonも生成します。 - バックエンドは小さなHTTPサーバー(自動導出されるポート、既定は
mcPort + 1)を起動し、リクエストごとにファイルを新しく読む/bedrock.zipと/mappings.jsonルートを公開し、実際にバインドした正確なポートをプロキシに通知します。 - プロキシプラグインは5秒ごとにポーリングし、
If-None-Matchによる強いETagを優先しつつ、古いバックエンドとの互換性のためにIf-Modified-Sinceも維持します。変更があった場合は各バックエンドの出力をダウンロードし、インボックスが安定するのを待ちます。 - プロキシプラグインはすべてのバックエンドのBedrockパックを1つのネットワーク全体パックにマージし、プロキシのGeyserを通じてBedrockクライアントに配信します。
- プロキシがバックエンドのHTTPポートに直接到達できない場合(共有/マネージドホスティングで隣接ポートがファイアウォールで遮断されているケースなど)、バックエンドはファイルを magmaguy.com のリレーエンドポイントにプッシュし、プロキシはそこ経由でファイルを取得します。
セットアップはプロキシネットワークを参照してください。プロキシ側のマージは自動で、有効化のトグルはありません。プロキシの設定にはちょうど2つの項目しかありません:バックエンドのエンドポイント通知が利用できるようになる前に使われるフォールバックのポートオフセット network-http-offset-v2 と、geyserExtensionAutoInstall のプロキシ側に相当する geyser-extension-auto-install です。
出力ファイル
ミックスが成功すると、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
Bedrockパックのzipは <geyser-folder>/packs/ にはコピーされず、代わりにセッション単位でライブ配信されます。古いRSPMのリリースがGeyserのパックディレクトリに ResourcePackManager_Bedrock.zip を残していた場合でも、現在のプラグインは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は、Javaの一人称/三人称トランスフォームとは異なる基本姿勢を持つ親ボーン経由で持ち物アイテムを描画します。そのため、アルゴリズムによる変換では、Javaモデルの display トランスフォームが指定するものに加えてベースオフセットを適用する必要があります。既定のオフセットは典型的な右利きのJavaモデル向けに調整されていますが、特殊なケースではチューニングが必要になることがあります。
一人称と三人称は完全に独立したBedrockのレンダーパス(親ボーンも基本姿勢も異なる)になっているため、それぞれに独自の6個のつまみがあります。一方を調整しても他方には影響しません。
# ===== 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のテストクライアントを再接続して、次の参加で再構築されたパックを受け取らせてください。持ち物の見た目が正しくなるまで繰り返します。
デバッグログ
2種類のデバッグ出力が利用できます:
- バックエンド:
config.ymlでbedrockConverterDebug: trueにすると、コンバーターからアイテム単位/アタッチャブル単位/マッピング単位のログ行が有効になります。特定のアイテムがBedrockパックに入らなかった理由を知りたいときに便利です。これはverboseLoggingとは別物です。verboseLoggingはBedrockパイプラインではなくパックのマージとホスティングを対象とします — 変換の問題を追いたいときはbedrockConverterDebugを使ってください。 - プロキシ(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.jsonとcrossbow.jsonを含む)は、1つのパックに完全に勝たせるのではなく、パックをまたいでマージされます。overrides配列のみが結合され(オーバーライドキーで重複排除)、オーバーライド以外のフィールドは引き続き優先度の高いパックが勝ちます。特別扱いされるファイルは1つもありません。 - 参照されているテクスチャやモデルファイルをコンバーターが解決できない場合、そのリーフはスキップされ、残りのパイプラインはそのまま継続します。詳細な解決トレースが必要なら
bedrockConverterDebugを有効にしてください。アイテムに有効なカスタムテクスチャが1つも残らなかった場合や、参照されたモデルJSONを解析できなかった場合には、通常の警告が出力されます。 - 不正なアイテム定義はこれとは別のケースで、現在はサイクル全体にとって致命的です。解析できないJSONがあると、静かに不完全なパックを生成するのではなく、
Bedrock conversion failed: ...とともに変換全体が中断されます。以前は「だいたい」変換できていたパックが、変換できなかったことをきちんと知らせるようになりました。 - バナーとレッドストーンのベースアイテムはスキップされます。 ベースが16色の染色バナーのいずれか、または
minecraft:redstoneであるカスタムアイテムには、Geyserのカスタムアイテムマッピングが付与されません。Geyserがそれらのベースから不正なブロックプレーサーを導出してしまうためです。Bedrockではバニラのアイコンが表示されます。この状況が発生した場合、コンソールが該当するアイテムを列挙します。 - 変換は協調的にキャンセル可能です。途中で
/rspm reloadやシャットダウンが発生しても、書きかけの出力を残さずクリーンに中断します。Geyserのマッピングファイルはパックのzipが成功した後にのみ公開されるため、新しいパックと古いマッピングの組み合わせが生じることはありません。 - マージされたパックに変換可能なアイテムマッピングも許可されたエンティティバンドルのファイルも含まれていない場合、Bedrockパックは一切生成されず、前回実行の出力も削除されます。エンティティのみのパックは有効であり、アイテムマッピングがゼロでも生成されます。
パックサイズの最適化
Bedrockパックを公開する前に、RSPMは同じ拡張子を持つバイト単位で同一のテクスチャファイルを重複排除し、JSON内のテクスチャ参照のうち完全一致するものを残されたファイルへ書き換えます。参照が曖昧な場合、より大きな文字列に埋め込まれている場合、あるいは不正/不透明なJSONに含まれる場合は、意図的にエイリアスを残します。これにより、最適化がリソース参照を静かに壊すことはありません。