Descrição da arquitetura
Estou criando (projetando) um sistema de entidades e tive muitos problemas. Estou tentando mantê-lo orientado a dados e eficiente, tanto quanto possível. Meus componentes são estruturas de POD (matriz de bytes para ser mais preciso) alocadas em conjuntos homogêneos. Cada pool possui um ComponentDescriptor - ele contém apenas o nome do componente, os tipos e os nomes dos campos.
A entidade é apenas um ponteiro para a matriz de componentes (onde o endereço atua como um ID da entidade). EntityPrototype contém o nome da entidade e a matriz dos nomes dos componentes. Finalmente, subsistema (sistema ou processador) que funciona em conjuntos de componentes.
Problema real
O problema é que alguns componentes dependem de outros (Model, Sprite, PhysicalBody, Animation depende do componente Transform), o que cria muitos problemas quando se trata de processá-los.
For example, lets define some entities using [S]prite, [P]hysicalBody and [H]ealth:
Tank: Transform, Sprite, PhysicalBody
BgTree: Transform, Sprite
House: Transform, Sprite, Health
and create 4 Tanks, 5 BgTrees and 2 Houses and my pools will look like:
TTTTTTTTTTT // Transform pool
SSSSSSSSSSS // Sprite pool
PPPP // PhysicalBody pool
HH // Health component
Não há como processá-los usando índices. Passo 3 dias trabalhando nisso e ainda não tenho nenhuma idéia. Em projetos anteriores, o TransformComponent estava vinculado à entidade - mas não era uma boa ideia. Você pode me dar alguns conselhos sobre como processá-los? Ou talvez eu deva mudar o design geral? Talvez eu deva criar pools de entidades (pools de pools de componentes) - mas acho que será um pesadelo para caches de CPU.
obrigado
Respostas:
Isenção de responsabilidade: puramente fora do meu conhecimento de classe de sistemas.
Inicialmente, pensei: por que não usar apenas uma função hash no ID da entidade para o seu índice?
Dessa forma, você obteria
Ou, no entanto, foram as entidades que foram colocadas. Você pode ter conjuntos para todos os componentes e entidades e usar o conjunto de entidades como "mestre", para que as colisões sejam verificadas na matriz de entidades. Mas é claro que você tem o problema de reciclar componentes e entidades.
Se o design do seu jogo permitir, você pode planejar com antecedência para onde cada tipo de entidade vai, para obter a embalagem mais eficiente possível. Digamos que as entidades 0-20 são reservadas para tanques, as entidades 21-30 para casas e 31-60 para BGTrees. Talvez você não consiga gerar com eficiência infinitos erros e meio que derrote o dinamismo dos sistemas de componentes, mas isso resolveria o problema. Não vejo uma maneira de comer seu bolo e comê-lo também.
Eu estava pensando em maneiras de talvez acelerar o passe de renderização, onde você tem um
RenderingComponent
que contém todos os dados de que o sistema de renderização precisa, para que ele possa passar por uma série dessas coisas, mas há uma sobrecarga de cópia de dados. Além disso, sempre que você desdiferenciar um ponteiro, estará pensando se ele ainda está no cache.Se você quer um jogo super rápido, eu diria que planeje sua alocação. Se você deseja uma arquitetura de jogo flexível, implante as hashtables e os IDs de string. Sempre que você desejar flexibilidade, precisará criar abstração e, portanto, sofrerá sobrecarga.
TL; DR;
Com base no que você descreveu, eu criaria um nível mais alto
RenderComponent
com ponteirosSprite
eTransform
componentes e daria as referências necessárias ao inicializar a entidade.(Desculpas por qualquer divagação percebida, estive pensando sobre isso no meu sistema também, então essa foi uma oportunidade para refletir sobre isso)
fonte
void update(u32 n, PhysicalBodyComponents* bodys, Transform* transforms)
Quero trabalhar em muitas entradas e dividir essa função em vários núcleos. É possível com hashmaps?bodys
e otransforms
array estejam alinhados. Isso é algo que você não pode solucionar sem adicionar uma camada de abstração ou planejar sua alocação. Sinto que não tenho o conhecimento necessário para falar sobre o dimensionamento para vários núcleos. Talvez encontre uma pergunta sobre segmentação e dimensionamento ou escreva sua própria.