1
\$\begingroup\$

I'm planning to use GdxAI Telegraph in GdxAshley ecs framework, my problem is how I'm gonna create a telegraph component if I wanted to dispatch a message? I have created AIComponent and AISystem.

class AIComponent implements Component{
    StateMachine<Entity, EntityState> fsm;
}

class AISystem extends IteratingSystem {

    public void processEntity(Entity entity, float deltaTime) {
         AIComponent ai = Mappers.ai.get(entity);

         ai.fsm.update();
    }

}

For example I wanted to dispatch a message using space input.

if(Gdx.input.isTouched()) {

     MessageManager.getInstance().dispatchMessage(
                0.0f, // no delay
                entitySender, entityReceiver,
                MessageType.SAYHELLO, null);

}

I'm thinking of creating a class that extends Entity and implement it to Telegraph. But the ashley ECS approach will be disregard here.

class EntityAI extends Entity implements Telegraph {

     StateManager fsm;

     public EntityAI (StateManager fsm) {
          this.fsm = fsm;
     }

     @Override
     public boolean handleMessage(Telegram telegram) {
         return fsm.handleMessage(telegram); // In this part, the logic exists. Im thinking of creating a System that will handle message? but how
     }

}

Question How do I properly convert the this EntityAI to entity-componentbased-system approach? In the below code is not tested but it was the idea entered my mind.

class Script implements Telegraph {

     StateManager fsm;

     public Script (StateManager fsm) {
          this.fsm = fsm;
     }

     @Override
     public boolean handleMessage(Telegram telegram) {
         return fsm.handleMessage(telegram);
     }
}

class ScriptComponent implements Component {
     Script script;
}


 ScriptComponent script
 AIComponent ai
 ai.fsm = new StateMachine();
 script.script = new Script(ai.fsm); // as you can see here the fsm is used twice in component

 // AIComponent has StateMachine
 // ScriptComponent need StatMachine
 // do you in the above code is a good idea?


MessageManager.getInstance().dispatchMessage(
                0.0f, // no delay
                scriptSendeer, scriptReceiver,
                MessageType.SAYHELLO, null);
\$\endgroup\$
1
\$\begingroup\$

I'd try to avoid using any form of event dispatch within an ECS.

From the looks of it you're trying to change state based on some kind of input. I assume that block of code where you track input is inside a system. So instead of dispatching an event why not just update the requisite components directly from that system.

Systems can process multiple types of components, but more importantly any two Systems can process components of the same kind on a given entity. So say you have a system (call it SytemA) that updates a component based on input, then its possible for another system (call it SystemB) to take up that component to do further processing. That is possible because SystemA and SystemB have components in common. That's how you normally track and respond to changes in state in an ECS.

\$\endgroup\$
0
\$\begingroup\$

For now this is the way I handle AI messaging with ashley ECS in libgdx.

TelegraphAgent implements Telegraph {

    StateMachine fsm;         

    public TelegraphAgent (StateMachine fsm) {
        this.fsm = fsm;
    }

    @Override
    public void handleMessage(Telegram msg) {
        fsm.handleMessage(msg):
    }
}

AIComponent implements Component {

    StateMachine fsm;
    TelegraphAgent telegraph;  // or create another class called TelegraphAgentComponent

}
\$\endgroup\$

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.