Jump to content

  • Log In with Google      Sign In   
  • Create Account





Developing the AI Middleware's Interface

Posted by Squared'D, in AI 28 March 2014 · 595 views

ai ai engine ai middleware
Developing the AI Middleware's Interface

As I explained in my last post, I've developed a text-based sample game that I'll use to build the initial version of the AI system. Then I'll get it to work on my 2D engine, and then finally on my 3D engine for Auxnet:Battlegrounds. I'm at the stage now where I need to develop the AI systems public interface.

The AI system is still very early in its development so things will probably change, but this is how I invision using the code in a real application.

// Startup
RootAI::Engine *ai_engine = RootAI::CreateAIEngine();

RootAI::WorldDesc worlddesc;
...
RootAI::World *world = ai_engine->CreateWorld(worlddesc);

RootAI::AgentDesc aidesc;
...
RootAI::Agent *agent = world->CreateAgent(aidesc);

...

// Shutdown
world->DestroyAgent(agent);
ai_engine->DestroyWorld(world);
RootAI::DestroyEngine(ai_engine);


I haven't decided if I want to force the developer to have to explicitly destroy the agents and the world or allow just destroying the engine and have that take care of cleaning up everything. My current thoughts are to let the engine take care of cleaning things up and returning a message if there are any AI objects that weren't properly destroyed before the engine.

Here's the preliminary code for the AI agents and their tasks. The task should be basic enough so that the AI system can tell the game engine what in a way that will be easy to implement.

struct AIAgentDesc
{
    // the initial position and orientation of the entity
    Pose initial_pose;

    // set to true if the agent can move on more than one
    // axis at a time
    bool diagonal_movement;
};

enum AITaskType
{
    TaskIdle, // The AI should wait in an idle state
    TaskGoto, // The AI should go to a point (path will be unblocked)
    TaskAttack, // The an attack
    TaskTurnTo  // turn to face a direction
};

struct AITask
{
    AITaskType type;
    union
    {
        struct
        {
            int animation_num;
        } IdleTaskOptions;

        struct
        {
            Vector location;
        } GotoTaskOptions;

        struct
        {
            int attack_number;
            Vector direction;
        } AttackTaskOptions;

        struct
        {
            Vector direction;
        } TurnToTaskOptions;
    };
};

class Agent
{
    public:
        virtual ~Agent() {}
        virtual void SetAgentPose(Pose pose) = 0;
        virtual void GetCurrentAITask(AITask &out) const = 0;
        virtual void SetTaskDone() = 0;
};
The task currently just use unions. The reason why I decided to do it this way instead of using inheritance was I want to be able to easily copy data back and forth between the AI system and the game engine without creating new objects task objects and I can process the task without casting.

Another design choice that I've made is completely separating the public interface from the implementation. That's why the agent class is an abstract base class. The same will be true of the world and engine classes.

Let me know if you have any questions or suggestions.


AI video for beginners and young programmers

Squared Game Engine Modular Architecture

Fun Indie Games In Development YouTube Playlist

http://ai.squaredprogramming.com/2014/03/developing-ai-middlewares-interface.html




Recent Comments

December 2014 »

S M T W T F S
 123456
78910111213
14151617181920
21222324252627
28 293031   
PARTNERS