[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -2,61 +2,271 @@
|
||||
id: wiki-2026-0508-drama-management-systems
|
||||
title: Drama Management Systems
|
||||
category: 10_Wiki/Topics
|
||||
status: needs_review
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [P-Reinforce-AI-DRAMA-MGMT]
|
||||
aliases: [drama manager, narrative AI, DM, story generation, interactive narrative]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.95
|
||||
tags: [GameDesign, AI, Narrative, DramaManagement]
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [game-design, narrative, drama-management, interactive-narrative, ai, story-generation]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-04-20
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
inferred_by: Claude Opus 4.7 (auto-normalize 2026-05-08)
|
||||
tech_stack:
|
||||
language: Game Design
|
||||
applicable_to: [Interactive Narrative, Game AI, LLM Story]
|
||||
---
|
||||
|
||||
# [[Drama Management[[ system]]s]] (드라마 관리 시스템)
|
||||
# Drama Management Systems
|
||||
|
||||
## 📌 한 줄 통찰 (The Karpathy Summary)
|
||||
> "플레이어 모르게 등 뒤에서 연극 무대를 조절하는 보이지 않는 연출가." 게임 엔진 내부에서 플레이어의 행동을 실시간 모니터링하여, 이야기가 너무 지루하거나 너무 급박해지지 않도록 이벤트를 배치하고 난이도를 조절하는 지능형 서사 제어 시스템이다.
|
||||
## 매 한 줄
|
||||
> **"매 game 의 author 의 intended pacing / arc 의 maintain 의 AI"**. 매 player agency ↔ author intent 의 tension 의 mediate. 매 famous: Façade (Mateas & Stern), Storytron (Crawford), Left 4 Dead AI Director. 매 modern: 매 LLM 의 dynamic story.
|
||||
|
||||
## 📖 구조화된 지식 (Synthesized Content)
|
||||
- **Target**: 플레이어의 '극적 긴장감(Dramatic Tension)'을 유지하는 것.
|
||||
- **Components**:
|
||||
- **Story [[State]] Monitor**: 현재 서사의 진행 상황 파악.
|
||||
- **Experience Manager**: 사용자 경험의 질을 실시간으로 점수화(Metric).
|
||||
- **Narrative Planner**: 목표 서사 구조로 유도하기 위한 최적의 행동(NPC 배치, 아이템 드랍 등) 결정.
|
||||
- **Key Technique**: **[[Search]]-based Drama Management (SBDM)**. 미래의 여러 시나리오를 시뮬레이션하여 현재 가장 필요한 '자극'을 골라냄.
|
||||
## 매 핵심
|
||||
|
||||
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
|
||||
- 드라마 매니지먼트가 노골적이면 플레이어는 자신의 '자유의지(Agency)'가 침해받는다고 느껴 몰입이 깨진다(조작받는 느낌). 따라서 최근에는 LLM을 결합하여, 유저의 돌발 행동에도 논리적으로 대응하면서 자연스럽게 메인 플롯으로 복귀시키는 '생성형 드라마 매니지먼트'가 연구되고 있다.
|
||||
### 매 motivation
|
||||
- **Plot vs play**: 매 player 의 freedom + author 의 arc.
|
||||
- **Pacing**: 매 tension curve 의 maintain.
|
||||
- **Coherence**: 매 character / setting 의 consistent.
|
||||
|
||||
## 🔗 지식 연결 (Graph)
|
||||
- Related: [[Dynamic Difficulty Adjustment (DDA)]] , Player-Agency
|
||||
- System: AI-Director (eg Left 4 Dead)
|
||||
### 매 famous example
|
||||
- **Façade** (Mateas & Stern, 2005): 매 ABL behavior + plot points.
|
||||
- **Storytron** (Crawford): 매 character-driven.
|
||||
- **Left 4 Dead Director** (Valve): 매 pacing + drama.
|
||||
- **AI Dungeon**: 매 GPT-driven.
|
||||
- **Inkle (Heaven's Vault, 80 Days)**: 매 ink narrative scripting.
|
||||
|
||||
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
|
||||
### 매 architecture pattern
|
||||
- **Plot-point manager**: 매 must-hit beat.
|
||||
- **Character authority**: 매 NPC autonomy.
|
||||
- **Pacing controller**: 매 tension curve.
|
||||
- **Coherence guardian**: 매 contradiction 의 detect.
|
||||
|
||||
**언제 이 지식을 쓰는가:**
|
||||
- *(TODO)*
|
||||
### 매 method
|
||||
- **Search-based** (Roberts/Riedl): 매 plot tree 의 search.
|
||||
- **Beat-based**: 매 narrative beat 의 sequence.
|
||||
- **Constraint-based**: 매 author intent 의 constraint.
|
||||
- **LLM-based**: 매 token 의 narrative.
|
||||
|
||||
**언제 쓰면 안 되는가:**
|
||||
- *(TODO)*
|
||||
### 매 응용
|
||||
1. **RPG**: 매 quest pacing.
|
||||
2. **Interactive fiction**: 매 plot.
|
||||
3. **Sim**: 매 emergent story.
|
||||
4. **Educational**: 매 lesson narrative.
|
||||
5. **VR experience**: 매 presence + arc.
|
||||
|
||||
## 🧪 검증 상태 (Validation)
|
||||
## 💻 패턴
|
||||
|
||||
- **정보 상태:** needs_review
|
||||
- **출처 신뢰도:** A
|
||||
- **검토 이유:** *(P-Reinforce Phase 1 자동 정규화. 본문 검증 필요.)*
|
||||
### Plot-point manager
|
||||
```python
|
||||
class PlotPointManager:
|
||||
def __init__(self, plot_points):
|
||||
self.points = plot_points # 매 ordered required events
|
||||
self.completed = []
|
||||
|
||||
def hint(self, world_state):
|
||||
"""매 next required point 의 condition 의 nudge."""
|
||||
for p in self.points:
|
||||
if p not in self.completed and p.preconditions(world_state):
|
||||
return p.suggest_nudge(world_state)
|
||||
return None
|
||||
|
||||
def mark_complete(self, point):
|
||||
self.completed.append(point)
|
||||
|
||||
## 🧬 중복 검사 (Duplicate Check)
|
||||
# 매 example
|
||||
plot = [
|
||||
PlotPoint('meet_mentor', preconditions=lambda w: w.location == 'tavern'),
|
||||
PlotPoint('learn_skill', preconditions=lambda w: 'meet_mentor' in w.events),
|
||||
PlotPoint('confront_villain', preconditions=lambda w: 'learn_skill' in w.events),
|
||||
]
|
||||
```
|
||||
|
||||
- **기존 유사 문서:** *(TODO: 인덱서 클러스터 리포트 참조)*
|
||||
- **처리 방식:** UPDATE (자동 정규화)
|
||||
- **처리 이유:** Phase 1 정규화 — 옛 템플릿/누락 필드 보강.
|
||||
### Pacing controller (tension curve)
|
||||
```python
|
||||
class PacingController:
|
||||
def __init__(self):
|
||||
# 매 ideal 5-act curve
|
||||
self.target = lambda t: 4 * t * (1 - t) + 0.2 * np.sin(20 * t)
|
||||
|
||||
def desired_tension(self, story_progress):
|
||||
return self.target(story_progress) # 매 0 to 1
|
||||
|
||||
def adjust(self, current_tension, story_progress):
|
||||
target = self.desired_tension(story_progress)
|
||||
if current_tension < target - 0.1:
|
||||
return 'introduce_conflict'
|
||||
elif current_tension > target + 0.1:
|
||||
return 'introduce_calm'
|
||||
return 'maintain'
|
||||
```
|
||||
|
||||
## 🕓 변경 이력 (Changelog)
|
||||
### Beat-based (Mateas-style)
|
||||
```python
|
||||
class Beat:
|
||||
def __init__(self, name, preconditions, characters, duration):
|
||||
self.name = name
|
||||
self.preconditions = preconditions
|
||||
self.characters = characters
|
||||
self.duration = duration
|
||||
|
||||
def can_fire(self, world):
|
||||
return all(c(world) for c in self.preconditions)
|
||||
|
||||
| 날짜 | 변경 내용 | 처리 방식 | 신뢰도 |
|
||||
|------|-----------|-----------|--------|
|
||||
| 2026-05-08 | P-Reinforce Phase 1 정규화 (frontmatter + 헤더 표준화) | UPDATE | A |
|
||||
class DramaManager:
|
||||
def __init__(self, beats):
|
||||
self.beats = beats
|
||||
self.active_beat = None
|
||||
|
||||
def select_beat(self, world):
|
||||
candidates = [b for b in self.beats if b.can_fire(world)]
|
||||
# 매 score by drama value
|
||||
return max(candidates, key=lambda b: b.drama_score(world))
|
||||
```
|
||||
|
||||
### Search-based (declarative author intent)
|
||||
```python
|
||||
import heapq
|
||||
|
||||
def best_first_search(state, author_intent, max_depth=10):
|
||||
"""매 plot search 의 author 의 maximize."""
|
||||
queue = [(0, state, [])]
|
||||
while queue:
|
||||
score, s, path = heapq.heappop(queue)
|
||||
if author_intent.satisfied(s) or len(path) >= max_depth:
|
||||
return path
|
||||
for action in s.legal_actions():
|
||||
new_s = s.apply(action)
|
||||
new_score = -author_intent.evaluate(new_s)
|
||||
heapq.heappush(queue, (new_score, new_s, path + [action]))
|
||||
return None
|
||||
```
|
||||
|
||||
### LLM-based dynamic story
|
||||
```python
|
||||
def llm_drama_step(world_state, history, author_intent):
|
||||
prompt = f"""You are a drama manager. Author intent: "{author_intent}"
|
||||
|
||||
Recent history:
|
||||
{format_history(history[-5:])}
|
||||
|
||||
World state: {world_state}
|
||||
|
||||
Output the next narrative beat that:
|
||||
1. Honors player choice (do NOT railroad)
|
||||
2. Moves toward author intent
|
||||
3. Maintains pacing (current tension: {tension})
|
||||
4. Stays consistent with character traits
|
||||
|
||||
Beat (JSON): {{ "type": "...", "description": "...", "characters": [...], "consequences": {{...}} }}"""
|
||||
return llm.generate(prompt)
|
||||
```
|
||||
|
||||
### Coherence guardian
|
||||
```python
|
||||
class CoherenceCheck:
|
||||
def __init__(self, kb):
|
||||
self.kb = kb # 매 character traits, world facts
|
||||
|
||||
def validate(self, beat):
|
||||
contradictions = []
|
||||
for fact in self.kb.facts:
|
||||
if beat.contradicts(fact):
|
||||
contradictions.append((beat, fact))
|
||||
return contradictions
|
||||
|
||||
def auto_fix(self, beat):
|
||||
# 매 LLM 의 use 의 reword
|
||||
contras = self.validate(beat)
|
||||
if contras:
|
||||
return llm.fix_contradictions(beat, contras)
|
||||
return beat
|
||||
```
|
||||
|
||||
### Inkle ink-style (declarative narrative)
|
||||
```ink
|
||||
=== meet_mentor ===
|
||||
The old wizard turns. "You've come at last."
|
||||
* [Bow] -> bow_branch
|
||||
* [Question] -> question_branch
|
||||
- -> learn_skill
|
||||
|
||||
=== bow_branch ===
|
||||
You bow deeply. He nods.
|
||||
~ respect += 1
|
||||
-> learn_skill
|
||||
```
|
||||
|
||||
### AI Director-style pacing (Valve)
|
||||
```python
|
||||
class L4DDirector:
|
||||
"""매 Left 4 Dead pacing AI."""
|
||||
def __init__(self):
|
||||
self.intensity = 0 # 매 0-1
|
||||
|
||||
def update(self, players):
|
||||
# 매 measure recent danger
|
||||
recent_damage = sum(p.recent_damage for p in players)
|
||||
recent_kills = sum(p.recent_kills for p in players)
|
||||
|
||||
self.intensity = min(1, recent_damage / 100 + recent_kills / 20)
|
||||
|
||||
def decide(self):
|
||||
if self.intensity > 0.7:
|
||||
return 'relaxation' # 매 calm period
|
||||
elif self.intensity < 0.3:
|
||||
return 'build_up' # 매 zombie wave
|
||||
return 'sustain'
|
||||
```
|
||||
|
||||
### Player model integration
|
||||
```python
|
||||
def adapt_drama(player_history):
|
||||
"""매 player preference 의 drama 의 tune."""
|
||||
if player_history.combat_seek_count > 10:
|
||||
return 'combat_heavy'
|
||||
if player_history.dialog_engagement > 5:
|
||||
return 'dialog_heavy'
|
||||
return 'balanced'
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Linear story | Plot-point manager |
|
||||
| Emergent | Beat + character authority |
|
||||
| Action-paced | AI Director (Valve) |
|
||||
| Branching narrative | Inkle / Yarn |
|
||||
| Open-ended LLM | GPT + author constraint |
|
||||
| Educational | Lesson-arc + scaffold |
|
||||
|
||||
**기본값**: 매 hybrid — 매 plot-point + character authority + LLM dialog + coherence guardian.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Game-Design]] · [[Interactive-Narrative]]
|
||||
- 변형: [[Beat-Based]] · [[Search-Based-DM]] · [[LLM-Story]]
|
||||
- 응용: [[Dynamic Difficulty Adjustment (DDA)]] · [[NPC-Behavior]]
|
||||
- Adjacent: [[Generative-AI]] · [[Computational-Creativity]] · [[Façade]] · [[Inkle-Ink]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 narrative game. 매 interactive fiction. 매 dynamic story.
|
||||
**언제 X**: 매 strict scripted (no agency). 매 pure sim.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Railroad**: 매 player choice 의 fake.
|
||||
- **No coherence check**: 매 contradiction story.
|
||||
- **LLM-only**: 매 author intent 의 lose.
|
||||
- **Static beat**: 매 player adaptation X.
|
||||
- **Drama at all cost**: 매 player frustrate.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Façade paper, Roberts/Riedl, Crawford).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-04-20 | Auto-reinforced |
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — DM architectures + 매 plot point / pacing / beat / LLM / Inkle code |
|
||||
|
||||
Reference in New Issue
Block a user