Using Behaviour
Trees in Unity
to Model Villager AI​
Ups and Downs of
Video game and
hardware developer
established in 2017,
based in Zagreb, Croatia
Numerous
international awards
and nominations
About Gamechuck
Retro-styled action
games, and large-scale
narrative-driven adventure
games
Game developer who
learned the trade by
annoying too many
people to share
knowledge
Mostly working in
Unity and C#, while no
stranger to Unreal
Engine and C++
About me
Experienced in
games for
Android/IOS, PC,
Current Console
General knowledge of
majority of Game
programming, while
focus is in Performance
and Game AI
About Midwintär
Narrative-driven
stealth-action inspired
by medieval horror
folklore​
Combines careful
tactical planning with
fast-paced arcade
execution
Relies on complex,
adaptive behaviour of
NPCs
Singleplayer, co-op, for PC
and Consoles, with cross-
platform multiplayer in
mind
3 playable characters
Specific goals
Tools
Hostile villagers
Gameplay
What is an NPC?
NPC or "non-playable
character" is any
character in-game that
is not controlled by
Player(s)​
NPCs are commonly
used to fill out the world,
make it more interesting
and immersive, giving
Player more to interact
with
Etc
What is a game AI?
What does it do
regularly?
How does it react
to dangers?
How will it react to
something
suspicious?
Technical limitations
Behaviour tree
Behaviour tree
Main Node types
Action (Execution) nodes Composite (Control) nodes
Node
“leaf” or end point of branch in tree, usually checks
condition or does some kind of action, like set
destination for npc to move towards​
they further control order and selection of where should
wanted behaviour be found (e.g. Sequence, Selector...)​
Behaviour tree
Optional Node types
Condition
(either as action or composite)
Decorator
Node
as always, key for branching, without complex
composites that do specific sub-branch selection, this
one will check and block / allow specific executions​
used to modify a return value of Node / Branch beneath it.
e.g. : “Success” decorator returns successful execution
regardless if branch failed of succeeded in execution; or
“Repeat” which will Repeat it’s branch until some
condition(s) are met​
Behaviour tree
Node status
Each Update / Tick of Behaviour tree, there is a return value of running branch,
one of following:
Success: Job / Action completed
successfully
Failure: Failed to complete the job or conditions for it not met​
Running: Job is still in progress​
Behaviour tree
Node control
Behaviour tree
Node control
• Interrupter here serves as a specialized Selector​
• “Is Higher Priority In Sight” returns failure, so the selector goes on
to the next one, without executing “Increase Alertness”​
• “Has Behaviour Changed” is true, so it continues throughout that
execution​
• The sequencer here continues the execution of a sequence of
actions​
• “Is Inside Container” condition wasn’t met (red frame), but
“Succeed” decorator modified that return value to “Success”
(green frame) so Sequencer takes next action​
• Check “Is behaviour Feasible” return Success, telling Sequencer
to proceed​
• Further chaining through similar conditions made this specific
NPC in scene move towards the clothes cupboard for him to “get
dressed” for the job he is planning to do​
• The current status is “Running” which goes from “Move to
Position” node, which will be so until the villager reaches its
destination​
Creating a
Behaviour tree
Behaviour tree starts with a
unique “Root Node” and will
progress from top to bottom,
left to right, what is needed
besides that are specific
nodes that will control the
flow and execute what we
want
Creating a more “lifelike”
behaviour leads to
potential first pitfall:
Visually large tree that is
basically unmanageable
To more easily manage and
edit certain behaviours
inside a complex unit, we
can compose it of multiple
sub-trees, so we can
edit/debug each part
independently.
Such sub-trees can also
be dynamically placed,
according to specific
needs, so we can mix
and match them based
on the needs of specific
NPC instead of creating
new ones for each
unique combination, or
cluttering a single one
with everything
Creating a Behaviour tree
Here we have a base tree
that is common for each and
every NPC, where the right-
most node is “Behaviour
Runner” which on start loads
the sub-trees that specific
villager needs (bottom
picture), and selects which is
currently in use based on
data outside the tree
Behaviour tree
performance
As mentioned, we have “limit” of 16ms of processing time for all calculations in
between and it is quite easy to exceed that
Behaviour trees can take a lot of time on CPU's Main Thread (Especially with
multi-threading limitations, which are common in game development)
Framerate needs to be as constant as possible, every drop, even for a single
frame, impacts the feel of game
Behaviour tree
optimisation
As anywhere in Update / Tick loop in the game, avoid “Heavy functions” in
Behaviour tree as much as possible, especially in parts that are oftenly
executed/checked (e.g. in Unity: GetComponent())
Use composites to “manually” navigate to certain parts of the tree (if possible),
every unnecessary check can prolong execution time
Multithread what you can, but beware of race conditions and other risks
Still too heavy on
performance?
Behaviour tree update is manually called, and maybe it doesn’t have to check
every frame.​
⚬ Calling Update is possible in intervals​
⚬ To smooth up the frame rate, spread the updates of individual NPCs
across the frames
Set priority for how often you update specific NPCs like​
⚬ NPC in the Player's view is more frequent than one outside​
⚬ Chicken clucking in the coop won’t be so influential on gameplay so can
be updated less frequently
But now NPCs
are stuttering
After applying previous advice, we can have situations where visuals are “chop-
y” and similar issues​
⚬ To address that we have to be aware and adapt related scripts to two
different timings: one is frame time, second is frame * x (where x is
frequency), and use it as such​
⚬ Even if we collect data less frequently than we display them, we can
compare those timings and interpolate visuals between behaviour trees
updates​
What else can
we do?
​Stacking
Interruptions​
It is possible also to stack Interrupters (which re-check conditions every update)
to narrow the number of checks which update of tree evaluates and also gain
additional control options.​
⚬ Usually achieved by giving proper depth to the tree besides wideness​
⚬ Can be also accomplished with the Flat Stack approach​
Constant
re-iteration​
Behaviour tree nodes need constant adaptation as the project progresses,
meaning actions, conditions etc. need to be adapted.
Such frequent looks at code enable us to spot bottlenecks and other issues for
constant improvement besides adaptations.
Open discussion​
Behaviour trees are adjustable and quite open, so anything that may improve it
is a good topic to discuss, be it among peers while having a drink or on the
internet at 3 a.m.
Such talk can only improve systems and bring new levels of quality​.
Let's wrap it up
AI vs
Video game AI
While related to video games, AI loses the connection between machine
learning and similar relations.
Instead, it defines how NPC “gets “lifelike” conclusions and reactions” to things
in the game caused by the Player
Behaviour Tree
Behaviour Tree is basically a compact visual way to connect different conditions
and actions, making it possible for designers, etc to connect what they want
from given blocks while allowing almost* limitless possibilities to those writing
such blocks​
That's all folks!
TheSoky#6970
https://game-chuck.com

