Saltar para o conteúdo principal

Scripts Lua: API de elementos decorativos

Esta página cobre as APIs disponíveis nos scripts de elementos decorativos FMM: context.prop, context.event, context.player, context.projectile, context.world, context.zones, context.scheduler, context.state, context.cooldowns e context.log. Se está a começar, consulte primeiro Primeiros passos.


context.prop​

A tabela fornece informações sobre o elemento e métodos para controlar as animações. O FMM mantém uma cópia em cache por elemento para reduzir trabalho. Campos como current_location são consultados quando lidos e refletem o estado atual.

Campos​

CampoTipoNotas
prop.model_idCadeiaNome do modelo da definição, como "torch_01"
prop.current_locationTabela de posiçãoPosição atual, consultada ao ler o campo; não é uma cópia fixa

A tabela de posição contém x, y, z, world, yaw e pitch.

Exemplo: consultar informações do elemento
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 pelo nome no modelo do elemento.

ParâmetroTipoPredefiniçãoNotas
nameCadeiaObrigatórioNome da animação no ficheiro do modelo
blendBooleanotrueCom true, aguarda o fim do tick do estado atual; com false, interrompe imediatamente. Não faz uma transição gradual
loopBooleanotrueRepetição de uma animação personalizada; os estados integrados usam a sua própria regra

Devolve true quando aceita o pedido, mesmo que fique em espera ou seja suprimido, e false quando não o pode aceitar. O estado terminal death recusa novos pedidos. Durante uma animação personalizada, um pedido de ataque é aceite sem a interromper. Só cabe um pedido na fila; um novo pedido em espera substitui o anterior. A aceitação não prova reprodução visível. Consulte Animações.

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()​

Limpa os pedidos em espera e regressa a idle, se existir. Caso contrário, termina o estado atual do motor de animação partilhado. O estado terminal death mantém-se, embora a implementação Bedrock receba um pedido de paragem.

Não recebe parâmetros.

Exemplo
return {
api_version = 1,

on_right_click = function(context)
context.prop:stop_animation()
end
}

prop:hurt_visual()​

Apresenta o flash vermelho de dano sem causar dano real ao elemento.

Não recebe parâmetros.

Exemplo
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()​

Remove o elemento do mundo e deixa cair o item de papel de colocação na sua posição. Esse item permite voltar a colocá-lo com um clique direito num bloco.

Não recebe parâmetros nem devolve valores. A remoção e a queda do item são agendadas na thread principal Bukkit. Não verifica permissões nem transfere os dados guardados do inventário ou livro para o papel. Verifique o acesso e trate dos conteúdos guardados antes de recolher o elemento. Não repita pickup() enquanto uma recolha já estiver agendada.

Exemplo
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 um jogador no primeiro assento disponível. O modelo precisa de ossos de pontos de montada.

ParâmetroTipoNotas
playerTabela de entidadeJogador, por exemplo de context.player ou context.event.player

Devolve true quando o jogador foi encontrado, o elemento tem pontos de montada e a ação foi agendada. Devolve false se essas referências não forem válidas. true não garante que exista um assento disponível no momento em que a ação for executada.

Quando um script de clique direito controla os assentos, cancele context.event para impedir que o comportamento predefinido do FMM também tente sentar o jogador.

Exemplo
return {
api_version = 1,

on_right_click = function(context)
if context.event then context.event.cancel() end
local player = context.event and context.event.player
if player then
context.prop:mount(player)
end
end
}

prop:dismount(player)​

Retira um jogador do assento no elemento.

ParâmetroTipoNotas
playerTabela de entidadeJogador a desmontar

Devolve true quando o jogador foi encontrado, o elemento tem um gestor de montadas e a verificação foi agendada. Devolve false se essas referências não forem válidas.

Exemplo
return {
api_version = 1,

on_right_click = function(context)
if context.event then context.event.cancel() end
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()​

Devolve um vetor Lua de tabelas de entidades com todos os passageiros atuais.

Não recebe parâmetros.

Exemplo
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()​

Indica se o modelo tem ossos de pontos de montada.

Não recebe parâmetros. Devolve true ou false.

Exemplo
return {
api_version = 1,

on_right_click = function(context)
if context.event then context.event.cancel() end
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)​

Cria um boss personalizado EliteMobs na posição indicada. Exige EliteMobs instalado.

ParâmetroTipoNotas
filenameCadeiaFicheiro do boss, como "my_boss.yml"
xNúmeroCoordenada X
yNúmeroCoordenada Y
zNúmeroCoordenada Z

Devolve uma tabela de entidade viva para o boss criado, ou nil quando a integração não consegue devolver um boss vivo. Isso inclui plugin indisponível, configuração em falta ou falha na criação. nil não identifica a causa.

Exemplo
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)​

Agenda a abertura de um inventário de baú para o jogador. Cada elemento tem um único inventário partilhado: a primeira abertura constrói-o a partir dos dados guardados no PersistentDataContainer do elemento, e as aberturas seguintes mostram esse mesmo inventário em tempo real a todos os jogadores. O FMM guarda-o de volta no elemento quando o último jogador o fecha, quando o chunk do elemento é descarregado e antes de drop_inventory() o ler.

ParâmetroTipoPredefiniçãoNotas
playerTabela de entidadeObrigatórioJogador a quem mostrar o inventário
titleCadeiaObrigatórioTítulo; aceita códigos de cor &
rowsInteiro3De 1 a 6 linhas; 6 equivalem a 54 posições, um baú duplo

Devolve true se as referências do elemento e jogador forem válidas e a abertura tiver sido agendada; caso contrário, false. O número de linhas é limitado ao intervalo 1–6 antes de criar o inventário.

O tamanho e o título vêm da chamada que constrói o inventário; enquanto estiver aberto, as chamadas seguintes reutilizam-no tal como está. Quando o conteúdo guardado ocupa mais posições do que as linhas pedidas, o inventário cresce para as acomodar, pelo que um valor rows menor nunca descarta itens guardados. Se os dados guardados não puderem ser lidos, o inventário não abre. A ação é ignorada se o elemento tiver sido removido antes de ser executada. true não garante que o inventário tenha aberto.


prop:is_viewing_inventory(player)​

Indica se o listener de inventário acompanha o jogador como utilizador deste elemento. Não garante que a interface continue realmente aberta.

ParâmetroTipoNotas
playerTabela de entidadeJogador a verificar

Devolve true ou false.

Exemplo: animação ao fechar o inventário
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)​

Retira o livro escrito ou editável da mão principal do jogador e guarda-o no elemento.

ParâmetroTipoNotas
playerTabela de entidadeJogador com o livro na mão

Devolve true se as referências forem válidas e a ação tiver sido agendada. A ação posterior, na thread principal, só coloca o livro se o jogador tiver um livro editável ou escrito e o elemento ainda não tiver um.


prop:read_book(player)​

Abre o livro guardado para o jogador ler.

ParâmetroTipoNotas
playerTabela de entidadeJogador a quem mostrar o livro

Devolve true se as referências forem válidas e a leitura tiver sido agendada. A ação posterior exige um WRITTEN_BOOK guardado e desserializável. Um WRITABLE_BOOK guardado não é aberto.


prop:take_book(player)​

Devolve o livro guardado ao inventário do jogador e remove-o do elemento.

ParâmetroTipoNotas
playerTabela de entidadeJogador que recebe o livro

Devolve true se as referências forem válidas e a ação tiver sido agendada. Não garante que exista um livro guardado.

Garanta espaço livre no inventário do jogador. O registo guardado é removido antes de adicionar o livro; os itens que não couberem não são deixados cair. place_book serializa toda a pilha da mão e depois retira um item. Use livros individuais normais.


prop:has_book()​

Verifica apenas se existe a chave do livro no PDC do suporte de armadura. Não valida o conteúdo serializado. Não recebe parâmetros.


prop:drop_inventory()​

Agenda a gravação do inventário aberto, se existir, e o seu fecho para todos os jogadores; depois lê o conteúdo guardado, remove o registo do PDC e deixa cair os itens na posição do elemento. As alterações feitas no inventário aberto até esse momento são incluídas. Uma falha de descodificação após a remoção do registo pode não deixar itens para cair.

Não recebe parâmetros. Devolve true se o suporte de armadura for válido e a ação tiver sido agendada. Não garante que existam itens guardados.


prop:drop_book()​

Agenda a queda do livro guardado na posição do elemento. A ação remove o registo antes de descodificar; uma falha de descodificação pode perder o livro.

Não recebe parâmetros. Devolve true se o suporte de armadura for válido e a ação tiver sido agendada. Não garante que exista um livro guardado.


prop:set_persistent_data(key, value)​

Guarda uma cadeia de texto no PersistentDataContainer do suporte de armadura. Os dados acompanham esse suporte durante a gravação normal do mundo e o descarregamento de chunks. Remover definitivamente o elemento ou substituí-lo por um papel de colocação não transfere esses dados.

ParâmetroTipoNotas
keyCadeiaSufixo de chave Bukkit válido, com letras minúsculas, algarismos e ._-/. Guardado como fmm_lua_<key>; caracteres inválidos provocam um erro
valueCadeiaValor a guardar. Use tostring() para números e booleanos

Devolve true em caso de sucesso e false se não houver suporte de armadura.


prop:get_persistent_data(key)​

Lê uma cadeia guardada por set_persistent_data. Devolve nil se a chave não tiver sido definida.

ParâmetroTipoNotas
keyCadeiaChave usada em set_persistent_data
Exemplo: estado alternável 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
}

Efeitos de itens​

A API context.item de itens equipados foi removida. Defina efeitos com encantamentos personalizados e associe-os pela lista enchantments: do item, com espaço de nomes.

context.event​

Dados do evento atual, disponíveis em cliques, impactos de projéteis e eventos genéricos de zonas. É nil quando não há evento nem jogador associado, como em on_spawn, on_game_tick e on_destroy.

Os cliques FMM usam uma opção própria de cancelamento do comportamento predefinido. A tabela Lua expõe apenas os campos e métodos aqui indicados.

Campos e métodos​

Campo ou métodoTipoNotas
event.playerTabela de jogadorJogador que clicou ou atravessou a fronteira da zona. Disponível em on_left_click, on_right_click, on_zone_enter e on_zone_leave. Em on_projectile_hit é a entidade viva que disparou o projétil, que pode ser um mob, e está ausente quando o atirador não é uma entidade viva. Consulte Métodos de jogadores
event.is_cancelledBooleanoEstado de cancelamento quando o contexto foi construído. Não é atualizado após cancel() ou uncancel()
event.cancel()FunçãoCancela o evento, por exemplo, para impedir o dano ou interação
event.uncancel()FunçãoRetira o cancelamento de um evento
Ponto e dois-pontos funcionam

cancel e uncancel ignoram os argumentos recebidos. Assim, context.event.cancel() e context.event:cancel() são equivalentes. Esta página usa ponto; ambas as formas funcionam.

informação

Os eventos genéricos de zona fornecem um jogador, sem opção de cancelamento. Nesses eventos não existem event.cancel() nem event.uncancel(), e event.is_cancelled é false. Nos cliques, o cancelamento impede a ação predefinida correspondente do FMM.

Trate event.is_cancelled como uma cópia do estado inicial. Se chamar cancel() ou uncancel() e precisar de recordar a alteração na mesma função, guarde um indicador local.

A tabela não expõe campos específicos Bukkit como target, block, projectile ou item. Para contexto adicional, use context.player, context.event.player, context.projectile (em on_projectile_hit), player:get_target_entity(range), context.world:raycast(...) ou consultas de entidades próximas.

on_projectile_hit​

É acionado quando um projétil atinge a hitbox do elemento, uma vez por projétil.

Valor do contextoNotas
context.projectileTabela de entidade do projétil (flecha, tridente, bola de neve, etc.). Só é definido neste evento
context.event.playerA entidade viva que disparou o projétil, se existir
context.playerO atirador quando é um jogador; caso contrário, nil

O evento é executado depois de o FMM ter tratado o impacto, e o tratamento predefinido de projéteis do FMM não faz nada nos elementos decorativos. Chamar context.event.cancel() aqui não impede que um projétil não perfurante seja consumido pelo impacto. O evento não é acionado quando outro plugin já cancelou o impacto.

return {
api_version = 1,

on_projectile_hit = function(context)
local shooter = context.player
if shooter then
shooter:send_message("&eYou hit the target!")
end
context.prop:play_animation("hit", false, false)
end
}

Exemplo: cancelar dano do clique esquerdo​

Exemplo
return {
api_version = 1,

on_left_click = function(context)
if context.event then
context.event.cancel()
end
end
}

Exemplo: consultar 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
}
cuidado

Nas funções agendadas de scheduler:run_later e scheduler:run_repeating, context.event é sempre nil. Só pode modificar o evento durante a própria função que o trata.


context.world​

Esta é a API do mundo FreeMinecraftModels/MagmaCore. Consulte context.world para a referência completa.

informação

Todos os métodos da página global estão disponíveis no FMM: 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, place_temporary_block, drop_item e spawn_firework. Consulte a API do mundo MagmaCore para world:raycast(), que deteta entidades e blocos ao longo de um raio, world:place_temporary_block(), que substitui blocos temporariamente, e world:spawn_firework(), que cria fogos de artifício personalizados. Os poderes de bosses EliteMobs partem da mesma base e acrescentam métodos com tabelas de posição para bosses, reforços, blocos em queda, blocos temporários e outras operações. Consulte Mundo e ambiente EliteMobs.

Adições ao mundo específicas do FMM​

O FreeMinecraftModels acrescenta três auxiliares opcionais de saque EliteMobs a context.world. Estão sempre presentes, mas devolvem false sem fazer nada se o EliteMobs não estiver instalado:

MétodoNotas
world:drop_elitemobs_procedural_loot(player, level, location?)Gera saque procedural EliteMobs. Respeita a configuração de entrega direta ao inventário, deixando cair junto do jogador o que não couber; caso contrário, usa a posição escolhida. Devolve false se esse tipo de saque estiver desativado
world:drop_elitemobs_random_loot(player, level, location?)Sorteia as tabelas de saque EliteMobs para o jogador ao nível indicado
world:drop_elitemobs_custom_loot(player, file, level, location?)Deixa cair um item personalizado EliteMobs específico. Devolve false se o ficheiro não for encontrado

As assinaturas completas estão na Referência da API Lua. Para criar bosses através do elemento, use prop:spawn_elitemobs_boss(...), descrito acima.


Métodos de jogadores​

As tabelas de jogadores vêm de context.player, context.event.player e context.world:get_nearby_players(). Os eventos genéricos MagmaCore on_zone_enter e on_zone_leave colocam o jogador que entrou ou saiu em ambos os campos do contexto.

Tabelas de entidades MagmaCore

O FMM usa as tabelas de entidades, métodos de entidades vivas, métodos específicos de jogadores e métodos de interface descritos na página global. Os poderes EliteMobs expõem tabelas semelhantes, mas específicas de bosses, em Bosses e entidades. Consulte Motor de scripts Lua do MagmaCore para os campos e métodos das entidades e jogadores, incluindo Métodos de interface para jogadores. Os métodos novos incluem player:get_target_entity() para selecionar alvos por raio, player:get_eye_location(), player:get_look_direction(), player:send_block_change() para blocos falsos por jogador e player:reset_block(). Consulte Métodos específicos de jogadores.

Campos de entidades específicos do FMM​

Todas as tabelas de entidades criadas num script FMM recebem automaticamente estes campos através de LuaEntityEnricher. Os indicadores e a referência ao modelo são cópias do momento de construção da tabela. Obtenha uma nova tabela após alterar o modelo associado. has_permission consulta as permissões atuais do jogador; is_op é uma cópia fixa.

CampoTipoNotas
entity.is_modeledBooleanotrue se a entidade Bukkit for a entidade subjacente de uma ModeledEntity
entity.is_propBooleanotrue se for um suporte de armadura de uma PropEntity
entity.modelTabela ou nilPreenchido apenas com is_modeled = true

Quando existe, entity.model disponibiliza:

Campo ou métodoNotas
model.model_idNome do modelo da definição, como "dragon"
model.is_dynamictrue para uma DynamicEntity, ligada a uma entidade viva
model:play_animation(name, blend, loop)Pede uma animação. Nesta integração, blend e loop têm predefinição false. true significa pedido aceite, sem provar reprodução visível
model:stop_animations()Limpa a reprodução em espera e regressa a idle se existir; não interrompe a morte terminal
model:remove()Remove imediatamente a entidade com modelo e todos os ossos
on_right_click = function(context)
local player = context.event and context.event.player
if not player then return end

local target = player:get_target_entity(8)
if target and target.is_modeled then
target.model:play_animation("hurt", true, false)
end
end

Campos de entidades EliteMobs​

Com EliteMobs instalado, o FMM também usa o seu enriquecimento de entidades para acrescentar:

CampoTipoNotas
entity.is_eliteBooleanotrue se a entidade for acompanhada pelo EliteMobs
entity.is_custom_bossBooleanotrue se usar uma configuração de boss personalizado
entity.is_significant_bossBooleanotrue para bosses personalizados com healthMultiplier > 1, excluindo mobs comuns com nome
entity.eliteTabela ou nilPreenchido apenas com is_elite = true. Contém level, name, health, max_health, health_multiplier, damage_multiplier, is_custom_boss e elite:remove()

Os indicadores e a maioria dos campos elite são cópias fixas; health e max_health são consultados ao ler. Com EliteMobs ativo, entity:can_receive_hostile_effect(player_uuid) também aplica a autorização de alvos mágicos do EliteMobs depois da verificação partilhada de alvos hostis. Se o adaptador estiver indisponível, a verificação recusa o alvo em vez de tratar aliados como alvos independentes.


context.zones​

Esta é a API de zonas FreeMinecraftModels/MagmaCore. Consulte context.zones. Os poderes de bosses usam outra tabela, com definições nativas de zonas EliteMobs; consulte Zonas e seleção de alvos EliteMobs.


context.scheduler​

É o agendador MagmaCore usado pelos scripts FMM e NPC EliteMobs. Os nomes de estilo EliteMobs run_after, run_every e cancel_task são aliases do agendador partilhado, pelo que ambos os estilos funcionam. Os poderes de bosses expõem os mesmos aliases através do contexto próprio. Consulte context.scheduler.


context.state​

A API de estado é partilhada pelos scripts FMM, poderes de bosses e scripts de NPC EliteMobs. Consulte context.state.


context.log​

O registo FreeMinecraftModels/MagmaCore oferece info, warn e error. Os NPC EliteMobs usam o mesmo registo; os poderes de bosses expõem info, warn e debug. Consulte context.log.


context.cooldowns​

A API usa a ordem partilhada MagmaCore/FMM, também usada pelos NPC EliteMobs: check_local(key?, duration). Os poderes de bosses usam a mesma ordem de argumentos, com armazenamento próprio. Consulte context.cooldowns.

MétodoNotas
local_ready(key?)Verifica se o tempo de recarga local terminou
local_remaining(key?)Devolve os ticks restantes ou 0
check_local(key?, duration)Verifica e inicia atomicamente um tempo de recarga local
set_local(duration, key?)Define um tempo de recarga local sem verificar
global_ready()Consulta o tempo de recarga global partilhado do proprietário do script
set_global(duration)Define esse tempo de recarga global

Use context.cooldowns:check_local("my_key", 40) para limitar a frequência normal de ações do elemento.


Modelo de execução​

Um ambiente por instância de script​

Cada entrada na lista scripts: de um elemento recebe um ambiente Lua independente. O FMM descobre e valida o código ao registar o fornecedor, depois avalia o código em cache num ambiente isolado novo para cada associação. Alterar ou adicionar um ficheiro Lua exige um recarregamento bem-sucedido antes de novas associações o usarem. As funções dos scripts executam pela ordem da lista configurada; o valor priority é lido mas não altera essa ordem. Ao remover o elemento, as suas instâncias de scripts são encerradas.

Os encantamentos de itens têm um ciclo de vida separado; não criam uma instância de script de elemento decorativo para um item equipado.

Assim:

  • As variáveis locais declaradas ao nível do ficheiro são privadas da instância.
  • context.state é completamente isolado entre instâncias, mesmo usando o mesmo ficheiro.

Responsabilidade pelas tarefas agendadas​

Todas as tarefas de context.scheduler pertencem ao ambiente que as criou. Ao remover o elemento:

  1. O ambiente é encerrado.
  2. Todas as suas tarefas, únicas ou repetidas, são canceladas automaticamente.
  3. Todas as observações de zonas são limpas.

on_destroy só é executado primeiro quando o elemento é removido definitivamente: recolhido, partido, eliminado com /fmm deleteall ou removido por um plugin. Quando o chunk ou o mundo do elemento é descarregado, ou quando o FMM recarrega ou encerra, o ambiente termina sem chamar on_destroy. O elemento regressa com um novo ambiente, e um novo on_spawn, quando o seu chunk volta a carregar.

Âmbito dos tempos de recarga​

O motor partilhado oferece auxiliares locais local_ready, local_remaining, check_local e set_local, e globais global_ready e set_global. No FMM, o armazenamento tem este âmbito:

Tipo de scriptArmazenamento localArmazenamento global
Elemento decorativoPor ScriptInstance, elemento e ficheiro de scriptPor PropEntity, partilhado por todos os scripts associados ao elemento

Os tempos de recarga globais são limpos ao retirar o registo do elemento ou encerrar o gestor durante um recarregamento bem-sucedido ou desativação. Uma preparação de recarregamento rejeitada mantém o ambiente atual. As durações usam tempo decorrido monotónico, com 50 ms por tick pedido. Os atrasos do agendador seguem ticks do servidor; podem divergir quando há atraso no servidor.

Limites de execução​

Cada evento, função agendada e avaliação inicial de ficheiro tem um limite rígido. É imposto dentro da máquina virtual Lua, durante a execução.

LimiteValor
Tempo de CPU da thread atual50 milissegundos
Instruções Lua executadas250 000

O primeiro limite atingido interrompe a chamada com um erro Lua e desativa a instância. As mensagens são:

Lua instruction budget exceeded (250000 instruction limit)
Lua CPU-time budget exceeded (50ms current-thread CPU limit)

O contador de instruções limita ciclos exclusivamente Lua, como while true do end. O tempo é verificado a cada 1 024 instruções Lua e no regresso da chamada. O mecanismo não interrompe um método Java/Bukkit bloqueante enquanto este está a executar.

O tempo medido é o de CPU da thread atual. O script não é penalizado pelo tempo em que a thread do servidor não esteve a executar. Se a JVM não disponibilizar essa medição, o MagmaCore usa 250 milissegundos de tempo decorrido, com Lua elapsed-time fallback budget exceeded (250ms fallback; current-thread CPU time unavailable), mantendo o limite de 250 000 instruções.

As chamadas aninhadas partilham uma quota única. Se um evento chamar uma função que chama outra, toda a cadeia tem 50 ms de CPU ou 250 000 instruções.

A avaliação durante a descoberta do fornecedor rejeita definições inválidas antes do registo. O código em cache volta a ser avaliado para cada nova instância, com os mesmos limites.

Para respeitar os limites:

  • Evite ciclos sem limite nos eventos.
  • Mantenha on_game_tick leve, pois executa em cada tick.
  • Distribua o trabalho por ticks com context.scheduler:run_repeating(...).

Referência completa de eventos​

A tabela seguinte contém os eventos ativos de elementos decorativos.

A coluna context.event descreve a opção de cancelamento FMM ou o jogador da zona. A tabela Lua expõe event.player, event.is_cancelled, event.cancel() e event.uncancel() quando aplicáveis.

Oito eventos ativos de elementos decorativos​

EventoQuando ocorrecontext.event
on_spawnCriação no mundo ou novo carregamento com o seu chunknil
on_game_tickCada tick do servidor, 50 ms a 20 TPSnil
on_destroyRemoção definitiva do elemento (não ao descarregar o chunk nem ao recarregar)nil
on_left_clickClique esquerdo de um jogadorOpção de cancelamento do dano predefinido
on_right_clickClique direito de um jogadorOpção de cancelamento da interação predefinida
on_zone_enterEntrada de um jogador numa zona observadaJogador em context.player / context.event.player; não cancelável
on_zone_leaveSaída de um jogador de uma zona observadaJogador em context.player / context.event.player; não cancelável
on_projectile_hitUm projétil atinge o elementoEvento de impacto de projétil; event.player é o atirador. Consulte on_projectile_hit

Efeitos de itens​

Use Encantamentos personalizados para efeitos de itens de mão. A antiga tabela de 22 eventos de itens já não descreve um sistema em execução.

Próximos passos​

Transporte EliteMobs​

context.world:start_elitemobs_transport(player, route_id) inicia uma rota guardada do EliteMobs para um jogador no mundo do contexto. Devolve se o pedido foi aceite e exige EliteMobs com essa rota carregada. O ID não inclui .yml. Consulte Rotas de transporte.