Scripts Lua: primeros pasos
Esta página te enseña a escribir tu primer script Lua para un elemento decorativo de FreeMinecraftModels, desde un archivo vacío hasta un script interactivo funcional. Al terminar, comprenderás los eventos de script, el contexto, la API de elementos decorativos y la estructura general de los archivos de script.
Cuando domines lo básico, continúa con estas páginas:
- API de elementos decorativos -- las API de
context.prop,context.event,context.worldy otros componentes del contexto - Ejemplos y patrones: scripts de elementos decorativos con notas de configuración para estudiar y adaptar
- Solución de problemas -- errores habituales, consejos de depuración y la lista de control de calidad
Los scripts Lua de elementos decorativos son experimentales. Los nombres de los eventos, los métodos auxiliares y el comportamiento pueden cambiar conforme evolucione FreeMinecraftModels, así que pruébalos con cuidado antes de usarlos en un servidor de producción.
FreeMinecraftModels usa el motor Lua de MagmaCore. Si ya escribes poderes Lua para EliteMobs, reconocerás los conceptos principales: archivos que devuelven una tabla, api_version, eventos de script, context, estado, tiempos de reutilización, programación de tareas y el entorno aislado. Los eventos y los nombres exactos de los métodos del contexto dependen del plugin:
- Los scripts de EliteMobs se ejecutan en jefes y tienen eventos como
on_boss_damaged_by_player,on_enter_combat, etc. - Los scripts de elementos decorativos de FMM se ejecutan en esos elementos y tienen eventos como
on_right_click,on_left_click,on_zone_enter, etc. - Los encantamientos de objetos usan el contexto independiente de los encantamientos personalizados.
Las API context.world, context.zones, context.scheduler, context.state y context.log documentadas aquí son las versiones de FreeMinecraftModels/MagmaCore. Los scripts de NPC de EliteMobs usan las mismas tablas genéricas de MagmaCore más context.npc; los poderes de jefes de EliteMobs usan variantes específicas para varias tablas. Esta página cubre lo específico de los elementos decorativos de FMM.
Qué son los scripts de elementos decorativos
Son archivos .lua independientes que se guardan en plugins/FreeMinecraftModels/scripts/. Se referencian desde un archivo de configuración YAML situado junto al archivo del modelo y se ejecutan cuando el elemento decorativo aparece en el mundo.
Para qué sirven
Estos scripts son útiles para:
- Elementos interactivos que respondan a los clics de jugadores, como puertas, palancas y botones
- Elementos decorativos que ignoren el daño predeterminado del clic izquierdo
- Activadores de proximidad que detecten cuándo los jugadores entran o salen de una zona
- Elementos animados que reproduzcan animaciones al interactuar o mediante un temporizador
- Elementos que emitan sonidos al hacer clic o acercarse
- Cualquier comportamiento que necesite lógica más allá de la decoración estática
Si el elemento es puramente decorativo y no necesita interacción, no necesita un script.
Objetos personalizados y encantamientos
Los objetos personalizados siguen usando un YAML junto al modelo con un material, pero sus efectos ahora utilizan encantamientos con espacio de nombres. El antiguo sistema de scripts de objetos equipados se ha retirado. Los objetos personalizados que tengan una lista scripts: no vacía se omiten con un mensaje informativo en consola; su definición queda intacta.
Los archivos Lua reconocidos como scripts retirados de objetos equipados en scripts/ se conservan en plugins/MagmaCore/outdated files/FreeMinecraftModels/<archive batch>/scripts/ antes de la detección y después de las importaciones. La regla exige una definición antigua válida que contenga un evento retirado de objetos, como on_equip u on_attack_entity. No clasifica como scripts retirados los scripts de elementos decorativos, los que solo usan eventos compartidos, los scripts malformados ni los efectos actuales de enchantments/. Consulta la recuperación en archivos de configuración retirados.
Consulta objetos personalizados y armas mágicas para las definiciones actuales de objetos y encantamientos personalizados para sus efectos. Las listas scripts: de elementos decorativos siguen funcionando.
A quién va dirigida esta página
Esta página está escrita para tres tipos de lectores:
- Quienes ya conocen los scripts Lua de EliteMobs y quieren aprender los eventos y las API específicos de FMM
- Quienes empiezan con Lua y necesitan una referencia completa con los nombres exactos para elementos decorativos
- Quienes usan IA para redactar scripts y necesitan suficiente detalle para detectar funciones inventadas
No necesitas dominar Lua por completo para escribir scripts útiles. Para la mayoría de los casos prácticos basta con saber:
- Colocar un evento válido en la tabla devuelta
- Leer valores de
context - Detener la ejecución anticipadamente con
if ... then return end - Llamar a unos pocos métodos auxiliares con su nombre exacto
Breve introducción a Lua
No necesitas ser experto en Lua para escribir scripts de FMM. La mayoría usa pocos conceptos: variables (local x = 5), funciones (function foo() end), condiciones if (if x then ... end), tablas ({key = value}) y nil (el valor de Lua que representa la ausencia de un valor). La sintaxis es ligera: sin punto y coma ni llaves para los bloques; se usa end para cerrarlos.
Encontrarás una explicación completa con ejemplos en Motor de scripts Lua de MagmaCore — Breve introducción a Lua. Esa introducción es común a todos los plugins de Nightbreak, así que lo aprendido sirve para todos ellos.
Dónde se guardan los archivos
Archivos de script
Coloca los archivos .lua en la carpeta central de scripts:
plugins/
FreeMinecraftModels/
scripts/
invulnerable.lua
interactive_door.lua
proximity_sound.lua
FMM busca archivos .lua de forma recursiva en plugins/FreeMinecraftModels/scripts/ al inicializar su proveedor de scripts y guarda el código en caché. Usa nombres únicos entre subcarpetas, porque las asociaciones usan el nombre del archivo, no su ruta relativa. Después de añadir o editar Lua, completa un /fmm reload correcto antes de crear nuevas asociaciones. Regenerar el elemento no vuelve a leer el código Lua.
Incluye la extensión .lua en la lista scripts: del modelo para mayor claridad. FMM también acepta entradas sin extensión y añade .lua internamente. El archivo en disco debe terminar en .lua y los nombres distinguen mayúsculas de minúsculas.
Archivos de modelo y configuración
Cada archivo de modelo puede tener un archivo de configuración .yml con el mismo nombre en el mismo directorio:
plugins/
FreeMinecraftModels/
models/
torch_01.fmmodel
torch_01.yml <-- script config for torch_01
scripts/
invulnerable.lua <-- referenced by torch_01.yml
El archivo .yml conecta el modelo con sus scripts.
Formato del archivo de configuración
El archivo YAML situado junto al modelo tiene estos campos:
isEnabled: true
voxelize: false
solidify: false
scripts:
- invulnerable.lua
Los campos para elementos decorativos son:
| Campo | Tipo | Predeterminado | Notas |
|---|---|---|---|
isEnabled | booleano | true | Si la definición está habilitada |
scripts | lista de cadenas | [] | Nombres de archivos Lua de scripts/ |
voxelize | booleano | false | Ajusta la colocación a la cuadrícula de bloques y a rotaciones de 90 grados |
solidify | booleano | false | Añade bloques barrera mediante paquetes a un elemento voxelizado |
Cada script de la lista obtiene su propia instancia. Para objetos que se sostienen, define en su lugar material, name, lore y enchantments con espacio de nombres. Consulta objetos personalizados.
Generación diferida de la configuración
Cuando aparece un elemento decorativo y no existe un .yml junto al modelo, FMM crea automáticamente una configuración predeterminada con isEnabled: true y una lista scripts: vacía. Ocurre de forma asíncrona, por lo que el elemento no tendrá scripts en su primera aparición; solo los tendrá después de crear la configuración y añadir los nombres de archivo.
Por tanto:
- Coloca el archivo de modelo en
models/ - Genera el elemento una vez; FMM crea el
.ymlautomáticamente - Edita el
.ymlgenerado para añadir los nombres de tus scripts - Completa correctamente
/fmm reloadtras editar YAML o Lua. Después coloca un prop nuevo y confirma su registro o interacción. Los ajustes, las comprobaciones de colocación y las listas de scripts del menú comparten el catálogo preparado; volver a generar el prop no relee el YAML.
Referencia de eventos de script
Cada archivo Lua devuelve una tabla. Cada clave de esa tabla, aparte de api_version y priority, debe ser uno de los eventos siguientes. El motor llama a la función correspondiente cuando se produce ese evento del juego.
| Evento | Se ejecuta cuando | Notas |
|---|---|---|
on_spawn | El elemento aparece en el mundo, o vuelve a cargarse con su chunk | Se ejecuta una vez cada vez que se vincula el script |
on_game_tick | Una vez por tick del servidor (50 ms a 20 TPS) | Solo está activo si el script define este evento |
on_destroy | Se elimina el elemento definitivamente | Evento de limpieza. No se llama cuando se descarga el chunk del elemento ni cuando FMM se recarga |
on_left_click | Un jugador hace clic izquierdo (golpea) en el elemento | context.event contiene la marca que cancela el daño predeterminado de FMM |
on_right_click | Un jugador hace clic derecho en el elemento | context.event contiene la marca que cancela la interacción predeterminada de FMM |
on_zone_enter | Un jugador entra en una zona vigilada | Requiere configurar la vigilancia de una zona |
on_zone_leave | Un jugador sale de una zona vigilada | Requiere configurar la vigilancia de una zona |
on_projectile_hit | Un proyectil impacta en el elemento | context.projectile es el proyectil; context.event.player es quien lo disparó. Consulta la API de elementos decorativos |
Efectos de objetos
Los antiguos eventos de objetos equipados ya no se ejecutan. Los efectos pertenecen a los encantamientos personalizados, que tienen sus propios eventos y contexto. No adjuntes Lua de encantamientos a la lista scripts: de un elemento decorativo ni copies un script antiguo de objetos sin adaptarlo.
Contrato mínimo del archivo
Cada script Lua debe devolver una tabla mediante return.
Campos de nivel superior obligatorios y opcionales
| Campo | Obligatorio | Tipo | Notas |
|---|---|---|---|
api_version | Sí | Número | Actualmente debe ser 1 |
priority | No | Número | Se valida si está presente, pero FMM no ordena actualmente los scripts de elementos decorativos por este valor. Se ejecutan en el orden de la lista scripts: |
| claves de eventos admitidos | No | Función | Deben usar uno de los nombres exactos de la referencia de eventos |
Reglas de validación
- El archivo debe devolver una tabla.
api_versiones obligatorio y actualmente debe ser1.prioritydebe ser numérico si está presente.- Cada clave adicional de nivel superior debe ser un nombre de evento admitido.
- Cada clave de evento debe apuntar a una función.
- Se rechazan las claves de nivel superior desconocidas.
priority ayuda a que los scripts sean portables entre motores basados en MagmaCore, pero el orden actual de ejecución de FreeMinecraftModels lo determina la configuración. Coloca los scripts en el orden deseado en la lista scripts: del modelo.
Las funciones auxiliares y las constantes locales deben estar antes del return final, fuera de la tabla devuelta.
Tu primer script funcional, paso a paso
Antes del paso 1: preparar la configuración
- Coloca el archivo de modelo (p. ej.,
my_prop.fmmodel) enplugins/FreeMinecraftModels/models/ - Genera el elemento una vez para crear la configuración
.yml - Crea el script en
plugins/FreeMinecraftModels/scripts/first_test.lua - Edita
plugins/FreeMinecraftModels/models/my_prop.yml:
isEnabled: true
scripts:
- first_test.lua
- Guarda el contenido Lua del paso 1 siguiente, ejecuta
/fmm reloady comprueba que termine correctamente. Vuelve a generar el elemento si hace falta. Repite la recarga correcta después de cada edición Lua de los siguientes pasos.
Paso 1: conseguir que el archivo se cargue
return {
api_version = 1,
on_spawn = function(context)
end
}
La ausencia de errores en la consola es una primera comprobación útil. Usa el mensaje explícito del paso 2 para confirmar que:
- El archivo contiene Lua válido
- FMM lo encontró en la carpeta
scripts/ - La configuración lo referencia correctamente
- La estructura de la tabla devuelta es correcta
Paso 2: producir un resultado visible
return {
api_version = 1,
on_spawn = function(context)
context.log:info("Prop script loaded for: " .. (context.prop.model_id or "unknown"))
end
}
Revisa la consola del servidor. Si aparece el mensaje, la función del evento se está ejecutando.
Paso 3: reaccionar al clic de un jugador
return {
api_version = 1,
on_right_click = function(context)
context.log:info("Prop was right-clicked!")
end
}
Haz clic derecho en el elemento dentro del juego. Si la consola muestra el mensaje, el evento de clic funciona.
Paso 4: cancelar el daño del clic izquierdo
return {
api_version = 1,
on_left_click = function(context)
if context.event then
context.event.cancel()
end
end
}
Este es el patrón del script incluido invulnerable.lua. Cancela el daño predeterminado de FMM para ese clic. No vuelve invulnerable a la entidad subyacente frente a todas las fuentes de daño.
Paso 5: reproducir una animación al hacer clic
return {
api_version = 1,
on_right_click = function(context)
context.prop:play_animation("open", true, false)
end
}
Esto solicita la animación "open", sin bucle, después del tick del estado actual. El modelo debe contenerla. blend no hace una transición gradual; la cola solo tiene un espacio y una solicitud posterior puede sustituirla. La muerte terminal puede rechazarla. Comprueba el resultado visible en el juego; la aceptación no demuestra la reproducción.
Qué es context
Cada función de evento recibe un argumento llamado context. Es la caja de herramientas que FMM te entrega cada vez que ocurre algo: contiene lo necesario para interactuar con el elemento, el mundo, las zonas y otros sistemas.
No creas context por tu cuenta: FMM lo crea y lo pasa a la función. Para conocer las API compartidas (context.state, context.log, context.cooldowns, context.scheduler, context.world, context.zones), consulta el Motor de scripts Lua de MagmaCore.
API principales de context
Este es un resumen de lo disponible. Para los detalles completos, consulta la API de elementos decorativos.
-
context.prop-- Solo en scripts de elementos decorativos. La entidad del elemento. Proporcionamodel_id,current_location,play_animation()ystop_animation(). -
context.player-- El jugador que activa un evento de clic o un evento genérico de zona, y quien disparó enon_projectile_hitcuando fue un jugador quien lanzó el proyectil. Esnilen eventos del ciclo de vida, funciones programadas y eventos que no involucran a un jugador. -
context.event-- La marca de cancelación de FMM y el jugador que provoca un clic, el evento de impacto de proyectil y quien disparó enon_projectile_hit, o una tabla que solo contiene al actor para los eventos genéricos de zona. Proporcionaevent.player,is_cancelledy, para clics e impactos de proyectiles,cancel()/uncancel(); no expone campos específicos de Bukkit comotarget,block,projectileoitem. Esnilen los eventos sin evento subyacente ni jugador actor, comoon_spawnyon_game_tick. -
context.projectile-- La entidad del proyectil enon_projectile_hit, ynilen todos los demás eventos. Consultaon_projectile_hit. -
context.state-- Tabla Lua simple que persiste durante la vida de la instancia del script. Consulta context.state. -
context.cooldowns-- Métodos para tiempos de reutilización locales y globales. Usacontext.cooldowns:check_local("key", ticks)para un tiempo de reutilización normal de un script. Consulta context.cooldowns. -
context.log-- Registro en consola. Consulta context.log. -
context.scheduler-- Tareas diferidas y repetitivas. Consulta context.scheduler. -
context.world-- Interacción con el mundo: partículas, sonidos, consultas de bloques, rayos y entidades cercanas. Consulta context.world. -
context.zones-- Creación y vigilancia de zonas espaciales: esferas, cilindros y cuboides. Consulta context.zones.
Sintaxis de métodos: : frente a .
Encontrarás una explicación de la sintaxis : frente a . en Lua en el Motor de scripts Lua de MagmaCore. La API de FMM acepta ambas formas.
Plantillas para copiar y pegar
Script válido mínimo
return {
api_version = 1,
on_spawn = function(context)
end
}
Plantilla para cancelar el daño del clic izquierdo
return {
api_version = 1,
on_left_click = function(context)
if context.event then
context.event.cancel()
end
end
}
Plantilla de elemento interactivo
return {
api_version = 1,
on_spawn = function(context)
context.state.is_active = false
end,
on_right_click = function(context)
context.state.is_active = not context.state.is_active
if context.state.is_active then
context.prop:play_animation("activate", true, true)
else
context.prop:stop_animation()
end
end
}
Estructura de un archivo más grande
local ANIMATION_NAME = "idle"
local function do_something(context)
context.log:info("Doing something!")
end
return {
api_version = 1,
priority = 0,
on_spawn = function(context)
context.state.task_id = nil
end,
on_right_click = function(context)
do_something(context)
end,
on_destroy = function(context)
if context.state.task_id ~= nil then
context.scheduler:cancel(context.state.task_id)
end
end
}
Primer flujo de trabajo real
Para crear un script desde cero, sigue este orden:
- Crea el archivo
.luay consigue queon_spawnfuncione. - Añade el nombre del archivo de script al
.ymldel elemento. - Cambia al evento que necesitas, por ejemplo,
on_right_click. - Añade primero un mensaje de registro, antes que animaciones o efectos.
- Añade un efecto real: animación, sonido o partícula.
- Después añade funciones auxiliares, estado, tareas programadas o zonas.
Después de cada edición Lua, guarda el archivo y completa un /fmm reload correcto antes de comprobar el nuevo comportamiento. Cambia una sola cosa por paso para que el registro o efecto visible identifique qué funcionó.
Scripts incluidos
FMM escribe cuatro scripts Lua cuando faltan. También sustituye versiones antiguas reconocidas de los scripts predeterminados, pero conserva otras ediciones existentes. Revisa el archivo instalado si su comportamiento difiere de los valores actuales:
invulnerable.lua-- Cancela el daño predeterminado del clic izquierdo de FMM. No bloquea todas las fuentes posibles de daño.pickupable.lua: cancela el daño predeterminado del clic izquierdo y cuenta tres golpes permitidos antes de solicitar la recogida. El contador pertenece a la asociación y se comparte entre jugadores; una tarea de 100 ticks del servidor lo reinicia después de un golpe anterior. Los golpes permitidos solicitan un destello de daño. Bloquea ubicaciones protegidas o de mazmorras salvo que el jugador tenga el permiso de omisión de protección de FMM o sea operador.storage_double.lua: solicita un inventario de 54 ranuras, animaciones y sonidos de apertura y cierre. Usa la misma comprobación de protección y excepción de operador; consulta el seguimiento de espectadores cada 5 ticks del servidor. El inventario del elemento lo comparten todos los espectadores y se guarda cuando lo cierra el último espectador o cuando se descarga el chunk. La destrucción solicitadrop_inventory(), que primero guarda el inventario abierto, así que los objetos colocados en un inventario aún abierto se incluyen en lo que se suelta. Consultaprop:open_inventorypara ver los detalles.storage_single.lua-- Igual questorage_double, pero con 3 filas (27 ranuras) en lugar de 6.
Encontrarás más ejemplos en Ejemplos y patrones.
Entorno aislado de Lua
Los scripts de elementos decorativos se ejecutan en el mismo entorno LuaJ aislado que EliteMobs, con las mismas restricciones. Para ver la lista completa de variables globales eliminadas y funciones disponibles de la biblioteca estándar, consulta el Motor de scripts Lua de MagmaCore.
Siguientes pasos
- API de elementos decorativos -- referencia completa de
context.prop,context.event,context.world,context.zonesycontext.scheduler - Ejemplos y patrones: scripts de elementos decorativos con explicaciones y notas de configuración
- Solución de problemas -- problemas habituales, consejos de depuración y una lista de control de calidad
Si también escribes poderes Lua para jefes de EliteMobs, reconocerás el entorno aislado, api_version, la tabla de estado, los tiempos de reutilización y la estructura basada en eventos, pero el contexto de los jefes usa métodos específicos de EliteMobs. Consulta la documentación Lua de EliteMobs para las API exactas de jefes.