Directly accessing other system's datas

Ahoy,

How do you handle the case where a system needs to access a Map of type <Entity, MyFrameworkObject> from another system. There are cases where messaging doesn’t really work.

If I have a ModelPositionSystem requiring components Position and ModelType i probably store a Model object in a map in that very system.

But let’s say i want to reach the model.blink() method from another system, how does that work? What makes most sense to me would be to just add a Blink component to that entity whenever i need it to blink and build a BlinkingComponent naively calling the .blink method onAddEntities getting the model directly from ModelPositionSystem. Is direct inter-system communication ok? How does that work thread-wise?

Sometimes it’s necessary but I would keep it to a minimum. I don’t know what “blink” is doing so I can’t really say for sure.

Threading is an issue if you are multithreading and you will have a bunch of nice state problems to deal with if the entity shows up in one set before the other and so on. This is why it’s best avoided. For example, it’s possible that the entity might show up to the system watching for Blink before the system with the model has seen it… then what do you do? You have to cache the blink add until you can check next update loop. A pain.

The better (although only marginally) approach is to expose this sort of thing directly in the Model system… since it at least knows when those models come and go. For example, in one of my physics systems I expose the ability to add a force manipulator interface to an entity. The physics system doesn’t know what it is and it will hold them in ready if it hasn’t seen the entity yet. That way when I want to move an object around (like by user input) I can have a mover system that manages that and simply registers its force manipulator that moves the object based on input (by applying forces every physics tick).

You’d have to explain more about your use-case before I could see if it was really required in your case. It could be that one system is just completely subordinate to the other.

Another solution if those systems are that muchc oupled is, to put them into a compoundsystem, that just calls each stuff in the right order.

aka

for every method in system interface do something like:

method(){
a.method()
b.method()
}

@Empire Phoenix said: Another solution if those systems are that muchc oupled is, to put them into a compoundsystem, that just calls each stuff in the right order.

aka

for every method in system interface do something like:

method(){
a.method()
b.method()
}

It’s not even that big of a deal but then they are effectively one “system”. Zay-ES has no concept of a “system interface” because it’s unnecessary. So a “system” is just the code that is using a particular set of entities. In this case, they are often implemented as AppStates and what you are suggesting is basically an app state that happens to use two EntitySets.

…which does happen but should be avoided unless the things really are tightly coupled. There is frequently a “better way” depending on the use-case. For example, it might make sense to generally tie the model, parent-child linkage, and skeletal animation into one ‘system’ state. It just depends.

Also note: if the entities are being modified from another thread then one would still have to take care… the second entity set might see the entity before the first. Either the changes need to be forced onto the same thread or the out-of-order issues dealt with (ie: queueing the pending entities for rechecking on next update).

@pspeed said: For example, in one of my physics systems I expose the ability to add a force manipulator interface to an entity. The physics system doesn't know what it is and it will hold them in ready if it hasn't seen the entity yet. That way when I want to move an object around (like by user input) I can have a mover system that manages that and simply registers its force manipulator that moves the object based on input (by applying forces every physics tick).

Alright so you have one system handling several purposes for corner-cases like this, it means several entitysets i guess then.

A more concrete example i’m having right now:

[java]class TextPositionSystem extends System
{
var frameworkText:Map<Entity, Text> = new Map();

public function new()
{
    need([CPosition, CText]);
}

public override function onEntityAdded(entity:Entity)
{
    var textContent = entity.get(CText).value;
    var pos = entity.get(CPosition);

    var text = new framework.Text({
        color : new Color(),
        font : Framework.loadFont('font.fnt', 'assets/' ),
        text : textContent,
        pos : new Vector(pos.x, pos.y),
        depth : 1,
    });
}

}[/java]

It’s quite explicit but since the Text object of my framework is having different attributes like color, pos, text and depth it’s not that natural to redirect certain behaviours to me.

In my case i’d like to make a text entity turn red when a damage is occurring, I could either make a TextDamageSystem looking for an entity set of CText, CDamageReactive and another entity set of CDamage and grabbing framework Text object from another system (which is apparently to be avoided).

Or I could do this from a more general TextSystem handling all the cases manipulating the Text object with several entitysets.

Am i on the right track?

I don’t think text is a system or a component at all, really. It’s a “view” side reaction to some game object state.

Entity System data is for the “model” in the “model view controller” sense. And whether there is some text and what color it is, etc. is really a “view” thing. You might have one system watching for damage components to actually deal the damage and you might have another system watching for damage components so that it can set some red text on the screen or whatever. These should be as decoupled as possible.

For example, it’s even possible that the text need not even be attached to the original node in any way since you already have the position. And there might be plenty of good reasons to keep the text nodes entirely separate from the on-screen model nodes.

Either way, given the caveats above, you could still have a central system/appstate that managed the models and provided them to the other purely view-related systems for things like this.

@pspeed said: I don't think text is a system or a component at all, really. It's a "view" side reaction to some game object state.
I completely agree with that idea but i don't see any alternative myself.
Entity System data is for the "model" in the "model view controller" sense. And whether there is some text and what color it is, etc. is really a "view" thing. You might have one system watching for damage components to actually deal the damage and you might have another system watching for damage components so that it can set some red text on the screen or whatever. These should be as decoupled as possible.
Then it seems like the first case i described but i still don't see how to reach the Text object from the other system.
For example, it's even possible that the text need not even be attached to the original node in any way since you already have the position. And there might be plenty of good reasons to keep the text nodes entirely separate from the on-screen model nodes.
There i'm lost, i don't follow the concept of a "node", are you implying to remove that text behaviour completely from the ES?
Either way, given the caveats above, you could still have a central system/appstate that managed the models and provided them to the other purely view-related systems for things like this.
Meaning direct inter-system communication!?
@Moop said: I completely agree with that idea but i don't see any alternative myself.

Then it seems like the first case i described but i still don’t see how to reach the Text object from the other system.

There i’m lost, i don’t follow the concept of a “node”, are you implying to remove that text behaviour completely from the ES?

Meaning direct inter-system communication!?

Yes, for example, the text “Hogart shot the food” is not an ES data element. It’s entirely a display thing and not a game element. Someone shot the food… that is ES data. The fact that the view decides to display a message to a particular user is not the concern of the ES data.

A system might watch for that ES data and decide to display text to the user, either hovering over the object or in a console or said aloud as audio or whatever.

If the display is to be shown hovering over the object then there are two ways to do it:

  1. use the position information already associated with the ES object and just use that (and potentially the model type) to decide where to display the text.
  2. some intersystem communication (and all requisite down sides) to attach the Label to the actual JME Node/Spatial/Whatever.

Since this is not game data, in the (probably rare in this case) chance that you see an ‘event’ for an object for which you have no node then you could just ignore it. If the condition that wants to emit “Hogart shot the food” arises and there is no “Hogart” entity (or no “food” entity or whatever) then the message could be dropped. It seems extremely unlikely to happen in this particular case since an entity wouldn’t have been damaged if it didn’t already exist.

For more general intersystem communication you do have to think about it.

Alright that makes more sense indeed, thanks.

So if i understand well, avoiding those Text attributes as ES Data and using a simple Class with a few entityset listening to behaviours instead of text specific data would be more appropriate.