Scripting Lua: API de Props
Esta página cobre todas as APIs disponíveis para scripts de props do FreeMinecraftModels: context.prop, context.event, context.world, context.zones, context.scheduler, context.state e context.log. Se você é novo em scripting de props, comece primeiro com Primeiros Passos.
context.prop
A tabela prop fornece informações sobre a entidade do prop e métodos para controlar suas animações. Ela é reconstruída a cada chamada de hook.
Campos
| Campo | Tipo | Notas |
|---|---|---|
prop.model_id | string | O nome do modelo blueprint (ex.: "torch_01") |
prop.current_location | location table | A posição do prop no momento em que o contexto foi construído |
A tabela de localização possui os campos padrão: x, y, z, world, yaw, pitch.
Exemplo: lendo informações do 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)
Reproduz uma animação nomeada no modelo do prop.
| Parâmetro | Tipo | Padrão | Notas |
|---|---|---|---|
name | string | obrigatório | O nome da animação conforme definido no arquivo do modelo |
blend | boolean | true | Se deve mesclar com a animação atual |
loop | boolean | true | Se a animação repete em loop |
Retorna true se a animação foi encontrada e iniciada, false caso contrário.
Exemplo
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()
Para todas as animações sendo reproduzidas atualmente no prop.
Não recebe parâmetros.
Exemplo
return {
api_version = 1,
on_right_click = function(context)
context.prop:stop_animation()
end
}
context.event
Dados do evento para o hook atual. Disponível em on_left_click, on_right_click e on_projectile_hit. Retorna nil em hooks que não possuem evento associado (on_spawn, on_game_tick, on_destroy, on_zone_enter, on_zone_leave).
Campos e métodos
| Campo ou método | Tipo | Notas |
|---|---|---|
event.is_cancelled | boolean | Se o evento está atualmente cancelado |
event.cancel() | function | Cancela o evento (ex.: impede dano ou interação) |
event.uncancel() | function | Reverte o cancelamento de um evento previamente cancelado |
Nem todos os eventos são canceláveis. Se o evento Bukkit subjacente não implementa Cancellable, event.cancel() e event.uncancel() não estarão presentes e event.is_cancelled será sempre false.
Exemplo: Tornando um prop invulnerável
Exemplo
return {
api_version = 1,
on_left_click = function(context)
if context.event then
context.event.cancel()
end
end
}
Exemplo: Verificando o estado de cancelamento
Exemplo
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 agendados (scheduler:run_later, scheduler:run_repeating), context.event é sempre nil. A modificação de eventos só pode acontecer durante o próprio hook do evento.
context.world
A tabela world fornece métodos para consultar e interagir com o mundo do Minecraft. Ela é construída a partir do mundo atual do prop.
A API context.world é compartilhada com o EliteMobs. Props do FMM usam a mesma tabela world do Magmacore que os bosses do EliteMobs. Os métodos documentados aqui são os disponíveis na implementação base do Magmacore. Para a referência completa, consulte a página EliteMobs World & Environment -- os métodos listados lá como parte da API base context.world também estão disponíveis no FMM.
world.name
Um campo string contendo o nome do mundo.
world:get_block_at(x, y, z)
Retorna o nome do material do bloco nas coordenadas fornecidas como uma string em minúsculas (ex.: "stone", "air").
| Parâmetro | Tipo | Notas |
|---|---|---|
x | int | Coordenada X do bloco |
y | int | Coordenada Y do bloco |
z | int | Coordenada Z do bloco |
Exemplo
return {
api_version = 1,
on_spawn = function(context)
local loc = context.prop.current_location
if loc then
local block = context.world:get_block_at(
math.floor(loc.x),
math.floor(loc.y) - 1,
math.floor(loc.z)
)
context.log:info("Prop is standing on: " .. block)
end
end
}
world:spawn_particle(particle, x, y, z, count, dx, dy, dz, speed)
Gera partículas em uma localização.
| Parâmetro | Tipo | Padrão | Notas |
|---|---|---|---|
particle | string | obrigatório | Nome do enum Particle do Bukkit, em MAIÚSCULAS (ex.: "FLAME", "DUST") |
x | number | obrigatório | Coordenada X |
y | number | obrigatório | Coordenada Y |
z | number | obrigatório | Coordenada Z |
count | int | 1 | Número de partículas |
dx | number | 0 | Dispersão/deslocamento em X |
dy | number | 0 | Dispersão/deslocamento em Y |
dz | number | 0 | Dispersão/deslocamento em Z |
speed | number | 0 | Velocidade das partículas |
Exemplo
return {
api_version = 1,
on_right_click = function(context)
local loc = context.prop.current_location
if loc then
context.world:spawn_particle("HEART", loc.x, loc.y + 1, loc.z, 5, 0.3, 0.3, 0.3, 0)
end
end
}
world:play_sound(sound, x, y, z, volume, pitch)
Reproduz um som em uma localização.
| Parâmetro | Tipo | Padrão | Notas |
|---|---|---|---|
sound | string | obrigatório | Nome do enum Sound do Bukkit, em MAIÚSCULAS (ex.: "ENTITY_EXPERIENCE_ORB_PICKUP") |
x | number | obrigatório | Coordenada X |
y | number | obrigatório | Coordenada Y |
z | number | obrigatório | Coordenada Z |
volume | number | 1.0 | Volume |
pitch | number | 1.0 | Tom |
Exemplo
return {
api_version = 1,
on_right_click = function(context)
local loc = context.prop.current_location
if loc then
context.world:play_sound("BLOCK_NOTE_BLOCK_PLING", loc.x, loc.y, loc.z, 1.0, 1.2)
end
end
}
world:strike_lightning(x, y, z)
Invoca um raio em uma localização (visual e causando dano).
| Parâmetro | Tipo | Notas |
|---|---|---|
x | number | Coordenada X |
y | number | Coordenada Y |
z | number | Coordenada Z |
Exemplo
return {
api_version = 1,
on_projectile_hit = function(context)
local loc = context.prop.current_location
if loc then
context.world:strike_lightning(loc.x, loc.y, loc.z)
end
end
}
world:get_time()
Retorna o horário atual do mundo em ticks.
world:set_time(ticks)
Define o horário do mundo.
| Parâmetro | Tipo | Notas |
|---|---|---|
ticks | int | Horário do mundo (0 = amanhecer, 6000 = meio-dia, 13000 = noite, 18000 = meia-noite) |
world:get_nearby_entities(x, y, z, radius)
Retorna um array de tabelas wrapper de entidades para todas as entidades vivas dentro de uma caixa delimitadora centrada nas coordenadas fornecidas.
| Parâmetro | Tipo | Notas |
|---|---|---|
x | number | Centro X |
y | number | Centro Y |
z | number | Centro Z |
radius | number | Raio de busca (usado como meia-extensão nos três eixos) |
Exemplo
return {
api_version = 1,
on_right_click = function(context)
local loc = context.prop.current_location
if loc then
local entities = context.world:get_nearby_entities(loc.x, loc.y, loc.z, 10)
context.log:info("Found " .. #entities .. " entities nearby")
end
end
}
world:get_nearby_players(x, y, z, radius)
Retorna um array de tabelas wrapper de jogadores para todos os jogadores dentro de uma caixa delimitadora centrada nas coordenadas fornecidas.
| Parâmetro | Tipo | Notas |
|---|---|---|
x | number | Centro X |
y | number | Centro Y |
z | number | Centro Z |
radius | number | Raio de busca |
Exemplo
return {
api_version = 1,
on_right_click = function(context)
local loc = context.prop.current_location
if loc then
local players = context.world:get_nearby_players(loc.x, loc.y, loc.z, 20)
for i = 1, #players do
context.log:info("Nearby player: " .. (players[i].name or "unknown"))
end
end
end
}
context.zones
A tabela zones permite criar zonas espaciais e monitorá-las para eventos de entrada/saída de jogadores. As zonas são vinculadas à instância do script e limpas automaticamente quando o prop é removido.
zones:create_sphere(x, y, z, radius)
Cria uma zona esférica centrada nas coordenadas fornecidas. Retorna um identificador numérico de zona.
| Parâmetro | Tipo | Notas |
|---|---|---|
x | number | Centro X |
y | number | Centro Y |
z | number | Centro Z |
radius | number | Raio da esfera |
zones:create_cylinder(x, y, z, radius, height)
Cria uma zona cilíndrica. Retorna um identificador numérico de zona.
| Parâmetro | Tipo | Notas |
|---|---|---|
x | number | Centro X |
y | number | Centro Y (base) |
z | number | Centro Z |
radius | number | Raio do cilindro |
height | number | Altura do cilindro |
zones:create_cuboid(x, y, z, xSize, ySize, zSize)
Cria uma zona em forma de cuboide. Retorna um identificador numérico de zona.
| Parâmetro | Tipo | Notas |
|---|---|---|
x | number | Centro X |
y | number | Centro Y |
z | number | Centro Z |
xSize | number | Meia-extensão em X |
ySize | number | Meia-extensão em Y |
zSize | number | Meia-extensão em Z |
zones:watch(handle, onEnterCallback, onLeaveCallback)
Começa a monitorar uma zona para eventos de entrada/saída de jogadores. Quando um jogador entra ou sai da zona, o hook correspondente é disparado (on_zone_enter ou on_zone_leave).
| Parâmetro | Tipo | Notas |
|---|---|---|
handle | int | Identificador de zona de uma chamada create_* |
onEnterCallback | function ou nil | Chamado quando um jogador entra na zona |
onLeaveCallback | function ou nil | Chamado quando um jogador sai da zona |
Retorna true se o monitoramento foi configurado com sucesso, nil se o identificador de zona era inválido.
Os monitoramentos de zona são verificados a cada tick do servidor contra todos os jogadores no mesmo mundo. Mantenha a quantidade de zonas razoável para evitar sobrecarga de desempenho.
zones:unwatch(handle)
Para o monitoramento de uma zona e limpa seus recursos.
| Parâmetro | Tipo | Notas |
|---|---|---|
handle | int | Identificador de zona a parar de monitorar |
Exemplo: Zona de ativação por proximidade
Exemplo
return {
api_version = 1,
on_spawn = function(context)
local loc = context.prop.current_location
if loc == nil then return end
-- Create a sphere zone around the prop
local handle = context.zones:create_sphere(loc.x, loc.y, loc.z, 5)
-- Watch for player enter/leave
context.zones:watch(
handle,
function(player)
context.log:info("Player entered zone!")
end,
function(player)
context.log:info("Player left zone!")
end
)
-- Store handle so we can clean up later if needed
context.state.zone_handle = handle
end,
on_destroy = function(context)
if context.state.zone_handle then
context.zones:unwatch(context.state.zone_handle)
end
end
}
context.scheduler
O scheduler permite executar tarefas atrasadas e repetitivas. Todas as tarefas pertencem à instância do script e são canceladas automaticamente quando o prop é removido.
scheduler:run_later(ticks, callback)
Executa um callback uma vez após um atraso. Retorna um ID de tarefa numérico.
| Parâmetro | Tipo | Notas |
|---|---|---|
ticks | int | Atraso em ticks do servidor (20 ticks = 1 segundo) |
callback | function | Chamado com um context novo quando o atraso expira |
Exemplo
return {
api_version = 1,
on_right_click = function(context)
context.log:info("Something will happen in 2 seconds...")
context.scheduler:run_later(40, function(delayed_context)
local loc = delayed_context.prop.current_location
if loc then
delayed_context.world:spawn_particle("EXPLOSION_EMITTER", loc.x, loc.y, loc.z, 1)
end
end)
end
}
scheduler:run_repeating(delay, interval, callback)
Executa um callback repetidamente em um intervalo fixo. Retorna um ID de tarefa numérico.
| Parâmetro | Tipo | Notas |
|---|---|---|
delay | int | Atraso inicial em ticks antes da primeira execução |
interval | int | Ticks entre cada execução subsequente |
callback | function | Chamado com um context novo a cada intervalo |
Exemplo
return {
api_version = 1,
on_spawn = function(context)
-- Emit particles every second
context.state.particle_task = context.scheduler:run_repeating(0, 20, function(tick_context)
local loc = tick_context.prop.current_location
if loc then
tick_context.world:spawn_particle("FLAME", loc.x, loc.y + 1, loc.z, 3, 0.1, 0.1, 0.1, 0.02)
end
end)
end,
on_destroy = function(context)
if context.state.particle_task then
context.scheduler:cancel(context.state.particle_task)
end
end
}
scheduler:cancel(taskId)
Cancela uma tarefa agendada pelo seu ID.
| Parâmetro | Tipo | Notas |
|---|---|---|
taskId | int | O ID da tarefa retornado por run_later ou run_repeating |
Se você iniciar uma tarefa repetitiva, sempre cancele-a em on_destroy (ou quando não for mais necessária). Esquecer de cancelar deixa uma tarefa em segundo plano executando até que o prop seja removido do servidor, o que desperdiça desempenho e pode causar erros.
context.state
Uma tabela Lua simples que persiste durante toda a vida do prop. Use-a para armazenar flags, contadores, IDs de tarefas, estados de alternância e quaisquer dados que precise compartilhar 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
Apenas context.state persiste entre chamadas de hooks. Todas as outras tabelas de contexto (context.prop, context.world, context.event, etc.) são reconstruídas a cada vez.
context.log
Métodos de log no console. As mensagens são prefixadas com o nome do arquivo do script no console do servidor.
| Método | Notas |
|---|---|
log:info(message) | Mensagem informativa |
log:warn(message) | Mensagem de aviso |
log:error(message) | Mensagem de erro (funcionalmente igual a warn) |
Exemplo
return {
api_version = 1,
on_spawn = function(context)
context.log:info("Script loaded!")
end,
on_right_click = function(context)
context.log:warn("Prop was clicked -- this is a debug warning")
end
}
Modelo de execução
Um runtime por prop
Cada entidade prop que possui scripts atribuídos recebe sua própria instância independente de runtime Lua. Quando o prop é gerado, o FMM carrega o código-fonte Lua, avalia-o em um ambiente sandbox novo e armazena a tabela retornada. Quando o prop é removido, o runtime é encerrado.
Isso significa:
- Variáveis locais declaradas no escopo do arquivo são privadas para aquela instância de prop.
context.stateé completamente isolado entre instâncias de prop, mesmo que compartilhem o mesmo arquivo de script.
Propriedade de tarefas
Todas as tarefas criadas através de context.scheduler pertencem ao runtime que as criou. Quando um prop é removido:
- O runtime é encerrado.
- Todas as tarefas -- tanto as únicas quanto as repetitivas -- são automaticamente canceladas.
- Todos os monitoramentos de zona são limpos.
Orçamento de execução
Cada invocação de hook e cada invocação de callback é cronometrada. Se uma única chamada levar mais de 50 milissegundos, o script é desativado com um aviso no console:
[Lua] my_script.lua took 73ms in 'on_game_tick' (limit: 50ms) -- script disabled to prevent lag.
Para se manter dentro do orçamento:
- Evite loops sem limite dentro de hooks.
- Mantenha os handlers de
on_game_tickleves -- eles executam a cada tick. - Use
context.scheduler:run_repeating(...)para distribuir o trabalho entre ticks.
Próximos passos
- Exemplos e padrões -- scripts de props completos e funcionais com explicações passo a passo
- Solução de problemas -- problemas comuns, dicas de depuração e checklist de QC
- Primeiros Passos -- estrutura de arquivos, hooks, tutorial do primeiro script