Aller au contenu principal

Scripting Lua : API Prop

Cette page couvre toutes les API disponibles pour les scripts de props FreeMinecraftModels : context.prop, context.event, context.world, context.zones, context.scheduler, context.state et context.log. Si vous débutez avec le scripting de props, commencez par Premiers pas.


context.prop

La table prop fournit des informations sur l'entité prop et des méthodes pour contrôler ses animations. Elle est reconstruite à chaque appel de hook.

Champs

ChampTypeNotes
prop.model_idstringLe nom du modèle blueprint (ex. "torch_01")
prop.current_locationlocation tableLa position du prop au moment où le contexte a été construit

La table de localisation possède les champs standard : x, y, z, world, yaw, pitch.

Exemple : lire les informations du prop
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)

Joue une animation nommée sur le modèle du prop.

ParamètreTypePar défautNotes
namestringrequisLe nom de l'animation tel que défini dans le fichier du modèle
blendbooleantrueSi l'animation doit se fondre avec l'animation en cours
loopbooleantrueSi l'animation boucle

Retourne true si l'animation a été trouvée et démarrée, false sinon.

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

Arrête toutes les animations en cours de lecture sur le prop.

Ne prend aucun paramètre.

Exemple
return {
api_version = 1,

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

context.event

Données d'événement pour le hook en cours. Disponible dans on_left_click, on_right_click et on_projectile_hit. Retourne nil dans les hooks sans événement associé (on_spawn, on_game_tick, on_destroy, on_zone_enter, on_zone_leave).

Champs et méthodes

Champ ou méthodeTypeNotes
event.is_cancelledbooleanSi l'événement est actuellement annulé
event.cancel()functionAnnule l'événement (ex. empêche les dégâts ou l'interaction)
event.uncancel()functionRétablit un événement précédemment annulé
info

Tous les événements ne sont pas annulables. Si l'événement Bukkit sous-jacent n'implémente pas Cancellable, event.cancel() et event.uncancel() ne seront pas présents et event.is_cancelled sera toujours false.

Exemple : Rendre un prop invulnérable

Exemple
return {
api_version = 1,

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

Exemple : Vérifier l'état d'annulation

Exemple
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
}
attention

Dans les callbacks programmés (scheduler:run_later, scheduler:run_repeating), context.event est toujours nil. La modification d'événements ne peut se faire que pendant le hook d'événement lui-même.


context.world

La table world fournit des méthodes pour interroger et interagir avec le monde Minecraft. Elle est construite à partir du monde actuel du prop.

API partagée

L'API context.world est partagée avec EliteMobs. Les props FMM utilisent la même table world Magmacore que les boss EliteMobs. Les méthodes documentées ici sont celles disponibles dans l'implémentation de base Magmacore. Pour la référence complète, consultez la page EliteMobs World & Environment -- les méthodes listées comme faisant partie de l'API de base context.world sont également disponibles dans FMM.

world.name

Un champ string contenant le nom du monde.


world:get_block_at(x, y, z)

Retourne le nom du matériau du bloc aux coordonnées données sous forme de string en minuscules (ex. "stone", "air").

ParamètreTypeNotes
xintCoordonnée X du bloc
yintCoordonnée Y du bloc
zintCoordonnée Z du bloc
Exemple
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)

Génère des particules à un emplacement.

ParamètreTypePar défautNotes
particlestringrequisNom de l'enum Particle de Bukkit, en MAJUSCULES (ex. "FLAME", "DUST")
xnumberrequisCoordonnée X
ynumberrequisCoordonnée Y
znumberrequisCoordonnée Z
countint1Nombre de particules
dxnumber0Dispersion/décalage en X
dynumber0Dispersion/décalage en Y
dznumber0Dispersion/décalage en Z
speednumber0Vitesse des particules
Exemple
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)

Joue un son à un emplacement.

ParamètreTypePar défautNotes
soundstringrequisNom de l'enum Sound de Bukkit, en MAJUSCULES (ex. "ENTITY_EXPERIENCE_ORB_PICKUP")
xnumberrequisCoordonnée X
ynumberrequisCoordonnée Y
znumberrequisCoordonnée Z
volumenumber1.0Volume
pitchnumber1.0Hauteur du son
Exemple
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)

Frappe la foudre à un emplacement (visuel et infligeant des dégâts).

ParamètreTypeNotes
xnumberCoordonnée X
ynumberCoordonnée Y
znumberCoordonnée Z
Exemple
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()

Retourne l'heure actuelle du monde en ticks.


world:set_time(ticks)

Définit l'heure du monde.

ParamètreTypeNotes
ticksintHeure du monde (0 = aube, 6000 = midi, 13000 = nuit, 18000 = minuit)

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

Retourne un tableau de tables wrapper d'entités pour toutes les entités vivantes dans une boîte englobante centrée aux coordonnées données.

ParamètreTypeNotes
xnumberCentre X
ynumberCentre Y
znumberCentre Z
radiusnumberRayon de recherche (utilisé comme demi-étendue sur les trois axes)
Exemple
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)

Retourne un tableau de tables wrapper de joueurs pour tous les joueurs dans une boîte englobante centrée aux coordonnées données.

ParamètreTypeNotes
xnumberCentre X
ynumberCentre Y
znumberCentre Z
radiusnumberRayon de recherche
Exemple
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

La table zones permet de créer des zones spatiales et de les surveiller pour les événements d'entrée/sortie de joueurs. Les zones sont liées à l'instance du script et nettoyées automatiquement lorsque le prop est supprimé.

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

Crée une zone sphérique centrée aux coordonnées données. Retourne un identifiant numérique de zone.

ParamètreTypeNotes
xnumberCentre X
ynumberCentre Y
znumberCentre Z
radiusnumberRayon de la sphère

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

Crée une zone cylindrique. Retourne un identifiant numérique de zone.

ParamètreTypeNotes
xnumberCentre X
ynumberCentre Y (base)
znumberCentre Z
radiusnumberRayon du cylindre
heightnumberHauteur du cylindre

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

Crée une zone cuboïde. Retourne un identifiant numérique de zone.

ParamètreTypeNotes
xnumberCentre X
ynumberCentre Y
znumberCentre Z
xSizenumberDemi-étendue en X
ySizenumberDemi-étendue en Y
zSizenumberDemi-étendue en Z

zones:watch(handle, onEnterCallback, onLeaveCallback)

Commence à surveiller une zone pour les événements d'entrée/sortie de joueurs. Lorsqu'un joueur entre ou quitte la zone, le hook correspondant se déclenche (on_zone_enter ou on_zone_leave).

ParamètreTypeNotes
handleintIdentifiant de zone d'un appel create_*
onEnterCallbackfunction ou nilAppelé lorsqu'un joueur entre dans la zone
onLeaveCallbackfunction ou nilAppelé lorsqu'un joueur quitte la zone

Retourne true si la surveillance a été configurée avec succès, nil si l'identifiant de zone était invalide.

info

Les surveillances de zone sont vérifiées à chaque tick du serveur pour tous les joueurs dans le même monde. Gardez le nombre de zones raisonnable pour éviter une surcharge de performance.


zones:unwatch(handle)

Arrête la surveillance d'une zone et nettoie ses ressources.

ParamètreTypeNotes
handleintIdentifiant de zone à ne plus surveiller

Exemple : Zone de déclenchement par proximité

Exemple
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

Le scheduler permet d'exécuter des tâches différées et répétitives. Toutes les tâches appartiennent à l'instance du script et sont annulées automatiquement lorsque le prop est supprimé.

scheduler:run_later(ticks, callback)

Exécute un callback une fois après un délai. Retourne un ID de tâche numérique.

ParamètreTypeNotes
ticksintDélai en ticks serveur (20 ticks = 1 seconde)
callbackfunctionAppelé avec un context fraîchement créé lorsque le délai expire
Exemple
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)

Exécute un callback de manière répétée à intervalle fixe. Retourne un ID de tâche numérique.

ParamètreTypeNotes
delayintDélai initial en ticks avant la première exécution
intervalintTicks entre chaque exécution suivante
callbackfunctionAppelé avec un context fraîchement créé à chaque intervalle
Exemple
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)

Annule une tâche programmée par son ID.

ParamètreTypeNotes
taskIdintL'ID de tâche retourné par run_later ou run_repeating
Annulez toujours les tâches répétitives

Si vous démarrez une tâche répétitive, annulez-la toujours dans on_destroy (ou quand elle n'est plus nécessaire). Oublier de l'annuler laisse une tâche en arrière-plan qui s'exécute jusqu'à ce que le prop soit retiré du serveur, ce qui gaspille des performances et peut causer des erreurs.


context.state

Une table Lua simple qui persiste pendant toute la durée de vie du prop. Utilisez-la pour stocker des drapeaux, compteurs, IDs de tâches, états de bascule et toutes données à partager entre les hooks.

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

Seul context.state persiste entre les appels de hooks. Toutes les autres tables de contexte (context.prop, context.world, context.event, etc.) sont reconstruites à chaque fois.


context.log

Méthodes de journalisation console. Les messages sont préfixés par le nom du fichier de script dans la console du serveur.

MéthodeNotes
log:info(message)Message d'information
log:warn(message)Message d'avertissement
log:error(message)Message d'erreur (fonctionnellement identique à warn)
Exemple
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
}

Modèle d'exécution

Un environnement d'exécution par prop

Chaque entité prop ayant des scripts attachés obtient sa propre instance indépendante d'environnement d'exécution Lua. Lorsque le prop apparaît, FMM charge le code source Lua, l'évalue dans un environnement sandbox fraîchement créé et stocke la table retournée. Lorsque le prop est supprimé, l'environnement d'exécution est arrêté.

Cela signifie :

  • Les variables locales déclarées au niveau du fichier sont privées à cette instance de prop.
  • context.state est complètement isolé entre les instances de prop, même si elles partagent le même fichier de script.

Propriété des tâches

Toutes les tâches créées via context.scheduler appartiennent à l'environnement d'exécution qui les a créées. Lorsqu'un prop est supprimé :

  1. L'environnement d'exécution s'arrête.
  2. Chaque tâche -- à la fois les tâches uniques et répétitives -- est automatiquement annulée.
  3. Toutes les surveillances de zone sont nettoyées.

Budget d'exécution

Chaque invocation de hook et chaque invocation de callback est chronométrée. Si un seul appel prend plus de 50 millisecondes, le script est désactivé avec un avertissement en console :

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

Pour rester dans le budget :

  • Évitez les boucles non bornées dans les hooks.
  • Gardez les handlers on_game_tick légers -- ils s'exécutent à chaque tick.
  • Utilisez context.scheduler:run_repeating(...) pour répartir le travail sur plusieurs ticks.

Prochaines étapes

  • Exemples et modèles -- scripts de props complets et fonctionnels avec explications
  • Dépannage -- problèmes courants, conseils de débogage et liste de vérification QC
  • Premiers pas -- structure de fichiers, hooks, guide de création du premier script