Zum Hauptinhalt springen

Lua-Scripting: Erste Schritte

webapp_banner.jpg

Was du lernen wirst​

Diese Seite zeigt dir, wie du deine erste Lua-Power für EliteMobs schreibst, von einer leeren Datei bis hin zu einer funktionierenden Boss-Fähigkeit. Am Ende wirst du Hooks, Context, Abklingzeiten und die allgemeine Struktur jeder Lua-Power-Datei verstehen.

Sobald du mit den Grundlagen vertraut bist, fahre mit den Begleitseiten fort:

  • Hooks & Lebenszyklus -- Hook-Namen, Ausführungsreihenfolge und Context-Verfügbarkeit
  • NPC-Skripte -- NPC-Lebenszyklus, Interaktions- und Näherungs-Hooks
  • Boss & Entitäten -- die APIs context.boss, context.player, context.players und context.entities
  • Welt & Umgebung -- Partikel, Sounds, Blitze, Spawning und die context.world-API
  • Zonen & Zielerfassung -- native Lua-Zonen, Script-Utilities-Zielerfassung und die APIs context.zones / context.script
  • Beispiele & Muster -- vollständige, funktionierende Powers zum Studieren und Anpassen
  • Enums & Werte -- Links zu den Spigot-Javadocs für Particle, Material, PotionEffectType und andere String-Konstanten
  • Fehlerbehebung -- häufige Fehler, Debugging-Tipps und die QC-Checkliste
  • Verhaltensprogramme -- in Lua geschriebene Mob-KI, ausgewählt über die Einstellung behavior eines Bosses
Noch in Entwicklung

Die meisten mitgelieferten EliteMobs-Powers verwenden Lua. Namen und Verhalten von Hilfsmethoden können sich zwischen Versionen ändern. Prüfe eigene Powers auf einem Staging-Server, bevor du sie produktiv verwendest, und lies die Referenz nach Updates erneut.

Beziehung zu EliteScript

Lua ersetzt nicht das bestehende eliteScript:-YAML-System, und EliteScript ist nicht veraltet.

  • Verwende EliteScript, wenn du deklaratives, YAML-gesteuertes Scripting mit den bestehenden Seiten für Aktionen, Ziele, Zonen, Bedingungen, Abklingzeiten und Relative Vektoren wünschst.
  • Verwende Lua-Power-Dateien, wenn du Variablen, Schleifen, zufällige Auswahl, wiederverwendbare Hilfsfunktionen, persistenten Zustand pro Boss und einen traditionelleren Programmierablauf benötigst.

Die Script-Utilities-API (context.script) übergibt deine Spezifikationstabellen an die EliteScript-Klassen für Ziele, Zonen, relative Vektoren und Partikel. Deren Parser und Einschränkungen gelten weiterhin, eigenständige Lua-Objekte besitzen jedoch nicht jeden Kontext einer YAML-Aktion. Vererbte Ziele und Landepositionen benötigen Kontext, der diesen Objekten fehlt. Lua-Helfer wenden auch Wartezeiten, Bedingungen und Ziel-Caches von YAML-Aktionen nicht automatisch an. Die Begleitseite zu Zonen und Zielerfassung erklärt die Unterschiede.


Was Lua-Powers sind​

Lua-Powers sind eigenständige .lua-Dateien, die im normalen EliteMobs-powers-Verzeichnisbaum liegen und genau wie normale Power-Dateien referenziert werden.

Boss-Powers vs. NPC-Skripte

Diese Seite behandelt Lua-Powers für Bosse. NPC-Lua-Skripte sind ein separates Feature: Sie liegen in plugins/EliteMobs/npc_scripts/, werden über eine scripts:-Liste in der NPC-Konfiguration angehängt und verwenden NPC-spezifische Hooks wie on_npc_proximity_enter. Siehe NPC-Skripte.

Wofür Lua-Powers gut geeignet sind​

Lua-Powers glänzen, wenn du Folgendes benötigst:

  • Angriffsrotationen und zufällige Fähigkeitsauswahl
  • Persistenter Zustand zwischen Hooks mit context.state
  • Verzögerte und wiederholte Aktionen, ohne alles mit YAML-Wartezeiten aufzubauen
  • Benutzerdefinierte Hilfsfunktionen innerhalb einer Datei
  • Komplexe Verzweigungen, die in reinem EliteScript umständlich wären
  • Boss-Logik, die dennoch EliteScript-ähnliche Zielerfassung und Zonendefinitionen wiederverwenden möchte

