MagmaCore Lua スクリプティングエンジン
MagmaCore は、Nightbreak の複数のプラグインで利用される共有 Lua スクリプティングエンジンを提供します。このエンジンはサンドボックス、スケジューリング、ゾーン管理、ワールドとのやり取り、エンティティテーブル、プレイヤー UI を扱い、プラグイン間で一貫した API を提供します。
現在、以下のプラグインがこのエンジンを使用しています:
- EliteMobs -- カスタムボス向けの 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
-- イベントに対して何かを行う
end
~= は「等しくない」を意味します。
テーブル
Lua ではテーブルが複数の用途に使われます:
- リスト
- 名前付きキーを持つオブジェクト
- 最終的に返されるスクリプト定義
名前付きキーを持つテーブルの例:
local particle = {
particle = "FLAME",
amount = 1,
speed = 0.05
}
スクリプト定義を返す
すべてのスクリプトファイルの末尾では 1 つのテーブルを返します:
return {
api_version = 1,
on_spawn = function(context)
end
}
その返されたテーブルこそがスクリプトファイルです。
コメント
人間向けのメモを書くには -- を使います:
-- このクールダウンは攻撃がヒットするたびに発動するのを防ぎます
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.* 関数 |
| Iterators | pairs、ipairs、next |
| Type | type、tostring、tonumber、select、unpack |
| エラー処理 | pcall、xpcall、error、assert |
| その他 | print、rawget、rawset、rawequal、rawlen、setmetatable、getmetatable |
os ライブラリは利用できませんos ライブラリはサンドボックスから完全に除外されています。タイミング情報が必要な場合は、ワールド時刻には context.world:get_time() を使うか、on_game_tick フックを介して tick カウンタを使ってタイムスタンプを context.state に保存してください。
print はサーバーコンソールに出力しますが、出力には context.log:info(msg) の利用を推奨します。ログメッセージにはスクリプトのファイル名が前置されるため、どのスクリプトがメッセージを出したかを追跡しやすくなります。
ファイル契約
すべての Lua スクリプトはテーブルを return しなければなりません。そのテーブルは意図的に厳格です。
必須・任意のトップレベルフィールド
| フィールド | 必須 | 型 | 備考 |
|---|---|---|---|
api_version | Yes | Number | 現状は 1 でなければならない |
priority | No | Number | 実行優先度。値が小さいほど先に実行される。デフォルトは 0 |
| サポートされたフックキー | No | 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
}
共有エンジンフック
以下のフックは MagmaCore スクリプティングエンジンを使用するすべてのプラグインで利用できます。個々のプラグインは、これらに加えて独自のフックを追加します。
| フック | 発火タイミング |
|---|---|
on_spawn | スクリプトインスタンスが作成されたとき(エンティティのスポーンやプロップの設置時)に一度呼び出される |
on_game_tick | エンティティが生存/アクティブな間、サーバーの tick ごとに呼び出される |
on_zone_enter | プレイヤーが監視中のゾーンに入ったときに呼び出される |
on_zone_leave | プレイヤーが監視中のゾーンから出たときに呼び出される |
メソッド構文: : と .
Lua では、object:method(arg) は object.method(object, arg) の省略形です。MagmaCore の API はどちらの形式も受け付けるため、両方とも動作します:
context.log:info("hello")
context.log.info("hello") -- 同じ意味
すべてのドキュメントでは一貫して : を使用します。
実行バジェット
すべてのフック呼び出しおよびすべてのコールバック呼び出しは時間計測されます。1 回の呼び出しが 50 ミリ秒 を超えると、スクリプトは無効化され、コンソールに警告が出ます:
[Lua] my_script.lua took 73ms in 'on_game_tick' (limit: 50ms) -- script disabled to prevent lag.
バジェット内に収めるためのコツ:
- フック内で無限ループを避ける。
on_game_tickハンドラは軽量に保つ -- これらは毎 tick 実行される。context.scheduler:run_repeating(...)を使って作業を複数の tick に分散させる。- 重い処理は状態ベースのクールダウンや適切な間隔の背後に置く。
Lua スクリプトがフックやスケジュールされたコールバックで実行時エラーをスローすると、そのエンティティ用のスクリプトインスタンスは即座に永続的に無効化されます。スクリプトファイル内のエラーを修正してください -- 次にエンティティがスポーンした際にスクリプトは再初期化されます。
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) | 警告レベルのメッセージ(log:warn と同じく WARN レベルでログに出力される) |
EliteMobs の context.log は error の代わりに debug を登録します。デバッグ出力には log:debug(message) を使用してください(debug プレフィックス付きの info レベルとして表示されます)。
context.log:info("Script loaded!")
context.log:warn("Something unexpected happened")
context.log:error("Critical failure in zone setup")
context.cooldowns
cooldowns テーブルはスクリプトの時間ベースのクールダウンを管理します。スコープは 2 種類あります:
- ローカルクールダウン はスクリプトインスタンスごとに固有で、文字列キーで識別されます。キーが指定されない場合、デフォルトキーとしてスクリプトのファイル名が使われます。
- グローバルクールダウン は同じオーナーエンティティ上のすべてのスクリプトで共有されます(例: 同じプロップ上のすべてのスクリプト、同じボス上のすべての Lua パワー)。
cooldowns:check_local(key?, duration)
最もよく使われるメソッド。クールダウンが準備完了かを確認し、準備完了であればクールダウンを開始して true を返します。準備未完了なら false を返します。これはアトミックなチェック&セットであり、競合状態は発生しません。
| パラメータ | 型 | 備考 |
|---|---|---|
key | string (任意) | クールダウン識別子。デフォルトはスクリプトファイル名 |
duration | int | クールダウンの長さ(tick 単位、20 = 1 秒) |
on_right_click = function(context)
-- このアクションは 3 秒に 1 回だけ許可
if not context.cooldowns:check_local("interact", 60) then
return
end
-- ... 実際のアクション
end
cooldowns:local_ready(key?)
ローカルクールダウンが終了していれば(または設定されていなければ)true を、まだ有効なら false を返します。
cooldowns:local_remaining(key?)
ローカルクールダウンの残り tick 数を返します。準備完了なら 0 を返します。
cooldowns:set_local(duration, key?)
すでに有効かどうかを確認せずにローカルクールダウンを設定します。無条件のクールダウンリセットに使います。
| パラメータ | 型 | 備考 |
|---|---|---|
duration | int | tick 単位の期間。0 または負の値でクリア |
key | string (任意) | クールダウン識別子。デフォルトはスクリプトファイル名 |
cooldowns:global_ready()
グローバルクールダウン(同じエンティティ上のすべてのスクリプトで共有)が終了していれば true を返します。
cooldowns:set_global(duration)
グローバルクールダウンを設定します。
| パラメータ | 型 | 備考 |
|---|---|---|
duration | int | tick 単位の期間 |
グローバルクールダウンの「オーナー」はスクリプトタイプによって異なります:
- EliteMobs Lua パワー —
EliteEntity単位で共有(ボスごとに 1 バケット)。global_ready()/set_global()はボスに組み込まれたパワークールダウンシステムを使い、ローカルクールダウンも同じボス上のすべてのパワーで共有されます。 - FMM プロップスクリプト —
PropEntity単位で共有(設置されたプロップごとに 1 バケット)。 - FMM アイテムスクリプト — プレイヤー UUID 単位で共有(プレイヤーごとに 1 バケット)。アイテム上のローカルクールダウンは装備/解除サイクルをまたいで永続化され、
playerUUID → "itemId:scriptFile" → keyでキー付けされるため、プレイヤーがアイテムをホットバーから出し入れしてもクールダウンが残ります。
context.scheduler
スケジューラを使うと、遅延タスクや繰り返しタスクを実行できます。すべてのタスクはスクリプトインスタンスに所有され、スクリプトインスタンスが破棄されたとき(プロップが除去されたりボスが死亡したりしたとき)に自動的にキャンセルされます。
scheduler:run_later(ticks, callback)
遅延後に 1 度だけコールバックを実行します。数値のタスク ID を返します。
| パラメータ | 型 | 備考 |
|---|---|---|
ticks | int | サーバー tick 単位の遅延(20 tick = 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 | 最初の実行までの初期遅延(tick) |
interval | int | その後の各実行の間隔(tick) |
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、ボスなら on_exit_combat / on_death、アイテムなら on_unequip)でキャンセルしてください。キャンセルし忘れると、スクリプトインスタンスが破棄されるまでバックグラウンドタスクが動き続け、パフォーマンスを浪費したりエラーを引き起こしたりする可能性があります。
スケジュールされたコールバックは引数として 新しい context を受け取ります。コールバックを作成した外側のフックの context ではなく、必ずコールバック自身の context 引数を使ってください。外側の context には古い参照が含まれている可能性があります。
context.world
world テーブルは Minecraft ワールドの問い合わせや操作のためのメソッドを提供します。エンティティの現在のワールドから構築されます。
EliteMobs は context.world を拡張し、ボス、増援、落下ブロック、花火、スプラッシュポーション、一時ブロックのスポーン用メソッドを追加します。拡張 API の完全版については EliteMobs World & Environment を参照してください。ここで解説するメソッドはすべてのプラグインで利用できます。
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 enum 名、大文字(例: "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 enum 名、大文字(例: "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()
現在のワールド時刻を tick 単位で返します。
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 | 検索半径(3 軸とも half-extent として使用) |
これは範囲内のすべてのエンティティ(アーマースタンドやドロップアイテムなど、living でないエンティティも含む)を返します。living エンティティのメソッドを呼び出す前に、必ず 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 座標 |
スポーンしたエンティティのテーブル(該当する場合は living entity メソッドを含む)を返します。エンティティタイプが無効なら 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 or nil | レイが最初にヒットしたエンティティ。なければ nil |
hit_location | location table or nil | 何かにヒットした正確な点 |
hit_block | table or 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 |
-- 例: 赤と金の花火バースト
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 | ブロックが戻るまでの tick 数。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 テーブルを使うと、空間ゾーンを作成し、プレイヤーの enter/leave イベントを監視できます。ゾーンはスクリプトインスタンスに紐づき、スクリプトインスタンスが破棄されると自動的にクリーンアップされます。
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 方向の half-extent |
ySize | number | Y 方向の half-extent |
zSize | number | Z 方向の half-extent |
zones:watch(handle, onEnterCallback, onLeaveCallback)
ゾーンへのプレイヤーの enter/leave イベントを監視し始めます。コールバックパラメータは boolean シグナル として機能し、nil 以外の値(関数や true など)を渡すと、スクリプトの対応するフックが有効になります。コールバック自体は直接呼び出されません。代わりに、enter/leave のロジックはスクリプトの on_zone_enter / on_zone_leave フックで発火します。
| パラメータ | 型 | 備考 |
|---|---|---|
handle | int | create_* 呼び出しから得られたゾーンハンドル |
onEnterCallback | nil 以外の任意の値、または nil | nil 以外でこのゾーンの on_zone_enter フックを有効化 |
onLeaveCallback | nil 以外の任意の値、または nil | nil 以外でこのゾーンの on_zone_leave フックを有効化 |
監視の設定に成功すれば true、ゾーンハンドルが無効なら nil を返します。
ゾーン監視は同じワールド内のすべてのプレイヤーに対してサーバーの tick ごとに確認されます。パフォーマンスのオーバーヘッドを抑えるため、ゾーン数は妥当な範囲に保ってください。
zones:unwatch(handle)
ゾーンの監視を停止し、リソースをクリーンアップします。
| パラメータ | 型 | 備考 |
|---|---|---|
handle | int | 監視停止対象のゾーンハンドル |
例: 近接トリガーゾーン
return {
api_version = 1,
on_spawn = function(context)
local loc = context.prop.current_location -- または context.boss:get_location()
if loc == nil then return end
local handle = context.zones:create_sphere(loc.x, loc.y, loc.z, 5)
-- nil 以外の値を渡して on_zone_enter / on_zone_leave フックを有効化。
-- これらは boolean シグナルでコールバックではなく、実際のロジックは下のフックに書く。
context.zones:watch(handle, true, true)
context.state.zone_handle = handle
end,
on_zone_enter = function(context)
context.log:info("Player entered zone!")
end,
on_zone_leave = function(context)
context.log:info("Player left zone!")
end,
on_destroy = function(context)
if context.state.zone_handle then
context.zones:unwatch(context.state.zone_handle)
end
end
}
context.event
event テーブルは、現在のフックがゲームイベント(例: on_right_click、on_zone_enter)によってトリガーされたときに存在します。on_game_tick やスケジュールされたコールバックでは存在しません。
| フィールド / メソッド | 型 | 備考 |
|---|---|---|
is_cancelled | boolean | イベントがキャンセルされたかどうか |
cancel() | method | イベントをキャンセルする(デフォルト動作を防ぐ) |
uncancel() | method | 以前キャンセルされたイベントのキャンセルを取り消す |
player | entity table | イベントに関与するプレイヤー(該当する場合) |
on_right_click = function(context)
if context.event then
context.event:cancel() -- デフォルトの右クリック操作を防ぐ
end
end
EliteMobs パワースクリプトでは、ダメージ量、ダメージ原因、ダメージ元参照、ダメージ修正メソッドを備えた、より詳細なイベントテーブルが利用できます。EliteMobs のイベントフィールドの全容は Lua API リファレンス を参照してください。
em ヘルパー名前空間
em テーブルはファイルロード時(どのフックも実行される前)に利用可能です。API 全体で使用される location テーブル、ベクトルテーブル、ゾーン定義を作るためのヘルパーコンストラクタを提供します。
| 関数 | 用途 |
|---|---|
em.create_location(x, y, z [, world, yaw, pitch]) | location テーブルを作成する。任意でワールド名、yaw、pitch も指定可能。返されるテーブルには .add(dx, dy, dz) メソッドがあり、location を in-place でオフセットして自身を返すのでチェーン可能。 |
em.create_vector(x, y, z) | vector テーブルを作成する |
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) | 移動レイゾーン定義を作成する |
em.location.is_in_dungeon(loc) | location が登録済みダンジョンリージョン内かを確認する |
em.location.is_protected(loc) | location が保護リージョン内かを確認する(WorldGuard、GriefPrevention、EM リージョンなど) |
em.location.owned_by(loc, namespace) | 特定のプラグイン namespace が location を所有しているかを確認する(例: "EliteMobs") |
em.location.owners(loc) | location を所有する namespace 文字列の配列 |
em.location.kinds_at(loc) | location における種類タグの配列("elitemobs"、"world_package"、"open_world_dungeon"、ダンジョンサイズカテゴリ) |
em.location.has_kind(loc, kind) | location に指定の種類タグが付いているかを確認する |
ゾーンビルダーは、:set_center(loc)(またはゾーンタイプに応じて :set_origin(loc) / :set_destination(loc))を持つチェーン可能なテーブルを返します:
-- ファイルスコープ: 再利用可能なゾーン形状を作成
local blast_zone = em.zone.create_sphere_zone(5)
return {
api_version = 1,
on_spawn = function(context)
-- 呼び出し時にゾーンを固定する
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 では、シンプルな watch ベースのゾーンには context.zones:create_sphere(...) / create_cylinder(...) / create_cuboid(...) メソッドの方が一般的に利用されます。
エンティティテーブル
エンティティテーブルはワールドクエリ、イベントデータ、ゾーンコールバックから返されます。エンティティタイプに応じて、フィールドとメソッドが階層的に提供されます。
Entity ベースフィールド
| フィールド | 型 | 備考 |
|---|---|---|
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 | エンティティがいるワールド名 |
Entity ベースメソッド
| メソッド | 戻り値 | 備考 |
|---|---|---|
teleport(location_table) | void | エンティティをテレポートする。location テーブルには x、y、z、world が必要で、yaw と pitch は任意。 |
remove() | void | エンティティをワールドから削除する。エンティティがまだ有効な場合のみ動作する。 |
set_silent(flag) | void | エンティティの音を抑制または再有効化する。 |
set_invulnerable(flag) | void | エンティティをダメージに対して無敵または脆弱にする。 |
set_gravity(flag) | void | エンティティの重力を有効/無効にする。 |
set_glowing(flag) | void | エンティティの発光アウトラインエフェクトを切り替える。 |
Living Entity フィールド
Living エンティティ(プレイヤー、モブなど)は、すべての Entity ベースフィールドに加えて以下を持ちます:
| フィールド | 型 | 備考 |
|---|---|---|
health | number | 現在の体力 |
maximum_health | number | 最大体力 |
name | string | 表示名 |
is_alive | boolean | エンティティが生存しているか |
Living Entity メソッド
| メソッド | 戻り値 | 備考 |
|---|---|---|
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 は tick 単位。amplifier は効果レベル - 1(0 = レベル I)。 |
remove_potion_effect(effect) | void | 名前を指定してポーション効果を除去する |
get_scale() | number | 現在のエンティティスケールを返す(generic.scale 属性をサポートしないサーバーではデフォルトで 1.0) |
set_scale(value) | void | generic.scale 属性を介してエンティティスケールを設定する。1.20.5 より前のサーバーでは何もしない。 |
get_nearby_entities() から返されるエンティティがすべて living entity とは限りません。カテゴリでフィルタリングするには entity.is_player、entity.is_hostile、entity.is_passive を使えますし、living entity のメソッド(damage()、push()、add_potion_effect() など)を呼ぶ前に if entity.damage then で確認することもできます。
プラグイン統合フィールド
エンティティテーブルには、他の Nightbreak プラグインが管理するエンティティを検出・操作するためのフィールドが自動的に含まれます。これらのフィールドは該当プラグインがインストールされているときのみ値が入り、そうでなければゼロオーバーヘッドで false / nil がデフォルトとなります。
EliteMobs フィールド
EliteMobs がインストールされている場合に利用可能です。
| フィールド | 型 | 備考 |
|---|---|---|
is_elite | boolean | エンティティが EliteMobs のエリートか |
is_custom_boss | boolean | エンティティが EliteMobs のカスタムボスか(elite サブテーブル内でも参照可能) |
is_significant_boss | boolean | エンティティが体力倍率 1 超のカスタムボスか(つまり、フィラーエリートでない設計された遭遇か) |
elite | table or nil | エリート情報のサブテーブル(下記参照)。エリートでなければ nil。 |
elite サブテーブルには以下が含まれます:
| フィールド | 型 | 備考 |
|---|---|---|
elite.level | int | エリートのレベル |
elite.name | string | エリートの表示名 |
elite.health | number | 現在の体力 |
elite.max_health | number | 最大体力 |
elite.is_custom_boss | boolean | これがカスタムボスか(自然発生のエリートではないか) |
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
-- エリートには倍のダメージ
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 or nil | モデル情報のサブテーブル(下記参照)。モデルがなければ nil。 |
model サブテーブルには以下が含まれます:
| フィールド | 型 | 備考 |
|---|---|---|
model.model_id | string | モデルのブループリント ID(例: "torch_01") |
model.is_dynamic | boolean | モデル付きエンティティが DynamicEntity(モブ/ボスモデル)か、静的プロップではないか |
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
-- プロップはスキップ
elseif entity.is_player then
entity:damage(5)
elseif entity.entity_type == "villager" then
-- 村人は傷つけない
elseif entity.is_elite then
entity:damage(20)
elseif entity.is_hostile then
entity:damage(10)
end
end
プレイヤー固有フィールド
プレイヤーエンティティはすべての entity および living entity フィールドに加えて以下を持ちます:
| フィールド | 型 | 備考 |
|---|---|---|
game_mode | string | プレイヤーのゲームモード("creative"、"survival"、"adventure"、"spectator") |
プレイヤー固有メソッド
| メソッド | 戻り値 | 備考 |
|---|---|---|
send_message(msg) | void | プレイヤーにチャットメッセージを送信する。& カラーコードに対応。 |
get_held_item() | table or nil | プレイヤーのメインハンドのアイテムについて {type, amount, display_name} を返す。空なら nil。 |
consume_held_item(amount?) | void | プレイヤーのメインハンドからアイテムを消費する。amount のデフォルトは 1。 |
has_item(material, amount?) | boolean | プレイヤーのインベントリ内のいずれかに指定マテリアルが少なくとも amount(デフォルト 1)あれば true を返す。 |
get_target_entity([range]) | entity table or nil | レイキャストでプレイヤーが見ているエンティティを返す。なければ nil。デフォルト射程は 50。 |
get_eye_location() | location table | プレイヤーの目の高さでの location テーブルを返す。 |
get_look_direction() | table | プレイヤーが向いている方向の {x, y, z} ベクトルを返す。 |
send_block_change(x, y, z, material, [ticks]) | boolean | このプレイヤーにのみ見える偽ブロックを送る。ticks が指定されていれば、その期間後に偽ブロックは自動的に元に戻る。成功すれば true、マテリアルが無効なら false を返す。 |
reset_block(x, y, z) | boolean | このプレイヤーにとって偽ブロックを実際のブロックに戻す。常に true を返す。 |
sleep(x, y, z) | void | プレイヤーを指定座標でベッド睡眠アニメーションに入らせる。プレイヤーが睡眠を止めたときブロックは自動的に復元される。 |
wake_up() | void | 睡眠中のプレイヤーを起こす。 |
プレイヤー UI メソッド
これらのメソッドは任意のプレイヤーエンティティテーブルで利用でき、Minecraft 内蔵の UI 要素を通じてプレイヤーに情報を表示する手段を提供します。
player:show_boss_bar(text, [color], progress, [ticks])
プレイヤーにボスバーを表示します。
| パラメータ | 型 | デフォルト | 備考 |
|---|---|---|---|
text | string | 必須 | 表示するテキスト。& カラーコードに対応。 |
color | string | "WHITE" | バーの色。次のいずれか: "RED"、"BLUE"、"GREEN"、"YELLOW"、"PURPLE"、"PINK"、"WHITE" |
progress | number | 必須 | 0.0(空)から 1.0(満杯)までの充填量 |
ticks | int | nil | 自動消去までの遅延 tick(任意)。省略すると手動で消されるまで残る。 |
player:hide_boss_bar()
プレイヤー画面からボスバーを削除します。引数はありません。
player:show_action_bar(text, [ticks])
アクションバー領域(ホットバーの上)にテキストを表示します。
| パラメータ | 型 | デフォルト | 備考 |
|---|---|---|---|
text | string | 必須 | 表示するテキスト。& カラーコードに対応。 |
ticks | int | nil | 任意の表示時間(tick)。指定すると 40 tick ごとに再送信されて指定期間表示され続ける。 |
player:show_title(title, [subtitle], fade_in, stay, fade_out)
プレイヤーにタイトル画面を表示します。
| パラメータ | 型 | デフォルト | 備考 |
|---|---|---|---|
title | string | 必須 | メインタイトルのテキスト。& カラーコードに対応。 |
subtitle | string | "" | メインタイトルの下に表示されるサブタイトル。任意。 |
fade_in | int | 必須 | フェードインの時間(tick) |
stay | int | 必須 | タイトルが画面に表示され続ける時間(tick) |
fade_out | int | 必須 | フェードアウトの時間(tick) |
Next Steps
プラグイン固有のフック、API、ワークフローについて:
- EliteMobs: はじめに | フックとライフサイクル | ボスとエンティティ | ワールドと環境 | ゾーンとターゲティング
- FreeMinecraftModels: はじめに | プロップとアイテム API | 例