1
\$\begingroup\$

I use Artemis entity system framework, C# port. I have problem with figuring out a good way to handle items and using them.

Game is AI driven mostly, so it's not the player that is interacting, but AI. AI is basically Entity with AIBehaviorComponent that is ran by AISystem. AI has helper functions that allows it to find all items (ie. Entities with InteractiveComponent) and then it can pathfind to it and use that item. AI is using BehaviorTree that is stored in it's component.

I have InteractiveComponentthat allows player and AI to Use entity. I have this thing working, but it looks a bit dirty solution. Use method is interface that is implemented by Item object that is tied to that component. This way i can have item made with:

new InteractiveComponent(new AwesomeItem());

Calling Use requires me to:

  1. Get entity ref
  2. Find component 'InteractiveComponent`
  3. interactiveComponent.use(me)

me is (this) Entity. The AI entity that is calling the use. I am passing entity to Use method, because using something can alter the entity. It could add component to it, check if it has certain component and then modify the data or remove components, it could even remove the entity.


So, I'm bit lost here. This works, so it's "ok" i guess, but it looks very dirty. I have not found a way to allow somekind of InteractiveSystem to take care of item using without adding huge complexity issues ( Those arise quickly when you try to force Entity system to do something it does not easily allow ).

So, question is:

How to decouple this so, that i don't have to pass Entity to component?

I just don't feel good about the current code but so far it's the best solution we have come up with.

\$\endgroup\$
1
\$\begingroup\$

I am passing entity to Use method, because using something can alter the entity. It could add component to it, check if it has certain component and then modify the data or remove components, it could even remove the entity.

So you're passing the Entity to Use because Use could (effectively) "do anything" with the entity, but you want to come up with a way to not pass the entity?

This is pretty straightforward: change your design. Define more concretely what you want Use to be permitted to do to a thing, and pass it a reference to some interface exposing what it is allowed to do. Otherwise accept that your current design needs the entity in Use because Use is allowed to do almost anything to an entity.

There are lots of different ways you could reorganize this to make it look or feel different, but fundamentally if your fixed principle is that "using a a thing can mutate the using entity, you're going to need to give it the entity, and what you have now seems like a reasonably straightforward approach to that (your dependencies in Use are explicit; this is a good thing).

\$\endgroup\$
  • \$\begingroup\$ Passing entity to component method ( even thou that method is actually Item objects method) is my concern. And yes, item could do anything for the entity, even destroy it. I wonder if somekind of event system could help? I could maybe set some event up, that entity a is using entity b and then some system could pick up that event and handle it ( and set that system run last)? My first project with Entity framework and it surely needs a bit different mindset. Your answer certainly gave me more confidence on my current setup. Thanks \$\endgroup\$ – Katu Apr 14 '15 at 20:26
  • \$\begingroup\$ An "event system" is also an option but won't change the fundamental thing going on; it will only obfuscate the relationship between the action and it's dependencies more. \$\endgroup\$ – user1430 Apr 14 '15 at 20:28
  • \$\begingroup\$ Yeah, you might be right. Thanks for your time. Your answer kickstarted me to mindstorming phase. I realize now, even thou i have been here for quite some time already, this is something i could have handled in the chat. I will keep the item system as it is and just stop forcing everything to component system pairs. \$\endgroup\$ – Katu Apr 14 '15 at 20:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.