Aitoolkit
Give a brain to your game's NPCs
Install / Use
/learn @linkdd/AitoolkitREADME
AI Toolkit
<center>
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.
Related Skills
node-connect
334.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
82.1kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
334.1kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
82.1kCommit, push, and open a PR
