Zum Hauptinhalt springen

MagmaCore Lua-Scripting-Engine

MagmaCore stellt die Lua-Sandbox und die Laufzeit ScriptInstance für EliteMobs-Bossfähigkeiten, NPC-Skripte, FreeMinecraftModels-Props und eigene Verzauberungseffekte bereit. Sie teilen Dateivalidierung und Ressourcenverwaltung. Verfügbare Hooks, Kontexttabellen, Cooldown-Geltungsbereiche und Lebensdauer hängen jedoch vom ausführenden System ab. Verzauberungsabfragen haben außerdem einen eingeschränkten Kontext und eigene Provider-Limits; verwende dafür ihre Referenz weiter unten.

FreeMinecraftModels-Props und EliteMobs-NPC-Skripte übernehmen die generischen MagmaCore-Kontexttabellen direkt (context.world, context.zones, context.scheduler, context.cooldowns, context.log, context.event, context.player und context.state) und ergänzen ihre Besitzertabelle (context.prop oder context.npc). EliteMobs-Bossfähigkeiten verwenden dieselbe Laufzeit, stellen aber umfangreichere bossspezifische Varianten mehrerer Tabellen bereit (context.world, context.zones, context.cooldowns, context.scheduler, context.log, context.event) sowie reine Boss-Hilfen wie context.players, context.entities, context.vectors, context.settings und context.script.

Aktuell nutzen die folgenden Plugins diese Engine:

  • EliteMobs — Lua-Fähigkeiten für eigene Bosse (Hooks wie on_boss_damaged_by_player, on_enter_combat usw.) und NPC-Lua-Skripte für Interaktionen und Annäherungsverhalten (Hooks wie on_npc_interact, on_npc_proximity_enter usw.)
  • FreeMinecraftModels — Lua-Skripte für Props (Hooks wie on_right_click, on_left_click usw.) und eigene Verzauberungseffekte für benutzerdefinierte Items

Diese Seite dokumentiert die generischen MagmaCore-Engine-Funktionen, die FreeMinecraftModels-Skripte verwenden, und Kompatibilitätshinweise für EliteMobs, wo dieselben Konzepte boss- oder NPC-spezifische Varianten haben. Den genauen Boss-Kontext beschreiben die EliteMobs-Lua-Seiten; den genauen NPC-Kontext findest du unter NPC-Lua-Skripting.


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
-- do something with the 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
}

Die zurückgegebene Tabelle ist die Skriptdefinition. Der Loader wertet die Datei zur Validierung aus und führt ihren gespeicherten Quelltext für jede Laufzeitinstanz erneut aus. Dateilokale Variablen gehören deshalb zu dieser Instanz, nicht zu allen Entities mit demselben Dateinamen. Eine Dateiänderung verändert weder eine geladene Definition noch eine laufende Instanz. Lade sie über den vorgesehenen Ablauf des zuständigen Plugins neu.

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 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​

Die LuaJ-Standardumgebung stellt diese gewöhnlichen Lua-Funktionen bereit:

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. Verwende context.world:get_time() für die Weltzeit auf den generischen MagmaCore-Oberflächen; EliteMobs-Bossfähigkeiten erhalten die Methode über die gemeinsame Basis ihrer Welt-Tabelle. Für Logik mit vergangener Zeit speichere Tick-Zähler in context.state über den Hook on_game_tick.

Tipp

print schreibt in die Serverkonsole; bevorzuge jedoch context.log:info(msg). Jede Oberfläche stellt context.log bereit: FreeMinecraftModels-Skripte und EliteMobs-NPC-Skripte bieten info, warn und error; EliteMobs-Bossfähigkeiten bieten info, warn und debug.


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
priorityNeinNumberStandard 0; wird in eine Ganzzahl umgewandelt. EliteMobs-Boss- und NPC-Skripte führen niedrigere Werte zuerst aus. FMM validiert das Feld, Props folgen aber der scripts:-Liste
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.
priority ist anbieterspezifisch

Der Lua-Validator akzeptiert priority für alle MagmaCore-gestützten Skripte. EliteMobs verwendet es für die Reihenfolge von Boss- und NPC-Skripten. FreeMinecraftModels sortiert derzeit nicht nach priority: Props folgen der Reihenfolge der scripts:-Liste in der Konfiguration. Eigene Verzauberungen verwenden ihren Provider-Katalog und ihren Aktions-/Abfragelebenszyklus.

Wo Skriptdateien liegen​

Jeder Provider wählt sein Verzeichnis. Die generische Engine sucht rekursiv nach .lua-Dateien und schließt archivierte Konfigurationspfade aus. Sie sortiert normalisierte absolute Pfade zunächst ohne Beachtung der Groß- und Kleinschreibung, danach exakt. Pro kleingeschriebenem Dateinamen gewinnt die erste Datei; übersprungene Duplikate werden gemeldet, wenn sich ihr Inhalt von der gewählten Datei unterscheidet. Scheitert die gewählte Datei an der Validierung, wird kein Duplikat nachgeladen. Registrierte Abfragen behalten die tatsächliche Schreibweise des gewählten Namens bei; verwende diese in Verweisen. Bossfähigkeiten und Verzauberungskataloge haben eigene Suchregeln. Der gemeinsame Validator macht ihre Verzeichnisse nicht austauschbar.

