<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.chrishecker.com/index.php?action=history&amp;feed=atom&amp;title=My_Liner_Notes_for_Spore%2FSpore_Behavior_Tree_Docs</id>
	<title>My Liner Notes for Spore/Spore Behavior Tree Docs - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.chrishecker.com/index.php?action=history&amp;feed=atom&amp;title=My_Liner_Notes_for_Spore%2FSpore_Behavior_Tree_Docs"/>
	<link rel="alternate" type="text/html" href="https://www.chrishecker.com/index.php?title=My_Liner_Notes_for_Spore/Spore_Behavior_Tree_Docs&amp;action=history"/>
	<updated>2026-04-21T16:16:50Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.36.1</generator>
	<entry>
		<id>https://www.chrishecker.com/index.php?title=My_Liner_Notes_for_Spore/Spore_Behavior_Tree_Docs&amp;diff=2125&amp;oldid=prev</id>
		<title>Checker at 13:14, 12 April 2009</title>
		<link rel="alternate" type="text/html" href="https://www.chrishecker.com/index.php?title=My_Liner_Notes_for_Spore/Spore_Behavior_Tree_Docs&amp;diff=2125&amp;oldid=prev"/>
		<updated>2009-04-12T13:14:13Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 13:14, 12 April 2009&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;This is from the example code for Spore's Behavior Tree AI System.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   SPBehaviorTreeDocs - The Spore Behavior Tree AI System Documentation&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   SPBehaviorTreeDocs - The Spore Behavior Tree AI System Documentation&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   Chris Hecker - Maxis / Electronic Arts&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   Chris Hecker - Maxis / Electronic Arts&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key checkerwiki:diff::1.12:old-2123:rev-2125 --&gt;
&lt;/table&gt;</summary>
		<author><name>Checker</name></author>
	</entry>
	<entry>
		<id>https://www.chrishecker.com/index.php?title=My_Liner_Notes_for_Spore/Spore_Behavior_Tree_Docs&amp;diff=2123&amp;oldid=prev</id>
		<title>Checker: New page:   SPBehaviorTreeDocs - The Spore Behavior Tree AI System Documentation   Chris Hecker - Maxis / Electronic Arts       &quot;The present letter is a very long one, simply because I had no       ...</title>
		<link rel="alternate" type="text/html" href="https://www.chrishecker.com/index.php?title=My_Liner_Notes_for_Spore/Spore_Behavior_Tree_Docs&amp;diff=2123&amp;oldid=prev"/>
		<updated>2009-04-12T12:42:48Z</updated>

		<summary type="html">&lt;p&gt;New page:   SPBehaviorTreeDocs - The Spore Behavior Tree AI System Documentation   Chris Hecker - Maxis / Electronic Arts       &amp;quot;The present letter is a very long one, simply because I had no       ...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;  SPBehaviorTreeDocs - The Spore Behavior Tree AI System Documentation&lt;br /&gt;
  Chris Hecker - Maxis / Electronic Arts&lt;br /&gt;
&lt;br /&gt;
     &amp;quot;The present letter is a very long one, simply because I had no&lt;br /&gt;
      leisure to make it shorter.&amp;quot; - Blaise Pascal&lt;br /&gt;
&lt;br /&gt;
  This documentation is written as a sort of &amp;quot;literate program&amp;quot;, which&lt;br /&gt;
  means the documentation and the demo code are interspersed, and the&lt;br /&gt;
  code can actually be compiled to make a running sample of the AI (if&lt;br /&gt;
  you've also got the Animpreview prototyping environment to link in,&lt;br /&gt;
  but even if you don't, you at least know the code is real since it's&lt;br /&gt;
  used as the test rig).  This means the demo code is slightly&lt;br /&gt;
  exaggerated to be a good example of the system's features; you&lt;br /&gt;
  wouldn't necessarily use as many different features in such close&lt;br /&gt;
  proximity during normal use.&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  Contents&lt;br /&gt;
  --------&lt;br /&gt;
&lt;br /&gt;
  S01: Overview&lt;br /&gt;
  S02: Design Principles&lt;br /&gt;
  S03: Differences From Halo's Behavior Tree AI&lt;br /&gt;
  S04: How Deciders Decide&lt;br /&gt;
  S05: Subset Rule&lt;br /&gt;
  S06: Preconditions &amp;amp; Stimuli&lt;br /&gt;
  S07: Memory &amp;amp; Blocks&lt;br /&gt;
  S08: Behaviors&lt;br /&gt;
  S09: Initializing and Ticking the Behavior Tree&lt;br /&gt;
  S10: Performance&lt;br /&gt;
  S11: Debugging&lt;br /&gt;
  S12: Macros&lt;br /&gt;
  S13: Behavior Declaraction&lt;br /&gt;
  S14: Behavior Definitions&lt;br /&gt;
  S15: Behavior Flags&lt;br /&gt;
  S16: Decider Declarations&lt;br /&gt;
  S17: Decider Definitions&lt;br /&gt;
  S18: Decider and Behavior Function Definitions&lt;br /&gt;
  S19: The Agent Pointer&lt;br /&gt;
  S20: Basic Behavior Memory Blocks&lt;br /&gt;
  S21: Advanced Behavior Memory Blocks&lt;br /&gt;
  S22: Decider Blocks (DBlocks)&lt;br /&gt;
  S23: Group Decider Behaviors&lt;br /&gt;
&lt;br /&gt;
  You can search for sections using the &amp;quot;Sn:&amp;quot; section number.  There&lt;br /&gt;
  are lots of comments that aren't big enough for sections, so also&lt;br /&gt;
  search for &amp;quot;//&amp;quot;.&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  S01: Overview&lt;br /&gt;
  -------------&lt;br /&gt;
