Zum Hauptinhalt springen

Lua Scripting: Erste Schritte

Diese Seite zeigt Ihnen, wie Sie Ihr erstes Lua Script für ein FreeMinecraftModels Prop schreiben -- von einer leeren Datei bis hin zu einem funktionierenden interaktiven Prop. Am Ende werden Sie Hooks, Context, die Prop API und den allgemeinen Aufbau jeder Prop Script-Datei verstehen.

Sobald Sie mit den Grundlagen vertraut sind, fahren Sie mit den Begleitseiten fort:

  • Prop API -- die context.prop, context.event, context.world und andere Context APIs
  • Beispiele & Muster -- vollständige, funktionierende Scripts zum Studieren und Anpassen
  • Fehlerbehebung -- häufige Fehler, Debugging-Tipps und die QC-Checkliste
Experimentelle Funktion

Lua Prop Scripts sind derzeit experimentell. Hook-Namen, Hilfsmethoden und Verhalten können sich noch ändern, während FreeMinecraftModels weiterentwickelt wird. Testen Sie daher sorgfältig, bevor Sie sie auf einem Produktiv-Server einsetzen.

Beziehung zu EliteMobs Lua

FreeMinecraftModels verwendet dieselbe Lua-Engine (Magmacore) wie EliteMobs. Wenn Sie bereits Lua-Powers für EliteMobs schreiben, sind die Kernkonzepte -- Hooks, context, api_version, Scheduler, Zonen und die Sandbox -- identisch. Der Unterschied ist:

  • EliteMobs Scripts laufen auf Bossen und haben Hooks wie on_boss_damaged_by_player, on_enter_combat usw.
  • FMM Scripts laufen auf Props und haben Hooks wie on_right_click, on_left_click, on_projectile_hit usw.

Die context.world, context.zones, context.scheduler, context.state und context.log APIs sind bei beiden Plugins identisch. Diese Seite behandelt nur das, was spezifisch für FMM Props ist.


Was Prop Scripts sind

Prop Scripts sind eigenständige .lua-Dateien, die im Ordner plugins/FreeMinecraftModels/scripts/ liegen. Sie werden aus einer YAML-Config-Datei referenziert, die neben der Modelldatei liegt, und sie werden ausgeführt, sobald das Prop in der Welt gespawnt wird.

Wofür Prop Scripts gut geeignet sind

Prop Scripts eignen sich besonders, wenn Sie Folgendes benötigen:

  • Interaktive Props, die auf Spielerklicks reagieren (Türen, Hebel, Knöpfe)
  • Unverwundbare dekorative Props, die von Spielern nicht zerstört werden können
  • Näherungsauslöser, die erkennen, wenn Spieler einen Bereich betreten oder verlassen
  • Animierte Props, die Animationen bei Interaktion oder nach einem Timer abspielen
  • Klangemittierende Props, die Sounds abspielen, wenn sie angeklickt oder angenähert werden
  • Jegliches Prop-Verhalten, das Logik über statische Dekoration hinaus erfordert

Wenn Ihr Prop rein dekorativ ist und keine Interaktion benötigt, brauchen Sie kein Script.


Für wen diese Seite gedacht ist

Diese Seite richtet sich an drei Arten von Lesern:

  • Jemand, der bereits EliteMobs Lua Scripting kennt und die FMM-spezifischen Hooks und APIs lernen möchte
  • Jemand, der neu im Lua Scripting ist und eine vollständige Referenz mit exakten Namen für Props benötigt
  • Jemand, der KI zum Entwurf von Prop Scripts nutzt und genug Details braucht, um zu erkennen, wenn die KI etwas Falsches erfunden hat

Sie müssen kein vollwertiger Lua-Entwickler werden, bevor Sie nützliche Prop Scripts schreiben. Für die meisten praktischen Prop Scripts benötigen Sie nur:

  • Wie man einen gültigen Hook in der zurückgegebenen Tabelle platziert
  • Wie man Werte aus context ausliest
  • Wie man frühzeitig mit if ... then return end abbrechen kann
  • Wie man einige Hilfsmethoden exakt aufruft

Kleiner Lua-Überblick

Wenn Sie komplett neu bei Lua sind, hier die minimale Syntax, die Sie benötigen.

Variablen

Verwenden Sie local, um einen Wert zu speichern:

local animation_name = "open"
local sound_volume = 1.0

Funktionen

Funktionen sind wiederverwendbare Logikblöcke:

local function log_click(context)
context.log:info("Prop was clicked!")
end

if-Prüfungen

Verwenden Sie if, wenn etwas nur manchmal passieren soll:

if context.event == nil then
return
end

nil

nil bedeutet "kein Wert". Sie werden häufig darauf prüfen:

if context.event ~= nil then
context.event.cancel()
end

Tabellen

Lua verwendet Tabellen für Objekte mit benannten Schlüsseln und für die zurückgegebene Script-Definition:

return {
api_version = 1,

on_spawn = function(context)
end
}

Kommentare

Verwenden Sie -- für Anmerkungen:

-- Cancel the damage event so the prop cannot be broken
context.event.cancel()
tipp

Für einen ausführlicheren Lua-Überblick siehe die Seite EliteMobs Erste Schritte. Die Syntax-Grundlagen sind identisch.


Wo die Dateien liegen

Script-Dateien

Legen Sie .lua-Dateien im zentralen Scripts-Ordner ab:

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

FMM erkennt alle .lua-Dateien in plugins/FreeMinecraftModels/scripts/ beim Start.

Modelldateien und Config-Dateien

Jede Modelldatei kann eine zugehörige .yml-Config-Datei im selben Verzeichnis haben:

plugins/
FreeMinecraftModels/
models/
torch_01.fmmodel
torch_01.yml <-- Script-Config für torch_01
scripts/
invulnerable.lua <-- referenziert von torch_01.yml

Die .yml-Config verbindet ein Modell mit seinen Scripts.


Config-Dateiformat

Die YAML-Config-Datei, die neben einer Modelldatei liegt, hat zwei Felder:

isEnabled: true
scripts:
- invulnerable.lua
FeldTypStandardHinweise
isEnabledbooleantrueOb Scripts für dieses Prop aktiv sind
scriptsListe von Strings[]Dateinamen von .lua-Scripts im scripts/-Ordner

Sie können mehrere Scripts an dasselbe Prop anhängen. Jedes Script ist eine eigene unabhängige Instanz.

Verzögerte Config-Generierung

Wenn ein Prop gespawnt wird und keine zugehörige .yml-Datei existiert, erstellt FMM automatisch eine Standard-Config-Datei mit isEnabled: true und einer leeren scripts:-Liste. Dies geschieht asynchron, sodass das Prop beim ersten Spawn keine Scripts hat -- erst nachdem die Config erstellt wurde und Sie sie bearbeiten, um Script-Dateinamen hinzuzufügen.

Das bedeutet:

  1. Platzieren Sie Ihre Modelldatei in models/
  2. Spawnen Sie das Prop einmal (FMM erstellt die .yml automatisch)
  3. Bearbeiten Sie die generierte .yml, um Ihre Script-Dateinamen hinzuzufügen
  4. Spawnen Sie das Prop erneut oder laden Sie den Server neu (Scripts sind nun aktiv)

Hook-Referenz

Jede Lua Prop Script-Datei 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 Laufzeitumgebung ruft die entsprechende Funktion auf, wann immer das zugehörige Spielereignis ausgelöst wird.

HookWird ausgelöst, wennHinweise
on_spawnDas Prop in der Welt gespawnt wirdWird einmal ausgeführt, wenn das Script gebunden wird
on_game_tickEinmal pro Server-Tick (50 ms)Nur aktiv, wenn das Script diesen Hook definiert
on_destroyDas Prop aus der Welt entfernt wirdAufräum-Hook
on_left_clickEin Spieler das Prop links klickt (schlägt)context.event ist das Schadensereignis
on_right_clickEin Spieler das Prop rechts klicktcontext.event ist das Interaktionsereignis
on_projectile_hitEin Projektil das Prop trifftcontext.event ist das Projektiltreffer-Ereignis
on_zone_enterEin Spieler eine überwachte Zone betrittErfordert, dass eine Zonenüberwachung eingerichtet ist
on_zone_leaveEin Spieler eine überwachte Zone verlässtErfordert, dass eine Zonenüberwachung eingerichtet ist

Minimaler Dateivertrag

Jedes Lua Prop Script muss eine Tabelle return-en.

Erforderliche und optionale Top-Level-Felder

FeldErforderlichTypHinweise
api_versionJaNumberMuss derzeit 1 sein
priorityNeinNumberAusführungspriorität. Niedrigere Werte werden zuerst ausgeführt. Standard ist 0
Unterstützte Hook-SchlüsselNeinFunctionMuss 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, 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.

Hilfsfunktionen und lokale Konstanten sollten über dem abschließenden return stehen, nicht innerhalb der zurückgegebenen Tabelle.


Ihr erstes funktionierendes Prop Script, Schritt für Schritt

Vor Schritt 1: Config einrichten

  1. Platzieren Sie Ihre Modelldatei (z. B. my_prop.fmmodel) in plugins/FreeMinecraftModels/models/
  2. Spawnen Sie das Prop einmal, um die .yml-Config zu generieren
  3. Erstellen Sie Ihre Script-Datei in plugins/FreeMinecraftModels/scripts/first_test.lua
  4. Bearbeiten Sie plugins/FreeMinecraftModels/models/my_prop.yml:
isEnabled: true
scripts:
- first_test.lua
  1. Spawnen Sie das Prop erneut oder laden Sie den Server neu

Schritt 1: Die Datei laden lassen

return {
api_version = 1,

on_spawn = function(context)
end
}

Wenn dies ohne Fehler in der Konsole geladen wird, haben Sie bewiesen:

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

Schritt 2: Das Prop eine sichtbare Aktion ausführen lassen

return {
api_version = 1,

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

Prüfen Sie die Serverkonsole. Wenn Sie die Log-Nachricht sehen, wird Ihr Hook ausgelöst.

Schritt 3: Auf einen Spielerklick reagieren

return {
api_version = 1,

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

Rechtsklicken Sie das Prop im Spiel. Wenn die Konsole die Nachricht anzeigt, funktioniert der Click-Hook.

Schritt 4: Schaden abbrechen, um das Prop unverwundbar zu machen

return {
api_version = 1,

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

Dies ist das Muster, das vom mitgelieferten invulnerable.lua-Script verwendet wird. Es bricht das Schadensereignis ab, sodass der zugrunde liegende Armor Stand des Props nicht zerstört werden kann.

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 spielt die "open"-Animation am Prop-Modell ab, überblendet und nicht als Schleife.


Was ist context?

Jede Hook-Funktion erhält ein Argument namens context. Betrachten Sie es als Werkzeugkasten, den FMM Ihnen jedes Mal übergibt, wenn etwas passiert -- er enthält alles, was Sie brauchen, um mit dem Prop, der Welt, Zonen und mehr zu interagieren.

on_right_click = function(context)
-- context.prop = das Prop, das angeklickt wurde
-- context.event = das Klick-Ereignis (kann abgebrochen werden)
-- context.world = Werkzeuge für Partikel, Sounds, Block-Abfragen
-- context.state = Ihr eigener persistenter Speicher
-- context.log = Konsolenprotokollierung
-- context.scheduler = verzögerte und wiederkehrende Aufgaben
-- context.zones = räumliche Zonenerstellung und -überwachung
end

Sie erstellen context nicht selbst -- FMM erstellt es und übergibt es an Ihren Hook.

info

context wird für jeden Hook-Aufruf neu erstellt, außer context.state, das für die gesamte Lebensdauer des Props bestehen bleibt. Das bedeutet, Sie können Daten in context.state speichern und sie später in einem anderen Hook wieder auslesen.


Wichtige context APIs

Hier ist eine Zusammenfassung der verfügbaren Funktionen. Für vollständige Details siehe Prop API.

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

  • context.event -- Das Bukkit-Ereignis, das diesen Hook ausgelöst hat. Verfügbar in on_left_click, on_right_click und on_projectile_hit. Bietet cancel(), uncancel() und is_cancelled. Ist nil in Hooks ohne Ereignis (wie on_spawn und on_game_tick).

  • context.state -- Eine einfache Lua-Tabelle, die für die Lebensdauer des Props bestehen bleibt. Verwenden Sie sie zum Speichern von Flags, Umschaltzuständen, Task-IDs und allem, was Sie sich zwischen Hooks merken müssen.

  • context.log -- Konsolenprotokollierung mit log:info(msg), log:warn(msg) und log:error(msg).

  • context.scheduler -- Verzögerte und wiederkehrende Aufgaben mit scheduler:run_later(ticks, callback) und scheduler:run_repeating(delay, interval, callback). Callbacks erhalten einen frischen Context. Aufgaben abbrechen mit scheduler:cancel(taskId).

  • context.world -- Weltinteraktion: Partikel, Sounds, Block-Abfragen, Blitze, nahegelegene Entitäten. Siehe Prop API für die vollständige Methodenliste.

  • context.zones -- Erstellung und Überwachung räumlicher Zonen (Kugeln, Zylinder, Quader). Siehe Prop API für die vollständige Methodenliste.


Methodensyntax: : vs .

In Lua ist object:method(arg) eine Kurzform für object.method(object, arg). Die FMM API akzeptiert beide Formen:

context.log:info("hello")
context.log.info("hello") -- dasselbe

Die gesamte Dokumentation verwendet durchgehend :.


Kopiervorlagen zum Schnelleinstieg

Kleinstes gültiges Prop Script

return {
api_version = 1,

on_spawn = function(context)
end
}

Unverwundbares Prop Vorlage

return {
api_version = 1,

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

Interaktives Prop Vorlage

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
}

Größeres Dateilayout

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 realer Arbeitsablauf

Verwenden Sie beim Erstellen eines brandneuen Prop Scripts diese Reihenfolge:

  1. Erstellen Sie die .lua-Datei und bringen Sie on_spawn zum Laufen.
  2. Fügen Sie den Script-Dateinamen zur .yml-Config des Props hinzu.
  3. Wechseln Sie zum gewünschten Hook (z. B. on_right_click).
  4. Fügen Sie zuerst eine Log-Nachricht hinzu, bevor Sie Animationen oder Effekte einsetzen.
  5. Fügen Sie einen echten Effekt hinzu (Animation, Sound, Partikel).
  6. Erst danach fügen Sie Hilfsfunktionen, State, Scheduler-Logik oder Zonen hinzu.

Diese Reihenfolge erleichtert das Debugging erheblich, da sich jeweils nur eine Sache ändert.


Mitgelieferte Scripts

FMM wird mit einem vorbereiteten Lua Script ausgeliefert:

  • invulnerable.lua -- Bricht Linksklick-Schadensereignisse ab und macht das Prop unzerstörbar. Dies ist das einfachste nützliche Prop Script.

Weitere Beispiele finden Sie auf der Seite Beispiele & Muster.


Lua Sandbox

Prop Scripts laufen in derselben sandboxed LuaJ-Umgebung wie EliteMobs. Die Sandbox-Einschränkungen sind identisch. Für die vollständige Liste entfernter Globals und verfügbarer Standardbibliotheksfunktionen siehe die Seite EliteMobs Hooks & Lifecycle.

Zusammenfassung:

  • Entfernt: debug, dofile, io, load, loadfile, luajava, module, os, package, require
  • Verfügbar: Alle math.*, string.*, table.*-Funktionen, pairs, ipairs, type, tostring, tonumber, pcall, print und mehr
tipp

print schreibt in die Serverkonsole, aber bevorzugen Sie context.log:info(msg) für die Ausgabe. Log-Nachrichten sind mit dem Script-Dateinamen prefixed, was es einfacher macht, nachzuvollziehen, welches Script die Nachricht erzeugt hat.


Nächste Schritte

  • Prop API -- vollständige Referenz für context.prop, context.event, context.world, context.zones und context.scheduler
  • Beispiele & Muster -- vollständige funktionierende Scripts mit Erklärungen
  • Fehlerbehebung -- häufige Probleme, Debugging-Tipps und eine QC-Checkliste

Wenn Sie auch EliteMobs Lua-Powers schreiben, funktionieren die gemeinsamen APIs (context.world, context.zones, context.scheduler, context.state, context.log) identisch. Siehe die EliteMobs Lua-Dokumentation für die boss-spezifischen APIs.