Inter-Entity Communication in an Entity System

Any thoughts about how communication between entities could be best implemented in a hypothetical Entity System similar to Artemis (http://gamadu.com/artemis/)?

I was thinking of having a Messenger component, but do you think it would better to have messaging built into the Entity System framework itself? Also, what do you the the timing of message dispatch and creation should be?

What is it you mean by “communication”?

Like for example, an entity attacks another one. The attacker entity would send an “Attack” message to the attacked entity.

I think I’d personally use a solver class that does all the calculations in an update method. Also it’d have to contain all the lists and references to the entities. That’s what I’d do. There might be a better way. Looking forward to hear from the rest about their methods. :slight_smile:

Right, although perhaps something that could include more complex communication, like the entity representing the flagship of a fleet sending tasks to only the entities within the fleet, or user input changing the state of a group of entities.

It would be pretty cool if the communication could be a two-directional conversation as well.

Obviously a lot of this stuff is case-specific. I’m just wondering what general setup you all think would me most conducive to implementing these sorts of behaviors.

In Artemis entities don’t communicate directly, since they’re only an identifier and comprised of data only objects, how could they?

If you wanted an entity to broadcast an event to other entities you’d probably have to use systems for it.

What I feel is the most under-used feature of Artemis is the fact it’s designed to allow for inter-system communication!

So, a system A could broadcast an event to system B, and system B acts accordingly. So you could imagine systems acting like mediators between entity communication.

Another way would be to actually spawn an “event entity” into the world, with a component as a payload, and some event listening system that acts on it.

Either way, the same applies, systems are mediators for entity communication.

And btw, take a look at the managers provided in Artemis, they help you organize your entities by e.g. teams or groups.

There’s two good examples that I can think of for doing this, and it comes mainly from working with Artemis in my most recent project.

The first way I learned from the one game example link they have on their website
http://code.google.com/p/spaceship-warrior/

In that one, anything that’s collidable have a “Bounds” property and is either a player or enemy. On every update cycle, it checks all entities, if it’s a player it iterates through the enemy list to find which one it collided with and interacts directly with it within the system, and vise versa if it was a player. I did this approach with my own vertical shooter because it works rather well.

The other way I can think of would be good if you were doing something like a turn-based RPG, where you have something like an “Attack” component that could look like this


public class Attack
{
    final Entity target;
    public Attack(Entity target)
    {
        this.target = target;
    }
}

Whenever you would set a target you would then add the component to the actor attacking.


e.addComponent(new Attack(myTarget));
e.changedInWorld();

Be sure to use e.changedInWorld() to ensure all systems in the world have their lists updated so they know it has the attack component now. Then you have an AttackSystem that’ll process everything with Attack Components


public class AttackSystem extends EntityProcessingSystem
{
    public AttackSystem()
    {
        super(Aspect.getFor(Attack.class));
    }

    @Mapper ComponentMapper<Attack> attacksMap;

    protected void process(Entity e)
    {
        Attack a = attacksMap.get(e);
        
        //some example battle logic for you
        Strength str = e.getComponent(Strength.class);
        Defense def = a.target.getComponent(Defense.class);
        int dmg = Math.max(str.value-def.value, 0);

        Health hp = a.target.getComponent(Health.class);
        hp.value -= dmg;

        //be sure to do this when you're done so it doesn't 
        //process this attack multiple times
        e.removeComponent(a);
        e.changedInWorld();
    }
}

I can’t stress enough that the second way is not something you would want to do in a real-time interaction scenario. Adding and removing components, and having to update the world and all systems to recognize that change is extremely expensive. In fact, it’s probably not a good idea to use for such a heavily hit system as the example provides.

Nevertheless, it does show how to do a level of interactive one-way coupling of entities. By linking using components, you can actually reference the other entity even outside of systems by just getting the component from the parent entity using the getComponent method.

I hope those two ways help you in understanding Artemis

I’ve seen them, but the documentation on them is sparse. Could you give any examples of how to use them without breaking the entity system model?

Managers are something extra I added, they’re not really “pure entity system”, but for my purposes I found them useful, although they could probably be implemented in many different ways, including with just components and systems. I’m not encouraging you to use them, but if it helps make your task easier then sure why not.

Managers are listeners to changes to entities, like removal, adding, etc. They’re not part of the game loop, meaning they don’t get processed/updated. Their main job is to provide for a “blackboard” access to all sorts of data in your game, including helping you organize entities.

TeamManager would help you organize certain entities into teams. Teams could help the collision system so that bullet entities don’t hit same team entities, or that you can only control your own team units. There are many uses.

There is a little text about it here: http://gamadu.com/artemis/manual.html#Managers

But you could also implement a TeamSystem which pretty much does the same thing, along with a TeamComponent added to entities. And then you’d have to communicate with the teamSystem from other systems.
In reality I’d probably recommend it that way for anyone wanting to go pure entity systems.

Not to nitpick on names, but why weren’t they called “Listeners” then? Every time I see “Manager” in a class name, I sniff a strong reek of “code smell” where said Manager class is often just some ill-defined “god class” or grab bag of miscellaneous functionality that should have been defined on interfaces on the things purportedly being managed.

I get a smaller but similar reaction when I see “context”, but since most languages don’t have a nice way to express them without monads (or applicatives anyway) I have to give those a pass.

In a general sense, yes, Managers are ill defined god classes. But in the context of games they serve to solve a certain problem.

While I haven’t played with this on the client side at all, I’ve been using Akka a lot for a server side engine based on entities and components. It might be a bit memory hungry for the client, but it’s a natural fit for entity systems. Akka is an actor based messaging system that uses the java 7 fork/join framework. It’s a really nice abstraction for concurrency, probably the best I’ve ever used.

I have things setup so my ‘systems’ are actors, and messages are entities. I use state machines in the systems for flow/logic control.

Chris