Ralith / hecs

A handy ECS
Apache License 2.0
921 stars 79 forks source link

Entity Relationships #365

Open Olle-Lukowski opened 5 months ago

Olle-Lukowski commented 5 months ago

I really like working with hecs, I just feel like there is one big feature missing: entity relationships. Especially after using flecs for a while, I am now really starting to miss it in hecs. Sander Mertens (the author of flecs) has written a great article on how to implement it.

I realise that implementing relationships is no small task and will take a long time, but I still think it would be amazing if it could be made reality. I can even try to help if needed.

Ralith commented 5 months ago

I understand "entity relationships" to mean "relationships between entities", which I've had good results representing by storing values of type Entity inside components. Skimming the article, I'm not sure it's talking about the same thing. Can you provide some background as to what exactly this feature means to you, and why it must be implemented within the ECS?

Olle-Lukowski commented 5 months ago

I think this other article explains it pretty well, not sure how else to explain it. And for why it should be implemented in the ECS: proper querying. say you have an Item component, Player compnent, and a Owned relationship. within flecs, you can easily query for all instances of Item that have the Owned relationship with a specific Player

Ralith commented 5 months ago

What do you imagine the memory layout and query execution for your example looking like?

adamreichold commented 5 months ago

If I understood the linked resources correctly, then every combination of Owned for a particular player entity ID should go into dedicated archetype for the "fragmenting" kind of relationships using the idea of encoding the Owned(Entity) into a single type ID (in hecs-speak) by stripping the generation from the Entity.

Olle-Lukowski commented 5 months ago

Sorry for not really responding. The message above this one is correct, but I would like to add that my example would look something like this in flecs' c++ api:

struct Owned{};
struct Item{
  size_t count;
};

flecs::entity player = world.entity();

// create some Item components and assign them the owned relationship with the player.
auto testItem = world.entity();
testItem.set(Item { 3 });

testItem.add<Owned>(player);

world.system<Item>()
  .term<Owned>(player)
  .each([](flecs::entity e, Item &i) {
    // here you have all items that are Owned by player.
  });
Ralith commented 5 months ago

every combination of Owned for a particular player entity ID should go into dedicated archetype

That's what I thought, but that seems liable to produce a combinatoric explosion of tiny archetypes. That would destroy memory locality and degrade performance of every operation that traverses the archetype list.

I think the memory layout arising from the naive approach in hecs today, where you just slap Entity fields in your components and traverse views with whatever logic you like (e.g. the transform hierarchy example), is much nicer.

kulkalkul commented 5 months ago

That's what I thought, but that seems liable to produce a combinatoric explosion of tiny archetypes. That would destroy memory locality and degrade performance of every operation that traverses the archetype list.

I love simplicity of hecs and don't think relations fit into it at current state: but fragmenting can be good depending on the usecase. After all, it is just a tool that one can use. I know flecs has lots of ways to mitigate the drawbacks and performs well afaik (though I haven't conducted a benchmark myself). Issue though is, it is complicated to implement it, requires lots of changes. Flecs depends on components as entities to make it work, for example.