1
\$\begingroup\$

My goal is to have a behavior tree that can run alone (autonomously) but also react to input from the player.

I'm making an AI for a hack and slash game where the AI will fight you, chase you, etc. and play defensive based on certain stats (health etc), but I want to add an additional layer; events from player. Say the player attacks, I want a random chance maybe 5-10% to trigger a dodge or step-back from the AI.

Currently I have its own selector running, but that is not sufficient, as it just has same priority or triggers on the same level as the other selectors / sequences in the tree. So how do I go about implementing a priority into the tree?

I want to have dodge, which should be labelled as maybe priority 1 if the event triggers, else it should just go about its usual business.

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

You did not specify engine, but any decent BT implementation should support some form of task abortion by a decorator, or at least re-running selection on demand.

Make dedicated event handling node right under the root selector, highest priority. Attach a decorator that checks if there is any pending event(s). Allow it to abort lower priority tasks. Put all relevant event handlers under that node.

enter image description here

You probably want to add another decorator, that locks current event handler (ignores other events) for duration of the animation (e.g. dodge), but be aware of event priority (death > dodge) and relevance/expiration (e.g. chaining next dodge while current one runs).

How to implement required functionality from scratch.

Nodes should have an Abort method, and it must be deterministic: that is, once called, underlying processes (e.g. coroutines and threaded tasks) must be cancelled immediately. If that's not possible, then make Abort to be a task itself, although this is undesirable.

Decorators should recalculate their states once relevant underlying state changes. One way to do it is with Blackboard and Services. Blackboard is just a collection of variables relevant to the BT; blackboard must notify decorators when any variable changes. Service is blackboard update function that is ran periodically, it copies and/or recalculates relevant state from outside (the agent and the world) into blackboard.

(Note that I am using UE4 terminology here, not sure if standard; btw UE4 BTs are great, you may as well just copy UE's model).

Once relay/gate-type decorator recalculates it's state to new outcome that enables it's node, the decorator should ask BT to re-select current node, starting selection from decorator owner's parent, but only if currently running node is lower priority or child (otherwise BT would just select that higher-priority node again). Note that node need to be aborted only if BT selects another node, otherwise it should continue uninterrupted.

\$\endgroup\$
3
  • \$\begingroup\$ Thanks for the detailed post. I'm using Unity as the engine and coding it myself in c#. I like the task abortion way of doing it with a decorator checking for pending events. How would i go about implementing the "abort" portion of it? Use Threading or add an additional Nodestate? atm i have Failure, Success and Running. I find it hard to find a way to implement a non-blocking node-state atm :) ie running keeps going untill its either failure or success, i cant have it async atm. Thanks again for the reply! \$\endgroup\$
    – Angelo
    Mar 21, 2021 at 22:30
  • \$\begingroup\$ @Angelo I did not realize that Unity has no built-in BT. I've edited my answer to include possible implementation. \$\endgroup\$ Mar 22, 2021 at 20:02
  • \$\begingroup\$ @Angelo going async with C# should be easy, do not hesitate. Most tasks boil down to running on a timer and exiting if cancellation token is set. \$\endgroup\$ Mar 22, 2021 at 20:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .