Designing AI routines

Hi! I want to implement NPC routine system. Different actor has a different set of routines.

E.g. all actors can: walk around, chat with different a NPCs, use an item. But only blacksmith can (in addition to that) mess around the forge, and only chief will look for a plate and cook sth.

I do have basic NPC behavior implemented in behavior tree, but I’m not sure if I can fit routines there.

Note that a single routine might include a multiple tasks: e.g. chat with a different NPC is:

  • find a “chatty” NPC around,
  • move to this NPC,
  • start talking animation/play sound,

Also a requirement is to do as much in C++ as possible, I want the code to be reusable. Any hints?

High level, first I would implement a state machine for your NPCs, then in your states properties you could have a pointer to the appropriate BehaviorTree that should run in this particular state.
Finally populate your trees with c++ implemented tasks, decorators and services.
I wouldn’ t write the BT in c++ though.

Thanks for sharing your thoughts! Two questions:

  1. is there any feature for machine states in behavior behavior trees in UE4? or should I just create a property with a state, and then check it in a decorator?
  2. What’s the reason for discouraging from c++ in BT?
  1. BT already are kind of state machines to me but hard to extend when you want complex behaviors and can really be a big mess. In your case you might want to use a HSM (Hierarchical State Machine) which I would not make using a behavior tree. But you will find tons of tutorial on the internet as it is a common game pattern.
    Then once your state flow is well designed and implemented you can assign states a specific BT.
    In my case I have some NPCs that can be exploring or in combat. I have a state machine that drives the high level states of the NPCs and one behavior tree per state.
    In my AIController I have things like:

    if (event == ECharacterEventType::CombatEnd || event == ECharacterEventType::EnterCombat)
    {
    if (UBehaviorTree* pBehavior = m_pAICharacter->GetProperBehaviorTree())
    {
    if (pBehavior != m_pCurrentBehaviorTree && !pCharacter->IsDead())
    {
    m_pCurrentBehaviorTree = pBehavior;
    StopMovement();
    RunBehaviorTree(m_pCurrentBehaviorTree);
    }
    }
    }
    Where event is a parmeter of callback called each time my AI character change state

2)To me a BT is just a node container. The logic is defined in your decorators, tasks and services so I prefer a visual representation to connect things which make things easier to iterate and debug.

Cool, thanks! I’ll experiment with this approach a little bit. For the time being I’ll give +1 here, as it’s the most inspiring answer, and accept it a little better if nothing better comes out. :slight_smile: Thanks again!

Behavior trees are a nice built-in state machine system that is quite re-usable. Official documentation for that matter is not bad. That being said nothing prevents you to code your own state machine framework in C++ if you’d like to. The basics are covered here.

Wow, that link with basics seems to be a really good read! First thing I’ll do tomorrow morning! Thanks a lot!

I cannot see why not other than processing power being an issue? The implementation would not be trivial. But with the combination of Services and Decorators… I personally am newish to the Behavior tree but I imagine you’ll need a method for characters to access a global clock, a set of stats to determine their desires for doing the things they do, probably a schedule they follow everyday normally. I imagine most of that would exist on the character/pawn itself. You may even utilize the Environment Query System (EQS) to query the world itself for desirable tasks.

As an example lets say you have a blacksmith that wakes up in the morning, eats breakfast, goes to work for 4 game hours, eats lunch, returns to work for 4 more game hours, then returns home for dinner, spends time in his house until bed time, and restarts this for five days, then for two days he relaxes. There are a few methods to implement this but these particular subsystems I would probably build out using components, sub objects, and structs to assemble the characters basic schedule. Then you could add some “drivers” such as his dedication to work which would drive a chance for him to skip lunch, come home late, or is prone to not getting up in the morning. You could give him drives to do other things such as eat too much, drink whenever he can, chat up anyone who wanders by his shop.

The Behavior tree of this would come in by checking the time of day and deciding if where he “should” be during that time of day. Then using the drivers to decide if he in fact does them, procrastinates, or does them earlier. This is most likely a service implementation checking every x number of game minutes.

You can use the Environmental Query System to check for wandering by character in conjuncture with a different driver “Chatty” to see if the blacksmith attempts to talk to that character. You can use a service to determine what the two talk about and then you can then use Decorators that fire each tick during the “Chatting” phase to check and see if the conversation has ended and send the chatty blacksmith back to work.

I’d also use generic, and configurable Custom Task Nodes for “Go To Work”, “Work”, “Get Food”, “Eat”, “Start Conversation”, “Chat with NPC”, and “Talk at PC”. That’s my thoughts on it, all this can easily be built in blueprints and probably should mostly be built in blueprints, I usually work in C++ but I find the behavior tree and extending the behavior tree and all it’s sub components to benefit greatly from being at a higher level.