Files
2nd/10_Wiki/Topics/AI_and_ML/Unit Stances.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

6.9 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, 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 tech_stack
wiki-2026-0508-unit-stances Unit Stances 10_Wiki/Topics verified self
RTS Stances
Behavior Modes
none A 0.9 applied
rts
game-ai
behavior
finite-state-machine
gameplay
2026-05-10 pending
language framework
cpp RTS-AI

Unit Stances

매 한 줄

"매 unit 의 player command 부재 시 매 default reaction policy." RTS (Age of Empires, StarCraft, WARNO) 와 매 RPG party AI 에서 매 micro burden 의 reduction 을 위한 매 핵심 mechanism. 매 4 stance (aggressive · defensive · hold position · stand ground) 가 매 universal taxonomy.

매 핵심

매 4 standard stance

  • Aggressive: 매 enemy 발견 → 매 추적 + 매 attack — 매 hunt-and-kill.
  • Defensive: 매 enemy 발견 → 매 attack 하되 매 limited pursuit (e.g. tile 5칸).
  • Hold position: 매 attack 은 매 in-range 만, 매 movement X — 매 ranged unit 의 default.
  • Stand ground / Patrol: 매 movement X + 매 attack X (or 매 patrol path).

매 game 별 variant

  • AoE2: aggressive · defensive · stand ground · no attack.
  • StarCraft 2: hold position · patrol · attack-move · stop.
  • WARNO: weapon-specific (e.g. ATGM hold fire) + stance.
  • Total War: skirmish · guard · cycle charge.

매 behavior tree 와 의 관계

  • 매 stance 는 매 root selector 의 priority 의 reorder.
  • 매 aggressive: pursue → attack → idle.
  • 매 hold: attack-in-range → idle (pursue subtree 의 prune).

매 modern game AI 의 LLM 통합

  • 2026 trend: 매 NPC commander 의 매 LLM-driven stance switch — 매 battlefield context 에 매 dynamic.
  • 매 latency 제약: 매 LLM call 매 5-10초 cooldown — 매 frame-level 결정 X.

매 응용

  1. RTS micro reduction: 매 player 가 매 100 units 의 manual control X — 매 stance 로 매 default behavior.
  2. Tower defense: 매 tower 의 target priority (closest · strongest · weakest) 의 stance variant.
  3. MMO pet AI: 매 hunter pet 의 aggressive · defensive · passive.

💻 패턴

매 Stance enum + FSM (C++)

enum class Stance {
    Aggressive,
    Defensive,
    HoldPosition,
    StandGround,
};

class Unit {
    Stance stance = Stance::Defensive;
    Vec2 anchor;  // 매 hold position 의 reference point
    float pursuit_radius = 5.0f;

    void Update(float dt, const World& world) {
        Unit* enemy = FindNearestEnemy(world);
        if (!enemy) { Idle(); return; }

        switch (stance) {
            case Stance::Aggressive:
                ChaseAndAttack(enemy);
                break;
            case Stance::Defensive:
                if (Distance(pos, enemy->pos) < pursuit_radius
                    && Distance(anchor, enemy->pos) < pursuit_radius * 2)
                    ChaseAndAttack(enemy);
                else if (InAttackRange(enemy))
                    Attack(enemy);
                else
                    ReturnTo(anchor);
                break;
            case Stance::HoldPosition:
                if (InAttackRange(enemy)) Attack(enemy);
                // 매 movement X
                break;
            case Stance::StandGround:
                // 매 nothing
                break;
        }
    }
};

매 Behavior tree 의 stance gating

# py_trees 스타일
def build_unit_bt(stance: str):
    root = Selector("root")
    if stance in ("aggressive", "defensive"):
        pursue = Sequence([CanSeeEnemy(), InPursuitRange(stance), MoveToEnemy()])
        root.add_child(pursue)
    attack = Sequence([CanSeeEnemy(), InAttackRange(), Attack()])
    root.add_child(attack)
    if stance == "defensive":
        root.add_child(Sequence([NotAtAnchor(), ReturnToAnchor()]))
    root.add_child(Idle())
    return root

매 Group stance broadcast (Unity, ECS)

public struct StanceComponent : IComponentData {
    public Stance Value;
    public float3 Anchor;
}

[BurstCompile]
public partial struct ApplyStanceJob : IJobEntity {
    public void Execute(ref StanceComponent stance, in SelectedTag _) {
        stance.Value = NewStanceFromUI;
    }
}

매 LLM-driven dynamic stance (2026)

# 매 commander NPC 가 매 5초마다 매 LLM 으로 stance update
import anthropic

client = anthropic.Anthropic()

def commander_stance(battlefield_state: dict) -> dict[str, str]:
    """매 unit_id → stance mapping 의 return"""
    resp = client.messages.create(
        model="claude-opus-4-7",
        max_tokens=512,
        system="당신은 RTS commander. 매 unit 별 stance 의 결정.",
        messages=[{"role": "user", "content": f"State: {battlefield_state}\n\nJSON: {{unit_id: stance}}"}],
    )
    import json
    return json.loads(resp.content[0].text)

매 Stance cycling hotkey

void OnHotkey_CycleStance(Unit& u) {
    int next = (static_cast<int>(u.stance) + 1) % 4;
    u.stance = static_cast<Stance>(next);
    PlaySound("stance_change.ogg");
    UpdateUI(u);
}

매 Stance-aware pathfinding

def navigate(unit, target, stance):
    if stance == "hold_position":
        return None  # 매 pathfinding 의 skip
    path = a_star(unit.pos, target)
    if stance == "defensive":
        # 매 anchor 에서 매 멀어지는 step 의 prune
        path = [p for p in path if dist(p, unit.anchor) < unit.pursuit_radius * 2]
    return path

매 결정 기준

상황 Default stance
매 melee unit, frontline Aggressive
매 ranged unit (archer, sniper) Hold Position
매 worker / villager Defensive (or Flee)
매 garrison / siege Stand Ground
매 hero / mage Defensive

기본값: 매 ranged 는 매 hold, 매 melee 는 매 defensive.

🔗 Graph

🤖 LLM 활용

언제: 매 strategic-level commander NPC 의 매 stance 결정 — 매 5-10초 cadence, 매 unit 별 X 매 group 별. 언제 X: 매 frame-level 결정, 매 individual unit 의 reactive logic — 매 latency · cost 의 prohibitive.

안티패턴

  • 매 Stance 너무 많음: 매 8+ stance — 매 player 의 cognitive overload, 매 같은 effective behavior.
  • 매 Hidden stance change: 매 attack-move 후 매 stance auto-revert X — 매 player 의 confusion.
  • 매 No visual feedback: 매 stance icon · color 의 부재 — 매 current state 의 invisible.
  • 매 Pursuit radius 의 unbounded: 매 defensive 가 매 map 끝까지 chase — 매 anchor distance check 누락.

🧪 검증 / 중복

  • Verified (AoE2 manual; StarCraft 2 Battle.net wiki; Eugen Systems WARNO wiki, 2024).
  • 신뢰도 A.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — 4 stance taxonomy + LLM commander 패턴 추가