Perché il pattern di progettazione Command è utile per l'IA del gioco?

2

Sto cercando di imparare il modello di progettazione di Command e applicarlo al gioco su cui sto lavorando. Per prima cosa leggo sull'implementazione generale e mi sembra di capirlo abbastanza bene. Ora voglio sapere come usarlo nei giochi. Ho iniziato a leggere questo libro sugli schemi di progettazione nei giochi e in la sezione sul pattern di comando che l'autore dice:

We can use this same command pattern as the interface between the AI engine and the actors; the AI code simply emits Command objects.

Ho programmato l'IA del gioco prima e ho difficoltà a capire come questo modello aiuti. Di solito, quando si programma AI, si desidera che le istruzioni vengano eseguite immediatamente, ma non riesco a vedere quale altra flessibilità fornisca questo modello, dato che non si modificherà ad esempio comandi diversi (come nell'esempio di input).

L'autore afferma che:

The decoupling here between the AI that selects commands and the actor code that performs them gives us a lot of flexibility. We can use different AI modules for different actors.

Non è realizzabile con una semplice interfaccia tra l'IA del gioco e l'attore? Qualcuno potrebbe darmi un esempio di una configurazione in cui viene utilizzato il modello di progettazione del comando come suggerito in questo libro?

    
posta Wojtek Wencel 28.09.2018 - 17:30
fonte

3 risposte

3

Hai ragione in questo è solo un altro modo per compartimentare il tuo codice, non l'unica soluzione.

Ma considera che spesso vuoi che il tuo codice AI generi una lista di comandi da seguire per un attore.

  1. sposta a x,
  2. ritiro y,
  3. sposta a z,
  4. rilascia y

Mentre il primo attore si sta spostando su x, i può scorrere tra gli altri attori che sono bloccati o hanno completato i loro comandi generando nuove istruzioni per loro.

Il pattern di comando è un buon (ma non il solo) adatto per questo stile di programmazione

    
risposta data 28.09.2018 - 17:56
fonte
3

La sezione Intent per il pattern Command nel libro Go4 recita:

Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

Interrompiamo un po 'di quello e guardiamolo nel contesto della programmazione del gioco.

Possibilità di parametrizzare il codice di richiamo

Ciò consente di configurare in modo dinamico la cosa che richiama il comando con un'azione da eseguire. Questo può essere ottenuto anche con i callback. Gli oggetti di comando possono servire come in sostituzione OO per i callback in una lingua che non li supporta in un modo che è necessario (ad esempio, nessun supporto per le funzioni di ordine superiore o nessun supporto per le chiusure); ma se hai bisogno di accedere o manipolare lo stato associato al comando in un secondo momento, o di supportare un'interfaccia più complessa, allora solo Execute (), avere una classe Command può aiutarti.

Nel libro, il modello introdotto nel contesto dello sviluppo di un framework per i menu delle applicazioni, in cui una voce di menu può essere configurata da un comando. Il bit importante è che la voce di menu non ha idea di cosa faccia o di quale sia l'oggetto di destinazione - non ha alcuna comprensione dell'operazione che esegue, sa solo che qualcosa dovrebbe accadere quando viene cliccato.

Puoi variare questa struttura di base; per esempio, il mio ricevitore può essere indirizzato indirettamente, tramite un ID di qualche tipo (e recuperato da qualche altro componente).

Nei giochi, e in particolare nell'IA del gioco, uno scenario piuttosto simile è quando si vuole supportare scripting - un comando può incapsulare uno script fornito dall'utente (e magari portare con sé alcuni metadati, e possibilmente un riferimento al motore di scripting). Qui, il codice chiamante sa quando e in quali circostanze eseguire uno script, ma non ha idea di cosa fare e quali entità influenzare. (Certo, ci sono altri modi per farlo). Ciò promuove la separazione delle preoccupazioni tra i diversi sistemi coinvolti (AI, Scripting).

Ma anche, considera qualcosa di meno esotico. Combinazioni di tasti. Potrebbero esserci più chiavi (o più trigger su diversi dispositivi di input) che invocano la stessa azione, oppure le azioni possono essere dipendenti dal contesto (la stessa chiave fa una cosa diversa in situazioni diverse). Inoltre, il giocatore può cambiarli in qualsiasi momento. Un modo per gestirli è disporre di un set di oggetti comando che puoi semplicemente inserire e uscire dal sistema che gestisce l'input, associandoli dinamicamente a vari trigger.

La capacità di effettuare richieste di coda

Una volta che hai questa infrastruttura in atto per mappare gli input ai comandi, puoi sfruttarli nel tuo sistema di IA per controllare gli NPC.

Ora hai detto:

Usually when programming AI you want the instructions to be executed instantly

Bene, non devono essere eseguiti proprio nel momento le decisioni sono prese - solo all'interno del ciclo corrente nel ciclo di gioco. Inoltre, se il gioco utilizza il modello ECS, un approccio al flusso di comandi potrebbe essere una buona idea. Inoltre, alcuni giochi eseguono i loro motori di intelligenza artificiale con una frequenza di aggiornamento diversa da quella del renderizzatore e del resto del gioco, e l'accodamento dell'uscita AI come comandi può essere un buon modo per avvicinarsi a questo.

Supporto per la registrazione

Questo può significare letteralmente il logging, ma pensiamo oltre. Un log è un flusso di eventi registrato. Questo può essere potenzialmente (quando costruito con un po 'di cura), riprodotto . Riproduci e amp; supporto demo pronto per l'uso! Aggiungi alcuni metadati di temporizzazione e con un certo sforzo questo può anche supportare cose come la meccanica di riavvolgimento temporale, in cui il giocatore può riavvolgere il tempo (fino a un certo punto) per riprovare lo stesso scenario (qualcosa sulla falsariga di ciò che è possibile in Braid o in GRID 2).

Extra extra

La possibilità di supportare annulla / ripristina è piuttosto auto-esplicativa, quindi non ci andrò.

Un'altra cosa interessante che puoi fare è combinarla con il pattern Composite, che ti consente quindi di avere comandi compositi - che sono fatti di sottocomandi. Questo può essere semplicemente considerato come una comodità per te come sviluppatore, ma questo potrebbe anche fornire supporto per la costruzione di editor dove gli utenti possono creare questi comandi compositi in una GUI, o anche abilitare l'utente a incorporare questo in un gameplay, dove il giocatore può creare comportamenti personalizzati come parte di una meccanica e far sì che il gioco li ricordi (dato che puoi serializzare e deserializzare i comandi, inclusi i comandi compositi).

Un altro vantaggio del trattamento dei comandi come oggetti o dati è che è possibile eseguirne in modo flessibile in parallelo (se le attività sono parallelizzabili), il che può migliorare le prestazioni.

    
risposta data 29.09.2018 - 02:21
fonte
0

Nel libro, la motivazione principale per usare il modello di comando in primo luogo è spiegata alcuni paragrafi prima delle virgolette e riguarda l'input dell'utente, non l'intelligenza artificiale.

We can use this same command pattern as the interface between the AI engine and the actors; the AI code simply emits Command objects.

Nel momento in cui "puoi usare questo stesso modello di comando come interfaccia tra il motore di intelligenza artificiale e gli attori" dovresti già utilizzare i comandi come metodo per tradurre l'input dell'utente in azioni nel gioco. Altrimenti la citazione non ha nemmeno senso.

The decoupling here between the AI that selects commands and the actor code that performs them gives us a lot of flexibility. We can use different AI modules for different actors.

Potrebbe essere vero che puoi ottenere gli stessi benefici con altri mezzi, ma utilizzando quello che hai già li ottieni gratuitamente.

    
risposta data 28.09.2018 - 20:05
fonte