--- 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; } ``` ### 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 |