Wenn deine Power hauptsächlich „Ereignis auslösen, ein paar geskriptete Aktionen ausführen" ist, sind die bestehenden EliteScript-Dokumente nach wie vor der schnellste und klarste Weg, sie zu erstellen. Wenn deine Power echten Programmfluss benötigt, ist Lua das richtige Werkzeug dafür.


Für wen diese Seite gedacht ist​

Diese Seite ist für drei Arten von Lesern geschrieben:

  • Jemand, der bereits EliteScript kennt und Lua lernen möchte, ohne gleich „echtes Programmieren" komplett zu erlernen
  • Jemand, der neu im EliteMobs-Scripting ist und eine vollständige Referenz mit exakten Namen benötigt
  • Jemand, der KI zum Entwerfen von Powers nutzt und genug Details braucht, um zu erkennen, wenn die KI etwas Falsches erfunden hat

Du musst nicht ein vollwertiger Lua-Entwickler werden, bevor du nützliche Powers schreiben kannst. Für die meisten praktischen EliteMobs-Powers benötigst du nur:

  • Wie man einen gültigen Hook in der zurückgegebenen Tabelle platziert
  • Wie man Werte aus context liest
  • Wie man mit if ... then return end frühzeitig abbricht
  • Wie man ein paar Hilfsmethoden korrekt aufruft
  • Wie man die richtigen Ziel- und Zonenspezifikationen aus den bestehenden EliteScript-Docs kopiert

Mentales Modell: EliteScript vs. Lua​

Wenn du EliteScript kennst, ist dieser Vergleich der schnellste Weg, Lua-Powers zu verstehen:

Wenn du in EliteScript-Begriffen denkstIn Lua bedeutet das normalerweise
EventsHook-Namen wie on_spawn oder on_boss_damaged_by_player
Cooldownscontext.cooldowns (siehe context.cooldowns weiter unten)
AktionenDirekte Methodenaufrufe wie context.world:spawn_particle_at_location(...) oder context.script:damage(...)
Zielecontext.script:target({...}) -- verwendet die Feldnamen von EliteScript Target
Zonencontext.script:zone({...}) oder native context.zones-Helfer -- siehe Zonen & Zielerfassung
Relative Vektorencontext.script:relative_vector({...}) oder context.vectors
SkriptflussDeine eigenen Lua-if-Anweisungen, Hilfsfunktionen, Timer und Zustand

Der größte Unterschied ist dieser:

  • EliteScript beschreibt in YAML, was passieren soll.
  • Lua lässt dich mithilfe von Code entscheiden, wann, warum und welcher Zweig ausgeführt werden soll.

Wenn sich EliteScript also wie „Konfiguration" anfühlt, fühlt sich Lua wie „Konfiguration plus Entscheidungsfindung" an.


Kleiner Lua-Einstieg für EliteMobs-Autoren​

Die meisten Powers verwenden wenige Lua-Konzepte: Variablen (local x = 5), Funktionen (function foo() end), if-Prüfungen (if x then ... end), Tabellen ({key = value}) und nil (kein Wert). Semikolons sind optional. Tabellen verwenden geschweifte Klammern; Funktionen und Kontrollblöcke enden mit end.

Eine vollständige Einführung mit Beispielen findest du unter MagmaCore Lua Scripting Engine — Tiny Lua Primer. Diese Einführung wird von allen Nightbreak-Plugins gemeinsam genutzt, einmal gelernt gilt sie also überall.


Deine erste funktionierende Power, Schritt für Schritt​

Wenn du komplett neu bist, ist dies die beste Progression für den „ersten Erfolg".

Vor Schritt 1: Speichern und an einen Boss anhängen​

Speichere die Lua-Datei im normalen EliteMobs-Powers-Ordner, zum Beispiel:

plugins/
EliteMobs/
powers/
first_test.lua

Füge dann diesen Dateinamen zur Boss-Konfiguration in der normalen powers:-Liste hinzu:

powers:
- first_test.lua

Der vollständige Anfänger-Ablauf ist also:

  1. Datei in plugins/EliteMobs/powers/ speichern
  2. Den .lua-Dateinamen zur powers:-Liste des Bosses hinzufügen
  3. /em reload ausführen, um geänderte Dateien zu laden, und anschließend einen neuen Testboss spawnen. Das Neuladen betrifft das Plugin und seine aktiven Inhalte; verwende einen Staging-Server.
  4. Den Hook auslösen und sowohl das sichtbare Ergebnis als auch die Konsole prüfen. Speichern oder das Spawnen eines weiteren Bosses ohne Neuladen aktualisiert keine bereits geladene Definition.

Wenn du mehr Hintergrundwissen zu Boss-Dateien, Power-Listen oder der Struktur benutzerdefinierter Bosse benötigst, sieh dir Benutzerdefinierte Bosse erstellen an. Diese Seite behandelt die Boss-Einrichtung im Detail, einschließlich der Funktionsweise der powers:-Liste.

Schritt 1: Die Datei laden lassen​

return {
api_version = 1,

on_spawn = function(context)
end
}

Der Loader prüft Lua-Syntax, Rückgabetabelle und Hook-Namen. Ein leerer Hook hat kein sichtbares Ergebnis. Schweigen allein beweist deshalb nicht, dass die Datei gefunden oder angehängt wurde. Ergänze den Sound aus Schritt 2 und spawne einen neuen Boss, um diesen Ablauf zu prüfen.

Schritt 2: Den Boss eine sichtbare Aktion ausführen lassen​

return {
api_version = 1,

on_spawn = function(context)
context.boss:play_sound_at_self("entity.blaze.ambient", 1.0, 1.0)
end
}

Jetzt hast du den wichtigsten Anfängerbeweis: Dein Hook wird ausgelöst.

Schritt 3: Auf einen Spielertreffer reagieren​

return {
api_version = 1,

on_boss_damaged_by_player = function(context)
if context.player == nil then
return
end

context.player:send_message("&eYou hit the boss.")
end
}

Dies vermittelt drei Kernideen:

  • on_boss_damaged_by_player ist der Hook-Name
  • context.player ist der Spieler, der an diesem Hook beteiligt ist
  • return bricht frühzeitig ab, wenn die benötigten Daten fehlen

Schritt 4: Spam mit einer Abklingzeit verhindern​

return {
api_version = 1,

on_boss_damaged_by_player = function(context)
if context.player == nil then
return
end

if not context.cooldowns:local_ready("hello_message") then
return
end

context.player:send_message("&eYou woke up the boss.")
context.cooldowns:set_local(60, "hello_message")
end
}

Ein Tick der lokalen Abklingzeit entspricht 50 Millisekunden verstrichener Zeit: 60 entspricht auch bei sinkenden Server-TPS drei Sekunden. Diese benannte Abklingzeit wird zwischen den Powers dieses Bosses geteilt, nicht zwischen verschiedenen Bossen. Stelle Schlüsseln den Namen deiner Power voran, wenn du eigene Powers kombinierst. Dieses Beispiel prüft nur seinen lokalen Schlüssel, nicht die globale Abklingzeit des Bosses.

Schritt 5: Einen echten Effekt hinzufügen​

return {
api_version = 1,

on_boss_damaged_by_player = function(context)
if context.player == nil then
return
end

if not context.cooldowns:local_ready("shock") then
return
end

context.cooldowns:set_local(100, "shock")
context.player:send_message("&cStatic jumps from the boss into your armor!")
context.world:strike_lightning_at_location(context.player.current_location)
end
}

Dies erzeugt einen echten Blitz in der Welt, keinen rein visuellen Effekt. Die Abklingzeit wird vor dem Effekt gesetzt, damit dadurch ausgelöste Ereignisse sie sehen. Diese lokale Abklingzeit von 100 Ticks entspricht fünf Sekunden verstrichener Zeit.


Erster echter Arbeitsablauf​

Wenn du eine brandneue Lua-Power erstellst, verwende diese Reihenfolge:

  1. Die Datei erstellen und on_spawn zum Laufen bringen.
  2. Zum gewünschten Hook wechseln.
  3. Bestätigen, dass der Hook die erwarteten Daten hat, wie context.player oder context.event.
  4. Zuerst eine Nachricht oder einen Sound hinzufügen, bevor Schaden oder Partikel.
  5. Abklingzeiten hinzufügen.
  6. Einen Gameplay-Effekt hinzufügen.
  7. Erst danach Helfer, Zustand, Scheduler-Logik oder Zonen hinzufügen.

Diese Reihenfolge macht das Debugging erheblich einfacher, da sich immer nur eine Sache ändert.


Wo Lua-Dateien liegen​

Platziere .lua-Dateien im selben Ordnerbaum wie normale Power-.yml-Dateien:

plugins/
EliteMobs/
powers/
mycoolpower.lua
attack_push.yml
subfolder/
myotherpower.lua

Lua-Powers werden automatisch aus den Power-Verzeichnissen erkannt, die EliteMobs bereits lädt.

Optionale YAML-Metadaten​

Neben einer eigenen mycoolpower.lua kann im selben Verzeichnis eine geladene mycoolpower.yml oder mycoolpower.yaml liegen. Die Erkennung liest daraus isEnabled, effect, powerType, powerCooldown und globalCooldown; isEnabled: false verhindert die Registrierung dieser eigenen Lua-Datei. Ohne passende Metadaten verwendet sie keinen Effekt und den Power-Typ MISCELLANEOUS. Lua-Hooks bestimmen weiterhin, wann Angriffe stattfinden, und müssen ihre Abklingzeiten selbst prüfen.

Eine geladene YAML-Datei mit demselben Basisnamen neben einer mitgelieferten Lua-Power wendet dieselben Felder auf diese Power an. Ohne eine solche Datei behält die mitgelieferte Power ihre ausgelieferten Metadaten. Siehe Powers erstellen für die Metadatenfelder.

Wie Bosse Lua-Powers referenzieren​

Boss-Dateien verwenden weiterhin die normale powers:-Liste:

powers:
- attack_push.yml
- mycoolpower.lua

Es ist kein spezielles Feld erforderlich. Lua-Powers werden nicht über eliteScript: geladen.

Dateibenennungsregeln​

  • Bosse referenzieren Lua-Powers über den Dateinamen, nicht über den Ordnerpfad.
  • EliteMobs registriert entdeckte Lua-Powers derzeit nur über den Basisnamen.
  • Vermeide doppelte Namen wie powers/fire.lua und powers/bosses/fire.lua. EliteMobs lädt nur die Datei, deren vollständiger Pfad alphabetisch zuerst kommt, und protokolliert eine Warnung zur übersprungenen Kopie, sofern die beiden Dateien nicht identisch sind.

Vorgefertigte Lua-Powers​

Die meisten mitgelieferten Powers verwenden Lua. Der aktuelle Quellcode definiert 68 konkrete vorgefertigte Lua-Powers, die bei Fehlen unter plugins/EliteMobs/powers/ installiert werden, darunter attack_fire.lua, frost_cone.lua, meteor_shower.lua und shield_wall.lua. Nutze diese Dateien als Beispiele, bedenke aber, dass eine bearbeitete lokale Kopie von der mitgelieferten Version abweichen kann.

Vorgefertigte Dateien werden nur geschrieben, wenn sie fehlen; Änderungen überleben daher Neustarts. Ändert ein Update eine mitgelieferte Power, wird eine unbearbeitete Kopie einer früher ausgelieferten Version beim Start nach plugins/MagmaCore/outdated files/EliteMobs/ verschoben und die aktuelle Version an ihrer Stelle geschrieben; bearbeitete Kopien bleiben erhalten. Wird eine mitgelieferte Datei entfernt, erzeugt die nächste Plugin-Initialisierung die ausgelieferte Version neu. Bewahre benötigte eigene Änderungen vor dem Ersetzen auf.

Gemeinsame Quelltextfragmente​

Boss-Powers können eine Hilfsdatei mit einer alleinstehenden Kommentardirektive einbinden:

-- @include helpers/common.inc

Der Loader fügt den Text der referenzierten Datei vor der Validierung ein. Pfade sind relativ zur Datei mit der Direktive und müssen innerhalb des Verzeichnisses der obersten Power-Datei bleiben, auch nach dem Auflösen symbolischer Links. Zyklische Includes, mehr als 16 Verschachtelungsebenen, Dateien über 4 MiB und expandierter Quelltext über 4.194.304 Zeichen werden abgelehnt.

Verwende für Fragmente eine andere Endung als .lua, etwa .inc, damit sie nicht zusätzlich als eigenständige Powers erkannt werden. Definiere Hilfsfunktionen vor der abschließenden return-Tabelle. Diese Direktive gilt nur beim Laden von Boss-Powers; sie aktiviert weder Lua-require noch Dateisystemzugriff und wird von NPC-Skripten nicht verarbeitet.

Alte .yml-Namen funktionieren weiterhin​

Boss-Konfigurationen mit attack_fire.yml funktionieren weiterhin. Bei .yml- oder .yaml-Referenzen sucht EliteMobs zuerst nach einer geladenen Lua-Power mit demselben Basisnamen und fällt danach auf den wörtlichen Namen zurück. Eine ungültige oder deaktivierte Datei ist kein geladener Ersatz. Halte Schreibweise und Groß-/Kleinschreibung des Basisnamens konsistent. Bearbeite zum Anpassen einer mitgelieferten Lua-Power ihre vorhandene Datei und lade neu; doppelte Basisnamen in anderen Verzeichnissen sind kein zuverlässiger Überschreibmechanismus.


Minimaler Dateivertrag​

Jede Lua-Power muss eine Tabelle mit return zurückgeben. Diese Tabelle ist absichtlich strikt.

Erforderliche und optionale Top-Level-Felder​

FeldErforderlichTypAnmerkungen
api_versionJaNumberVerwende die Ganzzahl 1
priorityNeinNumberVerwende eine Ganzzahl. Kleinere Werte laufen zuerst; Standard 0. YAML-Powers verwenden Priorität 0
Unterstützte Hook-SchlüsselNeinFunctionVerwende einen der exakten Namen aus der Hook-Referenz

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 zeigen.
  • Unbekannte Top-Level-Schlüssel werden abgelehnt.

Das bedeutet, dass Hilfsfunktionen und lokale Konstanten oberhalb des abschließenden return stehen sollten, nicht innerhalb der zurückgegebenen Tabelle, es sei denn, es handelt sich um tatsächliche Hooks.

Der Dateikörper wird bei der Validierung und erneut in einer separaten Lua-Umgebung für jede Power-Laufzeit eines Bosses ausgewertet. context existiert nur als Hook- oder Callback-Argument, nicht als globale Variable auf Dateiebene. Lokale Variablen können für diese Laufzeit bestehen bleiben; Werte aus der Validierung werden nicht übernommen. Die Laufzeit entfernt Datei-, Betriebssystem- und Java-Zugriff sowie require; verwende die Include-Direktive für Quelltextfragmente. Ein nicht abgefangener Hook- oder Callback-Fehler schließt diese Laufzeit und beendet ihre Aufgaben; beim nächsten Treffer erfolgt kein neuer Versuch. Korrigiere die Datei und lade vor dem nächsten Versuch neu.


Kopiervorlagen zum Einfügen​

Kleinstmögliche gültige Lua-Power​

return {
api_version = 1,

on_spawn = function(context)
end
}
local ATTACK_COOLDOWN = "my_attack"

local function can_run_attack(context)
return context.cooldowns:local_ready(ATTACK_COOLDOWN)
and context.cooldowns:global_ready()
end

local function run_attack(context)
context.boss:play_sound_at_self("entity.blaze.shoot", 1.0, 1.0)
context.cooldowns:set_local(100, ATTACK_COOLDOWN)
context.cooldowns:set_global(20)
end

return {
api_version = 1,
priority = 0,

on_boss_damaged_by_player = function(context)
if context.player == nil then
return
end

if not can_run_attack(context) then
return
end

run_attack(context)
end
}

Layout für größere Dateien​

local CONSTANT_NAME = "value"

local function helper_function(context)
end

local function another_helper(context, value)
end

return {
api_version = 1,
priority = 0,

on_spawn = function(context)
end,

on_enter_combat = function(context)
end,

on_boss_damaged_by_player = function(context)
end,

on_exit_combat = function(context)
end
}

Hooks​

Hooks sind speziell benannte Funktionen in der Tabelle, die du zurückgibst. EliteMobs ruft sie auf, wenn etwas passiert — der Boss spawnt, nimmt Schaden, tritt in den Kampf ein usw. Du hast on_spawn und on_boss_damaged_by_player bereits im obigen Tutorial gesehen.

Die häufigsten Hooks zum Einstieg sind on_spawn, on_boss_damaged_by_player, on_enter_combat und on_exit_combat. Für die vollständige Liste aller Hooks, welche Context-Schlüssel in jedem verfügbar sind und wie die Ausführungsreihenfolge funktioniert, siehe Hooks & Lebenszyklus.


Was ist context?​

Jede Hook-Funktion erhält ein Argument namens context. Stell es dir als einen Werkzeugkasten vor, den EliteMobs dir jedes Mal übergibt, wenn etwas passiert — er enthält alles, was du brauchst, um mit dem Boss, dem Spieler, der Welt, Abklingzeiten und mehr zu interagieren.

on_boss_damaged_by_player = function(context)
-- context.boss = the boss that was hit
-- context.player = the player who hit it
-- context.world = tools for spawning particles, sounds, etc.
-- context.cooldowns = cooldown management
-- context.state = your own persistent storage
end

Du erstellst context nicht selbst — EliteMobs erstellt es und übergibt es an deinen Hook. Du liest einfach daraus und rufst Methoden darauf auf.

