Qual é o papel dos “sistemas” em uma arquitetura de entidade baseada em componentes?

177

Eu tenho lido muito sobre componentes e sistemas de entidades e pensei que a idéia de uma entidade apenas sendo um ID é bastante interessante.

No entanto, não sei como isso funciona completamente com o aspecto de componentes ou o aspecto de sistemas. Um componente é apenas um objeto de dados gerenciado por algum sistema relevante. Um sistema de colisão usa algum BoundsComponent junto com uma estrutura de dados espaciais para determinar se ocorreram colisões.

Tudo de bom até agora, mas e se vários sistemas precisarem acessar o mesmo componente? Onde os dados devem ficar? Um sistema de entrada pode modificar o BoundsComponent de uma entidade, mas o (s) sistema (s) de física precisa acessar o mesmo componente que um sistema de renderização.

Além disso, como as entidades são construídas? Uma das vantagens que eu já li muito é a flexibilidade na construção da entidade. Os sistemas estão intrinsecamente vinculados a um componente? Se eu quiser introduzir algum novo componente, também tenho que introduzir um novo sistema ou modificar um existente?

Outra coisa que li com frequência é que o 'tipo' de uma entidade é inferido por quais componentes ela possui. Se minha entidade é apenas um ID, como posso saber que minha entidade robô precisa ser movida ou renderizada e, portanto, modificada por algum sistema?

Desculpem o post longo (ou pelo menos parece isso na tela do meu telefone)!

bio595
fonte

Respostas:

336

Existem várias maneiras de representar e implementar sistemas de componentes de entidades, mas aqui está uma explicação de uma maneira. Lembre-se de que não há uma definição concreta de arquiteturas de entidade / componente / sistema, portanto, essa é apenas uma implementação.

Vou apresentar uma analogia para arquiteturas de entidade / componente / sistema que podem ajudar. Vamos pensar em uma entidade como uma chave.

A entidade

Chave da entidade

As chaves também têm dentes (azul escuro). Os dentes da nossa chave de entidade são os componentes que a compõem. Você pode distinguir as entidades por seu ID, mesmo que elas tenham os mesmos dentes. Então, no que as chaves se encaixam? Fechaduras. Fechaduras são nossos sistemas. Por exemplo, um sistema de movimento.

O sistema

Bloqueio do sistema de movimento

A fechadura só funciona se nossa chave tiver dentes para posição e velocidade. Este sistema processa apenas entidades que possuem uma posição e uma velocidade. Existem várias maneiras de configurar como esses sistemas reconhecem quais entidades processar, mas uma maneira é usar a long. Cada bit é reservado para um tipo de componente. No nosso exemplo, vamos assumir um tipo de 4 bits em vez de um comprimento de 64 bits. Nossa entidade de exemplo teria todos os componentes disponíveis. Então é a chave seria 1111. Em seguida, o sistema está procurando por qualquer entidade que possua um 11--. (O -representante não se importa, porque o movimento não se importa se houver um sprite ou saúde). Pode verificar uma entidade com uma ANDoperação simples . Portanto, nossa entidade corresponde se ((1111 & 1100) == 1100). Se eu te perdi lá, confira um pouco mais sobre as operações bit a bit .

Como você pode ver, os sistemas têm acesso a recursos externos. Eles podem acessar a hora, gráficos, som e assim por diante. Eles são simplesmente pequenos processadores que pegam uma chave de cada vez e processam dados. Você vê que o sistema de movimento leva a velocidade, tempo delta e posição; depois faz alguns cálculos e armazena o resultado novamente na posição.

As chaves de entidade são realmente fáceis de gerar. Você pode adicioná-los ou removê-los à vontade. A entidade não se importa, é apenas uma maneira de agrupar e reter os componentes. Os componentes não têm interdependência. Quanto mais os componentes se aproximam da interação entre si, é quando um sistema opera neles e usa dados de um para atualizar outro, como nosso exemplo de movimento.

Vamos dar uma olhada em outro sistema para ajudar a solidificar a ideia:

Bloqueio do sistema de desenho

Este é o nosso sistema de desenho. Ele procura por componentes que correspondam 1-1-. Essa entidade corresponde porque: ((1111 & 1010) == 1010)Além disso, você pode ver que esse sistema envia informações para a tela, desenhando o sprite de entidade em sua posição.

OK, mais um. Vamos olhar para outra entidade e ver como ela pode se encaixar no nosso exemplo até agora.

Chave de entidade não móvel

Como você pode ver, essa entidade possui menos componentes anexados a ela. Observando os componentes que possui, parece que ele pode ser um item estático como uma rocha. Apenas tem uma posição e um sprite. Não vai se mexer e não será afetado por nenhuma mudança de saúde. Essa entidade produziria uma chave 1010. Então, quais sistemas operam nessa entidade? Vamos checar:

Contra o nosso sistema de movimento: ((1010 & 1100) != 1100)Não. Parece que o sistema de movimento não se importa com essa entidade, porque não possui os componentes necessários.

Contra o nosso sistema de desenho: ((1010 & 1010) == 1010)Ei, isso é uma partida. Essa entidade será operada pelo sistema de desenho. O sistema de desenho desenhará o sprite na posição definida.


Espero que você possa ver como seria fácil adicionar outro sistema que usaria nossos componentes e operasse neles. Deixe-me garantir que resolvi suas perguntas:

E se vários sistemas precisarem acessar o mesmo componente? Onde os dados devem ficar?

Normalmente, os sistemas operam um após o outro. Eles processam todas as entidades que atendem aos requisitos e, em seguida, o próximo sistema faz o mesmo e assim por diante. Os dados vivem com a entidade. Não deve haver nada armazenado no sistema, é apenas um bloqueio que é ativado, a chave é onde as informações ficam e se movem de bloqueio em bloqueio.

Como são construídas as entidades? Os sistemas estão intrinsecamente vinculados a um componente? Se eu quiser introduzir algum novo componente, também tenho que introduzir um novo sistema ou modificar um existente?

Entidades são apenas sacos de componentes. Eles têm um ID exclusivo e uma lista de componentes. Os sistemas são vinculados apenas aos componentes da maneira descrita acima. Você pode ter componentes sem sistemas que os operem, mas isso é inútil. Da mesma forma, você pode ter sistemas que estão procurando componentes que nenhuma entidade possui. Isso é menos inútil, porque eles podem estar apenas esperando a criação de uma entidade que corresponda ao seu bloqueio. Então, sim, se você introduzir um novo componente, você deseja criar um sistema que utilize esse componente. Caso contrário, você está apenas adicionando dentes à sua chave para uma trava que não existe.

Se minha entidade é apenas um ID, como posso saber que a entidade do meu robô precisa ser movida ou renderizada e, portanto, modificada por algum sistema?

Acho que respondo a isso com a ideia de uma longchave que define os componentes contidos em uma entidade. Você sabe porque a chave se encaixa na fechadura.

Ufa! Esse foi um longo post! (Ou pelo menos parece isso no meu monitor grande.)

MichaelHouse
fonte
23
Essa analogia chave é realmente útil para entender toda a idéia agora. Ideia brilhante! Lol no seu último parágrafo :)
bio595 02/07/2012
16
+1 Para a maior e melhor explicação do sistema de entidade-componente que eu já vi. : O!
knight666
7
-1 de mim - não porque essa seja uma abordagem ruim, mas porque está sendo retratada como a abordagem. No entanto, existem muitos sistemas em que não há separação de componentes e serviços (por exemplo, no Unity), e existem maneiras mais simples de os sistemas saberem quais entidades processar (basta adicioná-los quando a entidade for criada).
Kylotan
37
@Kylotan Eu digo " Existem várias maneiras de configurar como esses sistemas reconhecem quais entidades processar, mas uma maneira é usar a long. " Além disso, eu geralmente reservo o voto negativo para respostas que não são úteis (como o texto em foco diz). Eu acho que você gastaria muito tempo votando se fizesse isso por todas as respostas que não cobrissem 100% dos tópicos abordados.
Michaelhouse