Community程式設計與開發github.com

qad3n/modport

將 Minecraft Java 版模組(任何版本、jar 或原始碼)移植到 b1.7.3_rewrite 模組加載器,產生一個 .b173mod 檔案,可在用戶端和伺服器端執行。當使用者說 /modport、/port、「移植此模組」或交出模組 jar 時使用。

modport 是什麼?

此技能專為將任何版本(推薦 1.7.10、1.12、1.21)的 Minecraft Java 模組移植到 b1.7.3_rewrite 模組加載器而設計。它會從原始 jar 或原始碼開始,將模組重新實作為 Rust 驅動的 WebAssembly 客體,使用 b173_api SDK。目標是在不取代任何原版畫面的情況下,複製外觀、感覺和遊戲玩法(額外的 UI 會以可切換疊加層的形式存在)。 工作流程包括自動化設定(new_port.sh 會解編譯、提取資產、初始化 git)、庫存分析(inventory.txt)、基於 SDK 查詢(api.sh)的逐模組實作,以及完整的測試循環(使用 deploy、modtest.sh 和 console 指令)。它嚴格支援兩個使用者模式:使用者模式(預設)將加載器/SDK 變更保留為未提交的本機變更,並記錄在 LOADER_CHANGES.md 中;維護者模式則允許提交和推送此類變更。 此技能特別處理資料形狀(基於名稱的身分、具有資料元件的堆疊資料、區塊屬性)、世界生成、指令,以及透過主機呼叫(HostCall)、SDK 包裝器和用戶端掛鉤(client-side hooks)來擴充加載器。它會避免常見陷阱,例如不向現有的 ABI 結構體新增欄位(會破壞解碼)、在使用 modtest.sh 共用測試伺服器時不相互干擾,以及確保在加載器變更後執行 deploy --game。它支援所有平台(透過 Bash 工具在 Windows 的 Git Bash 上執行)。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/qad3n/b1.7.3-modport/tree/HEAD/skills/modport

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

將模組移植到 b1.7.3_rewrite 加載器

Java 模組無法執行。移植是使用解編譯後的模組作為規格的 Rust 重寫(wasm 客體,b173_api SDK)。 目標:在 b1.7.3 內擁有相同的外觀、感覺和遊戲玩法,從單一檔案在用戶端和伺服器端 mods/ 目錄中生效。當外觀和遊戲玩法不變時,可自由修正原始碼錯誤並進行最佳化。絕不取代原版畫面:額外 UI 是可切換的疊加層。

此檔案是完整的地圖。請勿閱讀加載器設計或進度文件、指南或完整的 SDK 檔案來定位方向。請使用這些工具,然後僅開啟該步驟所需的那一個範例檔案。

工作區

路徑相對於工作區根目錄,即包含 b1.7.3_rewrite/、ports/ 和工具集倉庫 b1.7.3_modport/ 的資料夾。工具集的 install.sh 會將其工具連結到 tools/modport/(下文以 T/ 表示),並將此技能連結到 .claude/skills/modport;從移植資料夾中,T/ 是 ../../tools/modport/。在 b1.7.3_modport/ 中修正或擴充工具,絕不在移植資料夾內進行。在新機器上,或當工具因缺少依賴項而失敗時,執行 T/doctor.sh:它會列印出修正每個間隙的指令。所有工具都是 bash 腳本:在 Windows 上,它們在 Git Bash(Claude Code 在 Windows 上的 bash 工具)中執行,並自行處理 .exe、.py 和路徑。透過 T/py.sh 呼叫 Python 工具,絕不直接使用 python3。

模式

每個工作階段檢查一次:在工作區根目錄中執行 test -f .modport-maintainer。

  • 維護者模式(標記存在):加載器、SDK 和工具集倉庫是此使用者的自有倉庫。僅在使用者要求時,才按照下列步驟對它們進行提交和推送。
  • 使用者模式(無標記,預設):加載器、SDK 和工具集倉庫屬於其上游作者。
    • 加載器和 SDK 的擴充保留在本機工作樹中。絕不將它們提交到那些倉庫,絕不推送到它們的遠端,絕不執行 gh pr create、gh issue create 或任何其他對它們的 gh 寫入操作,即使被要求「分享」或「上游」變更。請告訴使用者自行處理。
    • 在 ports/<modid>/LOADER_CHANGES.md 中記錄每次對加載器或 SDK 的變更:它新增了什麼、原因、哪些檔案。
    • 告知使用者,需要本機加載器變更的移植項目僅在其修補後的加載器上執行,無法在原始加載器上執行。
    • 移植資料夾是使用者自己的倉庫:當被要求時提交,僅推送到使用者設定的遠端。
    • 絕不建立標記檔案。

