Jump to content

Recent Comments

April 2017 »

232425262728 29
- - - - -

Developing the AI Middleware's Interface

ai ai engine ai middleware
4: Adsense

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

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;
            int animation_num;
        } IdleTaskOptions;

            Vector location;
        } GotoTaskOptions;

            int attack_number;
            Vector direction;
        } AttackTaskOptions;

            Vector direction;
        } TurnToTaskOptions;

class Agent
        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


Note: GameDev.net moderates comments.