Come gestire tutti gli oggetti NPC / AI sul server?


8

Sto scrivendo un MMO semplice e attualmente ho in atto l'architettura server-client in modo che più utenti possano vedersi e potersi muovere insieme ... ora è il momento di aggiungere nemici.

Mi chiedevo se qualcuno avesse collegamenti ad articoli che discutevano su come gestire al meglio le centinaia di oggetti NPC che devono essere gestiti nel mondo. Ho fatto qualche ricerca e non sono riuscito a trovare molte informazioni su come questo è fatto in genere.

Mi vengono in mente i due metodi per strutturare l'implementazione:

  1. Tenendo tutti gli oggetti NPC istanziati in un elenco e facendo in modo che un thread NPC li attraversi in sequenza, per vedere se ognuno ha una logica che deve essere elaborata ed eseguire le azioni necessarie. Non sono sicuro che le prestazioni di questo progetto siano sufficienti?
  2. Sistema basato sugli eventi. Creare un metodo nella classe NPC che elabora AI / Logic su di esso, fare in modo che questo metodo venga chiamato quando viene segnalato un evento associato, sia su un timer per funzionalità AI non interagite (come vagabondaggio), o segnalare l'evento esternamente dal pacchetto gestore (giocatore che si muove nelle vicinanze o giocatore che attacca nel raggio d'azione).

Uno di questi approcci è nel modo corretto? Quali altri metodi per farlo esistono?

Risposte:


5

Come sempre, l'architettura dipende dalle vostre esigenze. Quanti mob hai intenzione di avere? Quanto è complessa la loro IA? A cosa reagisce? Ogni quanto cambia il suo stato? Rispondi a queste domande e avrai una comprensione molto migliore di ciò che vuoi e come ottenerlo.

In generale, vorresti avere almeno un qualche tipo di sistema di eventi. L'intelligenza artificiale è generalmente definita in termini di eventi: "Quando A accade, fai B"; e se non hai eventi nel codice reale, dovresti in qualche modo tradurre queste definizioni.

Nella mia esperienza, puoi cavartela con una semplice implementazione in loop quando hai pochi mob davvero semplici (contrariamente a quanto sembra suggerire l'altra risposta). Ad esempio, nel nostro gioco attuale abbiamo centinaia di piccole istanze con ognuna al massimo 10 mob. E questi mob sono stupidi; L'intelligenza artificiale del 99% di essi può essere descritta in una frase: "Sto attaccando qualcuno? Altrimenti, attacca il giocatore più vicino". In questo caso un semplice loop è più che sufficiente: due volte al secondo controlliamo un nuovo target (e alcune altre cose per i rari mob "intelligenti"), e questo lo fa.

Tuttavia, quando hai mob più e / o più intelligenti, l'approccio ingenuo smette di funzionare. Affinché l'IA reagisca ad alcuni stimoli, dovresti scrivere un codice che lo rilevi all'interno del tuo ciclo AI. Ad esempio: supponiamo che il tuo mob dovrebbe fare qualcosa "quando viene colpito da un giocatore". Con un approccio ad anello, non c'è modo semplice per determinare se il mob è stato colpito. Quando l'IA è in esecuzione, puoi verificare che la salute del mob sia diminuita dall'ultimo tick o che il mob sia attualmente preso di mira da qualcuno. Ma non puoi rilevare hit reali senza ricorrere a hack, come salvare ogni informazione sui hit da qualche parte affinché AI possa accedervi in ​​un secondo momento.

In secondo luogo, scorre sempre un ciclo ingenuo, qualunque cosa accada. Quando hai molti mob, vuoi che l'IA funzioni il più velocemente possibile ... e il codice più veloce è il codice che non viene mai eseguito. Se disponi di mob che non sono attivi, vuoi che non eseguano l'intelligenza artificiale o che eseguano solo sporadicamente (come in, l'IA mobile errante dovrebbe funzionare solo quando decide dove andare dopo).

Con un approccio basato sugli eventi, puoi avere altri sottosistemi che inviano eventi AI ogni volta che è conveniente, eliminando il problema di "rilevare i colpi". Certo, alcuni eventi richiederebbero comunque il rilevamento del codice: l'esempio più noto è l'evento "approccio". E quando non esegui la tua routine AI in un ciclo quando non succede nulla, ottieni prestazioni.

Puoi anche usare un approccio ibrido. Invece di gestire immediatamente gli eventi AI, puoi inserirli in una sorta di coda. Quindi, quando viene eseguita la routine AI (in un ciclo), rimuove gli eventi da questa coda e li gestisce uno per uno. Con questa architettura, le prestazioni dell'IA potrebbero essere un po 'più lente, ma è più prevedibile; inoltre, puoi garantire che tutta l'IA venga eseguita su un singolo thread (che altrimenti potrebbe essere complicato). Questo tipo di loop può anche essere facilmente limitato saltando alcuni eventi (ad esempio, ogni iterazione AI gestisce solo i tre eventi più recenti, scartando il resto). Oppure gli eventi potrebbero essere prioritari e quelli meno importanti vengono scartati se si rileva che l'IA è in ritardo.

Nel complesso, l'approccio "loop con coda eventi" è probabilmente il più flessibile. Ma voglio ribadirlo: non limitarti a sceglierlo alla cieca come "il migliore". Pensa prima ai tuoi requisiti e un approccio più semplice potrebbe rivelarsi migliore.


e solo per completare questa risposta, puoi sempre aggiungere mob o rimuoverli dal tuo ciclo di controllo. per esempio. quando non c'è nessuno che osservi cosa sta facendo un mob non è logico fare tutte le cose che l'NPC farebbe in quel momento. così puoi facilmente filtrare molti mob e controllare se quelli importanti (di solito quelli abbastanza vicini ai giocatori) hanno bisogno di aggiornamenti
Ali1S232

Una "folla" è un gruppo di nemici o un singolo nemico?
Richard Marskell - Drackir,

"mob" è un singolo nemico. Il termine è stato coniato da Richard Bartle in MUD1, ed è l'abbreviazione di "mobile" - perché i mob si muovono un po ', al contrario di altri oggetti.
Nevermind,

2

Dipenderà dal numero di nemici che hai e da quanto saranno attivi.

Se hai molti nemici, ma non fanno molto per la maggior parte del tempo, un sistema di eventi potrebbe essere migliore. Se hai nemici che di solito stanno facendo qualcosa, il circuito potrebbe funzionare meglio poiché influisce sulla complessità del sistema di eventi e perché se gli eventi fossero in atto sparerebbero comunque comunque.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.