docs: 记录 3 个潜在 bug 的修复状态(对齐 dc05eea)

- 审计报告 D 节 + G.2 表标注 D1/D2/D5 已修复(待运行时验收),修正 D1
  修复方案为「单选枚举 + ==」(复核发现设计器 core_tab 以下标写入 feature_tags,
  不宜改 2 的幂位标志)
- architecture_design ADR-R5-N2 与 core_wand §1 的现状 callout 同步更新为已修复

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-20 14:53:27 +08:00
co-authored by Claude Opus 4.8
parent dc05eeada7
commit 5e3d80ad85
3 changed files with 12 additions and 9 deletions
+2 -1
View File
@@ -56,7 +56,8 @@ extends Resource
## Core 特性标签,驱动特殊执行规则 ## Core 特性标签,驱动特殊执行规则
## ⚠️ 实现现状(2026-07-20):代码实为 `@export var feature_tags: int = 0`int 位掩码,非 Array[String]); ## ⚠️ 实现现状(2026-07-20):代码实为 `@export var feature_tags: int = 0`int 位掩码,非 Array[String]);
## CoreFeatureTag 常量为 int 1..5 并用 `&` 判定——值非 2 的幂有位冲突 bug(见审计 D 节)。 ## CoreFeatureTag 常量为 int 1..5(单选枚举,设计器 OptionButton 下标写入);
## 判定已由 `&` 修复为 `==`dc05eea,原 `&` 因非 2 的幂会串扰;见审计 D 节)。
@export var feature_tags: Array[String] = [] @export var feature_tags: Array[String] = []
## 图标路径 ## 图标路径
+1 -1
View File
@@ -2944,7 +2944,7 @@ func reset() -> void:
> **结论**:所有 Feature Tag 字符串必须通过 `CoreFeatureTag` 常量访问,禁止在业务代码中写裸字符串。 > **结论**:所有 Feature Tag 字符串必须通过 `CoreFeatureTag` 常量访问,禁止在业务代码中写裸字符串。
> **⚠️ 实现现状 (2026-07-20 审计)**:代码**未按本节的 `String` 常量 + `in` 判定实现**。`core_feature_tag.gd` 实为 **`int` 常量**PERSISTENT_MEMORY=1, DUAL_STREAM=2, ALWAYS_CAST_LAST=3, SHUFFLE_DECK=4, INFINITE_SPELLS=5),`core.feature_tags` 为 `int` 位掩码,用 `&` 判定。**⚠️ 潜在 bug**:这些值非 2 的幂,`&` 会串扰(如 `ALWAYS_CAST_LAST(3) & PERSISTENT_MEMORY(1) = 1` 误判持久内存;当前仅 `wand_memory=1` 未触发)。修复建议:改真·2 的幂位标志(1,2,4,8,16),或回退到本节的 String + `in`(后者天然无冲突)。详见 [审计报告 D 节](../../docs_dev/doc_code_audit_2026-07-20.md)。 > **⚠️ 实现现状 (2026-07-20 审计)**:代码**未按本节的 `String` 常量 + `in` 判定实现**。`core_feature_tag.gd` 实为 **`int` 常量**PERSISTENT_MEMORY=1, DUAL_STREAM=2, ALWAYS_CAST_LAST=3, SHUFFLE_DECK=4, INFINITE_SPELLS=5),`core.feature_tags` 为 `int` 位掩码。**feature_tags 实为单选枚举**(游戏设计器 `core_tab.gd` 以 OptionButton 下标 0..5 写入,下标即等于常量值)。原代码用位与 `&` 判定,因常量非 2 的幂会串扰(`3 & 1 = 1` 误判持久内存)。✅ **已修复** (`fix/audit-latent-bugs` dc05eea):判定改为 `==`,常量保持 1..5(未改位标志以免与设计器 desync)。详见 [审计报告 D 节](../../docs_dev/doc_code_audit_2026-07-20.md)。
```gdscript ```gdscript
# core_feature_tag.gd (Autoload: CoreFeatureTag) # core_feature_tag.gd (Autoload: CoreFeatureTag)
+9 -7
View File
@@ -95,11 +95,13 @@
## D. ⚠️ 潜在 Bug / 风险(审计附带发现,建议单独修) ## D. ⚠️ 潜在 Bug / 风险(审计附带发现,建议单独修)
1. **`CoreFeatureTag` 位运算冲突(真实 latent bug)**:常量是 `1,2,3,4,5`(非 2 的幂),却用位与 `&` 判断持久内存。`ALWAYS_CAST_LAST(3) & PERSISTENT_MEMORY(1) = 1` → 若某 Core 设 `feature_tags=3` 会被误判为持久内存。当前仅 `wand_memory=1` 未触发。类型上也与文档 ADR-R5-N2(`architecture_design.md:2929` 示例为 `String` 常量 + `in core.feature_tags` 判定)相反——注:`core_feature_tag.gd:2` 自身头注把 ADR-R5-N2 解读为"禁止裸字符串",与文档正文的 String 方案存在张力。修复建议:改为真·2 的幂位标志(1,2,4,8,16),或改回 String + `in`(后者天然无冲突)。`core_feature_tag.gd:5-9`, `spell_evaluator.gd:41,324` > ✅ **修复状态 (2026-07-20)****D1 / D2 / D5 已在分支 `fix/audit-latent-bugs`commit `dc05eea`)实现修复**,静态审查 + grep 校验通过,**待 Godot 运行时验收**。D3SpatialGridCs 参数分叉)与 D4LOD `_visible_flags` 从不置 1)暂未处理——二者分别依赖尚未接线的 C# 与尚未启用的 LOD,风险潜伏、非当前活跃路径。
2. **`modifier_pierce_plus` 是空操作**:玩家能在商店买到,但 `_apply_modifier` 不识别 `pierce``CastStats` 无该字段 → **买了没效果**`spell_evaluator.gd:488-501`, `cast_stats.gd:6-13`
1. **`CoreFeatureTag` 位运算冲突(真实 latent bug)**:常量是 `1,2,3,4,5`(非 2 的幂),却用位与 `&` 判断持久内存。`ALWAYS_CAST_LAST(3) & PERSISTENT_MEMORY(1) = 1` → 若某 Core 设 `feature_tags=3` 会被误判为持久内存。当前仅 `wand_memory=1` 未触发。类型上也与文档 ADR-R5-N2(`architecture_design.md:2929` 示例为 `String` 常量 + `in core.feature_tags` 判定)相反——注:`core_feature_tag.gd:2` 自身头注把 ADR-R5-N2 解读为"禁止裸字符串",与文档正文的 String 方案存在张力。✅ **已修复** (`dc05eea`):复核发现 `feature_tags` 实为**单选枚举**——游戏设计器 `core_tab.gd` 以 OptionButton 下标 0..5 写入,下标即等于常量值。故修法是把判定从 `&` 改为 **`==`**、常量保持 1..5(未改 2 的幂位标志,以免与设计器下标 desync);串扰消除。若将来要一个 Core 同时带多个特性,再改为位标志 + 设计器多选。待运行时验收。`core_feature_tag.gd:5-9`, `spell_evaluator.gd:41,324`
2. **`modifier_pierce_plus` 是空操作**:玩家能在商店买到,但 `_apply_modifier` 不识别 `pierce``CastStats` 无该字段 → **买了没效果**`spell_evaluator.gd:488-501`, `cast_stats.gd:6-13`**已修复** (`dc05eea`):新增 `CastStats.pierce_add``_apply_modifier` 累加、`_push_projectile` 叠加到 ACTION 自带 pierce。
3. **`SpatialGridCs` 与 GDScript 版参数分叉**C# 版 `GridWidth=64` 无 offset,负坐标全 clamp 到 0GDScript 版 128 + offset 4096 支持负坐标。C# 一旦接线,负坐标实体会塌到边缘格且覆盖减半。`SpatialGridCs.cs:42-43,64-67` 3. **`SpatialGridCs` 与 GDScript 版参数分叉**C# 版 `GridWidth=64` 无 offset,负坐标全 clamp 到 0GDScript 版 128 + offset 4096 支持负坐标。C# 一旦接线,负坐标实体会塌到边缘格且覆盖减半。`SpatialGridCs.cs:42-43,64-67`
4. **敌人 LOD 剔除失效**`_visible_flags` 从不置 1 → `sync_node_positions` 永不同步;屏外低频分离力(`_offscreen_sep_counter` 自增后丢弃)未实现。`enemy_manager.gd:25,76-79,312-316` 4. **敌人 LOD 剔除失效**`_visible_flags` 从不置 1 → `sync_node_positions` 永不同步;屏外低频分离力(`_offscreen_sep_counter` 自增后丢弃)未实现。`enemy_manager.gd:25,76-79,312-316`
5. **战前无 Deck 防呆校验**:可携带空 / 纯 Modifier 卡组进战斗(`game_design §5.1` 要求拦截并提示"法术塔无法开火")。`combat_manager.gd:220-228` 5. **战前无 Deck 防呆校验**:可携带空 / 纯 Modifier 卡组进战斗(`game_design §5.1` 要求拦截并提示"法术塔无法开火")。`combat_manager.gd:220-228`**已修复** (`dc05eea`):新增 `CombatManager.has_castable_action()`,商店"下一波"按钮校验,无 ACTION 时显示 `SHOP_NEED_ACTION`(四语)并阻止进入。
--- ---
@@ -162,10 +164,10 @@
| 分歧 | 类型 | | 分歧 | 类型 |
|---|---| |---|---|
| `CoreFeatureTag` 位运算冲突(1..5 非 2 的幂)| **Bug**:改真·位标志或改回 String+`in` | | `CoreFeatureTag` 位运算冲突(1..5 非 2 的幂)| **Bug** ✅已修复(dc05eea):判定改 `==`(单选枚举)|
| `modifier_pierce_plus` 空操作(可购买无效果)| **Bug**:接线 pierce 到 CastStats/_apply_modifier | | `modifier_pierce_plus` 空操作(可购买无效果)| **Bug** ✅已修复(dc05eea):接线 pierce 到 CastStats/_apply_modifier |
| MAX_OPS 硬编码 `×5` 不读 cpu_limit | **Bug/缺口**CPU 词条对施法预算无影响 | | MAX_OPS 硬编码 `×5` 不读 cpu_limit | **Bug/缺口**CPU 词条对施法预算无影响(未修)|
| 战前无 Deck 防呆校验 | **缺口**:可带纯 Modifier 卡组进战斗 | | 战前无 Deck 防呆校验 | **缺口** ✅已修复(dc05eea)has_castable_action() + 商店校验 |
| Mana 系统 / 元进展 / 属性词条(4/5) / Boss 阶段·抗性 / 商店 B·C 货架 / 5 个 Core 特性标签(4/5) / MATRIX 增压触发 / 连锁弹跳 / 轨迹修正 / 元素催化 / 里程碑·NG+·通关 / TutorialManager·渐进解锁·靶场 / 归航 / DamageNumber / LOD 剔除 | **功能待实现**(设计核心,非文档错误)| | Mana 系统 / 元进展 / 属性词条(4/5) / Boss 阶段·抗性 / 商店 B·C 货架 / 5 个 Core 特性标签(4/5) / MATRIX 增压触发 / 连锁弹跳 / 轨迹修正 / 元素催化 / 里程碑·NG+·通关 / TutorialManager·渐进解锁·靶场 / 归航 / DamageNumber / LOD 剔除 | **功能待实现**(设计核心,非文档错误)|
**🟡 中性 —— 纯陈旧或文档自相矛盾,改文档即可(不改代码)** **🟡 中性 —— 纯陈旧或文档自相矛盾,改文档即可(不改代码)**