Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

linkdd/aitoolkit

Repository files navigation

AI Toolkit

tests docs license version

AI Toolkit is a header-only C++ library which provides tools for building the brain of your game's NPCs.

It provides:

  • Finite State Machines
  • Behavior Tree
  • Utility AI
  • Goal Oriented Action Planning

Why this project? Well, I wrote about it here.

Installation

Add the include folder of this repository to your include paths.

Or add it as a submodule:

$ git submodule add https://github.com/linkdd/aitoolkit.git
$ g++ -std=c++23 -Iaitoolkit/include main.cpp -o mygame

NB: This library is compatible with C++20.

Or using Shipp, add it to your dependencies:

{
 "name": "myproject",
 "version": "0.1.0",
 "dependencies": [
 {
 "name": "aitoolkit",
 "url": "https://github.com/linkdd/aitoolkit.git",
 "version": "v0.5.1"
 }
 ]
}

Usage

Finite State Machine

First, include the header:

#include <aitoolkit/fsm.hpp>
using namespace aitoolkit::fsm;

Then, create your blackboard type:

struct blackboard_type {
 // ...
};

Then, create a state type for each of your states:

class state_dummy final : public state<blackboard_type> {
 public:
 virtual void enter(blackboard_type& blackboard) override {
 // ...
 }
 virtual void exit(blackboard_type& blackboard) override {
 // ...
 }
 virtual void pause(blackboard_type& blackboard) override {
 // ...
 }
 virtual void resume(blackboard_type& blackboard) override {
 // ...
 }
 virtual void update(blackboard_type& blackboard) override {
 // ...
 }
};

Create your simple state machine:

auto simple_bb = blackboard_type{};
auto simple_fsm = simple_machine<blackboard_type>();
simple_fsm.set_state(state_dummy{}, simple_bb);
simple_fsm.pause(simple_bb);
simple_fsm.resume(simple_bb);
simple_fsm.update(simple_bb);

Or with a stack state machine:

auto stack_bb = blackboard_type{};
auto stack_fsm = stack_machine<blackboard_type>{};
stack_fsm.push_state(state_dummy{}, stack_bb);
stack_fsm.push_state(state_dummy{}, stack_bb);
stack_fsm.update(stack_bb);
stack_fsm.pop_state(stack_bb);
stack_fsm.pop_state(stack_bb);

Behavior Tree

First, include the header:

#include <aitoolkit/behtree.hpp>
using namespace aitoolkit::bt;

Then, create your blackboard type:

struct blackboard_type {
 // ...
};

Then, create your tree:

auto tree = seq<blackboard_type>(
 node_list<blackboard_type>(
 check<blackboard_type>([](const blackboard_type& bb) {
 // check some condition
 return true;
 }),
 task<blackboard_type>([](blackboard_type& bb) {
 // perform some action
 return execution_state::success;
 })
 )
);

Finally, evaluate it:

auto blackboard = blackboard_type{
 // ...
};
auto state = tree.evaluate(blackboard);

For more informations, consult the documentation.

Utility AI

First, include the header file:

#include <aitoolkit/utility.hpp>
using namespace aitoolkit::utility;

Then, create a blackboard type:

struct blackboard_type {
 int food{0};
 int wood{0};
 int stone{0};
 int gold{0};
};

Next, create a class for each action that you want to be able to perform:

class collect_food final : public action<blackboard_type> {
 public:
 virtual float score(const blackboard_type& blackboard) const override {
 return 50.0f;
 }
 virtual void apply(blackboard_type& blackboard) const override {
 blackboard.food += 1;
 }
};
class collect_wood final : public action<blackboard_type> {
 public:
 virtual float score(const blackboard_type& blackboard) const override {
 return 150.0f;
 }
 virtual void apply(blackboard_type& blackboard) const override {
 blackboard.wood += 1;
 }
};
class collect_stone final : public action<blackboard_type> {
 public:
 virtual float score(const blackboard_type& blackboard) const override {
 return -10.0f;
 }
 virtual void apply(blackboard_type& blackboard) const override {
 blackboard.stone += 1;
 }
};
class collect_gold final : public action<blackboard_type> {
 public:
 virtual float score(const blackboard_type& blackboard) const override {
 return 75.0f;
 }
 virtual void apply(blackboard_type& blackboard) const override {
 blackboard.gold += 1;
 }
};

Finally, create an evaluator and run it:

auto evaluator = evaluator<blackboard_type>(
 action_list<blackboard_type>(
 collect_food{},
 collect_wood{},
 collect_stone{},
 collect_gold{}
 )
);
auto blackboard = blackboard_type{};
evaluator.run(blackboard);

Goal Oriented Action Planning

First, include the header file:

#include <aitoolkit/goap.hpp>
using namespace aitoolkit::goap;

Then, create a blackboard class that will hold the state of the planner:

struct blackboard_type {
 bool has_axe{false};
 int wood{0};
};

NB: The blackboard needs to be comparable (a == b) and hashable.

Next, create a class for each action that you want to be able to perform:

class get_axe final : public action<blackboard_type> {
 public:
 virtual float cost(const blackboard_type& blackboard) const override {
 return 1.0f;
 }
 virtual bool check_preconditions(const blackboard_type& blackboard) const override {
 return !blackboard.has_axe;
 }
 virtual void apply_effects(blackboard_type& blackboard, bool dry_run) const override {
 blackboard.has_axe = true;
 }
};
class chop_tree final : public action<blackboard_type> {
 public:
 virtual float cost(const blackboard_type& blackboard) const override {
 return 1.0f;
 }
 virtual bool check_preconditions(const blackboard_type& blackboard) const override {
 return blackboard.has_axe;
 }
 virtual void apply_effects(blackboard_type& blackboard, bool dry_run) const override {
 blackboard.wood += 1;
 }
};

Finally, create a plan and run it:

auto initial = blackboard_type{};
auto goal = blackboard_type{
 .has_axe = true,
 .wood = 3
};
auto p = planner<blackboard_type>(
 action_list<blackboard_type>(
 get_axe{},
 chop_tree{}
 ),
 initial,
 goal
);
auto blackboard = initial;
while (p) {
 p.run_next(blackboard); // will mutate the blackboard
}

For more informations, consult the documentation.

Documentation

The documentation is available online here.

You can build it locally using doxygen:

$ make docs

License

This library is released under the terms of the MIT License.

AltStyle によって変換されたページ (->オリジナル) /