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

Diese zurückgegebene Tabelle ist die Skriptdatei.

Kommentare

Verwende --, um eine Notiz für Menschen zu schreiben:

-- This cooldown stops the attack from firing every hit
context.cooldowns:set_local(60, "fire_burst")

Lua-Sandbox

Alle Lua-Skripte laufen 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.
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, und Custom Items binden nur das erste gültige Skript aus dieser Liste.

Wo Skriptdateien liegen

Jedes Plugin verweist die Engine auf genau ein Skriptverzeichnis. Dieses Verzeichnis wird rekursiv durchsucht, sodass .lua-Dateien in Unterordnern erfasst werden und du Skripte beliebig organisieren kannst. Innerhalb jedes Ordners werden Dateien in alphabetischer Reihenfolge besucht.

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
}

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 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 also wie dokumentiert mit . auf: em.create_location(...), em.zone.create_sphere_zone(...) und em.location.is_protected(...). Auch EliteMobs-Event-Funktionen sind mit . am sichersten. Die Dokumentation verwendet : für Methoden von Kontexttabellen und . für einfache Funktionen.


Laufzeit-Budget

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.

Ein einzelner Aufruf wird abgebrochen, sobald er eines der beiden Limits überschreitet:

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

Das Erreichen eines der Limits löst innerhalb des Skripts einen Lua-Fehler aus. Während eines Hooks oder eines geplanten Callbacks wird die Meldung protokolliert und diese Skriptinstanz für ihren Besitzer deaktiviert. Während der anfänglichen Auswertung einer Skriptdatei gibt es noch keine Instanz: Die Definition wird abgelehnt und nicht registriert. Auf einer JVM, auf der die CPU-Zeitmessung des aktuellen Threads nicht verfügbar ist, verwendet MagmaCore ersatzweise eine verstrichene Zeit von 250 Millisekunden und behält dasselbe Instruktionslimit bei.

Endlosschleifen werden abgefangen, kosten dich aber trotzdem einen Tick

Da die VM das Budget beim Ausführen von Lua-Instruktionen prüft, friert ein while true do end den Server nicht mehr ein — es wird beim Budget abgeschnitten. Es kann trotzdem die volle CPU-Zuteilung auf dem Server-Thread verbrauchen, und es deaktiviert trotzdem das Skript; das ist also ein Sicherheitsnetz, kein Freibrief für unbegrenzte Schleifen.

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

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)
-- 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 — Boss-Powers, NPC-Skripte und FreeMinecraftModels-Skripte — verwenden die oben gezeigte gemeinsame Reihenfolge: check_local(key?, duration). (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. 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.

Gemeinsame Welt-Tabelle auf jeder Oberfläche

Die hier dokumentierten Methoden bilden die gemeinsame MagmaCore-Tabelle context.world. Props/Items von FreeMinecraftModels und EliteMobs-NPC-Skripte erhalten diese Tabelle direkt, einschließlich strike_lightning(...). FreeMinecraftModels legt zusätzlich drei optionale EliteMobs-Loot-Helfer darüber (drop_elitemobs_procedural_loot, drop_elitemobs_random_loot, drop_elitemobs_custom_loot), die nur dann etwas bewirken, wenn EliteMobs installiert ist; siehe context.world: FreeMinecraftModels-Ergänzungen. EliteMobs-Boss-Powers gehen von derselben Basistabelle aus und ergänzen oder überschreiben dann EliteMobs-spezifische Methoden wie geschützte Blitze, Fake-Projektile, das Spawnen von Verstärkungen und Spieler-Loot-Helfer; siehe EliteMobs World & Environment.

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.

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

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

Platziert einen Block, der nach einer Verzögerung automatisch in seinen ursprünglichen Zustand zurückkehrt.

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
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 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() -- 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 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 (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 eigene WorldGuard- und GriefPrevention-Adapter mit. Konsumierende Plugins initialisieren sie beim Aktivieren, und die erste Schutzabfrage führt zusätzlich eine verzögerte Initialisierung als Rückfalloption durch — es gibt keine Konfiguration und keine harte Abhängigkeit. Ist keines der beiden Plugins installiert und registriert kein Inhalts-Plugin einen Besitz, gibt em.location.is_protected(loc) schlicht false zurück; Start- und Abfragewarnungen weisen darauf hin, dass kein Anbieter verfügbar ist. Eine nil- oder ungültige Location liefert bei den Prädikaten false und bei owners / kinds_at eine leere Tabelle; diese Helfer werfen nie einen Fehler.

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

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 können Felder zur Erkennung und Interaktion mit Entities enthalten, die von anderen Nightbreak-Plugins verwaltet werden. Der Live-Enricher ergänzt seine booleschen Flags auf oberster Ebene, wenn das jeweilige Plugin installiert ist; ohne diesen Enricher fehlen diese Felder und lesen sich als nil statt standardmäßig als false.

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 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
-- 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])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.

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.
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, 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
-- 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. Die vollständige Tag-Liste findest du unter Farbcodes.

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:

Aktuelle Konstruktoren bieten em.create_location(...), em.zone.create_sphere_zone(...) und Abfragen wie em.location.is_protected(...); Spielertabellen ergänzen has_permission(node). Der genaue Kontext hängt vom Hook ab: Gehe in geplanten Callbacks nicht von context.event.player aus.