Files
zeling_v2/Docs/Architecture_Review.md
2026-05-08 11:04:00 +08:00

379 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Architecture vs Design 全面审查报告
> **审查日期**2025-01
> **审查范围**`Docs/Architecture/`24 份文档)← → `Docs/Design/`74 份文档)
> **审查方法**:人工逐节比对核心模块,重点覆盖战斗、弹反、霸体、护盾、玩家、墙壁力学
> **结论**`00_CoverageIndex.md` 声称"架构完整度 100%"与实际不符,存在若干**严重错误**、**内部矛盾**和**实现细节缺失**
---
## 一、总体评估
| 维度 | 声称状态 | 实际状态 |
|------|----------|----------|
| 内容覆盖(所有 Design 文档均有对应章节) | ✅ 100% | ✅ 基本完整,极少遗漏 |
| 技术数值/枚举值准确性 | ✅ 完整 | 🔴 多处**严重错误** |
| 架构文档内部一致性 | ✅ 完整 | 🔴 存在**互相矛盾**的代码片段 |
| 与 Design 意图对齐(设计意图传达) | ✅ 完整 | 🟠 3 个系统**根本设计不同** |
| 实现细节充分度 | ✅ 完整 | 🟡 部分模块**细节不足** |
---
## 二、🔴 严重错误Critical—— 必须修正,按此实现将产生 Bug
---
### D-01 · PoiseSystem 根本设计不同
**位置**`06_CombatModule.md §13` vs `Design/54_PoiseSystem.md`
Architecture 描述的是**数值耐久条系统**Design 定义的是**等级比较系统**——两者是完全不同的机制。
| 对比项 | Architecture 06 §13 | Design 54正确版本|
|--------|---------------------|----------------------|
| 系统类型 | 数值耐久(`int _currentPoise -= X` | 等级比较(`(int)breakLevel >= (int)poiseLevel`|
| 适用对象 | **仅敌人**(注释"玩家不使用霸体系统"| **玩家和敌人**均有霸体 |
| 玩家霸体 | 不存在 | `IPoiseSource` 接口,`PlayerController` 实现,攻击/技能期间激活 |
| 枚举结构 | 单一 `BreakLevel` 枚举 | **两个独立枚举**`PoiseLevel`(承受方)和 `BreakLevel`(攻击方)|
| 时间窗口 | 无 | `PoiseWindowConfig` struct可为每个状态/技能配置时间窗口 |
| 精细规则 | `GetPoiseBreakAmount(info)` 隐式处理 | `PoiseOverrideTableSO` — 显式配置 sourceId 对特定目标的精细规则 |
**Architecture BreakLevel 枚举值错误**(影响伤害管线中所有使用 BreakLevel 的比较逻辑):
```csharp
// Architecture 06 §2错误
public enum BreakLevel
{
Light = 0, // 值错误
Heavy = 1, // 值错误
Super = 2, // 名称错误Design 中无此值)
Unbreakable = 99, // 值错误
}
// Design 54正确
public enum BreakLevel { None=0, Light=1, Medium=2, Heavy=3, Breaker=4 }
public enum PoiseLevel { None=0, Light=1, Medium=2, Heavy=3, Unbreakable=100 }
```
**缺少的关键组件**
- `IPoiseSource` 接口(`PlayerController` 实现,提供 `CurrentPoiseLevel``GetPoiseWindow()`
- `PoiseWindowConfig` 结构体(每个动画状态/技能的霸体等级 + 起止时间窗口)
- `PoiseOverrideTableSO`(游戏资产,细粒度控制特定来源 vs 特定目标的打断规则)
- `DamageSourceSO` 中的 `BreakLevel` 字段应对应正确的枚举值范围
---
### D-02 · ParryConfigSO 数值与字段全部错误
**位置**`06_CombatModule.md §9` vs `Design/05_ParrySystem.md §9`
```csharp
// Architecture 06 §9错误
public class ParryConfigSO : ScriptableObject
{
public float ParryWindowDuration = 0.4f; // ❌ 应为 WindowDuration = 0.28s
public float PerfectParryWindow = 0.1f; // ❌ 字段名不符,且设计无此独立字段
public float ParryCooldown = 0.3f; // ⚠️ 设计未定义此字段
public int SoulPowerOnParry = 20; // ❌ 应为 SoulGainOnParry = 33
public int SoulPowerOnPerfect = 40; // ❌ 应为 +50Perfect 额外奖励)
public float PerfectParryCounterDmg = 1.5f; // ❌ 应为 ParryCounterMultiplier = 3.0
// ❌ 缺少以下字段:
// StartupDuration = 0.05f 弹反启动前摇
// EndlagDuration = 0.10f 弹反后摇
// CounterWindowDuration = 0.5f 弹反成功后的反击窗口
// BulletTimeScale = 0.25f 成功弹反时的子弹时间倍率
// BulletTimeDuration = 0.2f 子弹时间持续
// StaggerDuration = 0.8f 被弹反敌人的硬直时长
}
```
| 字段 | Architecture | Design正确值|
|------|-------------|-----------------|
| 弹反窗口 | 0.4f | **0.28s** |
| 普通弹反灵力 | 20 | **33** |
| 完美弹反灵力 | 40 | **+50**(累计 83|
| 完美弹反伤害倍率 | 1.5× | **3.0×** |
| 启动前摇 | 缺失 | **0.05s** |
| 后摇 | 缺失 | **0.10s** |
| 反击窗口 | 缺失 | **0.5s** |
| 子弹时间倍率 | 缺失 | **0.25** |
---
### D-03 · HurtBox.ReceiveDamage() 存在两个互相矛盾的版本
**位置**`06_CombatModule.md §5` vs `20_ShieldModule.md §2`
两个文档对同一方法有不同定义,行为**互相不兼容**
**版本 A06_CombatModule §5**
```csharp
// 护盾处理后,若 Amount > 0HurtBox 继续调用 _owner.TakeDamage
if (_shieldable != null && _shieldable.HasShield)
{
_shieldable.AbsorbDamage(ref info);
if (info.Amount <= 0) return; // 完全吸收才退出
}
int finalDamage = Mathf.Max(1, info.Amount - _owner.Defense);
_owner.TakeDamage(info); // 穿透伤害由 HurtBox 直接调用 TakeDamage
```
**版本 B20_ShieldModule §2标注为"修改 06_CombatModule §2 的实现"**
```csharp
// 护盾处理后总是 return穿透伤害通过事件传递
if (_shieldable != null && _shieldable.HasShield)
{
_shieldable.AbsorbDamage(ref info);
return; // 总是退出!穿透由 ShieldComponent 内部触发 _onDamagePassedThrough 事件
}
_damageable?.TakeDamage(info); // 无护盾时才直接调用
```
**冲突后果**:若使用版本 A当护盾未完全吸收时HurtBox 直接调用 `TakeDamage`,同时 `ShieldComponent.AbsorbDamage` 也触发 `_onDamagePassedThrough` 事件通知 `PlayerStats`——**玩家受到双倍穿透伤害**。
版本 BShieldModule 提供)才是正确的"护盾总线"设计,版本 A 需要移除护盾后的穿透处理逻辑。
**附加差异**:版本 A 有无敌帧检查,版本 B 没有;版本 B 有 `if (!_isActive) return;` 保护,版本 A 没有。
---
## 三、🟠 重要问题High—— 实现时需要大量补充或会导致功能不完整
---
### D-04 · ParrySystem 缺少完整状态机
**位置**`06_CombatModule.md §8` vs `Design/05_ParrySystem.md`
Architecture 的 `ParrySystem` 仅有一个 `bool _isParrying` + 单计时器Design 定义了**5 阶段状态机**
```
Design 05 正确状态机:
Inactive → Startup(0.05s) → Active(0.28s) → ParrySuccess → CounterWindow(0.5s) → Inactive
Architecture 06 实现:
_isParrying = true/false + _parryWindowTimer单一计时器无阶段区分
```
缺少的阶段及行为:
- **Startup前摇**0.05s,期间无法弹反但玩家进入弹反动画,给予视觉反馈
- **EndLag后摇**:弹反结束后 0.1s,防止立即连续弹反
- **CounterWindow反击窗口**:弹反成功后 0.5s玩家可使用强化攻击×3 倍率)
- `_isParrying > _config.PerfectParryWindow` 的"完美弹反"判定逻辑依赖 Startup 计时,但 Architecture 未建模
---
### D-05 · HandleSuccessfulParry() 方法不存在
**位置**`20_ShieldModule.md §8` 引用 vs `06_CombatModule.md §8`
`20_ShieldModule.md §8 弹反集成` 第 311 行写道:
> `ParrySystem.HandleSuccessfulParry()` 末尾调用:`shield.OnParrySuccess();`
`06_CombatModule.md §8 ParrySystem` 中,该类只有:
- `TryActivateParry()`
- `TryParryDamage(DamageInfo info)`
- `ApplyPerfectParryEffect(DamageInfo info)`
- `EndParry(bool success)`
**`HandleSuccessfulParry()` 方法在架构中未定义**,两个文档引用的不是同一个 API。
同时,`ShieldComponent.OnParrySuccess()` 的调用路径也有两个版本:
- `20_ShieldModule §6 表格`"弹反成功 | `ParrySystem.OnParrySuccess`SO 事件)→ `ShieldComponent.OnParrySuccess()`"
- `20_ShieldModule §8 代码``ParrySystem.HandleSuccessfulParry()` 内直接 `TryGetComponent<ShieldComponent>()` 调用
两种集成方式并存,需要统一。
---
### D-06 · OnParrySuccess 事件频道类型错误
**位置**`06_CombatModule.md §8` vs `Design/05_ParrySystem.md §10`
```csharp
// Architecture 06 §8错误
[SerializeField] private VoidEventChannelSO _onParrySuccess;
// 仅广播"发生了弹反",无附加数据
// Design 05 §10正确
// OnParrySuccess 应为 DamageInfoEventChannelSO
// 携带 DamageInfo payload下游系统根据 info 计算反击伤害量、特效强度等
```
`VoidEventChannelSO` 不携带 `DamageInfo`,导致:
1. `CounterWindow` 期间的反击伤害无法基于原始攻击力计算×3 倍率)
2. `ParryableProjectile.HandleParry(ParryInfo parry)` 签名中的 `ParryInfo` 结构在其他地方未定义
---
### D-07 · HurtBox 流程图声称有霸体检查但代码没有实现
**位置**`06_CombatModule.md §6 伤害流水线`流程图vs §5 HurtBox 代码
`§6` 流程图文字:
```
→ HurtBox.ReceiveDamage(info)
→ 检查无敌帧IgnoreIFrame flag
→ 检查霸体BreakLevel vs Poise ← 流程图列出此步骤
→ 计算 FinalDamage = RawDamage - Defense最低 1
```
`§5``HurtBox.ReceiveDamage()` 代码**完全没有霸体检查逻辑**,直接从无敌帧检查跳到护盾检查。
按 Design 54霸体检查PoiseLevel vs BreakLevel应该在 HurtBox 中完成,而不是在 `EnemyBase.TakeDamage()` 内部。
---
## 四、🟡 中等问题Medium—— 存在缺失或不清晰,实现时需补充
---
### D-08 · 墙壁力学实现细节严重不足
**位置**`05_PlayerModule.md §3 + §12 FSM 表格` vs `Design/26_WallMechanicsSystem.md`
Architecture 在 FSM 表格中列出了 `WallSlideState``WallJumpState`,但**没有任何详细实现描述**。
| 功能 | Architecture | Design 26要求实现|
|------|-------------|---------------------|
| 墙面检测 | §3每侧**单射线**`CheckWalls()` | **双射线**TopRay + BottomRay防止卡角 |
| 墙壁抓取 | 未提及 | `WallGrab` 机制——碰墙后自动抓取,**不需要持续按键** |
| 高度记录 | 未提及 | `wallGrabY` 记录抓取时 Y 坐标,防止无限蹬墙高度增益 |
| 跳墙类型 | 未说明 | 两种:**背墙跳**(同方向弹出)和**对墙跳**(反方向飞离),有不同速度向量 |
| 专用组件 | 无 | `PlayerWallDetector` 组件(独立,保持 PlayerMovement 干净)|
| 配置 SO | §15 中有 `WallSlideSpeed``WallJumpForce` 等 | 应独立为 `WallMechanicsConfigSO` |
`WallSlideState``WallJumpState``OnStateEnter``OnStateUpdate``OnStateExit` 实现**完全缺失**。
---
### D-09 · ParryableProjectile 订阅机制未说明清楚
**位置**`06_CombatModule.md §7`
代码中出现两种订阅机制:
- `ParrySystem.OnParrySuccess += HandleParry`C# 静态事件或实例委托)
- `ParrySystem` 类中 `_onParrySuccess``VoidEventChannelSO`ScriptableObject 事件频道)
架构文档没有说明 `ParrySystem.OnParrySuccess` 是一个 C# 事件而非 SO 频道,且与 `_onParrySuccess` 字段的关系未交代。`HandleParry(ParryInfo parry)``ParryInfo` 结构体在整个架构文档中均未定义。
---
### D-10 · DamageInfo 与 Design 定义不完全对齐
**位置**`06_CombatModule.md §1` vs `Design/04_CombatSystem.md §2`
| 对比项 | Architecture | Design |
|--------|-------------|--------|
| 结构特性 | `struct`,有可变 `Amount` 字段 | "**只读值类型**,不可修改" |
| 中间值字段 | 添加了 `Amount`(流水线中间量)| 无 `Amount`,只有 `RawDamage` / `FinalDamage` |
| `SkillId` 字段 | 有 | 无Design 版本较简洁)|
Architecture 的版本**更详细**Builder 模式、`Amount` 流水线字段、`SkillId`),技术上是对 Design 的合理扩展,但与 Design 声称的"不可修改"矛盾。需要明确说明这是架构层面的有意设计决策。
---
## 五、🔵 轻微问题Minor—— 不影响实现正确性,但影响文档准确性
---
### D-11 · 覆盖率索引节号标注错误
**位置**`00_CoverageIndex.md` 中关于 `16_SupportingModules` 的引用
| 覆盖索引声称 | 实际节号(`16_SupportingModules.md`|
|-------------|--------------------------------------|
| §7 = AnalyticsManager | **错误** — §7 是"支撑事件频道清单" |
| §8 = SpeedrunTimer | **错误** — §8 是 AnalyticsManager |
| — | §9 = SpeedrunTimer索引中未提及|
---
### D-12 · ShieldComponent.AbsorbDamage 签名与 Design 不同
**位置**`20_ShieldModule.md §5 IShieldable` vs `Design/30_ShieldMechanicsSystem.md`
- **Architecture**`void AbsorbDamage(ref DamageInfo info)`(通过 ref 修改 Amount穿透走事件总线
- **Design**:返回 `int`(穿透量),由调用方处理
Architecture 版本是更符合 C# 规范的架构设计,但应在文档中注明这是对 Design 的有意修改,而非与 Design 保持一致。
---
## 六、✅ 经人工核实正确的内容
以下内容经过手动比对,与对应 Design 文档基本一致:
| 架构文档 | 核实内容 |
|----------|----------|
| `07_EnemyModule.md §14` | LootSystem`LootTableSO``LootResolver``LootPickup` 均完整定义 |
| `09_ProgressionModule.md §2` | `AbilityGate` 系统存在且逻辑完整 |
| `09_ProgressionModule.md §7.5` | `ToolSlotManager``ToolHUD` 存在 |
| `14_NarrativeModule.md §5-7` | `EventChainSO``EventChainManager``CutsceneSO``CutsceneTrigger` 均完整 |
| `16_SupportingModules.md §4` | `DebugCheatSystem``DebugCheatOverlay` 均存在 |
| `16_SupportingModules.md §8-9` | `AnalyticsManager``SpeedrunTimer` 均存在 |
| `20_ShieldModule.md §1-9` | 整体架构完整IShieldable、ShieldComponent、ShieldConfigSO、SaveData 集成)|
| `21_LiquidPuzzleModule.md` | LiquidZone/SwimState、PuzzleSwitch/PuzzleReceiver/PuzzleWire、TutorialManager 均完整 |
| `06_CombatModule.md §3` | `DamageSourceSO` 结构完整,含 `sourceId``skillId``ComboWindowDuration` |
| `06_CombatModule.md §4` | `HitBox` 寄宿规则(武器/技能 Prefab 子节点)设计合理,与 Design 一致 |
| `06_CombatModule.md §14` | `IBreakable`/`BreakConditionSO` 机关交互系统设计完整 |
---
## 七、未能全面核实的文档
以下架构文档在本次审查中未进行深度手动比对,结论依赖 `00_CoverageIndex.md` 的自评:
| 架构文档 | 对应 Design 文档 | 风险评估 |
|----------|-----------------|---------|
| `08_WorldModule.md` | Design 08, 10, 17, 27, 29, 32, 34, 37, 42-44, 46, 48, 50, 52多达 14 份) | ⚠️ 范围最广,建议优先补充核实 |
| `10_UIModule.md` | Design 11, 21-25, 33, 53, 57, 70 | ⚠️ UI 相关 Design 较多,节号/字段有错误风险 |
| `11_AudioModule.md` | Design 12_AudioSystem | 🟢 FMOD 集成逻辑相对独立,风险较低 |
| `12_SaveModule.md` | Design 31_SaveDataSchema_Unified | ⚠️ SaveMigrator 细节值得核实 |
| `17_CameraModule.md` | Design 02_CameraSystem | 🟢 Cinemachine 配置,风险较低 |
| `18_VFXFeedbackModule.md` | Design 07_FeedbackSystem, 41_VFXArchitecture | ⚠️ Feel/MoreMountains 集成,参数可能有出入 |
| `22_QuestChallengeModule.md` | Design 38_QuestSystem, 39_ChallengeRoomSystem | ⚠️ 建议核实 |
| `23_BossSkillModule.md` | Design 19_BossPatternLibrary, 47_BossSkillSystem | ⚠️ Boss 技能系统复杂,建议核实 |
| `24_AnimEventModule.md` | Design 20_AnimationEventSystem | 🟢 事件名称列表性质,风险较低 |
---
## 八、修正优先级与行动计划
### P0立即修正影响一切基于此的实现
1. **修正 `06_CombatModule.md §2 BreakLevel` 枚举**:按 Design 54 改为 `{None=0, Light=1, Medium=2, Heavy=3, Breaker=4}`,并新增独立的 `PoiseLevel {None=0, Light=1, Medium=2, Heavy=3, Unbreakable=100}` 枚举
2. **重写 `06_CombatModule.md §13 PoiseSystem`**:按 Design 54 改为等级比较系统,覆盖玩家和敌人,新增 `IPoiseSource``PoiseWindowConfig``PoiseOverrideTableSO`
3. **统一 `HurtBox.ReceiveDamage()` 版本**:确定以 `20_ShieldModule §2` 版本为准(护盾命中总 return穿透走事件删除 `06_CombatModule §5` 中护盾后的直接 TakeDamage 路径
### P1高优先级修正影响弹反/战斗核心功能)
4. **修正 `06_CombatModule.md §9 ParryConfigSO`**:更新所有数值(窗口 0.28s,灵力 33/+50反击倍率 3.0),添加 Startup/EndLag/CounterWindow/BulletTime 字段
5. **扩展 `06_CombatModule.md §8 ParrySystem`**:添加 5 阶段状态机Startup→Active→ParrySuccess→CounterWindow→Inactive定义 `HandleSuccessfulParry()` 方法或统一为 `TryParryDamage()` 路径
6. **修正 `_onParrySuccess` 事件类型**:从 `VoidEventChannelSO` 改为 `DamageInfoEventChannelSO`
7. **修正 `20_ShieldModule.md §8`**:将 `HandleSuccessfulParry()` 改为架构中实际存在的方法名
### P2中优先级实现时需补充
8. **补充 `05_PlayerModule.md` 墙壁力学实现细节**:添加 `WallSlideState`/`WallJumpState` 的详细实现,双射线检测,`WallGrab` 机制,`wallGrabY` 高度记录,两种跳墙方式,`PlayerWallDetector` 组件
9. **在 `06_CombatModule.md §5 HurtBox` 代码中补充霸体检查逻辑**(使其与 §6 流程图一致)
10. **定义 `ParryInfo` 结构体**(供 `ParryableProjectile.HandleParry` 使用)
### P3轻微不影响实现
11. **修正 `00_CoverageIndex.md` 节号**`§7` 为事件频道清单,`§8` 为 AnalyticsManager`§9` 为 SpeedrunTimer
12. **在架构文档中注明** `DamageInfo.Amount` 字段和 `AbsorbDamage(ref DamageInfo)` 签名是对 Design 的有意架构决策(而非错误)
---
## 九、审查结论
`Docs/Architecture/` 在**覆盖广度**上基本达到 Design 文档的全部技术范围,但**"架构完整度 100%"的自评不符合实际**
- **战斗核心三角**HurtBox 伤害流水线 × 弹反系统 × 霸体系统)存在**多处相互矛盾或错误**的定义
- **PoiseSystem** 是最严重的设计偏差——Architecture 和 Design 是两套根本不同的机制直接影响玩家霸体、攻击打断、Boss 超甲等核心手感
- **ParryConfigSO** 的所有数值均错误,弹反手感将完全不符合设计意图
- **HurtBox 双版本矛盾**是最危险的隐患——如不统一,护盾命中将产生双倍伤害 Bug
建议在正式开始实现战斗模块之前,完成 P0 和 P1 级别的修正。