MagmaCore Lua Scripting-Engine
MagmaCore stellt eine gemeinsame Lua-Scripting-Engine bereit, die von mehreren Nightbreak-Plugins verwendet wird. Die Engine übernimmt Sandboxing, Scheduling, Zonenverwaltung, Weltinteraktion, Entity-Tabellen und Spieler-UI -- alles mit einer konsistenten API über alle Plugins hinweg.
Aktuell verwenden folgende Plugins diese Engine:
- EliteMobs -- Lua-Kräfte für benutzerdefinierte Bosse (Hooks wie
on_boss_damaged_by_player,on_enter_combat, etc.) - FreeMinecraftModels -- Lua-Skripte für Props und benutzerdefinierte Items (Hooks wie
on_right_click,on_left_click,on_equip, etc.)
Diese Seite dokumentiert die gemeinsamen Engine-Funktionen. Für plugin-spezifische Hooks, APIs und Workflows siehe die oben verlinkten Plugin-Seiten.
Kleiner Lua-Einstieg
Wenn du komplett neu bei Lua bist, hier ist die minimale Syntax, die du zum Schreiben von Skripten für jedes Nightbreak-Plugin brauchst.
Variablen
Verwende local, um einen Wert zu speichern:
local cooldown_key = "fire_burst"
local damage_multiplier = 1.5
local bedeutet, dass die Variable nur zu dieser Datei oder diesem Block gehört.
Funktionen
Funktionen sind wiederverwendbare Logikblöcke:
local function warn_player(player)
player:send_message("&cMove!")
end
Später kannst du sie aufrufen:
warn_player(some_player)
if-Prüfungen
Verwende if, wenn etwas nur manchmal passieren soll:
if context.player == nil then
return
end
Das bedeutet "wenn es für diesen Hook keinen Spieler gibt, hier aufhören".
nil
nil bedeutet "kein Wert". Es ist Luas Version von "hier ist nichts".
Du wirst oft auf nil prüfen mit:
if context.event ~= nil then
-- do something with the event
end
~= bedeutet "ist nicht gleich".
Tabellen
Lua verwendet Tabellen für verschiedene Aufgaben:
- Listen
- Objekte mit benannten Schlüsseln
- Die endgültige zurückgegebene Skript-Definition
Beispiel einer Tabelle mit benannten Schlüsseln:
local particle = {
particle = "FLAME",
amount = 1,
speed = 0.05
}
Die Skript-Definition zurückgeben
Am Ende jeder Skriptdatei gibst du eine Tabelle zurück:
return {
api_version = 1,
on_spawn = function(context)
end
}
Diese zurückgegebene Tabelle ist die Skriptdatei.
Kommentare
Verwende --, um eine Notiz für Menschen zu schreiben:
-- This cooldown stops the attack from firing every hit
context.cooldowns:set_local(60, "fire_burst")
Lua-Sandbox
Alle Lua-Skripte laufen innerhalb einer gesandboxten LuaJ-Umgebung. Mehrere Globals, die auf das Dateisystem oder die Java-Laufzeit zugreifen könnten, werden entfernt. Die Sandbox-Regeln sind über alle Plugins hinweg identisch, die MagmaCore verwenden.
Entfernte Globals
Die folgenden Standard-Lua-Globals sind auf nil gesetzt und können nicht verwendet werden:
| Entfernt | Grund |
|---|---|
debug | Legt internen VM-Zustand offen |
dofile | Dateisystemzugriff |
io | Dateisystemzugriff |
load | Laden von beliebigem Code |
loadfile | Dateisystemzugriff |
luajava | Direkter Java-Klassenzugriff |
module | Modulsystem (nicht benötigt) |
os | Betriebssystemzugriff |
package | Modulsystem (nicht benötigt) |
require | Modulsystem / Dateisystemzugriff |
Verfügbare Standardbibliothek
Alles andere aus der Lua-Standardbibliothek funktioniert normal:
| Kategorie | Funktionen |
|---|---|
| Math | math.abs, math.ceil, math.floor, math.max, math.min, math.random, math.sin, math.cos, math.sqrt, math.pi und alle anderen math.*-Funktionen |
| String | string.byte, string.char, string.find, string.format, string.gsub, string.len, string.lower, string.match, string.rep, string.sub, string.upper und alle anderen string.*-Funktionen |
| Table | table.insert, table.remove, table.sort, table.concat und alle anderen table.*-Funktionen |
| Iteratoren | pairs, ipairs, next |
| Typ | type, tostring, tonumber, select, unpack |
| Fehlerbehandlung | pcall, xpcall, error, assert |
| Andere | print, rawget, rawset, rawequal, rawlen, setmetatable, getmetatable |
os-Bibliothek ist nicht verfügbarDie os-Bibliothek ist vollständig aus der Sandbox entfernt. Wenn du Zeitinformationen benötigst, verwende context.world:get_time() für die Weltzeit oder speichere Zeitstempel in context.state unter Verwendung von Tick-Zählern mit on_tick / on_game_tick.
print schreibt in die Serverkonsole, aber bevorzuge context.log:info(msg) für die Ausgabe. Log-Nachrichten werden mit dem Skript-Dateinamen versehen, was es einfacher macht, nachzuvollziehen, welches Skript die Nachricht erzeugt hat.
Dateivertrag
Jedes Lua-Skript muss eine Tabelle returnen. Diese Tabelle ist absichtlich strikt.
Erforderliche und optionale Top-Level-Felder
| Feld | Erforderlich | Typ | Hinweise |
|---|---|---|---|
api_version | Ja | Number | Muss aktuell 1 sein |
priority | Nein | Number | Ausführungspriorität. Niedrigere Werte werden zuerst ausgeführt. Standard ist 0 |
| unterstützte Hook-Schlüssel | Nein | Function | Muss einen der genauen Hook-Namen verwenden, die vom Plugin unterstützt werden |
Validierungsregeln
- Die Datei muss eine Tabelle zurückgeben.
api_versionist erforderlich und muss aktuell1sein.prioritymuss numerisch sein, falls vorhanden.- Jeder zusätzliche Top-Level-Schlüssel muss ein unterstützter Hook-Name sein.
- Jeder Hook-Schlüssel muss auf eine Funktion verweisen.
- Unbekannte Top-Level-Schlüssel werden abgelehnt.
Hilfsfunktionen und lokale Konstanten sollten über dem finalen return leben, nicht innerhalb der zurückgegebenen Tabelle, es sei denn, sie sind tatsächliche Hooks.
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
}
Methodensyntax: : vs .
In Lua ist object:method(arg) eine Kurzform für object.method(object, arg). Die MagmaCore-API akzeptiert beide Formen, also funktioniert beides:
context.log:info("hello")
context.log.info("hello") -- same thing
Die gesamte Dokumentation verwendet konsistent :.
Ausführungsbudget
Jeder Hook-Aufruf und jeder Callback-Aufruf wird gemessen. Wenn ein einzelner Aufruf länger als 50 Millisekunden dauert, wird das Skript mit einer Konsolenwarnung deaktiviert:
[Lua] my_script.lua took 73ms in 'on_game_tick' (limit: 50ms) -- script disabled to prevent lag.
Um im Budget zu bleiben:
- Vermeide unbegrenzte Schleifen innerhalb von Hooks.
- Halte
on_game_tick/on_tick-Handler leichtgewichtig -- sie laufen jeden einzelnen Tick. - Verwende
context.scheduler:run_repeating(...), um Arbeit über Ticks zu verteilen. - Verschiebe aufwändige Arbeit hinter einen zustandsbasierten Cooldown oder ein vernünftiges Intervall.
context.state
Eine einfache Lua-Tabelle, die für die gesamte Lebensdauer der Skript-Instanz bestehen bleibt. Verwende sie, um Flags, Zähler, Task-IDs, Umschaltzustände und alle Daten zu speichern, die du zwischen Hooks teilen musst.
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
Nur context.state bleibt zwischen Hook-Aufrufen erhalten. Alle anderen Context-Tabellen (context.prop, context.world, context.event, etc.) werden jedes Mal neu erstellt. context.state wird nicht neu erstellt -- es überlebt vom Moment der Erstellung der Skript-Instanz bis zu ihrer Zerstörung.
context.log
Konsolenlogging-Methoden. Nachrichten werden in der Serverkonsole mit dem Skript-Dateinamen versehen.
| Methode | Hinweise |
|---|---|
log:info(message) | Informationsnachricht |
log:warn(message) | Warnmeldung |
log:error(message) | Warnstufennachricht (auf WARN-Level geloggt, gleich wie log:warn) |
log:debug(message) | Debug-Nachricht (erscheint als Info-Level mit einem Debug-Prefix) |
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
Die Cooldowns-Tabelle verwaltet zeitbasierte Cooldowns für deine Skripte. Es gibt zwei Gültigkeitsbereiche:
- Lokale Cooldowns sind pro Skript-Instanz und werden durch einen String-Schlüssel identifiziert. Wenn kein Schlüssel angegeben wird, wird der Dateiname des Skripts als Standard-Schlüssel verwendet.
- Globale Cooldowns werden zwischen allen Skripten desselben Entity-Besitzers geteilt (z.B. alle Skripte auf demselben Prop oder alle Lua-Kräfte auf demselben Boss).
cooldowns:check_local(key?, duration)
Die am häufigsten verwendete Methode. Prüft, ob der Cooldown bereit ist, und wenn ja, startet ihn und gibt true zurück. Wenn nicht bereit, gibt false zurück. Dies ist ein atomares Check-and-Set -- keine Race Conditions.
| Parameter | Typ | Hinweise |
|---|---|---|
key | string (optional) | Cooldown-Identifikator. Standard ist der Skript-Dateiname. |
duration | int | Cooldown-Dauer in Ticks (20 = 1 Sekunde) |
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?)
Gibt true zurück, wenn der lokale Cooldown abgelaufen ist (oder nie gesetzt wurde), false wenn noch aktiv.
cooldowns:local_remaining(key?)
Gibt die Anzahl verbleibender Ticks auf dem lokalen Cooldown zurück, oder 0 wenn bereit.
cooldowns:set_local(duration, key?)
Setzt einen lokalen Cooldown, ohne zu prüfen, ob bereits einer aktiv ist. Verwende dies für bedingungslose Cooldown-Resets.
| Parameter | Typ | Hinweise |
|---|---|---|
duration | int | Dauer in Ticks. Übergib 0 oder negativ zum Löschen. |
key | string (optional) | Cooldown-Identifikator. Standard ist der Skript-Dateiname. |
cooldowns:global_ready()
Gibt true zurück, wenn der globale Cooldown (geteilt zwischen allen Skripten desselben Entities) abgelaufen ist.
cooldowns:set_global(duration)
Setzt den globalen Cooldown.
| Parameter | Typ | Hinweise |
|---|---|---|
duration | int | Dauer in Ticks |
In EliteMobs Power-Skripten verwenden global_ready() und set_global() das eingebaute Power-Cooldown-System des Bosses, das zwischen allen Lua-Kräften desselben Bosses geteilt wird. Lokale Cooldowns in EliteMobs werden ebenfalls zwischen allen Kräften derselben Boss-Entity geteilt (identifiziert durch deinen gewählten String).
context.scheduler
Der Scheduler ermöglicht es dir, verzögerte und sich wiederholende Tasks auszuführen. Alle Tasks gehören zur Skript-Instanz und werden automatisch abgebrochen, wenn die Skript-Instanz zerstört wird (z.B. wenn ein Prop entfernt wird oder ein Boss stirbt).
scheduler:run_later(ticks, callback)
Führt einen Callback einmal nach einer Verzögerung aus. Gibt eine numerische Task-ID zurück.
| Parameter | Typ | Hinweise |
|---|---|---|
ticks | int | Verzögerung in Server-Ticks (20 Ticks = 1 Sekunde) |
callback | function | Wird mit einem frischen context aufgerufen, wenn die Verzögerung abläuft |
context.scheduler:run_later(40, function(delayed_context)
delayed_context.log:info("2 seconds have passed!")
end)
scheduler:run_repeating(delay, interval, callback)
Führt einen Callback wiederholt in einem festen Intervall aus. Gibt eine numerische Task-ID zurück.
| Parameter | Typ | Hinweise |
|---|---|---|
delay | int | Anfangsverzögerung in Ticks vor dem ersten Durchlauf |
interval | int | Ticks zwischen jedem folgenden Durchlauf |
callback | function | Wird mit einem frischen context bei jedem Intervall aufgerufen |
context.state.particle_task = context.scheduler:run_repeating(0, 20, function(tick_context)
tick_context.log:info("Another second passed!")
end)
scheduler:cancel(taskId)
Bricht einen geplanten Task anhand seiner ID ab.
| Parameter | Typ | Hinweise |
|---|---|---|
taskId | int | Die Task-ID, die von run_later oder run_repeating zurückgegeben wurde |
Wenn du einen wiederholenden Task startest, breche ihn immer in deinem Aufräum-Hook ab (on_destroy für Props, on_exit_combat / on_death für Bosse, on_unequip für Items). Das Vergessen des Abbrechens lässt einen Hintergrund-Task laufen, bis die Skript-Instanz zerstört wird, was Leistung verschwendet und Fehler verursachen kann.
Geplante Callbacks erhalten einen frischen Context als Parameter. Verwende immer das eigene Context-Argument des Callbacks, nicht den äußeren context aus dem Hook, der den Callback erstellt hat. Der äußere Context kann veraltete Referenzen enthalten.
context.world
Die World-Tabelle bietet Methoden zum Abfragen und Interagieren mit der Minecraft-Welt. Sie wird aus der aktuellen Welt des Entities erstellt.
EliteMobs erweitert context.world um zusätzliche Methoden zum Spawnen von Bossen, Verstärkungen, fallenden Blöcken, Feuerwerk, Wurftränken und temporären Blöcken. Siehe EliteMobs Welt & Umgebung für die vollständige erweiterte API. Die hier dokumentierten Methoden sind über alle Plugins hinweg verfügbar.
world.name
Ein String-Feld, das den Weltnamen enthält.
world:get_block_at(x, y, z)
Gibt den Materialnamen des Blocks an den gegebenen Koordinaten als kleingeschriebenen String zurück (z.B. "stone", "air").
| Parameter | Typ | Hinweise |
|---|---|---|
x | int | Block-X-Koordinate |
y | int | Block-Y-Koordinate |
z | int | Block-Z-Koordinate |
world:set_block_at(x, y, z, material)
Setzt den Block an den gegebenen Koordinaten. Läuft auf dem Hauptthread.
| Parameter | Typ | Hinweise |
|---|---|---|
x | int | Block-X-Koordinate |
y | int | Block-Y-Koordinate |
z | int | Block-Z-Koordinate |
material | string | Bukkit Material-Name, kleingeschrieben (z.B. "stone", "air", "oak_planks") |
Gibt true zurück, wenn der Block erfolgreich gesetzt wurde, andernfalls false.
world:spawn_particle(particle, x, y, z, count, dx, dy, dz, speed)
Spawnt Partikel an einem Ort.
| Parameter | Typ | Standard | Hinweise |
|---|---|---|---|
particle | string | erforderlich | Bukkit Particle-Enum-Name, GROSSBUCHSTABEN (z.B. "FLAME", "DUST") |
x | number | erforderlich | X-Koordinate |
y | number | erforderlich | Y-Koordinate |
z | number | erforderlich | Z-Koordinate |
count | int | 1 | Anzahl der Partikel |
dx | number | 0 | X-Streuung/Versatz |
dy | number | 0 | Y-Streuung/Versatz |
dz | number | 0 | Z-Streuung/Versatz |
speed | number | 0 | Partikelgeschwindigkeit |
Einige Partikeltypen erfordern Block- oder Item-Daten, die von dieser einfachen API nicht unterstützt werden. BLOCK_CRACK, FALLING_DUST, BLOCK_DUST und ITEM_CRACK werden fehlschlagen oder keinen sichtbaren Effekt erzeugen. Verwende stattdessen datenfreie Alternativen: CLOUD, SMOKE, CAMPFIRE_COSY_SMOKE, SNOWFLAKE, FLAME, DUST, etc.
world:play_sound(sound, x, y, z, volume, pitch)
Spielt einen Sound an einem Ort ab.
| Parameter | Typ | Standard | Hinweise |
|---|---|---|---|
sound | string | erforderlich | Bukkit Sound-Enum-Name, GROSSBUCHSTABEN (z.B. "ENTITY_EXPERIENCE_ORB_PICKUP") |
x | number | erforderlich | X-Koordinate |
y | number | erforderlich | Y-Koordinate |
z | number | erforderlich | Z-Koordinate |
volume | number | 1.0 | Lautstärke |
pitch | number | 1.0 | Tonhöhe |
world:strike_lightning(x, y, z)
Schlägt Blitz an einem Ort ein (visuell und schadensverursachend).
| Parameter | Typ | Hinweise |
|---|---|---|
x | number | X-Koordinate |
y | number | Y-Koordinate |
z | number | Z-Koordinate |
world:get_time()
Gibt die aktuelle Weltzeit in Ticks zurück.
world:set_time(ticks)
Setzt die Weltzeit.
| Parameter | Typ | Hinweise |
|---|---|---|
ticks | int | Weltzeit (0 = Morgendämmerung, 6000 = Mittag, 13000 = Nacht, 18000 = Mitternacht) |
world:get_nearby_entities(x, y, z, radius)
Gibt ein Array von Entity-Wrapper-Tabellen für alle Entities innerhalb einer Bounding-Box zurück, die an den gegebenen Koordinaten zentriert ist.
| Parameter | Typ | Hinweise |
|---|---|---|
x | number | Zentrum X |
y | number | Zentrum Y |
z | number | Zentrum Z |
radius | number | Suchradius (als halbe Ausdehnung in allen drei Achsen verwendet) |
Dies gibt ALLE Entities in Reichweite zurück, einschließlich nicht-lebender Entities (Rüstungsständer, gedropte Items, etc.). Schütze immer mit if entity.damage then, bevor du Methoden für lebende Entities aufrufst.
world:get_nearby_players(x, y, z, radius)
Gibt ein Array von Spieler-Wrapper-Tabellen für alle Spieler innerhalb einer Bounding-Box zurück, die an den gegebenen Koordinaten zentriert ist.
| Parameter | Typ | Hinweise |
|---|---|---|
x | number | Zentrum X |
y | number | Zentrum Y |
z | number | Zentrum Z |
radius | number | Suchradius |
world:spawn_entity(entity_type, x, y, z)
Spawnt ein Vanilla-Minecraft-Entity am gegebenen Ort.
| Parameter | Typ | Hinweise |
|---|---|---|
entity_type | string | Bukkit Entity-Typ-Name, kleingeschrieben (z.B. "zombie", "skeleton", "pig") |
x | number | X-Koordinate |
y | number | Y-Koordinate |
z | number | Z-Koordinate |
Gibt eine Entity-Tabelle für das gespawnte Entity zurück (mit Methoden für lebende Entities, falls zutreffend), oder nil, wenn der Entity-Typ ungültig ist.
world:get_highest_block_y(x, z)
Gibt die Y-Koordinate des höchsten Nicht-Luft-Blocks an der gegebenen X/Z-Position zurück.
| Parameter | Typ | Hinweise |
|---|---|---|
x | int | Block-X-Koordinate |
z | int | Block-Z-Koordinate |
world:raycast(from_x, from_y, from_z, dir_x, dir_y, dir_z, [max_distance])
Wirft einen Strahl von einem Punkt in eine Richtung und gibt Informationen darüber zurück, was er trifft.
| Parameter | Typ | Standard | Hinweise |
|---|---|---|---|
from_x | number | erforderlich | Ursprung X |
from_y | number | erforderlich | Ursprung Y |
from_z | number | erforderlich | Ursprung Z |
dir_x | number | erforderlich | Richtung X-Komponente |
dir_y | number | erforderlich | Richtung Y-Komponente |
dir_z | number | erforderlich | Richtung Z-Komponente |
max_distance | number | 50 | Maximale Strahldistanz |
Gibt eine Tabelle mit folgenden Feldern zurück:
| Feld | Typ | Hinweise |
|---|---|---|
hit_entity | Entity-Tabelle oder nil | Das erste vom Strahl getroffene Entity, oder nil wenn keines |
hit_location | Location-Tabelle oder nil | Der genaue Punkt, an dem der Strahl etwas getroffen hat |
hit_block | Tabelle oder nil | {x, y, z, material} des getroffenen Blocks, oder nil wenn kein Block getroffen wurde |
world:spawn_firework(x, y, z, colors, [type], [power])
Spawnt eine Feuerwerksrakete am gegebenen Ort.
| Parameter | Typ | Standard | Hinweise |
|---|---|---|---|
x | number | erforderlich | X-Koordinate |
y | number | erforderlich | Y-Koordinate |
z | number | erforderlich | Z-Koordinate |
colors | table | erforderlich | Array von Farb-Strings, z.B. {"RED", "BLUE", "WHITE"} |
type | string | "BALL" | Feuerwerksform: "BALL", "BALL_LARGE", "STAR", "BURST", "CREEPER" |
power | int | 1 | Flugkraft, 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])
Platziert einen Block, der nach einer Verzögerung automatisch in seinen ursprünglichen Zustand zurückkehrt.
| Parameter | Typ | Standard | Hinweise |
|---|---|---|---|
x | int | erforderlich | Block-X-Koordinate |
y | int | erforderlich | Block-Y-Koordinate |
z | int | erforderlich | Block-Z-Koordinate |
material | string | erforderlich | Bukkit Material-Name (z.B. "stone", "ice") |
ticks | int | 0 | Dauer in Ticks, bevor der Block zurückkehrt. 0 bedeutet permanent. |
require_air | boolean | false | Wenn true, wird der Block nur platziert, wenn das Ziel Luft ist |
Gibt true zurück, wenn der Block platziert wurde, false, wenn das Material ungültig war oder die Luft-Anforderung nicht erfüllt wurde.
world:drop_item(x, y, z, material, [amount])
Lässt ein Item-Entity am gegebenen Ort mit natürlicher Streuung fallen.
| Parameter | Typ | Standard | Hinweise |
|---|---|---|---|
x | number | erforderlich | X-Koordinate |
y | number | erforderlich | Y-Koordinate |
z | number | erforderlich | Z-Koordinate |
material | string | erforderlich | Bukkit Material-Name |
amount | int | 1 | Stapelgröße |
Gibt eine Entity-Tabelle für das fallengelassene Item zurück, oder nil, wenn das Material ungültig war.
context.zones
Die Zones-Tabelle ermöglicht es dir, räumliche Zonen zu erstellen und sie auf Spieler-Betreten/Verlassen-Events zu überwachen. Zonen sind an die Skript-Instanz gebunden und werden automatisch bereinigt, wenn die Skript-Instanz zerstört wird.
zones:create_sphere(x, y, z, radius)
Erstellt eine Kugelzone, die an den gegebenen Koordinaten zentriert ist. Gibt einen numerischen Zonen-Handle zurück.
| Parameter | Typ | Hinweise |
|---|---|---|
x | number | Zentrum X |
y | number | Zentrum Y |
z | number | Zentrum Z |
radius | number | Kugelradius |
zones:create_cylinder(x, y, z, radius, height)
Erstellt eine Zylinderzone. Gibt einen numerischen Zonen-Handle zurück.
| Parameter | Typ | Hinweise |
|---|---|---|
x | number | Zentrum X |
y | number | Zentrum Y (Basis) |
z | number | Zentrum Z |
radius | number | Zylinderradius |
height | number | Zylinderhöhe |
zones:create_cuboid(x, y, z, xSize, ySize, zSize)
Erstellt eine Quaderzone. Gibt einen numerischen Zonen-Handle zurück.
| Parameter | Typ | Hinweise |
|---|---|---|
x | number | Zentrum X |
y | number | Zentrum Y |
z | number | Zentrum Z |
xSize | number | Halbe Ausdehnung in X |
ySize | number | Halbe Ausdehnung in Y |
zSize | number | Halbe Ausdehnung in Z |
zones:watch(handle, onEnterCallback, onLeaveCallback)
Beginnt die Überwachung einer Zone auf Spieler-Betreten/Verlassen-Events. Wenn ein Spieler die Zone betritt oder verlässt, wird der entsprechende Callback ausgelöst (und, falls definiert, die on_zone_enter / on_zone_leave-Hooks).
| Parameter | Typ | Hinweise |
|---|---|---|
handle | int | Zonen-Handle von einem create_*-Aufruf |
onEnterCallback | function oder nil | Wird aufgerufen, wenn ein Spieler die Zone betritt |
onLeaveCallback | function oder nil | Wird aufgerufen, wenn ein Spieler die Zone verlässt |
Gibt true zurück, wenn die Überwachung erfolgreich eingerichtet wurde, nil wenn der Zonen-Handle ungültig war.
Zonenüberwachungen werden jeden Server-Tick gegen alle Spieler in derselben Welt geprüft. Halte die Zonenanzahl vernünftig, um Performance-Overhead zu vermeiden.
zones:unwatch(handle)
Stoppt die Überwachung einer Zone und bereinigt ihre Ressourcen.
| Parameter | Typ | Hinweise |
|---|---|---|
handle | int | Zonen-Handle, dessen Überwachung gestoppt werden soll |
Beispiel: Näherungstrigger-Zone
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
Die Event-Tabelle ist vorhanden, wenn der aktuelle Hook durch ein Spielereignis ausgelöst wurde (z.B. on_right_click, on_zone_enter). Sie ist nicht vorhanden während on_tick oder geplanten Callbacks.
| Feld / Methode | Typ | Hinweise |
|---|---|---|
is_cancelled | boolean | Ob das Event abgebrochen wurde |
cancel() | method | Bricht das Event ab (verhindert das Standardverhalten) |
uncancel() | method | Hebt den Abbruch eines zuvor abgebrochenen Events auf |
player | entity table | Der am Event beteiligte Spieler, falls vorhanden |
on_right_click = function(context)
if context.event then
context.event:cancel() -- prevent the default right-click interaction
end
end
EliteMobs Power-Skripte haben eine detailliertere Event-Tabelle mit Schadensbeträgen, Schadensursachen, Angreifer-Referenzen und Schadensmodifikationsmethoden. Siehe Lua API-Referenz für die vollständigen EliteMobs-Event-Felder.
em-Hilfs-Namespace
Die em-Tabelle ist zur Dateiladezeit verfügbar (bevor ein Hook ausgeführt wird). Sie bietet Hilfskonstruktoren zum Erstellen von Location-Tabellen, Vektor-Tabellen und Zonendefinitionen, die in der gesamten API verwendet werden.
| Funktion | Zweck |
|---|---|
em.create_location(x, y, z [, world, yaw, pitch]) | Erstellt eine Location-Tabelle mit optionalem Weltnamen, Yaw und Pitch. Die zurückgegebene Tabelle hat auch eine .add(dx, dy, dz)-Methode, die die Location in-place versetzt und sich selbst für Verkettung zurückgibt. |
em.create_vector(x, y, z) | Erstellt eine Vektor-Tabelle |
em.zone.create_sphere_zone(radius) | Erstellt eine Kugelzonen-Definition |
em.zone.create_dome_zone(radius) | Erstellt eine Kuppelzonen-Definition |
em.zone.create_cylinder_zone(radius, height) | Erstellt eine Zylinderzonen-Definition |
em.zone.create_cuboid_zone(x, y, z) | Erstellt eine Quaderzonen-Definition |
em.zone.create_cone_zone(length, radius) | Erstellt eine Kegelzonen-Definition |
em.zone.create_static_ray_zone(length, thickness) | Erstellt eine statische Strahlzonen-Definition |
em.zone.create_rotating_ray_zone(length, point_radius, animation_duration) | Erstellt eine rotierende Strahlzonen-Definition |
em.zone.create_translating_ray_zone(length, point_radius, animation_duration) | Erstellt eine sich verschiebende Strahlzonen-Definition |
Zonen-Builder geben verkettbare Tabellen mit :set_center(loc) (oder :set_origin(loc) / :set_destination(loc) je nach Zonentyp) zurück:
-- 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
}
Der em-Namespace ist besonders nützlich in EliteMobs, wo Zonendefinitionen mit context.zones:get_entities_in_zone() und context.script verwendet werden. In FreeMinecraftModels werden die context.zones:create_sphere(...) / create_cylinder(...) / create_cuboid(...)-Methoden häufiger für einfache überwachungsbasierte Zonen verwendet.
Entity-Tabellen
Entity-Tabellen werden von Weltabfragen, Eventdaten und Zonen-Callbacks zurückgegeben. Sie bieten einen geschichteten Satz von Feldern und Methoden, abhängig vom Entity-Typ.
Entity-Basisfelder
| Feld | Typ | Hinweise |
|---|---|---|
uuid | string | Die UUID des Entities |
entity_type | string | Der Entity-Typ (z.B. "player", "zombie", "skeleton", "villager") |
is_valid | boolean | Ob die Entity-Referenz noch gültig ist |
is_dead | boolean | Ob das Entity tot ist |
is_player | boolean | Ob das Entity ein Spieler ist |
is_hostile | boolean | Ob das Entity ein feindlicher Mob ist (Zombie, Skelett, etc.) |
is_passive | boolean | Ob das Entity ein passiver Mob ist (Kuh, Schwein, Huhn, etc.) |
current_location | Location-Tabelle | Die aktuelle Position des Entities (x, y, z, world, yaw, pitch) |
world | string | Der Weltname, in dem sich das Entity befindet |
Entity-Basismethoden
| Methode | Rückgabe | Hinweise |
|---|---|---|
teleport(location_table) | void | Teleportiert das Entity. Die Location-Tabelle muss x, y, z, world-Felder haben; yaw und pitch sind optional. |
remove() | void | Entfernt das Entity aus der Welt. Reagiert nur, wenn das Entity noch gültig ist. |
set_silent(flag) | void | Unterdrückt oder reaktiviert die Geräusche des Entities. |
set_invulnerable(flag) | void | Macht das Entity unverwundbar oder verwundbar gegen Schaden. |
set_gravity(flag) | void | Aktiviert oder deaktiviert die Schwerkraft für das Entity. |
set_glowing(flag) | void | Schaltet den leuchtenden Umrisseffekt auf dem Entity um. |
Felder für lebende Entities
Lebende Entities (Spieler, Mobs, etc.) haben alle Entity-Basisfelder plus:
| Feld | Typ | Hinweise |
|---|---|---|
health | number | Aktuelle Gesundheit |
maximum_health | number | Maximale Gesundheit |
name | string | Anzeigename |
is_alive | boolean | Ob das Entity am Leben ist |
Methoden für lebende Entities
| Methode | Rückgabe | Hinweise |
|---|---|---|
damage(amount) | void | Fügt dem Entity den angegebenen Schadensbetrag zu |
push(x, y, z) | void | Wendet einen Geschwindigkeitsimpuls an |
set_facing(x, y, z) | void | Setzt die Blickrichtung des Entities |
add_potion_effect(effect, duration, amplifier) | void | Fügt einen Trankeffekt hinzu. effect ist ein String (z.B. "speed", "slowness", "regeneration"). duration ist in Ticks. amplifier ist die Effektstufe minus 1 (0 = Stufe I). |
remove_potion_effect(effect) | void | Entfernt einen Trankeffekt nach Name |
Nicht alle Entities, die von get_nearby_entities() zurückgegeben werden, sind lebende Entities. Du kannst entity.is_player, entity.is_hostile oder entity.is_passive verwenden, um nach Kategorie zu filtern, oder if entity.damage then prüfen, bevor du Methoden für lebende Entities wie damage(), push() oder add_potion_effect() aufrufst.
Plugin-Integrationsfelder
Entity-Tabellen enthalten automatisch Felder zur Erkennung und Interaktion mit Entities, die von anderen Nightbreak-Plugins verwaltet werden. Diese Felder werden nur befüllt, wenn das entsprechende Plugin installiert ist -- andernfalls haben sie standardmäßig false / nil ohne Overhead.
EliteMobs-Felder
Verfügbar, wenn EliteMobs installiert ist.
| Feld | Typ | Hinweise |
|---|---|---|
is_elite | boolean | Ob das Entity ein EliteMobs-Elite ist |
is_custom_boss | boolean | Ob das Entity ein EliteMobs Custom Boss ist (auch in der elite-Untertabelle verfügbar) |
is_significant_boss | boolean | Ob das Entity ein Custom Boss mit einem Gesundheitsmultiplikator über 1 ist (d.h. ein designtes Encounter, kein Füller-Elite) |
elite | Tabelle oder nil | Elite-Info-Untertabelle (siehe unten). nil wenn das Entity kein Elite ist. |
Die elite-Untertabelle enthält:
| Feld | Typ | Hinweise |
|---|---|---|
elite.level | int | Das Level des Elites |
elite.name | string | Der Anzeigename des Elites |
elite.health | number | Aktuelle Gesundheit |
elite.max_health | number | Maximale Gesundheit |
elite.is_custom_boss | boolean | Ob dies ein Custom Boss ist (im Gegensatz zu einem natürlichen Elite) |
elite.health_multiplier | number | Konfigurationsdefinierter Gesundheitsmultiplikator |
elite.damage_multiplier | number | Konfigurationsdefinierter Schadensmultiplikator |
elite:remove() | void | Entfernt den Elite über EliteMobs' ordnungsgemäße Entfernungspipeline (bereinigt Tracking, Loot, etc.) |
Beispiel: Elites unterschiedlich beschädigen
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-Felder
Verfügbar, wenn FreeMinecraftModels installiert ist.
| Feld | Typ | Hinweise |
|---|---|---|
is_modeled | boolean | Ob das Entity ein FMM-Modell angehängt hat (DynamicEntity oder PropEntity) |
is_prop | boolean | Ob das Entity ein FMM-Prop ist (statisches dekoratives Entity) |
model | Tabelle oder nil | Modell-Info-Untertabelle (siehe unten). nil wenn das Entity nicht modelliert ist. |
Die model-Untertabelle enthält:
| Feld | Typ | Hinweise |
|---|---|---|
model.model_id | string | Die Modell-Blueprint-ID (z.B. "torch_01") |
model:play_animation(name, [blend], [loop]) | boolean | Spielt eine benannte Animation ab. blend ist standardmäßig false, loop standardmäßig false. Gibt true zurück, wenn die Animation gefunden wurde. |
model:stop_animations() | void | Stoppt alle aktuell abgespielten Animationen auf dem Modell. |
model:remove() | void | Entfernt das modellierte Entity über FMMs ordnungsgemäße Entfernungspipeline. |
Die Modell-Bridge (verfügbar auf jedem Entity) setzt blend und loop standardmäßig auf false. Die Prop-Tabelle play_animation setzt beide standardmäßig auf true, da Props typischerweise überblendete, sich wiederholende Animationen wünschen.
Beispiel: Entities nach Typ filtern
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
Spieler-spezifische Felder
Spieler-Entities haben alle Entity- und Living-Entity-Felder plus:
| Feld | Typ | Hinweise |
|---|---|---|
game_mode | string | Der Spielmodus des Spielers ("creative", "survival", "adventure", "spectator") |
Spieler-spezifische Methoden
| Methode | Rückgabe | Hinweise |
|---|---|---|
send_message(msg) | void | Sendet eine Chat-Nachricht an den Spieler. Unterstützt &-Farbcodes. |
get_held_item() | Tabelle oder nil | Gibt {type, amount, display_name} für das Item in der Haupthand des Spielers zurück, oder nil wenn leer |
consume_held_item(amount?) | void | Verbraucht Items aus der Haupthand des Spielers. amount ist standardmäßig 1 |
has_item(material, amount?) | boolean | Gibt true zurück, wenn der Spieler mindestens amount (Standard 1) des gegebenen Materials irgendwo im Inventar hat |
get_target_entity([range]) | Entity-Tabelle oder nil | Gibt das Entity zurück, das der Spieler via Raycast anschaut, oder nil wenn keines. Standard-Reichweite ist 50. |
get_eye_location() | Location-Tabelle | Gibt eine Location-Tabelle auf Augenhöhe des Spielers zurück |
get_look_direction() | Tabelle | Gibt einen {x, y, z}-Richtungsvektor zurück, der angibt, wohin der Spieler schaut |
send_block_change(x, y, z, material, [ticks]) | void | Sendet einen gefälschten Block, der nur für diesen Spieler sichtbar ist. Wenn ticks angegeben ist, wird der gefälschte Block nach dieser Dauer automatisch zurückgesetzt. |
reset_block(x, y, z) | void | Setzt einen gefälschten Block für diesen Spieler auf den echten Block zurück |
sleep(x, y, z) | void | Lässt den Spieler eine Bett-Schlafanimation an den gegebenen Koordinaten ausführen. Der Block wird automatisch wiederhergestellt, wenn der Spieler aufhört zu schlafen. |
wake_up() | void | Weckt einen schlafenden Spieler auf. |
Spieler-UI-Methoden
Diese Methoden sind auf jeder Spieler-Entity-Tabelle verfügbar und bieten Möglichkeiten, dem Spieler Informationen über Minecrafts eingebaute UI-Elemente anzuzeigen.
player:show_boss_bar(text, [color], progress, [ticks])
Zeigt dem Spieler eine Bossleiste an.
| Parameter | Typ | Standard | Hinweise |
|---|---|---|---|
text | string | erforderlich | Der anzuzeigende Text. Unterstützt &-Farbcodes. |
color | string | "WHITE" | Leistenfarbe. Eine von: "RED", "BLUE", "GREEN", "YELLOW", "PURPLE", "PINK", "WHITE" |
progress | number | erforderlich | Füllstand von 0.0 (leer) bis 1.0 (voll) |
ticks | int | nil | Optionale automatische Ausblendeverzögerung in Ticks. Wenn weggelassen, bleibt die Leiste, bis sie manuell ausgeblendet wird. |
player:hide_boss_bar()
Entfernt die Bossleiste vom Bildschirm des Spielers. Nimmt keine Parameter entgegen.
player:show_action_bar(text, [ticks])
Zeigt Text im Aktionsleistenbereich an (über der Hotbar).
| Parameter | Typ | Standard | Hinweise |
|---|---|---|---|
text | string | erforderlich | Der anzuzeigende Text. Unterstützt &-Farbcodes. |
ticks | int | nil | Optionale Dauer in Ticks. Falls angegeben, wird die Nachricht alle 40 Ticks erneut gesendet, um sie für die volle Dauer sichtbar zu halten. |
player:show_title(title, [subtitle], fade_in, stay, fade_out)
Zeigt dem Spieler einen Titelbildschirm an.
| Parameter | Typ | Standard | Hinweise |
|---|---|---|---|
title | string | erforderlich | Haupttiteltext. Unterstützt &-Farbcodes. |
subtitle | string | "" | Untertiteltext unter dem Haupttitel. Optional. |
fade_in | int | erforderlich | Einblenddauer in Ticks |
stay | int | erforderlich | Wie lange der Titel auf dem Bildschirm bleibt in Ticks |
fade_out | int | erforderlich | Ausblenddauer in Ticks |
Nächste Schritte
Für plugin-spezifische Hooks, APIs und Workflows:
- EliteMobs: Erste Schritte | Hooks & Lebenszyklus | Boss & Entities | Welt & Umgebung | Zonen & Targeting
- FreeMinecraftModels: Erste Schritte | Prop & Item API | Beispiele