&lt;br /&gt;
  The Behavior Tree (BT) system is a library for declaring and ticking&lt;br /&gt;
  Hierarchical Finite State Machines operating on &amp;quot;agents&amp;quot;[1].  The&lt;br /&gt;
  system is blind to the type of the agent, so the agent could be a&lt;br /&gt;
  character, or it could be some kind of strategic entity, or it could&lt;br /&gt;
  just be null.&lt;br /&gt;
&lt;br /&gt;
  At the highest level, a behavior tree is made up of arrays of&lt;br /&gt;
  &amp;quot;deciders&amp;quot;.  Eventually the deciders bottom out and reference&lt;br /&gt;
  specific &amp;quot;behaviors&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
  Deciders can contain references to arrays of other deciders (called&lt;br /&gt;
  &amp;quot;group deciders&amp;quot;, and the referenced deciders are called&lt;br /&gt;
  &amp;quot;children&amp;quot;), or they can reference behaviors (called &amp;quot;behavior&lt;br /&gt;
  deciders&amp;quot;)[2].&lt;br /&gt;
&lt;br /&gt;
  As their name implies, deciders do the decision-making in the tree.&lt;br /&gt;
  A decider has a function called Decide which looks at the state of&lt;br /&gt;
  the world and calculates whether the decider should activate.  If&lt;br /&gt;
  the decider was a group decider, then the decision process repeats&lt;br /&gt;
  for the children.  There are a number of policies for determining&lt;br /&gt;
  which child in a group will run, including prioritized list,&lt;br /&gt;
  random, sequential, Sims-like scored competition, etc.  These are&lt;br /&gt;
  covered below in detail.&lt;br /&gt;
  &lt;br /&gt;
  Behavior deciders activate their referenced behavior when they&lt;br /&gt;
  activate.  The behavior is where the actual AI action code lives.&lt;br /&gt;
  Behaviors have Activate, Deactivate, and Tick functions for&lt;br /&gt;
  accomplishing their goals.  Assuming no higher priority deciders&lt;br /&gt;
  interrupt it, the currently active behavior will get ticked every&lt;br /&gt;
  frame and the AI will do its stuff.&lt;br /&gt;
&lt;br /&gt;
  A decider that references a behavior is a leaf of the tree.  A given&lt;br /&gt;
  behavior can be referenced from multiple behavior deciders, and&lt;br /&gt;
  deciders can be referenced by multiple group deciders.  This means&lt;br /&gt;
  the BT is actually potentially a DAG and is not limited to a tree&lt;br /&gt;
  structure.&lt;br /&gt;
&lt;br /&gt;
  A simple example of a behavior tree might be:&lt;br /&gt;
&lt;br /&gt;
           +--------+&lt;br /&gt;
  *ROOT+--&amp;gt;| FLEE   |                               +----------------+&lt;br /&gt;
           | GUARD+-|------------------------------&amp;gt;| YELL_FOR_HELP  |&lt;br /&gt;
           | FIGHT  |                               | FIGHT          |&lt;br /&gt;
           |*EAT+---|--------+     +------------+   | PATROL         |&lt;br /&gt;
           | IDLE+--|--+     +----&amp;gt;| FIND_FOOD  |   | REST           |&lt;br /&gt;
           +--------+  |           |*EAT_FOOD   |   +----------------+&lt;br /&gt;
                       |           +------------+ &lt;br /&gt;
                       |  +-------+  &lt;br /&gt;
                       +-&amp;gt;| PLAY+-|--+   +--------+&lt;br /&gt;
                          | REST  |  +--&amp;gt;| FLIP   |&lt;br /&gt;
                          +-------+      | ROLL   |&lt;br /&gt;
                                         | DANCE  |&lt;br /&gt;
                                         +--------+&lt;br /&gt;
                           Figure 1.&lt;br /&gt;
&lt;br /&gt;
  Figure 1 only shows deciders in the tree, in ALL CAPS.  The deciders&lt;br /&gt;
  with arrows coming out of them are group deciders, and they point to&lt;br /&gt;
  their children arrays (the boxes), which contain other deciders.&lt;br /&gt;
  The deciders with no arrows coming from them--the leaves of the&lt;br /&gt;
  tree--are behavior deciders.  These behavior deciders reference a&lt;br /&gt;
  set of behaviors (not shown in the figure) that may or may not be&lt;br /&gt;
  named similarly to the deciders and may or may not be shared between&lt;br /&gt;
  the deciders.&lt;br /&gt;
&lt;br /&gt;
  Each call to TickBehaviorTree with the ROOT decider works its way&lt;br /&gt;
  down the deciders, finding either a new path through the tree to&lt;br /&gt;
  activate, or continuing with the currently active path.&lt;br /&gt;
&lt;br /&gt;
  Walking through a simple example, assume the starred deciders in&lt;br /&gt;
  Figure 1 are active (ROOT-&amp;gt;EAT-&amp;gt;EAT_FOOD).  Also assume the group&lt;br /&gt;
  decision policy on the various groups is kGroupPrioritizedList,&lt;br /&gt;
  which means each decider's Decide will be called in order until&lt;br /&gt;
  either one accepts, or the execution reaches the currently active&lt;br /&gt;
  decider, and then it recurses.&lt;br /&gt;
&lt;br /&gt;
  During a tick of this tree, we start at the ROOT and see it is&lt;br /&gt;
  active, so we enter the group and call the Decide function on FLEE,&lt;br /&gt;
  GUARD, and FIGHT in order, because they're higher priority than EAT.&lt;br /&gt;
  If none accept, we recurse into EAT without calling its Decide since&lt;br /&gt;
  it's already active.  This is how the system exhibits hysteresis:&lt;br /&gt;
  the test to activate a decider is different from the test to&lt;br /&gt;
  continue executing.&lt;br /&gt;
