Zum Hauptinhalt springen

MagmaCore Lua-Scripting-Engine

MagmaCore stellt eine gemeinsame Lua-Scripting-Engine bereit, die von mehreren Nightbreak-Plugins genutzt wird. Die Engine kümmert sich um Sandboxing, Scheduling, Zonenverwaltung, Weltinteraktion, Entity-Tabellen und Spieler-UI -- alles mit einer einheitlichen API über alle Plugins hinweg.

Aktuell nutzen die folgenden Plugins diese Engine:

  • EliteMobs -- Lua-Powers für Custom Bosses (Hooks wie on_boss_damaged_by_player, on_enter_combat, usw.)
  • FreeMinecraftModels -- Lua-Skripte für Props und Custom Items (Hooks wie on_right_click, on_left_click, on_equip, usw.)

Diese Seite dokumentiert die gemeinsamen Funktionen der Engine. Plugin-spezifische Hooks, APIs und Arbeitsabläufe findest du auf den oben verlinkten Plugin-Seiten.


Kleine Lua-Einführung

Wenn du komplett neu in Lua bist, ist hier die minimale Syntax, die du brauchst, um Skripte für jedes Nightbreak-Plugin zu schreiben.

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 die Lua-Version von "hier ist nichts".

Häufig prüfst du auf nil mit:

if context.event ~= nil then
-- mach etwas mit dem Event
end

~= bedeutet "ist ungleich".

Tabellen

Lua verwendet Tabellen für verschiedene Zwecke:

  • Listen
  • Objekte mit benannten Schlüsseln
  • Die abschließende zurückgegebene Skriptdefinition

Beispiel für eine Tabelle mit benannten Schlüsseln:

local particle = {
particle = "FLAME",
amount = 1,
speed = 0.05
}

Skriptdefinition 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:

-- Dieser Cooldown verhindert, dass der Angriff bei jedem Treffer auslöst
context.cooldowns:set_local(60, "fire_burst")

Lua-Sandbox

Alle Lua-Skripte laufen in einer abgesicherten LuaJ-Umgebung. Mehrere Globals, die auf das Dateisystem oder die Java-Laufzeit zugreifen könnten, werden entfernt. Die Sandbox-Regeln sind in allen Plugins, die MagmaCore verwenden, identisch.

Entfernte Globals

Die folgenden Lua-Standard-Globals sind auf nil gesetzt und können nicht verwendet werden:

EntferntGrund
debugLegt internen VM-Zustand offen
dofileDateisystemzugriff
ioDateisystemzugriff
loadLaden beliebigen Codes
loadfileDateisystemzugriff
luajavaDirekter Zugriff auf Java-Klassen
moduleModulsystem (nicht benötigt)
osBetriebssystemzugriff
packageModulsystem (nicht benötigt)
requireModulsystem / Dateisystemzugriff

Verfügbare Standardbibliothek

Alles andere aus der Lua-Standardbibliothek funktioniert ganz normal:

KategorieFunktionen
Mathematikmath.abs, math.ceil, math.floor, math.max, math.min, math.random, math.sin, math.cos, math.sqrt, math.pi und alle weiteren math.*-Funktionen
Stringstring.byte, string.char, string.find, string.format, string.gsub, string.len, string.lower, string.match, string.rep, string.sub, string.upper und alle weiteren string.*-Funktionen
Tabelletable.insert, table.remove, table.sort, table.concat und alle weiteren table.*-Funktionen
Iteratorenpairs, ipairs, next
Typentype, tostring, tonumber, select, unpack
Fehlerbehandlungpcall, xpcall, error, assert
Sonstigesprint, rawget, rawset, rawequal, rawlen, setmetatable, getmetatable
Die os-Bibliothek ist nicht verfügbar

Die os-Bibliothek wurde 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 mit Tick-Zählern über den on_game_tick-Hook.

Tipp

print schreibt in die Serverkonsole, doch bevorzuge context.log:info(msg) für die Ausgabe. Logmeldungen werden mit dem Skriptdateinamen versehen, was das Nachverfolgen erleichtert, welches Skript die Meldung erzeugt hat.


Dateivertrag

Jedes Lua-Skript muss eine Tabelle per return zurückgeben. Diese Tabelle ist absichtlich streng.

Erforderliche und optionale Top-Level-Felder

FeldErforderlichTypHinweise
api_versionJaNumberMuss aktuell 1 sein
priorityNeinNumberAusführungspriorität. Niedrigere Werte laufen zuerst. Standard ist 0
Unterstützte Hook-SchlüsselNeinFunctionMuss einer der vom Plugin unterstützten Hook-Namen sein

Validierungsregeln

  • Die Datei muss eine Tabelle zurückgeben.
  • api_version ist erforderlich und muss derzeit 1 sein.
  • priority muss 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 oberhalb des abschließenden return stehen, 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
}

Gemeinsame Engine-Hooks

Die folgenden Hooks stehen allen Plugins zur Verfügung, die die MagmaCore-Scripting-Engine verwenden. Einzelne Plugins ergänzen diese um eigene Hooks.

HookWann er ausgelöst wird
on_spawnWird einmal aufgerufen, wenn die Skript-Instanz erstellt wird (Entity spawnt oder Prop wird platziert)
on_game_tickWird in jedem Server-Tick aufgerufen, solange die Entity lebt/aktiv ist
on_zone_enterWird aufgerufen, wenn ein Spieler eine beobachtete Zone betritt
on_zone_leaveWird aufgerufen, wenn ein Spieler eine beobachtete Zone verlässt

Methodensyntax: : vs .

In Lua ist object:method(arg) die Kurzform für object.method(object, arg). Die MagmaCore-API akzeptiert beide Formen, also funktionieren beide:

context.log:info("hello")
context.log.info("hello") -- dasselbe

Die gesamte Dokumentation verwendet durchgängig :.


Laufzeit-Budget

Jeder Hook-Aufruf und jeder Callback-Aufruf wird zeitlich 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-Handler schlank -- sie laufen in jedem einzelnen Tick.
  • Verwende context.scheduler:run_repeating(...), um Arbeit auf mehrere Ticks zu verteilen.
  • Verlagere aufwändige Arbeit hinter einen zustandsbasierten Cooldown oder ein angemessenes Intervall.
Skript-Laufzeitfehler

Wenn ein Lua-Skript in einem Hook oder geplanten Callback einen Laufzeitfehler wirft, wird die Skript-Instanz für diese Entity sofort und dauerhaft deaktiviert. Behebe den Fehler in deiner Skriptdatei -- das Skript initialisiert sich beim nächsten Entity-Spawn neu.


context.state

Eine einfache Lua-Tabelle, die während der gesamten Lebensdauer der Skript-Instanz erhalten bleibt. Verwende sie, um Flags, Zähler, Task-IDs, Toggle-Zustände und alle Daten zu speichern, die du zwischen Hooks teilen möchtest.

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
Info

Nur context.state bleibt zwischen Hook-Aufrufen erhalten. Alle anderen Kontexttabellen (context.prop, context.world, context.event, usw.) werden bei jedem Aufruf neu aufgebaut. context.state wird nicht neu aufgebaut -- sie besteht ab dem Moment, in dem die Skript-Instanz erstellt wird, bis zu deren Zerstörung.


context.log

Methoden zum Logging in die Konsole. Meldungen werden in der Serverkonsole mit dem Skriptdateinamen versehen.

MethodeHinweise
log:info(message)Informationsmeldung
log:warn(message)Warnmeldung
log:error(message)Meldung auf Warn-Ebene (wird auf WARN-Level geloggt, identisch zu log:warn)
EliteMobs-Variante

Das EliteMobs context.log registriert debug statt error. Verwende log:debug(message) für Debug-Ausgaben (erscheint als Info-Level mit einem Debug-Präfix).

context.log:info("Script loaded!")
context.log:warn("Something unexpected happened")
context.log:error("Critical failure in zone setup")

context.cooldowns

Die Cooldowns-Tabelle verwaltet zeitbasierte Cooldowns für deine Skripte. Es gibt zwei Geltungsbereiche:

  • Lokale Cooldowns gelten pro Skript-Instanz und werden über einen String-Schlüssel identifiziert. Wird kein Schlüssel angegeben, wird der Dateiname des Skripts als Standardschlüssel verwendet.
  • Globale Cooldowns werden über alle Skripte auf derselben Owner-Entity geteilt (z. B. alle Skripte auf demselben Prop oder alle Lua-Powers auf demselben Boss).

cooldowns:check_local(key?, duration)

Die häufigste Methode. Prüft, ob der Cooldown bereit ist, startet ihn in diesem Fall und gibt true zurück. Wenn nicht bereit, gibt false zurück. Dies ist ein atomares Check-and-Set — keine Race Conditions.

ParameterTypHinweise
keystring (optional)Cooldown-Bezeichner. Standard ist der Skriptdateiname.
durationintCooldown-Dauer in Ticks (20 = 1 Sekunde)
on_right_click = function(context)
-- Diese Aktion nur alle 3 Sekunden erlauben
if not context.cooldowns:check_local("interact", 60) then
return
end
-- ... Aktion ausführen
end

