Saltar al contenido principal

Scripting Lua: API de Props

Esta página cubre todas las API disponibles para los scripts de props de FreeMinecraftModels: context.prop, context.event, context.world, context.zones, context.scheduler, context.state y context.log. Si eres nuevo en el scripting de props, comienza primero con Primeros pasos.


context.prop

La tabla prop proporciona información sobre la entidad del prop y métodos para controlar sus animaciones. Se reconstruye desde cero en cada llamada de hook.

Campos

CampoTipoNotas
prop.model_idstringEl nombre del modelo blueprint (ej. "torch_01")
prop.current_locationlocation tableLa posición del prop en el momento en que se construyó el contexto

La tabla de ubicación tiene los campos estándar: x, y, z, world, yaw, pitch.

Ejemplo: leer información del 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)

Reproduce una animación con nombre en el modelo del prop.

ParámetroTipoPor defectoNotas
namestringrequeridoEl nombre de la animación tal como está definido en el archivo del modelo
blendbooleantrueSi se debe mezclar con la animación actual
loopbooleantrueSi la animación se repite en bucle

Devuelve true si la animación fue encontrada e iniciada, false en caso contrario.

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

Detiene todas las animaciones que se están reproduciendo actualmente en el prop.

No requiere parámetros.

Ejemplo
return {
api_version = 1,

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

context.event

Datos del evento para el hook actual. Disponible en on_left_click, on_right_click y on_projectile_hit. Devuelve nil en hooks que no tienen un evento asociado (on_spawn, on_game_tick, on_destroy, on_zone_enter, on_zone_leave).

Campos y métodos

Campo o métodoTipoNotas
event.is_cancelledbooleanSi el evento está actualmente cancelado
event.cancel()functionCancela el evento (ej. previene daño o interacción)
event.uncancel()functionRevierte la cancelación de un evento previamente cancelado
info

No todos los eventos son cancelables. Si el evento subyacente de Bukkit no implementa Cancellable, event.cancel() y event.uncancel() no estarán presentes y event.is_cancelled siempre será false.

Ejemplo: Hacer un prop invulnerable

Ejemplo
return {
api_version = 1,

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

Ejemplo: Verificar el estado de cancelación

Ejemplo
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
}
precaución

Dentro de callbacks programados (scheduler:run_later, scheduler:run_repeating), context.event siempre es nil. La modificación de eventos solo puede ocurrir durante el propio hook del evento.


context.world

La tabla world proporciona métodos para consultar e interactuar con el mundo de Minecraft. Se construye a partir del mundo actual del prop.

API compartida

La API context.world se comparte con EliteMobs. Los props de FMM usan la misma tabla world de Magmacore que los jefes de EliteMobs. Los métodos documentados aquí son los disponibles en la implementación base de Magmacore. Para la referencia completa, consulta la página EliteMobs World & Environment -- los métodos listados allí como parte de la API base context.world también están disponibles en FMM.

world.name

Un campo de tipo string que contiene el nombre del mundo.


world:get_block_at(x, y, z)

Devuelve el nombre del material del bloque en las coordenadas dadas como un string en minúsculas (ej. "stone", "air").

ParámetroTipoNotas
xintCoordenada X del bloque
yintCoordenada Y del bloque
zintCoordenada Z del bloque
Ejemplo
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)

Genera partículas en una ubicación.

ParámetroTipoPor defectoNotas
particlestringrequeridoNombre del enum Particle de Bukkit, MAYÚSCULAS (ej. "FLAME", "DUST")
xnumberrequeridoCoordenada X
ynumberrequeridoCoordenada Y
znumberrequeridoCoordenada Z
countint1Número de partículas
dxnumber0Dispersión/desplazamiento en X
dynumber0Dispersión/desplazamiento en Y
dznumber0Dispersión/desplazamiento en Z
speednumber0Velocidad de las partículas
Ejemplo
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)

Reproduce un sonido en una ubicación.

ParámetroTipoPor defectoNotas
soundstringrequeridoNombre del enum Sound de Bukkit, MAYÚSCULAS (ej. "ENTITY_EXPERIENCE_ORB_PICKUP")
xnumberrequeridoCoordenada X
ynumberrequeridoCoordenada Y
znumberrequeridoCoordenada Z
volumenumber1.0Volumen
pitchnumber1.0Tono
Ejemplo
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)

Invoca un rayo en una ubicación (visual y con daño).

ParámetroTipoNotas
xnumberCoordenada X
ynumberCoordenada Y
znumberCoordenada Z
Ejemplo
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()

Devuelve la hora actual del mundo en ticks.


world:set_time(ticks)

Establece la hora del mundo.

ParámetroTipoNotas
ticksintHora del mundo (0 = amanecer, 6000 = mediodía, 13000 = noche, 18000 = medianoche)

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

Devuelve un array de tablas wrapper de entidades para todas las entidades vivas dentro de un cuadro delimitador centrado en las coordenadas dadas.

ParámetroTipoNotas
xnumberCentro X
ynumberCentro Y
znumberCentro Z
radiusnumberRadio de búsqueda (usado como media extensión en los tres ejes)
Ejemplo
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)

Devuelve un array de tablas wrapper de jugadores para todos los jugadores dentro de un cuadro delimitador centrado en las coordenadas dadas.

ParámetroTipoNotas
xnumberCentro X
ynumberCentro Y
znumberCentro Z
radiusnumberRadio de búsqueda
Ejemplo
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 tabla zones permite crear zonas espaciales y vigilarlas para eventos de entrada/salida de jugadores. Las zonas están vinculadas a la instancia del script y se limpian automáticamente cuando se elimina el prop.

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

Crea una zona esférica centrada en las coordenadas dadas. Devuelve un identificador numérico de zona.

ParámetroTipoNotas
xnumberCentro X
ynumberCentro Y
znumberCentro Z
radiusnumberRadio de la esfera

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

Crea una zona cilíndrica. Devuelve un identificador numérico de zona.

ParámetroTipoNotas
xnumberCentro X
ynumberCentro Y (base)
znumberCentro Z
radiusnumberRadio del cilindro
heightnumberAltura del cilindro

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

Crea una zona de forma cuboide. Devuelve un identificador numérico de zona.

ParámetroTipoNotas
xnumberCentro X
ynumberCentro Y
znumberCentro Z
xSizenumberMedia extensión en X
ySizenumberMedia extensión en Y
zSizenumberMedia extensión en Z

zones:watch(handle, onEnterCallback, onLeaveCallback)

Comienza a vigilar una zona para eventos de entrada/salida de jugadores. Cuando un jugador entra o sale de la zona, se dispara el hook correspondiente (on_zone_enter u on_zone_leave).

ParámetroTipoNotas
handleintIdentificador de zona de una llamada create_*
onEnterCallbackfunction o nilSe llama cuando un jugador entra en la zona
onLeaveCallbackfunction o nilSe llama cuando un jugador sale de la zona

Devuelve true si la vigilancia se configuró correctamente, nil si el identificador de zona era inválido.

info

Las vigilancias de zona se verifican cada tick del servidor contra todos los jugadores en el mismo mundo. Mantén la cantidad de zonas razonable para evitar sobrecarga de rendimiento.


zones:unwatch(handle)

Detiene la vigilancia de una zona y limpia sus recursos.

ParámetroTipoNotas
handleintIdentificador de zona a dejar de vigilar

Ejemplo: Zona de activación por proximidad

Ejemplo
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

El scheduler permite ejecutar tareas retrasadas y repetitivas. Todas las tareas pertenecen a la instancia del script y se cancelan automáticamente cuando se elimina el prop.

scheduler:run_later(ticks, callback)

Ejecuta un callback una vez después de un retraso. Devuelve un ID de tarea numérico.

ParámetroTipoNotas
ticksintRetraso en ticks del servidor (20 ticks = 1 segundo)
callbackfunctionSe llama con un context nuevo cuando expira el retraso
Ejemplo
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)

Ejecuta un callback repetidamente a un intervalo fijo. Devuelve un ID de tarea numérico.

ParámetroTipoNotas
delayintRetraso inicial en ticks antes de la primera ejecución
intervalintTicks entre cada ejecución subsiguiente
callbackfunctionSe llama con un context nuevo en cada intervalo
Ejemplo
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)

Cancela una tarea programada por su ID.

ParámetroTipoNotas
taskIdintEl ID de tarea devuelto por run_later o run_repeating
Cancela siempre las tareas repetitivas

Si inicias una tarea repetitiva, cancélala siempre en on_destroy (o cuando ya no sea necesaria). Olvidar cancelarla deja una tarea ejecutándose en segundo plano hasta que el prop se elimine del servidor, lo que desperdicia rendimiento y puede causar errores.


context.state

Una tabla Lua simple que persiste durante toda la vida del prop. Úsala para almacenar flags, contadores, IDs de tareas, estados de alternancia y cualquier dato que necesites compartir entre 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

Solo context.state persiste entre llamadas de hooks. Todas las demás tablas de contexto (context.prop, context.world, context.event, etc.) se reconstruyen desde cero cada vez.


context.log

Métodos de registro en consola. Los mensajes se muestran con el nombre del archivo del script como prefijo en la consola del servidor.

MétodoNotas
log:info(message)Mensaje informativo
log:warn(message)Mensaje de advertencia
log:error(message)Mensaje de error (funcionalmente igual que warn)
Ejemplo
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
}

Modelo de ejecución

Un entorno de ejecución por prop

Cada entidad prop que tiene scripts asignados obtiene su propia instancia independiente de entorno de ejecución Lua. Cuando el prop aparece, FMM carga el código fuente Lua, lo evalúa en un entorno sandbox nuevo y almacena la tabla devuelta. Cuando se elimina el prop, el entorno de ejecución se cierra.

Esto significa:

  • Las variables locales declaradas a nivel de archivo son privadas para esa instancia de prop.
  • context.state está completamente aislado entre instancias de prop, incluso si comparten el mismo archivo de script.

Propiedad de tareas

Todas las tareas creadas a través de context.scheduler pertenecen al entorno de ejecución que las creó. Cuando se elimina un prop:

  1. El entorno de ejecución se cierra.
  2. Todas las tareas -- tanto las de una sola vez como las repetitivas -- se cancelan automáticamente.
  3. Todas las vigilancias de zonas se limpian.

Presupuesto de ejecución

Cada invocación de hook y cada invocación de callback se mide en tiempo. Si una sola llamada tarda más de 50 milisegundos, el script se desactiva con una advertencia en consola:

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

Para mantenerte dentro del presupuesto:

  • Evita bucles sin límite dentro de hooks.
  • Mantén los handlers de on_game_tick ligeros -- se ejecutan en cada tick.
  • Usa context.scheduler:run_repeating(...) para distribuir el trabajo entre ticks.

Próximos pasos