f8b21af4be
10_Wiki/Topics 대규모 정리: - 오류 캡처/미완성 stub 문서 227개 제거 - 교차폴더 중복 43클러스터 병합 (63파일 → redirect) - 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건 - 카테고리 MOC 6개 신규 생성 - Graph 섹션 미해결 related-keyword 링크 10,058건 제거 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
8.3 KiB
8.3 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-drama-management-systems | Drama Management Systems | 10_Wiki/Topics | verified | self |
|
none | A | 0.9 | applied |
|
2026-05-10 | pending |
|
Drama Management Systems
매 한 줄
"매 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.
매 핵심
매 motivation
- Plot vs play: 매 player 의 freedom + author 의 arc.
- Pacing: 매 tension curve 의 maintain.
- Coherence: 매 character / setting 의 consistent.
매 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.
매 architecture pattern
- Plot-point manager: 매 must-hit beat.
- Character authority: 매 NPC autonomy.
- Pacing controller: 매 tension curve.
- Coherence guardian: 매 contradiction 의 detect.
매 method
- Search-based (Roberts/Riedl): 매 plot tree 의 search.
- Beat-based: 매 narrative beat 의 sequence.
- Constraint-based: 매 author intent 의 constraint.
- LLM-based: 매 token 의 narrative.
매 응용
- RPG: 매 quest pacing.
- Interactive fiction: 매 plot.
- Sim: 매 emergent story.
- Educational: 매 lesson narrative.
- VR experience: 매 presence + arc.
💻 패턴
Plot-point manager
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)
# 매 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),
]
Pacing controller (tension curve)
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'
Beat-based (Mateas-style)
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)
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)
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
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
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)
=== 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)
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
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
- 응용: Dynamic Difficulty Adjustment (DDA)
- Adjacent: Generative-AI · Computational_Creativity
🤖 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 |