&lt;br /&gt;
  In this case, we recurse into EAT, and call FIND_FOOD's Decide.  If&lt;br /&gt;
  it also does not want to run, we go into the active EAT_FOOD, and&lt;br /&gt;
  call Tick on the referenced behavior.&lt;br /&gt;
&lt;br /&gt;
  On the other hand, if GUARD's Decide accepts, then we deactivate the&lt;br /&gt;
  EAT-&amp;gt;EAT_FOOD path through the tree (so the behaviors and deciders&lt;br /&gt;
  can clean up if they want), and then we activate GUARD and recurse.&lt;br /&gt;
  The GUARD decider's children are then decided, one is activated,&lt;br /&gt;
  and that path becomes the new active path through the tree.  Next&lt;br /&gt;
  tick, only FLEE's Decide will be called in the ROOT group, because&lt;br /&gt;
  only FLEE is higher priority than GUARD.&lt;br /&gt;
&lt;br /&gt;
  To extend the walkthrough one step farther, if, within its Tick, the&lt;br /&gt;
  EAT_FOOD behavior decides it no longer wants to run, it returns&lt;br /&gt;
  false and the group does a &amp;quot;masked redecide&amp;quot;, meaning that the other&lt;br /&gt;
  children in the group are given a chance to Decide, but the child&lt;br /&gt;
  who failed is masked out of this decision step.  If one accepts,&lt;br /&gt;
  then the old path is deactivated and the new child is activated.  If&lt;br /&gt;
  none accept, the group decider pops back up a level and another&lt;br /&gt;
  masked redecide occurs, but now at the ROOT group level, with EAT&lt;br /&gt;
  masked out for this tick.  This gives IDLE a chance to activate.&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  S02: Design Principles&lt;br /&gt;
  ----------------------&lt;br /&gt;
  &lt;br /&gt;
  There are a few design principles that permeate the whole system:&lt;br /&gt;
&lt;br /&gt;
  1.  Clear, monolithic, and static declaration of the tree of states.&lt;br /&gt;
      As you'll see below, the declaration syntax of the state machine&lt;br /&gt;
      is highly C macro-driven and can be statically defined at file&lt;br /&gt;
      scope in a way that tries to make the overall structure of the&lt;br /&gt;
      tree visible at a glance, so it is fairly self-documenting.  The&lt;br /&gt;
      actual behavior function code itself can be in multiple files or&lt;br /&gt;
      anywhere you want it, but the tree structure should be declared&lt;br /&gt;
      in a single block of definition statements like below.  This&lt;br /&gt;
      architecture has the side benefit of compiling extremely&lt;br /&gt;
      quickly.&lt;br /&gt;
&lt;br /&gt;
  2.  Avoid O(n^2) coupling of behaviors by brute force, and make the&lt;br /&gt;
      brute force execution efficient.  The entire active part of the&lt;br /&gt;
      tree is ticked every frame, which--in the case of the common&lt;br /&gt;
      prioritized list group decision policy--means all designated&lt;br /&gt;
      higher priority behaviors get a chance to interrupt the current&lt;br /&gt;
      active behavior before it is ticked.  This frees a behavior from&lt;br /&gt;
      having to know about other behaviors or unrelated external&lt;br /&gt;
      stimuli; if a more important behavior is supposed to activate,&lt;br /&gt;
      it will activate naturally due to the flow of decision making.&lt;br /&gt;
      Various flags and masks allow this ticking to proceed without&lt;br /&gt;
      even calling functions a lot of the time.&lt;br /&gt;
  &lt;br /&gt;
  3.  Easy visualization and debuggability.  Because a tree is a&lt;br /&gt;
      static plain C struct data structure with no need for a dynamic&lt;br /&gt;
      initialization/construction phase or allocations, it is clearly&lt;br /&gt;
      visible in the debugger watch window at any point during&lt;br /&gt;
      execution, with full named symbols even in optimized builds.&lt;br /&gt;
      Also, multiple runtime visualization tools are provided to&lt;br /&gt;
      display the entire tree, the active path through the tree, and&lt;br /&gt;
      hookable debug output with 5 debug levels of output detail,&lt;br /&gt;
      covering everything from outputing only changes in the active&lt;br /&gt;
      state, to full output of every decision result.&lt;br /&gt;
&lt;br /&gt;
  4.  No boilerplate code.  Just about everything in the BT system has&lt;br /&gt;
      defaults and custom creation macros, so you should only ever need to&lt;br /&gt;
      write code that actually does something for your AI.  If you&lt;br /&gt;
      have a behavior that only needs to Tick, you don't have to write&lt;br /&gt;
      default Activate/Deactivate functions that simply return, or&lt;br /&gt;
      vice-versa if you only want Activate/Deactivate but don't need&lt;br /&gt;
      to Tick, etc.&lt;br /&gt;
&lt;br /&gt;
  5.  Diagonal design.  As Larry Wall says, orthogonal design is&lt;br /&gt;
      totally overrated.  You don't want to travel in right angles,&lt;br /&gt;
      you cut across and go direct.  There is more than one way to do&lt;br /&gt;
      just about everything in the BT system.  This is flexible, but&lt;br /&gt;
      can be confusing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  S03: Differences From Halo's Behavior Tree AI&lt;br /&gt;
  ---------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
  This BT system is basically trying to be &amp;quot;version 1.5&amp;quot; of Halo's AI&lt;br /&gt;
  system.  The Halo system is documented in the Gamasutra article&lt;br /&gt;
  &amp;quot;Handling Complexity in the Halo 2 AI&amp;quot; by Damian Isla, mirrored in&lt;br /&gt;
  this directory as halo_ai_isla.htm.  I talked with the Halo guys a&lt;br /&gt;
  bunch about their current system, and then brainstormed with them&lt;br /&gt;
  about how to improve it since we were starting from scratch.  This&lt;br /&gt;
  system is the result.  The Halo guys were incredibly helpful and&lt;br /&gt;
  open with sharing detailed information about their system, and its&lt;br /&gt;
  pros and cons, and this system owes much to them.&lt;br /&gt;
&lt;br /&gt;
  The Halo paper is slightly misleading in one key area: their tree is&lt;br /&gt;
  actually completely static.  Impusles and stimulus behaviors are not&lt;br /&gt;
  inserted into the tree at runtime, they are simply checked every&lt;br /&gt;
  tick like everything else, it's just that they won't fire until the&lt;br /&gt;
  conditions for them to fire are present.  This is conceptually like&lt;br /&gt;
  they are inserted dynamically, but in fact the tree structure is&lt;br /&gt;
  compile-time static.  Our system is the same.&lt;br /&gt;
&lt;br /&gt;
  The biggest difference between the two systems is that we separated&lt;br /&gt;
  out the concept of a &amp;quot;decider&amp;quot; from a &amp;quot;behavior&amp;quot;.  The Halo tree is&lt;br /&gt;
  all behaviors (group/mutex or regular) and impulses, and impulses&lt;br /&gt;
  can jump to behaviors to activate them at different priorities.  We&lt;br /&gt;
  unified the impulses and group behaviors into deciders, and the&lt;br /&gt;
  behaviors are completely separate.  This lets us reuse behaviors in&lt;br /&gt;
  multiple places in the tree like impulses do, without having a&lt;br /&gt;
  separate type.&lt;br /&gt;
&lt;br /&gt;
  There are a bunch of minor differences as well (we don't check&lt;br /&gt;
  preconditions on already active deciders, Halo does, etc.), but the&lt;br /&gt;
  concepts and design principles are basically the same.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  S04: How Deciders Decide&lt;br /&gt;
  ------------------------&lt;br /&gt;
&lt;br /&gt;
  Conceptually, a decider has a Decide function that gets called, and&lt;br /&gt;
  depending on the group policy, the floating point return value of&lt;br /&gt;
  the Decide function indicates whether the decider will activate.&lt;br /&gt;
&lt;br /&gt;
  In practice, there are a number of options available for deciders.&lt;br /&gt;
  The specific code expression of these options will be shown below,&lt;br /&gt;
  so this section will only give an overview.&lt;br /&gt;
  &lt;br /&gt;
  1.  There does not need to be a Decide function.  If it is 0, then&lt;br /&gt;
      it is semantically the same as if it had returned 1.0.  This can&lt;br /&gt;
      be used by itself to make a decider that always accepts, say as&lt;br /&gt;
      the last entry in a priority list, like IDLE in Figure 1, or it&lt;br /&gt;
      can be combined with the other decider options listed here to&lt;br /&gt;
      avoid writing a dummy Decide.&lt;br /&gt;
&lt;br /&gt;
  2.  There are optional preconditions that are checked before the&lt;br /&gt;
      Decide is called.  These preconditions can do things like only&lt;br /&gt;
      allow the Decide to be called after a given timeout, or they can&lt;br /&gt;
      do logical operations on two kinds of flags, DecisionFlags and&lt;br /&gt;
      StimuliFlags, covered below.&lt;br /&gt;
&lt;br /&gt;
  3.  A Decide can delegate its decision to its children.  There are&lt;br /&gt;
      currently a number of caveats to this mentioned in the header at&lt;br /&gt;
      the function declaration, but it is possible.&lt;br /&gt;
&lt;br /&gt;
  4.  The deciders have a flag that controls whether the Decide of the&lt;br /&gt;
      group is called when it redecides because a child failed.  This&lt;br /&gt;
      allows you to avoid writing the redundant checks inside the&lt;br /&gt;
      children if you want to check whether a group is still valid to&lt;br /&gt;
      run.&lt;br /&gt;
&lt;br /&gt;
  In general, Decide functions should not set state on the agent&lt;br /&gt;
  unless you know what you're doing.  If you know the structure of&lt;br /&gt;
  your tree, and know that if you return 1.0 from a Decide that you&lt;br /&gt;
  will activate it, then it's fine to set state since you know your&lt;br /&gt;
  return will cause a change in the AI state.  But, if you're in a&lt;br /&gt;
  Decide that you don't know will guarantee activation, setting state&lt;br /&gt;
  on the agent could cause bugs (you set state, then don't get&lt;br /&gt;
  activated, so your state isn't cleaned up or you hose existing&lt;br /&gt;
  state).  Decide functions can use DBlocks (see below) to handle&lt;br /&gt;
  transient data communication between Decides and behaviors.&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  S05: Subset Rule&lt;br /&gt;
  ----------------&lt;br /&gt;
  &lt;br /&gt;
  The most important thing to remember when writing a Decide function&lt;br /&gt;
  for a group decider is that the Decide has to obey the &amp;quot;Subset&lt;br /&gt;
  Rule&amp;quot;.  The Subset Rule says that a Decide on a group must be a&lt;br /&gt;
  subset of the Decides on the children.  This could mean they are&lt;br /&gt;
  equal (ie. it does not have to be a proper subset), but the parent&lt;br /&gt;
  Decide can not be a superset of the child Decides.  If the parent&lt;br /&gt;
  was a superset, then the parent would accept in some circumstances,&lt;br /&gt;
  but the children would all reject, and then the parent's group would&lt;br /&gt;
  redecide, the parent would potentially accept again (ignoring the&lt;br /&gt;
  masking on redecides for the moment), and you'd get an infinite&lt;br /&gt;
  loop.  There is a redecide loop count to guard against this, but if&lt;br /&gt;
  it fires, the TickBehaviorTree exits with an error (which makes it&lt;br /&gt;
  easy to call EA_VERIFY()), and potentially no behavior ticked that&lt;br /&gt;
  frame so the AI is frozen.&lt;br /&gt;
&lt;br /&gt;
  The Subset Rule is pretty easy to obey, it just takes a small amount&lt;br /&gt;
  of thought when designing your tree.  There is nothing stopping&lt;br /&gt;
  children from calling the parent's Decide directly (or using the&lt;br /&gt;
  kFlagsCallDecideOnRedecide) if that's the easiest way to enforce it.&lt;br /&gt;
  It's not really a constraint, because all it is actually saying is&lt;br /&gt;
  that if you're going to enter a sub-state, the states within it had&lt;br /&gt;
  better be ready to run.&lt;br /&gt;
&lt;br /&gt;
  The Subset Rule makes it slightly inconvenient if all you're trying&lt;br /&gt;
  to do is pull some deciders out of a group into a child group to&lt;br /&gt;
  clean up a large list or something.  In that case, you need to use&lt;br /&gt;
  the DelegateDecideToChildren function in the subgroup Decide, which&lt;br /&gt;
  has some performance and behavior caveats as documented at its&lt;br /&gt;
  declaration.  If this turns out to be a big problem, it would be a&lt;br /&gt;
  bit of work to fix, but we can make a flag for delegation and handle&lt;br /&gt;
  this within the TickBehaviorTree.  Usually, groups are used as&lt;br /&gt;
  semantic units, like GUARD_NEST, where the decision to guard the&lt;br /&gt;
  nest is very different from the children decisions about how to&lt;br /&gt;
  guard the nest, so I don't forsee this being much of an issue.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  S06: Preconditions &amp;amp; Stimuli&lt;br /&gt;
  ----------------------------&lt;br /&gt;
&lt;br /&gt;
  As mentioned above, a decider can have preconditions that are&lt;br /&gt;
  evaluated before the Decide is called.  There are two basic kinds:&lt;br /&gt;
  time checks, and flag checks.&lt;br /&gt;
&lt;br /&gt;
  Time check preconditions allow you to mask off deciders based on a&lt;br /&gt;
  countdown, so a time check precondition of 30.0 would mean only&lt;br /&gt;
  evaluate this decider every 30 seconds.  The delay is from the last&lt;br /&gt;
  call to Decide, not from the Deactivate, which might change in the&lt;br /&gt;
  future.&lt;br /&gt;
&lt;br /&gt;
  There are two kinds of flags checks, DecisionFlags and StimuliFlags,&lt;br /&gt;
  but they both have the same behavior.  You can specify &amp;quot;any&amp;quot; and&lt;br /&gt;
  &amp;quot;all&amp;quot; type checks (AND and OR), with 0 or 1 bits required in the&lt;br /&gt;
  check.&lt;br /&gt;
&lt;br /&gt;
  DecisionFlags are simple ad hoc flags passed into TickBehaviorTree&lt;br /&gt;
  to control the enabling and disabling of deciders.  DecisionFlags&lt;br /&gt;
  might be used for the agent's level, whether it's an herbivore or a&lt;br /&gt;
  carnivore, whether it's part of a squad, whether it's dead, whether&lt;br /&gt;
  it's nighttime in the level, etc.&lt;br /&gt;
&lt;br /&gt;
  The StimuliFlags support the same precondition logical checks as&lt;br /&gt;
  DecisionFlags, but they have more explicit semantic structure.  The&lt;br /&gt;
  StimuliFlags are passed in as a pointer to the StimuliAllFlags&lt;br /&gt;
  member of a behavior_stimuli structure, which stores &amp;quot;stimuli&amp;quot; for&lt;br /&gt;
  an agent.  A stimulus is a token with some optional data associated&lt;br /&gt;
  with it and a timeout.  It is used for things like inviting an agent&lt;br /&gt;
  to play, or notifying an agent that it took a hit, or setting some&lt;br /&gt;
  temporary state on yourself to avoid repeating something, etc.&lt;br /&gt;
  There are lots of stimuli examples spread throughout the example&lt;br /&gt;
  code below (search for kStimuli_), and the behavior_stimuli struct&lt;br /&gt;
  is declared in SPBehaviorTreeHelpers.h.&lt;br /&gt;
&lt;br /&gt;
  Both of these flag checks allow the BT system to not even call a&lt;br /&gt;
  Decide if the preconditions are passes, and often you don't even&lt;br /&gt;
  need to write a Decide because you can express the conditions for&lt;br /&gt;
  activation with just the precondition checks.&lt;br /&gt;
&lt;br /&gt;
  The preconditions support arbitrary combinations of all of these&lt;br /&gt;
  checks simultaneously.&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  S07: Memory &amp;amp; Blocks&lt;br /&gt;
  --------------------&lt;br /&gt;
&lt;br /&gt;
  The BT system manages transient per-behavior data for you, and&lt;br /&gt;
  passes behaviors a pointer to a fixed size block of memory for the&lt;br /&gt;
  behavior's use.  This memory is reused as behaviors are activated&lt;br /&gt;
  and deactivated, and it stores both the current path through the&lt;br /&gt;
  tree, and also any custom information a behavior needs for its&lt;br /&gt;
  execution.  With casting, it can store arbitrary C++ data with&lt;br /&gt;
  constructors and destructors, as long as placement new and explicit&lt;br /&gt;
  deletes are used correctly.  There are macros provided to make this&lt;br /&gt;
  easy and safe.&lt;br /&gt;
&lt;br /&gt;
  The Decide function also gets passed a block (called a DBlock) that&lt;br /&gt;
  it can use to pass information to its behavior if necessary.&lt;br /&gt;
&lt;br /&gt;
  Any persistent data is assumed to be stored on the agent (for&lt;br /&gt;
  example, the stimuli are a form of blackboard storage on the agent).&lt;br /&gt;
  Behaviors cannot pass information to other behaviors in the tree&lt;br /&gt;
  without using the agent or some other extra-tree means.&lt;br /&gt;
&lt;br /&gt;
  More details on these blocks are below near the usage examples.&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  S08: Behaviors&lt;br /&gt;
  --------------&lt;br /&gt;
&lt;br /&gt;
  Briefly, behaviors are the chunks of code that operate on the agent&lt;br /&gt;
  to perform actions.  They are usually relatively chunky, like&lt;br /&gt;
  PATROL, and often have simple switch-statement finite state machines&lt;br /&gt;
  in them, using the blocks to keep their state.  Any state machine&lt;br /&gt;
  could have been coded into the tree, but at some point it becomes&lt;br /&gt;
  easier to have a simple 3-state FSM in the behavior rather than keep&lt;br /&gt;
  breaking things up, especially if the behavior needs temporary data&lt;br /&gt;
  (which would have to be lifted up to the agent if the states were&lt;br /&gt;
  broken up).&lt;br /&gt;
&lt;br /&gt;
  It is expected there are layers of code somewhere that deal with&lt;br /&gt;
  things like animation blending between states, timesliced routing,&lt;br /&gt;
  and whatnot.  The behaviors call these layers, and they handle any&lt;br /&gt;
  blending necessary between their own states.  So, for example, the&lt;br /&gt;
  animation layer will handle blending between animations played by&lt;br /&gt;
  two different behaviors; the behaviors themselves should not have to&lt;br /&gt;
  know about behavior transitions (to avoid O(n^2) complexity&lt;br /&gt;
  scaling).&lt;br /&gt;
&lt;br /&gt;
  Group deciders can also have behaviors that Activate/Tick/Deactivate&lt;br /&gt;
  with the decider.  This can be useful for doing setup and&lt;br /&gt;
  shutdown for the group state.  For example, notifying the nest that&lt;br /&gt;
  you're guarding it or no longer guarding it.  A false return value&lt;br /&gt;
  from Activate or Tick will fail the group and force a redecide, just&lt;br /&gt;
  like it does for behavior deciders.&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  S09: Initializing and Ticking the Behavior Tree&lt;br /&gt;
  -----------------------------------------------&lt;br /&gt;
&lt;br /&gt;
  Most of this documentation deals with creating the behavior tree&lt;br /&gt;
  itself, and writing the AI code in it, but there are a few things to&lt;br /&gt;
  know about setting it up and ticking it on agents.&lt;br /&gt;
&lt;br /&gt;
  Each behavior tree needs to have InitializeTreeData() called on it&lt;br /&gt;
  once before it will be ready to use (not per-agent).  This will&lt;br /&gt;
  verify that the tree obeys some of the constraints (like&lt;br /&gt;
  kMaxNumShuffleDeciderGroupChildren, etc.), and it will initialize&lt;br /&gt;
  any timer preconditions that may be in the tree and set the total&lt;br /&gt;
  number of timers in the root decider.  It returns true if the tree&lt;br /&gt;
  has been initialized correctly.&lt;br /&gt;
&lt;br /&gt;
  TickBehaviorTree will automatically call the InitializeTreeData&lt;br /&gt;
  function if it hasn't been called on the tree yet, but by that time&lt;br /&gt;
  it will be too late to allocate the timers if there are any in the&lt;br /&gt;
  tree (because you'll already be inside TickBehaviorTree).&lt;br /&gt;
&lt;br /&gt;
  Each agent should have behavior_tree_memory object, a&lt;br /&gt;
  behavior_stimuli object, and an array of decider_timers if the tree&lt;br /&gt;
  has any timer-based preconditions.  The number of decider_timers is&lt;br /&gt;
  set by InitializeTreeData into Root.Preconditions.NumTimers, where&lt;br /&gt;
  Root is the name of the root level decider.  This is the only&lt;br /&gt;
  decider that needs to be visible to the calling code, as you can see&lt;br /&gt;
  in SPBehaviorTreeDocs.h.&lt;br /&gt;
&lt;br /&gt;
  Every tick, the calling code should update the DecisionFlags for the&lt;br /&gt;
  agent state, call behavior_stimuli::Update(dt) on the agent's&lt;br /&gt;
  stimuli, and use the return value from this call to pass in as the&lt;br /&gt;
  StimuliAllFlags pointer to TickBehaviorTree.  After ticking, you can&lt;br /&gt;
  optionally call DebugPrintState as documented below.&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  S10: Performance&lt;br /&gt;
  ----------------&lt;br /&gt;
&lt;br /&gt;
  The most important performance factor to keep in mind is that the&lt;br /&gt;
  Decide functions should be very fast, since it is potentially called&lt;br /&gt;
  a lot.  It should use external timesliced systems for doing hard&lt;br /&gt;
  work, or at the very least use DBlocks so that it can communicate&lt;br /&gt;
  information to its behavior and the behavior won't have to&lt;br /&gt;
  redundantly compute stuff.&lt;br /&gt;
&lt;br /&gt;
  The behavior Tick functions should loop internally if the behavior&lt;br /&gt;
  is supposed to repeat, rather than failing and letting the BT choose&lt;br /&gt;
  them again.  This avoids needless work.&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  S11: Debugging&lt;br /&gt;
  --------------&lt;br /&gt;
&lt;br /&gt;
  There are two main types of debugging helpers in the BT system.&lt;br /&gt;
&lt;br /&gt;
  1.  DebugPrintState is a function that takes a tree and the memory&lt;br /&gt;
      state and will fill a text buffer with an indented view of&lt;br /&gt;
      either the active deciders or the entire tree, depending on a&lt;br /&gt;
      flag.  This is useful for tooltip style floating text in-game,&lt;br /&gt;
      and you can see what state an agent is in.&lt;br /&gt;
&lt;br /&gt;
      Here is an example output from DebugPrintState on an agent:&lt;br /&gt;
&lt;br /&gt;
      *0:ROOT/0x2d5e207 (kGroup, kGroupPrioritizedList 0x0) time: 34.32&lt;br /&gt;
        [(no group behavior)] idx: 1&lt;br /&gt;
          *1:GUARD_NEST_GROUP/0x2d5e200 (kGroup, kGroupPrioritizedList 0x1) time: 34.32&lt;br /&gt;
            [GUARD_NEST_GROUP/0x2c20c25] (0x00000000 0) idx: 3&lt;br /&gt;
              *3:GUARD_NEST_PATROL/0x2d5e203 (kBehavior 0x0) time: 4.51&lt;br /&gt;
                [PATROL/0x2c20c23] (0x00000000 0)&lt;br /&gt;
            &lt;br /&gt;
  2.  The BT system has debug output hooks for displaying what's going&lt;br /&gt;
      on during the decision making process inside TickBehaviorTree.&lt;br /&gt;
      The variables to hook into are at the top of SPBehaviorTree.h,&lt;br /&gt;
      and including DebugOutputLevel and its kin.  DebugOutputLevel 0&lt;br /&gt;
      is no output, 1 and 2 cause output only on behavior state&lt;br /&gt;
      transitions, and 3 through 5 cause output every tick.&lt;br /&gt;
      DebugOutputAgent set to 0 outputs for all agents, or if set&lt;br /&gt;
      masks all other agents.  There are DebugOutputCurrent* variables&lt;br /&gt;
      for doing more custom masking inside the DebugOutputFunc.&lt;br /&gt;
&lt;br /&gt;
      Here is some example DebugOutputLevel == 1 output (notice the&lt;br /&gt;
      timestamps; it is not output every frame, but only on&lt;br /&gt;
      transitions):&lt;br /&gt;
&lt;br /&gt;
      BTDBO(1) 0x026DBE38 @ 106.017:     activating behavior GROWL/0x2c20c22 with flags 0x0, in decider GUARD_NEST_GROWL/0x2d5e202&lt;br /&gt;
      BTDBO(1) 0x026DBE38 @ 106.728:     activating behavior FIGHT/0x2c20c21 with flags 0x3, in decider GUARD_NEST_FIGHT/0x2d5e201&lt;br /&gt;
      BTDBO(1) 0x026DBE38 @ 110.266:     activating behavior PATROL/0x2c20c23 with flags 0x0, in decider GUARD_NEST_PATROL/0x2d5e203&lt;br /&gt;
&lt;br /&gt;
      The BTDBO(n) indicates the output level for the line, the next&lt;br /&gt;
      pointer is the agent, then the time passed to TickBehaviorTree&lt;br /&gt;
      during this tick.  Next is the number of spaces indicating the&lt;br /&gt;
      depth into the tree at which the output occured, and then is the&lt;br /&gt;
      custom message.  Often the messages will have a SYMBOL/id pair,&lt;br /&gt;
      like GROWL/0x2c20c22 (from the example behavior tree below).&lt;br /&gt;
      &lt;br /&gt;
      And here is DebugOutputLevel == 5 output, dumped every frame:&lt;br /&gt;
&lt;br /&gt;
      BTDBO(3) 0x026DBE38 @ 149.267: **************** starting tree @ 0x00918CD0 for 0x026DBE38 ****************&lt;br /&gt;
      BTDBO(3) 0x026DBE38 @ 149.267: dt: 0.065555, DecisionFlags: 0x00000000, StimuliAllFlags: 0x00000000&lt;br /&gt;
      BTDBO(5) 0x026DBE38 @ 149.267: processing decider ROOT/0x2d5e207, flags: 0x0, new: 0, mask: 0x00000000, redecide: 0, block id: 0x02d5e207&lt;br /&gt;
      BTDBO(4) 0x026DBE38 @ 149.267: visiting current kGroup decider ROOT/0x2d5e207, kGroupPrioritizedList, 7 children, active child 1, duration 145.434&lt;br /&gt;
      BTDBO(5) 0x026DBE38 @ 149.267: child 0 (DIE/0x2d5e211)...failed DecisionFlags check&lt;br /&gt;
      BTDBO(5) 0x026DBE38 @ 149.267: ChildrenDecide returned with RunIdx -1, ShuffleIdx -1&lt;br /&gt;
      BTDBO(4) 0x026DBE38 @ 149.267: continuing child 1 GUARD_NEST_GROUP/0x2d5e200, duration: 145.433682&lt;br /&gt;
      BTDBO(5) 0x026DBE38 @ 149.267: next_decider_push GUARD_NEST_GROUP/0x2d5e200&lt;br /&gt;
      BTDBO(5) 0x026DBE38 @ 149.267:   processing decider GUARD_NEST_GROUP/0x2d5e200, flags: 0x1, new: 0, mask: 0x00000000, redecide: 0, block id: 0x02d5e200&lt;br /&gt;
      BTDBO(4) 0x026DBE38 @ 149.267:   visiting current kGroup decider GUARD_NEST_GROUP/0x2d5e200, kGroupPrioritizedList, 5 children, active child 4, duration 145.434&lt;br /&gt;
      BTDBO(5) 0x026DBE38 @ 149.267:   child 0 (GUARD_NEST_HELP/0x2d5e212)...passed StimuliFlags check...Decide returned 0.000000&lt;br /&gt;
      BTDBO(5) 0x026DBE38 @ 149.267:   child 1 (GUARD_NEST_FIGHT/0x2d5e201)...has no preconditions...Decide returned 0.000000&lt;br /&gt;
      BTDBO(5) 0x026DBE38 @ 149.267:   child 2 (GUARD_NEST_GROWL/0x2d5e202)...has no preconditions...Decide returned 0.000000&lt;br /&gt;
      BTDBO(5) 0x026DBE38 @ 149.267:   child 3 (GUARD_NEST_PATROL/0x2d5e203)...has no preconditions...Decide returned 0.000000&lt;br /&gt;
      BTDBO(5) 0x026DBE38 @ 149.267:   ChildrenDecide returned with RunIdx -1, ShuffleIdx -1&lt;br /&gt;
      BTDBO(4) 0x026DBE38 @ 149.267:   continuing child 4 GUARD_NEST_IDLE/0x2d5e204, duration: 145.433682&lt;br /&gt;
      BTDBO(5) 0x026DBE38 @ 149.267:   next_decider_push GUARD_NEST_IDLE/0x2d5e204&lt;br /&gt;
      BTDBO(5) 0x026DBE38 @ 149.267:     processing decider GUARD_NEST_IDLE/0x2d5e204, flags: 0x0, new: 0, mask: 0x00000000, redecide: 0, block id: 0x02d5e204&lt;br /&gt;
      BTDBO(4) 0x026DBE38 @ 149.267:     visiting current kBehavior decider GUARD_NEST_IDLE/0x2d5e204, duration 7.904&lt;br /&gt;
      BTDBO(3) 0x026DBE38 @ 149.267:     ticking behavior IDLE_WALK/0x2c20c24 @ 149.266829 (dt: 0.065555) with flags 0x2, duration 7.904&lt;br /&gt;
      BTDBO(3) 0x026DBE38 @ 149.267:     current behavior IDLE_WALK/0x2c20c24 with flags 0x2, in decider GUARD_NEST_IDLE/0x2d5e204&lt;br /&gt;
      BTDBO(3) 0x026DBE38 @ 149.267: **************** finished tree for 0x026DBE38, depth 3 ****************      &lt;br /&gt;
&lt;br /&gt;
  You can also access the various Debug*Name char fields in the&lt;br /&gt;
  deciders and behaviors yourself, and there are some string arrays&lt;br /&gt;
  defined for introspection of types at the top of SPBehaviorTree.h.&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  S12: Macros&lt;br /&gt;
  -----------&lt;br /&gt;
&lt;br /&gt;
  As mentioned above, and as you'll see below, the BT system uses a&lt;br /&gt;
  lot of macros to reduce the need for the user to type boilerplate&lt;br /&gt;
  code.  The general rule is that all BT macros begin with BT_, and&lt;br /&gt;
  are then usually followed by either DEFINE or DECLARE, depending on&lt;br /&gt;
  which the macros do.  Most declarations can appear in header files,&lt;br /&gt;
  while most definitions have to appear in source files.  Next is the&lt;br /&gt;
  type of object that's defined or declared, and then options.  Often&lt;br /&gt;
  the options will come after a __, and the full version with all the&lt;br /&gt;
  options available is often postfixed with __FULL.&lt;br /&gt;
&lt;br /&gt;
  Sometimes a compile error on a line with a macro will be hard to&lt;br /&gt;
  figure out, because something about the generated code is wrong.&lt;br /&gt;
  Often you can spot the problem by inspection, but remember you can&lt;br /&gt;
  right-click on a file in the Solution Explorer in MSVC, select&lt;br /&gt;
  Properties|C/C++|Preprocessor, and turn on Generate Preprocessed&lt;br /&gt;
  File if you have a really hard problem to track down.  Compiling the&lt;br /&gt;
  file will produce a filename.i file in the directory containing the&lt;br /&gt;
  sln file.  You can usually search for your symbol name, so something&lt;br /&gt;
  similar and find the generated code.  Don't forget to turn off the&lt;br /&gt;
  preprocessing so the compiler will generate object code again.&lt;br /&gt;
&lt;br /&gt;
  If you want, you can go all the way down to the aggregate&lt;br /&gt;
  initializer if you want, but you shouldn't have to.  There is&lt;br /&gt;
  usually a __FULL macro that will give you all the access you need.&lt;br /&gt;
  You can avoid the auto-generated names, share functions between&lt;br /&gt;
  deciders, or whatever you want.&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  --------------&lt;br /&gt;
&lt;br /&gt;
  That's it for the high level overview.  The rest of the&lt;br /&gt;
  documentation is interspersed through the code below.  Major bits of&lt;br /&gt;
  documentation have section numbers like the above sections, but&lt;br /&gt;
  minor notes are just in regular C and C++ comments.&lt;br /&gt;
&lt;br /&gt;
  --------------&lt;br /&gt;
&lt;br /&gt;
  [1] No claim is made that HFSMs are the ultimate way to do game AI.&lt;br /&gt;
      However, they have certain nice clarity and development process&lt;br /&gt;
      advantages over other more complex simulated forms of decision&lt;br /&gt;
      making, like planning.  The idea behind this BT system is to&lt;br /&gt;
      make writing big HFSMs easy enough that you can increase the&lt;br /&gt;
      complexity of the AI code without needing to turn to a more&lt;br /&gt;
      advanced form of decision making.  Eventually I think we'll all&lt;br /&gt;
      have to switch over to more simuluation-y forms of decision&lt;br /&gt;
      making, but pushing that off as long as possible seems wise from&lt;br /&gt;
      a process standpoint.&lt;br /&gt;
  &lt;br /&gt;
  [2] There is a third kind of decider, a &amp;quot;reference decider&amp;quot;, that&lt;br /&gt;
      can cause a jump from one part of the tree to another, but it is&lt;br /&gt;
      not implemented yet because we haven't found a use case for it&lt;br /&gt;
      in Spore's AI.&lt;/div&gt;</summary>
		<author><name>Checker</name></author>
	</entry>
</feed>