Motor de Scripting Lua de MagmaCore
MagmaCore proporciona un motor de scripting Lua compartido utilizado por varios plugins de Nightbreak. El motor se encarga del sandboxing, la planificación, la gestión de zonas, la interacción con el mundo, las tablas de entidad y la UI del jugador -- todo con una API consistente entre plugins.
Actualmente, los siguientes plugins usan este motor:
- EliteMobs -- Poderes Lua para jefes personalizados (hooks como
on_boss_damaged_by_player,on_enter_combat, etc.) - FreeMinecraftModels -- Scripts Lua para props y objetos personalizados (hooks como
on_right_click,on_left_click,on_equip, etc.)
Esta página documenta las características compartidas del motor. Para hooks, APIs y flujos de trabajo específicos de cada plugin, consulta las páginas de plugin enlazadas arriba.
Mini Introducción a Lua
Si eres completamente nuevo en Lua, aquí tienes la sintaxis mínima que necesitas para escribir scripts para cualquier plugin de Nightbreak.
Variables
Usa local para almacenar un valor:
local cooldown_key = "fire_burst"
local damage_multiplier = 1.5
local significa que la variable pertenece solo a este archivo o bloque.
Funciones
Las funciones son bloques de lógica reutilizables:
local function warn_player(player)
player:send_message("&cMove!")
end
Más adelante, puedes invocarla:
warn_player(some_player)
Comprobaciones if
Usa if cuando algo solo deba ocurrir a veces:
if context.player == nil then
return
end
Eso significa "si no hay jugador para este hook, detente aquí".
nil
nil significa "ningún valor". Es la versión de Lua de "no hay nada aquí".
A menudo comprobarás nil con:
if context.event ~= nil then
-- hacer algo con el evento
end
~= significa "no es igual a".
Tablas
Lua usa tablas para varios propósitos:
- Listas
- Objetos con claves nombradas
- La definición final del script que se retorna
Ejemplo de una tabla con claves nombradas:
local particle = {
particle = "FLAME",
amount = 1,
speed = 0.05
}
Retornando la definición del script
Al final de cada archivo de script, retornas una tabla:
return {
api_version = 1,
on_spawn = function(context)
end
}
Esa tabla retornada es el archivo de script.
Comentarios
Usa -- para escribir una nota para humanos:
-- Este cooldown evita que el ataque se dispare en cada golpe
context.cooldowns:set_local(60, "fire_burst")
Sandbox de Lua
Todos los scripts Lua se ejecutan dentro de un entorno LuaJ sandboxeado. Varios globales que podrían acceder al sistema de archivos o al runtime de Java se eliminan. Las reglas del sandbox son idénticas en todos los plugins que usan MagmaCore.
Globales Eliminados
Los siguientes globales estándar de Lua se establecen a nil y no se pueden usar:
| Eliminado | Por qué |
|---|---|
debug | Expone el estado interno de la VM |
dofile | Acceso al sistema de archivos |
io | Acceso al sistema de archivos |
load | Carga arbitraria de código |
loadfile | Acceso al sistema de archivos |
luajava | Acceso directo a clases de Java |
module | Sistema de módulos (no necesario) |
os | Acceso al sistema operativo |
package | Sistema de módulos (no necesario) |
require | Sistema de módulos / acceso al sistema de archivos |
Biblioteca Estándar Disponible
Todo lo demás de la biblioteca estándar de Lua funciona con normalidad:
| Categoría | Funciones |
|---|---|
| Matemáticas | math.abs, math.ceil, math.floor, math.max, math.min, math.random, math.sin, math.cos, math.sqrt, math.pi, y todas las demás funciones math.* |
| Cadenas | string.byte, string.char, string.find, string.format, string.gsub, string.len, string.lower, string.match, string.rep, string.sub, string.upper, y todas las demás funciones string.* |
| Tablas | table.insert, table.remove, table.sort, table.concat, y todas las demás funciones table.* |
| Iteradores | pairs, ipairs, next |
| Tipo | type, tostring, tonumber, select, unpack |
| Manejo de errores | pcall, xpcall, error, assert |
| Otros | print, rawget, rawset, rawequal, rawlen, setmetatable, getmetatable |
os no está disponibleLa biblioteca os está completamente eliminada del sandbox. Si necesitas información de tiempo, usa context.world:get_time() para el tiempo del mundo o almacena marcas de tiempo en context.state usando contadores de ticks mediante el hook on_game_tick.
print escribe en la consola del servidor, pero prefiere context.log:info(msg) para la salida. Los mensajes de log se prefijan con el nombre del archivo del script, lo que facilita rastrear qué script produjo el mensaje.
Contrato del Archivo
Cada script Lua debe return una tabla. Esa tabla es intencionadamente estricta.
Campos de Nivel Superior Requeridos y Opcionales
| Campo | Requerido | Tipo | Notas |
|---|---|---|---|
api_version | Sí | Number | Actualmente debe ser 1 |
priority | No | Number | Prioridad de ejecución. Los valores más bajos se ejecutan primero. Por defecto 0 |
| claves de hooks soportadas | No | Function | Deben usar uno de los nombres exactos de hooks soportados por el plugin |
Reglas de Validación
- El archivo debe retornar una tabla.
api_versiones requerido y actualmente debe ser1.prioritydebe ser numérico si está presente.- Cada clave extra de nivel superior debe ser un nombre de hook soportado.
- Cada clave de hook debe apuntar a una función.
- Las claves de nivel superior desconocidas se rechazan.
Las funciones auxiliares y las constantes locales deben vivir encima del return final, no dentro de la tabla retornada salvo que sean hooks reales.
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)
do_something(context)
end
}
Hooks Compartidos del Motor
Los siguientes hooks están disponibles para todos los plugins que usan el motor de scripting de MagmaCore. Los plugins individuales añaden sus propios hooks encima de estos.
| Hook | Cuándo se dispara |
|---|---|
on_spawn | Se llama una vez cuando se crea la instancia del script (la entidad aparece o el prop se coloca) |
on_game_tick | Se llama cada tick del servidor mientras la entidad esté viva/activa |
on_zone_enter | Se llama cuando un jugador entra en una zona vigilada |
on_zone_leave | Se llama cuando un jugador sale de una zona vigilada |
Sintaxis de Métodos: : vs .
En Lua, object:method(arg) es una forma abreviada de object.method(object, arg). La API de MagmaCore acepta ambas formas, así que cualquiera funciona:
context.log:info("hello")
context.log.info("hello") -- lo mismo
Toda la documentación usa : de forma consistente.
Presupuesto de Ejecución
Cada invocación de hook y cada invocación de callback se cronometra. Si una sola llamada tarda más de 50 milisegundos, el script se deshabilita 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 los hooks.
- Mantén los manejadores de
on_game_tickligeros -- se ejecutan en cada tick. - Usa
context.scheduler:run_repeating(...)para repartir el trabajo entre ticks. - Mueve el trabajo costoso detrás de un cooldown basado en estado o un intervalo razonable.
Si un script Lua lanza un error en tiempo de ejecución en cualquier hook o callback planificado, la instancia del script se deshabilita inmediata y permanentemente para esa entidad. Corrige el error en tu archivo de script -- el script se reinicializará en el próximo spawn de entidad.
context.state
Una tabla Lua simple que persiste durante toda la vida útil de la instancia del script. Ú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
Solo context.state persiste entre llamadas de hooks. Todas las demás tablas de context (context.prop, context.world, context.event, etc.) se reconstruyen frescas cada vez. context.state no se reconstruye -- sobrevive desde el momento en que se crea la instancia del script hasta que se destruye.
context.log
Métodos de logging en consola. Los mensajes se prefijan con el nombre del archivo del script en la consola del servidor.
| Método | Notas |
|---|---|
log:info(message) | Mensaje informativo |
log:warn(message) | Mensaje de advertencia |
log:error(message) | Mensaje de nivel warning (registrado a nivel WARN, igual que log:warn) |
El context.log de EliteMobs registra debug en lugar de error. Usa log:debug(message) para la salida de depuración (aparece a nivel info con un prefijo debug).
context.log:info("Script loaded!")
context.log:warn("Something unexpected happened")
context.log:error("Critical failure in zone setup")
context.cooldowns
La tabla cooldowns gestiona los cooldowns basados en tiempo de tus scripts. Hay dos ámbitos:
- Los cooldowns locales son por instancia de script e identificados por una clave de cadena. Si no se proporciona una clave, se usa el nombre del archivo del script como clave por defecto.
- Los cooldowns globales se comparten entre todos los scripts de la misma entidad propietaria (por ejemplo, todos los scripts del mismo prop, o todos los poderes Lua del mismo jefe).
cooldowns:check_local(key?, duration)
El método más común. Comprueba si el cooldown está listo, y si lo está, lo inicia y devuelve true. Si no está listo, devuelve false. Es una comprobación-y-establecimiento atómica — sin condiciones de carrera.
| Parámetro | Tipo | Notas |
|---|---|---|
key | string (opcional) | Identificador del cooldown. Por defecto, el nombre del archivo del script. |
duration | int | Duración del cooldown en ticks (20 = 1 segundo) |
on_right_click = function(context)
-- Solo permite esta acción una vez cada 3 segundos
if not context.cooldowns:check_local("interact", 60) then
return
end
-- ... ejecutar la acción
end
cooldowns:local_ready(key?)
Devuelve true si el cooldown local ha expirado (o nunca se estableció), false si sigue activo.
cooldowns:local_remaining(key?)
Devuelve el número de ticks restantes en el cooldown local, o 0 si está listo.
cooldowns:set_local(duration, key?)
Establece un cooldown local sin comprobar si ya hay uno activo. Úsalo para reinicios incondicionales de cooldown.
| Parámetro | Tipo | Notas |
|---|---|---|
duration | int | Duración en ticks. Pasa 0 o un valor negativo para limpiar. |
key | string (opcional) | Identificador del cooldown. Por defecto, el nombre del archivo del script. |
cooldowns:global_ready()
Devuelve true si el cooldown global (compartido entre todos los scripts de la misma entidad) ha expirado.
cooldowns:set_global(duration)
Establece el cooldown global.
| Parámetro | Tipo | Notas |
|---|---|---|
duration | int | Duración en ticks |
El "propietario" de un cooldown global depende del tipo de script:
- Poderes Lua de EliteMobs — compartidos por
EliteEntity(un cubo por jefe).global_ready()/set_global()usan el sistema integrado de cooldowns de poderes del jefe; los cooldowns locales también se comparten entre todos los poderes del mismo jefe. - Scripts de prop de FMM — compartidos por
PropEntity(un cubo por prop colocado). - Scripts de objeto de FMM — compartidos por UUID de jugador (un cubo por jugador). Los cooldowns locales en objetos persisten entre ciclos de equipar/desequipar, indexados por
playerUUID → "itemId:scriptFile" → key, de modo que un cooldown sobrevive a que el jugador saque el objeto de su hotbar y vuelva a meterlo.
context.scheduler
El planificador te permite ejecutar tareas retrasadas y repetidas. Todas las tareas son propiedad de la instancia del script y se cancelan automáticamente cuando la instancia del script se destruye (por ejemplo, cuando se retira un prop o muere un jefe).
scheduler:run_later(ticks, callback)
Ejecuta un callback una vez tras un retraso. Devuelve un ID numérico de tarea.
| Parámetro | Tipo | Notas |
|---|---|---|
ticks | int | Retraso en ticks del servidor (20 ticks = 1 segundo) |
callback | function | Llamada con un context fresco cuando expira el retraso |
context.scheduler:run_later(40, function(delayed_context)
delayed_context.log:info("2 seconds have passed!")
end)
scheduler:run_repeating(delay, interval, callback)
Ejecuta un callback repetidamente en un intervalo fijo. Devuelve un ID numérico de tarea.
| Parámetro | Tipo | Notas |
|---|---|---|
delay | int | Retraso inicial en ticks antes de la primera ejecución |
interval | int | Ticks entre cada ejecución posterior |
callback | function | Llamada con un context fresco en cada intervalo |
context.state.particle_task = context.scheduler:run_repeating(0, 20, function(tick_context)
tick_context.log:info("Another second passed!")
end)
scheduler:cancel(taskId)
Cancela una tarea planificada por su ID.
| Parámetro | Tipo | Notas |
|---|---|---|
taskId | int | El ID de tarea devuelto por run_later o run_repeating |
Si inicias una tarea repetida, cancélala siempre en tu hook de limpieza (on_destroy para props, on_exit_combat / on_death para jefes, on_unequip para objetos). Olvidar cancelarla deja una tarea en segundo plano ejecutándose hasta que se destruya la instancia del script, lo que desperdicia rendimiento y puede causar errores.
Los callbacks planificados reciben un context fresco como su parámetro. Usa siempre el argumento context propio del callback, no el context externo del hook que creó el callback. El context externo puede contener referencias obsoletas.
context.world
La tabla world proporciona métodos para consultar e interactuar con el mundo de Minecraft. Se construye a partir del mundo actual de la entidad.
EliteMobs extiende context.world con métodos adicionales para generar jefes, refuerzos, falling blocks, fuegos artificiales, splash potions y bloques temporales. Consulta Mundo y Entorno de EliteMobs para la API extendida completa. Los métodos documentados aquí están disponibles en todos los plugins.
world.name
Un campo de cadena 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 cadena en minúsculas (por ejemplo, "stone", "air").
| Parámetro | Tipo | Notas |
|---|---|---|
x | int | Coordenada X del bloque |
y | int | Coordenada Y del bloque |
z | int | Coordenada Z del bloque |
world:set_block_at(x, y, z, material)
Establece el bloque en las coordenadas dadas. Se ejecuta en el hilo principal.
| Parámetro | Tipo | Notas |
|---|---|---|
x | int | Coordenada X del bloque |
y | int | Coordenada Y del bloque |
z | int | Coordenada Z del bloque |
material | string | Nombre del Material de Bukkit, en minúsculas (por ejemplo, "stone", "air", "oak_planks") |
Devuelve true si el bloque se estableció correctamente, false en caso contrario.
world:spawn_particle(particle, x, y, z, count, dx, dy, dz, speed)
Genera partículas en una ubicación.
| Parámetro | Tipo | Por defecto | Notas |
|---|---|---|---|
particle | string | requerido | Nombre del enum Particle de Bukkit, EN MAYÚSCULAS (por ejemplo, "FLAME", "DUST") |
x | number | requerido | Coordenada X |
y | number | requerido | Coordenada Y |
z | number | requerido | Coordenada Z |
count | int | 1 | Número de partículas |
dx | number | 0 | Dispersión/offset X |
dy | number | 0 | Dispersión/offset Y |
dz | number | 0 | Dispersión/offset Z |
speed | number | 0 | Velocidad de la partícula |
Algunos tipos de partículas requieren datos de bloque o de objeto que no son soportados por esta API simple. BLOCK_CRACK, FALLING_DUST, BLOCK_DUST e ITEM_CRACK fallarán o no producirán un efecto visible. Usa alternativas sin datos en su lugar: CLOUD, SMOKE, CAMPFIRE_COSY_SMOKE, SNOWFLAKE, FLAME, DUST, etc.
world:play_sound(sound, x, y, z, volume, pitch)
Reproduce un sonido en una ubicación.
| Parámetro | Tipo | Por defecto | Notas |
|---|---|---|---|
sound | string | requerido | Nombre del enum Sound de Bukkit, EN MAYÚSCULAS (por ejemplo, "ENTITY_EXPERIENCE_ORB_PICKUP") |
x | number | requerido | Coordenada X |
y | number | requerido | Coordenada Y |
z | number | requerido | Coordenada Z |
volume | number | 1.0 | Volumen |
pitch | number | 1.0 | Tono |
world:strike_lightning(x, y, z)
Lanza un rayo en una ubicación (visual y dañino).
| Parámetro | Tipo | Notas |
|---|---|---|
x | number | Coordenada X |
y | number | Coordenada Y |
z | number | Coordenada Z |
world:get_time()
Devuelve el tiempo actual del mundo en ticks.
world:set_time(ticks)
Establece el tiempo del mundo.
| Parámetro | Tipo | Notas |
|---|---|---|
ticks | int | Tiempo del mundo (0 = amanecer, 6000 = mediodía, 13000 = noche, 18000 = medianoche) |
world:get_nearby_entities(x, y, z, radius)
Devuelve un array de tablas envoltorio de entidades para todas las entidades dentro de una caja delimitadora centrada en las coordenadas dadas.
| Parámetro | Tipo | Notas |
|---|---|---|
x | number | Centro X |
y | number | Centro Y |
z | number | Centro Z |
radius | number | Radio de búsqueda (utilizado como semi-extensión en los tres ejes) |
Esto devuelve TODAS las entidades en el rango, incluidas las entidades no vivientes (armor stands, objetos soltados, etc.). Protege siempre con if entity.damage then antes de llamar a métodos de entidad viviente.
world:get_nearby_players(x, y, z, radius)
Devuelve un array de tablas envoltorio de jugador para todos los jugadores dentro de una caja delimitadora centrada en las coordenadas dadas.
| Parámetro | Tipo | Notas |
|---|---|---|
x | number | Centro X |
y | number | Centro Y |
z | number | Centro Z |
radius | number | Radio de búsqueda |
world:spawn_entity(entity_type, x, y, z)
Genera una entidad vanilla de Minecraft en la ubicación dada.
| Parámetro | Tipo | Notas |
|---|---|---|
entity_type | string | Nombre del tipo de entidad de Bukkit, en minúsculas (por ejemplo, "zombie", "skeleton", "pig") |
x | number | Coordenada X |
y | number | Coordenada Y |
z | number | Coordenada Z |
Devuelve una tabla de entidad para la entidad generada (con métodos de entidad viviente si aplica), o nil si el tipo de entidad es inválido.
world:get_highest_block_y(x, z)
Devuelve la coordenada Y del bloque no-aire más alto en la posición X/Z dada.
| Parámetro | Tipo | Notas |
|---|---|---|
x | int | Coordenada X del bloque |
z | int | Coordenada Z del bloque |
world:raycast(from_x, from_y, from_z, dir_x, dir_y, dir_z, [max_distance])
Lanza un rayo desde un punto en una dirección y devuelve información sobre lo que golpea.
| Parámetro | Tipo | Por defecto | Notas |
|---|---|---|---|
from_x | number | requerido | Origen X |
from_y | number | requerido | Origen Y |
from_z | number | requerido | Origen Z |
dir_x | number | requerido | Componente X de la dirección |
dir_y | number | requerido | Componente Y de la dirección |
dir_z | number | requerido | Componente Z de la dirección |
max_distance | number | 50 | Distancia máxima del rayo |
Devuelve una tabla con los siguientes campos:
| Campo | Tipo | Notas |
|---|---|---|
hit_entity | tabla entidad o nil | La primera entidad alcanzada por el rayo, o nil si ninguna |
hit_location | tabla location o nil | El punto exacto donde el rayo golpeó algo |
hit_block | tabla o nil | {x, y, z, material} del bloque golpeado, o nil si no se golpeó ningún bloque |
world:spawn_firework(x, y, z, colors, [type], [power])
Genera un cohete de fuegos artificiales en la ubicación dada.
| Parámetro | Tipo | Por defecto | Notas |
|---|---|---|---|
x | number | requerido | Coordenada X |
y | number | requerido | Coordenada Y |
z | number | requerido | Coordenada Z |
colors | tabla | requerido | Array de cadenas de color, por ejemplo, {"RED", "BLUE", "WHITE"} |
type | string | "BALL" | Forma del fuego artificial: "BALL", "BALL_LARGE", "STAR", "BURST", "CREEPER" |
power | int | 1 | Potencia de vuelo, 0-127 |
-- Ejemplo: explosión de fuegos artificiales rojos y dorados
context.world:spawn_firework(loc.x, loc.y, loc.z, {"RED", "GOLD"}, "BURST", 2)
world:place_temporary_block(x, y, z, material, [ticks], [require_air])
Coloca un bloque que se revierte automáticamente a su estado original tras un retraso.
| Parámetro | Tipo | Por defecto | Notas |
|---|---|---|---|
x | int | requerido | Coordenada X del bloque |
y | int | requerido | Coordenada Y del bloque |
z | int | requerido | Coordenada Z del bloque |
material | string | requerido | Nombre del Material de Bukkit (por ejemplo, "stone", "ice") |
ticks | int | 0 | Duración en ticks antes de que el bloque revierta. 0 significa permanente. |
require_air | boolean | false | Si es true, solo coloca el bloque si el destino es aire |
Devuelve true si se colocó el bloque, false si el material era inválido o no se cumplió el requisito de aire.
world:drop_item(x, y, z, material, [amount])
Suelta una entidad de objeto en la ubicación dada con dispersión natural.
| Parámetro | Tipo | Por defecto | Notas |
|---|---|---|---|
x | number | requerido | Coordenada X |
y | number | requerido | Coordenada Y |
z | number | requerido | Coordenada Z |
material | string | requerido | Nombre del Material de Bukkit |
amount | int | 1 | Tamaño de la pila |
Devuelve una tabla de entidad para el objeto soltado, o nil si el material era inválido.
context.zones
La tabla zones te 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 destruye la instancia del script.
zones:create_sphere(x, y, z, radius)
Crea una zona esférica centrada en las coordenadas dadas. Devuelve un handle numérico de zona.
| Parámetro | Tipo | Notas |
|---|---|---|
x | number | Centro X |
y | number | Centro Y |
z | number | Centro Z |
radius | number | Radio de la esfera |
zones:create_cylinder(x, y, z, radius, height)
Crea una zona cilíndrica. Devuelve un handle numérico de zona.
| Parámetro | Tipo | Notas |
|---|---|---|
x | number | Centro X |
y | number | Centro Y (base) |
z | number | Centro Z |
radius | number | Radio del cilindro |
height | number | Altura del cilindro |
zones:create_cuboid(x, y, z, xSize, ySize, zSize)
Crea una zona cuboide. Devuelve un handle numérico de zona.
| Parámetro | Tipo | Notas |
|---|---|---|
x | number | Centro X |
y | number | Centro Y |
z | number | Centro Z |
xSize | number | Semi-extensión en X |
ySize | number | Semi-extensión en Y |
zSize | number | Semi-extensión en Z |
zones:watch(handle, onEnterCallback, onLeaveCallback)
Comienza a vigilar una zona para eventos de entrada/salida de jugadores. Los parámetros del callback actúan como señales booleanas — pasar un valor no-nulo (por ejemplo, una función o true) habilita el hook correspondiente en el script. Los propios callbacks no se invocan directamente. En su lugar, la lógica de entrada/salida se dispara mediante los hooks on_zone_enter / on_zone_leave del script.
| Parámetro | Tipo | Notas |
|---|---|---|
handle | int | Handle de zona de una llamada create_* |
onEnterCallback | cualquier no-nulo o nil | No-nulo habilita el hook on_zone_enter para esta zona |
onLeaveCallback | cualquier no-nulo o nil | No-nulo habilita el hook on_zone_leave para esta zona |
Devuelve true si la vigilancia se configuró correctamente, nil si el handle de zona era inválido.
Las vigilancias de zona se comprueban cada tick del servidor contra todos los jugadores en el mismo mundo. Mantén la cuenta de zonas razonable para evitar sobrecarga de rendimiento.
zones:unwatch(handle)
Detiene la vigilancia de una zona y limpia sus recursos.
| Parámetro | Tipo | Notas |
|---|---|---|
handle | int | Handle de zona para dejar de vigilar |
Ejemplo: Zona disparada por proximidad
return {
api_version = 1,
on_spawn = function(context)
local loc = context.prop.current_location -- o context.boss:get_location()
if loc == nil then return end
local handle = context.zones:create_sphere(loc.x, loc.y, loc.z, 5)
-- Pasa valores no-nulos para habilitar los hooks on_zone_enter y on_zone_leave.
-- Son señales booleanas, no callbacks — la lógica real va en los hooks de abajo.
context.zones:watch(handle, true, true)
context.state.zone_handle = handle
end,
on_zone_enter = function(context)
context.log:info("Player entered zone!")
end,
on_zone_leave = function(context)
context.log:info("Player left zone!")
end,
on_destroy = function(context)
if context.state.zone_handle then
context.zones:unwatch(context.state.zone_handle)
end
end
}
context.event
La tabla event está presente cuando el hook actual se desencadenó por un evento de juego (por ejemplo, on_right_click, on_zone_enter). No está presente durante on_game_tick ni en callbacks planificados.
| Campo / Método | Tipo | Notas |
|---|---|---|
is_cancelled | boolean | Si el evento ha sido cancelado |
cancel() | method | Cancela el evento (evita el comportamiento por defecto) |
uncancel() | method | Des-cancela un evento previamente cancelado |
player | tabla entidad | El jugador involucrado en el evento, si lo hay |
on_right_click = function(context)
if context.event then
context.event:cancel() -- evita la interacción por defecto del clic derecho
end
end
Los scripts de poder de EliteMobs tienen una tabla de eventos más detallada con cantidades de daño, causas de daño, referencias del dañador y métodos de modificación de daño. Consulta Referencia de la API de Lua para los campos completos de eventos de EliteMobs.
Namespace de Ayuda em
La tabla em está disponible en el momento de carga del archivo (antes de que se ejecute cualquier hook). Proporciona constructores auxiliares para construir tablas de ubicación, tablas de vector y definiciones de zona usadas a lo largo de la API.
| Función | Propósito |
|---|---|
em.create_location(x, y, z [, world, yaw, pitch]) | Crea una tabla de ubicación con nombre de mundo, yaw y pitch opcionales. La tabla devuelta también tiene un método .add(dx, dy, dz) que desplaza la ubicación en su lugar y se devuelve a sí misma para encadenamiento. |
em.create_vector(x, y, z) | Crea una tabla de vector |
em.zone.create_sphere_zone(radius) | Crea una definición de zona esférica |
em.zone.create_dome_zone(radius) | Crea una definición de zona de cúpula |
em.zone.create_cylinder_zone(radius, height) | Crea una definición de zona cilíndrica |
em.zone.create_cuboid_zone(x, y, z) | Crea una definición de zona cuboide |
em.zone.create_cone_zone(length, radius) | Crea una definición de zona cónica |
em.zone.create_static_ray_zone(length, thickness) | Crea una definición de zona de rayo estático |
em.zone.create_rotating_ray_zone(length, point_radius, animation_duration) | Crea una definición de zona de rayo rotatorio |
em.zone.create_translating_ray_zone(length, point_radius, animation_duration) | Crea una definición de zona de rayo trasladante |
em.location.is_in_dungeon(loc) | Comprueba si una ubicación está dentro de alguna región de dungeon registrada |
em.location.is_protected(loc) | Comprueba si una ubicación está dentro de alguna región protegida (WorldGuard, GriefPrevention, regiones de EM, etc.) |
em.location.owned_by(loc, namespace) | Comprueba si un namespace de plugin específico posee la ubicación (por ejemplo, "EliteMobs") |
em.location.owners(loc) | Array de cadenas de namespace que poseen la ubicación |
em.location.kinds_at(loc) | Array de etiquetas de tipo en la ubicación ("elitemobs", "world_package", "open_world_dungeon", categoría de tamaño de dungeon) |
em.location.has_kind(loc, kind) | Comprueba si la ubicación está etiquetada con el tipo dado |
Los constructores de zonas devuelven tablas encadenables con :set_center(loc) (o :set_origin(loc) / :set_destination(loc) dependiendo del tipo de zona):
-- A nivel de archivo: crear una forma de zona reutilizable
local blast_zone = em.zone.create_sphere_zone(5)
return {
api_version = 1,
on_spawn = function(context)
-- Anclar la zona en el momento de la llamada
blast_zone:set_center(context.boss:get_location())
local entities = context.zones:get_entities_in_zone(blast_zone)
-- ...
end
}
El namespace em es particularmente útil en EliteMobs, donde las definiciones de zona se usan con context.zones:get_entities_in_zone() y context.script. En FreeMinecraftModels, los métodos context.zones:create_sphere(...) / create_cylinder(...) / create_cuboid(...) se usan más comúnmente para zonas simples basadas en vigilancia.
Tablas de Entidad
Las tablas de entidad se devuelven de consultas del mundo, datos de eventos y callbacks de zona. Proporcionan un conjunto en capas de campos y métodos según el tipo de entidad.
Campos Base de Entidad
| Campo | Tipo | Notas |
|---|---|---|
uuid | string | El UUID de la entidad |
entity_type | string | El tipo de entidad (por ejemplo, "player", "zombie", "skeleton", "villager") |
is_valid | boolean | Si la referencia de la entidad sigue siendo válida |
is_dead | boolean | Si la entidad está muerta |
is_player | boolean | Si la entidad es un jugador |
is_hostile | boolean | Si la entidad es un mob hostil (zombie, esqueleto, etc.) |
is_passive | boolean | Si la entidad es un mob pasivo (vaca, cerdo, gallina, etc.) |
current_location | tabla location | La posición actual de la entidad (x, y, z, world, yaw, pitch) |
world | string | El nombre del mundo en el que se encuentra la entidad |
Métodos Base de Entidad
| Método | Devuelve | Notas |
|---|---|---|
teleport(location_table) | void | Teletransporta la entidad. La tabla de ubicación debe tener los campos x, y, z, world; yaw y pitch son opcionales. |
remove() | void | Elimina la entidad del mundo. Solo actúa si la entidad sigue siendo válida. |
set_silent(flag) | void | Suprime o vuelve a habilitar los sonidos de la entidad. |
set_invulnerable(flag) | void | Hace que la entidad sea invulnerable o vulnerable al daño. |
set_gravity(flag) | void | Habilita o deshabilita la gravedad de la entidad. |
set_glowing(flag) | void | Alterna el efecto de contorno brillante sobre la entidad. |
Campos de Entidad Viviente
Las entidades vivientes (jugadores, mobs, etc.) tienen todos los campos base de entidad más:
| Campo | Tipo | Notas |
|---|---|---|
health | number | Salud actual |
maximum_health | number | Salud máxima |
name | string | Nombre mostrado |
is_alive | boolean | Si la entidad está viva |
Métodos de Entidad Viviente
| Método | Devuelve | Notas |
|---|---|---|
damage(amount) | void | Inflige la cantidad dada de daño a la entidad |
push(x, y, z) | void | Aplica un impulso de velocidad |
set_facing(x, y, z) | void | Establece la dirección a la que mira la entidad |
add_potion_effect(effect, duration, amplifier) | void | Añade un efecto de poción. effect es una cadena (por ejemplo, "speed", "slowness", "regeneration"). duration está en ticks. amplifier es el nivel del efecto menos 1 (0 = nivel I). |
remove_potion_effect(effect) | void | Elimina un efecto de poción por nombre |
get_scale() | number | Devuelve la escala actual de la entidad (por defecto 1.0 en servidores sin el atributo generic.scale) |
set_scale(value) | void | Establece la escala de la entidad mediante el atributo generic.scale. Sin efecto en servidores anteriores a 1.20.5. |
No todas las entidades devueltas por get_nearby_entities() son entidades vivientes. Puedes usar entity.is_player, entity.is_hostile o entity.is_passive para filtrar por categoría, o comprobar if entity.damage then antes de llamar a métodos de entidad viviente como damage(), push() o add_potion_effect().
Campos de Integración con Plugins
Las tablas de entidad incluyen automáticamente campos para detectar e interactuar con entidades gestionadas por otros plugins de Nightbreak. Estos campos solo se rellenan cuando el plugin relevante está instalado -- de lo contrario, por defecto son false / nil sin sobrecarga.
Campos de EliteMobs
Disponible cuando EliteMobs está instalado.
| Campo | Tipo | Notas |
|---|---|---|
is_elite | boolean | Si la entidad es un elite de EliteMobs |
is_custom_boss | boolean | Si la entidad es un jefe personalizado de EliteMobs (también disponible dentro de la subtabla elite) |
is_significant_boss | boolean | Si la entidad es un jefe personalizado con un multiplicador de salud superior a 1 (es decir, un encuentro diseñado, no un elite de relleno) |
elite | tabla o nil | Subtabla de información del elite (ver abajo). nil si la entidad no es un elite. |
La subtabla elite contiene:
| Campo | Tipo | Notas |
|---|---|---|
elite.level | int | El nivel del elite |
elite.name | string | El nombre mostrado del elite |
elite.health | number | Salud actual |
elite.max_health | number | Salud máxima |
elite.is_custom_boss | boolean | Si es un jefe personalizado (en oposición a un elite natural) |
elite.health_multiplier | number | Multiplicador de salud definido en la configuración |
elite.damage_multiplier | number | Multiplicador de daño definido en la configuración |
elite:remove() | void | Elimina el elite mediante el pipeline de eliminación adecuado de EliteMobs (limpia tracking, botín, etc.) |
Ejemplo: Dañar elites de forma diferente
local entities = context.world:get_nearby_entities(x, y, z, 5)
for _, entity in ipairs(entities) do
if entity.is_elite then
-- Inflige el doble de daño a elites
entity:damage(20)
context.log:info("Hit elite: " .. entity.elite.name .. " (level " .. entity.elite.level .. ")")
elseif entity.is_hostile then
entity:damage(10)
end
end
Campos de FreeMinecraftModels
Disponible cuando FreeMinecraftModels está instalado.
| Campo | Tipo | Notas |
|---|---|---|
is_modeled | boolean | Si la entidad tiene un modelo FMM adjunto (DynamicEntity o PropEntity) |
is_prop | boolean | Si la entidad es un prop de FMM (entidad decorativa estática) |
model | tabla o nil | Subtabla de información del modelo (ver abajo). nil si la entidad no está modelada. |
La subtabla model contiene:
| Campo | Tipo | Notas |
|---|---|---|
model.model_id | string | El ID del blueprint del modelo (por ejemplo, "torch_01") |
model.is_dynamic | boolean | Si la entidad modelada es una DynamicEntity (modelo de mob/jefe) en lugar de un prop estático |
model:play_animation(name, [blend], [loop]) | boolean | Reproduce una animación con nombre. blend por defecto es false, loop por defecto es false. Devuelve true si se encontró la animación. |
model:stop_animations() | void | Detiene todas las animaciones que se estén reproduciendo actualmente en el modelo. |
model:remove() | void | Elimina la entidad modelada mediante el pipeline de eliminación adecuado de FMM. |
El bridge de modelo (disponible en cualquier entidad) tiene por defecto blend y loop en false. El tabla prop play_animation tiene ambos por defecto en true porque los props normalmente quieren animaciones mezcladas y en bucle.
Ejemplo: Filtrar entidades por tipo
local entities = context.world:get_nearby_entities(x, y, z, 10)
for _, entity in ipairs(entities) do
if entity.is_prop then
-- Omitir props
elseif entity.is_player then
entity:damage(5)
elseif entity.entity_type == "villager" then
-- No herir aldeanos
elseif entity.is_elite then
entity:damage(20)
elseif entity.is_hostile then
entity:damage(10)
end
end
Campos Específicos del Jugador
Las entidades de jugador tienen todos los campos de entidad y entidad viviente más:
| Campo | Tipo | Notas |
|---|---|---|
game_mode | string | El modo de juego del jugador ("creative", "survival", "adventure", "spectator") |
Métodos Específicos del Jugador
| Método | Devuelve | Notas |
|---|---|---|
send_message(msg) | void | Envía un mensaje de chat al jugador. Admite códigos de color &. |
get_held_item() | tabla o nil | Devuelve {type, amount, display_name} para el objeto en la mano principal del jugador, o nil si está vacía |
consume_held_item(amount?) | void | Consume objetos de la mano principal del jugador. amount por defecto es 1 |
has_item(material, amount?) | boolean | Devuelve true si el jugador tiene al menos amount (por defecto 1) del material dado en cualquier parte de su inventario |
get_target_entity([range]) | tabla entidad o nil | Devuelve la entidad a la que mira el jugador mediante raycast, o nil si ninguna. El rango por defecto es 50. |
get_eye_location() | tabla location | Devuelve una tabla de ubicación a la altura de los ojos del jugador |
get_look_direction() | tabla | Devuelve un vector de dirección {x, y, z} para hacia donde mira el jugador |
send_block_change(x, y, z, material, [ticks]) | boolean | Envía un bloque falso visible solo para este jugador. Si se proporciona ticks, el bloque falso se restablece automáticamente tras esa duración. Devuelve true en éxito, false si el material es inválido. |
reset_block(x, y, z) | boolean | Restablece un bloque falso al bloque real para este jugador. Siempre devuelve true. |
sleep(x, y, z) | void | Hace que el jugador entre en una animación de dormir en cama en las coordenadas dadas. El bloque se restaura automáticamente cuando el jugador deja de dormir. |
wake_up() | void | Despierta a un jugador dormido. |
Métodos de UI del Jugador
Estos métodos están disponibles en cualquier tabla de entidad jugador y proporcionan formas de mostrar información al jugador mediante los elementos de UI integrados de Minecraft.
player:show_boss_bar(text, [color], progress, [ticks])
Muestra una barra de jefe al jugador.
| Parámetro | Tipo | Por defecto | Notas |
|---|---|---|---|
text | string | requerido | El texto a mostrar. Admite códigos de color &. |
color | string | "WHITE" | Color de la barra. Uno de: "RED", "BLUE", "GREEN", "YELLOW", "PURPLE", "PINK", "WHITE" |
progress | number | requerido | Cantidad de relleno desde 0.0 (vacío) hasta 1.0 (lleno) |
ticks | int | nil | Retraso opcional de auto-cierre en ticks. Si se omite, la barra permanece hasta que se oculta manualmente. |
player:hide_boss_bar()
Elimina la barra de jefe de la pantalla del jugador. No toma parámetros.
player:show_action_bar(text, [ticks])
Muestra texto en el área de la barra de acción (sobre el hotbar).
| Parámetro | Tipo | Por defecto | Notas |
|---|---|---|---|
text | string | requerido | El texto a mostrar. Admite códigos de color &. |
ticks | int | nil | Duración opcional en ticks. Si se proporciona, el mensaje se reenvía cada 40 ticks para mantenerlo visible durante toda la duración. |
player:show_title(title, [subtitle], fade_in, stay, fade_out)
Muestra una pantalla de título al jugador.
| Parámetro | Tipo | Por defecto | Notas |
|---|---|---|---|
title | string | requerido | Texto principal del título. Admite códigos de color &. |
subtitle | string | "" | Texto del subtítulo debajo del título principal. Opcional. |
fade_in | int | requerido | Duración del fundido de entrada en ticks |
stay | int | requerido | Cuánto tiempo permanece el título en pantalla en ticks |
fade_out | int | requerido | Duración del fundido de salida en ticks |
Siguientes Pasos
Para hooks, APIs y flujos de trabajo específicos de cada plugin:
- EliteMobs: Primeros Pasos | Hooks y Ciclo de Vida | Jefes y Entidades | Mundo y Entorno | Zonas y Targeting
- FreeMinecraftModels: Primeros Pasos | API de Prop y Objeto | Ejemplos