[Pandora 22] Ups and Down of Using Behaviour Trees in Unity to Model Villager AI - Martin Sostar

  • 1.
    Using Behaviour Trees inUnity to Model Villager AI​ Ups and Downs of
  • 2.
    Video game and hardwaredeveloper established in 2017, based in Zagreb, Croatia Numerous international awards and nominations About Gamechuck Retro-styled action games, and large-scale narrative-driven adventure games
  • 3.
    Game developer who learnedthe trade by annoying too many people to share knowledge Mostly working in Unity and C#, while no stranger to Unreal Engine and C++ About me Experienced in games for Android/IOS, PC, Current Console General knowledge of majority of Game programming, while focus is in Performance and Game AI
  • 4.
    About Midwintär Narrative-driven stealth-action inspired bymedieval horror folklore​ Combines careful tactical planning with fast-paced arcade execution Relies on complex, adaptive behaviour of NPCs Singleplayer, co-op, for PC and Consoles, with cross- platform multiplayer in mind
  • 5.
    3 playable characters Specificgoals Tools Hostile villagers Gameplay
  • 6.
    What is anNPC? NPC or "non-playable character" is any character in-game that is not controlled by Player(s)​ NPCs are commonly used to fill out the world, make it more interesting and immersive, giving Player more to interact with
  • 7.
    Etc What is agame AI? What does it do regularly? How does it react to dangers? How will it react to something suspicious?
  • 8.
  • 9.
  • 10.
    Behaviour tree Main Nodetypes Action (Execution) nodes Composite (Control) nodes Node “leaf” or end point of branch in tree, usually checks condition or does some kind of action, like set destination for npc to move towards​ they further control order and selection of where should wanted behaviour be found (e.g. Sequence, Selector...)​
  • 11.
    Behaviour tree Optional Nodetypes Condition (either as action or composite) Decorator Node as always, key for branching, without complex composites that do specific sub-branch selection, this one will check and block / allow specific executions​ used to modify a return value of Node / Branch beneath it. e.g. : “Success” decorator returns successful execution regardless if branch failed of succeeded in execution; or “Repeat” which will Repeat it’s branch until some condition(s) are met​
  • 12.
    Behaviour tree Node status EachUpdate / Tick of Behaviour tree, there is a return value of running branch, one of following: Success: Job / Action completed successfully Failure: Failed to complete the job or conditions for it not met​ Running: Job is still in progress​
  • 13.
  • 14.
    Behaviour tree Node control •Interrupter here serves as a specialized Selector​ • “Is Higher Priority In Sight” returns failure, so the selector goes on to the next one, without executing “Increase Alertness”​ • “Has Behaviour Changed” is true, so it continues throughout that execution​ • The sequencer here continues the execution of a sequence of actions​ • “Is Inside Container” condition wasn’t met (red frame), but “Succeed” decorator modified that return value to “Success” (green frame) so Sequencer takes next action​ • Check “Is behaviour Feasible” return Success, telling Sequencer to proceed​ • Further chaining through similar conditions made this specific NPC in scene move towards the clothes cupboard for him to “get dressed” for the job he is planning to do​ • The current status is “Running” which goes from “Move to Position” node, which will be so until the villager reaches its destination​
  • 15.
    Creating a Behaviour tree Behaviourtree starts with a unique “Root Node” and will progress from top to bottom, left to right, what is needed besides that are specific nodes that will control the flow and execute what we want Creating a more “lifelike” behaviour leads to potential first pitfall: Visually large tree that is basically unmanageable To more easily manage and edit certain behaviours inside a complex unit, we can compose it of multiple sub-trees, so we can edit/debug each part independently. Such sub-trees can also be dynamically placed, according to specific needs, so we can mix and match them based on the needs of specific NPC instead of creating new ones for each unique combination, or cluttering a single one with everything
  • 16.
    Creating a Behaviourtree Here we have a base tree that is common for each and every NPC, where the right- most node is “Behaviour Runner” which on start loads the sub-trees that specific villager needs (bottom picture), and selects which is currently in use based on data outside the tree
  • 17.
    Behaviour tree performance As mentioned,we have “limit” of 16ms of processing time for all calculations in between and it is quite easy to exceed that Behaviour trees can take a lot of time on CPU's Main Thread (Especially with multi-threading limitations, which are common in game development) Framerate needs to be as constant as possible, every drop, even for a single frame, impacts the feel of game
  • 18.
    Behaviour tree optimisation As anywherein Update / Tick loop in the game, avoid “Heavy functions” in Behaviour tree as much as possible, especially in parts that are oftenly executed/checked (e.g. in Unity: GetComponent()) Use composites to “manually” navigate to certain parts of the tree (if possible), every unnecessary check can prolong execution time Multithread what you can, but beware of race conditions and other risks
  • 19.
    Still too heavyon performance? Behaviour tree update is manually called, and maybe it doesn’t have to check every frame.​ ⚬ Calling Update is possible in intervals​ ⚬ To smooth up the frame rate, spread the updates of individual NPCs across the frames Set priority for how often you update specific NPCs like​ ⚬ NPC in the Player's view is more frequent than one outside​ ⚬ Chicken clucking in the coop won’t be so influential on gameplay so can be updated less frequently
  • 20.
    But now NPCs arestuttering After applying previous advice, we can have situations where visuals are “chop- y” and similar issues​ ⚬ To address that we have to be aware and adapt related scripts to two different timings: one is frame time, second is frame * x (where x is frequency), and use it as such​ ⚬ Even if we collect data less frequently than we display them, we can compare those timings and interpolate visuals between behaviour trees updates​
  • 21.
  • 22.
    ​Stacking Interruptions​ It is possiblealso to stack Interrupters (which re-check conditions every update) to narrow the number of checks which update of tree evaluates and also gain additional control options.​ ⚬ Usually achieved by giving proper depth to the tree besides wideness​ ⚬ Can be also accomplished with the Flat Stack approach​
  • 23.
    Constant re-iteration​ Behaviour tree nodesneed constant adaptation as the project progresses, meaning actions, conditions etc. need to be adapted. Such frequent looks at code enable us to spot bottlenecks and other issues for constant improvement besides adaptations.
  • 24.
    Open discussion​ Behaviour treesare adjustable and quite open, so anything that may improve it is a good topic to discuss, be it among peers while having a drink or on the internet at 3 a.m. Such talk can only improve systems and bring new levels of quality​.
  • 25.
  • 26.
    AI vs Video gameAI While related to video games, AI loses the connection between machine learning and similar relations. Instead, it defines how NPC “gets “lifelike” conclusions and reactions” to things in the game caused by the Player
  • 27.
    Behaviour Tree Behaviour Treeis basically a compact visual way to connect different conditions and actions, making it possible for designers, etc to connect what they want from given blocks while allowing almost* limitless possibilities to those writing such blocks​
  • 28.