工具

工具使用時機輸出
T/new_port.sh <modid> <jar> [name]開始移植。寫入清單檔案、初始化 git、將內容解編譯到 reference/src(使用 Vineflower,首次使用時會下載並驗證)、執行庫存盤點ports/<modid>/
T/inventory.sh <src>列出模組註冊的內容:方塊、物品和實體及其類別、瓷磚、模型、渲染器、GUI、世界生成、事件大型模組約 15 KB,保留在 reference/inventory.txt 中
T/api.sh在根據 SDK 編寫程式碼之前。sdk <file>(world、register、screen、behavior、events、terrain、config、services)、spec <Struct>、enum <Name>(HostCall、EntityField、ModelOp)、templates、events、console、hooks每個簽名一行,附帶 SDK 行號
T/py.sh extract_assets.py <jar> <modid>從移植資料夾中執行一次。紋理、聲音和語言檔提取到 assets/<modid>,語言鍵對應到 tile.<modid>.x.name、item.<modid>.x.name、<modid>.<key>永不提交
T/py.sh convert_models.py --out src/models/generated.rs <Model.java>... [--arg Model.scale=0.5]模型。ModelBase 建構子(SRG 或 MCP 名稱)轉換為 parts 和 boxes。將呼叫包裝在移植項目的 tools/convert_models.sh 中產生的 Rust 程式碼,禁止手動編輯
T/test.sh deploy ports/<modid> [--game]每個測試週期。建置、停止測試伺服器、單獨安裝模組、啟動伺服器。--game 會先重新建置遊戲和 cargo-b173(在加載器或 SDK 變更後)。當測試伺服器仍在執行時拒絕:可能被另一個工作階段佔用,詢問後再使用 --force伺服器主控台尾部
T/test.sh errors [n]任何失敗後第一件事兩個日誌中的 panic、trap 和 error 行
T/modtest.sh cmd <console line> / log server 80驅動和檢查伺服器僅回覆行
T/modtest.sh client / shot <png>僅視覺檢查。啟動用戶端前詢問使用者:它會在使用者桌面開啟一個視窗遊戲視窗 PNG

主控台(T/modtest.sh cmd loader ...,語法來自 T/api.sh console):gen、map(俯視 PNG)、slice(垂直切片 PNG)、column(在 tp 前檢查:傳送到地形的玩家會窒息)、fill、tp、use、interact、close、entities、summon、slot、tile。使用「Read」工具讀取 PNG。將重複的檢查鏈放入 ports/<modid>/tools/ 中的小型腳本,而不是重新輸入。

工作流程

  1. 設定。 選擇最接近測試版的原始版本(1.7.10 優於 1.12 優於 1.21):其模型、紋理和資料形狀幾乎是 1:1 對應。1.7.10 的 jar 使用 SRG 名稱(func_、field_):從用途理解含義,不要尋找對應。執行 new_port.sh,然後執行 extract_assets.py。將模組模型繼承的原版模型類別複製到 reference/vanilla/ 供轉換器使用。特定的資產額外項目(來自 3D 渲染器的精靈圖)放入移植項目自己的 tools/ 腳本中。
  2. 規劃。 將 reference/inventory.txt 轉換為 PORT_STATUS.md 中的待辦事項行,按依賴順序排列:方塊和物品、配方、世界生成和維度、實體、機器與 GUI、結構、Boss、玩家系統、額外欄位、物品行為、聲音與粒子、設定。里程碑以部署和主控台檢查結束。
  3. 逐模組移植。 閱讀模組的類別,使用 api.sh 檢查 SDK,從範例複製模式。在 PORT_STATUS.md 中引用原始類別,而不是在程式碼註解中。
  4. 僅在 api.sh 顯示無任何方法時擴充加載器(請參閱下方清單)。
  5. 每個模組後進行測試,使用 deploy、cmd、errors。將錯誤清單保留在 PORT_STATUS.md 中,而不是在一個問題上循環;最後修復清單。
  6. 完成。 更新 PORT_STATUS.md。在移植項目中執行 cargo +nightly fmt,並在 b1.7.3_rewrite 中執行 cargo clippy。僅在被要求時提交:移植項目包含 Rust 原始碼、工具和清單,絕不包含資產、reference/ 或 AI 檔案。ports/ 可以是每個移植項目一個 git 倉庫,或是一個資料夾一個模組的單一倉庫;new_port.sh 會自動偵測。在使用者模式下,在最終報告中列出移植項目需要的本機加載器變更(來自 LOADER_CHANGES.md)。

範例

SDK 範例,始終存在:b1.7.3_rewrite/vendor/b1.7.3-modding-sdk/examples/ 包含 testmod(所有 API 模組在一個檔案中)、ruby(僅資料內容)、energy、energy_api、machines(模組間的服務)。

當工作區中有完成的移植項目時,它是最快的地圖。Aether 移植項目(ports/aether/src):

需求檔案
方塊表、範本、行為blocks.rs(每種一個 const 行陣列)
物品、工具、盔甲、食物、配方items.rs、tools.rs、gear.rs、recipes.rs
設定選項config.rs(移植每個生成率骰子,缺少的會淹沒世界)
實體註冊和輔助函數entities/mod.rs
被動生物與坐騎、敵對、飛行器、投射物entities/phyg.rs + mount.rs、cockatrice.rs、zephyr.rs、projectile.rs
用戶端可見的實體狀態entities/swet.rs、entities/moa.rs (setSynced/synced)
模型與動畫models/mod.rs(part、cuboid、Program;複製到新移植項目)
Boss、Boss 血條 HUD、對話畫面entities/bosses/mod.rs、valkyrie_queen.rs(transparent() 畫面加伺服器端通道)
附帶 GUI 和瓷磚資料的機器machines.rs(ScreenBuilder、#[tile_behavior])
額外裝備欄、渲染圖層accessories.rs(screens().overlay("GuiInventory", ..)、playerLayer)
本機玩家移動player.rs(用戶端在 TickPost 中,伺服器端在由實體 ID 索引的 thread_local 映射中)
維度、地形、裝飾world/mod.rs、world/terrain.rs、world/decorate.rs
結構world/dungeons/mod.rs、writer.rs(terrain::structure::candidates、裁剪到 StructureBox::populated、將 256 高高度壓縮為 128)
傳送門和旅行portal.rs

始終適用的形狀:渲染器 GL 呼叫變成 Program 操作(push、translate、rotate、scale、texture、blend、lighting)在實體的 pose 中;onLivingUpdate/updateEntityActionState 移至 onAi(取代模板 AI)或 onTick;terrain::Random 和噪音移植保持種子相同;修改世界前檢查 isAuthority()(單人遊戲會將封包迴送,同一程式碼在兩端);驗證每個伺服器端封包;透過 translate("<modid>.gui.…") 聊天;聲音使用 <modid>.<path.with.dots>;紋理使用 <modid>:<path>。

資料形狀(加載器 API 1.1,ABI 3)。身分始終由名稱識別,絕不使用數值 ID:

  • 方塊變體和朝向。 原始 metadata 或方塊狀態變成命名狀態:ctx.blocks().states(name, BlockStatesSpec) 或 data/<modid>/states/<block>.toml。

    • 按原始 metadata 的順序列出每個屬性的值,以便 ctx.meta() 程式碼繼續運作。
    • 超過 16 個狀態的方塊會從加載器獲得額外的隱藏 ID。僅透過 world.blockState/setBlockState 或 ctx.state()/setState() 讀寫此類方塊。
    • 每個狀態的紋理放在 variants 中。
  • 每個堆疊的資料。 物品 NBT 和 capabilities 變成資料組件:使用 StackRef 的 stackComponent/setStackComponent。

    • 一個模組僅寫入 <modid>:* 組件。
    • 具有不同組件的堆疊永不疊加。
    • 耐久度維持不變。使用每種變體一個物品,而不是使用耐久度子類型。
  • 模組不擁有的東西上的資料。 實體、玩家、瓷磚、區塊和世界的 NBT 或 capabilities 變成每個模組的插槽:

    • 實體:entity.setData 或 setSynced
    • 玩家:player.setData(key, ..)
    • 瓷磚實體:world.setTileAttachment
    • 區塊:world.setChunkAttachment
    • 世界:setWorldData

    每個插槽由模組 ID 作為鍵,因此兩個模組永不衝突。

  • 對原版或其他模組內容的編輯。 屬性編輯(硬度、亮度、可燃性、工具)變成 ctx.blocks().modify(BlockModifySpec) 或 data/<modid>/modify/blocks/*.toml。生成列表編輯變成 modifySpawns 或 modify/spawns/*.toml。工具類別的挖掘速度來自 minecraft:mineable/<pickaxe|axe|shovel> 標籤。衝突的編輯會在模組加載器畫面中顯示。絕不為屬性變更而取代整個原版方塊。

  • 世界生成和指令。

    • 每個世界生成特性使用唯一名稱。名稱為其隨機數播種,因此其他模組永遠不會移動它。
    • 指令回覆 /<modid>:<name>。簡短形式 /<name> 會分配給第一個註冊它的模組。

擴充加載器

僅限通用特性,絕非一次性模組 hack。以下路徑在 b1.7.3_rewrite/ 內部。依序的接觸點:

  1. 協定:在 vendor/b1.7.3-modding-sdk/mod_protocol/src/abi.rs 中的 HostCall、GuestCall、GuestReply 或 EntityField 結尾附加變體;在 spec.rs 中新增規格欄位作為 Option 或 Default 類型(spec 結構體使用 #[serde(default)],因此舊模組仍可載入)。已發布的契約永不變更:變更的契約會獲得新版本。
  2. 主機:在 crates/modloader/src/host/world.rs(執行時期呼叫)或 host/register.rs(註冊階段)中的 match 分支;較大的系統放在它們自己的 crates/modloader/src/<system>.rs 或 extensions.rs 中。新的模板是 crates/modloader/src/entities.rs(ENTITY_TEMPLATES)或 content/templates.rs(BLOCK_TEMPLATES)中的行。
  3. SDK 包裝器放在 b173_api/src/{world,register,screen}.rs 中其同類旁邊,如果模組到處使用則放在 prelude 中。
  4. 用戶端放在 crates/client/src/modded/ 中。原版程式碼透過帶有 // rewrite: 註解的一行掛鉤呼叫新行為,該掛鉤在 crates/modloader/hooks.toml 中列出並帶有版本。
  5. 開發者主控台工具在 crates/modloader/src/devtools.rs 中(新增到 USAGE)。
  6. cargo build 和 cargo clippy,然後 T/test.sh deploy ports/<modid> --game。在工作區儲存加載器註記的地方記錄新增。維護者模式:僅在使用者要求時,在 SDK 子模組中提交 SDK 變更,然後在 rewrite 中更新版本。使用者模式:那裡不提交任何內容,變更記錄在 LOADER_CHANGES.md 中。

範例鏈:World::lightning:HostCall::Lightning (abi.rs) 到其在 host/world.rs 中的分支,再到 b173_api/src/world.rs 中的包裝器。

已知陷阱

  • HostCall、HostReply 和 spec 結構體是 postcard 編碼的。絕不向現有結構體新增欄位:ABI 2 客體將無法解碼。新資料需要新的變體或新的結構體。

  • T/modtest.sh 驅動一個共享的測試伺服器和用戶端(b1.7.3_rewrite/target/modtest,伺服器在其 server/ 中)。未經使用者詢問,絕不停止、重置或接管另一個工作階段啟動的伺服器。

  • cargo b173 build 已經執行 wasm 建置;沒有單獨的 cargo build 步驟。

  • 加載器或 SDK 變更後未執行 deploy --game:伺服器仍然執行沒有新主機呼叫的舊二進位檔。

  • 測試用戶端的視窗失去焦點並開啟暫停選單;它是測試台,不是移植項目。

相關技能