Scripting Lua: Solución de problemas
Esta página cubre los problemas comunes que puedes encontrar al escribir o depurar scripts de props de FreeMinecraftModels, además de consejos para trabajar con el sistema de generación diferida de configuración. Si buscas ejemplos funcionales, consulta Ejemplos y patrones. Si recién estás comenzando, consulta Primeros pasos.
Problemas comunes
1. El archivo de configuración no se carga / El script no está asignado
Síntoma: El prop aparece pero no responde a clics ni a ningún hook.
Causas y soluciones:
-
Aún no existe un archivo de configuración
.yml. FMM genera la configuración de forma diferida en el primer spawn del prop. La primera vez que se genera un modelo, FMM crea la configuración.ymlde forma asíncrona con valores predeterminados (habilitado, sin scripts). Debes editar la configuración generada para agregar los nombres de tus archivos de script y luego volver a generar el prop. -
La configuración tiene
isEnabled: false. Abre el archivo.ymljunto al archivo del modelo y estableceisEnabled: true. -
La lista
scripts:está vacía. Agrega los nombres de tus archivos de script:isEnabled: true
scripts:
- my_script.lua -
El nombre del archivo
.ymlno coincide con el nombre del archivo del modelo. La configuración debe tener el mismo nombre base que el archivo del modelo. Por ejemplo,torch_01.fmmodelnecesitatorch_01.ymlen el mismo directorio.
2. Archivo de script no encontrado
Síntoma: La consola muestra: [FMM Scripts] Script 'my_script.lua' not found in scripts/ folder
Causas y soluciones:
-
Directorio incorrecto. Los archivos de script deben estar en
plugins/FreeMinecraftModels/scripts/, no junto al archivo del modelo. -
Nombre de archivo no coincide. El nombre en la configuración
.ymldebe coincidir exactamente con el nombre del archivo en la carpetascripts/, incluyendo mayúsculas/minúsculas y la extensión.lua. -
Archivo no presente. Verifica que el archivo
.luarealmente exista en la carpetascripts/.
3. El script no se carga en absoluto
Síntoma: No hay error en la consola, pero ningún hook se activa.
Revisa la consola del servidor en busca de errores de sintaxis Lua durante el inicio. Las causas más comunes son:
- Falta
endpara cerrar una función o un bloqueif - Paréntesis no emparejados
- Falta coma entre definiciones de hooks en la tabla retornada
- El archivo no termina con
.lua
Si hay un error de Lua, la consola imprimirá un bloque de error [Lua] con el nombre del archivo, el número de línea y una descripción.
4. El hook nunca se activa
Síntoma: El script se carga (ves el mensaje [FMM Scripts] Bound script), pero un hook específico nunca se activa.
Verifica que el nombre del hook esté escrito exactamente como aparece en la referencia de hooks. Errores comunes:
| Nombre incorrecto | Nombre correcto |
|---|---|
on_click | on_right_click o on_left_click |
on_interact | on_right_click |
on_hit | on_left_click |
on_tick | on_game_tick |
on_remove | on_destroy |
on_arrow_hit | on_projectile_hit |
Verifica también que el prop tenga realmente una entidad armor stand asociada. Algunas configuraciones de props pueden no producir una entidad que se pueda hacer clic.
5. Tiempo de espera agotado / Presupuesto de ejecución excedido
Síntoma: La consola muestra un mensaje como:
[Lua] my_script.lua took 73ms in 'on_game_tick' (limit: 50ms) -- script disabled to prevent lag.
El script estaba realizando demasiado trabajo en una sola llamada de hook. Causas comunes:
- Iterar sobre demasiadas entidades en
on_game_tick - Crear demasiadas partículas por tick
- Ejecutar bucles costosos sin distribuir el trabajo entre ticks
Solución: Mueve el trabajo pesado detrás de un cooldown basado en estado o usa scheduler:run_repeating() con un intervalo razonable en lugar de on_game_tick.
6. context.event es nil en un hook de clic
Esto normalmente no debería ocurrir para on_left_click y on_right_click, pero siempre protégete con:
if context.event then
context.event.cancel()
end
Dentro de los callbacks del scheduler, context.event siempre es nil -- este es el comportamiento esperado. La modificación de eventos solo puede ocurrir dentro del hook del evento mismo.
7. La animación no se reproduce
Síntoma: play_animation() devuelve false, o no ocurre nada visible.
Causas y soluciones:
-
Nombre de animación incorrecto. El nombre debe coincidir exactamente con lo definido en el archivo del modelo. Revisa tu archivo
.bbmodelo.fmmodelpara obtener el nombre correcto de la animación. -
El modelo no tiene animaciones. No todos los modelos tienen animaciones. Verifica que el archivo del modelo realmente contenga datos de animación.
-
Los jugadores no están en el rango del paquete de recursos. La animación es del lado del servidor, pero los jugadores necesitan tener cargado el paquete de recursos de FMM para ver el modelo.
8. Las partículas no aparecen
- Verifica que el nombre de la partícula sea un valor válido del enum
Particlede Bukkit en MAYÚSCULAS:"FLAME", no"flame". - Verifica que la ubicación esté en un chunk cargado. Si no hay jugadores cerca, el chunk puede estar descargado.
- Verifica que
countsea al menos 1. - Algunas partículas (como
DUST) necesitan datos adicionales específicos que elspawn_particle()básico puede no soportar. Usa partículas estándar comoFLAME,HEART,HAPPY_VILLAGER,NOTE,ENCHANT, etc.
9. El sonido no se reproduce
- Verifica que el nombre del sonido sea una constante válida del enum
Soundde Bukkit en MAYÚSCULAS. Ejemplo:"BLOCK_NOTE_BLOCK_HARP", no"block.note_block.harp". - Verifica que las coordenadas de ubicación sean correctas (no todas cero ni NaN).
- Verifica que el volumen sea mayor que 0.
10. El estado se reinicia inesperadamente
context.state es por instancia de prop y persiste durante la vida del prop. Si el estado parece reiniciarse:
- El prop puede haber sido eliminado y vuelto a generar (cada spawn crea una nueva instancia).
- Puede que estés leyendo el estado en un callback del scheduler usando la variable de contexto incorrecta. Usa siempre el parámetro de contexto propio del callback.
Cómo funciona la generación diferida de configuración
Entender el sistema de configuración diferida ayuda a evitar confusión al configurar nuevos props:
-
Primer spawn: Cuando un prop aparece y no existe un archivo
.ymlasociado, FMM crea la configuración de forma asíncrona. Esto significa que el archivo se escribe en un hilo de fondo y no está disponible inmediatamente. -
Valores predeterminados: La configuración generada tiene
isEnabled: truey una lista vacíascripts: []. -
Sin scripts en el primer spawn: Como la configuración se crea después de que el prop ya ha aparecido (y no tiene scripts listados), el prop no tendrá scripts asignados en su primer spawn.
-
Editar y volver a generar: Después de que FMM cree la configuración, la editas para agregar los nombres de tus archivos de script. La próxima vez que el prop aparezca, los scripts se cargarán.
-
Ubicación de la configuración: El archivo
.ymlse crea en el mismo directorio que el archivo del modelo, con el mismo nombre base. Por ejemplo:- Modelo:
plugins/FreeMinecraftModels/models/fountain.fmmodel - Configuración:
plugins/FreeMinecraftModels/models/fountain.yml
- Modelo:
- Coloca el modelo en
models/ - Coloca el script en
scripts/ - Genera el prop una vez (genera el
.yml) - Edita el
.ymlpara agregarscripts: [my_script.lua] - Vuelve a generar el prop -- el script ahora está activo
Lectura de mensajes de error
Cuando algo sale mal en un script Lua de prop, la consola imprime un bloque de error [Lua]. Estos mensajes te indican exactamente qué archivo, qué línea, qué hook y qué salió mal en lenguaje claro.
Un error típico se ve así:
[Lua] Error in 'my_door.lua' at line 12 during 'on_right_click':
[Lua] -> You tried to call a method or function that doesn't exist.
[Lua] -> Check the method name for typos, or make sure you're using ':' (colon) for method calls, not '.' (dot).
[Lua] -> Script has been disabled for this entity to prevent further errors.
El sistema traduce los errores comunes de Lua a lenguaje claro:
| Error Lua sin procesar | Lo que la consola te indica |
|---|---|
attempt to call nil | Intentaste llamar a un método o función que no existe. Revisa errores tipográficos y el uso de : vs. .. |
index expected, got nil | Intentaste acceder a un campo en algo que es nil. Verifica que el código anterior lo haya inicializado. |
attempt to index | Intentaste acceder a una propiedad en un valor nil o inválido. |
bad argument | Una función recibió el tipo de argumento incorrecto. El mensaje muestra el tipo esperado vs. el real. |
| Timeout | Tu script tardó Xms en 'hook_name' (límite: 50ms) -- script deshabilitado para prevenir lag. |
Siempre lee el mensaje de error [Lua] completo antes de sumergirte en el código. Generalmente te señala directamente la solución.
No asumas que existen métodos no documentados
La API Lua de FMM expone un conjunto específico de métodos. No asumas que existen nombres abreviados o alternativos. Errores comunes:
context.prop:get_location()-- no existe. Usacontext.prop.current_location(un campo, no un método).context.prop:set_animation("open")-- no existe. Usacontext.prop:play_animation("open", true, true).context.event:setCancelled(true)-- no existe. Usacontext.event.cancel().context.cooldowns:check_local(...)-- no existe en FMM. Usacontext.stateconscheduler:run_later()para cooldowns.context.player-- no existe en los scripts de props de FMM. Usacontext.world:get_nearby_players()para encontrar jugadores cerca del prop.context.boss-- no existe. Eso es de EliteMobs. Usacontext.propen FMM.
En caso de duda, consulta la página de API de Props. Si no está documentado allí, no existe.
Consejos de depuración
1. Usa context.log:info() con frecuencia
Agrega mensajes de registro en cada paso al depurar:
on_right_click = function(context)
context.log:info("Right click received!")
context.log:info("Event present: " .. tostring(context.event ~= nil))
context.log:info("State is_open: " .. tostring(context.state.is_open))
end
2. Revisa la consola al inicio
FMM registra [FMM Scripts] Bound script 'X' to prop 'Y' por cada vinculación exitosa. Si no ves este mensaje, la configuración o el script no se cargaron.
3. Verifica la ruta del archivo del modelo
La configuración .yml debe ser un archivo hermano del archivo del modelo (mismo directorio, mismo nombre base). Verifícalo revisando:
- Ruta del archivo del modelo:
plugins/FreeMinecraftModels/models/my_model.fmmodel - Ruta del archivo de configuración:
plugins/FreeMinecraftModels/models/my_model.yml
4. Prueba los hooks individualmente
Al construir un script complejo, comienza probando cada hook por separado. Agrega un hook a la vez y verifica que se active antes de pasar al siguiente.
5. Busca errores tipográficos en los nombres de hooks
La razón más común por la que un hook no se activa es un nombre de hook mal escrito. El script se cargará sin errores, pero la función de hook mal escrita será rechazada durante la validación.
Ruta de progresión para principiantes
Si quieres aprender este sistema desde cero, esta progresión funciona bien:
- Escribe un archivo con solo
api_version = 1yon_spawnque registre un mensaje. - Agrega el script a una configuración de prop y verifica que aparezca el mensaje de registro.
- Agrega
on_right_clicky registra cuando se hace clic en el prop. - Agrega
on_left_clickconcontext.event.cancel()para invulnerabilidad. - Reproduce una animación al hacer clic derecho.
- Agrega un sonido al hacer clic derecho.
- Agrega estado y comportamiento de alternancia.
- Agrega una vigilancia de zona para detección de proximidad.
- Solo entonces pasa a scripts complejos con múltiples hooks y schedulers.
Cada paso se basa en el anterior, y puedes probar en cada etapa.
Próximos pasos
- Primeros pasos -- estructura de archivos, hooks, tutorial del primer script, plantillas para copiar y pegar
- API de Props -- referencia completa de la API
- Ejemplos y patrones -- scripts funcionales completos que puedes estudiar y adaptar