Zum Hauptinhalt springen

Lua-Scripting: Fehlerbehebung

webapp_banner.jpg

Diese Seite behandelt häufige Probleme, die beim Schreiben oder Debuggen von Lua-Fähigkeiten auftreten können, sowie Migrationshinweise für Autoren, die von EliteScript kommen. Für funktionierende Beispiele siehe Beispiele & Muster. Für den Einstieg siehe Erste Schritte.


Häufige Probleme

1. Fähigkeit lädt überhaupt nicht

Überprüfen Sie die Serverkonsole auf Fehler beim Serverstart. Die häufigste Ursache ist ein Lua-Syntaxfehler (fehlendes end, nicht übereinstimmende Klammern, etc.). Stellen Sie außerdem sicher, dass die Datei auf .lua endet und im richtigen powers-Verzeichnis liegt.

2. Hook wird nie ausgelöst

Überprüfen Sie, ob der Hook-Name exakt wie in der Hook-Liste geschrieben ist. Häufige Fehler: on_boss_hit (falsch) vs. on_boss_damaged_by_player (richtig), oder on_tick (falsch) vs. on_game_tick (richtig).

3. context.player ist nil

Nicht alle Hooks stellen einen Spieler bereit. on_spawn, on_game_tick, on_enter_combat und on_exit_combat haben keinen Spieler. In on_boss_damaged (generischer Schaden) ist der Angreifer möglicherweise kein Spieler. Fügen Sie immer einen Nil-Schutz hinzu, bevor Sie context.player verwenden.

4. Timeout / Ausführungsbudget überschritten

Wenn ein Hook oder Callback zu lange dauert, wird die Fähigkeit automatisch deaktiviert, um Lag zu vermeiden. Die Konsolenmeldung sieht so aus:

[Lua]   -> Your script took 73ms in 'on_tick' (limit: 50ms) — power disabled to prevent lag.

Häufige Ursachen: zu viele Entitäten iterieren, zu viele Zonen pro Tick erstellen oder aufwendige String-Operationen in on_game_tick. Verschieben Sie aufwendige Arbeit hinter einen Cooldown-Gate oder reduzieren Sie die Arbeit pro Aufruf.

5. Scheduler-Callback verwendet veraltete Daten

Sie verwenden wahrscheinlich den äußeren context anstelle des Callback-Parameters. Ändern Sie function() ... context.boss ... end zu function(tick_context) ... tick_context.boss ... end.

6. Zonenabfrage gibt keine Entitäten zurück

Überprüfen Sie die Zonendefinition. Für native Zonen stellen Sie sicher, dass kind kleingeschrieben ist ("sphere", nicht "SPHERE"). Für Script-Utilities stellen Sie sicher, dass shape großgeschrieben ist ("CONE", nicht "cone"). Überprüfen Sie auch, dass origin oder Target tatsächlich zu einer gültigen Position aufgelöst wird.

7. Partikel erscheinen nicht

Überprüfen Sie, ob der Partikelname ein gültiger Bukkit Particle-Enum-Wert in UPPER_CASE ist. Häufiger Fehler: "flame" (falsch) vs. "FLAME" (richtig). Prüfen Sie auch, ob amount mindestens 1 ist und die Position in einem geladenen Chunk liegt.

8. Cooldown scheint nicht zu funktionieren

Stellen Sie sicher, dass Sie check_local(key, duration) verwenden (das in einem Aufruf prüft UND setzt), nicht local_ready(key) gefolgt von einem separaten set_local(duration, key). Wenn Sie local_ready allein verwenden, prüfen Sie nur, setzen den Cooldown aber nie.

9. Boss führt Fähigkeit nach dem Tod weiter aus

Fügen Sie Aufräumlogik in on_exit_combat und/oder on_death hinzu, um Scheduler-Aufgaben abzubrechen. Wenn der Boss stirbt, sollte on_exit_combat ausgelöst werden, aber explizites Aufräumen in beiden Hooks ist sicherer.


Fehlermeldungen lesen

Wenn in einer Lua-Fähigkeit etwas schiefgeht, gibt die Konsole einen freundlichen Fehlerblock mit dem Präfix [Lua] aus. Diese Meldungen sagen Ihnen genau, welche Datei, welche Zeile, welcher Hook und was schiefgegangen ist -- in einfacher Sprache. Lesen Sie immer die vollständige Meldung vor dem Debuggen.

Ein typischer Fehler sieht so aus:

[Lua] Error in 'push_zone.lua' at line 35 during 'on_boss_damaged_by_player':
[Lua] -> You tried to call a method or function that doesn't exist.
[Lua] -> Check the method name for typos, or make sure you're using ':' (colon) for method calls, not '.' (dot).
[Lua] -> Power has been disabled for this boss to prevent further errors.

Das System übersetzt häufige Lua-Fehler in verständliche Sprache. Hier sind die häufigsten:

Roher Lua-FehlerWas die Konsole Ihnen sagt
attempt to call nilSie haben versucht, eine Methode oder Funktion aufzurufen, die nicht existiert. Prüfen Sie den Methodennamen auf Tippfehler, oder stellen Sie sicher, dass Sie : (Doppelpunkt) für Methodenaufrufe verwenden, nicht . (Punkt).
index expected, got nilSie haben versucht, auf ein Feld von etwas zuzugreifen, das nil ist. Prüfen Sie, ob vorheriger Code es initialisiert hat.
attempt to indexSie haben versucht, auf eine Eigenschaft eines nil- oder ungültigen Werts zuzugreifen.
bad argumentZeigt die spezifischen Argument-Abweichungsdetails (erwarteter Typ vs. tatsächlicher Typ).
TimeoutIhr Skript hat Xms in 'hook_name' benötigt (Limit: 50ms) -- Fähigkeit deaktiviert, um Lag zu verhindern.
tipp

Wenn Sie einen [Lua]-Fehler in der Konsole sehen, sagt Ihnen die Fehlermeldung genau, welche Datei, welche Zeile, welcher Hook und was schiefgegangen ist in einfacher Sprache. Lesen Sie die vollständige Meldung, bevor Sie in den Code eintauchen -- sie weist Sie normalerweise direkt auf die Lösung hin.


Nehmen Sie nicht an, dass undokumentierte Aliase existieren

Die Lua-API stellt einen bestimmten Satz von Methodennamen bereit. Wenn Sie Fähigkeiten von Hand oder mit KI-Unterstützung schreiben, nehmen Sie nicht an, dass Kurzformen oder alternative Namen existieren. Folgende Namen existieren nicht und verursachen Fehler:

  • show_temporary_boss_bar() -- verwenden Sie stattdessen player:show_boss_bar(title, color, style, duration).
  • run_command_as_player() -- verwenden Sie stattdessen player:run_command(command).
  • em.location(...) -- es gibt kein em-Global. Verwenden Sie context.boss:get_location(), context.player.current_location oder context.world-Methoden.
  • em.vector(...) -- es gibt kein em-Global. Verwenden Sie context.vectors.get_vector_between_locations(loc1, loc2) oder einfache {x=0, y=1, z=0} Tabellen.
  • em.zone.sphere(...) -- es gibt kein em-Global. Verwenden Sie eine Zonendefinitions-Tabelle wie {kind = "sphere", radius = 5, origin = location}.
  • entity:teleport_to(...) -- verwenden Sie entity:teleport_to_location(location).
  • entity:set_velocity(...) -- verwenden Sie entity:set_velocity_vector(vector).
  • entity:set_facing(...) -- verwenden Sie entity:face_direction_or_location(direction_or_location).

Im Zweifelsfall prüfen Sie die API-Referenzseiten (Boss & Entitäten, Welt & Umgebung, Zonen & Zielerfassung). Wenn es dort nicht dokumentiert ist, existiert es nicht.


Migrationshinweise für EliteScript-Autoren

Wenn Sie bereits gute EliteScripts schreiben, ist der einfachste Weg, Lua-Fähigkeiten zu lernen:

  1. Denken Sie weiterhin in Begriffen von Ereignissen, Zielen, Zonen, relativen Vektoren und Partikeln. Die Konzepte sind dieselben -- nur die Syntax ändert sich. EliteScript-Ereignisse werden zu Hook-Namen wie on_spawn oder on_boss_damaged_by_player. Ziele und Zonen werden als Tabellen an context.script übergeben, wobei die gleichen Feldnamen verwendet werden, die auf den Seiten EliteScript-Zonen und EliteScript-Ziele dokumentiert sind.

  2. Verlagern Sie Ihren Kontrollfluss nach Lua. Zufallswürfe, gemeinsame Hilfsfunktionen, Schleifen, persistenter Zustand (context.state) und Aufgabenplanung (context.scheduler) sind die Dinge, die Lua hinzufügt und die reines EliteScript nicht einfach kann.

  3. Verwenden Sie context.script für Zielerfassung und Zonengeometrie. Die Script-Utilities akzeptieren die gleichen Feldnamen wie EliteScript (targetType, shape, Target, Target2, range, offset, coverage), sodass Sie die vorhandene EliteScript-Dokumentation als Referenz verwenden können.


Lernpfad für Anfänger

Wenn Sie dieses System von Grund auf lernen möchten, funktioniert dieser Lernpfad gut:

  1. Schreiben Sie eine Datei mit nur api_version = 1 und on_spawn.
  2. Lassen Sie den Boss eine Nachricht senden oder einen Sound abspielen.
  3. Fügen Sie einen Cooldown mit context.cooldowns hinzu.
  4. Fügen Sie einen spielerausgelösten Hook wie on_boss_damaged_by_player hinzu.
  5. Fügen Sie eine verzögerte Aktion mit context.scheduler:run_after(...) hinzu.
  6. Fügen Sie eine einfache native Lua-Zonenabfrage oder ein einfaches context.script:target(...) hinzu.
  7. Erst dann gehen Sie zu rotierenden Angriffen, Zustandsmaschinen und Mehrstufen-Mechaniken über.

Jeder Schritt baut auf dem vorherigen auf, und Sie können in jeder Phase testen. Versuchen Sie nicht, einen Mehrstufen-Boss als erste Lua-Fähigkeit zu schreiben.


Nächste Schritte

  • Erste Schritte -- Dateistruktur, Hooks, erste Power-Erklärung, Copy-Paste-Vorlagen
  • Beispiele & Muster -- vollständige funktionierende Fähigkeiten zum Studieren und Anpassen