Lua-Scripting: Erste Schritte
Was Sie lernen werden
Diese Seite zeigt Ihnen, wie Sie Ihre erste Lua-Power für EliteMobs schreiben, von einer leeren Datei bis hin zu einer funktionierenden Boss-Fähigkeit. Am Ende werden Sie Hooks, Context, Abklingzeiten und die allgemeine Struktur jeder Lua-Power-Datei verstehen.
Sobald Sie mit den Grundlagen vertraut sind, fahren Sie mit den Begleitseiten fort:
- Hooks & Lebenszyklus -- Hook-Namen, Ausführungsreihenfolge und Context-Verfügbarkeit
- Boss & Entitäten -- die APIs
context.boss,context.player,context.playersundcontext.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
Lua-Power-Dateien sind derzeit experimentell. Hook-Namen, Hilfsmethoden und Verhaltensweisen können sich noch ändern, während EliteMobs weiterentwickelt wird. Testen Sie daher sorgfältig, bevor Sie sie auf einem Produktionsserver verwenden.
Lua ersetzt nicht das bestehende eliteScript:-YAML-System.
- Verwenden Sie EliteScript, wenn Sie deklaratives, YAML-gesteuertes Scripting mit den bestehenden Seiten für Aktionen, Ziele, Zonen, Bedingungen, Abklingzeiten und Relative Vektoren wünschen.
- Verwenden Sie Lua-Power-Dateien, wenn Sie Variablen, Schleifen, zufällige Auswahl, wiederverwendbare Hilfsfunktionen, persistenten Zustand pro Boss und einen traditionelleren Programmierablauf benötigen.
Lua hat sein eigenes Zielerfassungs- und Zonensystem, das dieselben bekannten Enum-Namen und Konzepte verwendet, die Sie bereits aus EliteScript kennen. Die Script-Utilities-API (context.script) ermöglicht es Ihnen, Zonen, Ziele und relative Vektoren mit denselben Feldnamen zu erstellen, die in den EliteScript-Seiten dokumentiert sind.
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.
Wofür Lua-Powers gut geeignet sind
Lua-Powers glänzen, wenn Sie Folgendes benötigen:
- 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 Ihre 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 Ihre 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
Sie müssen nicht ein vollwertiger Lua-Entwickler werden, bevor Sie nützliche Powers schreiben können. Für die meisten praktischen EliteMobs-Powers benötigen Sie nur:
- Wie man einen gültigen Hook in der zurückgegebenen Tabelle platziert
- Wie man Werte aus
contextliest - Wie man mit
if ... then return endfrü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 Sie EliteScript kennen, ist dieser Vergleich der schnellste Weg, Lua-Powers zu verstehen:
| Wenn Sie in EliteScript-Begriffen denken | In Lua bedeutet das normalerweise |
|---|---|
| Events | Hook-Namen wie on_spawn oder on_boss_damaged_by_player |
| Cooldowns | context.cooldowns (siehe context.cooldowns weiter unten) |
| Aktionen | Direkte Methodenaufrufe wie context.world:spawn_particle_at_location(...) oder context.script:damage(...) |
| Ziele | context.script:target({...}) -- verwendet die Feldnamen von EliteScript Target |
| Zonen | context.script:zone({...}) oder native context.zones-Helfer -- siehe Zonen & Zielerfassung |
| Relative Vektoren | context.script:relative_vector({...}) oder context.vectors |
| Skriptfluss | Ihre eigenen Lua-if-Anweisungen, Hilfsfunktionen, Timer und Zustand |
Der größte Unterschied ist dieser:
- EliteScript beschreibt in YAML, was passieren soll.
- Lua lässt Sie 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
Dies ist die minimale Lua-Syntax, die die meisten Power-Autoren benötigen.
Variablen
Verwenden Sie 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 können Sie sie aufrufen:
warn_player(context.player)
if-Prüfungen
Verwenden Sie if, wenn etwas nur manchmal passieren soll:
if context.player == nil then
return
end
Das bedeutet: „Wenn es keinen Spieler für diesen Hook gibt, hier anhalten".
nil
nil bedeutet „kein Wert". Es ist Luas Version von „hier ist nichts".
Sie werden oft auf nil prüfen mit:
if context.event ~= nil then
-- etwas mit dem Event machen
end
~= bedeutet „ist nicht gleich".
Tabellen
Lua verwendet Tabellen für verschiedene Aufgaben:
- Listen
- Objekte mit benannten Schlüsseln
- Die zurückgegebene Power-Definition
Beispiel einer Tabelle mit benannten Schlüsseln:
local particle = {
particle = "FLAME",
amount = 1,
speed = 0.05
}
Die Power-Definition zurückgeben
Am Ende der Datei geben Sie eine Tabelle zurück:
return {
api_version = 1,
on_spawn = function(context)
end
}
Diese zurückgegebene Tabelle ist die Power-Datei.
Kommentare
Verwenden Sie --, um eine Notiz für Menschen zu schreiben:
-- Dieser Cooldown verhindert, dass der Angriff bei jedem Treffer ausgelöst wird
context.cooldowns:set_local(60, "fire_burst")
Ihre erste funktionierende Power, Schritt für Schritt
Wenn Sie komplett neu sind, ist dies die beste Progression für den „ersten Erfolg".
Vor Schritt 1: Speichern und an einen Boss anhängen
Speichern Sie die Lua-Datei im normalen EliteMobs-Powers-Ordner, zum Beispiel:
plugins/
EliteMobs/
powers/
first_test.lua
Fügen Sie dann diesen Dateinamen zur Boss-Konfiguration in der normalen powers:-Liste hinzu:
powers:
- first_test.lua
Der vollständige Anfänger-Ablauf ist also:
- Datei in
plugins/EliteMobs/powers/speichern - Den
.lua-Dateinamen zurpowers:-Liste des Bosses hinzufügen - Den Boss spawnen oder neu laden
- Den Hook testen, den Sie gerade bauen
Wenn Sie mehr Hintergrundwissen zu Boss-Dateien, Power-Listen oder der Struktur benutzerdefinierter Bosse benötigen, sehen Sie sich 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
}
Wenn dies ohne Fehler geladen wird, haben Sie bereits bewiesen:
- Die Datei ist gültiges Lua
- EliteMobs hat sie gefunden
- Die Struktur der zurückgegebenen Tabelle ist korrekt
on_spawnist ein gültiger Hook-Name
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 haben Sie den wichtigsten Anfängerbeweis: Ihr 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_playerist der Hook-Namecontext.playerist der Spieler, der an diesem Hook beteiligt istreturnbricht 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
}
Dies ist das erste wirklich nützliche Muster, das die meisten Autoren benötigen. Wenn Sie dieses Muster verstehen, können Sie bereits viele praktische Powers erstellen.
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.player:send_message("&cStatic jumps from the boss into your armor!")
context.world:strike_lightning_at_location(context.player.current_location)
context.cooldowns:set_local(100, "shock")
end
}
Ab diesem Punkt schreiben Sie bereits eine echte Power.
Erster echter Arbeitsablauf
Wenn Sie eine brandneue Lua-Power erstellen, verwenden Sie diese Reihenfolge:
- Die Datei erstellen und
on_spawnzum Laufen bringen. - Zum gewünschten Hook wechseln.
- Bestätigen, dass der Hook die erwarteten Daten hat, wie
context.playerodercontext.event. - Zuerst eine Nachricht oder einen Sound hinzufügen, bevor Schaden oder Partikel.
- Abklingzeiten hinzufügen.
- Einen Gameplay-Effekt hinzufügen.
- 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
Platzieren Sie .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.
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.
- Vermeiden Sie doppelte Namen wie
powers/fire.luaundpowers/bosses/fire.lua, da einer den anderen bei der Erkennung überschreiben kann.
Vorgefertigte Lua-Powers
EliteMobs wird mit Dutzenden vorgefertigter Lua-Powers im powers-Ordner ausgeliefert, wie attack_fire.lua, frost_cone.lua, meteor_shower.lua und viele mehr. Diese sind ausgezeichnete Referenzen zum Studieren — öffnen Sie einfach eine beliebige .lua-Datei in Ihrem plugins/EliteMobs/powers/-Verzeichnis. Aus Gründen der Abwärtskompatibilität werden vorgefertigte Powers auch unter ihren alten .yml-Namen registriert.
Minimaler Dateivertrag
Jede Lua-Power muss eine Tabelle mit return zurückgeben. Diese Tabelle ist absichtlich strikt.
Erforderliche und optionale Top-Level-Felder
| Feld | Erforderlich | Typ | Anmerkungen |
|---|---|---|---|
api_version | Ja | Number | Muss derzeit 1 sein |
priority | Nein | Number | Ausführungspriorität. Niedrigere Werte werden zuerst ausgeführt. Standard ist 0 |
| Unterstützte Hook-Schlüssel | Nein | Function | Muss einen der exakten Hook-Namen verwenden, die in der Hook-Referenz aufgeführt sind |
Validierungsregeln
- Die Datei muss eine Tabelle zurückgeben.
api_versionist erforderlich und muss derzeit1sein.prioritymuss numerisch sein, falls vorhanden.- Jeder zusätzliche Top-Level-Schlüssel muss ein unterstützter Hook-Name sein.
- Jeder Hook-Schlüssel muss auf eine Funktion 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.
Kopiervorlagen zum Einfügen
Kleinstmögliche gültige Lua-Power
return {
api_version = 1,
on_spawn = function(context)
end
}
Empfohlene Startvorlage
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 Sie zurückgeben. EliteMobs ruft sie auf, wenn etwas passiert — der Boss spawnt, nimmt Schaden, tritt in den Kampf ein usw. Sie haben 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. Stellen Sie es sich als einen Werkzeugkasten vor, den EliteMobs Ihnen jedes Mal übergibt, wenn etwas passiert — er enthält alles, was Sie brauchen, um mit dem Boss, dem Spieler, der Welt, Abklingzeiten und mehr zu interagieren.
on_boss_damaged_by_player = function(context)
-- context.boss = der Boss, der getroffen wurde
-- context.player = der Spieler, der ihn getroffen hat
-- context.world = Werkzeuge zum Spawnen von Partikeln, Sounds usw.
-- context.cooldowns = Abklingzeit-Verwaltung
-- context.state = Ihr eigener persistenter Speicher
end
Sie erstellen context nicht selbst — EliteMobs erstellt es und übergibt es an Ihren Hook. Sie lesen einfach daraus und rufen Methoden darauf auf.
context wird für jeden Hook-Aufruf neu erstellt, außer context.state, der für die gesamte Lebensdauer des Bosses bestehen bleibt. Das bedeutet, dass Sie Daten in context.state speichern und sie später in einem anderen Hook wieder lesen können.
Wichtige context-APIs
Hier sind die wichtigsten APIs, die Sie aus context verwenden werden:
-
context.state— Eine einfache Lua-Tabelle, die für die Lebensdauer des Bosses bestehen bleibt. Verwenden Sie sie, um Phasennummern, Task-IDs, Flags und alles, was Sie sich zwischen Hooks merken müssen, zu speichern. Nurcontext.statebleibt bestehen — alle anderen Context-Tabellen werden bei jedem Aufruf neu erstellt. -
context.log— Konsolenprotokollierung mitlog:info(msg),log:warn(msg)undlog:debug(msg). Unverzichtbar während der Entwicklung. -
context.cooldowns— Lokale Abklingzeiten pro Power und globale Abklingzeiten pro Boss. Die Schlüsselmethode istcooldowns:check_local(key, ticks), die eine Abklingzeit atomar prüft UND setzt. Siehe die Seite Hooks & Lebenszyklus für die vollständige Cooldown-API. -
context.scheduler— Verzögerte und wiederholte Aufgaben mitscheduler:run_after(ticks, callback)undscheduler:run_every(ticks, callback). Callbacks erhalten einen frischen Context — verwenden Sie immer den Callback-Parameter, nicht den äußerencontext. Brechen Sie wiederholte Aufgaben inon_exit_combatab. Siehe Hooks & Lebenszyklus für Details. -
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. .
In Lua ist object:method(arg) eine Kurzschreibweise für object.method(object, arg). Die EliteMobs-API akzeptiert beide Formen, daher funktioniert beides:
context.cooldowns:set_local(60, "test")
context.cooldowns.set_local(60, "test") -- dasselbe
In der gesamten Dokumentation wird konsistent : verwendet.
Nächste Schritte
Nachdem Sie nun die Grundlagen kennen, erkunden Sie den Rest der Lua-Scripting-Dokumentation:
- Hooks & Lebenszyklus -- Hook-Namen, Ausführungsreihenfolge und welche Context-Schlüssel in jedem Hook verfügbar sind
- Boss & Entitäten --
context.boss,context.player,context.players,context.entitiesundcontext.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:
