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
Réponses:
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
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
RenderingComponent
qui 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
RenderComponent
avec des pointeurs versSprite
et desTransform
composants 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)
la source
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?bodys
et votretransforms
alignement 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.