Editor's Notes

  • #2 Pleased to see you all here
  • #3 1.7.2013
  • #4 To introduce myself a bit better, I’ve been working as game developer for years now, and while I don’t have any official education in that field, I got my knowledge from people who were willing to share it. I do mostly work in Unity and C#, I also like using UE and actually do like CPP as language. While having various, “Jack of all trades” style knowledge, my specializes would be game AI and Performance Optimization
  • #5 Project I am currently working on; and is solid example for talk about behaviour trees is Midwintar It is a Narrative driven, stealth – action inspired by medieval horror folklore. We aim to combine careful tactical planning with fast-paced arcade execution Available play types are either single-player or co-op (which can be either splitscreen or 2 separate devices) with cross-platform multiplayer in mind Game relies on complex and adaptive behaviour of NPCs
  • #6 1.7.2013
  • #7 NPC or “non-playable character” is any character in-game that is not controlled by Players NPCs are commonly used to fill out the world, make it more interesting and immersive, giving Players more to interact with
  • #8 1.7.2013
  • #9 1.7.2013
  • #10 1.7.2013
  • #11 1.7.2013
  • #12 1.7.2013
  • #13 1.7.2013
  • #14 1.7.2013
  • #15 1.7.2013
  • #16 1.7.2013
  • #17 1.7.2013
  • #18 1.7.2013
  • #19 1.7.2013
  • #20 1.7.2013
  • #21 1.7.2013
  • #22 1.7.2013
  • #23 1.7.2013
  • #24 1.7.2013
  • #25 1.7.2013
  • #26 1.7.2013
  • #27 1.7.2013
  • #28 1.7.2013
  • #29 1.7.2013