Planner Reasoner

Planner Reasoner class enables you to use Grail’s planning algorithm to govern behaviors of AI Entities, by managing goal selection, state and action translation, the number of planner’s iterations and behavior sequence execution.

If you wish to use planners in a different context, you can use the Grail Planner directly.

To make Planner Reasoner work properly, you have to provide it with some information about the game world and various goals that can be chosen. The following sections describe the required work.

To see a complete example, see Planner Reasoner: Quickstart page.

Domain definition, state and action translation

For the planner to work, you have to provide a domain definition, i.e to declare all possible objects and action types that can be considered by the planner.

The other most important thing needed by the planner is a game state description - because Grail’s planning algorithm operates on abstract game states, you have to provide logic that will translate the state of your game to an abstract representation digestable by the planner.

Additionaly, you have to provide a piece of code that will translate action sequences to behaviors that can be executed by an entity.

To help you in this tasks, Grail provides the DomainTranslator class that you can derive from. See this page for more details.

Code Example

The following code example shows how to the concepts and tools described above can be put together.

  • C++

  • C#

auto pool = std::make_unique<grail::MemoryPool>();

//You have to define game state and action translation logic by providing a class derived from grail::DomainTranslator
auto trans = std::make_unique<MyDomainTranslator>(*pool);

//You can define the goal selection method by implementing IGoalSelector interface
auto goalSelector = std::make_unique<MyGoalSelector>();
auto entity = std::make_shared<AIEntity>();

PlannerReasoner::Config config;
config.iterationsPerFrame = 20;
config.maxIterations = 50000;
config.maxPlanLength = 20;
config.usePartialPlans = true;

//assign the reasoner to the entity
entity->SetReasoner(std::make_unique<grail::PlannerReasoner>(*pool,
  goalSelector,
  std::move(trans),
  config));

//register the entity
manager.RegisterAIEntity(entity, 0);
//You have to define game state and action translation logic by providing a class derived from grail::DomainTranslator
var trans = new MyDomainTranslator();

//You can define the goal selection method by implementing IGoalSelector interface
var goalSelector = new MyGoalSelector();
var entity = new AIEntity();

var config = new PlannerReasoner.Config()
{
  IterationsPerFrame = 20,
  MaxIterations = 50000,
  MaxPlanLength = 20,
  UsePartialPlans = true
}

//assign the reasoner to the entity
entity.SetReasoner(new PlannerReasoner(goalSelector, trans, config));

//register the entity
manager.RegisterAIEntity(entity, 0);