Closed Tisten closed 1 year ago
Adding/removing entities to a flattened tree is not yet supported. As per the documentation:
Relationship flattening is an experimental feature, and some limitations apply for the current implementation. After a subtree has been flattened, the entities in that subtree can no longer be individually deleted from a target, and cannot be moved to another parent. Additionally, no components can be added/removed to entities in a flattened subtree. Relationship flattening is currently supported only for exclusive, acyclic relationships.
https://www.flecs.dev/flecs/md_docs_Relationships.html
I would like to make this possible eventually, but hierarchy flattening makes some changes to the storage that make this non-trivial.
I'm not removing or adding any entities, the entities in the flattened tree and their relationship are all kept intact and I'm only adding components, i.e changing the C in the EntityComponentSystem. The documentation only speaks about entities which is the E in ECS. This makes me very confused.
Would it be possible to add an assert with a clear error message when a component is added to a flattened tree? Because I don't get any assert if I reduce the depth one step (and that should still be invalid) and the !(table->flags & EcsTableHasTarget)
assert didn't give me any clue that I had made an error. It might very well be this error which end up causing the segfault in https://github.com/SanderMertens/flecs/issues/965
In flecs, any entity can be added to an entity. Components are entities, that when added to other entities, just happen to come with a value attached as well. Non-component entities are usually referred to as "tags" when added to an entity.
Okay, thanks for the clarification.
So when I've been reading all this talk about what a component is and what an entity is, then flecs could be said to be an Entity-EntityWithData-System instead, and "component" is just syntactic sugar. And if I'm interpreting this correctly then I can't use flecs' tags with flattened subtrees, but need to add another tagging system on top of flecs if I want both featues, right?
I'm also getting the same assert when I remove the root entity of a flattened tree. Is there a special function to use when removing the whole subtree?
You can also enable / disable specific components or tags on entities without removing them from the entity. I'm unsure if that is fully supported with flattened trees but I'm guessing since it doesn't change the entity type and only affects query matching, it might work? Also not sure about the performance impact.
C: https://www.flecs.dev/flecs/group__enabling__disabling.html C++: https://www.flecs.dev/flecs/structflecs_1_1entity__builder.html#a5ba67bf384c2d2f96e6e1a2651243a11
This would require knowing which tags and components might appear on these entities and adding them (disabled) beforehand, but it might be a possibility to consider. Otherwise you might just have to wait for the ability to modify flattened hierarchies to be implemented, or not use the feature for now.
Great, I will have a look at disabling components. It won't be an option for tags since content creators are free to add their own tags. But I wouldn't like tags to cause table switches anyway so separating them out could be a good thing overall, but it will make tag based queries more complicated.
If an entity can be added to an entity, perhaps I can tweak flecs to only partially flatten a subtree and keep an unflattened conjoined twin in each entity which can be used for dynamic components and tags... It would add an extra indirection when I want to look at those dynamic entities, and again it would make queries and filters more complicated which goes against the direction of core flecs.
From your comment:
I'm not removing or adding any entities, the entities in the flattened tree and their relationship are all kept intact and I'm only adding components
The documentation states:
Additionally, no components can be added/removed to entities in a flattened subtree.
In the code example you add Velocity
, which is what is causing the assert.
it would make queries and filters more complicated which goes against the direction of core flecs.
I 100% agree with that, and this limitation is something that I'd like to eventually get rid of. Tree flattening is still pretty new and experimental, but over time I expect the rough edges will get ironed out :)
About:
You can also enable / disable specific components or tags on entities without removing them from the entity. I'm unsure if that is fully supported with flattened trees but I'm guessing since it doesn't change the entity type and only affects query matching, it might work? Also not sure about the performance impact.
The first time you enable or disable anything you add a "toggle" entity to the entity, so all tags and components you want to be able to disable you need to make togglable before you flatten.
The documentation of ecs_enable_id
says Enabling or disabling a component does not add or remove a component from an entity
which feel a bit misleading since it does add an entity with data (aka component) to the entity, and it adds one per component and tag.
Disabling tags works fine in all unittests I've made so far, but the disabled tags still make it through the queries I make in my engine so there is something wrong with how I do tag based queries. :(
Apparently our engine used a filter instead of a query, and disabling things seems to onlyt work with queries and not with filters.
Will dig deeper into this, but reported it right away: https://github.com/SanderMertens/flecs/issues/973
Describe the bug When adding a component to an entity which is part of a flattened branch I get
fatal: table.c: 1533: assert: !(table->flags & EcsTableHasTarget) INVALID_OPERATION
with the callstack:To Reproduce I wrote a test in the
FixedHierarchies
suite for it, the test is based onGet_component_get_1_from_2_add_in_progress()
: