Como sempre, a arquitetura depende de seus requisitos. Quantos mobs você vai ter? Quão complexa é a IA deles? A que reage? Com que frequência ele muda de estado? Responda a essas perguntas e você entenderá muito melhor o que deseja e como obtê-lo.
Geralmente, você deseja ter pelo menos algum tipo de sistema de eventos. A IA é geralmente definida em termos de eventos: "Quando A acontecer, faça B"; e se você não tiver eventos no código real, teria que traduzir essas definições de alguma forma.
Na minha experiência, você pode se dar bem com uma implementação de loop simples quando tiver poucos e realmente simples mobs (ao contrário do que a outra resposta parece sugerir). Por exemplo, em nosso jogo atual, temos centenas de pequenas instâncias, cada uma com 10 mobs no máximo. E essas multidões são estúpidas; A IA de 99% deles pode ser descrita em uma frase: "Estou atacando alguém? Se não, ataque o jogador mais próximo". Nesse caso, um loop simples é mais do que suficiente - duas vezes por segundo, procuramos um novo alvo (e algumas outras coisas para os raros mobs "inteligentes"), e é isso.
No entanto, quando você tem mobs mais e / ou mais inteligentes, a abordagem ingênua para de funcionar. Para que a IA reaja a algum estímulo, você precisa escrever um código que o detecte dentro do loop da AI. Por exemplo: suponha que sua turba faça algo "quando atingida por um jogador". Com uma abordagem em loop, não há uma maneira fácil de determinar se a multidão foi atingida. Quando a IA está em execução, você pode verificar se a saúde da multidão diminuiu desde o último tick ou se a multidão está atualmente sendo alvo de alguém. Mas você não pode detectar hits reais sem recorrer a hacks, como salvar cada informação de hit em algum lugar para a IA acessá-las posteriormente.
Em segundo lugar, um loop ingênuo sempre é executado, não importa o que aconteça. Quando você tem muitos mobs, deseja que a IA seja executada o mais rápido possível .. e o código mais rápido é o código que nunca é executado. Se você tem mobs que não estão ativos, deseja que eles não executem a IA ou executem apenas esporadicamente (como no caso, a IA da multidão errante só deve ser executada quando decidir para onde ir).
Com a abordagem baseada em eventos, você pode solicitar que outros subsistemas enviem eventos de IA sempre que conveniente, eliminando o problema de "detecção de ocorrências". Certamente, alguns eventos ainda exigiriam a detecção de código: o exemplo mais notável é o evento "abordagem". E quando você não executa sua rotina de IA em loop quando nada acontece, você obtém desempenho.
Você também pode usar uma abordagem híbrida. Em vez de manipular eventos de IA imediatamente, você pode colocá-los em algum tipo de fila. Em seguida, quando a rotina do AI é executada (em um loop), ela remove os eventos dessa fila e os lida um por um. Com essa arquitetura, o desempenho da IA pode ser um pouco mais lento, mas é mais previsível; Além disso, você pode garantir que toda a IA seja executada em um único segmento (o que pode ser complicado). Esse tipo de loop também pode ser facilmente controlado, ignorando alguns eventos (por exemplo, cada iteração de IA lida apenas com os três eventos mais recentes, descartando o restante). Ou os eventos podem ser priorizados e os menos importantes descartados se a IA estiver atrasada.
No geral, a abordagem "loop com fila de eventos" é provavelmente a mais flexível. Mas quero reiterar: não o escolha cegamente como "o melhor". Pense primeiro nos seus requisitos, e uma abordagem mais simples pode se tornar melhor.
Vai depender do número de inimigos que você tem e de quão ativos eles serão.
Se você tem muitos inimigos, mas eles não fazem muito na maioria das vezes, um sistema de eventos pode ser melhor. Se você tem inimigos que geralmente estão fazendo algo, o loop pode funcionar melhor, pois leva em consideração a complexidade do sistema de eventos e porque, se os eventos estivessem no local, eles constantemente disparariam.
fonte