Info

Jeder Hook erhält einen neuen context. Seine Tabelle context.state gehört zur Laufzeit dieser Power auf diesem Boss und kann Daten für spätere Hooks und Callbacks speichern. Andere Powers haben einen eigenen Zustand; Schließen oder Neuladen der Laufzeit verwirft ihn.


Wichtige context-APIs​

Hier sind die wichtigsten APIs, die du aus context verwenden wirst:

  • context.state — Eine Lua-Tabelle, die für die Laufzeit dieser Power auf diesem Boss erhalten bleibt. Speichere darin Phasennummern, Aufgaben-IDs und Flags zwischen Hooks. Entfernen oder Neuladen der Laufzeit erhält diese Daten nicht.

  • context.log — Konsolenprotokollierung mit log:info(msg), log:warn(msg) und log:debug(msg). Nimm den Namen der Power in Nachrichten auf, wenn du Ausgaben mehrerer Powers unterscheiden musst.

  • context.cooldowns — Benannte Abklingzeiten und eine globale Abklingzeit, die die Powers des Bosses teilen. Explizite Schlüssel verwenden einen gemeinsamen Namensraum pro Boss; stelle ihnen den Namen deiner Power voran. nil wählt die Standardabklingzeit dieses Lua-Dateinamens. cooldowns:check_local(key, ticks) prüft und setzt die lokale Abklingzeit in einem Aufruf; die globale wird weder geprüft noch gesetzt. Die vollständige API steht unter Hooks & Lebenszyklus.

  • context.scheduler — scheduler:run_after(ticks, callback) verzögert einen einzelnen Callback. scheduler:run_every(ticks, callback) wiederholt ohne anfängliche Intervallwartezeit; verwende scheduler:run_repeating(delay, interval, callback) für eine ausdrückliche Startverzögerung. Callbacks erhalten einen neuen Kontext ohne auslösendes Ereignis oder Spieler. Verwende dieses Argument und speichere benötigte Spieler-UUIDs oder Positionen bewusst; verlass dich nicht darauf, dass ctx.player nach einer Verzögerung vorhanden ist. Beende kampfgebundene Wiederholungen in on_exit_combat; sonst laufen Aufgaben bis zur Abmeldung oder zum Schließen der Laufzeit weiter. Siehe Hooks & Lebenszyklus.

  • context.boss / context.player — Der Boss und der Spieler, die am aktuellen Ereignis beteiligt sind. Siehe Boss & Entitäten für alle Felder und Methoden.

  • context.world — Partikel, Entitäten, Sounds, Blitze, Blöcke spawnen. Siehe Welt & Umgebung.

  • context.zones / context.script — Zonengeometrie, Zielerfassung, Schaden, Partikel. Siehe Zonen & Zielerfassung.


Methodensyntax: : vs. .​

Eine Erklärung zu : und . findest du in der MagmaCore Lua Scripting Engine. Entitätsmethoden und gemeinsame Dienste akzeptieren beide Formen. context.event.set_damage_amount(value) und context.event.multiply_damage_amount(multiplier) benötigen den Punkt; ein Doppelpunkt übergibt die Ereignistabelle als erstes Argument. context.event:transfer_damage(target, amount) akzeptiert einen Doppelpunkt. Globale Konstruktoren wie em.create_location(...) verwenden einen Punkt.


Nächste Schritte​

Nachdem du nun die Grundlagen kennst, erkunde den Rest der Lua-Scripting-Dokumentation:

  • Hooks & Lebenszyklus -- Hook-Namen, Ausführungsreihenfolge und welche Context-Schlüssel in jedem Hook verfügbar sind
  • NPC-Skripte -- Speicherort der NPC-Dateien, Hooks, Näherungs-Events und context.npc
  • Boss & Entitäten -- context.boss, context.player, context.players, context.entities und context.event
  • Welt & Umgebung -- Partikel, Sounds, Blitze, Spawning und context.world
  • Zonen & Zielerfassung -- native Lua-Zonen, Script-Utilities-Zielerfassung/-Zonen/-Partikel und relative Vektoren
  • Beispiele & Muster -- vollständige, funktionierende Powers mit Erklärungen
  • Enums & Werte -- Links zu den Spigot-Javadocs für Particle, Material, PotionEffectType und mehr
  • Fehlerbehebung -- häufige Fehler, Debugging-Tipps und eine QC-Checkliste

Für YAML-basiertes Scripting bleiben die EliteScript-Seiten die maßgebliche Referenz: