Scripting Lua: API de Props e Ítems
Esta página cubre todas las API disponibles para los scripts de props e ítems de FreeMinecraftModels: context.prop, context.item, context.event, context.player, context.world, context.zones, context.scheduler, context.state y context.log. Si eres nuevo en el scripting, 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
| Campo | Tipo | Notas |
|---|---|---|
prop.model_id | string | El nombre del modelo blueprint (ej. "torch_01") |
prop.current_location | location table | La 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ámetro | Tipo | Por defecto | Notas |
|---|---|---|---|
name | string | requerido | El nombre de la animación tal como está definido en el archivo del modelo |
blend | boolean | true | Si se debe mezclar con la animación actual |
loop | boolean | true | Si 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
}
prop:hurt_visual()
Reproduce la animación visual de daño (destello de tinte rojo) en el prop sin causar ningún daño real.
No requiere parámetros.
Ejemplo
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()
Elimina el prop del mundo y suelta un ítem de papel de colocación en su ubicación. El ítem soltado puede usarse con clic derecho en un bloque para colocar el prop nuevamente.
No requiere parámetros.
Ejemplo
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)
Monta a un jugador en la primera posición de asiento de punto de montaje disponible en el prop. El modelo debe tener bones de punto de montaje definidos.
| Parámetro | Tipo | Notas |
|---|---|---|
player | entity table | Una tabla de entidad de jugador (ej. de context.event.player) |
Ejemplo
return {
api_version = 1,
on_right_click = function(context)
local player = context.event and context.event.player
if player then
context.prop:mount(player)
end
end
}
prop:dismount(player)
Desmonta a un jugador de su posición de asiento de punto de montaje en el prop.
| Parámetro | Tipo | Notas |
|---|---|---|
player | entity table | Una tabla de entidad de jugador |
Ejemplo
return {
api_version = 1,
on_right_click = function(context)
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()
Devuelve un array de Lua con tablas de entidades para todos los pasajeros actuales del prop.
No requiere parámetros.
Ejemplo
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()
Devuelve si este prop tiene bones de punto de montaje definidos en su modelo.
No requiere parámetros. Devuelve true o false.
Ejemplo
return {
api_version = 1,
on_right_click = function(context)
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)
Genera un jefe personalizado de EliteMobs en la ubicación dada. Requiere que EliteMobs esté instalado en el servidor.
| Parámetro | Tipo | Notas |
|---|---|---|
filename | string | El nombre de archivo del jefe personalizado (ej. "my_boss.yml") |
x | number | Coordenada X |
y | number | Coordenada Y |
z | number | Coordenada Z |
Devuelve una tabla de entidad viva para el jefe generado, o nil si EliteMobs no está instalado o el archivo de jefe no existe.
Ejemplo
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)
Abre un inventario de cofre GUI persistente para el jugador. El contenido se guarda en el PersistentDataContainer del prop cuando se cierra el inventario, y se restaura cuando se abre nuevamente.
| Parámetro | Tipo | Por defecto | Notas |
|---|---|---|---|
player | entity table | requerido | El jugador al que mostrar el inventario |
title | string | requerido | El título del inventario (soporta códigos de color con &) |
rows | int | 3 | Número de filas (1-6, donde 6 = 54 slots = cofre doble) |
Devuelve true si el inventario fue abierto, false en caso contrario.
prop:is_viewing_inventory(player)
Devuelve si el jugador dado actualmente tiene abierto el inventario de este prop.
| Parámetro | Tipo | Notas |
|---|---|---|
player | entity table | El jugador a verificar |
Devuelve true o false.
Ejemplo: Animación de cierre cuando se cierra el inventario
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)
Toma el libro escrito o escribible de la mano principal del jugador y lo almacena en el prop.
| Parámetro | Tipo | Notas |
|---|---|---|
player | entity table | El jugador que sostiene el libro |
Devuelve true si fue exitoso.
prop:read_book(player)
Abre el libro almacenado para que el jugador lo lea.
| Parámetro | Tipo | Notas |
|---|---|---|
player | entity table | El jugador al que mostrar el libro |
Devuelve true si se abrió un libro.
prop:take_book(player)
Devuelve el libro almacenado al inventario del jugador y lo elimina del prop.
| Parámetro | Tipo | Notas |
|---|---|---|
player | entity table | El jugador al que dar el libro |
Devuelve true si fue exitoso.
prop:has_book()
Devuelve si hay un libro almacenado en este prop. No requiere parámetros.
prop:drop_inventory()
Suelta todo el contenido del inventario almacenado en la ubicación del prop como entidades de ítems, luego limpia los datos almacenados. Cierra automáticamente el inventario para cualquier jugador que lo esté viendo actualmente.
No requiere parámetros. Devuelve true si fue exitoso.
prop:drop_book()
Suelta el libro almacenado en la ubicación del prop como una entidad de ítem y limpia los datos del libro almacenado.
No requiere parámetros. Devuelve true si fue exitoso.
prop:set_persistent_data(key, value)
Almacena un valor de tipo string en el PersistentDataContainer del armor stand del prop. Estos datos sobreviven reinicios del servidor y descargas de chunks.
| Parámetro | Tipo | Notas |
|---|---|---|
key | string | Un nombre de clave único (almacenado como fmm_lua_<key> internamente) |
value | string | El valor a almacenar. Usa tostring() para números y booleanos. |
Devuelve true si fue exitoso, false si el prop no tiene un armor stand de respaldo.
prop:get_persistent_data(key)
Recupera un valor de tipo string previamente almacenado con set_persistent_data. Devuelve nil si la clave no ha sido establecida.
| Parámetro | Tipo | Notas |
|---|---|---|
key | string | El nombre de clave usado en set_persistent_data |
Ejemplo: Estado de alternancia persistente
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
}
context.item
La tabla item está disponible solo en scripts de ítems (no en scripts de props). Proporciona información sobre el ítem personalizado y métodos para manipularlo. Esta tabla se reconstruye desde cero en cada llamada de hook.
Campos
| Campo | Tipo | Notas |
|---|---|---|
item.id | string | El ID de tipo de ítem (el fmm_item_id de la configuración YML) |
item:material()
Devuelve el nombre del material del ítem como string (ej. "DIAMOND_SWORD", "STICK").
item:get_amount() / item:set_amount(n)
Obtiene o establece el tamaño del stack del ítem.
| Parámetro | Tipo | Notas |
|---|---|---|
n | int | La nueva cantidad del stack |
item:consume(n)
Decrementa la cantidad del stack del ítem en n (por defecto 1). Si la cantidad resultante es 0 o menos, el ítem se elimina del inventario del jugador.
| Parámetro | Tipo | Por defecto | Notas |
|---|---|---|---|
n | int | 1 | Cantidad a consumir |
item:get_uses() / item:set_uses(n)
Obtiene o establece un contador de uso personalizado almacenado en el PersistentDataContainer del ítem. Esto es independiente de la durabilidad vanilla y puede usarse para implementar sistemas de durabilidad o carga personalizados.
| Parámetro | Tipo | Notas |
|---|---|---|
n | int | El nuevo conteo de usos |
item:get_name() / item:set_name(s)
Obtiene o establece el nombre de visualización del ítem. Soporta códigos de color con &.
| Parámetro | Tipo | Notas |
|---|---|---|
s | string | El nuevo nombre de visualización (ej. "&b&lFrost Sword") |
item:get_lore() / item:set_lore(table)
Obtiene o establece el lore del ítem. get_lore() devuelve una tabla de strings (una por línea). set_lore() recibe una tabla de strings.
| Parámetro | Tipo | Notas |
|---|---|---|
table | table | Array de strings, una por línea de lore |
Ejemplo: Script de ítem que rastrea usos
return {
api_version = 1,
on_right_click = function(context)
local uses = context.item:get_uses()
if uses <= 0 then
context.player:send_message("&cThis item is out of charges!")
return
end
context.item:set_uses(uses - 1)
context.player:send_message("&aUsed! Charges remaining: " .. (uses - 1))
end
}
item:get_durability()
Devuelve una tabla con campos current y max representando la durabilidad vanilla del ítem, o nil si el ítem no tiene barra de durabilidad.
Ejemplo
local dur = context.item:get_durability()
if dur then
context.player:send_message("Durability: " .. dur.current .. "/" .. dur.max)
end
item:get_durability_percentage()
Devuelve la durabilidad restante como una fracción de 0.0 a 1.0, o nil si el ítem no tiene barra de durabilidad.
item:use_durability(amount, can_break)
Reduce la durabilidad vanilla del ítem por una cantidad fija.
| Parámetro | Tipo | Por defecto | Notas |
|---|---|---|---|
amount | int | requerido | Cuántos puntos de durabilidad consumir |
can_break | boolean | false | Si es true, el ítem se destruye cuando la durabilidad se agota. Si es false, la durabilidad se detiene en 1. |
item:use_durability_percentage(fraction, can_break)
Reduce la durabilidad vanilla del ítem por un porcentaje de su máximo.
| Parámetro | Tipo | Por defecto | Notas |
|---|---|---|---|
fraction | number | requerido | Fracción de la durabilidad máxima a consumir (ej. 0.1 = 10%) |
can_break | boolean | false | Si es true, el ítem se destruye cuando la durabilidad se agota. Si es false, la durabilidad se detiene en 1. |
context.event
Datos del evento para el hook actual. Disponible en hooks de clic, combate e interacción tanto para scripts de props como de ítems. Devuelve nil en hooks que no tienen un evento asociado (on_spawn, on_game_tick, on_destroy, on_zone_enter, on_zone_leave, on_equip).
Campos y Métodos
| Campo o Método | Tipo | Notas |
|---|---|---|
event.player | tabla de entidad de jugador | El jugador que activó el evento. Disponible en on_left_click, on_right_click y on_projectile_hit (el lanzador, si fue un jugador). Consulta Métodos de Entidad de Jugador para todos los campos y métodos. |
event.is_cancelled | boolean | Si el evento está actualmente cancelado |
event.cancel() | function | Cancela el evento (ej. previene daño o interacción) |
event.uncancel() | function | Revierte la cancelación de un evento previamente cancelado |
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
}
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 API world se comparte entre todos los plugins de Nightbreak. Consulta context.world para la referencia completa.
Los props de FMM usan la misma tabla world de MagmaCore que los jefes de EliteMobs. Todos los métodos documentados en la página global (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, spawn_firework) están disponibles en FMM. Consulta la API world de MagmaCore para detalles completos sobre world:raycast() (lanzar un rayo y detectar entidades/bloques impactados) y world:spawn_firework() (generar cohetes de fuegos artificiales con colores y formas personalizados). EliteMobs extiende la tabla world con métodos adicionales para generar jefes, refuerzos y más -- consulta Mundo y Entorno de EliteMobs.
Métodos de Entidad de Jugador
Las tablas de entidad de jugador se obtienen de context.event.player, context.world:get_nearby_players() y callbacks de zonas.
Las tablas de entidad, métodos de entidad viva, métodos específicos de jugador y métodos de UI de jugador se comparten entre todos los plugins de Nightbreak. Consulta el Motor de Scripting Lua de MagmaCore para la referencia completa que cubre campos base de entidad, campos y métodos de entidad viva, campos y métodos específicos de jugador, y Métodos de UI de Jugador. Los nuevos métodos de jugador incluyen player:get_target_entity() (apuntado por raycast), player:get_eye_location(), player:get_look_direction(), player:send_block_change() (bloques falsos por jugador), y player:reset_block() -- consulta Métodos Específicos de Jugador para detalles.
context.zones
La API de zonas se comparte entre todos los plugins de Nightbreak. Consulta context.zones para la referencia completa.
context.scheduler
La API del scheduler se comparte entre todos los plugins de Nightbreak. Consulta context.scheduler para la referencia completa.
context.state
La API de estado se comparte entre todos los plugins de Nightbreak. Consulta context.state para la referencia completa.
context.log
La API de logging se comparte entre todos los plugins de Nightbreak. Consulta context.log para la referencia completa.
Modelo de Ejecución
Un Entorno de Ejecución por Instancia de Script
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.
Para scripts de ítems, se crea un entorno de ejecución por par (jugador, itemId). Cuando un jugador equipa un ítem personalizado, FMM crea una instancia de script para ese jugador y tipo de ítem. Cuando el ítem se desequipa, el entorno de ejecución se cierra.
Esto significa:
- Las variables locales declaradas a nivel de archivo son privadas para esa instancia de script.
context.stateestá completamente aislado entre instancias, incluso si comparten el mismo archivo de script.
Propiedad de Tareas Programadas
Todas las tareas creadas a través de context.scheduler pertenecen al entorno de ejecución que las creó. Cuando se elimina un prop:
- El entorno de ejecución se cierra.
- Todas las tareas -- tanto las de una sola vez como las repetitivas -- se cancelan automáticamente.
- 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_tickligeros -- se ejecutan en cada tick. - Usa
context.scheduler:run_repeating(...)para distribuir el trabajo entre ticks.
Referencia Completa de Hooks
Esta tabla lista todos los hooks disponibles tanto en scripts de props como de ítems.
Hooks de Props (8)
| Hook | Se dispara cuando | context.event |
|---|---|---|
on_spawn | El prop aparece en el mundo | nil |
on_game_tick | Cada tick del servidor (50ms) | nil |
on_destroy | El prop es eliminado | nil |
on_left_click | Un jugador hace clic izquierdo en el prop | evento de daño |
on_right_click | Un jugador hace clic derecho en el prop | evento de interacción |
on_projectile_hit | Un proyectil impacta en el prop | evento de impacto de proyectil |
on_zone_enter | Un jugador entra en una zona vigilada | nil |
on_zone_leave | Un jugador sale de una zona vigilada | nil |
Hooks de Ítems (22)
| Hook | Categoría | Se dispara cuando | context.event |
|---|---|---|---|
on_attack_entity | Combate | El jugador ataca una entidad | evento de daño |
on_kill_entity | Combate | El jugador mata una entidad | evento de muerte |
on_take_damage | Combate | El jugador recibe daño | evento de daño |
on_shield_block | Combate | El jugador bloquea con escudo | evento de daño |
on_shoot_bow | Combate | El jugador dispara un arco | evento de disparo de arco |
on_projectile_hit | Combate | El proyectil del jugador impacta | evento de impacto de proyectil |
on_projectile_launch | Combate | El jugador lanza un proyectil | evento de lanzamiento |
on_right_click | Interacción | El jugador hace clic derecho | evento de interacción |
on_left_click | Interacción | El jugador hace clic izquierdo | evento de interacción |
on_shift_right_click | Interacción | El jugador hace shift+clic derecho | evento de interacción |
on_shift_left_click | Interacción | El jugador hace shift+clic izquierdo | evento de interacción |
on_interact_entity | Interacción | El jugador hace clic derecho en una entidad | evento de interacción con entidad |
on_equip | Equipamiento | El ítem entra en un slot activo | nil |
on_unequip | Equipamiento | El ítem sale de un slot activo | nil |
on_swap_hands | Equipamiento | Intercambia mano principal/secundaria | evento de intercambio |
on_drop | Equipamiento | El jugador suelta el ítem | evento de soltar |
on_break_block | Utilidad | El jugador rompe un bloque | evento de rotura de bloque |
on_consume | Utilidad | El jugador consume el ítem | evento de consumo |
on_item_damage | Utilidad | El ítem recibe daño de durabilidad | evento de daño de ítem |
on_fish | Utilidad | El jugador usa caña de pescar | evento de pesca |
on_death | Utilidad | El jugador muere mientras está equipado | evento de muerte |
on_game_tick | Ciclo de vida | Cada tick mientras está equipado | nil |
Próximos Pasos
- Ejemplos y Patrones -- scripts completos y funcionales de props e ítems con explicaciones
- Solución de Problemas -- problemas comunes, consejos de depuración y lista de verificación de QC
- Primeros Pasos -- estructura de archivos, hooks, tutorial del primer script