Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow entities to store multiple components with the same type #1527

Open
Tracked by #3742
alice-i-cecile opened this issue Feb 26, 2021 · 8 comments
Open
Tracked by #3742

Allow entities to store multiple components with the same type #1527

alice-i-cecile opened this issue Feb 26, 2021 · 8 comments
Labels
A-ECS Entities, components, systems, and events C-Enhancement A new feature S-Needs-Design-Doc This issue or PR is particularly complex, and needs an approved design doc before it can be merged

Comments

@alice-i-cecile
Copy link
Member

This tracking issue comes out of #1525. This feature is still very much up for debate, and this initial post paraphrases the initial definition by @cart from that PR .

Definition

Tags are archetype-specific by-value data that affects archetype identity

Usage

ArchetypeA could have [A, B, C] table components and [D(1)] "tag" component. ArchetypeB could have [A, B, C] table components and a [D(2)] tag component. The archetypes are different, despite both having D tags because the value inside D is different.

Implementation

Tags could potentially build on top of the archetype.unique_components added in #1525 for Resource storage.

@alice-i-cecile
Copy link
Member Author

Relationship to Indexes

@alice-i-cecile:

These sound a lot like minimal versions of indexes (#1205), but run into the issues discussed by Sander with the "pluggable storage model" approach: namely, you're blending concerns and that you often want to be able to index the same component in more than one way. I don't think this is a great approach to a very real issue.

@cart:

I don't think its a "pluggable storage" (as described in the discord discussion) and it doesn't suffer from the "multiple indices" problem. You can have (and query for) any number of tags. Its just a different form of archetype identity other than "has(component)". I view it more as a more limited form of Sander's relationship stuff (which are also typed values that affect archetype identity).

@alice-i-cecile
Copy link
Member Author

alice-i-cecile commented Feb 26, 2021

Naming and Use Cases

@Ratysz:

If we do, we really should think up a better name - I've seen people misunderstand what they are and confuse them with marker components.

@cart:

I think the primary motivator is to use them as "indices" (ex: give me everything with Parent(x), Handle, etc). We could call them that (and "market" them as such?).

I think one of the big issues with the legion implementation was that tags were required in every spawn api. Users were forced to think about them.

@alice-i-cecile
Copy link
Member Author

alice-i-cecile commented Feb 26, 2021

Archetype Fragmentation

@Ratysz:

I remember that when Legion shed its tags (I think that was a thing that happened, it's been a while) folks were talking about there not being a real usecase for them, citing the fate of the same feature in Unity. When this feature was suggested for hecs, @Ralith raised concerns that overreliance on tags could fragment archetypes more than necessary, impacting performance; stateful queries should help here, though.

@Ralith:

They don't do anything about the fundamental "problem," which is that you're (intentionally!) fragmenting your archetypes. Since that's really the entire point of the feature, it's up to the user to do so iff it's beneficial, which is a nice option to have in theory but could be a footgun in practice, suggesting that the feature should be justified by a strong use case.

@cart:

Yeah its worth measuring. Our sparse iteration performance is pretty great now, but it will still have some indirection in this case because Tags serve as "non-table filters", which means we can't directly iterate tables. We'd instead need to iterate archetypes like we do for sparse sets (which has the potential to jump around positions in tables, although in practice they still tend to glob up in cache friendly ways). I expect perf to still big pretty good, but not as good as direct table iteration. But yeah maybe separate index storage is the right call.

@alice-i-cecile alice-i-cecile added A-ECS Entities, components, systems, and events C-Enhancement A new feature labels Feb 26, 2021
@cart
Copy link
Member

cart commented Feb 26, 2021

One more bit of detail here:

[...] I expect perf to still big pretty good, but not as good as direct table iteration. But yeah maybe separate index storage is the right call.

Storing the index in Archetypes wouldn't fragment tables but it would fragment access patterns in those table. Storing the indices in something that doesn't affect archetype identity (ex: a Map<Index, Vec<Entity>>) would still fragment access patterns.

This could be "optimized" by sorting the Entity list according to table order (both in the Archetype impl and in the "separate storage" impl). The benefit of doing that in the Archetype is that you only need to do the sorting once (and it would also improve "untagged" / normal mixed table+sparse set iteration performance)

@Ratysz
Copy link
Contributor

Ratysz commented Feb 27, 2021

[...] we really should think up a better name [...]

"indices"

I was thinking more along the lines of "flyweight". Back when Legion had tags, in one of the experiments I did with it I've stored immutable data common among kinds of entities in a tag, e.g. a copy of the base mob properties, and handles to sprites and sounds it used.

Although, this could very well be a niche case, since I've spawed entities fully-formed with all the components they would ever use, and the archetypes never changed after first being populated.

@tigregalis
Copy link
Contributor

What would the usage API look like? How would you query for a specific tagged archetype?

@mtsr
Copy link
Contributor

mtsr commented Mar 20, 2021

I was thinking more along the lines of "flyweight". Back when Legion had tags, in one of the experiments I did with it I've stored immutable data common among kinds of entities in a tag, e.g. a copy of the base mob properties, and handles to sprites and sounds it used.

So you could even have some kind of CoW components, that would be great for Bundles with lots of defaults.

@recatek
Copy link
Contributor

recatek commented Mar 21, 2021

This could be useful for batching/instancing entities for rendering. If entities that share the same mesh and material can be easily organized into groups, that saves trouble down the line. For reference, the Unity ECS system does exactly this and takes advantage of it for instancing.

@alice-i-cecile alice-i-cecile added the S-Needs-Design-Doc This issue or PR is particularly complex, and needs an approved design doc before it can be merged label Apr 23, 2021
@alice-i-cecile alice-i-cecile changed the title Tag component storage type Allow entities to store multiple components with the same type Jan 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Enhancement A new feature S-Needs-Design-Doc This issue or PR is particularly complex, and needs an approved design doc before it can be merged
Projects
None yet
Development

No branches or pull requests

6 participants