Guide
Game GOAP explained
Harbor Outpost's colonists were supposed to feel autonomous — chop
wood when stockpiles ran low, cook when hungry, sleep when exhausted. The
first build used a rigid
finite state machine
with 14 hard-coded transitions. Players noticed NPCs standing idle beside
full lumber yards while the cook fire went cold: the FSM could not chain
“walk to tree → chop → haul → cook” unless every
sequence was pre-authored. Switching to goal-oriented action
planning (GOAP) let each colonist search for a short action chain
that transforms the current world state into a goal state
(HasCookedMeal=true) using reusable actions with
preconditions and effects. Idle time dropped 61%, bug reports about
“dumb settlers” fell 80%, and playtesters started sharing
emergent stories the team never scripted. GOAP is a
planning paradigm: designers define symbolic facts, actions that read and
write those facts, and goals as desired fact sets; a planner (usually A*
over actions) finds a valid sequence at runtime. This guide covers world
state representation, action authoring, the planning loop, replanning
triggers, a Harbor Outpost worked example, a GOAP vs
behavior tree
decision table, pitfalls, and a production checklist.
What GOAP is (and what it is not)
Goal-oriented action planning treats NPC behavior as a search problem. The agent knows:
- Current world state — a set of symbolic facts
(key-value pairs or predicates) describing what is true right now:
At(TreePatch),HasAxe=true,Hunger=0.8. - Available actions — reusable operators, each
with preconditions (facts that must hold to start) and
effects (facts that change when the action completes):
ChopWoodrequiresAt(Tree)andHasAxe; on success it addsHasLog=trueand removesTreeChopped. - A goal state — facts the planner must achieve:
Hunger<0.2orStockpile(Wood)>=10.
The planner searches backward or forward through action space —
classically A* where edge cost is action cost (time, risk,
stamina) — until it finds a chain whose combined effects satisfy
the goal. The NPC then executes actions in order, replanning when the
world changes.
GOAP is not machine learning, pathfinding, or animation. It does not replace navmesh movement; actions call into locomotion and animation systems when they run. It is also not a silver bullet for combat reflexes — shooters still use behavior trees for frame-tight dodge-and-shoot loops. GOAP shines in simulation, survival, stealth, and RPG sandbox loops where multi-step plans create believable autonomy.
World state: symbols, not pixels
GOAP operates on symbolic state, not raw geometry. Facts should be cheap to read and stable for the duration of one plan:
- Boolean flags:
DoorOpen(Kitchen),HasWeapon. - Enumerations:
Location=Forest,Job=Idle. - Numeric thresholds:
Hunger,Energy,WoodStockpile(often bucketed to reduce branching).
Bridging perception to symbols
A perception layer (sensors, trigger volumes, inventory queries) updates facts each tick or on events. Keep this layer separate from actions: the planner assumes facts are true when preconditions match. If perception lags — the colonist thinks a tree exists but it was already chopped — execution fails and triggers replanning.
State explosion
Every new fact multiplies the search space. Production GOAP uses fact pruning: only symbols relevant to the current goal set enter the planner; distant world events stay in a blackboard the planner ignores until a goal references them. Harbor Outpost tracks 40 facts per colonist but only 12 participate in any single plan.
Authoring actions
Each action is a data record plus an execution hook:
- Name and cost —
CookMealcost 3 (seconds or abstract effort); cheaper paths win when multiple plans exist. - Preconditions — all must be true:
At(Kitchen),HasLog=true,FireLit=true. - Effects — add/delete facts on success:
add
HasCookedMeal=true, deleteHasLog=true, setHunger=0.1. - Execute() — runtime code: play animation,
consume time, call pathfinding. Return
Success,Failure, orInProgress.
Procedural vs hand-authored actions
Start with 8–15 core actions (move-to, pick-up, use-station,
eat, sleep). Avoid combinatorial actions like
CookMealAtKitchenWithAxe — compose small steps
instead. For location-specific behavior, use parameterized facts
(At(X)) and one GoTo(X) action whose
preconditions check reachability via
navmesh.
Failure handling
If Execute() returns Failure (tree despawned, path
blocked), invalidate the plan and replan from the live world state.
Do not assume the planner's predicted effects still hold.
The planning loop
A typical GOAP tick:
- Goal selection — pick the highest-priority unsatisfied goal (hunger, cold, job quota). Goals can come from utility AI scores or a simple priority queue.
- Plan — run A* (or STRIPS-style backward search) from current state toward goal facts. Cap iterations and plan depth (Harbor uses max 8 actions, 2 ms budget).
- Execute — run the first action in the queue; when it completes, pop and continue.
- Replan triggers — world facts change materially, action fails, higher-priority goal appears, or a timer expires (re-evaluate every 2–5 seconds even on success).
Performance
Planning is O(branching^depth). Mitigations: limit action set per agent archetype, cache plans keyed by state hash, stagger planner calls across frames, precompute action relevance tables. For 50+ agents, Harbor batches 10 planners per frame at 20 Hz simulation.
Worked example: Harbor Outpost hungry colonist
Initial facts: Hunger=0.85,
At(Camp), HasAxe=true,
Stockpile(Wood)=0, FireLit=false,
HasCookedMeal=false.
Goal: Hunger<0.25 (satisfied by
EatMeal which requires HasCookedMeal=true).
Planner output (cost 11):
GoTo(Forest)— cost 2ChopWood— addsHasLog=true, cost 3GoTo(Kitchen)— cost 2LightFire— requiresHasLog, setsFireLit=true, cost 1CookMeal— requires fire, setsHasCookedMeal=true, cost 2EatMeal— setsHunger=0.1, cost 1
No designer authored that exact chain. When a storm extinguishes the
fire mid-CookMeal, execution fails, facts refresh
(FireLit=false), and the planner inserts
LightFire before resuming — behavior players read as
“the colonist reacted to the weather.” That reactive
multi-step problem is awkward for pure FSMs and deep
behavior trees
without exponential branch duplication.
GOAP vs behavior trees, FSMs, and utility AI
| Approach | Best for | Trade-offs |
|---|---|---|
| GOAP | Multi-step emergent plans, sims, survival loops, RPG autonomy | Runtime planning cost; harder to debug than visual trees |
| Behavior tree | Combat NPCs, designer-ordered priorities, fast iteration | Long action chains require huge trees or duplicated subtrees |
| FSM | Player controllers, simple patrol-guard, animation states | Transition explosion when needs combine |
| Utility AI | Choosing among competing goals (flee vs fight vs heal) | Does not inherently sequence many dependent steps |
Hybrid stacks are common: utility AI picks the goal
(SatisfyHunger vs Rest), GOAP plans the
steps, behavior tree leaves execute individual actions with animation
polish. Match the tool to the problem — see
emergent gameplay design
for when procedural agent stories help retention.
Engine and middleware notes
- Custom planners — Most teams roll lightweight GOAP in C#, C++, or Rust; data lives in JSON or ScriptableObjects.
- Unity — Assets like “CrashKonijn GOAP” or bespoke STRIPS implementations; pair with navmesh agents.
- Unreal — No first-party GOAP; community plugins or plan layers above Behavior Trees.
- Godot — GDScript planners work for small agent counts; profile A* on web exports carefully.
- Server authority — In multiplayer, run planners on the server; clients play animations from replicated action IDs.
Pitfalls
- Oversized fact sets. Tracking every object in the world chokes the planner; scope facts to agent relevance.
- Monolithic actions. Combining move+chop+carry into one action removes replanning flexibility and reuse.
- Stale plans. Never replanning after world events produces NPCs cooking on unlit fires.
- Zero-cost actions. If all actions cost 1, plans ignore distance and risk; tune costs to match gameplay values.
- Missing failure edges. Actions that always return Success hide bugs; propagate Failure to the planner.
- Debugging without visualization. Log planned chains and world-state diffs; replay files are essential for sim games.
- Planning every frame. Throttle replans; execution should dominate CPU, not search.
Production checklist
- Define a minimal fact vocabulary shared across agent types.
- Author 8–20 composable actions with explicit pre/effects.
- Assign non-uniform costs reflecting time, danger, and stamina.
- Cap plan depth and planner milliseconds per agent per frame.
- Separate perception updates from planner input snapshots.
- Replan on action failure, major fact change, and periodic timer.
- Log plan strings in development builds with state hashes.
- Unit-test action preconditions and effects without the full scene.
- Profile agent count scaling before shipping open-world sim loops.
- Document hybrid boundaries (utility picks goal, GOAP plans, BT executes).
Key takeaways
- GOAP searches action sequences toward symbolic goals — emergent multi-step behavior without scripting every chain.
- Small reusable actions with clear preconditions and effects — compose complexity instead of baking it into monolithic states.
- Replanning is mandatory — the world changes; successful sims replan often and cheaply.
- Hybrid stacks win in production — utility for goal choice, GOAP for sequencing, BTs for combat polish.
- Profile planner budgets early — GOAP does not scale to hundreds of agents without caps and batching.
Related reading
- Game behavior trees explained — selectors, sequences, and when trees beat planners
- Game utility AI explained — scoring competing goals before planning steps
- Game state machines (FSM) explained — simple transitions vs multi-step search
- Emergent gameplay design explained — systems that create player stories