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

18 KiB
Raw Permalink Blame History

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 的比较逻辑):

// 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 实现,提供 CurrentPoiseLevelGetPoiseWindow()
  • PoiseWindowConfig 结构体(每个动画状态/技能的霸体等级 + 起止时间窗口)
  • PoiseOverrideTableSO(游戏资产,细粒度控制特定来源 vs 特定目标的打断规则)
  • DamageSourceSO 中的 BreakLevel 字段应对应正确的枚举值范围

D-02 · ParryConfigSO 数值与字段全部错误

位置06_CombatModule.md §9 vs Design/05_ParrySystem.md §9

// 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

// 护盾处理后,若 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 的实现"

// 护盾处理后总是 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.OnParrySuccessSO 事件)→ ShieldComponent.OnParrySuccess()"
  • 20_ShieldModule §8 代码ParrySystem.HandleSuccessfulParry() 内直接 TryGetComponent<ShieldComponent>() 调用

两种集成方式并存,需要统一。


D-06 · OnParrySuccess 事件频道类型错误

位置06_CombatModule.md §8 vs Design/05_ParrySystem.md §10

// 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

§5HurtBox.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 表格中列出了 WallSlideStateWallJumpState,但没有任何详细实现描述

功能 Architecture Design 26要求实现
墙面检测 §3每侧单射线CheckWalls() 双射线TopRay + BottomRay防止卡角
墙壁抓取 未提及 WallGrab 机制——碰墙后自动抓取,不需要持续按键
高度记录 未提及 wallGrabY 记录抓取时 Y 坐标,防止无限蹬墙高度增益
跳墙类型 未说明 两种:背墙跳(同方向弹出)和对墙跳(反方向飞离),有不同速度向量
专用组件 PlayerWallDetector 组件(独立,保持 PlayerMovement 干净)
配置 SO §15 中有 WallSlideSpeedWallJumpForce 应独立为 WallMechanicsConfigSO

WallSlideStateWallJumpStateOnStateEnterOnStateUpdateOnStateExit 实现完全缺失


D-09 · ParryableProjectile 订阅机制未说明清楚

位置06_CombatModule.md §7

代码中出现两种订阅机制:

  • ParrySystem.OnParrySuccess += HandleParryC# 静态事件或实例委托)
  • ParrySystem 类中 _onParrySuccessVoidEventChannelSOScriptableObject 事件频道)

架构文档没有说明 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

  • Architecturevoid AbsorbDamage(ref DamageInfo info)(通过 ref 修改 Amount穿透走事件总线
  • Design:返回 int(穿透量),由调用方处理

Architecture 版本是更符合 C# 规范的架构设计,但应在文档中注明这是对 Design 的有意修改,而非与 Design 保持一致。


六、 经人工核实正确的内容

以下内容经过手动比对,与对应 Design 文档基本一致:

架构文档 核实内容
07_EnemyModule.md §14 LootSystemLootTableSOLootResolverLootPickup 均完整定义
09_ProgressionModule.md §2 AbilityGate 系统存在且逻辑完整
09_ProgressionModule.md §7.5 ToolSlotManagerToolHUD 存在
14_NarrativeModule.md §5-7 EventChainSOEventChainManagerCutsceneSOCutsceneTrigger 均完整
16_SupportingModules.md §4 DebugCheatSystemDebugCheatOverlay 均存在
16_SupportingModules.md §8-9 AnalyticsManagerSpeedrunTimer 均存在
20_ShieldModule.md §1-9 整体架构完整IShieldable、ShieldComponent、ShieldConfigSO、SaveData 集成)
21_LiquidPuzzleModule.md LiquidZone/SwimState、PuzzleSwitch/PuzzleReceiver/PuzzleWire、TutorialManager 均完整
06_CombatModule.md §3 DamageSourceSO 结构完整,含 sourceIdskillIdComboWindowDuration
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 改为等级比较系统,覆盖玩家和敌人,新增 IPoiseSourcePoiseWindowConfigPoiseOverrideTableSO
  3. 统一 HurtBox.ReceiveDamage() 版本:确定以 20_ShieldModule §2 版本为准(护盾命中总 return穿透走事件删除 06_CombatModule §5 中护盾后的直接 TakeDamage 路径

P1高优先级修正影响弹反/战斗核心功能)

  1. 修正 06_CombatModule.md §9 ParryConfigSO:更新所有数值(窗口 0.28s,灵力 33/+50反击倍率 3.0),添加 Startup/EndLag/CounterWindow/BulletTime 字段
  2. 扩展 06_CombatModule.md §8 ParrySystem:添加 5 阶段状态机Startup→Active→ParrySuccess→CounterWindow→Inactive定义 HandleSuccessfulParry() 方法或统一为 TryParryDamage() 路径
  3. 修正 _onParrySuccess 事件类型:从 VoidEventChannelSO 改为 DamageInfoEventChannelSO
  4. 修正 20_ShieldModule.md §8:将 HandleSuccessfulParry() 改为架构中实际存在的方法名

P2中优先级实现时需补充

  1. 补充 05_PlayerModule.md 墙壁力学实现细节:添加 WallSlideState/WallJumpState 的详细实现,双射线检测,WallGrab 机制,wallGrabY 高度记录,两种跳墙方式,PlayerWallDetector 组件
  2. 06_CombatModule.md §5 HurtBox 代码中补充霸体检查逻辑(使其与 §6 流程图一致)
  3. 定义 ParryInfo 结构体(供 ParryableProjectile.HandleParry 使用)

P3轻微不影响实现

  1. 修正 00_CoverageIndex.md 节号§7 为事件频道清单,§8 为 AnalyticsManager§9 为 SpeedrunTimer
  2. 在架构文档中注明 DamageInfo.Amount 字段和 AbsorbDamage(ref DamageInfo) 签名是对 Design 的有意架构决策(而非错误)

九、审查结论

Docs/Architecture/覆盖广度上基本达到 Design 文档的全部技术范围,但**"架构完整度 100%"的自评不符合实际**

  • 战斗核心三角HurtBox 伤害流水线 × 弹反系统 × 霸体系统)存在多处相互矛盾或错误的定义
  • PoiseSystem 是最严重的设计偏差——Architecture 和 Design 是两套根本不同的机制直接影响玩家霸体、攻击打断、Boss 超甲等核心手感
  • ParryConfigSO 的所有数值均错误,弹反手感将完全不符合设计意图
  • HurtBox 双版本矛盾是最危险的隐患——如不统一,护盾命中将产生双倍伤害 Bug

建议在正式开始实现战斗模块之前,完成 P0 和 P1 级别的修正。