docs(roadmap): 新增 E7-⑥ 计算模块化重构(用户 2026-07-31 指定的架构方向)
原则:凡涉及计算的都由专门功能模块负责,便于测试与配置。 AttributeFormula 是已验证的模板(纯静态零依赖,故不启动游戏就能单元断言)。 盘点出计算散落 8 处、仅 1 处已模块化。最严重的是伤害被劈成两半分居两个文件, 且两处都在扣护甲——目前不重复扣仅因调用点特意传 armor=0,而该约定只存在于 调用点,两个函数各自看都是完整公式。连击 +2%/层 也硬编码在管理器里。 记录立项时必须先决定的设计问题与热路径风险,避免实现期顺手定。 顺序:货架 C(含 PriceFormula)先做,本项独立立项。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -170,7 +170,39 @@ E6-a 玩家无敌帧(i-frames) ← 先行小项:Boss 弹幕公平性前置,
|
||||
|
||||
**依赖**:无。各项可独立作为"缝隙任务"穿插。
|
||||
|
||||
**切分(独立小项)**:① DamageNumber 飘字(S,高手感回报);② 敌人 LOD 屏内剔除 + 屏外低频分离(S~M);③ 内容名 tr 化 + 裸中文静态检查(S,i18n 收尾);④ UI 关键面板 `.tscn` 化(M,可选);⑤ C# 热路径落地(L,仅当 GDScript 达性能瓶颈时;当前 500 敌 3.6% 预算,非必需)。
|
||||
**切分(独立小项)**:① DamageNumber 飘字(S,高手感回报);② 敌人 LOD 屏内剔除 + 屏外低频分离(S~M);③ 内容名 tr 化 + 裸中文静态检查(S,i18n 收尾);④ UI 关键面板 `.tscn` 化(M,可选);⑤ C# 热路径落地(L,仅当 GDScript 达性能瓶颈时;当前 500 敌 3.6% 预算,非必需);⑥ **计算模块化重构(M~L,2026-07-31 立项确认,用户指定)** —— 见下。
|
||||
|
||||
### E7-⑥ 计算模块化重构(用户 2026-07-31 指定的架构方向)
|
||||
|
||||
**原则**:凡涉及计算的都由**专门功能模块**负责,便于测试、配置,符合「专门模块负责专门功能」的设计理念。`AttributeFormula`(E3-① 建)是已验证的模板:`class_name` 纯静态、零依赖(不碰 autoload/场景树),因此**不启动游戏就能单元断言**,改公式立刻回归。
|
||||
|
||||
**现状盘点(代码复核 2026-07-31)**:计算散落 8 处,仅 1 处已模块化。
|
||||
|
||||
| 计算 | 现在住在哪 | 状态 |
|
||||
| :-- | :-- | :-- |
|
||||
| 属性合成 | `AttributeFormula` | ✅ 已模块化(模板) |
|
||||
| 伤害合成(一半) | `DamageContext.calc_damage`(`damage_context.gd:26`) | ⚠️ 与上下文数据混在同一个类 |
|
||||
| 伤害合成(另一半) | `EnemyManager.apply_damage:285-289` | ❌ 内联在管理器 |
|
||||
| 经验曲线 | `PlayerStats.xp_for_level` | 纯静态但与状态混住 |
|
||||
| 分数 | `EndlessRecords.compute_score` | 同上 |
|
||||
| 刷新费用 | `ShopManager.get_reroll_cost` | ❌ 内联 |
|
||||
| 蓝耗 + heat 乘子 | `SpellEvaluator._charge_mana` | ❌ 内联在法术 VM |
|
||||
| 波次缩放 | `WaveManager:61,62,76` | ❌ 内联三处 |
|
||||
|
||||
**最严重的一处 —— 伤害被劈成两半,分别在两个文件里,且两处都在扣护甲**:
|
||||
```gdscript
|
||||
# damage_context.gd:26
|
||||
base_damage × mult × (1 − resistance) − armor × (1 − pierce_rate)
|
||||
# enemy_manager.gd:285-289 ← 又算了一遍
|
||||
damage × (1 + combo_stacks × 0.02) − armor # 保底 1
|
||||
```
|
||||
目前**没有**重复扣,因为 `apply_damage_from_context` 特意传 `calc_damage(0.0, res)` 把 armor 置 0 留给下游 —— 但该约定只存在于调用点,两个函数各自看都是完整公式。想知道「这一击到底怎么算」必须同时读两个文件并知道那条不成文约定。连击的 `+2%/层` 也硬编码在管理器里,不在任何数据文件中。
|
||||
|
||||
**立项时必须先决定的设计问题**(都不该在实现期顺手定):伤害那两半如何合并、`calc_damage` 的 `armor` 参数语义要不要改、连击 `+2%` 进哪个数据文件、DOT 伤害(`status_manager.gd:116` 直调 `apply_damage`,绕过 context 故不享元素抗性,E1-① 记录的已知限制)是否借此一并归位。
|
||||
|
||||
**风险**:触碰全游戏最热路径(500 敌 + 1500 弹),必须有迁移前后的基准对比。
|
||||
|
||||
**依赖**:无硬依赖。`PriceFormula`(E3-② 货架 C 建)会成为第二个已模块化的例子,可与 `AttributeFormula` 一起确立命名/签名/测试惯例,再据此重构其余 7 处。
|
||||
|
||||
**验收标准**:飘字随命中显示;屏外敌人低频更新且 FPS 提升;4 语言无裸中文;MCP/截图实测。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user