Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm starting to work on a game with Entity-Component Model Architecture (Artemis in C#). I'm beginning with something pretty simple, entities which are living things, with HealthComponent, PositionComponent, SpriteComponent, MoveComponent. I want them to be able to target other entities (for example other Living things or even other entities of the game (like say inerts objects)) for them to move to them and grab them or be able to do other actions with them.

I can find which entity they will target by going through the mechanic of searching through all entities having the good components (PositionComponent, TargetableComponent) but i don't see how I can store the information of the target except by saving somewhere the ID of the entity.

So I would have a TargetComponent which is basically the ID of an entity that has for exemple a PositionComponent

That does not seem right, does it?

share|improve this question

2 Answers 2

up vote 4 down vote accepted

It sounds right to me. There are some benefits to doing it this way:

  • You're not duplicating data.
  • The information about the entity is always up-to-date (i.e. using the entity ID to get the position of the entity will always return the current position of the entity).

Those two essentially mean the same thing. If you were to store the position of the target entity, you'd have to update it every time the target moved. Further, you'd have to still store some kind of entity ID to know which entity you were targeting so you could perform other operations like attacks that alter the HealthComponent of the target entity.

There are some things you need to consider, but aren't significant problems.

  1. You have to ensure the target entity has a position component. This is a simple check you can perform when assigning the target. It's pretty likely that the entity will have a position, otherwise it wouldn't make sense to be targeting it. But, it's just a simple check to make sure it has a position before assigning it as a target.
  2. When saving and loading the game state, you need to ensure that entity IDs are assigned in the same way they were before. You don't want to save the game targeting one entity, and load the game with a totally different target.

Overall, if you find something that works for you, it's right (at least it's right enough). Don't worry about straying from the entity-component system or breaking any rules. Just make your game, and don't sweat the little things.

share|improve this answer
    
The thing is i'm trying to actually not stray too far because one of the point is to make the cleanest project possible. I thought the main idea was actually to avoid accessing directly to entities (which would defeat the purpose of having the component system). Thanks for your answer! –  Linio Aug 5 '13 at 14:03
    
It doesn't defeat the purpose of the entity component system. I don't think it does that even a little. You're still not having the entity access the other entity directly. You have some kind of AttackSystem that will take the entity ID as input, and that system will access both entities. No entity-on-entity action at all. –  Byte56 Aug 5 '13 at 16:11
    
I guess you're right! I didn't see it that way. It's still cloudy for me, it's my first project that way and although i can manage to see where it's going with a classic project, here it's not so clear. Thanks! –  Linio Aug 5 '13 at 16:16

You need to ask yourself what are the requirements an entity must satisfy for it to be "targetable". Saying, "it must have the TargetableComponent" isn't useful. You are really trying to answer, "what additional information and behavior is required for an entity to be considered targetable?"

If all the information you need out of a targeting system is a back-reference to the owning entity from which you can access the position, maybe you're better off putting together a list of PositionComponents for your targeting system. No really new information is being added, and the TargetableComponent is just being used as a "marker component." That is, it exists solely to add a single bit of information to an entity: whether or not it is targetable. Marker components aren't inherently bad, but in most cases seeing them seems like a case of "to a hammer, everything looks like a nail."

In this case, I would have some sort of flag/tag system (a [Flags] enum could work well for this, you can have 64 different flags if you type it as a long), and arrange it such that I could quickly query an area of the game world for objects for which the following is true: (entity.Flags & EntityFlags.Targetable) == EntityFlags.Targetable. If you need more than 64 tag/flag/whatevs, then that's what lists of tag IDs are for (they could just be hashes of the string name).

I'm assuming you need much more than one bit of information for your TargetableComponent though. Maybe you need to send events when an entity becomes targeted, need to know how many other entities are targeting this entity, and all sorts of stuff. In which case, don't feel guilty for using this TargetableComponent pattern.

Whether or not it's better to use marker components versus some sort of tagging depends completely on how you're planning to use it in your game. Do you want to dynamically check for the presence of TargetableComponent on entities? How frequently are you doing that? If it's as frequent as every few frames, is that an expensive operation in your system (ie: Unity)? Are you pre-populating a list of targetable entities by scanning all entities at level load for those who have TargetableComponent? Or does TargetableComponent itself maintain a static fast-access list?

Bottom line: Keep doing what you're doing so you can make progress and better define your problem. If necessary, you can redesign this system later to better handle your requirements.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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