MagmaCore 開發者指南
產生的 Java 參考提供可搜尋的類別、方法與簽章,並記錄各模組的原始碼版本和提交。
MagmaCore 是透過 shade 打包進使用方插件的函式庫。它不是獨立伺服器插件,不應在 depend 中將其當作玩家能安裝的 MagmaCore 插件 JAR。
相依與打包
目前開發座標為 com.magmaguy:MagmaCore:2.2.0-SNAPSHOT。它發布在 MagmaGuy 的 releases 儲存庫,而不是快照儲存庫;快照儲存庫只存放較舊的 1.x 快照。快照內容可能改變而版本字串不變,且已發布的建置不會隨每次插件發行而更新,因此可能比目前插件中 shade 的 MagmaCore 還舊。2026 年 10 月 5 日發布的建置已包含下文的免重啟更新與對局 API。若要針對尚未發布的較新變更編譯,請從原始碼建置 MagmaCore 並發布到 Maven Local,做法見函式庫變更後重建使用方。需要可重現建置時,請記錄實際解析的產物。
repositories {
maven("https://repo.magmaguy.com/releases")
}
dependencies {
implementation("com.magmaguy:MagmaCore:2.2.0-SNAPSHOT")
}
<repositories>
<repository>
<id>magmaguy-releases</id>
<url>https://repo.magmaguy.com/releases</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.magmaguy</groupId>
<artifactId>MagmaCore</artifactId>
<version>2.2.0-SNAPSHOT</version>
</dependency>
</dependencies>
這些宣告用於解析相依。還需設定 shading 工作,將其包含在最終插件 JAR 中。遵循整合需求相同的現有使用方的重定位規則,改變套件名稱時檢查以字串進行的反射查找。發行包會將 org.luaj、org.reflections 和 javassist 重定位到 com.magmaguy.shaded,並排除編譯時期使用的 javax.annotation 類別。
每個插件都可以載入自己的函式庫副本。不同插件類別載入器中的同名 Java 類別是不同型別。請使用明確的跨插件約定,例如 EliteMobs Lua 技能服務與位置登錄表介接器。不要將其他插件私有的 MagmaCore 物件強制轉型為你的副本中的型別。
模組與職責
| 模組 | 職責 |
|---|---|
core | 插件生命週期、設定、命令、選單、對局、位置查詢、Lua 腳本、Nightbreak 內容和共用工具 |
nms:core | NMSManager、NMSAdapter 及不依賴版本的 EasyMinecraftGoals 介面 |
nms:v* | NMS 約定的伺服器版本實作 |
dist | 包含核心與啟用介接器的 shaded 發行包 |
共用附魔、物品操作、帳號處理、設定選單、目錄與更新屬於核心服務。為使用方加入行為時,重用負責該功能的元件。
插件生命週期
最小核心生命週期遵循現有使用方的模式:
package example;
import com.magmaguy.magmacore.MagmaCore;
import org.bukkit.plugin.java.JavaPlugin;
public final class CoreConsumer extends JavaPlugin {
@Override
public void onLoad() {
MagmaCore.createInstance(this);
}
@Override
public void onEnable() {
MagmaCore.onEnable(this);
}
@Override
public void onDisable() {
MagmaCore.shutdown(this);
}
}
這種初始化不只是取得一個工具物件。它會初始化帳號處理、共用命令、監聽器與暫時方塊支援。多載方法 createInstance(plugin, NightbreakPluginSpec) 用於提供插件專屬的共用命令文案。
優先使用明確接收所屬插件的方法。getInstance() 指向目前載入函式庫副本的單例,請求方插件在實例建立時確定。不要用它推斷每個使用方的擁有權。
shutdown(plugin) 清除該插件的下載器、內容更新器、初始化與更新服務註冊,之後也會關閉目前載入副本的共用執行環境。它不只是刪除一筆註冊記錄。請在你的插件關閉時,對自己嵌入的函式庫呼叫;不要為了重設整合而關閉其他插件的函式庫。
在 onLoad 中呼叫 createInstance,使插件的設定封存擁有者能在其他插件為其匯入內容之前註冊。封存透過目標插件自己的 shaded 實作執行;不要使用你的 MagmaCore 副本解釋其他插件的淘汰規則。
分階段啟動可使用 startInitialization,傳入非同步工作、同步工作、成功與失敗回呼。它會在呼叫非同步初始化之前封存符合規則的過時設定。Bukkit 世界和實體操作應放在同步階段。耗時非同步工作應在階段之間檢查 isShutdownRequested(plugin)。getInitializationState 和 isPluginReady 提供初始化管理器狀態。
免重啟插件更新
NightbreakPluginBootstrap.registerStandardCommands 會將 applypluginupdate 與其他共用子命令一併註冊。它在同一個伺服器工作階段中停用你的插件、替換其 JAR 並再次啟用,以換上已下載的更新;因此 onDisable 必須取消工作、取消註冊監聽器,並釋放所有會讓舊類別載入器存活的參照。主類別位於 com.magmaguy. 之下、且相依或軟相依於你的插件的已啟用插件,會隨之一起重新載入。只要有其他任何插件相依於你的插件,替換就會拒絕執行並要求重新啟動。伺服器管理員端的說明見不重新啟動即套用更新。
若插件有部分無法原地重新載入,請在開始檢查更新之前呼叫 NightbreakPluginHotSwap.requireRestartForUpdates(plugin, reason),並將 false 作為 NightbreakPluginUpdater.setAutoDownloadConfigDefault 的第二個參數傳入,讓 config.yml 不提供 applyPluginUpdatesWithoutRestart。當它所相依的插件被替換時,該插件仍會以目前的 JAR 重新載入。NightbreakPluginUpdater.onPluginUpdateDownloaded(plugin, listener) 會在通過驗證的更新進入 update 資料夾後,於下載執行緒上執行監聽器。
NMS 與封包實體
僅在插件需要時,透過 com.magmaguy.easyminecraftgoals 中的 NMSManager.initializeAdapter(plugin) 初始化 NMS。使用依賴介接器的功能前,檢查 NMSManager.isEnabled()。初始化可能失敗,也可能發現伺服器版本不受支援。
發行包包含以下介接器系列:
| 介接器 | Minecraft 版本 |
|---|---|
v1_21_R3 | 1.21.4 |
v1_21_R4 | 1.21.5 |
v1_21_R5 | 1.21.6, 1.21.7, 1.21.8 |
v1_21_R6 | 1.21.9, 1.21.10 |
v1_21_R7_spigot, v1_21_R7_paper | 1.21.11,Spigot 與 Paper 分別實作 |
v26 | 26.1 及目前 26.x 介接器系列 |
選中介接器並不保證所有未來伺服器版本相容。NMSManager 中的執行時選擇器決定目前伺服器能否載入介接器。早於 1.21.4 的版本不在目前範圍內。
EasyMinecraftGoals 管理僅透過封包存在的實體、可見性與互動路由,以及移動和尋路工具。它們不是普通世界實體。應透過所屬 API 管理,並在介接器仍可用時清理你的使用方建立的物件。
位置與保護查詢
com.magmaguy.magmacore.location.LocationQueryRegistry 提供地牢及區域保護查詢,包括 isInAnyDungeon、isInAnyProtectedRegion 和 canBuild。
透過 registerDungeonLocator 或 registerProtectionProvider 註冊自訂提供方;所屬插件停用時取消註冊同一個提供方。登錄表包含現有插件介接器,並能發現跨插件地牢提供方,而不要求使用方共用一個 MagmaCore 類別載入器。
請選擇符合操作的查詢。位於地牢外不等於擁有該位置的建造權限。涉及 Bukkit 或保護插件的查詢應在伺服器執行緒執行。
對局
對局生命週期位於 com.magmaguy.magmacore.match。啟用時呼叫一次 MatchCore.enable(plugin),然後繼承 Match,將由 MatchSettings.builder() 建立的 MatchSettings 傳入其建構子,並在子類別建構完成後呼叫 open()。遊戲邏輯放在受保護的掛鉤中,例如 onJoin、onStart、onDeath 與 onLeave。MagmaCore.shutdown(plugin) 會銷毀該插件剩餘的對局。
核心本身不觸發任何 Bukkit 事件。它會呼叫設定中指定的 MatchApi,由你的插件決定要公開哪些事件。可取消的回呼可透過傳回 false 或拋出例外來否決該步驟。每個插件的副本只追蹤自己的對局;玩家中繼資料標記 magmacore_match 會告知其他副本該玩家已在某個對局中。
MatchSettings.builder().permission(...) 設定玩家加入所需的權限。覆寫 hasJoinPermission(player) 可針對個別玩家決定,例如讓工作人員不需該權限也能加入。因死亡而離開的參與者(LeaveReason.DIED)會在被移出之前先治療至滿血,因此即使最大生命值加成在移出途中被移除,生命值仍會維持全滿的比例。對局期間以其他方式離開的玩家會保留他們所受的傷害,而對局結束時仍在其中的玩家則會被治療。這兩項行為都是在 2026 年 10 月 5 日發布的建置版本之後才加入的。
com.magmaguy.magmacore.instance 中較舊的對局類別(包括 MatchInstance)已被移除。InstanceProtector 仍保留在該處,並由 MagmaCore.enableWorldProtections(plugin) 註冊。
Lua Mind 宿主
MagmaCore 為宿主插件編譯以 Lua 編寫的 Mind 程式。腳本格式請見行為程式。宿主會建立自己的 LuaMindModuleRegistry,以 openOwner(namespace) 為它的命名空間開啟一個擁有者,用擁有者的 registerModule 註冊模組,並從擁有者的 validateProgram 取得 LuaMindDefinition。對該定義的每次 instantiate 呼叫,都會為一個實體建立一個全新、擁有自己 Lua 環境的程式。下列鉤子比 2026 年 10 月 5 日發布的建置版本更新。
- 檢查模組。
LuaMindModuleRegistry.inspectModule(sourceName, source)會讀取模組的 id、revision、依賴項和settings預設值,而不註冊它。LuaMindModuleDescriptor.settings()保存Double、Boolean、String或List<String>值。MagmaCore 不會把設定交給腳本。想要每隻生物各自數值的宿主,會把自己的值合併到這些預設值之上並對外公開,就像 FreeMinecraftModels 寵物以c.settings所做的那樣。 - 擴充回呼上下文。
LuaMindDefinition.instantiate(LuaMindContextExtension)會把你的欄位加入每個回呼的上下文表。extend(table, context, contribution)會在 Lua 看到該表之前收到它、該回呼的MindContext,以及宣告該回呼的模組的 id(或程式自己的 id)。它在伺服器執行緒上、在回呼的執行預算之內執行,因此它的 CPU 時間會計入程式的cpu_micros,而例外會使該回呼失敗。請用rawset或LuaTableSupport.lazyField加入欄位,後者會為所有其他鍵保留該表既有的__index。不要替換該表的 metatable 或它的__index,因為內建區段是透過它們讀取的,也不要覆寫tick、generation、entity、memory、perception、actuator或actions。在extend中讀取內建區段,會為該回呼建立它。當擴充保存每個實體的狀態時,請為每次instantiate呼叫傳入各自獨立的擴充。 - 探測間隔。 Java 行為可以覆寫
MindBehavior.probeInterval()(相當於 Lua 的probe_interval),讓它在停止期間每 N 個 tick 詢問一次canStart。其值必須介於 1 到MindBehavior.MAX_PROBE_INTERVAL(200)之間;MindProgram會拒絕其他值。預設的 1 表示每個 tick 都詢問。MindSensor會在其本體第一次被 tick 的那個 tick 感測,之後每intervalTicks()個 tick 感測一次,每個實體有各自的相位。 - 飛行。
MindActuator.steerFlight(Vector)在該建置中就已存在,它會讓FLYING本體以該速度飛行一個 tick,並需要 MOVE 和 LOOK 租約。新增的是它的上限和 Lua 的steer_flight:MindActuator.MAX_FLIGHT_SPEED為每 tick 4 個方塊,更快的速度會被縮減到該值。RouteFlight也把它的速度上限設在那裡,因此設定為超過每秒 80 個方塊的路線,會以 80 飛行。
函式庫變更後重建使用方
使用 JDK 21,並透過 ./gradlew publishToMavenLocal 將 MagmaCore 發布到 Maven Local;Windows 下使用 .\gradlew.bat publishToMavenLocal。確認使用方解析該儲存庫及所需版本,再重建其 shaded JAR。替換 Maven Local 中的函式庫不會更新已建置的插件。
已安裝插件的 API 見開發者索引。這類整合通常使用 provided 或 compileOnly;MagmaCore 的嵌入式函式庫打包約定不同。