Designs classical game AI as three layers: decision (FSM, behavior trees, utility, GOAP/HTN), NavMesh/A-star pathfinding with funnel smoothing, and Reynolds steering/flocking plus bounded perception. Use when building or debugging enemy/NPC agents that get stuck, jitter, or clump. Not for netcode replication, animation blending, ML/RL policy training, or dialogue trees with no movement loop.
Decision-making (what to do), pathfinding (how to get there), and steering (how to move) are three separate layers. Keep them separate and most AI bugs disappear.
Three layers, one direction: Decision → Pathfinding → Steering. Decision sets a goal; pathing finds the route; steering moves the body. Violating this one-way data flow is the single most common source of AI bugs.
When to Use
Activate when the task involves:
Choosing a decision architecture (FSM vs behavior tree vs utility AI vs GOAP/HTN) for an agent.
Implementing a behavior tree with composites, decorators, services, and a blackboard.
Pathfinding on a NavMesh or grid: A*, path smoothing (funnel), hierarchical/portal graphs, flow fields.
Replicating AI state across the network — own the behavior; let multiplayer-netcode own replication and authority.
Playing/blending the animations an AI decision triggers — that is runtime-animation (locomotion blend trees, IK). This skill outputs intent (move here, attack); the animation skill realizes it.
ML/RL training pipelines — this skill is classical, hand-authored game AI, not neural policy training.
Dialogue trees / narrative scripting with no autonomous movement or decision loop.
Prerequisites
A game engine or framework with a navigation system (NavMesh, grid, or graph) and basic vector math utilities.
Services: run on a cadence while a subtree is active (e.g. refresh "best target" every 0.5 s).
Leaves: condition checks and actions (MoveTo, Attack, PlayAnim-request).
Blackboard: shared key/value memory (target, lastKnownPos, homePos) — the only coupling between nodes.
enum Status { Success, Failure, Running }
abstract class Node { public abstract Status Tick(Blackboard bb); }
class Sequence : Node {
readonly Node[] kids; int i;
public override Status Tick(Blackboard bb) {
for (; i < kids.Length; i++) {
var s = kids[i].Tick(bb);
if (s != Status.Success) return s; // Running or Failure short-circuits
}
i = 0; return Status.Success;
}
}
class Selector : Node {
readonly Node[] kids;
public override Status Tick(Blackboard bb) {
foreach (var k in kids) {
var s = k.Tick(bb);
if (s != Status.Failure) return s; // first non-failure wins
}
return Status.Failure;
}
}
3. Implement GOAP (when action sequencing is needed)
Each action declares preconditions and effects (as world-state booleans) plus a cost. The planner runs A* over world states (not space): start = current world state, goal = desired state, neighbors = applicable actions. The resulting plan is an ordered action list the agent executes until the world changes and it replans.
A* on the NavMesh polygon graph (or grid). Heuristic = octile/Euclidean; keep it admissible.
String-pull / funnel the polygon corridor into a minimal set of waypoints — raw A* output hugs cell corners and looks robotic.
Hierarchical (portal/region graph) for large maps: plan coarse region-to-region, refine locally.
Flow fields when many agents share one goal (tower defense, RTS swarms): compute a Dijkstra field once, every agent samples the gradient.
List<Node> AStar(Node start, Node goal) {
var open = new PriorityQueue<Node, float>();
var g = new Dictionary<Node, float> { [start] = 0 };
var came = new Dictionary<Node, Node>();
open.Enqueue(start, Heuristic(start, goal));
while (open.Count > 0) {
var cur = open.Dequeue();
if (cur == goal) return Reconstruct(came, cur);
foreach (var (nbr, cost) in cur.Neighbors) {
float ng = g[cur] + cost;
if (ng < g.GetValueOrDefault(nbr, float.MaxValue)) {
g[nbr] = ng; came[nbr] = cur;
open.Enqueue(nbr, ng + Heuristic(nbr, goal)); // f = g + h
}
}
}
return null; // no path
}
5. Implement steering (Reynolds) — movement, not pathing
Steering produces a desired velocity; combine behaviors by weighted sum or priority, then clamp to max force/speed.
Drive path following by seeking the next funnel waypoint with Arrive on the last one. Avoidance (RVO/ORCA or feelers) sits on top to prevent agent–agent overlap.
6. Implement perception
Sight: target within view distance AND within FOV half-angle AND an unobstructed LoS raycast.
Hearing: stimuli (gunshots, footsteps) register as events with intensity falloff.
Memory: store lastKnownPosition + timestamp; investigate, then forget after a timeout so agents don't become omniscient.
Before tuning, add debug draws for: path lines, FOV cones, current BT node, target position, steering force vector, and perception range spheres. AI is nearly impossible to debug blind.
Examples
Engine mappings
Unreal: Behavior Trees + Blackboard (built-in), AIController, NavMesh (Recast),
EQS for environment queries (cover, flank points), Perception component.
Unity: NavMeshAgent + NavMesh baking; behavior via Behavior Designer / custom BT;
A* Pathfinding Project for grids/flow; steering hand-rolled or via add-ons.
Godot 4: NavigationAgent2D/3D + NavigationServer (funnel built in), Area-based
detection for perception, custom BT/FSM scripts.
Debugging scenarios
Input : "Agents jitter / vibrate when they reach the target."
Cause : Seek with no Arrive — they overshoot and snap back each frame.
Output: switch to Arrive (slow inside a radius), add a stop threshold, and stop
repathing once within acceptance radius.
Input : "Enemies clump into one spot and overlap."
Cause : no agent avoidance / separation.
Output: add Separation steering or RVO/ORCA; give each a slot/formation offset
around the target instead of all seeking the exact same point.
Input : "Agent oscillates between Patrol and Investigate every frame."
Cause : perception flickers on/off at the edge of detection range.
Output: add hysteresis (separate detect/lose thresholds) and a cooldown decorator
on the transition.
Pitfalls
Never couple BT nodes by direct references. The blackboard is the only shared state. Nodes that reference each other directly create spaghetti that is impossible to reorder or reuse.
Never use raw Seek at the destination. Seek has no slow-down — agents overshoot and jitter. Always use Arrive near goals with a stop threshold.
Never skip funnel smoothing. Unsmoothed A* paths hug polygon corners and look broken even when "correct."
Never repath every frame. Repath on a cadence or on significant target movement; stagger across agents (time-slicing) to avoid frame spikes.
Never give perception omniscience. FOV, range, LoS, and memory timeout make AI feel fair and fool-able. Without a memory timeout, agents never "forget" and feel psychic.
Never let all agents seek the exact same point. Without separation or formation slots, they clump and overlap. Use RVO/ORCA or slot offsets.
Never use an inadmissible A heuristic.* An overestimating heuristic produces suboptimal or broken paths. Use octile for grids, Euclidean for open NavMesh.
Never blend decision and steering layers. Decision sets a goal; pathing finds the route; steering moves the body. If steering feeds back into decision logic, you get circular dependencies and infinite oscillation.
GOAP/HTN: never execute a stale plan. Replan when the world state invalidates the current plan — otherwise agents act on outdated assumptions.
Verification
Decision, pathfinding, and steering are separate layers with one-way data flow (decision → path → steer).
The chosen decision architecture fits the agent complexity (FSM for trivial, BT/utility/GOAP for richer).
Behavior tree nodes return Success/Failure/Running and communicate only through the blackboard.
A* uses an admissible heuristic and its corridor is funnel-smoothed before following.
Large maps use hierarchical pathfinding; shared-goal swarms use flow fields.
Steering uses Arrive (not raw Seek) near goals and clamps to max force/speed.
Agent–agent avoidance (separation/RVO) prevents clumping and overlap.
Perception is bounded by range, FOV, line-of-sight, and a memory timeout.
Expensive work (repathing, perception scans) is throttled and staggered across agents.
Debug visualization exists for paths, FOV cones, current state/node, and targets.
(GOAP/HTN) Planner replans when the world state invalidates the current plan.
Related skills
runtime-animation — Realizes AI intent as locomotion blend trees, foot IK, and attack animations.
multiplayer-netcode — Replicates AI agent state/decisions and resolves authority in networked play.
performance-profiling — Time-slice perception/pathing and profile A* and steering across many agents.
custom-physics-solvers — Spatial math behind steering, avoidance, and raycast perception.
External resources
Craig Reynolds, "Steering Behaviors For Autonomous Characters".
"Game AI Pro" series (behavior trees, GOAP, utility, influence maps).
1---2name: game-ai-behavior3description: Designs classical game AI as three layers: decision (FSM, behavior trees, utility, GOAP/HTN), NavMesh/A-star pathfinding with funnel smoothing, and Reynolds steering/flocking plus bounded perception. Use when building or debugging enemy/NPC agents that get stuck, jitter, or clump. Not for netcode replication, animation blending, ML/RL policy training, or dialogue trees with no movement loop.4---56# Game AI & Behavior
78Decision-making (what to do), pathfinding (how to get there), and steering (how to move) are three separate layers. Keep them separate and most AI bugs disappear.
910**Three layers, one direction:** Decision → Pathfinding → Steering. Decision sets a goal; pathing finds the route; steering moves the body. Violating this one-way data flow is the single most common source of AI bugs.
1112## When to Use
1314Activate when the task involves:
1516- Choosing a **decision architecture** (FSM vs behavior tree vs utility AI vs GOAP/HTN) for an agent.
17- Implementing a **behavior tree** with composites, decorators, services, and a **blackboard**.
18- **Pathfinding** on a NavMesh or grid: A*, path smoothing (funnel), hierarchical/portal graphs, flow fields.
19- **Steering**: seek, flee, arrive, pursue, wander, obstacle/agent avoidance, path following, flocking.
20- **Perception**: sight cones, line-of-sight raycasts, hearing/stimulus, target memory and forgetting.
21- **Spatial reasoning**: influence maps, cover/EQS-style environment queries, tactical positioning.
22- Debugging agents that get **stuck, jitter, oscillate between states, or clump**.
2324**Trigger keywords:** enemy AI, NPC behavior, behavior tree, blackboard, decorator, state machine, utility AI, GOAP, HTN planner, NavMesh, A*, path smoothing, funnel, flow field, steering, flocking/boids, perception, sight cone, influence map, EQS.
2526### Do not use for
2728- **Replicating AI state across the network** — own the *behavior*; let `multiplayer-netcode` own replication and authority.
29- **Playing/blending the animations** an AI decision triggers — that is `runtime-animation` (locomotion blend trees, IK). This skill outputs intent (move here, attack); the animation skill realizes it.
30- **ML/RL training pipelines** — this skill is classical, hand-authored game AI, not neural policy training.
31- **Dialogue trees / narrative scripting** with no autonomous movement or decision loop.
3233## Prerequisites
3435- A game engine or framework with a navigation system (NavMesh, grid, or graph) and basic vector math utilities.
36- For Unreal: built-in Behavior Trees, Blackboard, AIController, NavMesh (Recast), EQS, Perception component.
37- For Unity: NavMeshAgent + NavMesh baking; behavior via Behavior Designer or custom BT; A* Pathfinding Project for grids/flow.
38- For Godot 4: NavigationAgent2D/3D + NavigationServer (funnel built in), Area-based detection for perception, custom BT/FSM scripts.
39- Windows host is primary (PowerShell). No external CLI tools required — this skill is architecture and code patterns, not a build pipeline.
4041## Procedure
4243### 1. Pick the decision architecture
4445| Architecture | Strength | Use when |
46|---|---|---|
47| **FSM / Hierarchical FSM** | Simple, debuggable | Few states, clear transitions (turret, simple guard) |
48| **Behavior Tree** | Modular, reusable, designer-friendly | Most action-game enemies/NPCs |
49| **Utility AI** | Smooth, emergent priority from scored options | Sims, many competing needs (The Sims-like) |
50| **GOAP** | Plans action sequences to reach a goal | Emergent, tool-using agents (F.E.A.R.-style) |
51| **HTN** | Authored task decomposition with planning | Squad tactics, structured plans |
5253**Default:** Behavior Tree + Blackboard, layered over NavMesh pathfinding and steering.
5455### 2. Implement the behavior tree core
5657Nodes return **Success / Failure / Running**. Ticking is top-down each frame; `Running` lets actions span frames.
5859- **Composites**: `Sequence` (AND — fail-fast), `Selector` (OR — succeed-fast), `Parallel`.
60- **Decorators**: invert, cooldown, condition guard, repeat, time-limit.
61- **Services**: run on a cadence while a subtree is active (e.g. refresh "best target" every 0.5 s).
62- **Leaves**: condition checks and actions (MoveTo, Attack, PlayAnim-request).
63- **Blackboard**: shared key/value memory (target, lastKnownPos, homePos) — the *only* coupling between nodes.
6465```csharp
66enum Status { Success, Failure, Running }
67abstract class Node { public abstract Status Tick(Blackboard bb); }
6869class Sequence : Node {
70 readonly Node[] kids; int i;
71 public override Status Tick(Blackboard bb) {
72 for (; i < kids.Length; i++) {
73 var s = kids[i].Tick(bb);
74 if (s != Status.Success) return s; // Running or Failure short-circuits
75 }
76 i = 0; return Status.Success;
77 }
78}
7980class Selector : Node {
81 readonly Node[] kids;
82 public override Status Tick(Blackboard bb) {
83 foreach (var k in kids) {
84 var s = k.Tick(bb);
85 if (s != Status.Failure) return s; // first non-failure wins
86 }
87 return Status.Failure;
88 }
89}
90```
9192Typical combat tree: `Selector[ Sequence(CanSeeTarget?, Attack), Sequence(HasLastKnownPos?, Investigate), Patrol ]`.
9394### 3. Implement GOAP (when action sequencing is needed)
9596Each **action** declares preconditions and effects (as world-state booleans) plus a cost. The planner runs **A\* over world states** (not space): start = current world state, goal = desired state, neighbors = applicable actions. The resulting plan is an ordered action list the agent executes until the world changes and it replans.
9798```text
99Actions: Reload {pre: hasAmmoBox; eff: weaponLoaded; cost:2}
100 AttackTarget {pre: weaponLoaded, targetVisible; eff: targetDead; cost:1}
101Goal: targetDead
102Plan: A* finds [Reload, AttackTarget] when weapon is empty.
103```
104105### 4. Implement pathfinding: A* then smooth
1061071. **A\*** on the NavMesh polygon graph (or grid). Heuristic = octile/Euclidean; keep it admissible.
1082. **String-pull / funnel** the polygon corridor into a minimal set of waypoints — raw A* output hugs cell corners and looks robotic.
1093. **Hierarchical** (portal/region graph) for large maps: plan coarse region-to-region, refine locally.
1104. **Flow fields** when *many* agents share one goal (tower defense, RTS swarms): compute a Dijkstra field once, every agent samples the gradient.
111112```csharp
113List<Node> AStar(Node start, Node goal) {
114 var open = new PriorityQueue<Node, float>();
115 var g = new Dictionary<Node, float> { [start] = 0 };
116 var came = new Dictionary<Node, Node>();
117 open.Enqueue(start, Heuristic(start, goal));
118 while (open.Count > 0) {
119 var cur = open.Dequeue();
120 if (cur == goal) return Reconstruct(came, cur);
121 foreach (var (nbr, cost) in cur.Neighbors) {
122 float ng = g[cur] + cost;
123 if (ng < g.GetValueOrDefault(nbr, float.MaxValue)) {
124 g[nbr] = ng; came[nbr] = cur;
125 open.Enqueue(nbr, ng + Heuristic(nbr, goal)); // f = g + h
126 }
127 }
128 }
129 return null; // no path
130}
131```
132133### 5. Implement steering (Reynolds) — movement, not pathing
134135Steering produces a desired velocity; combine behaviors by **weighted sum or priority**, then clamp to max force/speed.
136137```csharp
138Vector3 Seek(Vector3 pos, Vector3 target, Vector3 vel, float maxSpeed, float maxForce) {
139 Vector3 desired = (target - pos).normalized * maxSpeed;
140 return Vector3.ClampMagnitude(desired - vel, maxForce); // steering force
141}
142// Arrive: scale desired speed down inside a slowing radius to avoid overshoot.
143// Flocking = Separation (push apart) + Alignment (match heading) + Cohesion (toward center).
144// Obstacle avoidance: feeler rays; steer away from the nearest predicted collision.
145```
146147Drive **path following** by seeking the next funnel waypoint with `Arrive` on the last one. Avoidance (RVO/ORCA or feelers) sits on top to prevent agent–agent overlap.
148149### 6. Implement perception
150151- **Sight**: target within view distance AND within FOV half-angle AND an unobstructed LoS raycast.
152- **Hearing**: stimuli (gunshots, footsteps) register as events with intensity falloff.
153- **Memory**: store `lastKnownPosition` + timestamp; investigate, then forget after a timeout so agents don't become omniscient.
154155```csharp
156bool CanSee(Transform eye, Transform target, float range, float fovDeg) {
157 Vector3 to = target.position - eye.position;
158 if (to.magnitude > range) return false;
159 if (Vector3.Angle(eye.forward, to) > fovDeg * 0.5f) return false;
160 return !Physics.Raycast(eye.position, to.normalized, to.magnitude, obstacleMask);
161}
162```
163164### 7. Add debug visualization first
165166Before tuning, add debug draws for: path lines, FOV cones, current BT node, target position, steering force vector, and perception range spheres. AI is nearly impossible to debug blind.
167168## Examples
169170### Engine mappings
171172```text
173Unreal: Behavior Trees + Blackboard (built-in), AIController, NavMesh (Recast),
174 EQS for environment queries (cover, flank points), Perception component.
175Unity: NavMeshAgent + NavMesh baking; behavior via Behavior Designer / custom BT;
176 A* Pathfinding Project for grids/flow; steering hand-rolled or via add-ons.
177Godot 4: NavigationAgent2D/3D + NavigationServer (funnel built in), Area-based
178 detection for perception, custom BT/FSM scripts.
179```
180181### Debugging scenarios
182183```
184Input : "Agents jitter / vibrate when they reach the target."
185Cause : Seek with no Arrive — they overshoot and snap back each frame.
186Output: switch to Arrive (slow inside a radius), add a stop threshold, and stop
187 repathing once within acceptance radius.
188```
189190```
191Input : "Enemies clump into one spot and overlap."
192Cause : no agent avoidance / separation.
193Output: add Separation steering or RVO/ORCA; give each a slot/formation offset
194 around the target instead of all seeking the exact same point.
195```
196197```
198Input : "Agent oscillates between Patrol and Investigate every frame."
199Cause : perception flickers on/off at the edge of detection range.
200Output: add hysteresis (separate detect/lose thresholds) and a cooldown decorator
201 on the transition.
202```
203204## Pitfalls
2052061. **Never couple BT nodes by direct references.** The blackboard is the *only* shared state. Nodes that reference each other directly create spaghetti that is impossible to reorder or reuse.
2072. **Never use raw Seek at the destination.** Seek has no slow-down — agents overshoot and jitter. Always use `Arrive` near goals with a stop threshold.
2083. **Never skip funnel smoothing.** Unsmoothed A* paths hug polygon corners and look broken even when "correct."
2094. **Never repath every frame.** Repath on a cadence or on significant target movement; stagger across agents (time-slicing) to avoid frame spikes.
2105. **Never give perception omniscience.** FOV, range, LoS, and memory timeout make AI feel fair and fool-able. Without a memory timeout, agents never "forget" and feel psychic.
2116. **Never let all agents seek the exact same point.** Without separation or formation slots, they clump and overlap. Use RVO/ORCA or slot offsets.
2127. **Never use an inadmissible A* heuristic.** An overestimating heuristic produces suboptimal or broken paths. Use octile for grids, Euclidean for open NavMesh.
2138. **Never blend decision and steering layers.** Decision sets a goal; pathing finds the route; steering moves the body. If steering feeds back into decision logic, you get circular dependencies and infinite oscillation.
2149. **GOAP/HTN: never execute a stale plan.** Replan when the world state invalidates the current plan — otherwise agents act on outdated assumptions.
215216## Verification
217218- [ ] Decision, pathfinding, and steering are separate layers with one-way data flow (decision → path → steer).
219- [ ] The chosen decision architecture fits the agent complexity (FSM for trivial, BT/utility/GOAP for richer).
220- [ ] Behavior tree nodes return Success/Failure/Running and communicate only through the blackboard.
221- [ ] A* uses an admissible heuristic and its corridor is funnel-smoothed before following.
222- [ ] Large maps use hierarchical pathfinding; shared-goal swarms use flow fields.
223- [ ] Steering uses Arrive (not raw Seek) near goals and clamps to max force/speed.
224- [ ] Agent–agent avoidance (separation/RVO) prevents clumping and overlap.
225- [ ] Perception is bounded by range, FOV, line-of-sight, and a memory timeout.
226- [ ] Expensive work (repathing, perception scans) is throttled and staggered across agents.
227- [ ] Debug visualization exists for paths, FOV cones, current state/node, and targets.
228- [ ] (GOAP/HTN) Planner replans when the world state invalidates the current plan.
229230## Related skills
231232- **runtime-animation** — Realizes AI intent as locomotion blend trees, foot IK, and attack animations.
233- **multiplayer-netcode** — Replicates AI agent state/decisions and resolves authority in networked play.
234- **performance-profiling** — Time-slice perception/pathing and profile A* and steering across many agents.
235- **custom-physics-solvers** — Spatial math behind steering, avoidance, and raycast perception.
236237### External resources
238239- Craig Reynolds, "Steering Behaviors For Autonomous Characters".
240- "Game AI Pro" series (behavior trees, GOAP, utility, influence maps).
241- Recast/Detour NavMesh documentation; funnel (string-pulling) algorithm.
Run npx skillmds@latest add kayforkind/game-ai-behavior in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Designs classical game AI as three layers: decision (FSM, behavior trees, utility, GOAP/HTN), NavMesh/A-star pathfinding with funnel smoothing, and Reynolds steering/flocking plus bounded perception. Use when building or debugging enemy/NPC agents that get stuck, jitter, or clump. Not for netcode replication, animation blending, ML/RL policy training, or dialogue trees with no movement loop. It is listed under Coding & Dev Tools on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Capability flags: docs only. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
Kayforkind (@kayforkind) published this skill. Their other Agent Skills are listed on their SkillMD profile.