Files
2nd/10_Wiki/Topics/AI_and_ML/AI 추적 논리(AI Pursuit Logic).md
T
koriweb d8a80f6272 chore(wiki): dangling 링크 canonical 정규화 (768파일/1200건)
이름만 다른(표기 변형) [[위키링크]]를 대상 문서의 canonical 제목으로 치환해
끊겼던 1,200개 링크를 연결. 제목/파일명 정규화 일치만 적용하고 별칭 매칭은
과병합 위험으로 제외(애매성 가드). 원본은 _link_reconcile_backup/ 에 백업.
도구: Datacollect/scripts/link_reconcile_apply.mjs

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 12:24:15 +09:00

14 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, inferred_by, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit inferred_by tech_stack
wiki-2026-0508-ai-추적-논리-ai-pursuit-logic AI Pursuit Logic (AI 추적 논리) 10_Wiki/Topics verified self
AI 추적
pursuit logic
aggro
threat detection
leash range
NPC chase
none B 0.85 conceptual
game-ai
pursuit
aggro
threat-system
npc-design
baiting
leash
fsm
behavior-tree
2026-05-09 pending Claude Opus 4.7 (manual cleanup 2026-05-09)
language applicable_to
game design / Unity / Unreal
Game Design
Combat AI
RTS
MMO
FPS

AI Pursuit Logic (AI 추적 논리)

📌 한 줄 통찰 (The Karpathy Summary)

"매 enemy 의 어떤 target 의 chase?". Aggro / threat / line-of-sight / leash 의 4 component. 매 RTS / MMO / FPS 의 fundamental. 매 deterministic = baiting exploitable, 매 random = unpredictable feel.

📖 구조화된 지식 (Synthesized Content)

매 component

  1. Detection: 매 enemy 의 sight cone / sound / threat radius.
  2. Threat / aggro: 매 player 의 weight (proximity, damage dealt, special).
  3. Pursuit decision: 매 stance / state 의 chase / hold.
  4. Leash: 매 chase 의 max distance.
  5. De-aggro: 매 reset condition.

매 stance / state

Active pursuit (Fire at Will / Aggressive)

  • 매 enemy detect → chase to engage.
  • 매 wide pursuit radius.
  • Vulnerable to baiting.

Defensive (Hold Position / Stand Ground)

  • 매 stay in spot.
  • 매 in-range only engage.
  • Bait 의 immune.

Patrol

  • 매 fixed route.
  • 매 detect → pursue 일정 time → return.
  • 매 player 의 timing exploit.

Guarding

  • 매 specific target / area.
  • 매 leash 의 strict.
  • 매 player 의 line-of-sight break 의 reset.

Conditional (low HP, ally death)

  • 매 trigger 의 stance change.
  • Berserk / flee.

Aggro / threat system

Proximity-based (simple)

  • 매 distance 의 inverse 의 weight.
  • 매 closest = highest priority.

Damage-based

  • 매 damage dealt 의 cumulative.
  • 매 healer / DPS 의 high priority.
  • MMO 의 tank role 의 enable.

Stealth / detection

  • 매 sight cone (FPS, stealth game).
  • 매 noise level.
  • 매 disguise / blend.

Special abilities

  • 매 taunt / provoke 의 instant aggro.
  • 매 invisibility / cloak 의 break aggro.
  • 매 mind control.

Leash mechanism

  • 매 chase 의 max range.
  • 매 exceed = full reset (heal, return).
  • 매 cheese 의 prevent (kite + reset attack).
Chase distance > maxLeash:
  - Stop pursuit.
  - Reset HP to full.
  - Return to spawn.
  - 매 player 의 punish.

Wild goose chase 의 exploit

  1. Player unit (fast / cheap) 의 enemy 의 lure.
  2. Enemy 의 pursue.
  3. Player 의 ambush location.
  4. Enemy 의 trap.

→ 매 RTS / MMO 의 universal tactic.

Modern variants

Adaptive aggro

  • 매 player behavior 의 learn.
  • 매 cheese pattern 의 detect.
  • 매 counter-strategy.

Squad coordination

  • 매 enemy 의 group communicate.
  • 매 player 의 line-of-sight 의 share.
  • 매 flanking maneuver.

Memory / persistence

  • 매 enemy 의 last known player position.
  • 매 search 의 specific area.
  • 매 continued investigation.

Investigation state (stealth)

  • 매 noise → suspicious → investigate → return / aggro.
  • 매 partial detection 의 layered.

Game examples

Classic RTS (StarCraft, AoE, Warcraft)

  • A-move = active pursuit.
  • Stop / Hold = anchor.
  • 매 leash range.

MMO (WoW, FFXIV)

  • 매 mob 의 leash range (tunable).
  • 매 tank 의 threat.
  • 매 reset 의 full heal (anti-cheese).

Stealth (Splinter Cell, MGS)

  • 매 detection meter.
  • 매 sound radius.
  • 매 alert state cycle.

FPS (Halo, Doom)

  • 매 enemy 의 cover seeking.
  • 매 line-of-sight break 의 search.
  • 매 grenade 의 flush.

Player exploit pattern

1. Bait + lure

  • 매 cheap unit 의 sacrifice.
  • 매 enemy 의 chase.
  • 매 ambush.

2. Kiting

  • 매 ranged 의 attack + retreat.
  • 매 enemy 의 perpetual pursue.
  • 매 attrition kill.

3. Line-of-sight break

  • 매 wall 의 hide.
  • 매 enemy 의 lose vision.
  • 매 reset / stealth.

4. Leash exploit

  • 매 enemy 의 leash 끝.
  • 매 attack 후 retreat.
  • 매 enemy 의 reset (full heal — but separated).

→ 매 MMO 의 banned (exploit) 또는 intended (skill).

5. Aggro management

  • 매 player 의 selective threat.
  • 매 boss 의 specific target.
  • 매 strategic positioning.

💻 코드 패턴 (Code Patterns)

Threat / aggro table

public class ThreatTable {
    Dictionary<Player, float> threats = new();
    
    public void AddThreat(Player p, float amount) {
        threats[p] = threats.GetValueOrDefault(p, 0) + amount;
    }
    
    public Player GetTopThreat() {
        if (threats.Count == 0) return null;
        return threats.OrderByDescending(x => x.Value).First().Key;
    }
    
    public void Decay(float deltaTime) {
        foreach (var key in threats.Keys.ToList()) {
            threats[key] *= Mathf.Pow(0.9f, deltaTime);   // 10s half-life
        }
    }
    
    public void OnPlayerDeath(Player p) { threats.Remove(p); }
}

Pursuit FSM

public enum AIState { Idle, Patrol, Suspicious, Pursuing, Engaging, Returning }

public class EnemyAI : MonoBehaviour {
    public AIState state = AIState.Idle;
    public Vector3 spawnPoint;
    public float leashRange = 30f;
    public float sightRange = 15f;
    public Transform target;
    
    void Update() {
        switch (state) {
            case AIState.Idle:
                if (DetectPlayer()) state = AIState.Pursuing;
                break;
            
            case AIState.Pursuing:
                if (Vector3.Distance(transform.position, spawnPoint) > leashRange) {
                    state = AIState.Returning;
                    target = null;
                } else if (InAttackRange()) {
                    state = AIState.Engaging;
                } else {
                    MoveToward(target.position);
                }
                break;
            
            case AIState.Engaging:
                Attack(target);
                if (!InAttackRange()) state = AIState.Pursuing;
                break;
            
            case AIState.Returning:
                if (ReachedSpawn()) {
                    HealFully();   // anti-cheese
                    state = AIState.Idle;
                }
                MoveToward(spawnPoint);
                break;
        }
    }
    
    bool DetectPlayer() {
        Player p = FindNearestPlayer();
        if (p == null) return false;
        if (Vector3.Distance(transform.position, p.transform.position) > sightRange) return false;
        if (!HasLineOfSight(p)) return false;
        target = p.transform;
        return true;
    }
}

Stance-based pursuit (RTS)

public enum Stance { Passive, Defensive, Aggressive, Hold }

public class RTSUnit : MonoBehaviour {
    public Stance stance = Stance.Defensive;
    public float pursuitRadius = 10f;
    
    void Update() {
        switch (stance) {
            case Stance.Passive:
                // Don't engage. Move only on player command.
                break;
            
            case Stance.Defensive:
                // Engage in attack range only.
                Enemy nearby = FindEnemyInRange(attackRange);
                if (nearby != null) Attack(nearby);
                break;
            
            case Stance.Aggressive:
                // Pursue any enemy in radius.
                Enemy enemy = FindEnemyInRange(pursuitRadius);
                if (enemy != null) {
                    if (InAttackRange(enemy)) Attack(enemy);
                    else MoveToward(enemy.transform.position);
                }
                break;
            
            case Stance.Hold:
                // Like Defensive but no movement.
                Enemy inRange = FindEnemyInRange(attackRange);
                if (inRange != null) Attack(inRange);   // No move.
                break;
        }
    }
}

Sight cone (stealth)

public class SightCone : MonoBehaviour {
    public float sightRange = 15f;
    public float sightAngle = 90f;
    public LayerMask obstacleLayer;
    
    public bool CanSee(Transform target) {
        Vector3 dir = (target.position - transform.position).normalized;
        float dist = Vector3.Distance(transform.position, target.position);
        
        if (dist > sightRange) return false;
        if (Vector3.Angle(transform.forward, dir) > sightAngle / 2) return false;
        
        // Line-of-sight check
        if (Physics.Raycast(transform.position, dir, dist, obstacleLayer)) return false;
        
        return true;
    }
}

De-aggro / reset

public class DeAggro : MonoBehaviour {
    public float losTimeout = 5f;   // 5s 의 line-of-sight break = reset
    float lastSeenTime;
    
    void Update() {
        if (sight.CanSee(target)) {
            lastSeenTime = Time.time;
        } else if (Time.time - lastSeenTime > losTimeout) {
            ResetAggro();
        }
    }
    
    void ResetAggro() {
        threatTable.Clear();
        target = null;
        state = AIState.Returning;
    }
}

Squad coordination

public class Squad : MonoBehaviour {
    List<EnemyAI> members = new();
    Player sharedTarget;
    
    public void OnDetect(Player p) {
        if (sharedTarget == null) {
            sharedTarget = p;
            // Alert all members
            foreach (var m in members) {
                m.target = p.transform;
                m.state = AIState.Pursuing;
            }
        }
    }
    
    public void Coordinate() {
        // 매 member 의 different angle 의 attack.
        for (int i = 0; i < members.Count; i++) {
            float angle = (Mathf.PI * 2 * i) / members.Count;
            Vector3 offset = new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * 5;
            members[i].SetMoveTarget(sharedTarget.transform.position + offset);
        }
    }
}

Memory / investigation (stealth)

public class GuardAI : MonoBehaviour {
    public AIState state = AIState.Patrol;
    Vector3 lastSeenPosition;
    float investigateTime = 10f;
    
    void Update() {
        if (state == AIState.Patrol) {
            if (DetectPlayer()) {
                state = AIState.Pursuing;
                lastSeenPosition = target.position;
            }
        } else if (state == AIState.Pursuing) {
            if (CanSeePlayer()) {
                lastSeenPosition = target.position;
            } else {
                state = AIState.Investigating;
            }
        } else if (state == AIState.Investigating) {
            MoveToward(lastSeenPosition);
            
            if (ReachedDestination()) {
                if (CanSeePlayer()) {
                    state = AIState.Pursuing;
                } else if (timeInState > investigateTime) {
                    state = AIState.Patrol;   // Give up.
                }
            }
        }
    }
}

Anti-cheese (RTS leash + heal)

public class AntiCheese : MonoBehaviour {
    public float maxLeash = 30f;
    Vector3 spawnPoint;
    
    void Update() {
        if (Vector3.Distance(transform.position, spawnPoint) > maxLeash) {
            // 매 player 의 kite + reset attack 의 punish.
            ResetAggro();
            FullHeal();
            ReturnHome();
        }
    }
}

🤔 의사결정 기준 (Decision Criteria)

상황 추천 pursuit logic
RTS unit Stance-based (player choice)
MMO mob Threat table + leash
FPS enemy Sight cone + cover seeking
Stealth game Sight + sound + investigation state
Boss fight Phased + threat + special mechanic
Roguelike Simple proximity + variety

기본값: Threat table + leash + LOS-based reset. Anti-cheese.

⚠️ 모순 및 업데이트 (Contradictions & Updates)

  • Predictable vs unfair: 매 deterministic 의 baiting exploit, 매 random 의 frustrating.
  • Aggro 의 transparency: MMO 의 tank role 의 explicit threat. 매 player 의 strategic.
  • Leash 의 anti-cheese vs immersion: 매 reset 의 unrealistic feel.
  • AI 의 squad coordination 의 cost: 매 sophisticated 의 dev expensive.

🔗 지식 연결 (Graph)

🤖 LLM 활용 힌트 (How to Use This Knowledge)

언제 이 지식을 쓰는가:

  • 매 game 의 enemy AI design.
  • 매 stance / threat system 의 implement.
  • 매 stealth game 의 detection.
  • 매 boss fight 의 mechanic.
  • 매 player exploit 의 review.

언제 쓰면 안 되는가:

  • Single-player turn-based (different paradigm).
  • Walking simulator.
  • 매 LLM agent (different domain — partial overlap).

안티패턴 (Anti-Patterns)

  • No leash + open world: 매 cheese 의 enable.
  • Pure proximity threat: 매 healer / DPS 의 unfair.
  • No LOS reset: 매 wall 의 follow 의 unrealistic.
  • No memory: 매 player 의 hide 후 의 instant forget.
  • No squad coordination: 매 1 vs 1 의 weak.
  • Fully deterministic: 매 첫 try 후 trivialize.
  • Excessive randomness: 매 player 의 frustrating.

🧪 검증 상태 (Validation)

  • 정보 상태: verified (concept-level).
  • 출처 신뢰도: B (Game AI Programming Wisdom series, Unity / Unreal documentation, GDC talks).
  • 검토 이유: Manual cleanup. 매 specific game 의 implementation 가 design choice.

🧬 중복 검사 (Duplicate Check)

🕓 변경 이력 (Changelog)

날짜 변경 내용 처리 방식 신뢰도
2026-05-08 P-Reinforce Phase 1 정규화 UPDATE A
2026-05-09 Manual cleanup — Unity code + 4 component + 매 game example + 안티패턴 추가 UPDATE B