Dateinamen müssen eindeutig sein

Skripte werden anhand des Dateinamens geschlüsselt, nicht anhand des Pfads. Zwei Dateien namens door.lua in verschiedenen Unterordnern sind derselbe Schlüssel, und nur eine davon wird registriert. Gib jedem Skript einen eindeutigen Dateinamen.

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
}

Häufige Hook-Namen​

Diese Hook-Namen kommen in mehreren Lua-Laufzeiten vor. Jeder Skripttyp aktiviert nur die für seinen Besitzer sinnvolle Teilmenge: FMM-Prop-Skripte verwenden alle hier aufgeführten Hooks, EliteMobs-Bossfähigkeiten ihre Boss-Hook-Liste und EliteMobs-NPC-Skripte on_spawn, on_remove, on_game_tick, on_npc_interact, on_npc_proximity_enter, on_npc_proximity_leave, on_zone_enter und on_zone_leave.

HookWann er ausgelöst wird
on_spawnWird vom Spawn-Lebenszyklus des Plugins für FMM-Props sowie EliteMobs-Bosse und NPCs ausgelöst; allein das Erstellen eines ScriptInstance löst ihn nicht aus
on_game_tickLäuft jeden Server-Tick, solange die initialisierte Instanz aktiv und nicht pausiert ist
on_zone_enterWird aufgerufen, wenn eine von der Laufzeit unterstützte Zone einen Eintritt meldet. FMM- und EliteMobs-NPC-Zonenüberwachungen beziehen sich auf Spieler; die Top-Level-Zonen-Hooks von EliteMobs-Bossen stammen aus EliteScript-Zonen-Events.
on_zone_leaveWird aufgerufen, wenn eine von der Laufzeit unterstützte Zone einen Austritt meldet. FMM- und EliteMobs-NPC-Zonenüberwachungen beziehen sich auf Spieler; die Top-Level-Zonen-Hooks von EliteMobs-Bossen stammen aus EliteScript-Zonen-Events.

Methodensyntax: : vs .​

In Lua ist object:method(arg) die Kurzform für object.method(object, arg). Die Methoden der MagmaCore-Kontexttabellen entfernen dieses implizite erste Argument, daher funktionieren beide Formen bei Methoden wie context.log.info:

context.log:info("hello")
context.log.info("hello") -- same thing

Globale Hilfsfunktionen unter em sind einfache Funktionen und keine Methoden von Kontexttabellen. Rufe sie mit . auf: em.create_location(...), em.zone.create_sphere_zone(...) und em.location.is_protected(...). Auch die EliteMobs-Event-Setter context.event.set_damage_amount(...) und context.event.multiply_damage_amount(...) erfordern .. Die Dokumentation verwendet : für Methoden von Kontexttabellen und . für einfache Funktionen.


Ausführungsbudget​

Jeder Hook-Aufruf, jeder geplante Callback-Aufruf und die anfängliche Auswertung der Skriptdatei selbst laufen unter einem harten Ausführungsbudget. Das Budget wird innerhalb der Lua-VM durchgesetzt, greift also, während dein Code noch läuft, statt erst danach die Uhr zu prüfen.

Die gewöhnliche Laufzeit verwendet diese Limits:

LimitWert
CPU-Zeit des aktuellen Threads50 Millisekunden
Ausgeführte Lua-Instruktionen250.000

Ein überschrittenes Limit löst einen Lua-Fehler aus. Der Instruktionszähler wird bei jeder Lua-Instruktion geprüft, die Uhr alle 1.024 Instruktionen und nach Rückkehr des Aufrufs. Eine laufende Java/Bukkit-Methode wird dadurch nicht unterbrochen. 50 ms CPU-Zeit sind keine Frist von 50 ms Echtzeit. Ein nicht abgefangener Fehler in Hook oder Callback schließt die Instanz; bei der anfänglichen Validierung wird die Definition abgelehnt. Ohne CPU-Zeitmessung des aktuellen Threads gelten 250 Millisekunden vergangene Zeit und dasselbe Instruktionslimit. Verzauberungsabfragen können kleinere gemeinsame Budgets verwenden.

Endlosschleifen werden abgefangen, kosten dich aber trotzdem einen Tick

Die VM unterbricht ein gewöhnliches while true do end während der Lua-Instruktionen. Die Schleife verbraucht dennoch Zeit auf dem Server-Thread und schließt die Instanz, wenn der Fehler weitergereicht wird. Begrenze Schleifen trotz dieser Überwachung.

Verschachtelte Aufrufe teilen sich ein Budget: Wenn ein Hook einen Callback aufruft, der wiederum einen weiteren aufruft, wird die gesamte Kette als eine einzige Zuteilung von 50 ms CPU-Zeit / 250.000 Instruktionen gemessen, nicht als je eine Zuteilung pro Aufruf.

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.
  • Begrenze aufwendige Arbeit mit context.cooldowns oder einem angemessenen Intervall.
Skript-Laufzeitfehler

Ein nicht abgefangener Laufzeitfehler in Hook oder Callback schließt diese Instanz und bricht ihre eigenen Aufgaben ab. Korrigiere und lade die Definition neu, damit das zuständige Plugin eine neue Instanz erstellen kann. Das Speichern der Datei repariert die geschlossene Instanz nicht. Verzauberungssysteme wenden zusätzlich ihre Regeln zur Unterdrückung wiederholter Fehler an.


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.

return {
api_version = 1,

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

Verwende context.state für Daten zwischen den Hooks einer Instanz. Sie liegen im Arbeitsspeicher und überdauern weder Neuladen noch Neustarts. Andere Tabellen werden bei Bedarf erstellt und können Momentaufnahmen enthalten. FMM speichert context.prop zwischen, liest Felder wie current_location aber bei Bedarf. Lies ein dynamisches Feld erneut, um es zu aktualisieren; eine bereits gespeicherte Tabelle aktualisiert sich nicht selbst. Das Zuweisen eines solchen Feldes verdeckt seinen Getter.


context.log​

Methoden zur Konsolenausgabe, verfügbar auf jeder Skript-Oberfläche. Generische log.info-Meldungen tragen das Präfix [Lua]. Ergänze eine Skriptbezeichnung in deiner Nachricht, wenn du die Quelle erkennen möchtest. Fehlerdiagnosen benennen das fehlerhafte Skript; gewöhnliche Logausgaben fügen seinen Dateinamen jedoch nicht automatisch hinzu. FreeMinecraftModels-Skripte und EliteMobs-NPC-Skripte bieten info, warn und error; EliteMobs-Bossfähigkeiten bieten info, warn und debug.

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")
-- Generic/FMM/NPC logger:
context.log:error("Critical failure in zone setup")
-- EliteMobs boss logger:
context.log:debug("Boss debug detail")

context.cooldowns​

Die Tabelle verwaltet Cooldowns. Lokale und generische globale Cooldowns rechnen jeden Tick in 50 ms monoton gemessene Zeit um, einschließlich Pausen und niedriger TPS. Globale Boss-Cooldowns zählen dagegen Server-Ticks. Es gibt zwei Geltungsbereiche:

  • Lokale Cooldowns verwenden exakte String-Schlüssel im Speicher des Besitzers, dessen Geltungsbereich unten steht. nil wählt den Standardschlüssel __lua: gefolgt vom Skriptdateinamen.
  • Globale Cooldowns werden über alle Skripte derselben Besitzer-Entität geteilt, sofern die Laufzeit globale Cooldown-Methoden anbietet (etwa alle Skripte desselben Props oder alle Lua-Fähigkeiten desselben Bosses).

cooldowns:check_local(key?, duration)​

Prüft einen lokalen Schlüssel und startet seinen Cooldown, wenn er bereit ist; dann wird true, sonst false zurückgegeben. Dies ist ein synchroner Lua-Aufruf. Er prüft oder startet keinen globalen Cooldown. Der Speicher ist keine API zur Synchronisierung mehrerer Threads.

ParameterTypHinweise
keystring (optional)Cooldown-Bezeichner. nil wählt den Standardschlüssel.
durationintCooldown-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
Gemeinsame Cooldown-Reihenfolge

Alle Skript-Oberflächen — Bossfähigkeiten, NPC-Skripte und FreeMinecraftModels-Skripte — verwenden die oben gezeigte gemeinsame Reihenfolge: check_local(key?, duration). Für den Standardschlüssel übergib check_local(nil, 60); check_local(60) bedeutet keinen 60-Tick-Cooldown mit Standardschlüssel. (Frühere experimentelle NPC-Builds verwendeten check_local(duration, key?); passe alte NPC-Skripte auf die gemeinsame Reihenfolge an.)

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. nil wählt den Standardschlüssel.

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. In generischen MagmaCore-Tabellen löschen null oder negative Dauern ihn. Globale Boss-Cooldowns behalten den späteren Ablauf: Eine kürzere Dauer verkürzt nie einen aktiven globalen Cooldown, und null oder negative Dauern bewirken nichts. Das Setzen eines lokalen Cooldowns setzt nicht automatisch den globalen und umgekehrt.

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.
  • EliteMobs-NPC-Skripte: Globale Cooldowns und explizite lokale Schlüssel werden über den einzigen Adapter des NPCs geteilt. Zwei Skripte mit demselben lokalen Schlüssel beeinflussen einander; ausgelassene Schlüssel bleiben dateispezifisch.
  • FMM-Prop-Skripte: Globale Cooldowns gelten pro platziertem Prop; jedes angehängte Skript besitzt einen eigenen Adapter mit lokalem Speicher.
  • Verzauberungsaktionen — globale Cooldowns gelten gemeinsam pro Spieler innerhalb des Providers; lokale Cooldowns gehören zum Spieler und zur Verzauberungs-ID und überdauern Ausrüstungswechsel und abgeschlossene Aktionen. Siehe eigene Verzauberungen.

context.scheduler​

Der Scheduler führt verzögerte und wiederholte Aufgaben aus. Über ihn erstellte Aufgaben gehören zur Instanz und werden beim Schließen abgebrochen. Das macht weder gespawnte Entities noch Weltänderungen oder Timer separater UI-/Effektmethoden rückgängig. Während einer Pause warten fällige einmalige Aufgaben auf die Fortsetzung; wiederholte Aufgaben überspringen ihre pausierten Aufrufe.

Dieser Abschnitt verwendet die MagmaCore-Scheduler-Namen (run_later, run_repeating, cancel). Die EliteMobs-Namen (run_after(ticks, callback), run_every(interval, callback), cancel_task(taskId)) werden auf jeder Oberfläche als Aliasse akzeptiert. Beide Schreibweisen funktionieren daher in jedem Skript.

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 eine eigene Aufgabe dieser Instanz anhand ihrer ID ab. Eine unbekannte oder fremde ID bewirkt nichts.

ParameterTypHinweise
taskIdintDie von run_later oder run_repeating zurückgegebene Task-ID
Beende wiederholte Arbeit, sobald sie nicht mehr nötig ist

Das Schließen bricht eigene Aufgaben automatisch ab. Beende sie früher, wenn eine Interaktion oder Kampfphase endet und die Instanz aktiv bleibt, etwa im Boss-Hook on_exit_combat. Beide Namensfamilien funktionieren. Verwende die Lebenszyklus-Hooks des zuständigen Plugins; ein Fehler schließt die Instanz ohne Garantie eines eigenen Cleanup-Hooks.

Callbacks erhalten frischen Kontext

Callbacks erhalten einen neuen Kontext ohne ursprüngliches Event oder auslösenden Spieler. Verwende diesen statt des äußeren Kontexts. Falls du den Spieler später brauchst, speichere seine UUID im Hook und löse sie erneut auf; prüfe dabei seine Verfügbarkeit. Ein aufbewahrter äußerer Kontext kann ein dynamisches Event-Feld erst nach Ende des ursprünglichen Events auflösen.


context.world​

Die Welt-Tabelle bietet Methoden für Minecraft-Weltabfragen und Änderungen. Sie erfasst die aktuelle Welt des Besitzers beim ersten Aufbau. Eine gespeicherte Tabelle folgt späteren Weltwechseln nicht.

Gemeinsame Welt-Tabelle auf jeder Oberfläche

Diese Methoden beschreiben die gemeinsame Tabelle für FMM-Props und EliteMobs-NPCs, einschließlich des schädigenden strike_lightning(...). FMM ergänzt optionale EliteMobs-Transport- und Loot-Helfer; siehe context.world: FreeMinecraftModels-Ergänzungen. EliteMobs ergänzt seine gemeinsamen Tabellen um visuelle Blitze und NPC-/Boss-Spawns mit Prüfung auf geladene Chunks. Bossfähigkeiten ergänzen oder überschreiben anschließend eigene Methoden; siehe EliteMobs: Welt & Umgebung.

Koordinaten- und Location-Tabellen-Überladungen existieren nebeneinander

context.world akzeptiert auf den generischen Oberflächen sowohl Aufrufe im Koordinatenstil (z. B. strike_lightning(x, y, z), spawn_particle(name, x, y, z, ...)) als auch Überladungen im Location-Tabellen-Stil (z. B. strike_lightning_at_location(loc), spawn_particle_at_location(loc, ...)). EliteMobs-Boss-Powers unterstützen ebenfalls beide Stile, allerdings haben einige Location-Tabellen-Methoden dort boss-spezifisches Verhalten.

Gemeinsame Location-Argumente benötigen x, y und z. Eine ausgelassene oder nicht auflösbare Welt verwendet die Welt der Tabelle. Gemeinsame Partikelaufrufe mit Location verwenden weiterhin diese erfasste Welt; übergib daher eine Position derselben Welt. Boss-Konverter und em.location.*-Abfragen folgen anderen Regeln in ihren Referenzen.

Die vollständige Referenz der Welt-Tabelle beschreibt außerdem Entity-Suchen, Abfragen zu Passierbarkeit und Gebietsschutz, farbige Staubpartikel, Geländeeinschläge und Überladungen mit Location-Tabellen.

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"). Nicht geladene Chunks liefern "air"; die Abfrage lädt sie nicht nach.

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 und lädt keine Chunks nach.

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

Gibt true zurück, wenn das Material gültig ist und die Änderung eingeplant wurde. Das bestätigt keine tatsächlich erfolgte Platzierung: Ist der Chunk bei Ausführung des Tasks nicht geladen, wird die Änderung übersprungen. Ein ungültiges Material liefert false.

Regionsschutz wird nicht automatisch geprüft. Verwende ein Blockmaterial und frage den passenden Schutz vor der Platzierung ab; eine angenommene Aufgabe beweist keine Blockänderung.


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

Spawnt Partikel an einer Position.

ParameterTypStandardHinweise
particlestringerforderlichName des Bukkit-Particle-Enums; wird vor der Suche großgeschrieben (z. B. "FLAME", "HAPPY_VILLAGER")
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 zusätzliche Daten, die diese einfache API nicht übergibt; dazu gehören DUST und FALLING_DUST. Verwende hier datenfreie Partikel wie CLOUD, SMOKE, CAMPFIRE_COSY_SMOKE, SNOWFLAKE, FLAME, HAPPY_VILLAGER, HEART, NOTE oder ENCHANT. Für farbigen Staub verwende world:spawn_dust(...). Ein Partikel, das Daten benötigt, kann bei dieser einfachen Methode eine Bukkit-Ausnahme auslösen und die Skript-Instanz deaktivieren.


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

Spielt einen Sound an einer Position ab.

ParameterTypStandardHinweise
soundstringerforderlichName des Bukkit-Sound-Enums (z. B. "ENTITY_EXPERIENCE_ORB_PICKUP") oder ein benutzerdefinierter Ressourcenpaket-Sound-Schlüssel (z. B. "mypack:boss.roar")
xnumbererforderlichX-Koordinate
ynumbererforderlichY-Koordinate
znumbererforderlichZ-Koordinate
volumenumber1.0Lautstärke
pitchnumber1.0Tonhöhe
Eigene Ressourcenpaket-Sounds

Der Name wird zuerst gegen die bei Bukkit registrierten Sounds abgeglichen (ohne Beachtung der Groß-/Kleinschreibung, "ENTITY_ARROW_SHOOT" und "entity_arrow_shoot" sind also dasselbe). Passt nichts, wird er zu einem kleingeschriebenen Namespace-Schlüssel normalisiert und als benutzerdefinierter Ressourcenpaket-Sound abgespielt. Ein Wert, der weder ein bekannter Sound noch ein gültiger Namespace-Schlüssel ist, spielt nichts ab, statt einen Fehler auszulösen — ein Tippfehler bewirkt also still gar nichts, statt dein Skript zu deaktivieren.

Dasselbe gilt für world:play_sound_at_location(loc, sound, volume, pitch).


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 ab eins indiziertes Array von Entity-Tabellen in einem achsenparallelen Quader um die Koordinaten zurück. Der Skriptbesitzer wird nicht ausgeschlossen.

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 (gedroppter Items, Projektile 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 ab eins indiziertes Array von Spielertabellen in einem achsenparallelen Quader zurück. radius ist jede halbe Ausdehnung. Spielmodi werden nicht gefiltert.

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 mit passenden Methoden für lebende Entities zurück, bei unbekanntem Enum-Namen nil. Ein gültiger, aber nicht spawnbarer Typ kann einen Fehler auslösen. Die Methode prüft nicht, ob der Chunk geladen ist.


world:get_highest_block_y(x, z)​

Gibt Bukkits höchste Block-Y-Koordinate bei X/Z zurück. Anders als get_block_at prüft diese Abfrage nicht, ob der Chunk geladen ist.

ParameterTypHinweise
xintBlock-X-Koordinate
zintBlock-Z-Koordinate

world:raycast(from_x, from_y, from_z, dir_x, dir_y, dir_z, [max_distance], [fluid_mode], [blocks_only], [loaded_only])​

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
fluid_modestring"NEVER"Flüssigkeitskollisionen: "NEVER", "SOURCE_ONLY" oder "ALWAYS"
blocks_onlybooleanfalseIgnoriert Entities, wenn true
loaded_onlybooleanfalseGibt nil zurück, wenn irgendein Chunk im umschließenden Rechteck des Strahls nicht geladen ist

Gibt eine Tabelle mit den folgenden Feldern zurück, oder nil, wenn die Prüfung für loaded_only fehlschlägt. Ohne Treffer sind die Trefferfelder nil.

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

Blockmaterialien sind kleingeschrieben. Die kombinierte Abfrage verwendet die Strahlgröße 0.5 für Entities ohne Entity-Filter. Die Chunk-Prüfung erfasst das gesamte umschließende Rechteck und kann deshalb einen Chunk abseits des exakten Strahls ablehnen. Ein ungültiger Flüssigkeitsmodus löst einen Fehler aus.


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
-- Example: red and yellow firework burst
context.world:spawn_firework(loc.x, loc.y, loc.z, {"RED", "YELLOW"}, "BURST", 2)

world:place_temporary_block(x, y, z, material, [ticks], [require_air])​

Platziert einen temporären Block und stellt gespeicherte BlockData nach einer positiven Dauer wieder her. Vollständiger Blockzustand und Inventar werden nicht erfasst.

ParameterTypStandardHinweise
xinterforderlichBlock-X-Koordinate
yinterforderlichBlock-Y-Koordinate
zinterforderlichBlock-Z-Koordinate
materialstringerforderlichBukkit-Materialname (z. B. "stone", "ice")
ticksint0Dauer in Ticks bis zur Wiederherstellung. Null oder negative Werte platzieren den Block dauerhaft und ohne Verwaltung.
require_airbooleanfalseWenn true, wird der Block nur gesetzt, wenn das Ziel Luft ist

Gibt bei ungültigem Material oder einem nicht geladenen Chunk false zurück. true bedeutet, dass die Anfrage angenommen wurde; bei require_air=true kann der Manager die Platzierung trotzdem überspringen, wenn das Ziel keine Luft ist.

Bei positiven Ticks sichert der Manager die ursprünglichen Blockdaten und stellt sie wieder her, wenn der Timer endet, wenn der Chunk oder die Welt entladen wird oder wenn das Plugin herunterfährt. Er stellt nur wieder her, solange an der Stelle noch der temporäre Block steht; eine spätere Bearbeitung wird also nicht überschrieben. Eine erneute Platzierung auf einem Block, der noch einen temporären Block enthält, startet dessen Timer neu und behält das zuerst gesicherte Original. Blöcke mit Block-Entities wie Truhen und Schilder sowie Blöcke, die bereits ein anderer Besitzer temporärer Blöcke hält, etwa ein Verzauberungs-Lease, werden übersprungen. Das Abbauen eines temporären Blocks lässt nichts fallen und beendet die Verwaltung ohne Wiederherstellung; auch das Platzieren eines Blocks an dieser Stelle beendet die Verwaltung.

Diese Timer werden nicht mit dem Lua-Skript beendet, und die Platzierung prüft Regionsschutz nicht automatisch.


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 generische Zonen-Tabelle für FMM-Props und NPCs erstellt räumliche Zonen und überwacht, wann Spielerpunkte sie betreten oder verlassen. Zonen gehören zur Skript-Instanz und werden beim Zerstören der Instanz automatisch aufgeräumt. EliteMobs-Boss-Powers verwenden eine andere Tabelle mit Methoden wie get_entities_in_zone, get_locations_in_zone und watch_zone; siehe Zonen & Targeting.

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

Erstellt eine Kugelzone um die Koordinaten und gibt ein numerisches Handle zurück, oder nil, wenn der Besitzer keine Welt hat.

ParameterTypHinweise
xnumberMittelpunkt X
ynumberMittelpunkt Y
znumberMittelpunkt Z
radiusnumberKugelradius

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

Erstellt eine Zylinderzone und gibt ein numerisches Handle zurück, oder nil, wenn der Besitzer keine Welt hat.

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

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

Erstellt eine Quaderzone und gibt ein numerisches Handle zurück, oder nil, wenn der Besitzer keine Welt hat. Die Punktprüfung behandelt Größen als halbe Ausdehnungen um den Mittelpunkt. Das unterscheidet sich von EliteMobs-Entity-Abfragen und gesampelten Zonenpositionen. Ist zSize null und xSize ungleich null, wird für Z die X-Größe verwendet.

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

zones:watch(handle, onEnterCallback, onLeaveCallback)​

Aktiviert Eintritts- und Austrittsmeldungen einer bereits erstellten Zone. Die Argumente müssen Lua-Funktionen sein; ihre Körper werden nicht direkt aufgerufen. Die Logik läuft in on_zone_enter / on_zone_leave. Anwesenheit wird ab Erstellung erfasst. Ein späteres watch meldet deshalb keinen Eintritt eines bereits darin erfassten Spielers. nil bei einem weiteren watch entfernt keinen zuvor aktivierten Handler.

ParameterTypHinweise
handleintZonen-Handle aus einem create_*-Aufruf
onEnterCallbackfunction oder nilEine Funktion aktiviert den Hook on_zone_enter für diese Zone
onLeaveCallbackfunction oder nilEine Funktion aktiviert den Hook on_zone_leave für diese Zone

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

Info

Zonen werden vor on_game_tick anhand der Spielerpositionen in der aktuellen Welt des Besitzers geprüft, nicht anhand ganzer Bounding Boxes. Kugeln verlangen Punkte strikt innerhalb des Radius; Zylinder zusätzlich zwischen eingeschlossener Basis und ausgeschlossener Oberseite. Zonen behalten Koordinaten und Welt ihrer Erstellung. Disconnects oder entfernte Überwachungen garantieren keinen Austritts-Hook. Halte die Zonenanzahl überschaubar.


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
if loc == nil then return end

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

-- Pass placeholder functions to enable on_zone_enter and on_zone_leave hooks.
-- The placeholder bodies are ignored; the actual logic goes in the hooks below.
context.zones:watch(handle, function() end, function() end)

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 ein Event oder einen beteiligten Spieler mitliefert. FMM liefert das Event über den jeweiligen Plugin-Hook; NPCs und generische Zonen-Hooks können einen Spieler ohne Bukkit-Event bereitstellen. Bei on_game_tick, geplanten Callbacks und Lebenszyklus-Hooks ohne beteiligten Spieler fehlt sie gewöhnlich.

Hooks on_projectile_hit von FMM-Props erhalten das abbrechbare Projektiltreffer-Event von FreeMinecraftModels, daher sind cancel() und uncancel() vorhanden. Der Hook läuft, nachdem FMM den Treffer verarbeitet hat; ein Abbruch verhindert also nicht, dass ein nicht durchdringendes Projektil verbraucht wird. Er wird nicht ausgelöst, wenn ein anderes Plugin den Treffer bereits abgebrochen hat. context.event.player ist der Schütze, sofern er eine lebende Entity ist, was auch ein Mob sein kann, und fehlt andernfalls; context.player ist nur gesetzt, wenn ein Spieler das Projektil abgefeuert hat. Der Hook stellt außerdem context.projectile als Entity-Tabelle für das Projektil bereit.

Generische Zonen-Hooks liefern context.player und context.event.player, aber keine Methoden zum Abbrechen eines Events.

Feld / MethodeTypHinweise
is_cancelledbooleanAbbruchzustand beim ersten Auflösen der Event-Untertabelle; cancel() und uncancel() aktualisieren ihn nicht
cancel()methodBricht das Event ab (verhindert das Standardverhalten); nur bei abbrechbaren Events vorhanden
uncancel()methodHebt den Abbruch eines Events auf; nur bei abbrechbaren Events vorhanden
playerentity tableDer am Event beteiligte Spieler, falls vorhanden
on_right_click = function(context)
if context.event and context.event.cancel then
context.event:cancel() -- prevent the default right-click interaction
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-Referenz für die vollständigen EliteMobs-Event-Felder.


em-Hilfsnamespace​

Die em-Tabelle ist beim Laden der Datei verfügbar. Ihre Konstruktoren erstellen Daten, ohne Welten zu laden, Überwachungen anzumelden oder vollständige Formen zu validieren. Zurückgegebene Setter ändern ihre Tabelle und behalten übergebene Location-Tabellen als Referenz.

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 (jeder Besitzer, der das Kind "dungeon" meldet)
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", "dungeon", "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
Regions-Plugins werden automatisch erkannt

MagmaCore liefert WorldGuard- und GriefPrevention-Adapter. Verbraucher initialisieren sie beim Aktivieren; eine Schutzabfrage kann sie ebenfalls bei Bedarf initialisieren. Abfragen erfassen registrierte Provider, nicht jedes mögliche Schutzplugin. Ein fehlschlagender registrierter Regionsadapter meldet Schutz. Ohne Provider oder geschützten Besitz liefert die Abfrage false; Warnungen melden fehlende Provider.

Für em.location.* muss world den Namen einer geladenen Welt oder {name=...} enthalten. Es gibt keinen Rückfall auf die Besitzerwelt. Eine fehlende oder unbekannte Welt sowie nil liefern false oder ein leeres Array. Fehlende Koordinaten werden null; fehlerhafte Zahlenfelder können jedoch einen Fehler auslösen. Besitzer-Namespaces beachten Groß- und Kleinschreibung, Kind-Tags nicht. Besitz allein bedeutet weder Dungeon-Zugehörigkeit noch Schutz. Die Array-Reihenfolge ist nicht garantiert.

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
}
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​

Die folgenden Tabellen stellen gängige Methoden vor. Die vollständige Lua-API-Referenz beschreibt außerdem Projektilfelder, Bewegungspfade sowie Besitz- und Schutzabfragen. Sie gelten für generische Entity-Tabellen; die speziellen Wrapper von EliteMobs-Powers haben dort einen eigenen Abschnitt.

Entity-Tabellen werden aus Weltabfragen und Event-Daten zurückgegeben. Sie stellen je nach Entity-Typ aufeinander aufbauende Felder 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 Bukkit Monster implementiert, nicht ihre aktuelle Aggressivität
is_passivebooleanOb die Entity Bukkit Animals implementiert, ohne Garantie passiven Verhaltens
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)voidBenötigt x, y, z; fehlende oder unbekannte Welt verwendet die Entity-Welt. yaw und pitch sind standardmäßig null. Keine automatische Bewegungsweg- oder Schutzprüfung.
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)voidAddiert den Vektor sofort zur aktuellen Geschwindigkeit
set_facing(x, y, z)voidTeleportiert auf der Stelle mit neuer Blickrichtung
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 effektive Skalierung inklusive Modifikatoren zurück, oder 1.0, wenn nicht verfügbar
set_scale(value)voidÄndert den Basiswert des Skalierungsattributs, falls verfügbar
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 können Integrationsfelder enthalten. Ohne den passenden Enricher fehlen sie und liefern nil. Tracking-Flags, Modellidentität, Operatorstatus und die meisten verschachtelten Daten sind Momentaufnahmen vom Aufbau; sie folgen späteren Änderungen nicht. Gemeinsame EliteMobs-Gesundheitsfelder werden bei Bedarf gelesen. Modell- und Berechtigungsmethoden fragen ihre Objekte beim Aufruf ab.

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.namestring oder nilDer 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 EliteMobs' Entfernungsablauf; dies ist kein Kill und garantiert keinen Loot
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
-- 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.

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_idstring oder nilDie 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])booleanFordert eine benannte Animation an. blend und loop sind standardmäßig false. true bedeutet, dass die Anfrage angenommen wurde: Eingereihte oder während eines Angriffs unterdrückte Animationen können true liefern, ohne sofort zu starten. Ein endgültiger Todeszustand lehnt die Anfrage ab.
model:stop_animations()voidLeert laufende und eingereihte Animationen und startet, falls vorhanden, die Idle-Animation. Ein endgültiger Todeszustand bleibt bestehen.
model:remove()voidEntfernt die modellierte Entity über die ordnungsgemäße Entfernungspipeline von FMM.

