✚ Sviluppo videogiochi

Behavior tree: IA dei nemici modulare e facile da estendere

Cosa sono i behavior tree nell'IA dei videogiochi: nodi sequenza e selettore, decoratori, blackboard e confronto con le macchine a stati finiti.

Le macchine a stati sono perfette per nemici semplici, ma quando i comportamenti si moltiplicano il numero di transizioni cresce in fretta e il diagramma diventa una ragnatela. I behavior tree (alberi di comportamento) offrono un'alternativa diffusa nell'industria: invece di descrivere stati e passaggi tra stati, descrivono decisioni gerarchiche composte da blocchi riutilizzabili.

La struttura di base

Un behavior tree è un albero di nodi. A intervalli regolari, spesso più volte al secondo, il sistema lo «visita» partendo dalla radice. Ogni nodo, quando viene eseguito, restituisce uno di tre risultati:

  • successo: il compito è riuscito;
  • fallimento: il compito non è possibile o non è riuscito;
  • in corso: il compito richiede altro tempo, per esempio un movimento non ancora concluso.

I nodi si dividono in due grandi famiglie: le foglie, che fanno qualcosa o verificano una condizione, e i nodi composti, che decidono in che ordine eseguire i figli.

I nodi composti principali

Sequenza

Esegue i figli da sinistra a destra. Si ferma e restituisce fallimento al primo figlio che fallisce; restituisce successo solo se tutti riescono. Corrisponde a un «e poi»:

Sequenza
 ├─ Condizione: giocatore entro portata?
 ├─ Azione: girati verso il giocatore
 └─ Azione: attacca

Selettore

Esegue i figli da sinistra a destra finché uno riesce. Restituisce successo al primo successo e fallimento solo se falliscono tutti. Corrisponde a un «altrimenti», ed è il modo naturale di esprimere priorità:

Selettore
 ├─ Sequenza "fuggi se ferito"
 ├─ Sequenza "attacca se vicino"
 ├─ Sequenza "insegui se visibile"
 └─ Azione: pattuglia

L'ordine dei figli è la lista delle priorità: il nemico prova prima a fuggire, poi ad attaccare, poi a inseguire, e solo se nulla di tutto ciò è applicabile pattuglia.

Parallelo

Esegue più figli contemporaneamente, per esempio muoversi verso una copertura mentre si spara. La regola di successo va definita: basta che riesca un figlio, oppure devono riuscire tutti.

Decoratori

Un decoratore ha un solo figlio e ne modifica il risultato o l'esecuzione. Alcuni esempi molto usati:

Decoratore Effetto
Inverti Trasforma successo in fallimento e viceversa
Ripeti Esegue il figlio un numero fissato di volte o all'infinito
Raffreddamento Impedisce di rieseguire il figlio prima di un certo tempo
Limite di tempo Fa fallire il figlio se dura troppo
Riesci sempre Restituisce successo qualunque sia l'esito

Il raffreddamento, per esempio, permette di dire «lancia una granata, ma non più di una ogni otto secondi» senza aggiungere variabili alla logica dell'attacco.

La blackboard

I nodi devono condividere informazioni: la posizione dell'ultimo avvistamento, il bersaglio attuale, la copertura scelta. Invece di collegare i nodi direttamente, si usa una blackboard: una tabella di chiavi e valori accessibile a tutto l'albero. Un'azione «trova copertura» scrive la posizione nella chiave copertura, e un'azione successiva «vai a» la legge.

Questo mantiene i nodi indipendenti e riutilizzabili: la stessa azione «vai a» funziona con qualunque chiave le venga indicata.

Il ruolo dello stato «in corso»

Lo stato «in corso» è ciò che distingue un behavior tree da una semplice serie di condizioni. Un'azione come «cammina fino al punto» non termina in un solo aggiornamento: restituisce «in corso» finché il personaggio non arriva. Alla visita successiva l'albero riprende da lì.

C'è però una scelta di progetto importante. Se a ogni visita si rivalutano anche i rami a priorità più alta, il nemico può interrompere la camminata non appena vede il giocatore. Se invece si riprende sempre dal nodo in corso, il comportamento è più stabile ma meno reattivo. Molte implementazioni offrono entrambe le modalità, con nodi che possono «interrompere» quelli a priorità inferiore quando la loro condizione diventa vera.

Behavior tree o macchina a stati?

Aspetto Macchina a stati Behavior tree
Comportamenti semplici Molto chiara Leggermente più verbosa
Molti comportamenti Transizioni difficili da gestire Si aggiungono rami
Priorità Codificate nelle transizioni Espresse dall'ordine dei figli
Riutilizzo Stati riutilizzabili con fatica Sottoalberi riutilizzabili
Debug Facile vedere lo stato attuale Serve visualizzare il percorso nell'albero

Le due tecniche non si escludono. È comune usare una macchina a stati per le modalità generali, come esplorazione, combattimento e allarme, e un behavior tree all'interno di ciascuna.

Consigli pratici

  • Mantenere le foglie piccole: una condizione o un'azione per nodo.
  • Dare nomi chiari ai sottoalberi e riutilizzarli tra nemici diversi.
  • Costruire o adottare un visualizzatore che mostri in tempo reale quali nodi sono attivi: senza, il debug diventa difficile.
  • Non valutare l'albero a ogni fotogramma se non serve: pochi aggiornamenti al secondo bastano per la maggior parte dei nemici.

In sintesi

  • Un behavior tree organizza le decisioni come un albero di nodi riutilizzabili.
  • Ogni nodo restituisce successo, fallimento o in corso.
  • Sequenza significa «e poi», selettore significa «altrimenti» ed esprime le priorità.
  • Decoratori e blackboard aggiungono controllo e condivisione dei dati.
  • Behavior tree e macchine a stati si possono combinare in modo efficace.
MM
Marco Marzaduri

Marco Marzaduri si occupa di cybersecurity, informatica forense e sviluppo web. Laureato in informatica, unisce il rigore dell'analisi tecnica all'attenzione per le persone che usano la tecnologia.

Leggi anche