--- id: wiki-2026-0508-goal-oriented-action-planning title: Goal-Oriented Action Planning (GOAP) category: 10_Wiki/Topics status: verified canonical_id: self aliases: [GOAP, action planning, F.E.A.R AI, STRIPS, HTN, behavior tree alternative] duplicate_of: none source_trust_level: A confidence_score: 0.92 verification_status: applied tags: [game-ai, planning, goap, strips, htn, action-planning, npc] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: C# / C++ / Python applicable_to: [Game AI, Planning, NPC] --- # Goal-Oriented Action Planning (GOAP) ## 매 한 줄 > **"매 NPC 의 goal 의 의 의 action sequence 의 plan"**. F.E.A.R. (Monolith 2005) 매 famous. 매 STRIPS-derived. 매 modern alternative: 매 behavior tree, HTN, utility AI. 매 LLM 의 action plan 의 also similar. ## 매 핵심 ### 매 component - **Goal**: 매 desired world state. - **Action**: 매 (precondition, effect, cost). - **Planner**: 매 A* search 의 의 의 actions. - **WorldState**: 매 current facts. ### 매 vs alternatives - **FSM**: 매 hardcoded transitions. - **Behavior Tree**: 매 reactive, designer-friendly. - **GOAP**: 매 emergent, dynamic plan. - **HTN**: 매 hierarchical task decompose. - **Utility AI**: 매 score actions. ### 매 응용 1. **Game AI** (FPS, RTS). 2. **Robotics planning**. 3. **NPC complex behavior**. 4. **Strategy game**. 5. **LLM agent (similar pattern)**. ## 💻 패턴 ### Action definition ```python @dataclass class Action: name: str cost: float preconditions: dict # 매 state requirements effects: dict # 매 state changes def can_run(self, world_state): return all(world_state.get(k) == v for k, v in self.preconditions.items()) def apply(self, world_state): new = world_state.copy() new.update(self.effects) return new ``` ### Goal definition ```python @dataclass class Goal: name: str desired_state: dict priority: float def is_satisfied(self, world_state): return all(world_state.get(k) == v for k, v in self.desired_state.items()) ``` ### A* planner ```python import heapq def goap_plan(world_state, goal, actions): queue = [(0, world_state, [])] visited = set() while queue: cost, state, path = heapq.heappop(queue) state_key = frozenset(state.items()) if state_key in visited: continue visited.add(state_key) if goal.is_satisfied(state): return path for action in actions: if action.can_run(state): new_state = action.apply(state) heuristic = compute_heuristic(new_state, goal) heapq.heappush(queue, (cost + action.cost + heuristic, new_state, path + [action])) return None # 매 no plan ``` ### Heuristic (number of unsatisfied goal facts) ```python def compute_heuristic(state, goal): return sum(1 for k, v in goal.desired_state.items() if state.get(k) != v) ``` ### Example: combat AI ```python ACTIONS = [ Action('reload', cost=1, preconditions={'has_weapon': True, 'has_ammo': True}, effects={'weapon_loaded': True}), Action('grab_ammo', cost=2, preconditions={'near_ammo': True}, effects={'has_ammo': True}), Action('fire', cost=1, preconditions={'weapon_loaded': True, 'enemy_visible': True}, effects={'enemy_dead': True, 'weapon_loaded': False}), Action('take_cover', cost=3, preconditions={'cover_available': True}, effects={'in_cover': True}), ] GOAL_KILL = Goal('kill_enemy', {'enemy_dead': True}, priority=1.0) world = {'has_weapon': True, 'has_ammo': False, 'near_ammo': True, 'enemy_visible': True, 'cover_available': True} plan = goap_plan(world, GOAL_KILL, ACTIONS) # 매 → [grab_ammo, reload, fire] ``` ### Reactive replanning ```python class GOAPAgent: def __init__(self, actions): self.actions = actions self.current_plan = [] self.current_goal = None def update(self, world_state): # 매 select goal goals = self.evaluate_goals(world_state) new_goal = max(goals, key=lambda g: g.priority) # 매 replan if goal changed or plan invalid if new_goal != self.current_goal or not self.plan_valid(world_state): self.current_plan = goap_plan(world_state, new_goal, self.actions) self.current_goal = new_goal if self.current_plan: return self.current_plan.pop(0) return None ``` ### Cost dynamic adjustment ```python def dynamic_cost(action, world_state): base = action.cost if action.name == 'fire' and world_state['low_ammo']: return base * 3 if action.name == 'take_cover' and world_state['health'] < 30: return base * 0.3 return base ``` ### HTN (Hierarchical Task Network) ```python class Task: def __init__(self, name, methods): self.name = name; self.methods = methods # 매 list of decomposition class Method: def __init__(self, preconditions, subtasks): self.preconditions = preconditions; self.subtasks = subtasks # 매 decompose top task → primitive actions ``` ### Behavior Tree (alternative) ```python class Selector: def tick(self): for child in self.children: if child.tick() == 'success': return 'success' return 'fail' class Sequence: def tick(self): for child in self.children: if child.tick() != 'success': return 'fail' return 'success' # 매 attack tree attack = Sequence([HasAmmo(), HasWeapon(), Selector([Fire(), Reload()])]) ``` ### Utility AI (alternative) ```python def utility_decide(actions, world_state): scores = [] for action in actions: if not action.can_run(world_state): continue score = sum(consider.score(world_state) for consider in action.considerations) scores.append((action, score)) return max(scores, key=lambda x: x[1])[0] ``` ### LLM agent (similar pattern) ```python def llm_plan(goal, world_state, available_tools, llm): prompt = f"""You are a planner. Goal: {goal} Current state: {world_state} Tools: {available_tools} Output a plan (JSON list of tool invocations) to achieve the goal.""" return json.loads(llm.generate(prompt)) ``` ### Plan visualization ```python def visualize_plan(plan, world_state): state = world_state.copy() for i, action in enumerate(plan): print(f'{i+1}. {action.name} (cost {action.cost})') state = action.apply(state) print(f'Final state: {state}') ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Complex emergent NPC | GOAP | | Designer-driven | Behavior Tree | | Hierarchical task | HTN | | Score-based | Utility AI | | Modern flexible | LLM agent | | Simple | FSM | **기본값**: 매 GOAP for emergent + 매 BT for reactive + 매 HTN for hierarchical + 매 LLM for flexible/data-rich. ## 🔗 Graph - 부모: [[Planning]] - 변형: [[Behavior-Tree]] · [[HTN]] - 응용: [[F.E.A.R-AI]] - Adjacent: [[STRIPS]] · [[Drama Management Systems]] · [[Foundation-Models]] ## 🤖 LLM 활용 **언제**: 매 game NPC. 매 robot planning. **언제 X**: 매 simple linear behavior. ## ❌ 안티패턴 - **Plan once + execute blind**: 매 dynamic world fail. - **Action explosion**: 매 search slow. - **No replanning**: 매 stale. - **GOAP for trivial NPC**: 매 over-engineer. ## 🧪 검증 / 중복 - Verified (F.E.A.R AI postmortem, Orkin, GOAP literature). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-04-20 | Auto | | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — GOAP + 매 A* / BT / HTN / utility / LLM agent code |