benmoran56 / esper

An ECS (Entity Component System) for Python
MIT License
537 stars 67 forks source link

Component Relations #62

Closed f0ursqu4r3 closed 2 years ago

f0ursqu4r3 commented 2 years ago

This is an idea for an implementation on how to "link" entity components together to ensure resolution order. Probably not the best way to do it, but had an idea and there was a dire need to get it out there in code.

f0ursqu4r3 commented 2 years ago

Apologies for the mess commit history

benmoran56 commented 2 years ago

Hi Kyle,

Thank you for opening the PR, and I'm sorry for leaving this hanging for such a long time. Unfortunately I'm not sure if this is the right fit for the main code base. A pure ECS design dictates that the components shouldn't have any knowledge of each other. Component relationships can be useful in some cases, but it does go against this point. I'm not saying your idea is wrong, or that one way is better than the other, but for esper I would like to keep things closer to the more dogmatic design ideas.

HexDecimal commented 2 years ago

It isn't as useful to make these kinds of relations if you can't query by them. At that point you should put parent or children entities in components and use those to look up their relationships.

If this is about reordering entities then that should be its own separate function. It's sometimes useful to do that, more useful in low-level languages where memory order can be controlled. I think sorting entities in _get_component is a poor choice.

For a good example of relations I think of Flecs relations where you can use a component or tag to link an entity to another and can then filter entities by what kind of relationships they have or who they have relationships with.

f0ursqu4r3 commented 2 years ago

Thank you for the feedback. I'll admit, this was more of a concept PR, if anything. The issue I was originally trying to solve was that of parented movement. If the parent moves, the child should move its position based on the parent. As such, the entity order should be reordered so the parent's id comes before the child id. Ideally, I believe the sort order should be re-evaluated at the time of the set_parent or add_child call.

Suggestions on the best way to solve the issue stated above? Setting a relation via a new component type doesn't really work because it still doesn't guarantee that the parent's position will be updated before the child.

HexDecimal commented 2 years ago

I assume by position you mean the entities position in relation to the other entities, and you want them to be grouped by their parents in a hierarchy.

I can't really think of anything other than just using standard tree traversal right now. For example periodically you could traverse the hierarchy from the root and index every entity you touch in order, then sort the entities by that order.

I guess I'd need more info like why the entities are being sorted and when they need to be sorted.

f0ursqu4r3 commented 2 years ago

That is the thing, if the entity ids were returned in the correct order, such that the parent always preceded its children, then a parent: int property could be placed on the appropriate component (say Transform). For each returned component, calling the component_for_entity(parent_entity_id, Transform) would mean the parent's component was already processed and (should) be in an accurate state. Now, I do recognize this also gets very complicated if you have multiple parent lists being returned because you are requesting multiple component types which could have their own hierarchies.

benmoran56 commented 2 years ago

If you're talking about a single parent and multiple children, what about starting with something like this:

for pent, parent in self.world.get_component(Parent):
    for cent, child in self.world.get_component(Child):
        child.x = parent.x  # etc
f0ursqu4r3 commented 2 years ago

This approach works if you have a single layer but falls apart if it goes env a single layer deeper. As an example: Player has 3 layers: Body Appendages Equipment

You want to be able to parent the appendages to the body so they can flop around and you want the equipment to stay attached to the appropriate limb. If the transforms happen out of order, the whole thing falls apart. Unless, of course, you run through the whole mess several times to ensure everything is aligned correctly.

This really isn't something for either[any] of you to solve, just a thought experiment, really. Thank you for your time.