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>
191 lines
6.5 KiB
Markdown
191 lines
6.5 KiB
Markdown
---
|
|
id: wiki-2026-0508-status-effects
|
|
title: Status Effects
|
|
category: 10_Wiki/Topics
|
|
status: verified
|
|
canonical_id: self
|
|
aliases: [Buff Debuff, Status Conditions, Combat Effects, DoT HoT]
|
|
duplicate_of: none
|
|
source_trust_level: A
|
|
confidence_score: 0.92
|
|
verification_status: applied
|
|
tags: [game-design, combat-mechanics, buff-system, rpg, mmo]
|
|
raw_sources: []
|
|
last_reinforced: 2026-05-10
|
|
github_commit: pending
|
|
tech_stack:
|
|
language: typescript
|
|
framework: combat-system
|
|
---
|
|
|
|
# Status Effects
|
|
|
|
## 매 한 줄
|
|
> **"매 status effect 는 매 timed modifier on combatant 다."**. Status effects (buff/debuff, DoT/HoT, stun, root, silence, slow) 는 ARPG/MMO/MOBA combat depth 의 핵심 — 매 effect 가 stack rule, refresh rule, dispel rule, immunity rule 의 4 차원 contract 를 가지고, 매 designer 의 lever 와 매 player 의 mastery surface 를 정의한다. 매 2026 design 에서 status system 의 cleanliness 가 PvP balance 의 가장 큰 source.
|
|
|
|
## 매 핵심
|
|
|
|
### 매 Effect Categories
|
|
- **Buff**: positive modifier (haste, shield, damage up)
|
|
- **Debuff**: negative modifier (slow, weakness, vulnerability)
|
|
- **DoT** (damage over time): bleed, poison, burn
|
|
- **HoT** (heal over time): regen, lifesteal aura
|
|
- **CC** (crowd control): stun, root, silence, fear, sleep
|
|
- **Aura**: persistent radius effect
|
|
|
|
### 매 Stack Rules
|
|
- **Refresh**: 매 reapply → duration reset, no stack
|
|
- **Stack**: 매 reapply → +1 stack, max N
|
|
- **Stack-then-refresh**: stack to N then refresh duration
|
|
- **Independent**: each application = separate instance
|
|
|
|
### 매 Dispel/Immunity
|
|
- 매 effect 의 dispel category (magical, physical, curse)
|
|
- 매 immunity (boss, late-game gear)
|
|
- 매 cleanse priority (highest stack first)
|
|
|
|
### 매 응용
|
|
1. WoW class talents/auras.
|
|
2. Path of Exile ailments + curses.
|
|
3. League of Legends CC system.
|
|
4. Dark Souls bleed/poison build-up.
|
|
|
|
## 💻 패턴
|
|
|
|
### Pattern 1 — Effect schema
|
|
```typescript
|
|
type EffectKind = 'buff'|'debuff'|'dot'|'hot'|'stun'|'root'|'silence';
|
|
interface StatusEffect {
|
|
id: string;
|
|
kind: EffectKind;
|
|
durationMs: number;
|
|
startedAt: number;
|
|
stacks: number;
|
|
maxStacks: number;
|
|
stackRule: 'refresh'|'stack'|'stackThenRefresh'|'independent';
|
|
dispelCategory?: 'magical'|'physical'|'curse';
|
|
source: string; // applier id
|
|
modifierFn: (target: Combatant) => Partial<Stats>;
|
|
}
|
|
```
|
|
|
|
### Pattern 2 — Apply with stack rule
|
|
```typescript
|
|
function applyEffect(target: Combatant, incoming: StatusEffect) {
|
|
const existing = target.effects.find(e => e.id === incoming.id);
|
|
if (!existing) { target.effects.push(incoming); return; }
|
|
switch (existing.stackRule) {
|
|
case 'refresh':
|
|
existing.startedAt = Date.now();
|
|
existing.durationMs = incoming.durationMs;
|
|
break;
|
|
case 'stack':
|
|
existing.stacks = Math.min(existing.stacks + 1, existing.maxStacks);
|
|
break;
|
|
case 'stackThenRefresh':
|
|
if (existing.stacks < existing.maxStacks) existing.stacks++;
|
|
else { existing.startedAt = Date.now(); existing.durationMs = incoming.durationMs; }
|
|
break;
|
|
case 'independent':
|
|
target.effects.push(incoming);
|
|
break;
|
|
}
|
|
}
|
|
```
|
|
|
|
### Pattern 3 — Tick (DoT/HoT processing)
|
|
```typescript
|
|
function tickEffects(target: Combatant, now: number) {
|
|
for (const e of [...target.effects]) {
|
|
if (now - e.startedAt > e.durationMs) {
|
|
target.effects.splice(target.effects.indexOf(e), 1);
|
|
continue;
|
|
}
|
|
if (e.kind === 'dot') applyDamage(target, dotDmgPerTick(e));
|
|
if (e.kind === 'hot') applyHeal(target, hotHealPerTick(e));
|
|
}
|
|
}
|
|
```
|
|
|
|
### Pattern 4 — Stat aggregation
|
|
```typescript
|
|
function aggregateStats(target: Combatant): Stats {
|
|
const base = target.baseStats;
|
|
const mods = target.effects
|
|
.filter(e => e.kind === 'buff' || e.kind === 'debuff')
|
|
.map(e => e.modifierFn(target));
|
|
return mods.reduce((acc, m) => mergeStats(acc, m, target.effects), { ...base });
|
|
}
|
|
```
|
|
|
|
### Pattern 5 — Dispel
|
|
```typescript
|
|
function dispel(target: Combatant, category: DispelCategory, count = 1) {
|
|
const candidates = target.effects
|
|
.filter(e => e.dispelCategory === category && e.kind === 'debuff')
|
|
.sort((a, b) => b.stacks - a.stacks);
|
|
for (let i = 0; i < count && i < candidates.length; i++) {
|
|
target.effects.splice(target.effects.indexOf(candidates[i]), 1);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Pattern 6 — CC immunity (diminishing returns)
|
|
```typescript
|
|
function applyCC(target: Combatant, effect: StatusEffect) {
|
|
const recentCC = target.ccHistory.filter(t => Date.now() - t < 18_000).length;
|
|
const drFactor = [1.0, 0.5, 0.25, 0.0][Math.min(recentCC, 3)];
|
|
if (drFactor === 0.0) return; // immune
|
|
applyEffect(target, { ...effect, durationMs: effect.durationMs * drFactor });
|
|
target.ccHistory.push(Date.now());
|
|
}
|
|
```
|
|
|
|
### Pattern 7 — Aura propagation
|
|
```typescript
|
|
function tickAuras(world: World) {
|
|
for (const source of world.combatants) {
|
|
for (const aura of source.auras) {
|
|
const targets = world.combatants.filter(c => distance(c, source) < aura.radius);
|
|
for (const t of targets) ensureAuraEffect(t, aura, source.id);
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## 매 결정 기준
|
|
| 상황 | Approach |
|
|
|---|---|
|
|
| Simple action game | Refresh-only, 3-5 status types |
|
|
| ARPG with builds | Stack-based, ailments interact |
|
|
| Competitive MOBA | DR system mandatory, clear immunity rules |
|
|
| MMO raid | Per-instance effects, dispel priority defined |
|
|
|
|
**기본값**: 4 stack rules, max stacks 5, DoT tick rate 1s, CC DR 100%/50%/25%/immune at 18s window.
|
|
|
|
## 🔗 Graph
|
|
- 부모: [[State-Machine-and-Phase-Transition-Events]] · [[Stage-Director-and-World-Tension-Scaling]]
|
|
- 변형: [[Staggered-Firing-Logic-and-Phase-Offset]] · [[Combat_Balance_Buff]]
|
|
- 응용: [[Damage-Resistance-Platforms]] · [[Anti-Air-and-Anti-Ground-Combat]]
|
|
- Adjacent: [[Player-Experience-Modeling]] · [[Procedural-Rhetoric|Procedural Rhetoric (In Gaming)]]
|
|
|
|
## 🤖 LLM 활용
|
|
**언제**: status system schema review, stack rule design, CC DR system 검토.
|
|
**언제 X**: turn-based card game (different effect model).
|
|
|
|
## ❌ 안티패턴
|
|
- **Unbounded stacks**: 매 stack count infinity → 매 numerical explosion.
|
|
- **No DR on CC**: 매 chain-stun → 매 unfun PvP.
|
|
- **Hidden tick rate**: 매 player 가 DPS 계산 불가능 → 매 build crafting 막힘.
|
|
- **No dispel category**: 매 cleanse 가 모든 debuff 제거 → 매 debuff design 무력화.
|
|
|
|
## 🧪 검증 / 중복
|
|
- Verified (WoW combat log spec, Path of Exile ailment docs, LoL CC analysis).
|
|
- 신뢰도 A.
|
|
|
|
## 🕓 Changelog
|
|
| 날짜 | 변경 |
|
|
|---|---|
|
|
| 2026-05-08 | Phase 1 |
|
|
| 2026-05-10 | Manual cleanup — effect schema + 7 patterns + stack/dispel rules |
|