MagmaCore Lua 腳本引擎
MagmaCore 提供一個共享的 Lua 腳本引擎,供多個 Nightbreak 外掛程式使用。此引擎處理沙盒化、排程、區域管理、世界互動、實體表和玩家 UI -- 所有外掛程式都使用一致的 API。
目前以下外掛程式使用此引擎:
- EliteMobs -- 用於自訂 Boss 的 Lua 能力(如
on_boss_damaged_by_player、on_enter_combat等鉤子) - FreeMinecraftModels -- 用於道具和自訂物品的 Lua 腳本(如
on_right_click、on_left_click、on_equip等鉤子)
本頁面記錄了共享的引擎功能。有關特定外掛程式的鉤子、API 和工作流程,請參閱上方連結的外掛程式頁面。
Lua 簡易入門
如果您完全不熟悉 Lua,以下是為任何 Nightbreak 外掛程式編寫腳本所需的最基本語法。
變數
使用 local 儲存一個值:
local cooldown_key = "fire_burst"
local damage_multiplier = 1.5
local 表示該變數僅屬於此檔案或區塊。
函式
函式是可重複使用的邏輯區塊:
local function warn_player(player)
player:send_message("&cMove!")
end
之後您可以呼叫它:
warn_player(some_player)
if 檢查
當某些事情只在特定情況下發生時使用 if:
if context.player == nil then
return
end
這表示「如果此鉤子沒有玩家,就在此停止」。
nil
nil 表示「沒有值」。它是 Lua 版本的「這裡什麼都沒有」。
您通常會用以下方式檢查 nil:
if context.event ~= nil then
-- do something with the event
end
~= 表示「不等於」。
表
Lua 使用表來處理多種工作:
- 列表
- 帶有命名鍵的物件
- 最終回傳的腳本定義
帶有命名鍵的表範例:
local particle = {
particle = "FLAME",
amount = 1,
speed = 0.05
}
回傳腳本定義
在每個腳本檔案的結尾,您回傳一個表:
return {
api_version = 1,
on_spawn = function(context)
end
}
該回傳的表就是腳本檔案。
註解
使用 -- 為人類編寫備註:
-- This cooldown stops the attack from firing every hit
context.cooldowns:set_local(60, "fire_burst")
Lua 沙盒
所有 Lua 腳本都在沙盒化的 LuaJ 環境中執行。數個可存取檔案系統或 Java 執行環境的全域變數已被移除。沙盒規則在所有使用 MagmaCore 的外掛程式中完全相同。
已移除的全域變數
以下標準 Lua 全域變數已設為 nil,無法使用:
| 已移除 | 原因 |
|---|---|
debug | 公開內部 VM 狀態 |
dofile | 檔案系統存取 |
io | 檔案系統存取 |
load | 任意程式碼載入 |
loadfile | 檔案系統存取 |
luajava | 直接 Java 類別存取 |
module | 模組系統(不需要) |
os | 作業系統存取 |
package | 模組系統(不需要) |
require | 模組系統 / 檔案系統存取 |
可用標準函式庫
Lua 標準函式庫的其他部分正常運作:
| 分類 | 函式 |
|---|---|
| Math | math.abs、math.ceil、math.floor、math.max、math.min、math.random、math.sin、math.cos、math.sqrt、math.pi 以及所有其他 math.* 函式 |
| String | string.byte、string.char、string.find、string.format、string.gsub、string.len、string.lower、string.match、string.rep、string.sub、string.upper 以及所有其他 string.* 函式 |
| Table | table.insert、table.remove、table.sort、table.concat 以及所有其他 table.* 函式 |
| 迭代器 | pairs、ipairs、next |
| 型別 | type、tostring、tonumber、select、unpack |
| 錯誤處理 | pcall、xpcall、error、assert |
| 其他 | print、rawget、rawset、rawequal、rawlen、setmetatable、getmetatable |
os 函式庫不可用os 函式庫已從沙盒中完全移除。如果您需要計時資訊,請使用 context.world:get_time() 取得世界時間,或使用 on_tick / on_game_tick 的刻計數器將時間戳儲存在 context.state 中。
print 會輸出到伺服器主控台,但建議使用 context.log:info(msg) 進行輸出。日誌訊息會加上腳本檔案名稱前綴,更容易追蹤是哪個腳本產生的訊息。
檔案契約
每個 Lua 腳本必須 return 一個表。該表有嚴格的要求。
必要和可選的頂層欄位
| 欄位 | 必要 | 類型 | 備註 |
|---|---|---|---|
api_version | 是 | Number | 目前必須為 1 |
priority | 否 | Number | 執行優先順序。較低的值先執行。預設為 0 |
| 支援的鉤子鍵 | 否 | Function | 必須使用外掛程式支援的確切鉤子名稱之一 |
驗證規則
- 檔案必須回傳一個表。
api_version為必要欄位,目前必須為1。- 如果存在
priority,必須為數值。 - 每個額外的頂層鍵必須是支援的鉤子名稱。
- 每個鉤子鍵必須指向一個函式。
- 未知的頂層鍵會被拒絕。
輔助函式和本地常數應放在最終的 return 之上,而非放在回傳的表內,除非它們是實際的鉤子。
local ANIMATION_NAME = "idle"
local function do_something(context)
context.log:info("Doing something!")
end
return {
api_version = 1,
priority = 0,
on_spawn = function(context)
do_something(context)
end
}
方法語法:: 與 .
在 Lua 中,object:method(arg) 是 object.method(object, arg) 的簡寫。MagmaCore API 接受兩種形式,因此都可以使用:
context.log:info("hello")
context.log.info("hello") -- same thing
所有文件一致使用 : 語法。
執行預算
每次鉤子呼叫和每次回呼呼叫都會計時。如果單次呼叫超過 50 毫秒,腳本會被停用並在主控台顯示警告:
[Lua] my_script.lua took 73ms in 'on_game_tick' (limit: 50ms) -- script disabled to prevent lag.
保持在預算內的方法:
- 避免在鉤子內使用無限制的迴圈。
- 保持
on_game_tick/on_tick處理器輕量 -- 它們每個刻都會執行。 - 使用
context.scheduler:run_repeating(...)將工作分散到多個刻。 - 將昂貴的工作放在基於狀態的冷卻或合理的間隔之後。
context.state
一個普通的 Lua 表,在腳本實例的整個生命週期中持續存在。用於儲存旗標、計數器、任務 ID、切換狀態以及任何需要在鉤子之間共享的資料。
on_spawn = function(context)
context.state.is_open = false
context.state.click_count = 0
context.state.task_id = nil
end,
on_right_click = function(context)
context.state.click_count = (context.state.click_count or 0) + 1
end
只有 context.state 在鉤子呼叫之間持續存在。所有其他 context 表(context.prop、context.world、context.event 等)每次都會重新建立。context.state 不會重新建立 -- 它從腳本實例建立的那一刻起一直存在,直到實例被銷毀。
context.log
主控台日誌方法。訊息在伺服器主控台中會加上腳本檔案名稱前綴。
| 方法 | 備註 |
|---|---|
log:info(message) | 資訊訊息 |
log:warn(message) | 警告訊息 |
log:error(message) | 警告等級訊息(以 WARN 等級記錄,與 log:warn 相同) |
log:debug(message) | 偵錯訊息(以 info 等級顯示,帶有偵錯前綴) |
context.log:info("Script loaded!")
context.log:warn("Something unexpected happened")
context.log:error("Critical failure in zone setup")
context.log:debug("State value: " .. tostring(context.state.counter))
context.cooldowns
冷卻表管理腳本的時間冷卻。有兩種作用域:
- 本地冷卻 是按腳本實例的,由字串鍵識別。如果未提供鍵,則使用腳本檔案名稱作為預設鍵。
- 全域冷卻 在同一實體擁有者的所有腳本之間共享(例如同一道具的所有腳本,或同一 Boss 的所有 Lua 能力)。
cooldowns:check_local(key?, duration)
最常用的方法。檢查冷卻是否就緒,如果是則啟動冷卻並回傳 true。如果未就緒,回傳 false。這是原子性的檢查並設定操作——沒有競態條件。
| 參數 | 類型 | 備註 |
|---|---|---|
key | string(可選) | 冷卻識別碼。預設為腳本檔案名稱。 |
duration | int | 冷卻持續時間(以刻為單位,20 = 1 秒) |
on_right_click = function(context)
-- Only allow this action once every 3 seconds
if not context.cooldowns:check_local("interact", 60) then
return
end
-- ... do the action
end
cooldowns:local_ready(key?)
如果本地冷卻已過期(或從未設定),回傳 true;如果仍在冷卻中,回傳 false。
cooldowns:local_remaining(key?)
回傳本地冷卻剩餘的刻數,如果已就緒則回傳 0。
cooldowns:set_local(duration, key?)
設定本地冷卻而不檢查是否已有冷卻在執行。用於無條件的冷卻重設。
| 參數 | 類型 | 備註 |
|---|---|---|
duration | int | 持續時間(以刻為單位)。傳入 0 或負數可清除冷卻。 |
key | string(可選) | 冷卻識別碼。預設為腳本檔案名稱。 |
cooldowns:global_ready()
如果全域冷卻(在同一實體的所有腳本之間共享)已過期,回傳 true。
cooldowns:set_global(duration)
設定全域冷卻。
| 參數 | 類型 | 備註 |
|---|---|---|
duration | int | 持續時間(以刻為單位) |
在 EliteMobs 能力腳本中,global_ready() 和 set_global() 使用 Boss 內建的能力冷卻系統,該系統在同一 Boss 的所有 Lua 能力之間共享。EliteMobs 中的本地冷卻也在同一 Boss 實體的所有能力之間共享(由您選擇的字串鍵識別)。
context.scheduler
排程器讓您執行延遲和重複任務。所有任務都由腳本實例擁有,當腳本實例被銷毀時(例如道具被移除或 Boss 死亡時)會自動取消。
scheduler:run_later(ticks, callback)
在延遲後執行一次回呼。回傳一個數值任務 ID。
| 參數 | 類型 | 備註 |
|---|---|---|
ticks | int | 以伺服器刻為單位的延遲(20 刻 = 1 秒) |
callback | function | 延遲到期時以新的 context 呼叫 |
context.scheduler:run_later(40, function(delayed_context)
delayed_context.log:info("2 seconds have passed!")
end)
scheduler:run_repeating(delay, interval, callback)
以固定間隔重複執行回呼。回傳一個數值任務 ID。
| 參數 | 類型 | 備註 |
|---|---|---|
delay | int | 第一次執行前的初始延遲(以刻為單位) |
interval | int | 每次後續執行之間的刻數 |
callback | function | 每個間隔以新的 context 呼叫 |
context.state.particle_task = context.scheduler:run_repeating(0, 20, function(tick_context)
tick_context.log:info("Another second passed!")
end)
scheduler:cancel(taskId)
透過任務 ID 取消排程任務。
| 參數 | 類型 | 備註 |
|---|---|---|
taskId | int | run_later 或 run_repeating 回傳的任務 ID |
如果您啟動了重複任務,務必在清理鉤子中取消它(道具使用 on_destroy,Boss 使用 on_exit_combat / on_death,物品使用 on_unequip)。忘記取消會留下一個在背景執行的任務,直到腳本實例被銷毀,浪費效能並可能導致錯誤。
排程回呼接收一個新的 context 作為參數。請始終使用回呼自己的 context 參數,而非建立回呼的鉤子中的外部 context。外部 context 可能包含過時的引用。
context.world
世界表提供查詢和互動 Minecraft 世界的方法。它從實體當前所在的世界建立。
EliteMobs 擴展了 context.world,增加了生成 Boss、援軍、掉落方塊、煙火、投擲藥水和臨時方塊的額外方法。完整的擴展 API 請參閱 EliteMobs 世界與環境。此處記錄的方法在所有外掛程式中都可用。
world.name
包含世界名稱的字串欄位。
world:get_block_at(x, y, z)
回傳指定座標方塊的材料名稱,為小寫字串(例如 "stone"、"air")。
| 參數 | 類型 | 備註 |
|---|---|---|
x | int | 方塊 X 座標 |
y | int | 方塊 Y 座標 |
z | int | 方塊 Z 座標 |
world:set_block_at(x, y, z, material)
設定指定座標的方塊。在主執行緒上執行。
| 參數 | 類型 | 備註 |
|---|---|---|
x | int | 方塊 X 座標 |
y | int | 方塊 Y 座標 |
z | int | 方塊 Z 座標 |
material | string | Bukkit Material 名稱,小寫(例如 "stone"、"air"、"oak_planks") |
成功設定方塊回傳 true,否則回傳 false。
world:spawn_particle(particle, x, y, z, count, dx, dy, dz, speed)
在指定位置生成粒子。
| 參數 | 類型 | 預設值 | 備註 |
|---|---|---|---|
particle | string | 必要 | Bukkit Particle 列舉名稱,大寫(例如 "FLAME"、"DUST") |
x | number | 必要 | X 座標 |
y | number | 必要 | Y 座標 |
z | number | 必要 | Z 座標 |
count | int | 1 | 粒子數量 |
dx | number | 0 | X 擴散/偏移 |
dy | number | 0 | Y 擴散/偏移 |
dz | number | 0 | Z 擴散/偏移 |
speed | number | 0 | 粒子速度 |
某些粒子類型需要此簡單 API 不支援的方塊或物品資料。BLOCK_CRACK、FALLING_DUST、BLOCK_DUST 和 ITEM_CRACK 將失敗或不產生可見效果。請改用不需要資料的替代粒子:CLOUD、SMOKE、CAMPFIRE_COSY_SMOKE、SNOWFLAKE、FLAME、DUST 等。
world:play_sound(sound, x, y, z, volume, pitch)
在指定位置播放音效。
| 參數 | 類型 | 預設值 | 備註 |
|---|---|---|---|
sound | string | 必要 | Bukkit Sound 列舉名稱,大寫(例如 "ENTITY_EXPERIENCE_ORB_PICKUP") |
x | number | 必要 | X 座標 |
y | number | 必要 | Y 座標 |
z | number | 必要 | Z 座標 |
volume | number | 1.0 | 音量 |
pitch | number | 1.0 | 音調 |
world:strike_lightning(x, y, z)
在指定位置召喚閃電(有視覺效果且造成傷害)。
| 參數 | 類型 | 備註 |
|---|---|---|
x | number | X 座標 |
y | number | Y 座標 |
z | number | Z 座標 |
world:get_time()
回傳目前的世界時間(以刻為單位)。
world:set_time(ticks)
設定世界時間。
| 參數 | 類型 | 備註 |
|---|---|---|
ticks | int | 世界時間(0 = 黎明、6000 = 正午、13000 = 夜晚、18000 = 午夜) |
world:get_nearby_entities(x, y, z, radius)
回傳以指定座標為中心的包圍盒內所有實體的實體包裝表陣列。
| 參數 | 類型 | 備註 |
|---|---|---|
x | number | 中心 X |
y | number | 中心 Y |
z | number | 中心 Z |
radius | number | 搜尋半徑(用作三軸的半延伸量) |
這會回傳範圍內的所有實體,包括非生物實體(盔甲架、掉落物品等)。在呼叫生物實體方法前,請始終使用 if entity.damage then 進行防護。
world:get_nearby_players(x, y, z, radius)
回傳以指定座標為中心的包圍盒內所有玩家的玩家包裝表陣列。
| 參數 | 類型 | 備註 |
|---|---|---|
x | number | 中心 X |
y | number | 中心 Y |
z | number | 中心 Z |
radius | number | 搜尋半徑 |
world:spawn_entity(entity_type, x, y, z)
在指定位置生成一個原版 Minecraft 實體。
| 參數 | 類型 | 備註 |
|---|---|---|
entity_type | string | Bukkit 實體類型名稱,小寫(例如 "zombie"、"skeleton"、"pig") |
x | number | X 座標 |
y | number | Y 座標 |
z | number | Z 座標 |
回傳生成實體的實體表(如果適用則包含生物實體方法),如果實體類型無效則回傳 nil。
world:get_highest_block_y(x, z)
回傳指定 X/Z 位置最高非空氣方塊的 Y 座標。
| 參數 | 類型 | 備註 |
|---|---|---|
x | int | 方塊 X 座標 |
z | int | 方塊 Z 座標 |
world:raycast(from_x, from_y, from_z, dir_x, dir_y, dir_z, [max_distance])
從一個點向一個方向投射射線,回傳命中資訊。
| 參數 | 類型 | 預設值 | 備註 |
|---|---|---|---|
from_x | number | 必要 | 起點 X |
from_y | number | 必要 | 起點 Y |
from_z | number | 必要 | 起點 Z |
dir_x | number | 必要 | 方向 X 分量 |
dir_y | number | 必要 | 方向 Y 分量 |
dir_z | number | 必要 | 方向 Z 分量 |
max_distance | number | 50 | 最大射線距離 |
回傳包含以下欄位的表:
| 欄位 | 類型 | 備註 |
|---|---|---|
hit_entity | entity table 或 nil | 射線命中的第一個實體,如果沒有則為 nil |
hit_location | location table 或 nil | 射線命中的確切位置 |
hit_block | table 或 nil | 命中方塊的 {x, y, z, material},如果沒有命中方塊則為 nil |
world:spawn_firework(x, y, z, colors, [type], [power])
在指定位置生成煙火火箭。
| 參數 | 類型 | 預設值 | 備註 |
|---|---|---|---|
x | number | 必要 | X 座標 |
y | number | 必要 | Y 座標 |
z | number | 必要 | Z 座標 |
colors | table | 必要 | 顏色字串陣列,例如 {"RED", "BLUE", "WHITE"} |
type | string | "BALL" | 煙火形狀:"BALL"、"BALL_LARGE"、"STAR"、"BURST"、"CREEPER" |
power | int | 1 | 飛行動力,0-127 |
-- Example: red and gold firework burst
context.world:spawn_firework(loc.x, loc.y, loc.z, {"RED", "GOLD"}, "BURST", 2)
world:place_temporary_block(x, y, z, material, [ticks], [require_air])
放置一個在延遲後自動恢復為原始狀態的方塊。
| 參數 | 類型 | 預設值 | 備註 |
|---|---|---|---|
x | int | 必要 | 方塊 X 座標 |
y | int | 必要 | 方塊 Y 座標 |
z | int | 必要 | 方塊 Z 座標 |
material | string | 必要 | Bukkit Material 名稱(例如 "stone"、"ice") |
ticks | int | 0 | 方塊恢復前的持續時間(以刻為單位)。0 表示永久。 |
require_air | boolean | false | 如果為 true,僅在目標為空氣時放置方塊 |
方塊放置成功回傳 true,材料無效或空氣要求未滿足回傳 false。
world:drop_item(x, y, z, material, [amount])
在指定位置以自然散布方式掉落物品實體。
| 參數 | 類型 | 預設值 | 備註 |
|---|---|---|---|
x | number | 必要 | X 座標 |
y | number | 必要 | Y 座標 |
z | number | 必要 | Z 座標 |
material | string | 必要 | Bukkit Material 名稱 |
amount | int | 1 | 堆疊大小 |
回傳掉落物品的實體表,如果材料無效則回傳 nil。
context.zones
區域表讓您建立空間區域並監視玩家的進入/離開事件。區域綁定到腳本實例,在腳本實例銷毀時自動清理。
zones:create_sphere(x, y, z, radius)
在指定座標建立球形區域。回傳一個數值區域控制代碼。
| 參數 | 類型 | 備註 |
|---|---|---|
x | number | 中心 X |
y | number | 中心 Y |
z | number | 中心 Z |
radius | number | 球體半徑 |
zones:create_cylinder(x, y, z, radius, height)
建立圓柱形區域。回傳一個數值區域控制代碼。
| 參數 | 類型 | 備註 |
|---|---|---|
x | number | 中心 X |
y | number | 中心 Y(底部) |
z | number | 中心 Z |
radius | number | 圓柱半徑 |
height | number | 圓柱高度 |
zones:create_cuboid(x, y, z, xSize, ySize, zSize)
建立長方體區域。回傳一個數值區域控制代碼。
| 參數 | 類型 | 備註 |
|---|---|---|
x | number | 中心 X |
y | number | 中心 Y |
z | number | 中心 Z |
xSize | number | X 半延伸量 |
ySize | number | Y 半延伸量 |
zSize | number | Z 半延伸量 |
zones:watch(handle, onEnterCallback, onLeaveCallback)
開始監視區域的玩家進入/離開事件。當玩家進入或離開區域時,對應的回呼會觸發(如果已定義,on_zone_enter / on_zone_leave 鉤子也會觸發)。
| 參數 | 類型 | 備註 |
|---|---|---|
handle | int | create_* 呼叫回傳的區域控制代碼 |
onEnterCallback | function 或 nil | 玩家進入區域時呼叫 |
onLeaveCallback | function 或 nil | 玩家離開區域時呼叫 |
成功設定監視回傳 true,區域控制代碼無效則回傳 nil。
區域監視每個伺服器刻都會對同一世界中的所有玩家進行檢查。保持區域數量合理以避免效能開銷。
zones:unwatch(handle)
停止監視區域並清理其資源。
| 參數 | 類型 | 備註 |
|---|---|---|
handle | int | 要停止監視的區域控制代碼 |
範例:近距離觸發區域
return {
api_version = 1,
on_spawn = function(context)
local loc = context.prop.current_location -- or context.boss:get_location()
if loc == nil then return end
local handle = context.zones:create_sphere(loc.x, loc.y, loc.z, 5)
context.zones:watch(
handle,
function(player)
context.log:info("Player entered zone!")
end,
function(player)
context.log:info("Player left zone!")
end
)
context.state.zone_handle = handle
end,
on_destroy = function(context)
if context.state.zone_handle then
context.zones:unwatch(context.state.zone_handle)
end
end
}
context.event
當目前的鉤子由遊戲事件觸發時(例如 on_right_click、on_zone_enter),事件表會存在。在 on_tick 或已排程的回呼中不存在。
| 欄位 / 方法 | 類型 | 備註 |
|---|---|---|
is_cancelled | boolean | 事件是否已被取消 |
cancel() | method | 取消事件(阻止預設行為) |
uncancel() | method | 取消之前已取消的事件 |
player | entity table | 事件中涉及的玩家(如有) |
on_right_click = function(context)
if context.event then
context.event:cancel() -- prevent the default right-click interaction
end
end
EliteMobs 能力腳本具有更詳細的事件表,包含傷害數值、傷害原因、攻擊者引用和傷害修改方法。完整的 EliteMobs 事件欄位請參閱 Lua API 參考。
em 輔助命名空間
em 表在檔案載入時(在任何鉤子執行之前)就可用。它提供用於建構位置表、向量表和區域定義的輔助建構器,這些在整個 API 中都會用到。
| 函式 | 用途 |
|---|---|
em.create_location(x, y, z [, world, yaw, pitch]) | 建立位置表,可選填世界名稱、偏航角和俯仰角。回傳的表還有一個 .add(dx, dy, dz) 方法,可就地偏移位置並回傳自身以支援鏈式呼叫。 |
em.create_vector(x, y, z) | 建立向量表 |
em.zone.create_sphere_zone(radius) | 建立球形區域定義 |
em.zone.create_dome_zone(radius) | 建立穹頂區域定義 |
em.zone.create_cylinder_zone(radius, height) | 建立圓柱區域定義 |
em.zone.create_cuboid_zone(x, y, z) | 建立長方體區域定義 |
em.zone.create_cone_zone(length, radius) | 建立錐形區域定義 |
em.zone.create_static_ray_zone(length, thickness) | 建立靜態射線區域定義 |
em.zone.create_rotating_ray_zone(length, point_radius, animation_duration) | 建立旋轉射線區域定義 |
em.zone.create_translating_ray_zone(length, point_radius, animation_duration) | 建立平移射線區域定義 |
區域建構器回傳可鏈式呼叫的表,帶有 :set_center(loc)(或 :set_origin(loc) / :set_destination(loc),取決於區域類型):
-- At file scope: create a reusable zone shape
local blast_zone = em.zone.create_sphere_zone(5)
return {
api_version = 1,
on_spawn = function(context)
-- Anchor the zone at call time
blast_zone:set_center(context.boss:get_location())
local entities = context.zones:get_entities_in_zone(blast_zone)
-- ...
end
}
em 命名空間在 EliteMobs 中特別有用,其中區域定義與 context.zones:get_entities_in_zone() 和 context.script 一起使用。在 FreeMinecraftModels 中,context.zones:create_sphere(...) / create_cylinder(...) / create_cuboid(...) 方法更常用於簡單的基於監視的區域。
實體表
實體表從世界查詢、事件資料和區域回呼中回傳。它們根據實體類型提供分層的欄位和方法集。
實體基本欄位
| 欄位 | 類型 | 備註 |
|---|---|---|
uuid | string | 實體的 UUID |
entity_type | string | 實體類型(例如 "player"、"zombie"、"skeleton"、"villager") |
is_valid | boolean | 實體引用是否仍然有效 |
is_dead | boolean | 實體是否已死亡 |
is_player | boolean | 實體是否為玩家 |
is_hostile | boolean | 實體是否為敵對生物(殭屍、骷髏等) |
is_passive | boolean | 實體是否為被動生物(牛、豬、雞等) |
current_location | location table | 實體的當前位置(x、y、z、world、yaw、pitch) |
world | string | 實體所在的世界名稱 |
實體基本方法
| 方法 | 回傳 | 備註 |
|---|---|---|
teleport(location_table) | void | 傳送實體。位置表必須有 x、y、z、world 欄位;yaw 和 pitch 為可選。 |
remove() | void | 從世界移除實體。僅在實體仍然有效時執行。 |
set_silent(flag) | void | 抑制或重新啟用實體的聲音。 |
set_invulnerable(flag) | void | 使實體無敵或可受傷。 |
set_gravity(flag) | void | 啟用或停用實體的重力。 |
set_glowing(flag) | void | 切換實體的發光輪廓效果。 |
生物實體欄位
生物實體(玩家、怪物等)除了實體基本欄位外還有:
| 欄位 | 類型 | 備註 |
|---|---|---|
health | number | 目前生命值 |
maximum_health | number | 最大生命值 |
name | string | 顯示名稱 |
is_alive | boolean | 實體是否存活 |
生物實體方法
| 方法 | 回傳 | 備註 |
|---|---|---|
damage(amount) | void | 對實體造成指定量的傷害 |
push(x, y, z) | void | 施加速度脈衝 |
set_facing(x, y, z) | void | 設定實體面朝的方向 |
add_potion_effect(effect, duration, amplifier) | void | 添加藥水效果。effect 為字串(例如 "speed"、"slowness"、"regeneration")。duration 以刻為單位。amplifier 為效果等級減 1(0 = 一級)。 |
remove_potion_effect(effect) | void | 按名稱移除藥水效果 |
不是所有 get_nearby_entities() 回傳的實體都是生物實體。您可以使用 entity.is_player、entity.is_hostile 或 entity.is_passive 按類別過濾,或在呼叫 damage()、push() 或 add_potion_effect() 等生物實體方法前檢查 if entity.damage then。
外掛程式整合欄位
實體表自動包含用於偵測和互動其他 Nightbreak 外掛程式管理的實體的欄位。這些欄位僅在相關外掛程式安裝時才會填充 -- 否則預設為 false / nil,無額外開銷。
EliteMobs 欄位
在安裝 EliteMobs 時可用。
| 欄位 | 類型 | 備註 |
|---|---|---|
is_elite | boolean | 實體是否為 EliteMobs 菁英怪 |
is_custom_boss | boolean | 實體是否為 EliteMobs 自訂 Boss(在 elite 子表中也可用) |
is_significant_boss | boolean | 實體是否為生命值倍率超過 1 的自訂 Boss(即設計過的遭遇戰,而非填充用菁英怪) |
elite | table 或 nil | 菁英資訊子表(見下方)。如果實體不是菁英怪則為 nil。 |
elite 子表包含:
| 欄位 | 類型 | 備註 |
|---|---|---|
elite.level | int | 菁英怪的等級 |
elite.name | string | 菁英怪的顯示名稱 |
elite.health | number | 目前生命值 |
elite.max_health | number | 最大生命值 |
elite.is_custom_boss | boolean | 是否為自訂 Boss(相對於自然菁英怪) |
elite.health_multiplier | number | 設定中定義的生命值倍率 |
elite.damage_multiplier | number | 設定中定義的傷害倍率 |
elite:remove() | void | 透過 EliteMobs 的正確移除管道移除菁英怪(清理追蹤、戰利品等) |
範例:對菁英怪造成不同傷害
local entities = context.world:get_nearby_entities(x, y, z, 5)
for _, entity in ipairs(entities) do
if entity.is_elite then
-- Deal double damage to elites
entity:damage(20)
context.log:info("Hit elite: " .. entity.elite.name .. " (level " .. entity.elite.level .. ")")
elseif entity.is_hostile then
entity:damage(10)
end
end
FreeMinecraftModels 欄位
在安裝 FreeMinecraftModels 時可用。
| 欄位 | 類型 | 備註 |
|---|---|---|
is_modeled | boolean | 實體是否附加了 FMM 模型(DynamicEntity 或 PropEntity) |
is_prop | boolean | 實體是否為 FMM 道具(靜態裝飾實體) |
model | table 或 nil | 模型資訊子表(見下方)。如果實體沒有模型則為 nil。 |
model 子表包含:
| 欄位 | 類型 | 備註 |
|---|---|---|
model.model_id | string | 模型藍圖 ID(例如 "torch_01") |
model:play_animation(name, [blend], [loop]) | boolean | 播放命名動畫。blend 預設為 false,loop 預設為 false。如果找到動畫則回傳 true。 |
model:stop_animations() | void | 停止模型上所有目前播放的動畫。 |
model:remove() | void | 透過 FMM 的正確移除管道移除模型實體。 |
模型橋接(可用於任何實體)將 blend 和 loop 預設為 false。道具表 的 play_animation 將兩者預設為 true,因為道具通常需要混合的、循環的動畫。
範例:按類型過濾實體
local entities = context.world:get_nearby_entities(x, y, z, 10)
for _, entity in ipairs(entities) do
if entity.is_prop then
-- Skip props
elseif entity.is_player then
entity:damage(5)
elseif entity.entity_type == "villager" then
-- Don't hurt villagers
elseif entity.is_elite then
entity:damage(20)
elseif entity.is_hostile then
entity:damage(10)
end
end
玩家特定欄位
玩家實體擁有所有實體和生物實體欄位,外加:
| 欄位 | 類型 | 備註 |
|---|---|---|
game_mode | string | 玩家的遊戲模式("creative"、"survival"、"adventure"、"spectator") |
玩家特定方法
| 方法 | 回傳 | 備註 |
|---|---|---|
send_message(msg) | void | 向玩家發送聊天訊息。支援 & 顏色代碼。 |
get_held_item() | table 或 nil | 回傳玩家主手物品的 {type, amount, display_name},空手則為 nil |
consume_held_item(amount?) | void | 消耗玩家主手的物品。amount 預設為 1 |
has_item(material, amount?) | boolean | 玩家物品欄中是否有至少 amount(預設 1)個指定材料的物品 |
get_target_entity([range]) | entity table 或 nil | 透過射線投射回傳玩家正在看的實體,如果沒有則為 nil。預設範圍為 50。 |
get_eye_location() | location table | 回傳玩家眼睛高度的位置表 |
get_look_direction() | table | 回傳玩家視線方向的 {x, y, z} 方向向量 |
send_block_change(x, y, z, material, [ticks]) | void | 發送僅對此玩家可見的假方塊。如果提供 ticks,假方塊會在該時間後自動重設。 |
reset_block(x, y, z) | void | 為此玩家將假方塊重設為真實方塊 |
sleep(x, y, z) | void | 讓玩家在指定座標進入床上睡眠動畫。玩家停止睡眠時方塊會自動恢復。 |
wake_up() | void | 喚醒正在睡眠的玩家。 |
玩家 UI 方法
這些方法可在任何玩家實體表上使用,提供透過 Minecraft 內建 UI 元素向玩家顯示資訊的方式。
player:show_boss_bar(text, [color], progress, [ticks])
向玩家顯示 Boss 血條。
| 參數 | 類型 | 預設值 | 備註 |
|---|---|---|---|
text | string | 必要 | 要顯示的文字。支援 & 顏色代碼。 |
color | string | "WHITE" | 血條顏色。可選:"RED"、"BLUE"、"GREEN"、"YELLOW"、"PURPLE"、"PINK"、"WHITE" |
progress | number | 必要 | 填充量,從 0.0(空)到 1.0(滿) |
ticks | int | nil | 可選的自動消失延遲(以刻為單位)。省略則血條會一直顯示直到手動隱藏。 |
player:hide_boss_bar()
從玩家畫面移除 Boss 血條。無需參數。
player:show_action_bar(text, [ticks])
在動作欄區域(快捷欄上方)顯示文字。
| 參數 | 類型 | 預設值 | 備註 |
|---|---|---|---|
text | string | 必要 | 要顯示的文字。支援 & 顏色代碼。 |
ticks | int | nil | 可選的持續時間(以刻為單位)。如果提供,訊息會每 40 刻重新發送一次以在整個持續時間內保持可見。 |
player:show_title(title, [subtitle], fade_in, stay, fade_out)
向玩家顯示標題畫面。
| 參數 | 類型 | 預設值 | 備註 |
|---|---|---|---|
title | string | 必要 | 主標題文字。支援 & 顏色代碼。 |
subtitle | string | "" | 主標題下方的副標題文字。可選。 |
fade_in | int | 必要 | 淡入持續時間(以刻為單位) |
stay | int | 必要 | 標題在畫面上停留的時間(以刻為單位) |
fade_out | int | 必要 | 淡出持續時間(以刻為單位) |
後續步驟
有關特定外掛程式的鉤子、API 和工作流程: