Problème de pools de composants de traitement - Sous-système d'entité

8

Description de l'architecture

Je crée (conçois) un système d'entités et j'ai rencontré de nombreux problèmes. J'essaie de le garder axé sur les données et efficace autant que possible. Mes composants sont des structures POD (tableau d'octets pour être précis) allouées dans des pools homogènes. Chaque pool a un ComponentDescriptor - il contient juste le nom du composant, les types de champ et les noms de champ.

L'entité n'est qu'un pointeur vers un tableau de composants (où l'adresse agit comme un ID d'entité). EntityPrototype contient le nom de l'entité et un tableau de noms de composants. Enfin le sous-système (système ou processeur) qui fonctionne sur les pools de composants.

Problème réel

Le problème est que certains composants dépendent d'autres (Model, Sprite, PhysicalBody, Animation dépend du composant Transform) ce qui pose beaucoup de problèmes pour les traiter.

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

Il n'y a aucun moyen de les traiter à l'aide d'indices. Je passe 3 jours à travailler dessus et je n'ai toujours pas d'idées. Dans les conceptions précédentes, TransformComponent était lié à l'entité - mais ce n'était pas une bonne idée. Pouvez-vous me donner quelques conseils sur la façon de les traiter? Ou peut-être devrais-je changer la conception globale? Je devrais peut-être créer des pools d'entités (pools de pools de composants) - mais je suppose que ce sera un cauchemar pour les caches CPU.

Merci

mani3xis
la source
Multijoueur? (C'est pertinent)
Jonathan Dickinson

Réponses:

2

Avertissement: Sortir purement de mes connaissances en classe de systèmes.

J'ai pensé à l'origine, pourquoi ne pas simplement utiliser une fonction de hachage sur l'ID d'entité pour votre index?

De cette façon, vous obtiendrez

T[A]nk:   Transform, Sprite, PhysicalBody
B[G]Tree: Transform, Sprite
H[O]use:  Transform, Sprite, Health

and create 4 Tanks, 5 BgTrees and 2 Houses and my pools will look like:

OGAGAGGOGGG // Entity pool (letters corresopnding to entity type)
TTTTTTTTTTT // Transform pool
SSSSSSSSSSS // Sprite pool
P P P  P    // PhysicalBody pool
H      H    // Health component

Ou bien c'était les entités qui étaient placées. Vous pouvez avoir des pools pour tous les composants et pour les entités et utiliser le pool d'entités comme «maître», de sorte que les collisions sont vérifiées par rapport au tableau d'entités. Mais bien sûr, vous avez le problème du recyclage des composants et des entités.

Si la conception de votre jeu le permet, vous pouvez planifier à l'avance l'emplacement de chaque type d'entité afin d'obtenir l'emballage le plus efficace possible. Supposons que les entités 0-20 sont réservées pour les réservoirs, les entités 21-30 pour les maisons et 31-60 pour les BGTrees. Vous pourriez ne pas être en mesure de générer efficacement des baddos infinis et de vaincre le dynamisme des systèmes de composants, mais cela résoudrait le problème. Je ne vois pas comment avoir votre gâteau et le manger aussi.

Je pensais à des moyens d'accélérer peut-être la passe de rendu lorsque vous en avez une RenderingComponentqui contient toutes les données dont le système de rendu a besoin pour pouvoir simplement passer à travers un tableau de ces choses, mais il y a ensuite des frais généraux de copie des données. De plus, chaque fois que vous déréférencer un pointeur, vous pensez s'il est toujours dans le cache.

Si vous voulez un jeu super rapide, je dirais de planifier votre allocation. Si vous souhaitez une architecture de jeu flexible, déployez les tables de hachage et les ID de chaîne. Chaque fois que vous voulez de la flexibilité, vous devez créer une abstraction, et donc encourrez des frais généraux.

TL; DR;
Sur la base de ce que vous avez décrit, je créerais un niveau supérieur RenderComponentavec des pointeurs vers Spriteet des Transformcomposants et lui donnerais les références nécessaires lors de l'initialisation de l'entité.

(Toutes mes excuses pour toute randonnée perçue, j'ai aussi pensé à cela dans mon système, donc c'était l'occasion d'y réfléchir)

michael.bartnett
la source
Je ne sais pas si les cartes de hachage sont si efficaces. Je veux avoir un système d'entité où les sous-systèmes contiennent des fonctions DOD comme: void update(u32 n, PhysicalBodyComponents* bodys, Transform* transforms)Je veux travailler sur de nombreuses entrées et diviser cette fonction sur plusieurs cœurs. C'est possible avec des hashmaps?
mani3xis
Les hashmaps sont simplement un moyen d'identifier les relations entre les entités et les composants. Cela dépend de la façon dont votre jeu est configuré, mais je ne vois pas de moyen efficace de garantir que votre bodyset votre transformsalignement s'aligneront. C'est juste quelque chose que vous ne pouvez pas contourner sans ajouter une couche d'abstraction ou planifier votre allocation. Je pense que je n'ai pas l'expertise pour parler de la mise à l'échelle vers plusieurs cœurs. Peut-être trouver une question sur le filetage et la mise à l'échelle ou écrire la vôtre.
michael.bartnett
La mise à l'échelle est facile lorsque les fonctions fonctionnent sur des tableaux linéaires - je peux configurer une plage pour chaque cœur et simplement l'exécuter. C'est pourquoi j'essaie d'éviter les hashmaps. J'essaierai de repenser ce système d'entités. Je dois être très prudent avec les caches manqués - La PS2 a une mémoire RAM très limitée, etc. BTW: Rien n'est impossible :)
mani3xis
Rien n'est impossible, mais tout n'est pas faisable;). Vous pouvez viser la simplicité et l'élégance de la mise en œuvre, la vitesse d'exécution et la consommation de mémoire: choisissez-en deux. Lorsque vous trouverez votre solution, veuillez la poster comme réponse Je suis certain que je ne suis pas le seul à aimer la voir.
michael.bartnett