docs(10_Wiki): 위키 전체 재구성 — Topic_* 폴더를 4개 카테고리로 통합 + 대규모 중복 제거
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를 Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류. - 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로 자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거, 동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거. - 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming, Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business, Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로, 나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는 title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백). 원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지. - 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서. - 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는 지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지. - Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경. - 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
---
|
||||
id: wiki-2026-0508-전투-전술-battle-strategies
|
||||
title: 전투 전술(Battle Strategies)
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Battle Strategies, 전투 전술, Combat Tactics]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [game-design, rts, tactics, combat]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: typescript
|
||||
framework: ECS/BehaviorTree
|
||||
---
|
||||
|
||||
# 전투 전술 (Battle Strategies)
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 전투 전술은 unit composition × terrain × tempo 의 곱"**. RTS/wargame design 의 핵심 axis 로, Sun Tzu 의 고전 doctrine 에서 출발해 modern wargame (WARNO, Steel Division 2, Broken Arrow) 에서는 fog-of-war + recon priority + combined-arms 로 진화. AI opponent 는 utility-based scoring 과 behavior tree 로 구현.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 4대 축
|
||||
- **Composition**: unit roster 의 다양성 — infantry / armor / artillery / recon / support
|
||||
- **Terrain**: cover, elevation, choke point — line-of-sight 와 movement cost 의 변형
|
||||
- **Tempo**: 매 OODA loop — observe → orient → decide → act, 반복 주기
|
||||
- **Information**: fog-of-war, recon, EW (electronic warfare) — 정보 비대칭 활용
|
||||
|
||||
### 매 doctrine 분류
|
||||
- **Attrition**: 매 firepower 압박 — losses 를 강제, 적 reinforcement curve 를 break
|
||||
- **Maneuver**: 매 flanking + encirclement — Schwerpunkt (focal point) 에 mass 집중
|
||||
- **Defensive-elastic**: 매 layered defense — kill zone 유도 후 counter-attack
|
||||
- **Asymmetric**: 매 guerilla / hit-and-run — engagement 거부, 공급망 공격
|
||||
|
||||
### 매 응용
|
||||
1. RTS AI controller — utility scoring 으로 매 frame 행동 선택.
|
||||
2. Wargame mission design — objective gating 으로 player 가 doctrine 학습.
|
||||
3. Auto-battler balance — 상성 표 + composition entropy 측정.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Utility-based unit AI
|
||||
```typescript
|
||||
type UnitState = { hp: number; ammo: number; pos: Vec2; supply: number }
|
||||
type Action = "attack" | "retreat" | "hold" | "flank"
|
||||
|
||||
function score(s: UnitState, a: Action, ctx: BattleCtx): number {
|
||||
switch (a) {
|
||||
case "attack": return s.ammo * 0.4 + ctx.enemyExposed * 0.6 - s.hpDeficit * 0.5
|
||||
case "retreat": return s.hpDeficit * 0.8 - ctx.allyNearby * 0.3
|
||||
case "hold": return ctx.cover * 0.7 + ctx.objectiveDist * -0.2
|
||||
case "flank": return ctx.enemyFlankExposed * 0.9 - s.supply * 0.4
|
||||
}
|
||||
}
|
||||
|
||||
function pickAction(s: UnitState, ctx: BattleCtx): Action {
|
||||
const actions: Action[] = ["attack", "retreat", "hold", "flank"]
|
||||
return actions.reduce((best, a) =>
|
||||
score(s, a, ctx) > score(s, best, ctx) ? a : best
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Threat assessment grid
|
||||
```typescript
|
||||
function buildThreatMap(units: Unit[], grid: Grid): Float32Array {
|
||||
const map = new Float32Array(grid.w * grid.h)
|
||||
for (const u of units) {
|
||||
if (u.team !== "enemy") continue
|
||||
const range = u.weaponRange
|
||||
for (let dy = -range; dy <= range; dy++) {
|
||||
for (let dx = -range; dx <= range; dx++) {
|
||||
const x = u.pos.x + dx, y = u.pos.y + dy
|
||||
if (!grid.inBounds(x, y)) continue
|
||||
const dist = Math.hypot(dx, dy)
|
||||
if (dist > range) continue
|
||||
map[y * grid.w + x] += u.firepower * (1 - dist / range)
|
||||
}
|
||||
}
|
||||
}
|
||||
return map
|
||||
}
|
||||
```
|
||||
|
||||
### Schwerpunkt detection
|
||||
```typescript
|
||||
function findSchwerpunkt(allies: Unit[], threatMap: Float32Array, grid: Grid): Vec2 {
|
||||
let bestScore = -Infinity, bestPos = allies[0].pos
|
||||
for (const u of allies) {
|
||||
const idx = u.pos.y * grid.w + u.pos.x
|
||||
const massNearby = allies.filter(a => Vec2.dist(a.pos, u.pos) < 200).length
|
||||
const threatGap = 1 / (threatMap[idx] + 0.1)
|
||||
const score = massNearby * threatGap
|
||||
if (score > bestScore) { bestScore = score; bestPos = u.pos }
|
||||
}
|
||||
return bestPos
|
||||
}
|
||||
```
|
||||
|
||||
### Tempo controller (OODA)
|
||||
```typescript
|
||||
class TempoController {
|
||||
private lastDecisionAt = 0
|
||||
private cycleMs = 800
|
||||
|
||||
tick(now: number, ctx: BattleCtx) {
|
||||
if (now - this.lastDecisionAt < this.cycleMs) return
|
||||
const obs = this.observe(ctx)
|
||||
const orient = this.orient(obs)
|
||||
const decision = this.decide(orient)
|
||||
this.act(decision)
|
||||
this.lastDecisionAt = now
|
||||
this.cycleMs = Math.max(300, 800 - ctx.pressureLevel * 100)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Recon priority queue
|
||||
```typescript
|
||||
function reconTargets(unknown: Cell[], objectives: Vec2[]): Cell[] {
|
||||
return unknown
|
||||
.map(c => ({
|
||||
cell: c,
|
||||
score: objectives.reduce((s, o) => s + 1 / (Vec2.dist(c.pos, o) + 1), 0),
|
||||
}))
|
||||
.sort((a, b) => b.score - a.score)
|
||||
.slice(0, 5)
|
||||
.map(x => x.cell)
|
||||
}
|
||||
```
|
||||
|
||||
### Combined-arms morale boost
|
||||
```typescript
|
||||
function moraleBonus(unit: Unit, allies: Unit[]): number {
|
||||
const nearby = allies.filter(a => Vec2.dist(a.pos, unit.pos) < 150)
|
||||
const types = new Set(nearby.map(a => a.type))
|
||||
return types.size >= 3 ? 0.25 : types.size >= 2 ? 0.1 : 0
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Numeric superiority + open terrain | Attrition + frontal mass |
|
||||
| Mobile force vs static defense | Maneuver, flank Schwerpunkt |
|
||||
| Outnumbered, defensive | Elastic defense + kill zones |
|
||||
| Unknown enemy composition | Recon-heavy, delay engagement |
|
||||
| Long campaign, supply-limited | Asymmetric, denial |
|
||||
|
||||
**기본값**: combined-arms balanced doctrine + recon-first opening.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[제병협동 (Combined Arms)]] · [[Game_Design]]
|
||||
- 변형: [[유닛 상성(Unit Counters)]] · [[제로잉 (Getting Zero-ed)]]
|
||||
- 응용: [[Eugen Systems 모딩 매뉴얼|WARNO]] · [[Eugen Systems 모딩 매뉴얼|Eugen_Systems]] · [[4X_전략]]
|
||||
- Adjacent: [[AI 추적 논리(AI Pursuit Logic)]] · [[Combat_Timeline_Difficulty_Scaling]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: tactical AI scripting, mission designer 의 pacing 검증, opening-book 생성.
|
||||
**언제 X**: 매 frame-tight pathfinding 의 inner loop — LLM latency 가 너무 큼, behavior tree 에 위임.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Single-unit doctrine**: 단일 병종 spam — counter unit 1 종류로 전체 collapse.
|
||||
- **Static formation**: tempo 무시 — 매 적의 OODA 가 빨라 reactive 가 됨.
|
||||
- **Recon skip**: 매 fog-of-war 무시 → blind commit, ambush 함정.
|
||||
- **Schwerpunkt 부재**: 매 force dispersion → 어디서도 decisive mass 못 만듦.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Eugen Systems WARNO design docs, US FM 3-0 Operations).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — battle tactics doctrine + AI scoring patterns |
|
||||
Reference in New Issue
Block a user