BehaviourTree - простая реализация деревьев поведений
Деревья поведений
(BehaviourTree) - довольно часто используемый подход для построения логики поведения ботов. Существует много комплексных решений, предоставляющих визуальное построение, отладку, плотную интеграцию в какой-то движок. Но что, если все это излишне и требуется минимальный размер, простота сборки, скорость работы и возможность работать на сервере без движка?
В общем случае Деревья
состоят из узлов
(Node), собирающихся в иерархию по определенным правилам. В каждый момент времени выполняется только один узел, затем происходит переход к следующему на основе результатов работы текущего - Дерево
является по сути конечным автоматом (FSM - Finite State Machine), способным обрабатывать входящие данные и переключать внутренние состояния на их основе. Можно рассматривать Дерево
как блок-схему работы какого-то алгоритма обработки данных.
Узлы
являются атомарными абстрактными единицами построения Дерева
и могут содержать в себе произвольную логику работы, которая не зависит от логики других узлов
. Узлы
обычно имеют на выходе результат работы - какой-то признак корректности завершения, ошибки, отложенной работы и т.п. В некоторых реализациях узлы имеют жестко зафиксированные входящие параметры - это помогает в визуальном построении Деревьев
с подключением связей в нужные порты.
Примеры типов узлов
, встречающихся практически во всех реализациях Деревьев
:
- Пользовательский код - обертка над кодом, который должен выполниться в определенном месте работы
Дерева
. - Условное ветвление - аналог “if A then B else C” - если условие
A
верно - можно переходить кB
, иначе кC
. - Отрицание - инверсия результата работы: был успех, станет провал и наоборот.
- Альтернативный выбор - аналог “switch { case A then B; case C then D; }” - набор пар “условие”/“обработчик”, выполняющегося в случае срабатывания условия.
- Последовательность - цепочка-список
узлов
, выполняющихся последовательно друг за другом. - Цикл - аналог “while A do B” - повторять выполнение
B
пока условиеA
верно.
Пакет Leopotam.Ai.Bt
реализует все перечисленное и предлагает сборку Дерева
из кода. Давайте соберем следующее дерево:
1 | sequence: |
Его реализация может выглядеть примерно так:
1 | // Данные, которые будем обрабатывать. |
Это сильно упрощенный пример без использования всего функционала, каждый узел
может быть комплексным и состоять из десятка других узлов, собранных в нужную композицию.
Реализация в пакете Leopotam.Ai.Bt
дает возможность разделения обработки узла на несколько кадров с автоматическим продолжением с места остановки, а так же поддерживает реализацию своих типов узлов
в случае необходимости.