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

Relationships between entities (inventory as an example) #24

Open
jddeal opened this issue Feb 4, 2019 · 1 comment
Open

Relationships between entities (inventory as an example) #24

jddeal opened this issue Feb 4, 2019 · 1 comment

Comments

@jddeal
Copy link

jddeal commented Feb 4, 2019

Curious if you have any recommendations on a good way to handle references between entities, and how to store and access those relationships. In particular, we're looking at this in context of entity inventories.

Originally what we kind of hoped was going to work was a component along the lines of this:

struct Inventory {
    int capacity;
    std::vector<entity_t> items;
};

and then use a system and events to manage adding/removing items to a particular entity. This fell flat on its face because entity_t is defined after the components are.

One easy little change we found out we could make was to expose entityplus::detail::entity_id_t; and then using that in place of entity_t above in the vector. We kept going to see how it plays out, and what we ended up with was this helper function to convert the entityplus::detail::entity_id_t; into entity_t:

template <typename ...CompsAndTags>
inline std::unique_ptr<entity_t> find_entity_by_id(entity_manager_t* manager, entityplus::detail::entity_id_t id)
{
    for (entity_t entity : manager->get_entities<CompsAndTags...>())
    {
        if (entity.id == id)
        {
            return std::make_unique<entity_t>(entity);
        }
    }

    return NULL;
};

and it made for fairly enjoyable access anywhere you wanted to use the entities items

auto inventory = player.get_component<Components::Inventory>();
for (auto iter : inventory.items)
{
    auto item = find_entity_by_id(this->entity_manager, iter.second);

    // now we have a pointer to work with
    item->get_component<Components::Identity>();

    // off we go using the entity
}

We actually ran with that for a little bit and it's been alright, but it feels dirty given that we have to modify entityplus to expose that ID. We're lookin to switch this up, but the best next alternative we can think of is having the Inventory component know nothing about the items and go through our InventorySystem which could maintain a mapping of entities with inventories to the list of item entities, then have a function like std::vector<entity_t> InventorySystem::get_items_for_entity(entity_t) for accessing the items.

The reason we don't like that approach as much is because we lose the ability to fully describe our entity by simply looking at its components. With that approach our component tells us how many items might be in the inventory, but we need to communicate with a system to know what items those actually are.

So I guess what I'm asking is if you have any ideas that might allow for referencing entities from within a component. Or perhaps you know of an entirely different approach that maybe we didn't think of. I did notice you mentioned in #19 kind of this scenario we're talking about, but we're failing to understand how the tag approach would work when we have N entities that could have inventories (N tags?).

Appreciate any thoughts.

@Yelnats321
Copy link
Owner

Yelnats321 commented Feb 4, 2019

This is just a first draft approach to the problem, but maybe it would make sense to divide the items into it's own separate entity manager? It makes sense to me to specify this database of items by themselves, and then have the inventory system reference those entity ids. That way you have a flow of information from one manager to the other. If needed, you can share some components between the two managers but I doubt that will be necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants