Beyond states and trees, agents choose actions with decision trees, utility scoring, and goal-oriented planning. Learn approaches for AI that weighs options and reacts intelligently to the situation.
A decision tree chooses an action by walking a tree of yes/no questions from the root to a leaf — "is an enemy visible? if yes, is it close? if yes, attack." It is simple, fast, and transparent, easy for designers to author and debug. Decision trees suit reactive AI with clear rules, and they resolve in a single pass unlike a behavior tree with running actions.
def decide(agent):
# walk yes/no questions from the root to an action leaf
if agent.can_see_enemy():
if agent.distance_to_enemy() < 2:
return "attack"
elif agent.health < 30:
return "flee"
else:
return "chase"
elif agent.hears_noise():
return "investigate"
else:
return "patrol"
# fast, transparent, easy to author/debug. Best for REACTIVE AI with clear
# rules. (A behavior tree adds RUNNING/composition; a decision tree just picks.)Rule-based approaches struggle when many factors matter at once. Utility AI scores each possible action with a number computed from the current situation — how hungry, how threatened, how close the target — and picks the highest. This produces nuanced, context-sensitive choices and degrades gracefully as you add considerations, which is why it powers the AI in simulation-heavy games (The Sims, strategy titles).
def choose_action(agent):
actions = {
"attack": score_attack(agent),
"heal": score_heal(agent),
"flee": score_flee(agent),
"reload": score_reload(agent),
}
return max(actions, key=actions.get) # pick the highest-utility action
def score_heal(agent):
# more urgent as health drops; useless if no healing available
if agent.potions == 0: return 0.0
return (1.0 - agent.health / 100) ** 2 # curve emphasizes low health
def score_attack(agent):
if not agent.can_see_enemy(): return 0.0
return agent.weapon_ready * (1.0 - agent.distance_to_enemy() / agent.range)
# each action scores itself from the situation; the agent picks the max.
# scales gracefully to many considerations -> nuanced, context-aware behavior.GOAP flips scripting on its head: instead of authoring behavior, you give the agent a goal and a set of actions with preconditions and effects, and it plans a sequence to reach the goal (a search, often A* over world states). If the world changes, it re-plans. GOAP produces adaptive, emergent behavior — famously in F.E.A.R.’s enemies — at the cost of more setup and less predictability.
Goal-Oriented Action Planning (GOAP): don't script behavior — PLAN it.
Give the agent:
a GOAL e.g. "player is dead"
ACTIONS, each with preconditions + effects:
attack: needs (weapon loaded, in range) -> player takes damage
reload: needs (has ammo) -> weapon loaded
moveTo: needs (path exists) -> in range
The planner SEARCHES (usually A* over world states) for a sequence of actions
from the current state to the goal: moveTo -> reload -> attack.
If the world changes, it RE-PLANS.
Emergent, adaptive AI (F.E.A.R. made it famous). Cost: more setup, harder to
predict/debug than a decision or behavior tree.Match the technique to the AI’s complexity and how much authored control you want. Decision trees and FSMs suit simple, predictable reactive AI; behavior trees scale to complex authored behavior; utility AI handles many competing factors; GOAP gives adaptive planning at the cost of predictability. Most real games mix them — an FSM for high-level modes with behavior trees or utility inside states.
Pick by complexity + how much authored control you want:
FSM / decision tree simple, predictable, easy to author/debug (most enemies)
behavior tree complex AUTHORED behavior, composable + scalable (action games)
utility AI many competing factors, context-sensitive (sims, strategy)
GOAP adaptive PLANNING toward goals; emergent but less predictable
Real games MIX them:
FSM for top-level modes (Combat / Patrol / Flee)
+ behavior trees or utility scoring INSIDE each mode.
Start simple; add sophistication only where the behavior demands it.