Design baseado em componentes / entidades + Árvores de comportamento => como integrar?

9

Para o meu projeto atual, implementei um sistema baseado em componente / entidade , basicamente seguindo a maioria das melhores práticas existentes nessa área indefinida .

Então, eu tenho Entidades (um pouco estendidas) , que são basicamente um intID, um Nome legível por humanos, um std::mapdos componentes e um long"indicador de tipo" que é usado para mostrar quais componentes estão presentes (eu tenho dois enumpara todos os componentes) tipos e sempre que um componente é adicionado à entidade, eu automaticamente altero esse tempo por meio de operações bit a bit, comparo esta resposta ).

Depois, há os componentes , também bastante simples: intID, enumcomo tipo de componente, ponteiro de entidade pai e uma std::mapde todas as propriedades que esse componente possui.

Por fim, alguns sistemas / gerentes que lidam com o processamento lógico real. Eles primeiro verificam se a Entidade atualmente processada possui um long"indicador de tipo" correspondente = todos os componentes necessários para esse sistema estão presentes. Em seguida, ele acessa algumas propriedades, se necessário, ou chama diretamente algumas funções no respectivo componente ou envia algumas mensagens (por meio de um despachante de mensagens).

Conclusão: até aqui, um sistema baseado em entidade / componente bastante orientado a eventos combinado com uma abordagem orientada a dados (comparar, componentes não possuem variáveis ​​de dados codificadas), mas um mapa genérico, como (alguns) componentes / arquétipos de componentes serão lidos posteriormente a partir de arquivos com a opção de adicionar dados adicionais, que não fazem parte do código real do componente.

Agora, eu também gostaria de introduzir as Árvores de comportamento (baseadas no AiGameDev BTSK ) nesse projeto, mas não tenho certeza se e como elas devem ser vinculadas aos componentes já existentes ou como integrar esses projetos em geral.

Várias idéias / pontos / perguntas relacionadas vêm à mente:

  1. Meus BTs serão lidos a partir de arquivos (novamente). No momento, tenho dificuldade em ver como, no entanto, seria melhor fazer a conexão entre um BT Actionnessa árvore e a codificação real no meu aplicativo. Devo criar algum tipo de mapa entre os nomes das ações usadas nos arquivos BT e um ponteiro de função para a implementação lógica real? Qual é a abordagem usual para resolver isso?

  2. Suponho que terei que criar BTs para todos os meus Entitytipos diferentes (portanto, para cada combinação de componentes relevante para a lógica do jogo / IA, conforme indicado pelos vários "indicadores de tipo" longos mencionados anteriormente). Como resultado, não faz sentido colocar as BT Actionimplementações nos componentes, pois provavelmente muitos componentes estarão envolvidos por ação, não é?

  3. Então, a BT Actionlógica deveria estar em um / vários sistemas separados (para cujos métodos o mapa da idéia nº 1 aponta para)? O sistema verificaria, de acordo com meu long"indicador de tipo", se o EntityBT atualmente está marcado e que foi instruído a executar uma determinada ação (= método no sistema) está realmente autorizado a fazê-lo (= possui os componentes necessários). Mas, se não (porque, por exemplo, o criador da BT ignorou uma situação específica, onde um componente necessário pode não estar mais conectado à Entidade no tempo de execução), nada aconteceria.

Questões:

  • Existem conceitos comprovados para esse tipo de integração?
  • Qual é a sua opinião sobre os meus 3 pontos acima?
  • Alguma outra coisa que vem à mente, também em relação ao meu design baseado em componentes / entidades em geral?
Philip Allgaier
fonte
Re-ponto 1: As árvores de comportamento nada mais são do que uma DSL visual usada principalmente para criar o comportamento do personagem. Um componente BehaviorTree não deve fazer nada mais ou menos do que um componente Script faria. Re ponto 3: Qual o motivo do uso de um mapa em campos regulares?
Eric
# 1: O que significa "DSL" neste contexto? # 3: Desculpe, mas não posso segui-lo neste. Gostaria de explicar por favor o que você quer dizer?
Philip Allgaier
11
provavelmente idioma específico do domínio, ou seja. uma sintaxe personalizada para trabalhar com um problema muito específico.
Patrick Hughes
Patrick está correto, embora uma semântica também faça parte dela e "muito" possa ser excluído dessa definição. - Re 3: Minhas desculpas, ele deve ler: "Qual é o motivo para usar um mapa em campos regulares nos componentes ?"
Eric
Re 3: Quero a capacidade de especificar dinamicamente mais tarde propriedades adicionais fora do código C ++ (buzzword: data-driven). Por uma questão de simplicidade, eu (pelo menos por enquanto) coloco todas as propriedades nessa estrutura genérica (usando mapas), mesmo aquelas que são corrigidas no código e, portanto, podem ser campos C ++ reais. Talvez seja necessário revisar isso posteriormente, se isso se tornar um problema de desempenho ...
Philip Allgaier

Respostas:

2

Atualmente, tenho dificuldade em ver como, no entanto, seria melhor fazer a conexão entre uma ação BT nessa árvore e a codificação real no meu aplicativo. Devo criar algum tipo de mapa entre os nomes das ações usadas nos arquivos BT e um ponteiro de função para a implementação lógica real? Qual é a abordagem usual para resolver isso?

Esqueça os ponteiros de função e pense nos objetos. Cada nó na árvore de comportamento (BT a partir de agora) corresponderia idealmente a um objeto no seu código. Esses objetos terão uma interface padrão para permitir que você os organize como uma árvore e para atravessá-los. Um conjunto de ponteiros de função é bom para o comportamento, mas não captura a estrutura da sua árvore.

Como resultado, não faz sentido colocar as implementações do BT Action nos componentes, pois provavelmente muitos componentes estarão envolvidos por ação, não é?

Eu esperaria que as entidades tivessem um único componente BehaviorTree que armazena os dados relevantes para o BT dessa entidade. A execução do BT é feita pelo componente BT ou pelo subsistema BT, dependendo de como você lida com os componentes em seu sistema. Como praticamente qualquer coisa usando componentes, eles terão que se referir a outros componentes para fazer o trabalho, mas esses outros componentes não precisarão saber nada sobre BTs.

As diferentes ações disponíveis seriam, no nível mais simples, codificadas nos vários objetos do nó BT. Eles devem ser capazes de fazer a entidade relevante agir manipulando os componentes conforme necessário, por exemplo. acessando o componente de movimento para mover.

Kylotan
fonte
Parágrafo 1: Sim, o BT em si será um objeto (como eu disse como a versão do AiGameDev). Eu estava pensando nos functores para as próprias ações, mas o seu Parágrafo 2 mudou isso. Por alguma razão, essa abordagem realmente simples nunca me ocorreu (Entidade com sua própria instância de membro BT). Provavelmente, devido à coisa totalmente nova dos componentes, eu não pensava mais direito e simplicidade, então estava procurando uma maneira de misturar componentes com as coisas da BT, mas isso não é realmente necessário.
Philip Allgaier
A principal coisa em que eu estava perdido anteriormente era como conectar a ação à entidade. Agora está claro: as ações sabem a qual entidade, através de sua árvore, a qual, em troca, conhece a entidade à qual pertence.
Philip Allgaier
@ Philip Allgaier Estou curioso, como você acabou criando o nó BT? Você o criou como 1 nó de comportamento = 1 entidade (que seria muitas entidades por 1 objeto de jogo), ou criou o nó como uma classe normal (não relacionada ao ECS) ou usou outras abordagens? Obrigado!
precisa saber é o seguinte