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 的路由判定
轉換器會為每個葉節點模型決定要走兩條管線中的哪一條。以 minecraft:item/generated 或 minecraft:builtin/generated 為根的模型會留在扁平路徑。對於其他所有父模型鏈,只有當模型合併後帶有非空的 elements 陣列時,它才會走 3D 管線;沒有幾何的模型即為 2D 貼圖。
- 扁平 — 模型的
layer0材質會直接複製到textures/items/<hash>.png並註冊為 Geyser 圖示。在 Bedrock 上,該物品在物品欄與手持時會顯示正確的 2D 貼圖,與 Java 的渲染方式完全一致。 - 3D — 轉換器會拼接材質圖集、將 Java 立方體轉換為 Bedrock 幾何、產生手持/頭部動畫、以軟體渲染出 64×64 的物品欄圖示,並為每組
(模型 × 基礎物品 × 謂詞形狀)對應寫出一個附掛物。
為什麼幾何檢查很重要:一個扁平的手持工具(父模型為 minecraft:item/handheld、只有 layer0 材質且沒有 elements)仍然是 2D 貼圖。較早的版本會把扁平的手持物品推進 3D 管線,導致它們在幾何步驟失敗,並在 Bedrock 上消失或退回為原版基礎物品圖示。這對 ItemsAdder 資源包影響尤其明顯,因為它們提供大量扁平的手持物品。由於 elements 是從合併後的父模型鏈讀取,因此非產生型、但從父模型繼承幾何的模型仍會被路由到 3D。
每組 (模型 × 基礎物品 × 謂詞形狀) 對應都會產生唯一的 Bedrock 識別碼,因此將同一把劍模型註冊到多個基礎物品或謂詞分支時,在 Geyser 端不會發生衝突。產生的檔名是簡短的內容雜湊而非可讀名稱,因為完整的「命名空間+路徑」名稱經常超出 Geyser 的 80 字元資源包路徑長度限制。
1.21.4 之前的舊版資源包
仍使用舊格式 assets/minecraft/models/item/*.json + overrides[].predicate.custom_model_data 的資源包也會被納入,並合成為現代的 range-dispatch 形式。這是盡力而為的處理:主控台會記錄有多少物品使用了舊格式,因為它們在 Bedrock 上經常無法正確渲染。真正的解法是把來源資源包遷移到 1.21.4+ 的物品定義格式。
手工撰寫的 Bedrock 實體套組
外掛可以把原生的 Bedrock 實體資產放在其 Java 資源包的 assets/<namespace>/rspm_bedrock_pack/ 之下,直接隨包提供。RSPM 會將那些檔案原樣複製到產生的 Bedrock 資源包中。只有與實體相關的目錄會被接受(entity、models/entity、animations、animation_controllers、render_controllers、materials、textures/entity),因此提供內容的外掛無法覆蓋資源包的 manifest 或圖示圖集。過長的路徑會自動縮短,並同步改寫 JSON 中的交叉參照,讓幾何與材質參照仍能正確解析。兩個命名空間對同一個目的地寫入不同位元組會被視為硬性錯誤,而非靜默覆寫。
這正是實現真正自訂 Bedrock 實體的機制——請參閱 Geyser 擴充功能與自訂實體。即使某個資源包只含實體套組、完全沒有物品對應,仍會被發佈。
當存在並列的 assets/<namespace>/equipment/<material>.json 時,會偵測到自訂盔甲組。轉換器會串接一個盔甲附掛物,結合原版盔甲幾何與 Java 材質作為可見圖層,因此 Bedrock 玩家穿戴該物品時可看到正確的盔甲材質。
Bedrock 資源包的 manifest header / module UUID 是依外掛版本字串以確定性方式衍生(種子為 rspm_bedrock_header:<pluginVersion> 與 rspm_bedrock_module:<pluginVersion>),因此在同一外掛版本的多次重建之間保持穩定,只有在外掛版本變更時才會改變。可見的 header 名稱固定為 ResourcePackManager Bedrock Pack;它不是 UUID 的一部分。版本三元組會在每次建置時依一個 cache-bust token 遞增,該 token 衍生自暫存 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相容性。它會在每個後端的輸出變更時下載,並等待 inbox 穩定。 - 代理外掛將每個後端的 Bedrock 資源包合併為單一的網路級資源包,再透過代理的 Geyser 提供給 Bedrock 用戶端。
- 若代理無法直接連到後端的 HTTP 連接埠(在共享 / 代管託管環境中常見,相鄰埠通常被防火牆擋掉),後端會將檔案推送到 magmaguy.com 中繼端點,代理則從那裡取得。
設定方式請參閱代理網路。代理端的合併是自動進行的,沒有啟用開關。代理設定只有兩個項目:network-http-offset-v2,即在後端端點通報可用之前所使用的後備連接埠偏移量;以及 geyser-extension-auto-install,即 geyserExtensionAutoInstall 的代理端對應設定。
輸出檔案
成功混合之後,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 透過一個父 bone 來渲染手持物品,而該 bone 的靜止姿勢與 Java 的第一人稱/第三人稱變換不同,因此演算法式轉換必須在 Java 模型 display 變換所指定的內容之上再套用一個基礎偏移。預設偏移適用於一般的右手 Java 模型,但特殊情況可能需要調整。
第一人稱與第三人稱是兩個完全獨立的 Bedrock 渲染流程(不同的父 bone、不同的靜止姿勢),因此各自有獨立的六個調整項。調整其中一邊不會影響另一邊。
# ===== 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 測試用戶端重新連線,好讓它下次加入時收到重建後的資源包。反覆迭代直到手持物品看起來正確為止。
除錯日誌
有兩個除錯介面可用:
- 後端:在
config.yml中設定bedrockConverterDebug: true會開啟轉換器的逐物品、逐附掛物、逐對應日誌行。當你需要了解某個特定物品為何沒進入 Bedrock 資源包時相當有用。這與verboseLogging是分開的——後者涵蓋的是資源包合併與託管,而非 Bedrock 管線;遇到轉換問題時你要用的是bedrockConverterDebug。 - 代理(Velocity 與 BungeeCord):
/rspm debug bedrock on會切換代理GeyserBinder發出的[RSPM-BedrockDebug]日誌串流。當 Bedrock 玩家加入代理但看不到資源包時相當有用。此設定會在代理重啟時重置為關閉,因此不會意外被遺留為開啟。
限制與已知行為
- 3D 物品欄圖示是透過 Java 模型的
display.gui變換以軟體渲染。渲染結果合理但並非像素級完美;若圖示看起來不對,最常見的原因是模型參照的材質檔案缺失或檔名錯誤。 - 用作物品圖示的 flipbook 材質會被裁切為第 0 幀——Bedrock 的
item_texture.json不支援動畫圖示,只有透過flipbook_textures.json的方塊/地形材質才支援動畫。 - 附掛物幾何格式版本固定為
1.21.0;若你的安裝無法解析,請更新 Geyser。 - 舊版原版物品模型覆寫檔(
assets/minecraft/models/item/下的任何檔案,包括shield.json與crossbow.json)會跨資源包合併,而非讓單一資源包完全勝出:只有overrides陣列會被合併(並依覆寫鍵去除重複),非覆寫欄位則維持「最高優先級勝出」。沒有任何檔案會被挑出來特殊處理。 - 若轉換器無法解析某個被參照的材質或模型檔,該葉節點會被略過,管線其餘部分則繼續執行。啟用
bedrockConverterDebug可取得詳細的解析追蹤。當某個物品最終完全沒有有效的自訂材質,或某個被參照的模型 JSON 無法解析時,會發出一般等級的警告。 - 格式錯誤的物品定義則屬於另一種情況,現在對整個週期是致命的:無法解析的 JSON 會以
Bedrock conversion failed: ...中止整次轉換,而不會安靜地產出一個不完整的資源包。過去「大致上」能轉換成功的資源包,現在會明確告訴你它沒有成功。 - 旗幟與紅石基礎物品會被略過。 基礎物品為 16 種染色旗幟之一或
minecraft:redstone的自訂物品不會取得 Geyser 自訂物品對應,因為 Geyser 會從那些基礎物品衍生出無效的方塊放置器。Bedrock 上會顯示原版圖示。發生時主控台會列出受影響的物品。 - 轉換是可協同取消的:中途執行
/rspm reload或關機會乾淨地中止,而不會留下寫到一半的輸出。Geyser 對應檔只有在資源包 zip 成功之後才會發佈,因此你絕不會拿到「新資源包搭配過時對應」的組合。 - 當合併後的資源包既不含可轉換的物品對應,也不含允許的實體套組檔案時,不會輸出任何 Bedrock 資源包,且任何前次執行的輸出都會被刪除。只含實體的資源包仍屬有效,即使物品對應數為零也會被輸出。
資源包大小最佳化
在發佈 Bedrock 資源包之前,RSPM 會去除副檔名相同且位元組完全一致的重複材質檔案,並將精確的 JSON 材質參照改寫為指向保留下來的檔案。當某個參照有歧義、內嵌在較長的字串中,或出現在格式錯誤/不透明的 JSON 內時,它會刻意保留別名,以免最佳化悄悄破壞資源參照。