Zum Hauptinhalt springen

Lua-Skripting: Prop-API

Diese Seite behandelt alle APIs für FreeMinecraftModels-Prop-Skripte: context.prop, context.event, context.player, context.projectile, context.world, context.zones, context.scheduler, context.state, context.cooldowns und context.log. Wenn du neu im Skripting bist, beginne zuerst mit Erste Schritte.


context.prop​

Die Prop-Tabelle liefert Informationen über die Prop-Entität und Methoden zur Steuerung ihrer Animationen. Aus Leistungsgründen speichert FMM diese Tabelle pro Prop zwischen. Felder wie current_location werden beim Zugriff aktuell ermittelt und spiegeln daher weiterhin den aktuellen Zustand des Props wider.

Felder​

FeldTypHinweise
prop.model_idstringDer Blueprint-Modellname (z. B. "torch_01")
prop.current_locationlocation-TabelleDie aktuelle Position des Props. Dieses Feld wird beim Zugriff aktuell ermittelt und ist keine einmalige Momentaufnahme.

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

Beispiel: Prop-Informationen lesen
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 am Prop-Modell ab.

ParameterTypStandardHinweise
namestringerforderlichDer Animationsname, wie in der Modelldatei definiert
blendbooleantrueBei true wird der Wechsel nach dem aktuellen Zustandstick eingereiht; false unterbricht sofort. Keine Überblendung.
loopbooleantrueOb eine benutzerdefinierte Animation wiederholt wird; eingebaute Zustände verwenden ihre eigenen Regeln

Gibt true zurück, wenn die Anfrage angenommen wird, auch wenn sie eingereiht oder unterdrückt wird; false, wenn sie nicht angenommen werden kann. Ein abschließender death-Zustand lehnt weitere Wiedergabeanfragen ab. Eine Angriffsanfrage während einer benutzerdefinierten Animation wird angenommen, ohne diese Animation zu unterbrechen. Die Warteschlange hat nur einen Platz; eine neue eingereihte Anfrage ersetzt die vorherige. Eine angenommene Anfrage beweist keine sichtbare Wiedergabe. Siehe Animationen.

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()​

Leert die Wiedergabewarteschlange und kehrt zu idle zurück, sofern verfügbar; andernfalls wird der aktuelle Zustand der gemeinsamen Animationsengine gestoppt. Ein abschließender death-Zustand bleibt bestehen, obwohl das Bedrock-Backend eine Stoppanfrage erhält.

Nimmt keine Parameter entgegen.

Beispiel
return {
api_version = 1,

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

prop:hurt_visual()​

Spielt die visuelle Verletzungsanimation (rotes Blinken) am Prop ab, ohne ihm tatsächlichen Schaden zuzufügen.

Nimmt keine Parameter entgegen.

Beispiel
return {
api_version = 1,

on_left_click = function(context)
-- Flash red when punched, but don't actually take damage
if context.event then
context.event.cancel()
end
context.prop:hurt_visual()
end
}

prop:pickup()​

Entfernt den Prop aus der Welt und lässt ein Platzierungs-Papier-Item an seinem Standort fallen. Das fallengelassene Item kann auf einen Block rechtsgeklickt werden, um den Prop erneut zu platzieren.

Nimmt keine Parameter entgegen und gibt nichts zurück. Das Entfernen und Fallenlassen wird für den Bukkit-Hauptthread eingeplant. Die Methode prüft keine Berechtigungen und überträgt gespeicherte Inventar- oder Buchdaten nicht auf das Papier-Item. Prüfe den Zugriff und kümmere dich vor dem Aufnehmen um gespeicherte Inhalte. Rufe pickup() nicht wiederholt auf, solange eine Aufnahme bereits eingeplant ist.

Beispiel
return {
api_version = 1,

on_right_click = function(context)
-- Let players pick up the prop by right-clicking it
context.prop:pickup()
end
}

prop:mount(player)​

Setzt einen Spieler auf den ersten verfügbaren Mount-Point-Sitz am Prop. Das Modell muss Mount-Point-Bones definiert haben.

ParameterTypHinweise
playerentity-TabelleEine Spieler-Entity-Tabelle (z. B. aus context.player oder context.event.player)

Gibt true zurück, wenn der Spieler gefunden wurde, der Prop Sitzpunkte hat und das Aufsteigen eingeplant wurde. Gibt false zurück, wenn diese grundlegenden Referenzen ungültig sind. Ein Rückgabewert von true beweist nicht, dass bei der späteren Ausführung tatsächlich ein Sitz frei war.

Wenn ein Rechtsklick-Skript das Aufsitzen übernimmt, brich context.event ab, damit FMMs Standardbehandlung nicht ebenfalls versucht, den Spieler auf einen Sitz zu setzen.

Beispiel
return {
api_version = 1,

on_right_click = function(context)
if context.event then context.event.cancel() end
local player = context.event and context.event.player
if player then
context.prop:mount(player)
end
end
}

prop:dismount(player)​

Entfernt einen Spieler von seinem Mount-Point-Sitz auf dem Prop.

ParameterTypHinweise
playerentity-TabelleEine Spieler-Entity-Tabelle

Gibt true zurück, wenn der Spieler gefunden wurde, der Prop einen Mount-Manager hat und die Absteigeprüfung eingeplant wurde. Gibt false zurück, wenn diese grundlegenden Referenzen ungültig sind.

Beispiel
return {
api_version = 1,

on_right_click = function(context)
if context.event then context.event.cancel() end
local player = context.event and context.event.player
if player then
-- Toggle mount/dismount
local passengers = context.prop:get_passengers()
for i = 1, #passengers do
if passengers[i].uuid == player.uuid then
context.prop:dismount(player)
return
end
end
context.prop:mount(player)
end
end
}

prop:get_passengers()​

Gibt ein Lua-Array von Entity-Tabellen für alle aktuellen Passagiere auf dem Prop zurück.

Nimmt keine Parameter entgegen.

Beispiel
return {
api_version = 1,

on_game_tick = function(context)
local passengers = context.prop:get_passengers()
if #passengers > 0 then
context.log:info("Prop has " .. #passengers .. " passenger(s)")
end
end
}

prop:has_mount_points()​

Gibt zurück, ob dieser Prop Mount-Point-Bones in seinem Modell definiert hat.

Nimmt keine Parameter entgegen. Gibt true oder false zurück.

Beispiel
return {
api_version = 1,

on_right_click = function(context)
if context.event then context.event.cancel() end
local player = context.event and context.event.player
if player and context.prop:has_mount_points() then
context.prop:mount(player)
end
end
}

prop:spawn_elitemobs_boss(filename, x, y, z)​

Spawnt einen EliteMobs-Custom-Boss am angegebenen Standort. Erfordert, dass EliteMobs auf dem Server installiert ist.

ParameterTypHinweise
filenamestringDer Dateiname des Custom-Bosses (z. B. "my_boss.yml")
xnumberX-Koordinate
ynumberY-Koordinate
znumberZ-Koordinate

Gibt eine Living-Entity-Tabelle für den gespawnten Boss zurück, oder nil, wenn die Integration keinen lebenden Boss zurückgeben kann. Dazu gehören ein nicht verfügbares Plugin, fehlende Konfiguration oder ein fehlgeschlagener Spawn. nil allein nennt die Ursache nicht.

Beispiel
return {
api_version = 1,

on_right_click = function(context)
local loc = context.prop.current_location
if loc then
local boss = context.prop:spawn_elitemobs_boss("dungeon_guardian.yml", loc.x, loc.y + 1, loc.z)
if boss then
context.log:info("Spawned boss: " .. (boss.name or "unknown"))
else
context.log:warn("Could not spawn boss -- is EliteMobs installed?")
end
end
end
}

prop:open_inventory(player, title, rows)​

Plant das Öffnen einer Truheninventar-GUI für den Spieler ein. Jeder Prop hat ein gemeinsames Inventar: Das erste Öffnen baut es aus den gespeicherten Daten im PersistentDataContainer des Props auf, und spätere Öffnungen zeigen jedem Betrachter dasselbe Live-Inventar. FMM speichert es zurück in den Prop, wenn der letzte Betrachter es schließt, wenn der Chunk des Props entladen wird und bevor drop_inventory() es ausliest.

ParameterTypStandardHinweise
playerentity-TabelleerforderlichDer Spieler, dem das Inventar gezeigt werden soll
titlestringerforderlichDer Inventar-Titel (unterstützt &-Farbcodes)
rowsint3Anzahl der Reihen (1-6, wobei 6 = 54 Slots = Doppeltruhe)

Gibt true zurück, wenn die Prop-/Spielerreferenzen gültig waren und das Öffnen eingeplant wurde, andernfalls false. Die Zeilenzahl wird vor dem Erstellen des Inventars auf den Bereich 1–6 begrenzt.

Größe und Titel stammen aus dem Aufruf, der das Inventar aufbaut; solange es offen ist, verwenden spätere Aufrufe es unverändert weiter. Enthalten die gespeicherten Inhalte mehr Slots als die angeforderten Reihen, wächst das Inventar entsprechend mit, sodass ein kleinerer rows-Wert nie gespeicherte Items verwirft. Lassen sich die gespeicherten Daten nicht lesen, öffnet sich das Inventar nicht. Die Aktion wird übersprungen, wenn der Prop vor ihrer Ausführung entfernt wurde. Der Rückgabewert garantiert nicht, dass sich das Inventar geöffnet hat.


prop:is_viewing_inventory(player)​

Gibt zurück, ob der Inventar-Listener den Spieler als Betrachter dieses Props registriert hat. Das garantiert nicht, dass der Spieler die GUI tatsächlich noch geöffnet hat.

ParameterTypHinweise
playerentity-TabelleDer zu prüfende Spieler

Gibt true oder false zurück.

Beispiel: Schließanimation, wenn Inventar geschlossen wird
context.state["task_" .. player.uuid] = context.scheduler:run_repeating(5, 5, function(tick_context)
if not tick_context.prop:is_viewing_inventory(player) then
tick_context.prop:play_animation("close", true, false)
tick_context.scheduler:cancel(tick_context.state["task_" .. player.uuid])
end
end)

prop:place_book(player)​

Nimmt das beschriebene oder beschreibbare Buch aus der Haupthand des Spielers und speichert es am Prop.

ParameterTypHinweise
playerentity-TabelleDer Spieler, der das Buch hält

Gibt true zurück, wenn die Prop-/Spielerreferenzen gültig waren und die Aktion eingeplant wurde. Die spätere Aktion im Hauptthread legt nur dann ein Buch ab, wenn der Spieler ein beschreibbares oder beschriebenes Buch hält und der Prop noch keines besitzt.


prop:read_book(player)​

Öffnet das gespeicherte Buch zum Lesen für den Spieler.

ParameterTypHinweise
playerentity-TabelleDer Spieler, dem das Buch gezeigt werden soll

Gibt true zurück, wenn die Prop-/Spielerreferenzen gültig waren und das Lesen eingeplant wurde. Die spätere Aktion benötigt ein gespeichertes, deserialisierbares WRITTEN_BOOK. Ein gespeichertes WRITABLE_BOOK wird nicht geöffnet.


prop:take_book(player)​

Gibt das gespeicherte Buch in das Inventar des Spielers zurück und entfernt es vom Prop.

ParameterTypHinweise
playerentity-TabelleDer Spieler, dem das Buch gegeben werden soll

Gibt true zurück, wenn die Prop-/Spielerreferenzen gültig waren und das Entnehmen eingeplant wurde. Das garantiert nicht, dass ein gespeichertes Buch vorhanden war.

Stelle sicher, dass das Spielerinventar Platz hat. Der gespeicherte Eintrag wird vor dem Hinzufügen entfernt; überzählige Items werden nicht fallengelassen. place_book serialisiert den gesamten gehaltenen Stapel und zieht danach ein Item ab. Verwende deshalb normale einzelne Bücher.


prop:has_book()​

Prüft nur, ob der Buchschlüssel im PDC des Träger-Rüstungsständers vorhanden ist. Der gespeicherte Inhalt wird nicht validiert. Nimmt keine Parameter entgegen.


prop:drop_inventory()​

Plant das Speichern des offenen Inventars (falls vorhanden) und dessen Schließen für jeden Betrachter ein. Anschließend liest die Aktion die gespeicherten Inhalte, löscht den PDC-Eintrag und lässt die Items am Prop fallen. Änderungen, die bis zu diesem Moment im offenen Inventar vorgenommen wurden, sind enthalten. Ein Dekodierungsfehler nach dem Löschen des gespeicherten Eintrags kann dazu führen, dass keine Items fallengelassen werden.

Nimmt keine Parameter entgegen. Gibt true zurück, wenn der Prop einen gültigen Träger-Rüstungsständer hat und das Fallenlassen eingeplant wurde. Das garantiert nicht, dass gespeicherte Items vorhanden waren.


prop:drop_book()​

Plant das Fallenlassen des gespeicherten Buchs am Prop ein. Die Aktion entfernt den gespeicherten Eintrag vor dem Dekodieren. Schlägt das Dekodieren fehl, kann das Buch verloren gehen.

Nimmt keine Parameter entgegen. Gibt true zurück, wenn der Prop einen gültigen Träger-Rüstungsständer hat und das Fallenlassen eingeplant wurde. Das garantiert nicht, dass ein gespeichertes Buch vorhanden war.


prop:set_persistent_data(key, value)​

Speichert einen String-Wert im PersistentDataContainer des Armor-Stands des Props. Die Daten bleiben mit diesem Armor-Stand bei normalem Speichern der Welt und Entladen von Chunks erhalten. Dauerhaftes Entfernen des Props oder sein Ersatz durch ein Platzierungs-Papier-Item überträgt sie nicht.

ParameterTypHinweise
keystringEin gültiger Bukkit-Schlüsselsuffix aus Kleinbuchstaben, Ziffern und ._-/. Intern unter fmm_lua_<key> gespeichert; ungültige Zeichen verursachen einen Fehler.
valuestringDer zu speichernde Wert. Verwende tostring() für Zahlen und Booleans.

Gibt true bei Erfolg zurück, false wenn der Prop keinen unterstützenden Armor-Stand hat.


prop:get_persistent_data(key)​

Ruft einen zuvor mit set_persistent_data gespeicherten String-Wert ab. Gibt nil zurück, wenn der Schlüssel nicht gesetzt wurde.

ParameterTypHinweise
keystringDer in set_persistent_data verwendete Schlüsselname
Beispiel: Persistenter Umschaltzustand
return {
api_version = 1,

on_spawn = function(context)
local saved = context.prop:get_persistent_data("active")
context.state.active = saved == "true"
end,

on_right_click = function(context)
context.state.active = not context.state.active
context.prop:set_persistent_data("active", tostring(context.state.active))
end
}

Item-Effekte​

Die API context.item für ausgerüstete Items wurde eingestellt. Definiere Effekte mit eigenen Verzauberungen und binde sie über die enchantments:-Liste des Items mit IDs einschließlich Namensraum an.

context.event​

Event-Daten für den aktuellen Hook. Verfügbar in Prop-Klick-Hooks, im Projektiltreffer-Hook und in generischen Zonen-Hooks. Gibt in Hooks ohne zugehöriges Event oder handelnden Spieler (on_spawn, on_game_tick, on_destroy) nil zurück.

FMM-Klicks verwenden ein plugininternes Abbruch-Flag für die Standardbehandlung von Props. Der Lua-Wrapper stellt ausschließlich die hier aufgeführten Felder und Methoden bereit.

Felder und Methoden​

Feld oder MethodeTypHinweise
event.playerSpieler-Entity-TabelleDer Spieler, der das Event ausgelöst oder die Grenze einer überwachten generischen Zone überquert hat. Verfügbar in den Prop-Hooks on_left_click, on_right_click, on_zone_enter und on_zone_leave. In on_projectile_hit ist es die lebende Entität, die das Projektil abgeschossen hat; das kann auch ein Mob sein, und es fehlt, wenn der Schütze keine lebende Entität ist. Alle Felder und Methoden stehen unter Spieler-Entity-Methoden.
event.is_cancelledbooleanAbbruchzustand beim Erstellen des Kontexts. Dieses Feld wird nach einem Aufruf von cancel() oder uncancel() nicht aktualisiert.
event.cancel()functionBricht das Event ab (z. B. verhindert Schaden oder Interaktion)
event.uncancel()functionHebt ein zuvor abgebrochenes Event wieder auf
Punkt und Doppelpunkt funktionieren beide

cancel und uncancel ignorieren alle übergebenen Argumente. Daher verhalten sich context.event.cancel() und context.event:cancel() identisch. Diese Seite verwendet den Punkt; beide Schreibweisen funktionieren.

Info

Generische Zonen-Hooks liefern einen handelnden Spieler ohne Abbruch-Flag. Deshalb fehlen event.cancel() und event.uncancel(), und event.is_cancelled ist false. Prop-Klick-Hooks liefern das FMM-Abbruch-Flag; sein Abbruch verhindert die entsprechende Standardaktion des Props.

Behandle event.is_cancelled als Momentaufnahme des Anfangszustands. Wenn dein Skript event.cancel() oder event.uncancel() aufruft und sich die Änderung später im selben Hook merken muss, verwende dafür ein eigenes lokales Flag.

Die aktuelle FMM-Event-Tabelle stellt keine Bukkit-spezifischen Felder wie target, block, projectile oder item bereit. Nutze context.player, context.event.player, context.projectile (in on_projectile_hit), player:get_target_entity(range), context.world:raycast(...) oder Abfragen naher Entitäten, wenn du zusätzlichen Kontext benötigst.

on_projectile_hit​

Wird ausgelöst, wenn ein Projektil die Hitbox des Props trifft, einmal pro Projektil.

KontextwertHinweise
context.projectileEntity-Tabelle des Projektils (Pfeil, Dreizack, Schneeball usw.). Nur in diesem Hook gesetzt
context.event.playerDie lebende Entität, die das Projektil abgeschossen hat, falls vorhanden
context.playerDer Schütze, wenn er ein Spieler ist, sonst nil

Der Hook läuft, nachdem FMM den Treffer verarbeitet hat, und FMMs Standardbehandlung von Projektilen bewirkt bei Props nichts. Ein Aufruf von context.event.cancel() verhindert hier nicht, dass ein nicht durchdringendes Projektil durch den Treffer verbraucht wird. Der Hook wird nicht ausgelöst, wenn ein anderes Plugin den Treffer bereits abgebrochen hat.

return {
api_version = 1,

on_projectile_hit = function(context)
local shooter = context.player
if shooter then
shooter:send_message("&eYou hit the target!")
end
context.prop:play_animation("hit", false, false)
end
}

Beispiel: Linksklick-Schaden abbrechen​

Beispiel
return {
api_version = 1,

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

Beispiel: Abbruchzustand 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

Innerhalb geplanter Callbacks (scheduler:run_later, scheduler:run_repeating) ist context.event immer nil. Event-Modifikationen können nur während des Event-Hooks selbst stattfinden.


context.world​

Dies ist die FreeMinecraftModels-/MagmaCore-World-API. Siehe context.world für die vollständige Referenz.

Info

Alle Methoden, die auf der globalen Seite dokumentiert sind (get_block_at, set_block_at, spawn_particle, play_sound, strike_lightning, get_time, set_time, get_nearby_entities, get_nearby_players, spawn_entity, get_highest_block_y, raycast, place_temporary_block, drop_item, spawn_firework), sind in FMM verfügbar. Siehe die MagmaCore-World-API für vollständige Details zu world:raycast() (einen Strahl werfen und getroffene Entitäten/Blöcke erkennen), world:place_temporary_block() (temporärer Blockersatz) und world:spawn_firework() (Feuerwerkraketen mit benutzerdefinierten Farben und Formen spawnen). EliteMobs-Boss-Powers gehen von derselben World-Basis aus und ergänzen boss-spezifische Location-Tabellen-Methoden zum Spawnen von Bossen, Verstärkungen, fallenden Blöcken, temporären Blöcken und mehr; siehe EliteMobs Welt & Umgebung.

FMM-spezifische World-Erweiterungen​

FreeMinecraftModels legt drei optionale EliteMobs-Loot-Helfer auf context.world. Sie sind immer vorhanden, geben aber jeweils false zurück und tun nichts, wenn EliteMobs nicht installiert ist:

MethodeHinweise
world:drop_elitemobs_procedural_loot(player, level, location?)Erzeugt prozedurale EliteMobs-Beute. Beachtet die EliteMobs-Einstellung für direkte Inventarbelohnungen und lässt Überlauf beim Spieler fallen; andernfalls verwendet die Methode den gewählten Standort. Gibt false zurück, wenn prozedurale Item-Drops deaktiviert sind.
world:drop_elitemobs_random_loot(player, level, location?)Würfelt die EliteMobs-Loot-Tabellen für den Spieler auf der angegebenen Stufe aus
world:drop_elitemobs_custom_loot(player, file, level, location?)Lässt eine bestimmte EliteMobs-Custom-Item-Datei für den Spieler fallen. Gibt false zurück, wenn sich die Datei nicht auflösen lässt

Die vollständigen Signaturen stehen in der Lua-API-Referenz. Das prop-seitige Gegenstück für Bosse ist prop:spawn_elitemobs_boss(...), oben dokumentiert.


Player-Entity-Methoden​

Spieler-Entity-Tabellen werden von context.player, context.event.player und context.world:get_nearby_players() zurückgegeben. Die generischen MagmaCore-Hooks on_zone_enter / on_zone_leave setzen context.player und context.event.player auf den eintretenden bzw. verlassenden Spieler.

MagmaCore-Entity-Tabellen

Die Entity-Tabellen, Lebewesen-Methoden, spielerspezifischen Methoden und Player-UI-Methoden, die auf der globalen Seite dokumentiert sind, sind die von FMM verwendeten MagmaCore-Tabellen. EliteMobs-Boss-Powers stellen ähnliche, aber boss-spezifische Entity-Tabellen bereit, dokumentiert in Boss & Entitäten. Siehe die MagmaCore Lua-Skript-Engine für die vollständige FMM-Referenz, die Entity-Basis-Felder, Lebewesen-Felder und -Methoden, spielerspezifische Felder und Methoden sowie Player-UI-Methoden abdeckt. Neue Spielermethoden umfassen player:get_target_entity() (Raycast-Zielerfassung), player:get_eye_location(), player:get_look_direction(), player:send_block_change() (gefälschte Blöcke pro Spieler) und player:reset_block() -- siehe Spielerspezifische Methoden für Details.

FMM-spezifische Entity-Felder​

Jede Entity-Tabelle, die innerhalb eines FMM-Skripts erstellt wird, erhält diese zusätzlichen Felder automatisch über FMMs LuaEntityEnricher. Die Flags und die Modellreferenz sind Momentaufnahmen beim Erstellen der Tabelle. Hole nach Änderungen an der Modellzuordnung eine neue Entity-Tabelle. Spielerberechtigungen über has_permission werden aktuell geprüft; is_op ist eine Momentaufnahme.

FeldTypHinweise
entity.is_modeledbooleantrue, wenn diese Bukkit-Entität die zugrunde liegende Entität einer ModeledEntity ist
entity.is_propbooleantrue, wenn diese Entität ein Armor-Stand ist, der eine PropEntity stützt
entity.modelTabelle oder nilNur gefüllt, wenn is_modeled = true (siehe unten)

Wenn entity.model vorhanden ist, stellt es Folgendes bereit:

Feld / MethodeHinweise
model.model_idDer Blueprint-Modellname (z. B. "dragon")
model.is_dynamictrue, wenn dies eine DynamicEntity ist (an eine Lebewesen-Entität angeheftet)
model:play_animation(name, blend, loop)Fordert eine benannte Animation an. blend und loop sind beim Zugriff über das Entitätsmodell standardmäßig false. true bedeutet, dass die Anfrage angenommen wurde; es beweist keine sichtbare Wiedergabe.
model:stop_animations()Leert die Wiedergabewarteschlange und kehrt zu idle zurück, sofern verfügbar; unterbricht keine abschließende Todesanimation
model:remove()Entfernt die modellierte Entität und alle ihre Bones sofort
on_right_click = function(context)
local player = context.event and context.event.player
if not player then return end

local target = player:get_target_entity(8)
if target and target.is_modeled then
target.model:play_animation("hurt", true, false)
end
end

EliteMobs-Entity-Felder​

Wenn EliteMobs installiert ist, leitet FMM an EliteMobs' Enricher weiter, sodass dieselben Entity-Tabellen außerdem Folgendes bereitstellen:

FeldTypHinweise
entity.is_elitebooleantrue, wenn die Entität von EliteMobs verfolgt wird
entity.is_custom_bossbooleantrue, wenn es eine Custom-Boss-Konfiguration ist
entity.is_significant_bossbooleantrue für Custom-Bosse mit einem healthMultiplier > 1 (filtert benannte Trash-Mobs heraus)
entity.eliteTabelle oder nilNur gefüllt, wenn is_elite = true. Enthält level, name, health, max_health, health_multiplier, damage_multiplier, is_custom_boss, plus elite:remove()

Die Flags und die meisten Elite-Felder sind Momentaufnahmen; health und max_health werden beim Zugriff aktuell gelesen. Mit aktiviertem EliteMobs wendet entity:can_receive_hostile_effect(player_uuid) nach der gemeinsamen Prüfung feindlicher Ziele auch EliteMobs' Berechtigungsprüfung für Magieziele an. Ein nicht verfügbarer Adapter lehnt die Prüfung ab, statt Verbündete wie eigenständige Ziele zu behandeln.


context.zones​

Dies ist die Zonen-API von FreeMinecraftModels/MagmaCore. Die vollständige Referenz steht unter context.zones. EliteMobs-Bossfähigkeiten verwenden eine andere Tabelle context.zones mit nativen EliteMobs-Zonendefinitionen; siehe EliteMobs Zonen und Zielauswahl.


context.scheduler​

Die hier dokumentierte Scheduler-API ist der MagmaCore-Scheduler für FreeMinecraftModels-Skripte und EliteMobs-NPC-Skripte. Die EliteMobs-Namen run_after, run_every und cancel_task sind Aliasse des gemeinsamen Schedulers; beide Namensschemata funktionieren. Bossfähigkeiten stellen dieselben Aliasse über ihren bossspezifischen Kontext bereit. Die vollständige FMM-Referenz steht unter context.scheduler.


context.state​

FreeMinecraftModels-Skripte, EliteMobs-Bossfähigkeiten und EliteMobs-NPC-Skripte teilen sich die State-API. Die vollständige Referenz steht unter context.state.


context.log​

Die hier dokumentierte Logging-API ist der Logger von FreeMinecraftModels/MagmaCore (info, warn, error). EliteMobs-NPC-Skripte verwenden denselben Logger; EliteMobs-Bossfähigkeiten stellen info, warn und debug bereit. Die vollständige Referenz steht unter context.log.


context.cooldowns​

Die hier dokumentierte Abklingzeit-API verwendet die gemeinsame MagmaCore-/FMM-Reihenfolge, die von FreeMinecraftModels-Skripten und EliteMobs-NPC-Skripten genutzt wird: check_local(key?, duration). EliteMobs-Boss-Powers verwenden dieselbe Argumentreihenfolge mit boss-spezifischen Speichern. Die vollständige Referenz findest du unter context.cooldowns.

MethodeHinweise
local_ready(key?)Prüft, ob eine lokale Abklingzeit bereit ist.
local_remaining(key?)Gibt die verbleibenden Ticks der lokalen Abklingzeit zurück, oder 0.
check_local(key?, duration)Prüft und startet eine lokale Abklingzeit atomar.
set_local(duration, key?)Setzt eine lokale Abklingzeit ohne Prüfung.
global_ready()Prüft die gemeinsame globale Abklingzeit des Skript-Besitzers.
set_global(duration)Setzt die gemeinsame globale Abklingzeit des Skript-Besitzers.

Verwende context.cooldowns:check_local("my_key", 40) für normale Abklingzeiten von Prop-Aktionen.


Laufzeitmodell​

Eine Laufzeit pro Skript-Instanz​

Jeder Eintrag in der scripts:-Liste eines Props erhält eine eigene Lua-Laufzeit. FMM findet und validiert den Quellcode beim Registrieren des Providers und wertet anschließend den zwischengespeicherten Code für jede Bindung in einer frischen Sandbox aus. Nach dem Ändern oder Hinzufügen einer Lua-Datei ist ein erfolgreiches Neuladen nötig, bevor neue Bindungen sie verwenden. Skript-Callbacks laufen in der konfigurierten Listenreihenfolge; der gelesene Wert priority ändert die Reihenfolge der Prop-Bindungen nicht. Beim Entfernen des Props werden seine Skriptinstanzen heruntergefahren.

Item-Verzauberungen haben einen eigenen Lebenszyklus; sie erzeugen keine Prop-Skript-Instanz für ausgerüstete Items.

Das bedeutet:

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

Zugehörigkeit geplanter Tasks​

Alle Tasks, die durch context.scheduler erstellt werden, gehören der Laufzeit, die sie erstellt hat. Wenn ein Prop entfernt wird:

  1. Die Laufzeit wird heruntergefahren.
  2. Jeder eigene Task -- sowohl einmalige als auch wiederkehrende -- wird automatisch abgebrochen.
  3. Alle Zonenbeobachtungen werden gelöscht.

on_destroy läuft nur dann zuerst, wenn der Prop endgültig entfernt wird: aufgehoben, zerstört, mit /fmm deleteall gelöscht oder von einem Plugin entfernt. Wird der Chunk oder die Welt des Props entladen oder lädt FMM neu bzw. fährt herunter, stoppt die Laufzeit, ohne on_destroy aufzurufen. Der Prop kehrt mit einer neuen Laufzeit und einem neuen on_spawn zurück, wenn sein Chunk wieder geladen wird.

Cooldown-Geltungsbereich​

Die geteilte Skript-Engine stellt lokale Cooldown-Helfer (local_ready, local_remaining, check_local, set_local) und globale Cooldown-Helfer (global_ready, set_global) bereit. FMM ordnet diese Speicher wie folgt zu:

Skript-TypLokaler SpeicherbereichGlobaler Speicherbereich
Prop-SkriptPro ScriptInstance (Prop + Skript-Datei)Pro PropEntity (geteilt über jedes an diesen Prop gebundene Skript)

Globale Prop-Cooldowns werden beim Abmelden des Props oder beim Herunterfahren des Skript-Managers während eines erfolgreichen Neuladens oder Deaktivierens gelöscht. Eine abgelehnte Vorbereitung des Neuladens erhält die aktuelle Laufzeit. Cooldown-Dauern verwenden monoton vergangene Zeit mit 50 ms pro angefordertem Tick. Scheduler-Verzögerungen folgen dagegen Server-Ticks; bei Server-Lag können beide voneinander abweichen.

Ausführungsbudget​

Jeder Hook-Aufruf, jeder geplante Callback und die anfängliche Auswertung der Skriptdatei selbst laufen unter einem harten Ausführungsbudget. Das Budget wird innerhalb der Lua-VM durchgesetzt, greift also, während dein Code noch läuft, statt erst danach die Uhr zu prüfen.

LimitWert
CPU-Zeit des aktuellen Threads50 Millisekunden
Ausgeführte Lua-Instruktionen250.000

Welches Limit zuerst erreicht wird, bricht den Aufruf mit einem Lua-Fehler ab und deaktiviert die Skript-Instanz. Die Meldungen lauten:

Lua instruction budget exceeded (250000 instruction limit)
Lua CPU-time budget exceeded (50ms current-thread CPU limit)

Der Instruktionszähler begrenzt reine Lua-Schleifen wie while true do end. Die Zeit wird alle 1.024 Lua-Instruktionen und bei der Rückkehr des Aufrufs geprüft. Der Watchdog unterbricht keine blockierende Java-/Bukkit-Methode, während diese läuft.

Die Zeithälfte des Budgets wird als CPU-Zeit des aktuellen Threads gemessen, nicht als Echtzeit, ein Skript wird also nicht für Zeit belastet, in der der Server-Thread verdrängt war. Auf einer JVM, auf der die CPU-Zeitmessung des aktuellen Threads nicht verfügbar ist, weicht MagmaCore auf ein bewusst großzügigeres Limit von 250 Millisekunden vergangener Zeit aus (Lua elapsed-time fallback budget exceeded (250ms fallback; current-thread CPU time unavailable)) und behält dabei dieselbe Obergrenze von 250.000 Instruktionen bei, sodass nicht terminierende Skripte in jedem Fall begrenzt bleiben.

Verschachtelte Aufrufe teilen sich ein Budget: Wenn ein Hook einen Callback aufruft, der wiederum einen weiteren aufruft, wird die gesamte Kette als eine einzige Zuteilung von 50 ms CPU-Zeit / 250.000 Instruktionen gemessen, nicht als je eine pro Aufruf.

Die Auswertung beim Einlesen des Providers lehnt ungültige Definitionen vor der Registrierung ab. Der zwischengespeicherte Quellcode wird für jede neue Instanz unter demselben Budget erneut ausgewertet.

Um innerhalb des Budgets zu bleiben:

  • Vermeide unbegrenzte Schleifen innerhalb von Hooks.
  • Halte on_game_tick-Handler leichtgewichtig -- sie laufen in jedem einzelnen Tick.
  • Verwende context.scheduler:run_repeating(...), um Arbeit über Ticks zu verteilen.

Vollständige Hook-Referenz​

Diese Tabelle führt die aktiven Prop-Hooks auf.

Die Spalte context.event beschreibt das FMM-Abbruch-Flag oder den handelnden Spieler der Zone. Der Lua-Wrapper stellt gegebenenfalls event.player, event.is_cancelled, event.cancel() und event.uncancel() bereit.

Aktive Prop-Hooks (8)​

HookWird ausgelöst, wenncontext.event
on_spawnProp in die Welt spawnt oder mit seinem Chunk erneut geladen wirdnil
on_game_tickJeder Server-Tick (50 ms bei 20 TPS)nil
on_destroyProp endgültig entfernt wird (nicht beim Entladen eines Chunks oder beim Neuladen)nil
on_left_clickSpieler den Prop links anklicktAbbruch-Flag für Standardschaden
on_right_clickSpieler den Prop rechts anklicktAbbruch-Flag für Standardinteraktion
on_zone_enterSpieler eine beobachtete Zone betrittSpieler-Akteur der Zone (context.player / context.event.player; nicht abbrechbar)
on_zone_leaveSpieler eine beobachtete Zone verlässtSpieler-Akteur der Zone (context.player / context.event.player; nicht abbrechbar)
on_projectile_hitEin Projektil den Prop trifftProjektiltreffer-Event; event.player ist der Schütze. Siehe on_projectile_hit

Item-Effekte​

Verwende eigene Verzauberungen für Effekte gehaltener Items. Die alte Tabelle mit 22 Item-Skript-Hooks beschreibt keinen aktuellen Laufzeitvertrag mehr.

Nächste Schritte​

EliteMobs-Transport​

context.world:start_elitemobs_transport(player, route_id) startet für einen Spieler eine gespeicherte EliteMobs-Route in der Welt des Kontexts. Die Methode gibt zurück, ob die Anfrage angenommen wurde, und erfordert EliteMobs mit geladener Route. Die ID enthält keine .yml-Endung. Siehe Transportrouten.