# Death/Respawn Rules > **Status**: In Design > **Author**: SepComet + Claude > **Last Updated**: 2026-04-27 > **Implements Pillar**: 操作优于数值 (Skill Over Stats), 切换即承诺 (Switch is Commitment) ## Overview Death/Respawn Rules 是夜裔的玩家死亡与重生管理系统——定义玩家如何承受伤害、何时死亡、在何处重生、以及死亡带来的代价。它与"切换即承诺"支柱直接对齐:死亡惩罚的设计目标是让玩家在切形态时感受到风险(切错了可能死),但不会让死亡变成挫折(快速重生,代价合理)。系统采用 checkpoint 重生模型:玩家死亡后在最近的检查点重生,失去所有当前血能,当前波次重置——但不会失去关卡进度或任何永久升级。 玩家直接感受死亡时刻的**冲击**和重生时刻的**重新出发**。死亡不是"你输了"——屏幕短暂变暗、血能归零、你在检查点重新站起、敌人重新列阵。这个循环参考 Celeste 的"失败是学习"哲学——死亡足够轻,让你敢于尝试高风险操作(弹反时机、形态切换窗口);但足够重,让你在意每一次切换的决策。没有这个系统,形态切换的风险维度崩塌——玩家可以无代价地随意切换,违背"切换即承诺"支柱。 ## Player Fantasy Death/Respawn Rules 服务于一个动作游戏中最被低估的情感:**"再来一次"的渴望**。当你因切形态时机错误被 Brute 一拳砸死时,那一瞬间不是挫败——是"我知道了,下次弹反要早 0.1 秒按"。屏幕暗下、血能归零、你在检查点重新站起的 2 秒内,你已经在大脑里重放了刚才的失误并找到了修正方案。这就是好的死亡系统应该创造的感受:死亡不是终点,是**信息**。 参考 Celeste 的死亡哲学——"每次死亡都是学习,重生快到你不觉得被打断"——和 Hades 的死亡循环——"死亡是回家,不是失败"。夜裔的死亡走在两者之间:Celeste 的快速重生(检查点即重生,没有加载、没有菜单) + Hades 的资源重置(血能归零是实质性代价,迫使你重新赚取)。玩家敢于尝试高风险操作——极限弹反、狼形对撞、雾形深入包围——因为这些操作失败后的惩罚是**有限的、可量化的、可恢复的**。你不会因为一次失误而失去 30 分钟的进度,你只会失去当前的血能和当前波次——然后你立刻重新开始。 ## Detailed Design ### Core Rules **1. Player Health** - `MaxHealth`: 100 (baseline, before any upgrades) - `CurrentHealth`: tracked by Death/Respawn Rules, range [0, MaxHealth] - Health displayed to player via HUD, driven by `OnPlayerHealthChanged(current, max)` event **2. Player Damage Reception Pipeline** ``` Enemy AI produces AttackData → CombatCoordinator.ResolveFrame() → OnPlayerHit → Death/Respawn subtracts health ``` - Combat Logic's `CombatCoordinator.ResolveFrame(deltaTime)` handles all attack resolution (player + enemy) in a unified two-phase pipeline - Enemy attacks are resolved against `PlayerState` during the damage phase (after parry nullification in the parry phase) - Death/Respawn Rules subscribes to `CombatLogic.OnPlayerHit(PlayerDamageResult)` — subtracts FinalDamage from CurrentHealth - No player-side resistance or armor — damage is applied as-received (mirrors Enemy AI's pure-receiver model) **3. PlayerState Definition** `PlayerState` is defined in Combat Logic GDD (authoritative single source). Death/Respawn reads and writes these fields: - **Reads**: `Position`, `HitShape` (provided to CombatCoordinator for hit detection) - **Writes**: `CurrentHealth` (updated on damage), `MaxHealth` (baseline 100, modified by upgrades), `IsDead` (set when CurrentHealth <= 0), `IsInvincible` (set during respawn i-frames) - Other PlayerState fields (`FacingAngle`, `IsParryActive`, `ParryShape`) are managed by Form Switch SM and Combat Logic; Death/Respawn does not touch them. **4. Death Condition** - `CurrentHealth <= 0` → player dies - Death is immediate on the frame health reaches 0 - Player cannot act during death (all input ignored) - Trigger sequence: `OnPlayerDied` → systems react → respawn timer starts **5. Checkpoint System** - Checkpoint = start of current wave - Updated each time `OnWaveChanged` fires (Wave Manager) - On death: player respawns at the checkpoint wave's start state - No manual checkpoint activation needed — automatic, invisible ### Death State | Phase | Duration | What Happens | |-------|----------|--------------| | **Death Freeze** | 0.3s | Screen freeze-frame. Player input locked. `OnPlayerDied` emitted. | | **Death Fade** | 1.0s | Screen fades to black. Audio ducks. Systems react (enemies stop, blood energy resets). | | **Respawn Fade** | 0.5s | Player repositioned at checkpoint. HUD resets. `OnPlayerRespawned` emitted. | | **Invincibility** | 2.0s | Player can move and act but takes no damage. Visual: player geometry pulses/flashes. | | **Active** | — | i-frames expire. Full damage vulnerability restored. `OnPlayerVulnerable` emitted. | Total death-to-active: ~3.8 seconds. Fast enough to feel like "instant retry." ### Respawn Flow 1. Player dies → `OnPlayerDied` emitted 2. Blood Energy Economy receives `OnPlayerDied` → resets blood energy to 0 3. Wave Manager receives `OnPlayerDied` → freezes wave state 4. Death fade completes → player position reset to checkpoint spawn point 5. Wave Manager receives `OnPlayerRespawned` → resets current wave (despawn all enemies, restart from InterWave) 6. Player enters Invincibility (2s) 7. `OnPlayerVulnerable` → player fully active, wave restarts ### Interactions with Other Systems | System | Direction | Interface | |--------|-----------|-----------| | **Combat Logic** | Upstream | Provides `PlayerState` to Combat Logic as hit target. Receives `OnPlayerHit(PlayerDamageResult)` for health subtraction. | | **Blood Energy Economy** | Downstream | Emits `OnPlayerDied` → Blood Energy resets to 0. | | **Wave Manager** | Downstream | Emits `OnPlayerDied` (wave freezes), `OnPlayerRespawned` (wave resets to current checkpoint wave). | | **Enemy AI Logic** | Downstream | Emits `OnPlayerDied` → all enemies enter Cooldown/Idle. Emits `OnPlayerVulnerable` → enemies resume normal behavior. | | **Form Switch SM** | Downstream | Emits `OnPlayerDied` → resets form to default (Human) on respawn. | | **UI/HUD (L2)** | Downstream | Emits `OnPlayerHealthChanged`, `OnPlayerDied`, `OnPlayerRespawned`, `OnPlayerVulnerable` for HUD display. | | **VFX Spawner (L1)** | Downstream | Emits `OnPlayerDied` (death VFX), `OnPlayerRespawned` (respawn VFX). | | **Audio Player (L1)** | Downstream | Emits `OnPlayerHit` (pain SFX), `OnPlayerDied` (death sting), `OnPlayerRespawned` (respawn whoosh). | ## Formulas ### Player Damage Reception The player damage formula is defined as: `newHealth = currentHealth - finalDamage` **Variables:** | Variable | Symbol | Type | Range | Description | |----------|--------|------|-------|-------------| | Current health | `currentHealth` | float | 0–100 | Pre-hit health | | Final damage | `finalDamage` | float | 0–150 | From Combat Logic PlayerDamageResult | **Output Range**: 0–100 | Clamped at 0. If newHealth <= 0 → IsDead = true, OnPlayerDied fires. **Design Intent**: Player applies damage as-received — no armor, no resistance, no mitigation. Transparency: a Brute hit always does exactly 25 damage. The player always knows how many hits they can take. Skill expression is in avoiding/parrying hits, not in building damage resistance. --- ### Death Threshold The death formula is defined as: `isDead = currentHealth <= 0` **Output**: Boolean. Once true, triggers the full death→respawn sequence. `OnPlayerDied` fires exactly once per death. --- ### Hit Survival Thresholds (Baseline 100 HP) | Enemy Attack | Damage | Hits to Die | |-------------|--------|-------------| | Swarm | 6 | 17 | | Stalker | 18 | 6 | | Brute | 25 | 4 | **Design Intent**: Brute is always lethal in 4 hits — enough to create tension but enough time to learn the parry timing. Swarm chip damage adds up — ignoring them is viable short-term but fatal if sustained. ## Edge Cases - **If player takes damage exceeding current health (overkill)**: Health clamps to 0. No negative health. Death triggers once. Overkill damage is not tracked — does not affect respawn. - **If player takes damage while IsInvincible=true (respawn i-frames)**: Damage ignored. OnPlayerHit does NOT fire. Health unchanged. - **If multiple hits kill the player in the same frame (simultaneous hits from multiple enemies)**: All hits resolve (batched frame). Health drops to 0 or below. OnPlayerDied fires exactly once. Hit events for the same frame after death are still emitted but health stays at 0. - **If deltaTime = 0 (game paused)**: Death/respawn timers (Death Freeze, Death Fade, Respawn Fade, Invincibility) all pause. No phase transitions during pause. - **If player dies on Wave 1 (first wave, checkpoint = Wave 1 start)**: Normal respawn flow applies. Blood energy already 0 or low. Wave 1 restarts. No special case needed. - **If player dies during Invincibility (2s i-frames)**: Cannot happen — player is invincible. No damage received. - **If OnPlayerDied fires but OnPlayerRespawned never fires (e.g., game quit during death)**: State is discarded. Next session starts fresh. No partial death state persists. - **If MaxHealth is modified (future Skill Tree upgrade) while player is dead**: Applied on respawn. CurrentHealth = new MaxHealth on respawn. - **If checkpoint advances (OnWaveChanged) during death animation**: Ignored. Checkpoint only updates while player is in Active state. Death-locks checkpoint at the wave where death occurred. ## Dependencies | System | Layer | Type | Hard/Soft | Interface | |--------|-------|------|-----------|-----------| | **Combat Logic** | L0 | Upstream | Hard | Provides PlayerState for hit detection. Receives OnPlayerHit for health subtraction. Cannot function without damage pipeline. | | **Blood Energy Economy** | L0 | Downstream | Hard | Emits OnPlayerDied → resets blood energy to 0. Core death penalty mechanic. | | **Wave Manager** | L0 | Downstream | Hard | Emits OnPlayerDied (freeze), OnPlayerRespawned (reset wave). Wave reset is the other core death penalty. | | **Enemy AI Logic** | L0 | Downstream | Soft | Emits OnPlayerDied → enemies stop attacking. Works without but enemies attacking a corpse looks broken. | | **Form Switch SM** | L0 | Downstream | Soft | Emits OnPlayerDied → form resets to Human on respawn. | | **UI/HUD (L2)** | L2 | Downstream | Soft | Emits OnPlayerHealthChanged, OnPlayerDied, OnPlayerRespawned for display. | | **VFX Spawner (L1)** | L1 | Downstream | Soft | Emits death/respawn events for visual feedback. | | **Audio Player (L1)** | L1 | Downstream | Soft | Emits hit/death/respawn events for audio feedback. | | **Level Loader (L1)** | L1 | Upstream | Soft | Receives checkpoint spawn positions from LevelData. | **Hard dependencies**: Combat Logic, Blood Energy Economy, Wave Manager. ## Tuning Knobs | Parameter | Default | Safe Range | Too Low | Too High | |-----------|---------|------------|---------|----------| | `MaxHealth` | 100 | 60–150 | Every hit feels lethal — no learning window | Player immortal — no tension | | `DeathFreezeDuration` | 0.3s | 0.1–0.5s | No impact feel — death feels glitchy | Too long — feels unresponsive | | `DeathFadeDuration` | 1.0s | 0.5–1.5s | Not enough time for audio cue | Player waiting — frustration builds | | `RespawnFadeDuration` | 0.5s | 0.3–1.0s | Disorienting — player doesn't register new position | Dead air before action resumes | | `InvincibilityDuration` | 2.0s | 1.0–3.0s | Spawn-camped by enemies at perimeter | Too safe — player can clear enemies during i-frames | | `PlayerHitShapeRadius` | 0.5 | 0.3–0.7 | Too hard to hit — attacks whiff unfairly | Too easy to hit — player feels bloated | **Key tuning pair**: `MaxHealth` + enemy `AttackBaseDamage` values (in Enemy AI GDD). Changing MaxHealth changes every hits-to-die threshold. Baseline (non-crit worst case): Swarm=100/6≈17 hits, Stalker=100/18≈6 hits, Brute=100/25=4 hits. Actual hits-to-die varies with player crits, positional guarantees, and form-specific damage. ## Visual/Audio Requirements Combat is a visual system — Visual/Audio is REQUIRED. | Event | VFX | Audio | |-------|-----|-------| | `OnPlayerHit` | Red flash at screen edge from hit direction. Player geometry briefly flashes red. | Pain SFX — varies by damage amount (light grunt <15, heavy grunt ≥15) | | `OnPlayerDied` | Screen freeze-frame (0.3s) → player geometry shatters outward in white/silver fragments | Bass drop + silence — distinct from enemy death sounds | | `OnPlayerRespawned` | Player geometry reforms from fragments at checkpoint position. White flash → form color transition. | Rising whoosh + heartbeat start | | `OnPlayerVulnerable` | Player geometry stops pulsing/flashing. Brief shimmer. | Subtle "ready" chime | | `OnPlayerHealthChanged` | Health bar VFX (flash on damage, gentle pulse on low health <25%) | None (too frequent for SFX) | **Invincibility visual**: Player geometry pulses white at 4Hz during i-frames. Intensity decreases over the 2s duration — last 0.5s is barely visible. ## UI Requirements | Element | Content | Trigger | |---------|---------|---------| | Health Bar | CurrentHealth / MaxHealth as horizontal bar. Color: green (>50%), yellow (25-50%), red (<25%). | `OnPlayerHealthChanged` | | Death Overlay | Full-screen dark vignette + "You Died" text (1s) | `OnPlayerDied` | | Respawn Text | "Again" — centered, fades after 1s | `OnPlayerRespawned` | | i-Frame Indicator | Health bar border pulses white during invincibility | `OnPlayerRespawned` → `OnPlayerVulnerable` | ## Acceptance Criteria | # | GIVEN | WHEN | THEN | |---|-------|------|------| | 1 | Player CurrentHealth=100. `PlayerDamageResult { FinalDamage=25 }`. | OnPlayerHit received | CurrentHealth=75. OnPlayerHealthChanged(75, 100) fires. IsDead=false. | | 2 | Player CurrentHealth=20. `PlayerDamageResult { FinalDamage=25 }`. | OnPlayerHit received | CurrentHealth=0 (clamped). IsDead=true. OnPlayerDied fires. Death sequence begins. | | 3 | Player CurrentHealth=10. Two simultaneous hits: FinalDamage=8 and FinalDamage=6. | Both hits in same frame | CurrentHealth=0. OnPlayerDied fires exactly once. Both OnPlayerHit events fire. | | 4 | Player IsInvincible=true (during respawn i-frames). `PlayerDamageResult { FinalDamage=25 }`. | OnPlayerHit received | Damage ignored. CurrentHealth unchanged. OnPlayerHealthChanged does NOT fire. | | 5 | Player dies. Death Freeze(0.3s) → Death Fade(1.0s) → Respawn Fade(0.5s) → Invincibility(2.0s). | Death sequence completes | Total elapsed ~3.8s. Player is at checkpoint position, full health, form=Human. | | 6 | Player dies on Wave 3. Checkpoint = Wave 3. | Respawn completes | Wave Manager.OnPlayerRespawned fires → Wave 3 resets from InterWave. Blood energy = 0. | | 7 | Player in Active state. Wave 4 starts (OnWaveChanged fires). | Checkpoint update | CurrentCheckpointWave = 4. Future death respawns at Wave 4. | | 8 | deltaTime=0.0 during Death Fade (0.5s elapsed, 0.5s remaining). | Update called | Timer does not advance. Death Fade stays at 0.5s remaining. | | 9 | Player CurrentHealth=100. MaxHealth increased to 120 (future upgrade). | Upgrade applied | MaxHealth=120. CurrentHealth stays 100. (Does not auto-heal on upgrade.) | | 10 | Player dies at MaxHealth=120. | Respawn completes | CurrentHealth = MaxHealth = 120 (full heal on respawn). | ## Open Questions - Respawn position within arena: Should the player respawn at arena center, or at a designer-specified spawn point per wave? MVP defaults to arena center. Defer spawn point customization to Level Loader GDD. - Should there be a "death streak" mechanic (e.g., slight health buff after 3 consecutive deaths on same wave)? Aligns with Celeste philosophy of helping struggling players, but may conflict with "Skill Over Stats" pillar. - Player HitShape (Circle r=0.5): Is this the same regardless of current form? Or should HitShape change with form (Human smaller, Wolf larger, Mist diffuse)? MVP uses uniform HitShape for simplicity. - Should the death counter be tracked for scoring/statistics? Score Calculator GDD may want this data. - Game Over condition: Is there one? Infinite retries is the MVP plan, but should a level have a max-death count for challenge mode? Defer to Score Calculator / Menu System.