Zum Hauptinhalt springen

Lua-Skripting: Erste Schritte

Diese Seite zeigt dir, wie du dein erstes Lua-Skript für einen FreeMinecraftModels-Prop schreibst, von einer leeren Datei bis zu einem funktionierenden interaktiven Skript. Am Ende verstehst du Hooks, Context, die Prop-API und die allgemeine Struktur jeder Skriptdatei.

Sobald du dich mit den Grundlagen wohlfühlst, fahre mit den Begleitseiten fort:

  • Prop-API -- context.prop, context.event, context.world und weitere Context-APIs
  • Beispiele & Muster: Prop-Skripte mit Einrichtungshinweisen zum Lernen und Anpassen
  • Fehlerbehebung -- häufige Fehler, Debugging-Tipps und die QC-Checkliste
Experimentelle Funktion

Lua-Prop-Skripte sind derzeit experimentell. Hook-Namen, Hilfsmethoden und Verhalten können sich noch ändern, während sich FreeMinecraftModels weiterentwickelt. Teste daher sorgfältig, bevor du sie auf einem Produktionsserver einsetzt.

Beziehung zu EliteMobs Lua

FreeMinecraftModels verwendet die MagmaCore-Lua-Laufzeit. Wenn du bereits Lua-Powers für EliteMobs schreibst, werden dir die Kernkonzepte -- Skriptdateien, die eine Tabelle zurückgeben, api_version, Hooks, context, State, Cooldowns, Scheduling und die Sandbox -- vertraut vorkommen. Die genauen Hooks und Context-Methodennamen hängen weiterhin vom Plugin ab:

  • EliteMobs-Skripte laufen auf Bossen und haben Hooks wie on_boss_damaged_by_player, on_enter_combat usw.
  • FMM-Prop-Skripte laufen auf Props und haben Hooks wie on_right_click, on_left_click, on_zone_enter usw.
  • Item-Verzauberungen verwenden den separaten Context für selbst definierte Verzauberungen.

Die hier dokumentierten APIs context.world, context.zones, context.scheduler, context.state und context.log sind die FreeMinecraftModels-/MagmaCore-Varianten. EliteMobs-NPC-Skripte verwenden dieselben generischen MagmaCore-Tabellen plus context.npc; EliteMobs-Boss-Powers verwenden für mehrere Tabellen boss-spezifische Varianten. Diese Seite behandelt die Besonderheiten von FMM-Props.


Was Prop-Skripte sind​

Prop-Skripte sind eigenständige .lua-Dateien, die im Ordner plugins/FreeMinecraftModels/scripts/ liegen. Sie werden von einer YAML-Konfigurationsdatei referenziert, die neben der Modelldatei liegt, und sie laufen, sobald der Prop in die Welt gespawnt wird.

Wofür Prop-Skripte geeignet sind​

Prop-Skripte eignen sich hervorragend, wenn du Folgendes benötigst:

  • Interaktive Props, die auf Spielerklicks reagieren (Türen, Hebel, Knöpfe)
  • Dekorative Props, die normalen Linksklickschaden ignorieren
  • Näherungsauslöser, die erkennen, wenn Spieler einen Bereich betreten oder verlassen
  • Animierte Props, die Animationen bei Interaktion oder nach einem Timer abspielen
  • Sound-emittierende Props, die Sounds abspielen, wenn sie angeklickt oder angenähert werden
  • Jedes Prop-Verhalten, das Logik jenseits statischer Dekoration erfordert

Wenn dein Prop rein dekorativ ist und keine Interaktion benötigt, brauchst du kein Skript.


Benutzerdefinierte Items und Verzauberungen​

Benutzerdefinierte Items verwenden weiterhin eine YAML-Datei neben dem Modell mit einem material. Ihre Effekte verwenden jetzt jedoch Verzauberungen mit Namespace. Die alte Skript-Laufzeit für ausgerüstete Items wurde eingestellt. Ein benutzerdefiniertes Item mit einer nicht leeren scripts:-Liste wird mit einer Informationsmeldung in der Konsole übersprungen; seine Definition bleibt unverändert.

Erkannte eingestellte Lua-Skripte für ausgerüstete Items aus scripts/ werden vor der Erkennung und nach Importen unter plugins/MagmaCore/outdated files/FreeMinecraftModels/<archive batch>/scripts/ aufbewahrt. Die Archivierungsregel verlangt eine gültige alte Skriptdefinition mit einem eingestellten Item-Hook wie on_equip oder on_attack_entity. Prop-Skripte, Dateien mit ausschließlich gemeinsamen Hooks, fehlerhafte Skripte und aktuelle Effekte in enchantments/ werden dadurch nicht als eingestellte Item-Skripte eingestuft. Hinweise zur Wiederherstellung stehen unter Ausgemusterte Konfigurationsdateien.

Aktuelle Item-Definitionen findest du unter Benutzerdefinierte Items und magische Waffen, Effekte unter Selbst definierte Verzauberungen. Die scripts:-Listen von Props funktionieren weiterhin.

Für wen diese Seite ist​

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

  • Jemand, der bereits EliteMobs-Lua-Skripting kennt und die FMM-spezifischen Hooks und APIs lernen möchte
  • Jemand, der neu im Lua-Skripting ist und eine vollständige, exakte Namensreferenz für Props benötigt
  • Jemand, der KI zum Erstellen von Prop-Skripten verwendet und genügend Details braucht, um zu erkennen, wenn die KI etwas Falsches erfunden hat

Du musst kein vollständiger Lua-Entwickler werden, bevor du nützliche Prop-Skripte schreiben kannst. Für die meisten praktischen Prop-Skripte brauchst du nur:

  • Wie man einen gültigen Hook in der zurückgegebenen Tabelle platziert
  • Wie man Werte aus context liest
  • Wie man frühzeitig mit if ... then return end abbricht
  • Wie man ein paar Hilfsmethoden exakt aufruft

Kleiner Lua-Einstieg​

Du musst kein Lua-Experte sein, um FMM-Skripte zu schreiben. Die meisten Skripte verwenden nur eine Handvoll Konzepte: Variablen (local x = 5), Funktionen (function foo() end), if-Abfragen (if x then ... end), Tabellen ({key = value}) und nil (Luas Wert für „nichts"). Die Syntax ist schlank — keine Semikolons, keine geschweiften Klammern, nur end, um Blöcke zu schließen.

Für eine vollständige Einführung mit Beispielen siehe die MagmaCore Lua-Skript-Engine — Kleiner Lua-Einstieg. Dieser Einstieg wird von allen Nightbreak-Plugins geteilt, du lernst ihn also einmal und kannst ihn überall anwenden.


Wo die Dateien liegen​

Skriptdateien​

Platziere .lua-Dateien im zentralen Skript-Ordner:

plugins/
FreeMinecraftModels/
scripts/
invulnerable.lua
interactive_door.lua
proximity_sound.lua

FMM findet .lua-Dateien rekursiv in plugins/FreeMinecraftModels/scripts/, wenn der Skript-Provider initialisiert wird, und speichert ihren Quellcode zwischen. Verwende auch über Unterordner hinweg eindeutige Dateinamen, denn Bindungen verwenden den Namen ohne relativen Pfad. Nach dem Hinzufügen oder Ändern von Lua-Dateien muss /fmm reload erfolgreich abgeschlossen sein, bevor neue Bindungen den Code verwenden. Erneutes Spawnen allein liest den Lua-Code nicht neu.

Gib in der scripts:-Liste eines Modells die Endung .lua der Klarheit halber an. FMM akzeptiert auch Einträge ohne Endung und hängt intern .lua an. Die Datei auf der Festplatte muss trotzdem auf .lua enden, und Namen bleiben groß-/kleinschreibungsabhängig.

Modelldateien und Konfigurationsdateien​

Jede Modelldatei kann eine begleitende .yml-Konfigurationsdatei im selben Verzeichnis haben:

plugins/
FreeMinecraftModels/
models/
torch_01.fmmodel
torch_01.yml <-- script config for torch_01
scripts/
invulnerable.lua <-- referenced by torch_01.yml

Die .yml-Konfiguration ist das, was ein Modell mit seinen Skripten verbindet.


Konfigurationsdatei-Format​

Die YAML-Konfigurationsdatei, die neben einer Modelldatei liegt, hat folgende Felder:

isEnabled: true
voxelize: false
solidify: false
scripts:
- invulnerable.lua

Die Prop-Felder sind:

FeldTypStandardHinweise
isEnabledbooleantrueOb die Definition aktiviert ist
scriptsListe von Strings[]Lua-Dateinamen für Props aus scripts/
voxelizebooleanfalsePlatzierung an 90-Grad-Drehung und Blockraster-Ausrichtung einrasten
solidifybooleanfalsePaket-basierte Barrier-Blöcke im Grundriss des Props platzieren (erfordert voxelize)

Jedes aufgelistete Prop-Skript erhält eine eigene Instanz. Definiere für gehaltene Items stattdessen material, name, lore und enchantments mit Namespace. Siehe Benutzerdefinierte Items.

Verzögerte Konfigurationserzeugung​

Wenn ein Prop gespawnt wird und keine begleitende .yml-Datei existiert, erstellt FMM automatisch eine Standardkonfigurationsdatei mit isEnabled: true und einer leeren scripts:-Liste. Dies geschieht asynchron, sodass der Prop bei seinem ersten Spawn keine Skripte haben wird -- erst nachdem die Konfiguration erstellt wurde und du sie bearbeitest, um Skriptdateinamen hinzuzufügen.

Das bedeutet:

  1. Platziere deine Modelldatei in models/
  2. Spawne den Prop einmal (FMM erstellt die .yml automatisch)
  3. Bearbeite die generierte .yml, um deine Skriptdateinamen hinzuzufügen
  4. Führe nach jeder YAML- oder Lua-Änderung /fmm reload erfolgreich aus. Platziere dann einen neuen Prop und prüfe dessen Log oder Interaktion. Prop-Einstellungen, Platzierungsprüfungen und Skriptlisten im Menü verwenden denselben vorbereiteten Katalog. Erneutes Spawnen allein liest das YAML nicht neu ein.

Hook-Referenz​

Jede Lua-Prop-Skriptdatei gibt eine Tabelle zurück. Jeder Schlüssel in dieser Tabelle (außer api_version und priority) muss einer der unten aufgeführten Hooks sein. Die Laufzeit ruft die passende Funktion auf, wenn das entsprechende Spielereignis ausgelöst wird.

HookWird ausgelöst wennHinweise
on_spawnDer Prop in die Welt gespawnt oder mit seinem Chunk erneut geladen wirdLäuft jedes Mal einmal, wenn das Skript gebunden wird
on_game_tickEinmal pro Server-Tick (50 ms bei 20 TPS)Nur aktiv, wenn das Skript diesen Hook definiert
on_destroyDer Prop endgültig entfernt wirdAufräum-Hook. Wird nicht aufgerufen, wenn der Chunk des Props entladen wird oder FMM neu lädt
on_left_clickEin Spieler den Prop links anklickt (schlägt)context.event enthält FMMs Flag zum Abbrechen des Standardschadens
on_right_clickEin Spieler den Prop rechts anklicktcontext.event enthält FMMs Flag zum Abbrechen der Standardinteraktion
on_zone_enterEin Spieler eine überwachte Zone betrittErfordert eine eingerichtete Zonenüberwachung
on_zone_leaveEin Spieler eine überwachte Zone verlässtErfordert eine eingerichtete Zonenüberwachung
on_projectile_hitEin Projektil den Prop trifftcontext.projectile ist das Projektil; context.event.player ist der Schütze. Siehe Prop-API

Item-Effekte​

Die früheren Hooks für ausgerüstete Items werden nicht mehr ausgelöst. Effekte gehören zu selbst definierten Verzauberungen mit eigenen unterstützten Hooks und eigenem Context. Füge Verzauberungs-Lua nicht der scripts:-Liste eines Props hinzu und kopiere alte Item-Skripte nicht unverändert.

Mindestanforderungen an die Datei​

Jedes Lua-Prop-Skript muss mit return eine Tabelle zurückgeben.

Erforderliche und optionale Top-Level-Felder​

FeldErforderlichTypHinweise
api_versionJaZahlMuss derzeit 1 sein
priorityNeinZahlWird validiert, sofern vorhanden, aber FMM sortiert Prop-Skripte derzeit nicht danach. Props führen Skripte in der Reihenfolge der scripts:-Liste aus
Unterstützte Hook-SchlüsselNeinFunktionMuss einen der exakten Hook-Namen aus der Hook-Referenz verwenden

Validierungsregeln​

  • Die Datei muss eine Tabelle zurückgeben.
  • api_version ist erforderlich und muss derzeit 1 sein.
  • priority muss numerisch sein, wenn 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.
Hinweis

priority ist nützlich, um Skripte über MagmaCore-basierte Laufzeiten hinweg portabel zu halten, aber die aktuelle Ausführungsreihenfolge von FreeMinecraftModels ist konfigurationsgesteuert. Setze Prop-Skripte in der scripts:-Liste des Modells in die Reihenfolge, in der sie laufen sollen.

Hilfsfunktionen und lokale Konstanten sollten oberhalb des abschließenden return leben, nicht innerhalb der zurückgegebenen Tabelle.


Dein erstes funktionierendes Prop-Skript, Schritt für Schritt​

Vor Schritt 1: Konfiguration einrichten​

  1. Platziere deine Modelldatei (z.B. my_prop.fmmodel) in plugins/FreeMinecraftModels/models/
  2. Spawne den Prop einmal, um die .yml-Konfiguration zu generieren
  3. Erstelle deine Skriptdatei in plugins/FreeMinecraftModels/scripts/first_test.lua
  4. Bearbeite plugins/FreeMinecraftModels/models/my_prop.yml:
isEnabled: true
scripts:
- first_test.lua
  1. Speichere den Lua-Inhalt aus Schritt 1 unten, führe /fmm reload aus und prüfe den erfolgreichen Abschluss. Spawne den Prop bei Bedarf erneut. Wiederhole das erfolgreiche Neuladen nach jeder Lua-Änderung der folgenden Schritte.

Schritt 1: Die Datei zum Laden bringen​

return {
api_version = 1,

on_spawn = function(context)
end
}

Dass kein Konsolenfehler erscheint, ist eine nützliche erste Prüfung. Verwende die ausdrückliche Protokollmeldung in Schritt 2, um Folgendes zu bestätigen:

  • Die Datei ist gültiges Lua
  • FMM hat sie im scripts/-Ordner gefunden
  • Die Konfiguration referenziert sie korrekt
  • Die Form der zurückgegebenen Tabelle ist korrekt

Schritt 2: Eine sichtbare Aktion ausführen​

return {
api_version = 1,

on_spawn = function(context)
context.log:info("Prop script loaded for: " .. (context.prop.model_id or "unknown"))
end
}

Überprüfe die Serverkonsole. Wenn du die Log-Nachricht siehst, feuert dein Hook.

Schritt 3: Auf einen Spielerklick reagieren​

return {
api_version = 1,

on_right_click = function(context)
context.log:info("Prop was right-clicked!")
end
}

Rechtsklicke den Prop im Spiel. Wenn die Konsole die Nachricht zeigt, funktioniert der Klick-Hook.

Schritt 4: Linksklickschaden abbrechen​

return {
api_version = 1,

on_left_click = function(context)
if context.event then
context.event.cancel()
end
end
}

Dieses Muster verwendet das mitgelieferte Skript invulnerable.lua. Es bricht FMMs normalen Prop-Schaden für diesen Klick ab. Die zugrunde liegende Entity wird dadurch nicht gegen jede Schadensquelle unverwundbar.

Schritt 5: Eine Animation bei Klick abspielen​

return {
api_version = 1,

on_right_click = function(context)
context.prop:play_animation("open", true, false)
end
}

Dies fordert die nicht wiederholte Animation "open" nach dem aktuellen Zustandstick an. Das Modell muss diese Animation enthalten. blend erzeugt keinen fließenden Übergang; die Warteschlange hat nur einen Platz und eine spätere Anfrage kann die vorherige ersetzen. Der abschließende Todeszustand kann die Anfrage ablehnen. Prüfe das sichtbare Ergebnis im Spiel; die Annahme beweist keine Wiedergabe.


Was ist context?​

Jede Hook-Funktion erhält ein Argument namens context. Stelle es dir wie einen Werkzeugkasten vor, den FMM dir jedes Mal übergibt, wenn etwas passiert -- er enthält alles, was du brauchst, um mit dem Prop, der Welt, Zonen und mehr zu interagieren.

Du erstellst context nicht selbst -- FMM erstellt es und übergibt es an deinen Hook. Für alle Details zu den gemeinsamen Context-APIs (context.state, context.log, context.cooldowns, context.scheduler, context.world, context.zones) siehe die Seite MagmaCore Lua-Skript-Engine.


Wichtige context-APIs​

Hier ist eine Zusammenfassung des Verfügbaren. Für vollständige Details siehe Prop-API.

  • context.prop -- (Nur Prop-Skripte) Die Prop-Entität. Bietet model_id, current_location, play_animation() und stop_animation().

  • context.player -- Der auslösende Spieler in Prop-Klick-Hooks und generischen Zonen-Hooks sowie der Schütze in on_projectile_hit, wenn ein Spieler das Projektil abgefeuert hat. In Prop-Lebenszyklus-Hooks, geplanten Callbacks und Hooks ohne Spielerbezug ist es nil.

  • context.event -- FMMs Abbruchflag und auslösender Spieler bei Klick-Hooks, das Projektiltreffer-Event und sein Schütze in on_projectile_hit beziehungsweise eine reine Akteurstabelle bei generischen Zonen-Hooks. Bietet event.player, is_cancelled und bei Klicks und Projektiltreffern cancel() / uncancel(). Bukkit-spezifische Felder wie target, block, projectile oder item werden nicht bereitgestellt. In Hooks ohne Event oder auslösenden Spieler, etwa on_spawn und on_game_tick, ist es nil.

  • context.projectile -- Die Projektil-Entity in on_projectile_hit und nil in jedem anderen Hook. Siehe on_projectile_hit.

  • context.state -- Eine einfache Lua-Tabelle, die für die Lebensdauer der Skriptinstanz bestehen bleibt. Siehe context.state.

  • context.cooldowns -- Lokale und globale Cooldown-Helfer. Verwende context.cooldowns:check_local("key", ticks) für normale Cooldowns pro Skript. Siehe context.cooldowns.

  • context.log -- Konsolen-Logging. Siehe context.log.

  • context.scheduler -- Verzögerte und wiederholende Aufgaben. Siehe context.scheduler.

  • context.world -- Weltinteraktion: Partikel, Sounds, Block-Abfragen, Blitze, nahegelegene Entitäten. Siehe context.world.

  • context.zones -- Erstelle und überwache räumliche Zonen (Kugeln, Zylinder, Quader). Siehe context.zones.


Methodensyntax: : und .​

Eine Erklärung der Methodensyntax : vs . in Lua findest du auf der Seite MagmaCore Lua-Skript-Engine. Beide Formen werden von der FMM-API akzeptiert.


Vorlagen zum Kopieren​

Kleinstes gültiges Prop-Skript​

return {
api_version = 1,

on_spawn = function(context)
end
}

Vorlage zum Abbrechen von Linksklickschaden​

return {
api_version = 1,

on_left_click = function(context)
if context.event then
context.event.cancel()
end
end
}

Vorlage für einen interaktiven Prop​

return {
api_version = 1,

on_spawn = function(context)
context.state.is_active = false
end,

on_right_click = function(context)
context.state.is_active = not context.state.is_active

if context.state.is_active then
context.prop:play_animation("activate", true, true)
else
context.prop:stop_animation()
end
end
}

Struktur einer größeren Datei​

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)
context.state.task_id = nil
end,

on_right_click = function(context)
do_something(context)
end,

on_destroy = function(context)
if context.state.task_id ~= nil then
context.scheduler:cancel(context.state.task_id)
end
end
}

Erster praktischer Ablauf​

Wenn du ein brandneues Prop-Skript erstellst, verwende diese Reihenfolge:

  1. Erstelle die .lua-Datei und bringe on_spawn zum Laufen.
  2. Füge den Skriptdateinamen zur .yml-Konfiguration des Props hinzu.
  3. Wechsle zum tatsächlichen Hook, den du verwenden möchtest (z.B. on_right_click).
  4. Füge zuerst eine Log-Nachricht hinzu, bevor du Animationen oder Effekte hinzufügst.
  5. Füge einen echten Effekt hinzu (Animation, Sound, Partikel).
  6. Erst danach füge Helfer, State, Scheduler-Logik oder Zonen hinzu.

Speichere nach jeder Lua-Änderung die Datei und schließe /fmm reload erfolgreich ab, bevor du das neue Verhalten prüfst. Ändere pro Schritt nur eine Sache, damit das Log oder der sichtbare Effekt zeigt, was funktioniert hat.


Mitgelieferte Skripte​

FMM schreibt vier vorgefertigte Lua-Skripte, wenn sie fehlen. Erkannte ältere Standardversionen werden ersetzt; andere vorhandene Änderungen bleiben erhalten. Prüfe die installierte Datei, wenn ihr Verhalten von den aktuellen Vorgaben abweicht:

  • invulnerable.lua -- Bricht FMMs normalen Linksklickschaden ab. Es blockiert nicht jede mögliche Schadensquelle.
  • pickupable.lua: Bricht den normalen Linksklick-Schaden ab und zählt drei erlaubte Treffer, bevor die Aufnahme angefordert wird. Der Zähler gehört zur Bindung und wird zwischen Spielern geteilt. Ein Task über 100 Server-Ticks setzt ihn nach einem früheren Treffer zurück. Erlaubte Treffer fordern ein rotes Blinken an. Geschützte Orte und Dungeons werden blockiert, außer der Spieler besitzt FMMs Schutzumgehungsberechtigung oder Operatorstatus.
  • storage_double.lua: Fordert ein Inventar mit 54 Slots sowie Öffnungs- und Schließanimationen und Sounds an. Verwendet dieselbe Schutzprüfung mit Operatorausnahme und prüft registrierte Betrachter alle 5 Server-Ticks. Das Inventar des Props wird von allen Betrachtern geteilt und gespeichert, wenn der letzte Betrachter es schließt oder der Chunk entladen wird. Zerstörung fordert drop_inventory() an, das zuerst das offene Inventar speichert, sodass Items, die in ein noch offenes Inventar gelegt wurden, mit fallengelassen werden. Details findest du unter prop:open_inventory.
  • storage_single.lua -- Wie storage_double, aber mit 3 Reihen (27 Slots) statt 6.

Weitere Beispiele findest du auf der Seite Beispiele & Muster.


Lua-Sandbox​

Prop-Skripte laufen in derselben LuaJ-Sandbox wie EliteMobs. Die Sandbox-Einschränkungen sind identisch. Die vollständige Liste entfernter Globals und verfügbarer Standardbibliotheksfunktionen steht unter MagmaCore Lua-Skript-Engine.


Nächste Schritte​

  • Prop-API -- vollständige Referenz für context.prop, context.event, context.world, context.zones und context.scheduler
  • Beispiele & Muster: Prop-Skripte mit Erläuterungen und Einrichtungshinweisen
  • Fehlerbehebung -- häufige Probleme, Debugging-Tipps und eine QC-Checkliste

Wenn du auch EliteMobs-Boss-Lua-Powers schreibst, sind dir die Sandbox, api_version, die State-Tabelle, die Cooldown-Konzepte und die hook-getriebene Struktur vertraut, aber der Boss-Context verwendet EliteMobs-spezifische Methodennamen. Siehe die EliteMobs-Lua-Dokumentation für die genauen Boss-APIs.