Auf Spieler-Entity-Tabellen ergänzt der FreeMinecraftModels-Enricher außerdem:

Feld / MethodeTypHinweise
is_opbooleanOb der Spieler ein Serveroperator ist.
has_permission(node)booleanOb der Spieler den Berechtigungsknoten besitzt.

Diese beiden Spielerwerte gibt es nur in FreeMinecraftModels-Skripten. Auf gemeinsamen Tabellen, die innerhalb von EliteMobs aufgebaut werden, fügt der eigene FreeMinecraftModels-Adapter von EliteMobs is_modeled, is_prop und model hinzu, aber nicht is_op oder has_permission.

FMM-Spielertabellen bieten auch is_holding_elitemobs_item(filename). Es prüft den EliteMobs-Dateinamentag des Haupthand-Items inklusive .yml, nicht den Anzeigenamen. Leere Hände, andere Items oder fehlende Integration liefern false. EliteMobs' eigener gemeinsamer Enricher ergänzt separat elite_player mit dem Kampfrang, sofern Spielerdaten vorhanden sind. FMMs optionaler EliteMobs-Adapter ergänzt diese Untertabelle nicht.

Bridge- vs Prop-Standards

Die Modell-Bridge (auf jeder Entity verfügbar) verwendet für blend und loop standardmäßig false. Die Prop-Tabelle verwendet bei play_animation beide standardmäßig true. Hier steuert blend das Einreihen und loop die Wiederholung; blend bezeichnet keinen visuellen Crossfade.

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

Spielerspezifische Felder​

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

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

Spielerspezifische Methoden​

Textformatierung

Überall dort, wo die API „unterstützt Farbcodes" sagt, schickt Magmacore den String durch seinen eingebauten MiniMessage-Parser. Legacy-&-Codes, &#RRGGBB-Hex, <#RRGGBB>, <gradient>, <rainbow> und der restliche MiniMessage-Tag-Satz funktionieren alle und können frei gemischt werden. Kyori Adventure ist keine Abhängigkeit und den Scripts steht keine Adventure-API zur Verfügung — du brauchst sie nicht.

Die Lua-Textmethoden wandeln in einen Legacy-String mit Farbcodes um, sodass Farben, Verläufe und Dekorationen korrekt dargestellt werden, während interaktive Tags (<hover>, <click>, <insert>, <font>, <key>, <lang>) zwar geparst werden, aber keine Wirkung haben. Gängige Formate findest du im gemeinsamen Leitfaden Farbcodes.

MethodeGibt zurückHinweise
send_message(msg)voidSendet eine Chatnachricht an den Spieler. Unterstützt Farbcodes.
chat(text)voidSendet farbverarbeiteten Text über Bukkit-Spielerchat, einschließlich Befehlen mit führendem Schrägstrich als dieser Spieler
get_held_item()table oder nilGibt {type, amount, display_name} für das Item in der Haupthand des Spielers zurück, oder nil bei leerer Hand. type ist der Bukkit-Materialname in Großbuchstaben, beispielsweise "GOLD_INGOT".
consume_held_item(amount?)voidPlant Verbrauch aus der Haupthand zum Ausführungszeitpunkt ein. Standard 1; hält kein geprüftes Item fest und bestätigt keine Zahlung. Übergib eine positive Menge; negative Werte werden nicht abgelehnt.
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 nilPrüft einen Strahl von den Augen gegen Blöcke und Entities, ohne den Spieler, mit Entity-Strahlgröße 0.5. Ignoriert Flüssigkeiten und passierbare Blöcke; Standardreichweite 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])booleanPlant einen reinen Client-Block mit Rücksetzung nach positiven Ticks ein. True bedeutet eingeplant; ungültige oder nicht als Block verwendbare Materialien liefern false.
reset_block(x, y, z)booleanPlant die Wiederherstellung des echten Blocks für den Spieler ein und liefert true
sleep(x, y, z)voidPlant ein echtes weißes Bett und einen Schlafversuch ein. Beim Aufwachen oder Disconnect wird nur BlockData wiederhergestellt, kein Inhalt der Block-Entity.
wake_up()voidWeckt einen schlafenden Spieler auf.

Geplante Blockänderungen und Rücksetzungen lesen die Spielerwelt bei Ausführung. Verlasse dich nach einem Weltwechsel nicht auf die Wiederherstellung des vorgesehenen Blocks. Die Schlafbereinigung prüft nach 20 Ticks und dann alle 10 Ticks. Diese Aufgaben gehören nicht zu context.scheduler.


Spieler-UI-Methoden​

Dies sind die Methoden der gemeinsamen Player-Tabelle. Bossfähigkeiten haben andere UI-Signaturen in der API-Referenz. Gemeinsame Leisten werden pro Spieler innerhalb der MagmaCore-Kopie des Plugins verwaltet, nicht pro Skript. Ein Ablauftimer entfernt nur die Leiste oder wiederholte Action-Bar, die ihn gestartet hat; ein älterer Ablauf entfernt also keine neuere. Ihre Bukkit-Timer gehören nicht zu context.scheduler.

player:show_boss_bar(text, [color], progress, [ticks])​

Ersetzt die gemeinsame durchgehende Bossleiste des Spielers. Der Fortschritt wird auf 0..1 begrenzt; eine ungültige Farbe wird weiß. Übergib nil bei ausgelassener Farbe, damit der Fortschritt an dritter Stelle bleibt.

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)
ticksint-1Positive Werte planen das Entfernen ein; sonst bleibt die Leiste bis zum Ausblenden oder Ersetzen

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.
ticksint-1Positive Werte wiederholen alle 40 Ticks bis zum Ablauf; sonst einmaliger Versand. Ein neuer Aufruf beendet die vorige Wiederholung.

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: