State Machine

Máquinas de estado declarativas para comportamentos complexos

O addon State Machine permite criar máquinas de estado para NPCs, quests, minigames e qualquer sistema com estados e transições.

Sintaxe

state machine NOME:
  states: [estado1, estado2, ...]
  initial: estado_inicial
  
  transitions:
    estado1 -> estado2 when CONDIÇÃO
    
  on enter estado:
    # ações ao entrar
    
  on exit estado:
    # ações ao sair

Exemplo: Porta

state machine DoorMachine:
  states: [closed, open, locked]
  initial: closed
  
  transitions:
    closed -> open when event:interact and !is_locked
    open -> closed when time_in_state > 5s
    closed -> locked when event:lock
    locked -> closed when event:unlock
    
  on enter open:
    play sound "block.wooden_door.open" to {player}
    
  on exit open:
    play sound "block.wooden_door.close" to {player}
    
  on enter locked:
    send "&cDoor locked!" to {player}

# Criar instância
set {door_machine} to create state machine DoorMachine

# Enviar evento
send event "interact" to {door_machine}
send event "lock" to {door_machine}

Exemplo: NPC Quest

quest-npc.lzl
state machine QuestNPC:
  states: [idle, talking, giving_quest, waiting, complete]
  initial: idle
  
  transitions:
    idle -> talking when event:interact
    talking -> giving_quest when event:accept
    talking -> idle when event:decline
    giving_quest -> waiting when time_in_state > 3s
    waiting -> complete when player_has_items
    complete -> idle when event:claim_reward
    
  on enter idle:
    set npc pose to "standing"
    
  on enter talking:
    send "&e[Quest NPC] &fHello adventurer!" to {player}
    wait 1 second
    send "&e[Quest NPC] &fI need 10 diamonds. Can you help?" to {player}
    open modal form "quest_accept" with title "Accept Quest?" with buttons "Accept", "Decline" to {player}
    
  on enter giving_quest:
    send "&e[Quest NPC] &fGreat! Bring me 10 diamonds." to {player}
    set {quest::%{player}'s uuid%} to "collect_diamonds"
    set {quest_progress::%{player}'s uuid%} to 0
    
  on enter waiting:
    # NPC espera o player completar
    
  on enter complete:
    send "&e[Quest NPC] &fYou did it! Here's your reward!" to {player}
    remove 10 diamond from {player}
    give 1 diamond_sword with sharpness 5 to {player}
    add 1000 to {player}'s balance
    
# Uso
on interact with npc "quest_giver":
    set {_machine} to get state machine for {player} named "quest"
    if {_machine} is not set:
        set {_machine} to create state machine QuestNPC
        store {_machine} for {player} as "quest"
    
    send event "interact" to {_machine}

Exemplo: Minigame

minigame-states.lzl
state machine ArenaGame:
  states: [waiting, countdown, playing, ending]
  initial: waiting
  
  transitions:
    waiting -> countdown when player_count >= 2
    countdown -> waiting when player_count < 2
    countdown -> playing when time_in_state >= 10s
    playing -> ending when one_player_remaining or time_limit_reached
    ending -> waiting when time_in_state >= 5s
    
  on enter waiting:
    broadcast "&7[Arena] &eWaiting for players..."
    set {arena_status} to "waiting"
    
  on enter countdown:
    broadcast "&7[Arena] &aGame starting in 10 seconds!"
    loop numbers from 10 to 1:
        wait 1 second
        broadcast "&7[Arena] &e%loop-number%..."
    
  on enter playing:
    broadcast "&7[Arena] &c&lFIGHT!"
    set {arena_status} to "playing"
    loop {arena_players::*}:
        set loop-value's gamemode to survival
        teleport loop-value to {arena_spawn}
    
  on enter ending:
    set {_winner} to get last standing player
    broadcast "&7[Arena] &6%{_winner}% wins!"
    give 100 diamonds to {_winner}
    
    # Teleportar todos de volta
    loop {arena_players::*}:
        teleport loop-value to {lobby_spawn}
    
    clear {arena_players::*}

# Criar arena
on load:
    set {arena_machine} to create state machine ArenaGame

Condições de Transição

transitions:
  # Evento específico
  state1 -> state2 when event:nome_evento
  
  # Tempo no estado
  state1 -> state2 when time_in_state > 5s
  
  # Condição customizada
  state1 -> state2 when player_count >= 2
  
  # Múltiplas condições (AND)
  state1 -> state2 when event:interact and has_key
  
  # Negação
  state1 -> state2 when !is_locked

Uso

State Machines são ideais para sistemas com estados bem definidos e transições claras. Para lógica simples, use condições normais. Para comportamentos complexos, use State Machines.

Configuração

config.yml
official_addons:
  enabled: true
  state_machine: true