Skip to content

Give a brain to your game's NPCs

License

linkdd/aitoolkit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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.

Sponsor this project

 

Contributors 3

  •  
  •  
  •