Developing the AI Middleware's Interface

Published March 28, 2014
Advertisement
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.

[code=js:0]// StartupRootAI::Engine *ai_engine = RootAI::CreateAIEngine();RootAI::WorldDesc worlddesc;...RootAI::World *world = ai_engine->CreateWorld(worlddesc);RootAI::AgentDesc aidesc;...RootAI::Agent *agent = world->CreateAgent(aidesc);...// Shutdownworld->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.

[code=:0]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
0 likes 0 comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement
Advertisement