cooldowns:local_ready(key?)

Gibt true zurück, wenn der lokale Cooldown abgelaufen ist (oder nie gesetzt wurde), false, wenn er noch aktiv ist.

cooldowns:local_remaining(key?)

Gibt die Anzahl der verbleibenden Ticks im 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 unbedingte Cooldown-Resets.

ParameterTypHinweise
durationintDauer in Ticks. Übergib 0 oder einen negativen Wert, um zu löschen.
keystring (optional)Cooldown-Bezeichner. Standard ist der Skriptdateiname.

cooldowns:global_ready()

Gibt true zurück, wenn der globale Cooldown (geteilt über alle Skripte auf derselben Entity) abgelaufen ist.

cooldowns:set_global(duration)

Setzt den globalen Cooldown.

ParameterTypHinweise
durationintDauer in Ticks
Geltungsbereiche globaler Cooldowns

Der "Owner" eines globalen Cooldowns hängt vom Skripttyp ab:

  • EliteMobs Lua-Powers — geteilt pro EliteEntity (ein Bucket pro Boss). global_ready() / set_global() verwenden das eingebaute Power-Cooldown-System des Bosses; lokale Cooldowns werden ebenfalls über alle Powers auf demselben Boss geteilt.
  • FMM-Prop-Skripte — geteilt pro PropEntity (ein Bucket pro platziertem Prop).
  • FMM-Item-Skripte — geteilt pro Spieler-UUID (ein Bucket pro Spieler). Lokale Cooldowns auf Items bleiben über Equip/Unequip-Zyklen hinweg bestehen, gekennzeichnet durch playerUUID → "itemId:scriptFile" → key, sodass ein Cooldown bestehen bleibt, wenn der Spieler das Item aus seiner Hotbar herausnimmt und wieder hineinlegt.

context.scheduler

Der Scheduler erlaubt 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.

ParameterTypHinweise
ticksintVerzögerung in Server-Ticks (20 Ticks = 1 Sekunde)
callbackfunctionWird 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.

ParameterTypHinweise
delayintAnfängliche Verzögerung in Ticks vor dem ersten Lauf
intervalintTicks zwischen jedem nachfolgenden Lauf
callbackfunctionWird in jedem Intervall mit einem frischen context 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.

ParameterTypHinweise
taskIdintDie von run_later oder run_repeating zurückgegebene Task-ID
Sich wiederholende Tasks immer abbrechen

Wenn du einen sich wiederholenden Task startest, brich ihn immer in deinem Cleanup-Hook ab (on_destroy für Props, on_exit_combat / on_death für Bosse, on_unequip für Items). Vergisst du den Abbruch, läuft ein Hintergrundtask weiter, bis die Skript-Instanz zerstört wird, was Leistung verschwendet und Fehler verursachen kann.

Callbacks erhalten frischen Kontext

Geplante Callbacks erhalten einen frischen Kontext als Parameter. Verwende immer das eigene Kontext-Argument des Callbacks, nicht den äußeren context aus dem Hook, der den Callback erstellt hat. Der äußere Kontext kann veraltete Referenzen enthalten.


context.world

Die Welt-Tabelle bietet Methoden zum Abfragen und Interagieren mit der Minecraft-Welt. Sie wird aus der aktuellen Welt der Entity aufgebaut.

Plugin-spezifische Erweiterungen

EliteMobs erweitert context.world um zusätzliche Methoden zum Spawnen von Bossen, Verstärkungen, fallenden Blöcken, Feuerwerken, Wurftränken und temporären Blöcken. Siehe EliteMobs World & Environment für die vollständige erweiterte API. Die hier dokumentierten Methoden stehen über alle Plugins hinweg zur Verfügung.

world.name

Ein String-Feld, das den Weltnamen enthält.


world:get_block_at(x, y, z)

Gibt den Materialnamen des Blocks an den angegebenen Koordinaten als String in Kleinbuchstaben zurück (z. B. "stone", "air").

ParameterTypHinweise
xintBlock-X-Koordinate
yintBlock-Y-Koordinate
zintBlock-Z-Koordinate

world:set_block_at(x, y, z, material)

Setzt den Block an den angegebenen Koordinaten. Wird im Main-Thread ausgeführt.

ParameterTypHinweise
xintBlock-X-Koordinate
yintBlock-Y-Koordinate
zintBlock-Z-Koordinate
materialstringBukkit-Materialname, kleingeschrieben (z. B. "stone", "air", "oak_planks")

Gibt true zurück, wenn der Block erfolgreich gesetzt wurde, sonst false.


world:spawn_particle(particle, x, y, z, count, dx, dy, dz, speed)

Spawnt Partikel an einer Position.

ParameterTypStandardHinweise
particlestringerforderlichName des Bukkit-Particle-Enums, UPPER_CASE (z. B. "FLAME", "DUST")
xnumbererforderlichX-Koordinate
ynumbererforderlichY-Koordinate
znumbererforderlichZ-Koordinate
countint1Anzahl der Partikel
dxnumber0X-Streuung/Versatz
dynumber0Y-Streuung/Versatz
dznumber0Z-Streuung/Versatz
speednumber0Partikelgeschwindigkeit
Partikel mit Datenanforderungen

Einige Partikeltypen benötigen Block- oder Item-Daten, die von dieser einfachen API nicht unterstützt werden. BLOCK_CRACK, FALLING_DUST, BLOCK_DUST und ITEM_CRACK schlagen fehl oder erzeugen keinen sichtbaren Effekt. Verwende stattdessen datenfreie Alternativen: CLOUD, SMOKE, CAMPFIRE_COSY_SMOKE, SNOWFLAKE, FLAME, DUST usw.


world:play_sound(sound, x, y, z, volume, pitch)

Spielt einen Sound an einer Position ab.

ParameterTypStandardHinweise
soundstringerforderlichName des Bukkit-Sound-Enums, UPPER_CASE (z. B. "ENTITY_EXPERIENCE_ORB_PICKUP")
xnumbererforderlichX-Koordinate
ynumbererforderlichY-Koordinate
znumbererforderlichZ-Koordinate
volumenumber1.0Lautstärke
pitchnumber1.0Tonhöhe

world:strike_lightning(x, y, z)

Lässt einen Blitz an einer Position einschlagen (visuell und schadensverursachend).

ParameterTypHinweise
xnumberX-Koordinate
ynumberY-Koordinate
znumberZ-Koordinate

world:get_time()

Gibt die aktuelle Weltzeit in Ticks zurück.


world:set_time(ticks)

Setzt die Weltzeit.

ParameterTypHinweise
ticksintWeltzeit (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 um die angegebenen Koordinaten zentrierten Bounding Box zurück.

ParameterTypHinweise
xnumberMittelpunkt X
ynumberMittelpunkt Y
znumberMittelpunkt Z
radiusnumberSuchradius (wird als halbe Ausdehnung in allen drei Achsen verwendet)
Vorsicht

Dies gibt ALLE Entities im Bereich zurück, einschließlich nicht-lebender Entities (Armor Stands, gedroppter Items usw.). Sichere immer mit if entity.damage then ab, 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 um die angegebenen Koordinaten zentrierten Bounding Box zurück.

ParameterTypHinweise
xnumberMittelpunkt X
ynumberMittelpunkt Y
znumberMittelpunkt Z
radiusnumberSuchradius

world:spawn_entity(entity_type, x, y, z)

Spawnt eine Vanilla-Minecraft-Entity an der angegebenen Position.

ParameterTypHinweise
entity_typestringBukkit-Entity-Type-Name, kleingeschrieben (z. B. "zombie", "skeleton", "pig")
xnumberX-Koordinate
ynumberY-Koordinate
znumberZ-Koordinate

Gibt eine Entity-Tabelle für die gespawnte Entity zurück (mit Methoden für lebende Entities, falls zutreffend), oder nil, wenn der Entity-Type ungültig ist.


world:get_highest_block_y(x, z)

Gibt die Y-Koordinate des höchsten Nicht-Luft-Blocks an der angegebenen X/Z-Position zurück.

ParameterTypHinweise
xintBlock-X-Koordinate
zintBlock-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 aus und gibt Informationen darüber zurück, was er trifft.

ParameterTypStandardHinweise
from_xnumbererforderlichUrsprung X
from_ynumbererforderlichUrsprung Y
from_znumbererforderlichUrsprung Z
dir_xnumbererforderlichRichtungskomponente X
dir_ynumbererforderlichRichtungskomponente Y
dir_znumbererforderlichRichtungskomponente Z
max_distancenumber50Maximale Strahldistanz

Gibt eine Tabelle mit den folgenden Feldern zurück:

FeldTypHinweise
hit_entityentity table oder nilDie erste vom Strahl getroffene Entity, oder nil, wenn keine
hit_locationlocation table oder nilDer exakte Punkt, an dem der Strahl etwas getroffen hat
hit_blocktable 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 an der angegebenen Position.

ParameterTypStandardHinweise
xnumbererforderlichX-Koordinate
ynumbererforderlichY-Koordinate
znumbererforderlichZ-Koordinate
colorstableerforderlichArray von Farb-Strings, z. B. {"RED", "BLUE", "WHITE"}
typestring"BALL"Feuerwerksform: "BALL", "BALL_LARGE", "STAR", "BURST", "CREEPER"
powerint1Flugkraft, 0-127
-- Beispiel: rot-goldenes Feuerwerk
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.

ParameterTypStandardHinweise
xinterforderlichBlock-X-Koordinate
yinterforderlichBlock-Y-Koordinate
zinterforderlichBlock-Z-Koordinate
materialstringerforderlichBukkit-Materialname (z. B. "stone", "ice")
ticksint0Dauer in Ticks, bevor der Block zurückgesetzt wird. 0 bedeutet dauerhaft.
require_airbooleanfalseWenn true, wird der Block nur gesetzt, wenn das Ziel Luft ist

Gibt true zurück, wenn der Block platziert wurde, false, wenn das Material ungültig war oder die Luft-Bedingung nicht erfüllt wurde.


world:drop_item(x, y, z, material, [amount])

Droppt eine Item-Entity an der angegebenen Position mit natürlicher Streuung.

ParameterTypStandardHinweise
xnumbererforderlichX-Koordinate
ynumbererforderlichY-Koordinate
znumbererforderlichZ-Koordinate
materialstringerforderlichBukkit-Materialname
amountint1Stack-Größe

Gibt eine Entity-Tabelle für das gedroppte Item zurück, oder nil, wenn das Material ungültig war.


context.zones

Die Zonen-Tabelle ermöglicht es dir, räumliche Zonen zu erstellen und sie auf Spieler-Eintritts-/Austrittsereignisse zu überwachen. Zonen sind an die Skript-Instanz gebunden und werden automatisch aufgeräumt, wenn die Skript-Instanz zerstört wird.

zones:create_sphere(x, y, z, radius)

Erstellt eine Kugelzone, zentriert an den angegebenen Koordinaten. Gibt ein numerisches Zonen-Handle zurück.

ParameterTypHinweise
xnumberMittelpunkt X
ynumberMittelpunkt Y
znumberMittelpunkt Z
radiusnumberKugelradius

zones:create_cylinder(x, y, z, radius, height)

Erstellt eine Zylinderzone. Gibt ein numerisches Zonen-Handle zurück.

ParameterTypHinweise
xnumberMittelpunkt X
ynumberMittelpunkt Y (Basis)
znumberMittelpunkt Z
radiusnumberZylinderradius
heightnumberZylinderhöhe

zones:create_cuboid(x, y, z, xSize, ySize, zSize)

Erstellt eine Quaderzone. Gibt ein numerisches Zonen-Handle zurück.

ParameterTypHinweise
xnumberMittelpunkt X
ynumberMittelpunkt Y
znumberMittelpunkt Z
xSizenumberHalbe Ausdehnung in X
ySizenumberHalbe Ausdehnung in Y
zSizenumberHalbe Ausdehnung in Z

zones:watch(handle, onEnterCallback, onLeaveCallback)

Beginnt, eine Zone auf Spieler-Eintritts-/Austrittsereignisse zu überwachen. Die Callback-Parameter wirken als boolesche Signale — die Übergabe eines Nicht-nil-Werts (z. B. eine Funktion oder true) aktiviert den entsprechenden Hook am Skript. Die Callbacks selbst werden nicht direkt aufgerufen. Stattdessen wird die Eintritts-/Austrittslogik über die on_zone_enter / on_zone_leave Hooks des Skripts ausgelöst.

ParameterTypHinweise
handleintZonen-Handle aus einem create_*-Aufruf
onEnterCallbackany non-nil oder nilNon-nil aktiviert den on_zone_enter Hook für diese Zone
onLeaveCallbackany non-nil oder nilNon-nil aktiviert den on_zone_leave Hook für diese Zone

Gibt true zurück, wenn die Überwachung erfolgreich eingerichtet wurde, nil, wenn das Zonen-Handle ungültig war.

Info

Zonen-Überwachungen werden in jedem Server-Tick gegen alle Spieler in derselben Welt geprüft. Halte die Anzahl der Zonen vernünftig, um Performance-Overhead zu vermeiden.


zones:unwatch(handle)

Beendet die Überwachung einer Zone und räumt deren Ressourcen auf.

ParameterTypHinweise
handleintZonen-Handle, dessen Überwachung beendet werden soll

Beispiel: Näherungs-Triggerzone

return {
api_version = 1,

on_spawn = function(context)
local loc = context.prop.current_location -- oder context.boss:get_location()
if loc == nil then return end

local handle = context.zones:create_sphere(loc.x, loc.y, loc.z, 5)

-- Übergibt Nicht-nil-Werte, um die Hooks on_zone_enter und on_zone_leave zu aktivieren.
-- Dies sind boolesche Signale, keine Callbacks — die eigentliche Logik gehört in die Hooks darunter.
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

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_game_tick oder geplanter Callbacks.

Feld / MethodeTypHinweise
is_cancelledbooleanOb das Event abgebrochen wurde
cancel()methodBricht das Event ab (verhindert das Standardverhalten)
uncancel()methodHebt den Abbruch eines zuvor abgebrochenen Events auf
playerentity tableDer am Event beteiligte Spieler, falls vorhanden
on_right_click = function(context)
if context.event then
context.event:cancel() -- die Standard-Rechtsklick-Interaktion verhindern
end
end
EliteMobs Event-Tabelle

EliteMobs-Power-Skripte haben eine detailliertere Event-Tabelle mit Schadensbeträgen, Schadensursachen, Verweisen auf den Schadensverursacher und Methoden zur Schadensmodifikation. Siehe Lua API Reference für die vollständigen EliteMobs-Event-Felder.


em Helper-Namespace

Die em-Tabelle ist zum Zeitpunkt des Dateiladens verfügbar (bevor ein Hook läuft). Sie stellt Hilfskonstruktoren bereit, um Location-Tabellen, Vektor-Tabellen und Zonen-Definitionen zu erstellen, die in der gesamten API verwendet werden.

FunktionZweck
em.create_location(x, y, z [, world, yaw, pitch])Erstellt eine Location-Tabelle mit optionalem Weltnamen, Yaw und Pitch. Die zurückgegebene Tabelle besitzt zusätzlich eine .add(dx, dy, dz)-Methode, die die Location an Ort und Stelle versetzt und sich selbst zur 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 Strahlenzonen-Definition
em.zone.create_rotating_ray_zone(length, point_radius, animation_duration)Erstellt eine rotierende Strahlenzonen-Definition
em.zone.create_translating_ray_zone(length, point_radius, animation_duration)Erstellt eine sich bewegende Strahlenzonen-Definition
em.location.is_in_dungeon(loc)Prüft, ob sich eine Location innerhalb einer registrierten Dungeon-Region befindet
em.location.is_protected(loc)Prüft, ob sich eine Location innerhalb einer geschützten Region befindet (WorldGuard, GriefPrevention, EM-Regionen usw.)
em.location.owned_by(loc, namespace)Prüft, ob ein bestimmter Plugin-Namespace die Location besitzt (z. B. "EliteMobs")
em.location.owners(loc)Array von Namespace-Strings, die die Location besitzen
em.location.kinds_at(loc)Array von Kind-Tags an der Location ("elitemobs", "world_package", "open_world_dungeon", Dungeon-Größenkategorie)
em.location.has_kind(loc, kind)Prüft, ob die Location mit dem angegebenen Kind getaggt ist

Zonen-Builder geben verkettbare Tabellen mit :set_center(loc) (oder :set_origin(loc) / :set_destination(loc) je nach Zonentyp) zurück:

-- Auf Dateiebene: eine wiederverwendbare Zonenform erstellen
local blast_zone = em.zone.create_sphere_zone(5)

return {
api_version = 1,

on_spawn = function(context)
-- Die Zone zum Aufrufzeitpunkt verankern
blast_zone:set_center(context.boss:get_location())
local entities = context.zones:get_entities_in_zone(blast_zone)
-- ...
end
}
Info

Der em-Namespace ist besonders nützlich in EliteMobs, wo Zonen-Definitionen mit context.zones:get_entities_in_zone() und context.script verwendet werden. In FreeMinecraftModels werden die Methoden context.zones:create_sphere(...) / create_cylinder(...) / create_cuboid(...) häufiger für einfache, beobachtungsbasierte Zonen verwendet.


Entity-Tabellen

Entity-Tabellen werden aus Weltabfragen, Event-Daten und Zonen-Callbacks zurückgegeben. Sie stellen je nach Entity-Typ einen geschichteten Satz von Feldern und Methoden bereit.

Entity-Basisfelder

FeldTypHinweise
uuidstringDie UUID der Entity
entity_typestringDer Entity-Typ (z. B. "player", "zombie", "skeleton", "villager")
is_validbooleanOb die Entity-Referenz noch gültig ist
is_deadbooleanOb die Entity tot ist
is_playerbooleanOb die Entity ein Spieler ist
is_hostilebooleanOb die Entity ein feindlicher Mob ist (Zombie, Skeleton usw.)
is_passivebooleanOb die Entity ein passiver Mob ist (Kuh, Schwein, Huhn usw.)
current_locationlocation tableDie aktuelle Position der Entity (x, y, z, world, yaw, pitch)
worldstringDer Weltname, in dem sich die Entity befindet

Entity-Basismethoden

MethodeGibt zurückHinweise
teleport(location_table)voidTeleportiert die Entity. Die Location-Tabelle muss die Felder x, y, z, world enthalten; yaw und pitch sind optional.
remove()voidEntfernt die Entity aus der Welt. Wirkt nur, wenn die Entity noch gültig ist.
set_silent(flag)voidUnterdrückt oder reaktiviert die Sounds der Entity.
set_invulnerable(flag)voidMacht die Entity unverwundbar oder verwundbar gegenüber Schaden.
set_gravity(flag)voidAktiviert oder deaktiviert die Schwerkraft für die Entity.
set_glowing(flag)voidSchaltet den leuchtenden Umriss-Effekt der Entity um.

Felder lebender Entities

Lebende Entities (Spieler, Mobs usw.) haben alle Entity-Basisfelder plus:

FeldTypHinweise
healthnumberAktuelle Gesundheit
maximum_healthnumberMaximale Gesundheit
namestringAnzeigename
is_alivebooleanOb die Entity am Leben ist

Methoden lebender Entities

MethodeGibt zurückHinweise
damage(amount)voidFügt der Entity den angegebenen Schaden zu
push(x, y, z)voidWendet einen Geschwindigkeitsimpuls an
set_facing(x, y, z)voidSetzt die Richtung, in die die Entity blickt
add_potion_effect(effect, duration, amplifier)voidFü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)voidEntfernt einen Trankeffekt anhand seines Namens
get_scale()numberGibt die aktuelle Entity-Skalierung zurück (Standard 1.0 auf Servern ohne das generic.scale-Attribut)
set_scale(value)voidSetzt die Entity-Skalierung über das generic.scale-Attribut. No-op auf Servern vor 1.20.5.
Vorsicht

Nicht alle von get_nearby_entities() zurückgegebenen Entities 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 jeweilige Plugin installiert ist -- andernfalls sind sie standardmäßig false / nil ohne jeglichen Overhead.

EliteMobs-Felder

Verfügbar, wenn EliteMobs installiert ist.

FeldTypHinweise
is_elitebooleanOb die Entity ein EliteMobs-Elite ist
is_custom_bossbooleanOb die Entity ein EliteMobs Custom Boss ist (auch innerhalb der elite-Untertabelle verfügbar)
is_significant_bossbooleanOb die Entity ein Custom Boss mit einem Gesundheitsmultiplikator über 1 ist (d. h. eine bewusst gestaltete Begegnung, kein Füller-Elite)
elitetable oder nilUntertabelle mit Elite-Informationen (siehe unten). nil, wenn die Entity kein Elite ist.

Die elite-Untertabelle enthält:

FeldTypHinweise
elite.levelintDas Level des Elites
elite.namestringDer Anzeigename des Elites
elite.healthnumberAktuelle Gesundheit
elite.max_healthnumberMaximale Gesundheit
elite.is_custom_bossbooleanOb es sich um einen Custom Boss handelt (im Gegensatz zu einem natürlichen Elite)
elite.health_multipliernumberKonfigurationsdefinierter Gesundheitsmultiplikator
elite.damage_multipliernumberKonfigurationsdefinierter Schadensmultiplikator
elite:remove()voidEntfernt den Elite über die ordnungsgemäße Entfernungspipeline von EliteMobs (räumt Tracking, Loot usw. auf)
Beispiel: Elites unterschiedlich Schaden zufügen
local entities = context.world:get_nearby_entities(x, y, z, 5)
for _, entity in ipairs(entities) do
if entity.is_elite then
-- Doppelten Schaden gegen 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.

FeldTypHinweise
is_modeledbooleanOb an der Entity ein FMM-Modell angehängt ist (DynamicEntity oder PropEntity)
is_propbooleanOb die Entity ein FMM-Prop ist (statische, dekorative Entity)
modeltable oder nilUntertabelle mit Modell-Informationen (siehe unten). nil, wenn die Entity nicht modelliert ist.

Die model-Untertabelle enthält:

FeldTypHinweise
model.model_idstringDie ID des Modell-Blueprints (z. B. "torch_01")
model.is_dynamicbooleanOb die modellierte Entity eine DynamicEntity (Mob/Boss-Modell) statt eines statischen Props ist
model:play_animation(name, [blend], [loop])booleanSpielt eine benannte Animation ab. blend ist standardmäßig false, loop ist standardmäßig false. Gibt true zurück, wenn die Animation gefunden wurde.
model:stop_animations()voidStoppt alle derzeit laufenden Animationen auf dem Modell.
model:remove()voidEntfernt die modellierte Entity über die ordnungsgemäße Entfernungspipeline von FMM.
Bridge- vs Prop-Standards

Die Modell-Bridge (auf jeder Entity verfügbar) verwendet für blend und loop standardmäßig false. Die Prop-Tabelle (prop table) play_animation verwendet beide standardmäßig true, weil Props typischerweise geblendete, geloopte 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
-- Props überspringen
elseif entity.is_player then
entity:damage(5)
elseif entity.entity_type == "villager" then
-- Dorfbewohnern keinen Schaden zufügen
elseif entity.is_elite then
entity:damage(20)
elseif entity.is_hostile then
entity:damage(10)
end
end

Spielerspezifische Felder

Spieler-Entities haben alle Entity- und Living-Entity-Felder plus:

FeldTypHinweise
game_modestringDer Spielmodus des Spielers ("creative", "survival", "adventure", "spectator")

Spielerspezifische Methoden

MethodeGibt zurückHinweise
send_message(msg)voidSendet eine Chatnachricht an den Spieler. Unterstützt &-Farbcodes.
get_held_item()table oder nilGibt {type, amount, display_name} für das Item in der Haupthand des Spielers zurück, oder nil, wenn leer
consume_held_item(amount?)voidVerbraucht Items aus der Haupthand des Spielers. amount ist standardmäßig 1
has_item(material, amount?)booleanGibt true zurück, wenn der Spieler mindestens amount (Standard 1) des angegebenen Materials irgendwo in seinem Inventar hat
get_target_entity([range])entity table oder nilGibt die Entity zurück, die der Spieler per Raycast anvisiert, oder nil, wenn keine. Standardreichweite ist 50.
get_eye_location()location tableGibt eine Location-Tabelle auf Augenhöhe des Spielers zurück
get_look_direction()tableGibt einen {x, y, z}-Richtungsvektor zurück, in den der Spieler blickt
send_block_change(x, y, z, material, [ticks])booleanSendet einen Fake-Block, der nur für diesen Spieler sichtbar ist. Wenn ticks angegeben ist, setzt sich der Fake-Block nach dieser Dauer automatisch zurück. Gibt true bei Erfolg zurück, false, wenn das Material ungültig ist.
reset_block(x, y, z)booleanSetzt einen Fake-Block für diesen Spieler auf den echten Block zurück. Gibt immer true zurück.
sleep(x, y, z)voidLässt den Spieler an den angegebenen Koordinaten in eine Bett-Schlafanimation eintreten. Der Block wird automatisch wiederhergestellt, wenn der Spieler aufhört zu schlafen.
wake_up()voidWeckt 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.

ParameterTypStandardHinweise
textstringerforderlichDer anzuzeigende Text. Unterstützt &-Farbcodes.
colorstring"WHITE"Leistenfarbe. Eine von: "RED", "BLUE", "GREEN", "YELLOW", "PURPLE", "PINK", "WHITE"
progressnumbererforderlichFüllstand von 0.0 (leer) bis 1.0 (voll)
ticksintnilOptionale Auto-Ausblendverzögerung in Ticks. Wenn weggelassen, bleibt die Leiste, bis sie manuell ausgeblendet wird.

player:hide_boss_bar()

Entfernt die Bossleiste vom Bildschirm des Spielers. Erwartet keine Parameter.

player:show_action_bar(text, [ticks])

Zeigt Text im Action-Bar-Bereich an (über der Hotbar).

ParameterTypStandardHinweise
textstringerforderlichDer anzuzeigende Text. Unterstützt &-Farbcodes.
ticksintnilOptionale 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.

ParameterTypStandardHinweise
titlestringerforderlichHaupttiteltext. Unterstützt &-Farbcodes.
subtitlestring""Untertiteltext unter dem Haupttitel. Optional.
fade_ininterforderlichEinblenddauer in Ticks
stayinterforderlichWie lange der Titel in Ticks auf dem Bildschirm bleibt
fade_outinterforderlichAusblenddauer in Ticks

Nächste Schritte

Plugin-spezifische Hooks, APIs und Arbeitsabläufe: