Zum Hauptinhalt springen

Lua-Scripting: Prop-API

Diese Seite behandelt alle APIs, die FreeMinecraftModels-Prop-Skripten zur Verfügung stehen: context.prop, context.event, context.world, context.zones, context.scheduler, context.state und context.log. Wenn Sie neu im Prop-Scripting sind, beginnen Sie zuerst mit Erste Schritte.


context.prop

Die Prop-Tabelle liefert Informationen über die Prop-Entität und Methoden zur Steuerung ihrer Animationen. Sie wird für jeden Hook-Aufruf neu erstellt.

Felder

FeldTypHinweise
prop.model_idstringDer Blueprint-Modellname (z. B. "torch_01")
prop.current_locationlocation tableDie Position des Props zum Zeitpunkt der Kontexterstellung

Die Location-Tabelle hat die Standardfelder: x, y, z, world, yaw, pitch.

Beispiel: Prop-Informationen auslesen
return {
api_version = 1,

on_spawn = function(context)
context.log:info("Prop spawned: " .. (context.prop.model_id or "unknown"))
local loc = context.prop.current_location
if loc then
context.log:info("Location: " .. loc.x .. ", " .. loc.y .. ", " .. loc.z)
end
end
}

prop:play_animation(name, blend, loop)

Spielt eine benannte Animation auf dem Prop-Modell ab.

ParameterTypStandardHinweise
namestringerforderlichDer Animationsname, wie er in der Modelldatei definiert ist
blendbooleantrueOb mit der aktuellen Animation überblendet werden soll
loopbooleantrueOb die Animation in einer Schleife abgespielt wird

Gibt true zurück, wenn die Animation gefunden und gestartet wurde, andernfalls false.

Beispiel
return {
api_version = 1,

on_right_click = function(context)
local success = context.prop:play_animation("open", true, false)
if not success then
context.log:warn("Animation 'open' not found on this model!")
end
end
}

prop:stop_animation()

Stoppt alle aktuell abgespielten Animationen des Props.

Nimmt keine Parameter entgegen.

Beispiel
return {
api_version = 1,

on_right_click = function(context)
context.prop:stop_animation()
end
}

context.event

Ereignisdaten für den aktuellen Hook. Verfügbar in on_left_click, on_right_click und on_projectile_hit. Gibt nil zurück in Hooks ohne zugehöriges Ereignis (on_spawn, on_game_tick, on_destroy, on_zone_enter, on_zone_leave).

Felder und Methoden

Feld oder MethodeTypHinweise
event.is_cancelledbooleanOb das Ereignis aktuell abgebrochen ist
event.cancel()functionBricht das Ereignis ab (verhindert z. B. Schaden oder Interaktion)
event.uncancel()functionHebt die Stornierung eines zuvor abgebrochenen Ereignisses auf
info

Nicht alle Ereignisse können abgebrochen werden. Wenn das zugrunde liegende Bukkit-Event Cancellable nicht implementiert, sind event.cancel() und event.uncancel() nicht vorhanden, und event.is_cancelled ist immer false.

Beispiel: Ein Prop unverwundbar machen

Beispiel
return {
api_version = 1,

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

Beispiel: Stornierungsstatus prüfen

Beispiel
return {
api_version = 1,

on_left_click = function(context)
if context.event and not context.event.is_cancelled then
context.event.cancel()
context.log:info("Damage cancelled!")
end
end
}
vorsicht

In geplanten Callbacks (scheduler:run_later, scheduler:run_repeating) ist context.event immer nil. Ereignismodifikationen können nur während des Ereignis-Hooks selbst vorgenommen werden.


context.world

Die World-Tabelle stellt Methoden zum Abfragen und Interagieren mit der Minecraft-Welt bereit. Sie wird aus der aktuellen Welt des Props erstellt.

Gemeinsame API

Die context.world-API wird mit EliteMobs geteilt. FMM-Props verwenden dieselbe Magmacore-World-Tabelle wie EliteMobs-Bosse. Die hier dokumentierten Methoden sind die der Basis-Magmacore-Implementierung. Die vollständige Referenz finden Sie auf der Seite EliteMobs World & Environment -- die dort als Teil der Kern-context.world-API aufgeführten Methoden sind auch in FMM verfügbar.

world.name

Ein String-Feld, das den Weltnamen enthält.


world:get_block_at(x, y, z)

Gibt den Materialnamen des Blocks an den angegebenen Koordinaten als Kleinbuchstaben-String zurück (z. B. "stone", "air").

ParameterTypHinweise
xintBlock-X-Koordinate
yintBlock-Y-Koordinate
zintBlock-Z-Koordinate
Beispiel
return {
api_version = 1,

on_spawn = function(context)
local loc = context.prop.current_location
if loc then
local block = context.world:get_block_at(
math.floor(loc.x),
math.floor(loc.y) - 1,
math.floor(loc.z)
)
context.log:info("Prop is standing on: " .. block)
end
end
}

world:spawn_particle(particle, x, y, z, count, dx, dy, dz, speed)

Erzeugt Partikel an einer Position.

ParameterTypStandardHinweise
particlestringerforderlichBukkit Particle-Enum-Name, GROSSBUCHSTABEN (z. B. "FLAME", "DUST")
xnumbererforderlichX-Koordinate
ynumbererforderlichY-Koordinate
znumbererforderlichZ-Koordinate
countint1Anzahl der Partikel
dxnumber0X-Streuung/Versatz
dynumber0Y-Streuung/Versatz
dznumber0Z-Streuung/Versatz
speednumber0Partikelgeschwindigkeit
Beispiel
return {
api_version = 1,

on_right_click = function(context)
local loc = context.prop.current_location
if loc then
context.world:spawn_particle("HEART", loc.x, loc.y + 1, loc.z, 5, 0.3, 0.3, 0.3, 0)
end
end
}

world:play_sound(sound, x, y, z, volume, pitch)

Spielt einen Sound an einer Position ab.

ParameterTypStandardHinweise
soundstringerforderlichBukkit Sound-Enum-Name, GROSSBUCHSTABEN (z. B. "ENTITY_EXPERIENCE_ORB_PICKUP")
xnumbererforderlichX-Koordinate
ynumbererforderlichY-Koordinate
znumbererforderlichZ-Koordinate
volumenumber1.0Lautstärke
pitchnumber1.0Tonhöhe
Beispiel
return {
api_version = 1,

on_right_click = function(context)
local loc = context.prop.current_location
if loc then
context.world:play_sound("BLOCK_NOTE_BLOCK_PLING", loc.x, loc.y, loc.z, 1.0, 1.2)
end
end
}

world:strike_lightning(x, y, z)

Lässt einen Blitz an einer Position einschlagen (visuell und schadensverursachend).

ParameterTypHinweise
xnumberX-Koordinate
ynumberY-Koordinate
znumberZ-Koordinate
Beispiel
return {
api_version = 1,

on_projectile_hit = function(context)
local loc = context.prop.current_location
if loc then
context.world:strike_lightning(loc.x, loc.y, loc.z)
end
end
}

world:get_time()

Gibt die aktuelle Weltzeit in Ticks zurück.


world:set_time(ticks)

Setzt die Weltzeit.

ParameterTypHinweise
ticksintWeltzeit (0 = Morgendämmerung, 6000 = Mittag, 13000 = Nacht, 18000 = Mitternacht)

world:get_nearby_entities(x, y, z, radius)

Gibt ein Array von Entity-Wrapper-Tabellen für alle lebenden Entitäten innerhalb eines Begrenzungsrahmens zurück, der an den angegebenen Koordinaten zentriert ist.

ParameterTypHinweise
xnumberZentrum X
ynumberZentrum Y
znumberZentrum Z
radiusnumberSuchradius (wird als halbe Ausdehnung in allen drei Achsen verwendet)
Beispiel
return {
api_version = 1,

on_right_click = function(context)
local loc = context.prop.current_location
if loc then
local entities = context.world:get_nearby_entities(loc.x, loc.y, loc.z, 10)
context.log:info("Found " .. #entities .. " entities nearby")
end
end
}

world:get_nearby_players(x, y, z, radius)

Gibt ein Array von Player-Wrapper-Tabellen für alle Spieler innerhalb eines Begrenzungsrahmens zurück, der an den angegebenen Koordinaten zentriert ist.

ParameterTypHinweise
xnumberZentrum X
ynumberZentrum Y
znumberZentrum Z
radiusnumberSuchradius
Beispiel
return {
api_version = 1,

on_right_click = function(context)
local loc = context.prop.current_location
if loc then
local players = context.world:get_nearby_players(loc.x, loc.y, loc.z, 20)
for i = 1, #players do
context.log:info("Nearby player: " .. (players[i].name or "unknown"))
end
end
end
}

context.zones

Die Zones-Tabelle ermöglicht das Erstellen räumlicher Zonen und deren Überwachung auf Spieler-Betreten/Verlassen-Ereignisse. Zonen sind an die Skriptinstanz gebunden und werden automatisch bereinigt, wenn das Prop entfernt wird.

zones:create_sphere(x, y, z, radius)

Erstellt eine Kugelzone, die an den angegebenen Koordinaten zentriert ist. Gibt ein numerisches Zonen-Handle zurück.

ParameterTypHinweise
xnumberZentrum X
ynumberZentrum Y
znumberZentrum Z
radiusnumberKugelradius

zones:create_cylinder(x, y, z, radius, height)

Erstellt eine Zylinderzone. Gibt ein numerisches Zonen-Handle zurück.

ParameterTypHinweise
xnumberZentrum X
ynumberZentrum Y (Basis)
znumberZentrum Z
radiusnumberZylinderradius
heightnumberZylinderhöhe

zones:create_cuboid(x, y, z, xSize, ySize, zSize)

Erstellt eine Quaderzone. Gibt ein numerisches Zonen-Handle zurück.

ParameterTypHinweise
xnumberZentrum X
ynumberZentrum Y
znumberZentrum Z
xSizenumberHalbe Ausdehnung in X
ySizenumberHalbe Ausdehnung in Y
zSizenumberHalbe Ausdehnung in Z

zones:watch(handle, onEnterCallback, onLeaveCallback)

Beginnt die Überwachung einer Zone auf Spieler-Betreten/Verlassen-Ereignisse. Wenn ein Spieler die Zone betritt oder verlässt, wird der entsprechende Hook ausgelöst (on_zone_enter oder on_zone_leave).

ParameterTypHinweise
handleintZonen-Handle von einem create_*-Aufruf
onEnterCallbackfunction oder nilWird aufgerufen, wenn ein Spieler die Zone betritt
onLeaveCallbackfunction oder nilWird aufgerufen, wenn ein Spieler die Zone verlässt

Gibt true zurück, wenn die Überwachung erfolgreich eingerichtet wurde, nil wenn das Zonen-Handle ungültig war.

info

Zonenüberwachungen werden jeden Server-Tick gegen alle Spieler in derselben Welt geprüft. Halten Sie die Anzahl der Zonen angemessen, um Leistungseinbußen zu vermeiden.


zones:unwatch(handle)

Beendet die Überwachung einer Zone und bereinigt ihre Ressourcen.

ParameterTypHinweise
handleintZonen-Handle, dessen Überwachung beendet werden soll

Beispiel: Näherungsauslöser-Zone

Beispiel
return {
api_version = 1,

on_spawn = function(context)
local loc = context.prop.current_location
if loc == nil then return end

-- Create a sphere zone around the prop
local handle = context.zones:create_sphere(loc.x, loc.y, loc.z, 5)

-- Watch for player enter/leave
context.zones:watch(
handle,
function(player)
context.log:info("Player entered zone!")
end,
function(player)
context.log:info("Player left zone!")
end
)

-- Store handle so we can clean up later if needed
context.state.zone_handle = handle
end,

on_destroy = function(context)
if context.state.zone_handle then
context.zones:unwatch(context.state.zone_handle)
end
end
}

context.scheduler

Der Scheduler ermöglicht die Ausführung verzögerter und wiederkehrender Aufgaben. Alle Aufgaben gehören zur Skriptinstanz und werden automatisch abgebrochen, wenn das Prop entfernt wird.

scheduler:run_later(ticks, callback)

Führt einen Callback einmalig nach einer Verzögerung aus. Gibt eine numerische Aufgaben-ID zurück.

ParameterTypHinweise
ticksintVerzögerung in Server-Ticks (20 Ticks = 1 Sekunde)
callbackfunctionWird mit einem frischen context aufgerufen, wenn die Verzögerung abläuft
Beispiel
return {
api_version = 1,

on_right_click = function(context)
context.log:info("Something will happen in 2 seconds...")

context.scheduler:run_later(40, function(delayed_context)
local loc = delayed_context.prop.current_location
if loc then
delayed_context.world:spawn_particle("EXPLOSION_EMITTER", loc.x, loc.y, loc.z, 1)
end
end)
end
}

scheduler:run_repeating(delay, interval, callback)

Führt einen Callback wiederholt in festem Intervall aus. Gibt eine numerische Aufgaben-ID zurück.

ParameterTypHinweise
delayintAnfangsverzögerung in Ticks vor dem ersten Durchlauf
intervalintTicks zwischen jedem weiteren Durchlauf
callbackfunctionWird mit einem frischen context bei jedem Intervall aufgerufen
Beispiel
return {
api_version = 1,

on_spawn = function(context)
-- Emit particles every second
context.state.particle_task = context.scheduler:run_repeating(0, 20, function(tick_context)
local loc = tick_context.prop.current_location
if loc then
tick_context.world:spawn_particle("FLAME", loc.x, loc.y + 1, loc.z, 3, 0.1, 0.1, 0.1, 0.02)
end
end)
end,

on_destroy = function(context)
if context.state.particle_task then
context.scheduler:cancel(context.state.particle_task)
end
end
}

scheduler:cancel(taskId)

Bricht eine geplante Aufgabe anhand ihrer ID ab.

ParameterTypHinweise
taskIdintDie von run_later oder run_repeating zurückgegebene Aufgaben-ID
Wiederkehrende Aufgaben immer abbrechen

Wenn Sie eine wiederkehrende Aufgabe starten, brechen Sie diese immer in on_destroy ab (oder wenn sie nicht mehr benötigt wird). Das Vergessen des Abbruchs lässt eine Hintergrundaufgabe laufen, bis das Prop vom Server entfernt wird, was Leistung verschwendet und Fehler verursachen kann.


context.state

Eine einfache Lua-Tabelle, die für die gesamte Lebensdauer des Props bestehen bleibt. Verwenden Sie sie zum Speichern von Flags, Zählern, Aufgaben-IDs, Umschaltzuständen und allen Daten, die Sie zwischen Hooks teilen müssen.

on_spawn = function(context)
context.state.is_open = false
context.state.click_count = 0
context.state.task_id = nil
end,

on_right_click = function(context)
context.state.click_count = (context.state.click_count or 0) + 1
end
info

Nur context.state bleibt zwischen Hook-Aufrufen erhalten. Alle anderen Kontexttabellen (context.prop, context.world, context.event usw.) werden jedes Mal neu erstellt.


context.log

Konsolen-Logging-Methoden. Nachrichten werden in der Serverkonsole mit dem Skript-Dateinamen als Präfix versehen.

MethodeHinweise
log:info(message)Informationsnachricht
log:warn(message)Warnmeldung
log:error(message)Fehlermeldung (funktional identisch mit warn)
Beispiel
return {
api_version = 1,

on_spawn = function(context)
context.log:info("Script loaded!")
end,

on_right_click = function(context)
context.log:warn("Prop was clicked -- this is a debug warning")
end
}

Laufzeitmodell

Eine Laufzeit pro Prop

Jede Prop-Entität, der Skripte zugewiesen sind, erhält ihre eigene unabhängige Lua-Laufzeitinstanz. Beim Spawnen des Props lädt FMM den Lua-Quellcode, wertet ihn in einer frischen Sandbox-Umgebung aus und speichert die zurückgegebene Tabelle. Wenn das Prop entfernt wird, wird die Laufzeit heruntergefahren.

Das bedeutet:

  • Lokale Variablen, die auf Dateiebene deklariert werden, sind für diese Prop-Instanz privat.
  • context.state ist zwischen Prop-Instanzen vollständig isoliert, selbst wenn sie dieselbe Skriptdatei verwenden.

Aufgabenbesitz

Alle über context.scheduler erstellten Aufgaben gehören der Laufzeit, die sie erstellt hat. Wenn ein Prop entfernt wird:

  1. Die Laufzeit wird heruntergefahren.
  2. Jede zugehörige Aufgabe -- sowohl einmalige als auch wiederkehrende -- wird automatisch abgebrochen.
  3. Alle Zonenüberwachungen werden bereinigt.

Ausführungsbudget

Jeder Hook-Aufruf und jeder Callback-Aufruf wird zeitlich gemessen. Wenn ein einzelner Aufruf länger als 50 Millisekunden dauert, wird das Skript mit einer Konsolenwarnung deaktiviert:

[Lua] my_script.lua took 73ms in 'on_game_tick' (limit: 50ms) -- script disabled to prevent lag.

Um innerhalb des Budgets zu bleiben:

  • Vermeiden Sie unbegrenzte Schleifen innerhalb von Hooks.
  • Halten Sie on_game_tick-Handler leichtgewichtig -- sie laufen bei jedem einzelnen Tick.
  • Verwenden Sie context.scheduler:run_repeating(...), um Arbeit auf mehrere Ticks zu verteilen.

Nächste Schritte