Em um local virtual, totalmente orientado à rede, com um número arbitrário de jogadores e um número arbitrário de inimigos, quais dados devem ser armazenados em cache na memória do servidor, a fim de otimizar a simulação suave da IA?
Tentando explicar, digamos que o jogador A veja o jogador B para E e o inimigo A para G. Cada um desses jogadores vê o jogador A, mas não necessariamente um ao outro. O mesmo se aplica aos inimigos. Pense nesta questão de uma perspectiva descendente, por favor.
Em muitos casos, por exemplo, quando um jogador dispara sua arma, o servidor trata o som como um "sinal" radial que todas as outras entidades ao seu alcance "ouvem" e reagem.
Fazer essas pesquisas o tempo todo em uma área inteira, contendo possivelmente muitos jogadores e inimigos não relacionados, parece ser um problema, quando o orçamento para cada agente de IA é tão pequeno.
Toda entidade deve armazenar em cache o que entra e sai de seu raio de consciência? Existe uma ótima maneira de rastrear as entidades por perto sem inundar a memória com esses caches?
E quanto a outros problemas relacionados à IA que possam surgir, depois de assumir que o anterior funciona bem? Estamos falando de ambientes com possivelmente centenas de inimigos, um enxame.
fonte
Respostas:
Existem várias maneiras de fazer isso, mas elas dependem de onde você tiver uma grande quantidade de interações ou de uma população muito densa.
Infelizmente, se você deseja que sua simulação mantenha uma boa precisão, precisará lidar com a maioria dos eventos gerados por todos os atores e encontrar todos / a maioria dos atores que requerem notificação.
Colisões área baratos
Em relação ao problema nas áreas de conscientização, você pode resolvê-lo usando a detecção simples de colisão.
Em um mundo 2D, a detecção de colisões em círculos é "barata". Por exemplo, a operação para detectar se um ponto está em um círculo leva apenas 2 subtrações, 2 multiplicações e uma adição. Você não precisa fazer a raiz quadrada, pois pode armazenar e comparar o raio quadrado da sua área com a distância quadrada diretamente.
Se você usar o círculo 2D em um mundo 3d, ele funcionará basicamente como um cilindro. Pode ser uma maneira conveniente de criar áreas se a altura não for muito importante.
Raio orientado a eventos
Se o volume de eventos (tiroteio, movimento ...) for baixo, você poderá tentar detectar cada ator afetado por cada evento. Seus eventos irão gerar áreas (onde eles podem ser ouvidos).
Esse é o método mais simples de implementar; também é o mais flexível, pois você pode captar impactos de projéteis / projéteis originários de atores fora de uma área de conscientização.
Por outro lado, uma vez que o volume de eventos aumenta, você pode ter que reduzir o número de eventos que acionam varreduras de área ou reduzir o número de atores verificados por evento.
-> Você também pode criar pequenas zonas (eventos) em que todos os eventos são registrados juntos e processados em grandes quantidades (ou seja, 2 impactos de bala e uma etapa de pé ocorrendo em uma zona, usarão apenas uma varredura e serão enviados a todas as entidades afetadas). <-
Áreas orientadas ao ator
Você pode usar o princípio "área de conscientização". Ou seja, se um ator colide com a área de percepção (círculo) de outro ator, você simplesmente adiciona o ator colidindo a uma lista de atores potencialmente interagindo. Dependendo de como o seu mecanismo é construído, você pode se registrar para receber mensagens sonoras e outros eventos originários dos atores da lista.
Para verificar o contato visual, você também pode fazer suas varreduras visuais apenas na lista de atores registrados.
Você não precisa verificar se há alterações na área de conscientização a cada marca. Você pode fazer isso de tempos em tempos, a cada 5 a 30 ticks, por exemplo.
Se as listas começarem a crescer, você poderá limitá-las ao tamanho máximo. Mas então você terá que priorizar os atores para adicionar / trocar nas listas.
Abordagem mista
Você pode misturar as duas abordagens. Você pode registrar os atores nas áreas de conscientização para eventos como pegadas, narizes de motores, etc ... E outros eventos (impactos de projéteis, explosões, etc ...) podem desencadear varreduras com base em sua importância. Há uma chance muito maior de alguém ouvir uma explosão de granada do que o impacto de uma bala; portanto, a explosão da granada deve desencadear uma varredura mais extensa do que o impacto da bala.
Eu recomendo que você comece a implementar o raio do evento primeiro. Uma vez que este funcione e você possa reduzir / aumentar a precisão desse método à vontade, poderá começar a implementar as áreas de conscientização do ator. Dessa forma, você poderá começar a mover alguns eventos para o segundo sistema.
Pools de contexto
Nem todos os atores precisam ser notificados de todos os eventos. Por exemplo, uma torre antiaérea não precisa ser notificada sobre impactos de balas e pegadas ao redor dela, mesmo a presença de unidades terrestres pode ser ignorada em algumas unidades.
Se você encontrar muitos casos especiais, poderá criar um conjunto diferente de áreas de conscientização. Um ator pode tornar sua área de conscientização ativa em vários pools. Por exemplo, você pode querer que suas unidades terrestres reajam às unidades terrestres apenas enquanto algumas unidades equipadas com mísseis e laser também possam reagir às unidades aéreas. As aeronaves nunca precisam ser notificadas sobre impactos no solo, exceto explosões ...
Obviamente, você não precisa criar várias "listas" para os pools. Você pode simplesmente usar uma máscara de bits e definir a máscara certa para cada ator / área. Desta forma, você pode filtrar com um simples ou antes de verificar a distância.
Agregação
Se você vir as listas em cada área de conscientização crescerem e a memória for escassa, você poderá agregar áreas de conscientização para grupos de inimigos (equipes, esquadrões, pelotões, bandos, enxames ...), desde que permaneçam próximos um do outro. Dessa forma, um esquadrão inteiro pode se registrar para eventos ou outros atores / grupos que entram na sua área de conscientização.
Basicamente, a entidade do grupo se torna um substituto / proxy para todas as verificações enquanto todos os membros do grupo são removidos dos conjuntos.
Este princípio também pode ser aplicado a todas as unidades dentro de um veículo.
Ativações por proximidade
Se o servidor estiver realmente superpovoado de bots (e você realmente precisar mantê-los vivos), você poderá ativar a conscientização / IA apenas em pessoas dentro de uma "área de ativação especial em torno de cada jogador". Dessa forma, os robôs (ou grupos) dentro de uma ou mais áreas de ativação mantêm a si mesmos e a área de conscientização ativada (na piscina de colisão). Caso contrário, a área de conscientização é removida das piscinas das áreas ativas.
A frequência com que essas "áreas de ativação" pesquisam "áreas de conscientização" pode variar dependendo da velocidade do player. Um jogador que viaja em velocidade mais alta aciona mais ativações do que um jogador que acampa uma zona (necessário pelo menos para ativar roaming bots e desativar bots que saem da área).
Além disso, você pode desativar a área de ativação de um jogador se ele embarcar em um veículo e atribuir uma área de ativação ao veículo se ele não tiver um. Dessa forma, 10 jogadores que viajam no mesmo veículo não precisam ter 10 áreas de ativação.
Delegação
Se você não tem medo de trapaceiros e outros criadores de problemas, pode delegar parte da detecção de eventos no aplicativo cliente.
O servidor pode enviar periodicamente uma lista de atores próximos (bots e players) que serão notificados pelos aplicativos clientes. O aplicativo cliente terá que fazer a varredura e a detecção de eventos para todos os eventos gerados pelo player. Por exemplo, pode enviar a lista de atores para notificar sobre um tiro, um impacto de bala ou pegadas.
Esta é uma opção, pode ser válida dependendo do tipo de jogo que você está fazendo. Essa é uma idéia teórica e eu não recomendaria fazer isso até que você tenha controle total sobre os clientes delegados (servidores de bot ou clientes protegidos).
Eu espero que isso ajude.
fonte