docs: 整理文档目录并对齐代码现状

- 将开发过程/归档文档迁至 docs_dev/(development_plan、certification_checklist、
  已废弃的 Cocos 架构草案 archived_cocos_architecture_draft),并修正全部跨引用
- 新增根 README.md(项目介绍,暂定名 Spellforge)与 docs_dev/README.md 索引
- 新增 docs_dev/doc_code_audit_2026-07-20.md:文档 vs 代码交叉审计报告(经 6
  路对抗性复核,零证伪),含「代码更优 / 文档更优 / 中性」判定汇总
- 在 docs/ 各设计·技术·机制文档就地加「实现现状 (2026-07-20)」callout:
  追认代码更优实现(纯 JSON 数据驱动、SpatialGrid-only 碰撞、MultiMesh 单档、
  存档选最新槽等),订正陈旧/矛盾内容(.tres→JSON、Boss HP/阈值/波次、EventID、
  StatusManager.apply 签名等),标记未实现功能(C# 热路径、Mana、元进展、
  Boss 阶段/抗性、Tutorial、轨迹/连锁/催化等)与 latent bug(CoreFeatureTag 位运算、
  pierce 空操作、MAX_OPS 不读 cpu_limit)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-20 14:35:55 +08:00
co-authored by Claude Opus 4.8
parent 7bcc0026e0
commit ad2f4c0bc6
20 changed files with 446 additions and 67 deletions
+135
View File
@@ -0,0 +1,135 @@
# Spellforge(万法熔炉)
> **"Noita 遇上 Brotato"** —— 快节奏割草 × 深度法术编程的 Roguelite 弹幕射击游戏
>
> Godot 4.6 (Mono) · GDScript 热路径 + C# · SoA / ECS-Lite 架构
被困异次元的"土豆工匠",捡到的不是武器,而是**逻辑碎片与弹头**。你要像程序员一样**"编写"你的子弹**——用核心(法杖)、修正器、触发器和逻辑门,组装出毁天灭地的魔法武器,抵御无穷波次的怪物潮。
> 📛 **命名说明**`Spellforge / 万法熔炉` 为当前候选名(`project.godot` 中工程名仍暂为 `Rogue`)。定稿后同步更新此处与 `application/config/name`。
---
## ✨ 核心玩法:法术管道 (The Spell Pipeline)
武器由一个 **核心 (Core)** 和若干 **法术节点 (Spell Node)** 组成,四类节点自由排列组合,实现近乎图灵完备的武器逻辑:
| 类型 | 作用 | 示例 |
|:---|:---|:---|
| **ACTION** 动作 | 实际产生的飞行物 | 魔法弹、黑洞、治疗雾、召唤炮台 |
| **MODIFIER** 修正 | 改变下一个动作 | 伤害+、弹道折射、多重施法、正弦轨迹 |
| **TRIGGER** 触发 | 逻辑传递(子母弹) | 击中触发、定时触发 |
| **LOGIC** 逻辑门 | 自动化灵魂 | `IF_HP_LOW``IF_ENEMY_CLOSE``LOOP` |
深度构建维度:
- **拓扑构建** —— Core 不只是列表,还有 `LINEAR` / `MATRIX`(邻接加成)/ `CIRCUIT`(电路分叉)三种插槽拓扑
- **逻辑寄存器** —— 史诗核心提供跨帧持久寄存器,可搭出"蓄力计数器""击杀连击"
- **炼金共鸣** —— 特定元素法术相邻时自动质变合成(如 `水属性波` + `闪电链``等离子风暴`
**性能怪兽**:得益于 SoA + Spatial Grid,支持同屏 **1000+ 敌人**、**2000+ 独立弹幕**,实测 500 敌人 + 1500 子弹下模拟+渲染仅 ~0.6ms16.67ms 预算的 3.6%)。
---
## 🚀 快速上手
**前置**[Godot 4.6 **.NET/Mono 版**](https://godotengine.org/)(工程使用 C#,需 .NET SDK)。
```bash
# 1. 用 Godot 4.6 Mono 打开工程
# 直接打开项目根目录的 project.godot
# 2. 首次打开会自动构建 C# 程序集(Rogue.sln
# 3. 运行工程(F5
# 主场景:res://scenes/ui/splash.tscn
# 流程:Splash → 主菜单 → 战斗 → 商店 → 结算 → 排行榜
```
> 详细步骤见 [`docs/handbook/01_quickstart.md`](docs/handbook/01_quickstart.md)。
---
## 🧰 技术栈与架构
- **引擎**Godot 4.6 (Mono),渲染 D3D12,物理 Jolt
- **架构****ECS-Lite** —— ~35 个 Autoload 单例分层协作,EventBus + 整数 `EventID` 常量解耦
- **数据布局**SoAStructure of Arrays),`BulletManager` STRIDE=12、`EnemyManager` STRIDE=8,配合对象池零 GC
- **渲染**`MultiMeshInstance2D` 单批次绘制全部子弹/敌人,程序化着色器发光(`shaders/`
- **法术虚拟机**:两阶段架构 —— `compile_wand()`(装备/换牌时编译为 `CompiledDeck`+ `execute_compiled()`(每次施法执行线性化节点)
- **热路径**:当前跑 GDScript`csharp/` 下 C# 管理器(`BulletManagerCs` / `EnemyManagerCs` / `SpatialGridCs`)为骨架,供后续迁移
---
## 📂 项目结构
```
daihaoRogue/
├── project.godot 工程配置(Autoload 注册、编辑器插件)
├── scenes/
│ ├── ui/ splash / main_menu(启动与菜单)
│ └── main/ combat_s2(主战斗场景,唯一可玩入口)
├── scripts/
│ ├── autoloads/ 全局单例(EventID/EnemyManager/WaveManager…)
│ ├── core/ 基础数据结构
│ └── domain/
│ ├── spell_system/ 法术虚拟机(spell_evaluator.gd 等)
│ └── combat/ 游戏循环状态机
├── csharp/ C# 热路径管理器(骨架,含 .cs)
├── data/ ⭐ 纯数据驱动内容(JSON)
│ ├── spells.json cores.json enemies.json waves.json
│ └── balance.json resonance.json status_effects.json
├── shaders/ 子弹/敌人/地面网格程序化着色器
├── translations/ zh_CN / zh_TW / en / ja.po
├── assets/ 精灵 / UI 主题(目前几何占位)
├── addons/ 编辑器插件(见下)
├── docs/ 产品文档:设计 / 技术 / 机制 / 手册
└── docs_dev/ 开发过程 / 归档文档:开发计划 · 认证清单 · 早期草案
```
---
## 🎮 编辑器工具(零代码配置内容)
工程为策划/美术提供了 **@tool 编辑器插件**,所有游戏内容纯数据驱动(`data/*.json`),改内容无需碰代码:
| 插件 | 位置 | 功能 |
|:---|:---|:---|
| **🎮 游戏设计器** | `addons/game_designer/` · 底部面板 | 一站式:法术 / 敌人 / 波次 / Core / 平衡 / 共鸣 / 状态 共 7 个表单页 |
| **法术编辑器** | `addons/spell_editor/` | 单独的法术 meta 字段编辑(已并入设计器) |
| **Godot MCP** | `addons/godot_mcp/` | AI 辅助开发(截图 / 输入 / 场景检查服务) |
> 修改后需 **F5 重启**生效(内容在 `_ready()` 时加载)。用法见 [`docs/handbook/07_game_designer.md`](docs/handbook/07_game_designer.md)。
---
## 📖 文档导航
完整文档索引见 [`docs/README.md`](docs/README.md);开发/策划手册见 [`docs/handbook/`](docs/handbook/README.md)。
| 分类 | 关键文档 |
|:---|:---|
| **游戏设计** | [`game_design.md`](docs/design/game_design.md) · [`numerical_design.md`](docs/design/numerical_design.md) · [`core_wand_design.md`](docs/design/core_wand_design.md) |
| **技术架构** | [`architecture_design.md`](docs/technical/architecture_design.md) · [`implementation_plan.md`](docs/technical/implementation_plan.md) |
| **机制细节** | [`docs/mechanics/`](docs/mechanics/) —— 溯源 / 连锁 / 状态 / 召唤 / 环境场 |
| **开发计划** | [`development_plan.md`](docs_dev/development_plan.md)S0S6 垂直切片) · [`certification_checklist.md`](docs_dev/certification_checklist.md) —— 位于 [`docs_dev/`](docs_dev/)(开发过程/归档文档) |
> `docs/README.md` 末尾附有 **关键规范速查表(P6-N* / ADR-*)**,是跨切片实现约束的权威来源。
---
## 🏗️ 开发状态
采用"骨架垂直切片" S0–S6 推进。当前主体流程已可完整游玩:
-**完整游戏外壳**:Splash → 菜单 → 战斗 → 商店 → 结算 → Endless 排行榜,含存档(A/B 局内槽)、暂停、首启难度选择(FTUE)
-**核心战斗**:法术虚拟机(LINEAR/MATRIX/CIRCUIT 三拓扑 + LOGIC + 共鸣 + 召唤/地面场)、20 波内容 + W8/W20 多阶段 Boss、精英寻路
-**系统**:难度/音量/语言设置、4 语言本地化、程序化音效、MultiMesh 渲染 + 发光着色器、纯数据驱动 + 可视化编辑器
- 🚧 **待完善**:C# 热路径迁移(当前 GDScript)、正式美术/音频资源(现为几何占位 + 蜂鸣)、法术/Core/状态名的多语言化、Steam/Switch 平台认证项
> 详细进度与计划/代码差异见 `docs_dev/development_plan.md`。
---
## 📄 许可
尚未指定许可证(暂为私有工程)。如需开源发布,请在根目录添加 `LICENSE` 并在此说明。
+13 -5
View File
@@ -7,22 +7,30 @@
## 目录结构
```
docs/
docs/ 产品文档(设计规范 / 架构参考)
README.md 本文件,文档导航索引
design/ 游戏设计文档
technical/ 技术架构文档
mechanics/ 机制细节设计
plan/ 垂直切片开发计划与平台认证清单
handbook/ 开发者 / 策划手册
docs_dev/ 开发过程 / 归档文档(工程根目录,见下)
development_plan.md 垂直切片开发计划
certification_checklist.md 平台认证清单
archived_cocos_architecture_draft.md 早期 Cocos 架构草案(已废弃)
```
---
## 工程计划 (`plan/`)
## 工程计划与归档 (`../docs_dev/`)
> 开发过程/追踪与归档类文档已移出 `docs/`,统一存放于工程根目录的 [`docs_dev/`](../docs_dev/)。
| 文档 | 内容简述 |
| :--- | :--- |
| [development_plan.md](plan/development_plan.md) | S0–S6 骨架垂直切片、风险登记、验收与出口检查、跨切片约束、参考文档地图(与 `technical/` 架构对齐) |
| [certification_checklist.md](plan/certification_checklist.md) | Steam / Switch / 无障碍 / 发布前检查项,并映射到切片 |
| [development_plan.md](../docs_dev/development_plan.md) | S0–S6 骨架垂直切片、风险登记、验收与出口检查、跨切片约束、参考文档地图(与 `technical/` 架构对齐) |
| [certification_checklist.md](../docs_dev/certification_checklist.md) | Steam / Switch / 无障碍 / 发布前检查项,并映射到切片 |
| [archived_cocos_architecture_draft.md](../docs_dev/archived_cocos_architecture_draft.md) | 早期 Cocos Creator / TypeScript 架构草案(已废弃,权威架构见 `technical/` |
---
+8 -3
View File
@@ -54,8 +54,9 @@ extends Resource
@export var base_cast_delay: float = 0.25 # 基础施法后摇(乘算基准)
@export var base_recharge_time: float = 0.5 # 完整一轮打完后的充能时间
## Core 特性标签 (Array[String]),驱动特殊执行规则
## 例如: ["persistent_memory", "dual_stream", "shuffle_deck"]
## Core 特性标签,驱动特殊执行规则
## ⚠️ 实现现状(2026-07-20):代码实为 `@export var feature_tags: int = 0`int 位掩码,非 Array[String]);
## CoreFeatureTag 常量为 int 1..5 并用 `&` 判定——值非 2 的幂有位冲突 bug(见审计 D 节)。
@export var feature_tags: Array[String] = []
## 图标路径
@@ -92,7 +93,7 @@ extends Resource
| **ACTION** | **ACTION**(同 ID) | 完全相同的 ACTION 对齐 | 伤害 ×1.5`damage_mult +0.5` | "强化同类弹" |
| **ACTION** | **MODIFIER** | 任意 | 该 MODIFIER 效果额外再施加一次(等效双倍加成) | "增幅器加倍" |
| **MODIFIER** | **MODIFIER**(同 ID | 完全相同的 MODIFIER 对齐 | 修正值 ×2(平直叠加而非乘算) | "共鸣修正" |
| **ACTION** | **TRIGGER** | 任意 | 该 TRIGGER 的 `proc_rate ×1.5`(最大 1.0 | "增压触发" |
| **ACTION** | **TRIGGER** | 任意 | 该 TRIGGER 的 `proc_rate ×1.5`(最大 1.0 | "增压触发" ⚠️**未实现**(代码只实现 ACTION+ACTION / ACTION+MODIFIER / MODIFIER+MODIFIER 三行)|
| **LOGIC** | **任意** | 任意 | 无加成(LOGIC 节点不参与邻接计算) | 设计原则:逻辑层不受物理拓扑影响 |
| **空槽** | **任意** | 行 A 为空 | 无加成 | 空槽不传递邻接效果 |
@@ -150,6 +151,8 @@ extends Resource
| `infinite_spells` | 法力耗尽时不停止执行,但每发增加 1 点 HP 代价(需配合 `heavy_cost` 法术) | 传说 |
| `always_cast_last` | 无论 Deck 如何执行,最后一个插槽的法术在一轮结束时**必定**执行一次 | 稀有 |
> **⚠️ 实现现状 (2026-07-20 审计)**5 个特性标签中**只有 `persistent_memory` 实现**`dual_stream` / `shuffle_deck` / `infinite_spells` / `always_cast_last` 在代码里除常量定义外**无任何逻辑引用**`core_feature_tag.gd:6` 自注"S6 P1 实现")。下文对这 4 个标签的详细行为规范(P5-N2/P6-N7/P6-N12 等)均为目标设计。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
> **实现约束说明(P5-N2**
> - **`shuffle_deck`**:仅随机化**独立 ACTION 节点**的执行顺序;MODIFIER 节点始终与其紧接的 ACTION 视为原子单元整体移动,防止修正器与错误的动作配对,保持构建意图的确定性。UI 上以"卡组"为单位展示被打乱的顺序,而非单张卡牌。
> - **`dual_stream`**:两条执行流**各自独立计算 ops 消耗**,每条流的 MAX_OPS 上限 = `cpu_limit × MAX_OPS_PER_CPU / 2`(平均分配)。双流模式下单帧总指令数与单流相同,不额外增加运算力消耗;实际可用插槽从序列头尾各取一半,两条流不可互相访问对方的槽位。
@@ -220,6 +223,7 @@ extends Resource
# ── 阶段 1:编译(法杖装备/换牌时调用,结果缓存于 CompiledDeck)──────────────────
# 参数类型:raw_deck: SpellDeck(通过 deck.nodes[i] 访问节点序列,禁止传入 Array[SpellNode]
# ⚠️ 实现现状(2026-07-20):真实签名 compile_wand(core, raw_nodes: Array)——第 2 参是 Array 而非 SpellDeck
func compile_wand(core: CoreDefinition, raw_deck: SpellDeck) -> CompiledDeck:
match core.topology:
CoreDefinition.LINEAR:
@@ -234,6 +238,7 @@ func compile_wand(core: CoreDefinition, raw_deck: SpellDeck) -> CompiledDeck:
# ── 阶段 2:执行(每次施法时调用缓存的 CompiledDeck)────────────────────────────
# 必须接受 core: CoreDefinition 参数,用于读取 core.feature_tags 判断寄存器持久策略。
# 禁止将 feature_tags 复制到 SpellContextSpellContext 不持有 Core 引用;ctx.core_feature_tags 不存在)。
# ⚠️ 实现现状(2026-07-20):真实签名 execute_compiled(compiled, caster_id: int, spawn_pos: Vector2)——不传 ctx/corefeature_tags 从 CompiledDeck 编译期快照读取
func execute_compiled(compiled: CompiledDeck, ctx: SpellContext, core: CoreDefinition) -> void:
_run_deck(compiled, ctx) # SpellEvaluator 不感知拓扑,仅执行线性化节点序列
+15 -1
View File
@@ -131,6 +131,9 @@
为了支撑如此复杂的构建,数值系统必须严谨且具备极其宽广的边界。
### 4.1 核心资源:魔力 (Mana)
> **⚠️ 实现现状 (2026-07-20 审计)****Mana 魔力系统完全未实现**——`PlayerStats` 无 mana 变量,法术无蓝耗/回蓝逻辑。作为设计文档声称的核心平衡阀,这是最大的功能缺口之一。当前施法仅受 `MAX_OPS` 与 `Cast Delay` 限制。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
为了防止无限“加特林核弹”,限制资源是 **魔力**
* 强力修正器(如伤害+100)会有巨大的 **Delay (施法后摇)** 和 **Mana Cost (蓝耗)**
* **平衡点**:高射速 = 低单发伤害;高爆发 = 便秘的手感(打一发回蓝3秒)。
@@ -148,6 +151,9 @@ $$ FinalDamage = ((Base + \sum Mod_{flat}) \times \prod Mod_{mult}) \times (1 -
* **Armor**: 敌人护甲平铺扣除值(固定数值,不受百分比影响)。最终伤害最小为 1。
### 4.3 属性词条池 (Stats Pool) — *MVP 层*
> **⚠️ 实现现状 (2026-07-20 审计)**:下表 5 条 MVP 属性中**仅 CPU`cpu_limit`)实现**——且因 `MAX_OPS` 硬编码不读 cpu_limit,连它也对施法预算无效(见架构文档 §3.4 现状注)。Cast Speed / Mana Leech / Accuracy / Attunement 均未实现。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
玩家在升级或商店中购买的属性,直接影响构建的上限。
> ⚠️ **MVP 说明**:以下 5 条属性为 MVP 阶段实现目标。后续扩充方向:
@@ -172,6 +178,8 @@ $$ FinalDamage = ((Base + \sum Mod_{flat}) \times \prod Mod_{mult}) \times (1 -
Boss 出现于特定里程碑波次,强制验证玩家构建的适应性。
> **⚠️ 实现现状 (2026-07-20 审计)**:本节多为设计蓝图,代码差异较大。① **波次**:精英/Mini Boss 实际在 **W8**(非本节标题的 W10),最终 Boss 在 W20`waves.json`)。② **阶段阈值**:代码统一用 **66%/33%**,非下方 JSON schema 的 50%/10%。③ **血量**:代码取 `balance.json` 的 450(mini)/1800(final),与 `numerical_design §3.2` 的 50000 冲突(DPS 门槛测算已失真)。④ **未实现**:元素抗性 `(1-Res)`、镜像法师反射、重甲降甲、`regen_on_physical_hit` 虚空再生、NG+ Phase4——Boss 现状只是会在血线召唤 FAST 援军的厚血怪。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
#### W10 精英 Boss (第 10 波)
* **功能**: 展示某一核心机制的利用方式。
* **典型设计示例**:
@@ -265,7 +273,7 @@ Boss 阶段数据完全由 JSON 驱动(`res://resources/bosses/boss_XX.json`
3. **购物 (The Shop)**:
* 战斗结束,进入商店。
* **货架 A**: 出售新的法术卡片(随机池)。
* **货架 B**: 出售新的”核心”(更牛的主板)。
* **货架 B**: 出售新的”核心”(更牛的主板)。 ⚠️**未实现**(现状商店仅货架 A 法术抽取;货架 C 属性、出售退款 G5 亦未实现)
* **货架 C**: 基础属性提升(生命值、暴击率)。
* **出售与转型规则 (G5)**
* 玩家可在商店界面将背包中的法术卡**出售**,回收该卡购入价格的 **50%**(下限 10G)。
@@ -302,6 +310,8 @@ Roguelite 的"第一把"体验至关重要。系统复杂度必须渐进式解
## 7. 元进展设计 (Meta-Progression)
> **⚠️ 实现现状 (2026-07-20 审计)**:**本章整体未实现**——以太碎片局外货币、局外解锁树、图鉴 Codex、成就系统在代码中均无实现(仅 1 个孤立未接线的 `ACHIEVEMENT_UNLOCKED` 事件常量)。属 Roguelite 长期粘性核心,为后续切片的功能待办。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
元进展是 Roguelite 的长期粘性来源。玩家每次游玩都在为"总体库"做出贡献,即使失败也有收获感。
### 7.1 局外货币:以太碎片 (Aether Fragments)
@@ -345,6 +355,8 @@ Roguelite 的"第一把"体验至关重要。系统复杂度必须渐进式解
### 8.2 通关条件与通关后内容 (G2)
> **⚠️ 实现现状 (2026-07-20 审计)****通关流程整体未实现**。击败 W20 Boss 后照常结算进商店并继续 W21,无通关演出、无 `GAME_CLEARED` 事件、无 NG+ 解锁;游戏目前只能靠死亡结束。Endless 已实现但为**逐波 ×1.12 膨胀**(非"每 5 波 +10%"),且无 Boss Rush、无全局词条。EndlessRecords 本地排行榜(评分 + HMAC)已实现。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
* **通关条件**:击败 W20 终波 Boss(三阶段精英怪),触发通关演出。
* **首通奖励**
* 给予 30 以太碎片(固定)。
@@ -369,6 +381,8 @@ Roguelite 的"第一把"体验至关重要。系统复杂度必须渐进式解
### 8.3 里程碑与 Checkpoint (G3)
> **⚠️ 实现现状 (2026-07-20 审计)**:本节里程碑体系(W5/W10/W15 奖励与练习模式解锁)**未实现**;练习模式、Boss Rush 均无代码。里程碑碎片依赖的元进展系统(以太碎片/解锁树/图鉴)也未落地。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
到达 **W5 / W10 / W15** 触发里程碑事件:
| 里程碑 | 即时奖励 | 解锁内容 |
+4 -2
View File
@@ -21,7 +21,7 @@
| `cast_delay_mod` | 施法延迟修正 | 1.0 (100%) | 0.1 | 0.01 | 越低越快,乘算系数 |
| `recharge_speed_mod` | 充能速度修正 | 1.0 (100%) | 5.0 | - | 越低越快 |
| `luck` | 幸运 | 0 | 100 | - | 影响高阶法术掉率、暴击率 |
| `cpu_limit` | 运算力上限 | 5 | 20 | 50 | `SpellEvaluator` 实际 MAX_OPS = `cpu_limit × 40`(默认 5 → 200 步;软上限 20 → 800 步;硬上限 50 → 2000 步)。升级此属性可执行更复杂的法术链,与 `implementation_plan.md §2.2``MAX_OPS_PER_CPU = 40` 常量对应。 |
| `cpu_limit` | 运算力上限 | 5 | 20 | 50 | `SpellEvaluator` 实际 MAX_OPS = `cpu_limit × 40`(默认 5 → 200 步;软上限 20 → 800 步;硬上限 50 → 2000 步)。升级此属性可执行更复杂的法术链,与 `implementation_plan.md §2.2``MAX_OPS_PER_CPU = 40` 常量对应。 ⚠️**实现现状(2026-07-20)**:代码硬编码 `MAX_OPS = 40×5 = 200`**从不读 cpu_limit**——升级此属性对施法预算无效(待修,本设计更优)。 |
| `attunement_fire` | 火焰精通 | 0 | 50 | 100 | 每点:火焰伤害 +3%(乘算),火焰状态(点燃/爆燃)触发概率 +2%。影响 `damage_type=FIRE` 的所有投射物。 |
| `attunement_ice` | 冰霜精通 | 0 | 50 | 100 | 每点:冰霜伤害 +3%,冰冻/减速触发概率 +2%。 |
| `attunement_lightning` | 雷电精通 | 0 | 50 | 100 | 每点:雷电伤害 +3%,麻痹/连锁导电触发概率 +2%。 |
@@ -135,7 +135,7 @@ Damage = ((Base + Add) × Mult) × (1 - Res) - Armor
| Wave 1 | 杂鱼土豆 | 15 | 100 | 5 | - |
| Wave 5 | 冲锋甲虫 | 80 | 250 | 12 | 击退抗性 50% |
| Wave 10| 坦克巨兽 | 2000 | 50 | 30 | 护甲 5 (免疫机枪) |
| Wave 20| 虚空领主 | 50000| 150 | 100 | 弹幕反射盾 |
| Wave 20| 虚空领主 | 50000 ⚠️| 150 | 100 | 弹幕反射盾 |
### 3.3 波次强度控制 (Pacing)
@@ -191,6 +191,8 @@ Damage = ((Base + Add) × Mult) × (1 - Res) - Armor
### D. W20 Boss Phase 1 DPS 门槛(P6-N17
* **问题**: Phase 1 的 `regen_on_physical_hit = 0.005`(每次物理命中恢复 Boss 最大 HP 的 0.5%)。
Boss 最大 HP = 50,000,即每次物理命中回血 **250 HP**
> **⚠️ 实现现状 (2026-07-20 审计)**:代码 Boss 实际 HP = 450(mini)/1800(final)`balance.json`,疑为占位),**非 50000**`regen_on_physical_hit` 虚空再生、反射盾、元素抗性**均未实现**。本节 DPS 门槛测算基于 50000 已失真,需统一血量口径后重算。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
若玩家攻速 10 发/秒(纯物理构建),Boss 每秒净回血 2,500 HP。
* **DPS 突破阈值(最低要求)**:物理构建需满足以下条件才能有效磨血:
$$DPS_{physical} > \frac{250 \times hit\_rate}{1} \Rightarrow DPS > 2500 \text{10发/秒时)}$$
+4
View File
@@ -7,6 +7,8 @@
---
> **⚠️ 实现现状 (2026-07-20 审计)**:本文档描述的整套 FTUE 架构——`TutorialManager` Autoload、9 步状态机、气泡提示 `tutorial_hint_bubble.tscn`、`hint_*.tres`、情境提示、渐进解锁(局 1-5)、靶场慢放——**均未实现**。现状"新手引导" = 仅**首次启动的难度三选一弹窗**`main_menu.gd` 的 FTUE 面板 + `SettingsManager.ftue_done`)。下文保留作目标设计。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
## 一、设计目标
| 目标 | 度量标准 |
@@ -218,6 +220,8 @@ T=Wave 4+ 触发共鸣时 → 最终提示显示
| 18 | `TUTORIAL_STEP_COMPLETED` | `step: int` | TutorialManager | UIManager(显示解锁提示)|
| 19 | `SHOP_OPENED` | — | ShopManager | TutorialManager |
| 20 | `RESONANCE_TRIGGERED` | `recipe_id: String` | SpellEvaluator | TutorialManager, VFXManager |
> **⚠️ 实现现状 (2026-07-20 审计)**:上表 EventID 与实际 `event_ids.gd` **不符**——`TUTORIAL_STEP_COMPLETED` 与 `RESONANCE_TRIGGERED` 常量**根本不存在**ID 18/19/20/21 实为 `ACHIEVEMENT_UNLOCKED`/`BOSS_SPAWNED`/`GAME_STATE_CHANGED`/`SPELL_DROP_PICKUP``SHOP_OPENED` 实为 17。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
| 21 | `ACHIEVEMENT_UNLOCKED` | `achievement_id: String` | AchievementManager | Steam 插件层 |
> **注意**ID 0 为 `CRASH_DETECTED`CrashReporter 专用,已定义)。
+13 -43
View File
@@ -2,60 +2,30 @@
> 策划和程序共同维护的内容文件。所有数值修改无需改架构代码,只改指定位置。
> ⭐ **策划/美术优先用可视化工具**:[07 游戏设计器](07_game_designer.md) 提供编辑器内一站式面板(法术/敌人/波次/Core/平衡),表单填数值即可,**无需写代码**。本文的代码方式适合需要复杂自定义逻辑的程序员,或了解底层数据结构
> **⚠️ 实现现状 (2026-07-20 审计)**:本文多个「改硬编码」的步骤已**过期作废**——项目内容早已全面 JSON 数据驱动,法术/波次/敌人/共鸣/Core 均从 `data/*.json` 加载,相关硬编码工厂函数与常量表已从代码中删除。**当前唯一权威的内容创作工作流是 [07 游戏设计器](07_game_designer.md)**编辑器内插件面板,全部经 `data/*.json` + 编辑器,零代码)。本文中标注 ❌**OBSOLETE** 的小节仅保留作历史参考,请勿据其修改代码。详见审计报告 ../../docs_dev/doc_code_audit_2026-07-20.md
> ⭐ **策划/美术优先用可视化工具**:[07 游戏设计器](07_game_designer.md) 提供编辑器内一站式面板(法术/敌人/波次/Core/平衡),表单填数值即可,**无需写代码**。本文的代码方式已大部分作废(见上方现状说明)。
---
## A. 添加/修改法术
> 💡 **策划优先用可视化工具**:[06 法术编辑器](06_spell_editor.md) 提供编辑器内表单,无需写代码即可新增/编辑法术(保存到 `data/spells.json`)。下面的代码方式适合需要复杂逻辑的程序员
> **⚠️ 实现现状 (2026-07-20 审计)**:法术定义唯一来源是 `res://data/spells.json`,由 `SpellRegistry` 启动时加载。`wand_preset.gd` **已不再定义任何法术**(文件头注:「法术已迁至 SpellRegistry」),下文 `make_frost_bolt` / `make_spell_by_id` / `get_all_spell_ids` 等工厂函数**在代码中已不存在**,请勿添加。详见审计报告 ../../docs_dev/doc_code_audit_2026-07-20.md
> 💡 **策划优先用可视化工具**:在 [07 游戏设计器](07_game_designer.md) 的「法术」页签(或独立的 [06 法术编辑器](06_spell_editor.md))用表单新增/编辑法术,保存到 `data/spells.json`**无需写代码**。
### 法术定义位置
- **数据驱动(推荐)**`res://data/spells.json`(由法术编辑器维护,启动时由 `SpellRegistry` 加载,优先级最高
- **硬编码(程序)**`scripts/autoloads/wand_preset.gd`(向后兼容回退)
- **唯一来源**`res://data/spells.json`(由游戏设计器/法术编辑器维护,启动时由 `SpellRegistry` 加载)
- 手工编辑时,每条法术是一个对象,键与旧工厂函数字段对应:`id` / `type` / `display_name`tr() 键)/ `description` / `element_tags`(如 `["tag:ice"]`/ `meta``base_damage` / `speed` / `lifetime` / `radius` / `damage_type` / `apply_status_id` / `shop_cost` 等)。推荐用编辑器面板生成,避免手写 JSON 出错。
### 步骤:添加一个新 ACTION 法术
### 步骤:添加一个新 ACTION 法术(当前正确流程)
**1. 在 `wand_preset.gd` 添加工厂函数**
1. 打开游戏设计器「法术」页签,新增一条法术,填写上述字段(`data/spells.json` 会自动写入)。
2.`translations/*.po` 四个文件中添加对应翻译键(见本地化指南)。
3. 无需改动任何 `.gd` 代码;`SpellRegistry` 启动即加载,商店会自动抽取新法术。
```gdscript
func make_frost_bolt() -> SpellNode:
var n := SpellNode.new()
n.id = "action_frost_bolt" # 全局唯一 ID
n.type = SpellNode.SpellType.ACTION
n.display_name = "SPELL_FROST_BOLT_NAME" # tr() 键(见本地化指南)
n.description = "SPELL_FROST_BOLT_DESC"
n.element_tags = ["tag:ice"] # 共鸣系统用的元素标签
n.meta = {
"base_damage": 5.0, # 基础伤害
"speed": 380.0, # 弹速 (px/s)
"lifetime": 4.0, # 存活时间 (s)
"radius": 7.0, # 弹体半径 (px)
"damage_type": 0, # 0=通用 (DamageType.NORMAL)
"apply_status_id": StatusID.FREEZE, # 命中施加状态(可选)
"shop_cost": 22, # 商店价格
}
return n
```
**2. 注册到 `make_spell_by_id` 和 `get_all_spell_ids`**
```gdscript
func make_spell_by_id(spell_id: String) -> SpellNode:
match spell_id:
# ... 已有法术 ...
"action_frost_bolt": return make_frost_bolt() # 新增
_: push_warning(...)
func get_all_spell_ids() -> Array:
return [
# ... 已有 ...
"action_frost_bolt", # 新增到列表末尾(商店会自动抽取)
]
```
**3. 在 `translations/*.po` 四个文件中添加翻译键**(见本地化指南)
> ❌ **OBSOLETE(历史参考,代码已删除)**:早期版本需在 `wand_preset.gd` 添加 `make_frost_bolt()` 工厂函数并注册到 `make_spell_by_id` / `get_all_spell_ids`。这些函数已随 SpellRegistry 迁移删除,请勿参照。
---
+2 -2
View File
@@ -1,6 +1,6 @@
# 05 发布标准清单 (Release Guide)
> 正式发布前所有 **P0 必须项** 须全部打勾。参考:`docs/plan/certification_checklist.md`(权威完整版)。
> 正式发布前所有 **P0 必须项** 须全部打勾。参考:`docs_dev/certification_checklist.md`(权威完整版)。
---
@@ -109,7 +109,7 @@
| ST-40/41 | HMAC 签名排行榜 | `endless_records.gd` ✅ |
| ST-50 | Steam Cloud 存档 | 待实现(profile_manager.gd 已有位置) |
完整清单见 `docs/plan/certification_checklist.md`
完整清单见 `docs_dev/certification_checklist.md`
---
+6 -6
View File
@@ -34,12 +34,12 @@ daihaoRogue/
├── translations/ ← zh_CN / zh_TW / en / ja .po
├── audio/sfx/ ← 音效放这里(目前占位蜂鸣)
├── assets/sprites/ ← 精灵图放这里(目前几何占位)
── docs/
├── design/ ← 游戏设计文档
├── mechanics/ ← 机制深度文档
├── technical/ ← 架构 / 实现方案
── plan/ 开发计划 / 认证清单
└── handbook/本手册(你在这里)
── docs/
├── design/ ← 游戏设计文档
├── mechanics/ ← 机制深度文档
├── technical/ ← 架构 / 实现方案
── handbook/本手册(你在这里)
└── docs_dev/ 开发计划 / 认证清单 / 归档草案
```
---
@@ -1,5 +1,7 @@
# 进阶机制扩展:召唤与环境蔓延 (Advanced Mechanics: Summons & Propagation)
> **⚠️ 实现现状 (2026-07-20 审计)**:召唤体系**只实现了 Stationary 炮台一种**;随从/卫星/镜像(含 hp / 碰撞体积 / 移动 / `behavior_state`)未实现,施法者死亡联动也无。`MinionManager` 用 `Array[Dictionary]`(§5.12,非 SoA),`MAX_MINIONS=20` FIFO 已实现。环境传导 / 反应地表 / 元素蔓延**未实现**。StatusID 常量 FREEZE/WET/OILY/STUN/VULNERABILITY 存在,但 `status_effects.json` 只定义 Burn/Poison/Combo。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
基于现有的 ECS 战斗系统,我们可以进一步拓展 **“召唤体系 (Summoning System)”** 和 **“环境传导 (Environmental Propagation)”** 维度。
## 1. 召唤体系 (Summoning Dimension)
+2
View File
@@ -1,5 +1,7 @@
# 深度战斗机制扩展设计文档 (Advanced Combat Mechanics Design)
> **⚠️ 实现现状 (2026-07-20 审计)**:本文档的多个进阶维度**未实现**:① §2 连锁/弹跳(`visited_targets` 排除表、`pow(0.9, bounce)` 衰减)——`bounce_remaining` 字段从不被消费;② §3.0 StatusType 现从 `data/status_effects.json`JSON)加载而非 `res://resources/status_types/*.tres`,且 `can_catalyze`/`immune_faction_tags` 不解析;③ §3.3 催化/覆盖/免疫状态交互未实现;④ §4 伤害公式的 `(1-Res)` 抗性项虽存在于 `calc_damage`,但实战路径恒传 `resistance=0`(死维度)。已实现:DoT/伤害基础管线、DamageContext(含 `mult`,伤害计算在 EnemyManager/SRP)。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
为了支持 Roguelike 游戏中涌现式的玩法组合(如:闪电链、叠毒流、触发流),现有的简单"伤害+阵营"模型需要升级为多维度的**上下文感知 (Context-Aware)** 系统。
本文档详细定义了扩展战斗深度所需的关键维度和判断逻辑。
@@ -1,5 +1,7 @@
# 连续打击与伤害叠加设计 (Consecutive Hits & Damage Stacking)
> **⚠️ 实现现状 (2026-07-20 审计)**`VULNERABILITY`(易伤,+5%/层)状态**未实现**——无 JSON 条目、`apply_damage` 不读取。现状代码改用 **`COMBO_MARK` 每层 +2%**`enemy_manager.gd`)。文中标注为 P2 长期方案的 `is_combo_tracker` **已提前实现**并正确守卫 DoT tickCOMBO_MARK 不误触发 DoT)。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
## 需求分析
用户希望实现“对同一个目标,同一种伤害在一定间隔内认定为持续多次伤害,从而可以制作伤害叠加”。
@@ -1,5 +1,7 @@
# 武器系统扩展设计方案 (Weapon System Expansion Design)
> **⚠️ 实现现状 (2026-07-20 审计)**:本文档为**扩展蓝图,大部分未实现**。§1 轨迹修正器(正弦 / 回旋镖 / 环绕,含 `is_orbiting`/`wave_frequency` 等字段)**完全未落地**;文中引用的 `ProjectileDef` 字段属**死类**(代码 `spawn_bullet` 走扁平参数 + cold_data,从不实例化 ProjectileDef)。已实现的触发器/子母弹见 `spell_evaluator.gd`。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
本文档旨在描述基于现有的 **HMWS (Hackable Modular Weapon System)****ECS BulletManager** 架构,可以进一步扩展的玩法机制。
当前的系统已经支持了基础的投射物、霰弹、激光,以及修正器(多重施法、弹射、追踪、穿透、连锁、冰冻)。在此基础上,我们可以引入更高级的策略组合和“涌现式”玩法。
+26 -1
View File
@@ -53,6 +53,8 @@ graph TD
end
```
> **⚠️ 实现现状 (2026-07-20 审计)**:数据层实际为**纯 `data/*.json`**7 个文件:spells / cores / enemies / waves / resonance / status_effects / balance),各 Manager 自行 `FileAccess` 直读;全项目**零 `.tres` 数据资源**(仅 `assets/ui/ui_theme.tres`),无 `resources/` 目录。图中 `ConfigMgr` autoload 虽已注册(`project.godot`),但**从未被任何调用方引用,是死代码**。文中后续所有 `res://resources/**/*.tres` 路径均为设计蓝图,与实际 `data/*.json` 布局不符。详见 [`docs_dev/doc_code_audit_2026-07-20.md`](../../docs_dev/doc_code_audit_2026-07-20.md)。
---
## 3. 核心子系统:超模块化法术系统 (HMWS)
@@ -263,6 +265,11 @@ func reset() -> void:
`SpellEvaluator` 的 while 循环只能处理线性指令流。为此,在 `SpellEvaluator.compile_wand(core, raw_deck)` 预编译阶段引入 **拓扑扁平化 (Topology Flattening)**,将不同 Core 的空间拓扑提前转换为线性指令序列,运行时 while 循环无需感知拓扑:
> **⚠️ 实现现状 (2026-07-20 审计)**:真实签名与本节伪代码不同:
> - `compile_wand(core, raw_nodes: Array)` —— 第 2 参是 `Array` 而非 `SpellDeck``spell_evaluator.gd:36`)。
> - `execute_compiled(compiled, caster_id: int, spawn_pos: Vector2)` —— 执行期不传 `ctx`/`core``feature_tags` 从 `CompiledDeck` 编译期快照读取(`spell_evaluator.gd:321`)。
> 详见 [`docs_dev/doc_code_audit_2026-07-20.md`](../../docs_dev/doc_code_audit_2026-07-20.md)。
| Core 类型 | 扁平化策略 |
| :--- | :--- |
| **LINEAR** | 无需处理,直接输出原始 SpellNode 序列 |
@@ -279,6 +286,9 @@ func update_max_ops(cpu_limit: int) -> void:
# MAX_OPS_PER_CPU = 8(基准值,SpellEvaluator 常量)
const MAX_OPS_PER_CPU: int = 8
_max_ops = clamp(MAX_OPS_PER_CPU * cpu_limit, 8, 200)
# ⚠️ 实现现状(2026-07-20)SpellEvaluator 从不调用本函数、从不读 cpu_limit;
# 实际硬编码 max_ops = MAX_OPS_PER_CPU * 5(代码常量为 40,本处写 8,文档内部亦不一致)。
# 结果:升级 CPU 词条对施法预算无效——本设计更优,代码待修。见审计报告 D 节。
func compile_wand(core: CoreDefinition, raw_deck: SpellDeck) -> CompiledDeck:
match core.topology:
@@ -719,10 +729,14 @@ func _node_has_tag(node: SpellNode, tag_pattern: String) -> bool:
* 下穿回滞(`_active_count < 1500 and _collision_mode == 1`):反向切回,避免阈值附近频繁震荡。**⚠️ 反向切换 Jitter 风险**:从 SpatialGrid 切回 Area2D 时,约 1500 颗子弹需要重新启用 Node(`process_mode = INHERIT`)。若全部在单帧完成,将产生约 1500 次节点状态更改(额外 1~2ms,可见微卡顿)。**缓解策略**:反向切换同样须分帧渐进(`BATCH_ENABLE_PER_FRAME = 100`,约 15 帧完成),过渡期内存活子弹继续走 SpatialGrid 路径,碰撞正确性不受影响。
* 两段路径(信号回调 vs 手动查询)最终均调用同一 `_on_bullet_hit(bullet_id, enemy_id)` 函数,后处理逻辑完全共用。
> **⚠️ 实现现状 (2026-07-20 审计)**:上述 Area2D 优先 + `_collision_mode` 三档运行时切换**从未实现**。现状是 **SpatialGrid-only**`BulletManager._check_collision` 无条件走 `SpatialGrid.query_circle`,代码中不存在 Area2D / CircleShape2D / `body_entered` / `_collision_mode` / `BATCH_DISABLE_PER_FRAME`。这一简化与 `implementation_plan.md` §S0 的 **R-04 决议**(永久锁定 SpatialGrid 为 200+ 主力、不保留 Area2D 回退)一致——本节 §4.3/§4.4 属尚未同步的旧设计。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
### 4.4 渲染优化
子弹渲染策略依据同屏数量分三档,**Area2D 与 MultiMeshInstance2D 不共存**——MultiMesh 绕过节点树,意味着子弹无法挂载 Area2D。因此两者适用于不同的弹幕规模区间:
> **⚠️ 实现现状 (2026-07-20 审计)**:下表三档**未实现**。现状:`MultiMeshInstance2D` **从第 1 帧起单档常开**(无 Node2D 池、无 <200/200-2000 档),子弹与敌人均走 MultiMesh。同步是 **GDScript 逐实例 `set_instance_transform_2d` 循环**(非文档的 C# `SetBuffer` 批量上传);子弹无按型颜色(统一 `modulate`),敌人有 per-instance color。既然碰撞已 SpatialGrid-onlyNode 池档位已无意义,此简化为**代码更优**。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
| 同屏弹幕数 | 渲染方案 | 碰撞方案 | 说明 |
| :--- | :--- | :--- | :--- |
| < 200 | Node Pool (Node2D) | Area2D | 全功能,支持粒子特效、信号回调 |
@@ -771,6 +785,8 @@ func _node_has_tag(node: SpellNode, tag_pattern: String) -> bool:
> **目标**60fps → 单帧总预算 **16.67ms**。以下为 S0 性能验收的基准分配;S0 Profiler 实测后需将"S0 实测值"列回填并提交 git,作为后续切片的性能基线快照。
> **⚠️ 实现现状 (2026-07-20 审计)**:下表"语言"列标注 C#`BulletManagerCs`/`EnemyManagerCs`/`SpatialGridCs`/`SpellEvaluatorCs`)的热路径**均未接线**——三个 C# 内核从未实例化、从未进场景树,战斗逻辑 **100% 由 GDScript 回退路径承载**R-08 顺延)。C# `AsSpan()` 零拷贝在代码中不存在。表中"S0 实测值"确为 GDScript 回退实测(见 :795 摘要)。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
| 系统 | 语言 | 预算上限 | S0 实测值 | 说明 |
| :--- | :--- | :--- | :--- | :--- |
| `BulletManagerCs._PhysicsProcess` | C# | 2.0ms | **0.37ms** | 2000 子弹 GDScript SoA 积分(P-S0-01C# 热路径 S1 填充后预计更低) |
@@ -823,6 +839,8 @@ func _node_has_tag(node: SpellNode, tag_pattern: String) -> bool:
### 5.1 GameCycleManager 状态机 (FSM)
> **⚠️ 实现现状 (2026-07-20 审计)**`GameCycleManager` Autoload **不存在**。顶层状态机现内嵌在场景子节点 `combat_manager.gd`,仅 **5 态**INIT/BATTLE/SETTLEMENT/SHOP/GAME_OVER),缺文档的 WAVE_INTRO 开场、WAVE_RESULT 升级卡结算、GAME_CLEARED 通关、PAUSE 独立态(暂停改由 `get_tree().paused` 处理)。`GAME_STATE_CHANGED` payload 用字符串态名而非枚举。同理 §5.10 的 `UIManager` Autoload 也不存在——全部 UI 在 `combat_s2.gd` 程序化构建,无 `HUD.tscn`/`shop.tscn` 等场景,`DamageNumber` 飘字未实现。下文 GameCycleManager/UIManager 相关设计保留作目标蓝图。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
`GameCycleManager` 是游戏最顶层的协调者,持有全局状态机并驱动各 Manager 的生命周期。
```gdscript
@@ -2815,6 +2833,8 @@ DoT(持续伤害)、召唤物(Minion)、持续性法术的属性在**施
> **结论:采用独立的 MinionManager(方案 B),不在 EnemyManager 中混管召唤物。**
> **⚠️ 实现现状 (2026-07-20 审计)**MinionManager 存在,但数据结构用的是 **`Array[Dictionary]`(随 §5.12)而非本节的 SoA `stride=8`**(两处文档矛盾,代码选了 Array);`behavior_state` 枚举未实现。召唤物**只实现了 Stationary 炮台一种**,随从/卫星/镜像(含 hp/碰撞体积/移动)均未落地。`MAX_MINIONS=20` FIFO 顶替已实现。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
`MinionManager` 为独立的 Autoload 单例,管理玩家召唤的炮台/傀儡/宠物类实体:
- **与 EnemyManager 隔离**EnemyManager 的 SoA 中 `faction_and_type` 字段不扩展到友军,
@@ -2894,7 +2914,8 @@ func _physics_process(delta: float) -> void:
while _zone_data[base + 6] >= _zone_data[base + 5]:
_zone_data[base + 6] -= _zone_data[base + 5] # -= tick_interval 保留余量精度
for t_id in targets:
StatusManager.apply(t_id, sid, 1.0, int(_zone_data[base + 7])) # intensity=1.0, owner_id=zone_owner
# ⚠️ 修正(2026-07-20):真实签名 apply(entity_id, status_type_id, stacks:int=1, duration:float=-1.0, owner_id:int=-1)——5 参
StatusManager.apply(t_id, sid, 1, -1.0, int(_zone_data[base + 7])) # stacks=1, duration=default, owner_id=zone_owner(现实 zone_manager.gd:60 即如此调用)
if _zone_data[base + 4] <= 0.0: # duration 耗尽,移除此 Zone
var cx_exp: float = _zone_data[base + 0]; var cy_exp: float = _zone_data[base + 1]
@@ -2923,6 +2944,8 @@ func reset() -> void:
> **结论**:所有 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)。
```gdscript
# core_feature_tag.gd (Autoload: CoreFeatureTag)
## Core 特性标签常量表 — 所有系统通过此处引用,禁止裸字符串
@@ -2974,6 +2997,8 @@ const ALWAYS_CAST_LAST: String = "always_cast_last"
> **结论:S2 实现波次边界自动存档,采用 A/B 双槽写入防崩溃损坏,支持断点续玩。**
> **⚠️ 实现现状 (2026-07-20 审计)**A/B 双槽 + 波次自动存档 + `WM_CLOSE` 兜底 + 链式迁移已实现。差异:① 选槽逻辑现按 `saved_at` **时间戳选最新未损坏槽**(比下文伪代码"固定顺序取第一个有效"更健壮,**代码更优**);② `SCHEMA_VERSION` 已到 **2**(新增 `wand` 键),本节仅记 v1;③ 实存字段为 `wave_num/shop_seed/player_stats/wand`**缺** `elapsed_sec`(影响无尽续玩计时)、`active_core_idx`、`unlocked_upgrades`、多 Core 数组(待补)。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
商业 RogueliteHades / Slay the Spire / Balatro)均支持中途退出后恢复到当前波次起始状态。
**存档时机**
+9 -3
View File
@@ -5,6 +5,10 @@
---
> **⚠️ 实现现状 (2026-07-20 审计)**:本文档描述的整套 Boss 架构(`BossManager` Autoload、`BossDef`/`BossPhaseDef`/`.tres` 资源、`BossAttackRegistry` 攻击模式注册表、场地机制如冰墙/场地收缩、多阶段弹幕、状态机 `BossInstance`**均为设计蓝图,代码 0% 实现**。现状 Boss 只是 `EnemyManager` SoA 中 `type=4`Mini BossWave 8/`type=5`Final BossWave 20)的普通厚血实体;唯一的"阶段行为"是当血量跨越 66% / 33% 阈值时召唤一批 `FAST` 杂兵援军(`wave_manager.gd:94-117`)。以下 `BossManager`/`.tres`/攻击模式注册表/场地机制全部尚未落地,保留作为未来实现的目标设计。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
---
## 1. 设计原则
- **阶段驱动(Phase-Driven**Boss 行为由明确的阶段(Phase)枚举驱动,阶段切换在 `_physics_process` 中以血量阈值触发,不使用独立 Timer Node。
@@ -141,6 +145,8 @@ func _tick_attack(delta: float) -> void:
## 5. 具体 Boss 设计模板
> **⚠️ 实现现状 (2026-07-20 审计)**:下表 HP 与阶段阈值均为**设计目标**,与代码现值不符。① **血量**:代码实取 `balance.json` 的 `boss_hp`Mini=**450** / Final=**1800**`balance.json:8-11`,疑为占位/待平衡值),并非本节的 2000 / 10000,也非 `numerical_design §3.2` 的 50000;三处数值互相矛盾。② **阶段阈值**:代码统一用 **66% / 33%** 两段(`wave_manager.gd:99-102`),并非本节 Mini 的 60%/30% 或 Final 的 70%/40%/15%。③ **攻击模式 / 场地机制 / move_speed / enrage_vfx** 字段全部未实现;每次"进阶"只是召唤 `4 + phase*2` 个 FAST 杂兵。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。
### 5.1 Mini Boss — Wave 8(待策划填充)
| 字段 | 值 |
@@ -151,7 +157,7 @@ func _tick_attack(delta: float) -> void:
| **Phase 0**100%→60% HP| 攻击模式:`"charge_slam"` + `"spread_shot_3"` |
| **Phase 1**60%→30% HP| 追加:`"summon_minion_x2"`move_speed_mult=1.2 |
| **Phase 2**30%→0% HP| 追加:`"zone_aoe_fire"`move_speed_mult=1.5enrage_vfx="boss_enrage" |
| 死亡事件 | `BOSS_KILLED`EventID 待分配,建议 ID=15|
| 死亡事件 | `BOSS_KILLED`**未实现**:该常量不存在;现状仅在生成时发 `BOSS_SPAWNED=19`,死亡走通用 `ENEMY_KILLED=7`|
| 战场机制 | 无(Mini Boss 不设场地机制,Final Boss 才有)|
### 5.2 Final Boss — Wave 20(待策划填充)
@@ -165,8 +171,8 @@ func _tick_attack(delta: float) -> void:
| **Phase 1**70%→40% HP| 追加:`"zone_ice_wall"`;场地:随机生成 4 个冰墙障碍(`ZoneManager` 驱动)|
| **Phase 2**40%→15% HP| 追加:`"enrage_laser_sweep"`;场地收缩:边界每 10 秒向中心缩小 50px |
| **Phase 3**15%→0% HP| 全弹幕覆盖;`"phase3_barrage"`;恢复部分 HP 后进入死亡序列(演出用)|
| 死亡事件 | `BOSS_KILLED``EventID` **16**+ `GAME_CLEARED`**17**);阶段切换为 **15**(均以 `implementation_plan.md` §2.1 为准|
| 战场机制 | 场地收缩(Phase 2+)、冰墙障碍(Phase 1+|
| 死亡事件 | **未实现**`BOSS_KILLED` / `GAME_CLEARED` / `BOSS_PHASE_CHANGED` 三个常量均不存在(ID 15/16/17 实为 `SPELL_EQUIPPED`/`LEVEL_UP`/`SHOP_OPENED`)。现状:生成发 `BOSS_SPAWNED=19`,死亡走 `ENEMY_KILLED=7`,阶段切换发通用 `GAME_STATE_CHANGED=20`payload `to="BOSS_PHASE_N"`|
| 战场机制 | 场地收缩(Phase 2+)、冰墙障碍(Phase 1+——**均未实现** |
---
+14
View File
@@ -0,0 +1,14 @@
# docs_dev —— 开发过程 / 归档文档
> 本目录存放**开发过程中**产生的计划、追踪与历史归档类文档,与 `docs/`(面向产品的设计规范与架构参考)区分开。
>
> 产品文档索引见 [`../docs/README.md`](../docs/README.md)。
| 文档 | 类型 | 内容简述 |
| :--- | :--- | :--- |
| [doc_code_audit_2026-07-20.md](doc_code_audit_2026-07-20.md) | 审计 | 文档 vs 代码交叉审计:三大结构性分歧、更优/偏离/未实现分类清单、潜在 bug、文档内部矛盾(2026-07-20 |
| [development_plan.md](development_plan.md) | 计划 / 追踪 | S0–S6 骨架垂直切片开发计划、技术风险登记表、各切片验收与出口检查、`P-S*` 任务勾选 |
| [certification_checklist.md](certification_checklist.md) | 计划 / 追踪 | Steam / Nintendo Switch 平台发行认证清单,映射到对应切片,含状态列 |
| [archived_cocos_architecture_draft.md](archived_cocos_architecture_draft.md) | 归档(已废弃) | 早期基于 Cocos Creator 3.x / TypeScript 的架构草案。项目已迁移至 Godot 4.6,权威架构见 [`../docs/technical/architecture_design.md`](../docs/technical/architecture_design.md) |
> **说明**:这些文档中以文件名(如 `architecture_design.md §4.5`)方式引用的权威架构/实现文档,均位于 `../docs/technical/` 下。
@@ -2,7 +2,7 @@
> ⚠️ **此文件为历史草案,已废弃。**
> 项目已迁移至 **Godot 4.6 + GDScript/C#**
> 当前权威架构请参阅:[docs/technical/architecture_design.md](technical/architecture_design.md)
> 当前权威架构请参阅:[docs/technical/architecture_design.md](../docs/technical/architecture_design.md)
---
+188
View File
@@ -0,0 +1,188 @@
# 文档 vs 代码 交叉审计报告
> **审计日期**2026-07-20 · **复核日期**2026-07-20
> **方法**:按子系统拆分为 6 个审计域并行核对,每条结论均带 `file:line` 证据。
> ✅ **已经对抗性复核**(6 个独立验证 agent 逐条重验,约 65 条主张零证伪)——结论与"代码 vs 文档 更优"判定见 **G 节**。正文中标 ⚠️**复核修正** 处为复核后订正。
> **范围**`docs/` 下全部设计/技术/机制文档,对照 `scripts/`、`csharp/`、`data/`、`scenes/`、`addons/` 实际代码。
> **分类图例**:🟢 更优 IMPROVEMENT(开发中做了更好的选择)· 🔴 偏离 DRIFT(与文档不符)· 🟠 未实现 UNIMPLEMENTED(设计了但代码没有)· 📄 文档过期 DOC-STALE。
---
## A. 结论先行:当前**真实**运行的架构
文档描述的是设计蓝图;代码在开发中做了大量简化与技术转向。当前实际系统:
- **纯 GDScript 运行**。`csharp/` 下三个 C# 内核(`BulletManagerCs` / `EnemyManagerCs` / `SpatialGridCs`)**从未被实例化、从未进入场景树**——战斗热路径 100% 跑 GDScript 回退路径。文档 §4.5 / §6.1 描述的 C# 驱动 `_physics_process` + `AsSpan()` 零拷贝在代码中不存在。
- 证据:`project.godot:19-59` autoload 仅 `.gd``bullet_manager.gd:24``enemy_manager.gd:28``spatial_grid.gd:11``_cs_node` 恒为 `null`;全库无 `Cs.new()`
- **纯 JSON 数据驱动 + 自建可视化编辑器**。全项目**零** `.tres` 数据资源(仅 `assets/ui/ui_theme.tres`),无 `resources/` 目录。内容集中在 `data/*.json`7 个:spells / cores / enemies / waves / resonance / status_effects / balance),每个 Manager 各自 `FileAccess` 直读。文档反复出现的 `res://resources/**/*.tres``ConfigMgr` 数据层入口——**`ConfigMgr` 已注册为 autoload 但零调用,是死代码**。
- **全部 UI 程序化构建**。仅 4 个**游戏** `.tscn`splash / main_menu / combat_s2 / combat_test+ 1 个编辑器插件场景(`addons/godot_mcp/ui/status_panel.tscn`,非游戏 UI)。HUD、商店、背包、结算、暂停、设置 6 套面板全部在 `combat_s2.gd`(约 792 行)内 `Label.new()` / `Button.new()` 现建。文档的 `UIManager` / `GameCycleManager` / `TutorialManager` 三个 Autoload **全部不存在**
- **战斗模型是"能打通的最小闭环"**,深度维度多为字段占位。Boss 是 SoA 里一个会召唤援军的厚血杂鱼;归航 / 弹跳 / 连锁 / 轨迹修正 / 元素催化 / 抗性 大多是**有字段无行为**;**Mana 魔力系统完全不存在**(而它是设计文档声称的核心平衡阀)。
---
## B. 三大结构性分歧(最需要决策)
| # | 分歧 | 文档 | 代码现实 | 判定 |
|---|---|---|---|---|
| 1 | **数据载体** | `.tres` Resource + `ConfigMgr` 统一数据层入口 | 纯 `data/*.json` + 7 页签"游戏设计器"插件,各 Manager 自读 | 🟢 更优(策划零代码可视化编辑),但文档系统性过期 |
| 2 | **热路径语言** | C# 内核驱动 `_physics_process` + 零拷贝 `AsSpan()` | 100% GDScriptC# 为死骨架 | 🔴/顺延(R-08);实测 500 敌 1500 弹 ≈0.6msGDScript 够用 |
| 3 | **UI 架构** | 场景化 `.tscn` + `UIManager` 协调者 | 单文件程序化构建,无协调器 | 🔴 偏离(技术债:不可视化编辑、魔数坐标、单文件耦合) |
---
## C. 分类清单
### 🟢 更优 — 建议"追认",改文档以对齐代码
| 项 | 说明 | 证据 |
|---|---|---|
| JSON + 编辑器插件 | 放弃 `.tres`,7 页签设计器(法术/敌人/波次/Core/共鸣/状态/平衡)全落地,与 handbook 07 吻合 | `addons/game_designer/`, `designer_panel.gd:11-18` |
| 存档 A/B 选最新 | 用 `saved_at` 时间戳选最新未损坏槽,比 ADR-A2 伪代码"固定顺序取第一个"更健壮;链式迁移 v0→v1→v2 | `profile_manager.gd:46-60,110-118` |
| 永远 MultiMesh 渲染 | 砍掉三档 Area2D→NodePool→MultiMesh 切换,单档 MultiMesh + per-instance 颜色 | `combat_s2.gd:149-177`, `enemy_manager.gd:288` |
| SpatialGrid-only 碰撞 | 无 Area2D、无 `_collision_mode` 阈值切换。⚠️**复核修正**:这与 §4.3/§4.4(描述 Area2D 优先 + 三档切换)**相反**;真正锁定 SpatialGrid-only 的 R-04 决议在 `implementation_plan.md:385` / `development_plan.md`。属**文档自相矛盾**,代码站在更新的 R-04 一侧 | `bullet_manager.gd:55-105` |
| `is_combo_tracker` 提前落地 | 文档标 P2,代码已实现,COMBO_MARK 不误触发 DoT | `status_manager.gd:25`, `status_effects.json:4` |
| MinionManager 用 Array[Dictionary] | 文档 §8 ADR-R4-N4 要 SoA,但 §5.12 允许 Array(≤20 数量),代码选了更简单且文档内部允许的方案 | `minion_manager.gd:6-7,15` |
### 🔴 偏离 — 与文档不符(需决策:改文档 or 改代码)
| 项 | 文档 | 代码 | 影响 |
|---|---|---|---|
| `execute_compiled` 签名 | `(compiled, ctx, core)` 且**禁止**快照 feature_tags | `(compiled, caster_id, spawn_pos)`,改从 `CompiledDeck.feature_tags`(编译期快照) | 接口契约与"禁止快照"约束双违背,但自洽 · `spell_evaluator.gd:321,324` |
| `compile_wand` 第 2 参 | `SpellDeck`P6-N65 禁止 Array | `Array` | 与硬约束相反 · `spell_evaluator.gd:36` |
| MAX_OPS 公式 | `MAX_OPS_PER_CPU×cpu_limit``implementation_plan`/`numerical` 用 40`architecture §3.4` 用 8——文档内部亦不一致) | `MAX_OPS_PER_CPU=40`(值对),但 `40×5` 硬编码 **不读 cpu_limit** | 升级 CPU 词条对施法预算无影响(真实功能缺口,文档更优)· `spell_evaluator.gd:8,328` |
| Boss 阶段阈值 | 50% / 10%(§4.5 schema | 66% / 33% | 数值不符 · `wave_manager.gd:99-102` |
| Endless 膨胀 | 每 5 波难度 +10% | 每波 ×1.12 HP(更陡) | 曲线形态不同 · `wave_manager.gd:153-159` |
| XP 曲线 | `⌊10×1.4^(n-1)⌋`floorP6-N16 | `roundi(...)`(四舍五入) | ⚠️**复核**:可忽略——`numerical §1` 的示例数值表本身用的是四舍五入值(5→6=54,floor 应为 53),`roundi` 反而更贴合文档表格 · `player_stats.gd:30-31` |
| 排行榜记录 Schema | `{wave, elapsed, build_snapshot, timestamp}`,留 20 条 | `{wave, elapsed, kills, score}`,留 50 条,无 snapshot | 文档所述"反作弊审核"无法实现 · `endless_records.gd:28-40` |
| 存档字段 | ADR-A2 含 `elapsed_sec / active_core_idx / unlocked_upgrades / 多Core` | 只存 `wave / shop_seed / stats / 单wand` | 缺 `elapsed_sec` 影响无尽续玩计时 · `profile_manager.gd:88-96` |
| COMBO_MARK 增伤 | ⚠️**复核修正**:文档 +5% 是 **VULNERABILITY** 状态的公式(`consecutive_hits_stacking.md:80`),非 COMBO_MARK | COMBO_MARK 每层 +2%VULNERABILITY 未实现 | 审计原文把两个机制混为一谈;数值本身 +2% 确认 · `enemy_manager.gd:245` |
| CastStats/SpellContext/ProjectileDef 字段集 | 文档伪代码列出大量字段(pierce/bounce/homing/payloads/on_kill…) | 精简字段集,逻辑层实际用的更少 | 文档伪代码严重过期 · `cast_stats.gd:6-13`, `spell_context.gd:7-11`, `projectile_def.gd` |
| ProjectileDef 管线 | ACTION 填 ProjectileDef → 批量生成,`SpellContext.payloads` 队列 | `_push_projectile` 直接调 `spawn_bullet(裸参数)`ProjectileDef 类未实例化(死代码) | 模板→池设计被绕过 · `spell_evaluator.gd:431-436` |
| ENEMY SoA +6/+7 语义 | `+6 faction_and_type` 打包、`+7 status_bits` 位掩码 | `+6` 仅存 type、`+7` 当存活标志 | 友军 faction 与内联状态位未落地 · `enemy_manager.gd:129-130` |
| MinionManager 结构 | ADR-R4-N4 SoA stride=8 | Array[Dictionary] | 见 C 节更优(文档内部矛盾,选了 §5.12) |
| SCOPE_CLOSE 作用域机制 | 预编译注入 SCOPE_CLOSE 虚节点 + label_table | 用"扫描到下一 TRIGGER 即停"直接分包,SCOPE_CLOSE 未使用 | 残留脚手架,实际方案更简单 · `spell_evaluator.gd:63-96` |
### 🟠 未实现 — 设计了但代码没有(或仅字段占位)
**整块缺失的系统:**
- **元进展全套** —— 以太碎片、局外解锁树、图鉴 Codex、成就、炼金日志。`scripts/` 下仅 1 个孤立的 `ACHIEVEMENT_UNLOCKED=18` 事件常量(无订阅方、无系统),其余 `aether/fragment/codex/unlock` 零命中。(`game_design §7`;无对应 autoload/字段)
- **Boss 系统架构** —— `BossManager` Autoload、`BossPhaseDef` / 攻击模式注册表、场地机制(冰墙 / 场地收缩)、多阶段弹幕全部 0% 实现。Boss 是 `EnemyManager` SoA 里 `type=4/5` 的普通敌人,唯一"阶段行为"是进阶时召唤一批 FAST 杂兵。(整个 `boss_design.md``wave_manager.gd:85,94-117`
- **Mana 魔力系统** —— 核心平衡资源,`player_stats.gd` 无 mana 变量。(`game_design §4.1`
- **里程碑 W5/W10/W15 / 练习模式 / Boss Rush / Endless 全局词条 / NG+ Phase4 / W20 通关演出 / GAME_CLEARED** —— 均未实现;游戏只能靠死亡结束。(`game_design §8`
- **TutorialManager + 情境提示 + 渐进解锁(局1-5)+ 靶场慢放 DPS 演示** —— 实际只有首启难度三选一弹窗。(`tutorial_design.md` 全文;`main_menu.gd:277-353`
- **战前 "The Lab" 独立准备界面 + 拖拽式背包** —— 改为商店内点击选中式插槽编辑器(功能等价,交互与入口偏离)。(`game_design §5.1``combat_s2.gd:532-662`
- **伤害飘字 DamageNumber** —— 全无。(`architecture_design.md:2534,3359`
**字段占位但无行为:**
- **归航子弹** —— `_enemy_pos_snapshot` 每帧填充(P6-N25 预分配满足)但 `_gd_integrate` 无 homing 计算,快照无人消费。`bullet_manager.gd:31,36-51`
- **连锁 / 弹跳** —— `bounce_remaining` 字段存在但从不消费;无 `visited_targets`、无 `pow(0.9, bounce)` 衰减。`bullet_manager.gd:97-104`, `enemy_manager.gd:240-257`
- **轨迹修正**(正弦 / 回旋镖 / 环绕)—— 全库无相关字段或分支。(`weapon_system_expansion.md §1`
- **元素抗性 `(1-Res)`** —— `calc_damage(armor, resistance)` 公式正确,但实战路径恒传 `resistance=0`,抗性维度是死代码。`damage_context.gd:26-28`, `enemy_manager.gd:236-237`
- **催化 / 环境反应 / 状态交互矩阵** —— `can_catalyze` 是死字段,`StatusRegistry` 不解析该键;无 overwrite/immunity/反应地表。`status_registry.gd:20-30`
- **硬控与增幅状态** —— `FREEZE/WET/OILY/STUN/VULNERABILITY` 有 StatusID 常量但 `status_effects.json` 只定义了 Burn/Poison/Combo 三条;VULNERABILITY 叠层增伤未接线。`status_effects.json:2-4`, `enemy_manager.gd:244-245`
- **Core 特性标签** —— 5 个里只有 `PERSISTENT_MEMORY` 生效;`dual_stream / shuffle_deck / infinite_spells / always_cast_last` 除定义处无任何引用。`core_feature_tag.gd:6`
- **MATRIX 邻接表** —— P6-N13 的 6 行表中 4 个"加成行"只实现 3 个,缺 `ACTION+TRIGGER`(增压触发 proc_rate ×1.5)。`spell_evaluator.gd:232-244`
- **共鸣 `anywhere_in_deck`** —— 仅 stub,非 `adjacent` 直接跳过。`spell_evaluator.gd:272-273`
- **召唤物多形态** —— 只实现 Stationary(炮台);随从/卫星/镜像无 hp/behavior_state/移动/碰撞。`minion_manager.gd:29-42`
- **敌人 LOD 屏内剔除** —— `_visible_flags` 声明却从不置 1,屏外低频分离力未实现。`enemy_manager.gd:25,312-316`
- **商店货架 B(核心)/ C(属性)/ 出售退款 G5** —— 只实现货架 A(法术抽取)。`shop_manager.gd:33-46`
- **玩家属性池** —— §4.3 的 5 条 MVP 属性只实现 CPU 一条;无 cast_speed/mana_leech/accuracy/attunement。`player_stats.gd:9-23`
- **掉落表** —— 所有敌人固定 `XP=5 / GOLD=2`,无按类型掉落表、无地面拾取物。`drop_manager.gd:7-15`
---
## 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`
2. **`modifier_pierce_plus` 是空操作**:玩家能在商店买到,但 `_apply_modifier` 不识别 `pierce``CastStats` 无该字段 → **买了没效果**`spell_evaluator.gd:488-501`, `cast_stats.gd:6-13`
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`
5. **战前无 Deck 防呆校验**:可携带空 / 纯 Modifier 卡组进战斗(`game_design §5.1` 要求拦截并提示"法术塔无法开火")。`combat_manager.gd:220-228`
---
## E. 文档**自身**的内部矛盾(改代码前先修文档)
| 矛盾点 | 冲突来源 | 代码事实 |
|---|---|---|
| Boss 波次 W8 vs W10 | `game_design §4.5`(W10) vs `§8.3`(W8) vs `boss_design`(W8) | W8 miniboss / W20 final`waves.json:9,21` |
| Boss 血量 | `numerical §3.2`=50000 vs `boss_design §5`=10000 vs balance=1800 | 1800`balance.json:8-11`)——数值策划 DPS 门槛基于错误血量 |
| Boss 阶段阈值 | 三处不一:`§4.5` schema=50%/10%、`boss_design` mini=60%/30% & final=70%/40%/15% | 代码 66%/33% | 文档需先自洽再对齐 |
| Boss EventID | `boss_design §6` 称 15/16/17 "已登记勿改" | 15/16/17 被 SPELL_EQUIPPED/LEVEL_UP/SHOP_OPENED 占用;三个 Boss 事件常量不存在(`event_ids.gd:25-32` |
| MinionManager 结构 | `§8 ADR-R4-N4`(SoA) vs `§5.12`(Array) | 代码选 Array`minion_manager.gd` |
| 内容创作教程 | handbook 02(教改硬编码 `wand_preset.gd`/`WAVE_CONFIG`vs handbook 07JSON 编辑器) | 早已 JSON 化,handbook 02 会误导人改不存在的代码 |
---
## F. 建议的后续动作(按风险/价值排序)
1. **改文档以追认更优实现**(低风险,先做):`architecture_design.md``.tres`/`ConfigMgr` 段、handbook 02、E 节全部文档矛盾、ADR-A2 存档伪代码 —— 对齐代码现状。
2. **修潜在 bug**(小改动高价值):CoreFeatureTag 改真·位标志(或改回 String + `in` 判断)、pierce 修正器接线、战前 Deck 防呆校验。
3. **补关键玩法缺口**(按优先级排期):Mana 系统 → 元进展 → Boss 阶段/抗性 → 属性词条。这些是"设计核心但未实现",属真正的功能待办,非文档问题。
---
## G. 复核(对抗性验证)结论与"代码 vs 文档 更优"判定
> **复核方法**2026-07-20 就地复核,6 个独立验证 agent 分域对本报告逐条**对抗性重验**(默认怀疑、行号全部从当前代码重新推导、代码不支持则证伪)。共复核约 65 条主张。
### G.1 准确性结论
- **零条被证伪(REFUTED)**。全部实质结论成立,关键 `file:line` 抽查无漂移。
- **两个 latent bugD1 CoreFeatureTag 位运算、D2 pierce 空操作)经完整数据流追踪,均确认为真。**
- 少数措辞修正(已并入正文,不影响结论):
1. 碰撞 SpatialGrid-only 的功劳被错记到"§4.3 自身 R-04"——实为**文档自相矛盾**(§4.3/§4.4 描述 Area2D 优先,R-04 锁定决议在 `implementation_plan.md`)。
2. MAX_OPS`MAX_OPS_PER_CPU=40` 其实与多数文档一致,真正缺陷是硬编码 `×5` 不读 cpu_limit;且文档自身 8 vs 40 不一致。
3. COMBO_MARK +2% 属实,但文档"+5%"是 **VULNERABILITY**(未实现)的公式,被审计混为一谈。
4. MATRIX"五行只实现三行"应为"6 行表中 4 个加成行实现 3 个"。
5. 元进展"grep 零命中"实为"1 个孤立 `ACHIEVEMENT_UNLOCKED` 事件常量"。
6. UI"仅 4 个 .tscn"应为"4 个游戏场景 + 1 个编辑器插件场景"。
7. XP `roundi` 分歧可忽略(反而更贴合文档数值表)。
8. Boss 阶段阈值实为**三处**互相矛盾(50/10、60/30、70/40/15),不止两处。
### G.2 "代码 vs 文档 更优"判定汇总
**🟢 代码更优 —— 建议改文档追认(低风险,先做)**
| 分歧 | 为何代码更优 |
|---|---|
| JSON + 7 页签编辑器(弃 `.tres`/`ConfigMgr`) | 策划零代码可视化编辑;Godot Inspector 路线对本项目内容量无优势 |
| 存档 A/B 按 `saved_at` 选最新槽 | 正确处理"两槽都有效但一旧"场景,文档"固定顺序取第一个"会错取旧槽 |
| MultiMesh 单档常开(弃三档切换) | 碰撞已 SpatialGrid-only,子弹无法挂 Area2D,Node 池档位无意义;消除切换卡顿 |
| `execute_compiled(compiled, caster_id, pos)` | VM 内部自管 ctx,执行期无需 live `core`;快照随每次 compile 失效,自洽 |
| `compile_wand(core, Array)` | flatten 直接索引 Array,包成 SpellDeck 纯属仪式;P6-N65 所述崩溃不会发生 |
| `is_combo_tracker` 提前落地 | 文档标 P2,代码已实现且正确守卫 DoT |
| `_flatten_linear` 扫描到下个 TRIGGER(弃 SCOPE_CLOSE/label_table | 更简单且功能等价;SCOPE_CLOSE 是应删的死脚手架 |
| `spawn_bullet` 扁平参数 + cold_data(绕过 ProjectileDef | 避免热路径每发 RefCounted 分配;ProjectileDef 类应删 |
| ZoneManager 调 `StatusManager.apply(5 参)` | 代码签名/调用正确,文档 §8 内联伪代码是错的 4 参 |
**🔴 文档更优 / 真实缺陷 —— 建议改代码(补功能或修 bug)**
| 分歧 | 类型 |
|---|---|
| `CoreFeatureTag` 位运算冲突(1..5 非 2 的幂)| **Bug**:改真·位标志或改回 String+`in` |
| `modifier_pierce_plus` 空操作(可购买无效果)| **Bug**:接线 pierce 到 CastStats/_apply_modifier |
| MAX_OPS 硬编码 `×5` 不读 cpu_limit | **Bug/缺口**CPU 词条对施法预算无影响 |
| 战前无 Deck 防呆校验 | **缺口**:可带纯 Modifier 卡组进战斗 |
| Mana 系统 / 元进展 / 属性词条(4/5) / Boss 阶段·抗性 / 商店 B·C 货架 / 5 个 Core 特性标签(4/5) / MATRIX 增压触发 / 连锁弹跳 / 轨迹修正 / 元素催化 / 里程碑·NG+·通关 / TutorialManager·渐进解锁·靶场 / 归航 / DamageNumber / LOD 剔除 | **功能待实现**(设计核心,非文档错误)|
**🟡 中性 —— 纯陈旧或文档自相矛盾,改文档即可(不改代码)**
`.tres`/`ConfigMgr` 段、handbook 02 硬编码教程、CastStats/SpellContext 字段伪代码、collision §4.3/§4.4、boss 血量(50000/10000/1800)、boss 阶段阈值(三处不一)、W8 vs W10、boss EventID 15/16/17、MinionManager §5.12 vs ADR-R4-N4、tutorial_design EventID、存档 ADR-A2 伪代码、排行榜 Schema、COMBO/VULN 混淆、Endless 膨胀曲线、XP roundi、charge 进度环→文字(占位)、i18n 债务。
> **一句话**:本审计报告经独立对抗性复核**准确可信**;分歧中约 9 项代码更优(改文档追认)、3 个真实 bug + 一批未实现功能属文档更优(改代码),其余为文档陈旧/自相矛盾(仅改文档)。
---
## 附:审计覆盖的域与主要文件
| 审计域 | 主要代码 | 对照文档 |
|---|---|---|
| Spell VM / Wand·Core | `spell_evaluator.gd`, `sub_payload_registry.gd`, `wand_preset.gd`, `spell_registry.gd`, `scripts/core/*` | `core_wand_design.md`, `architecture_design.md §3`, `weapon_system_expansion.md` |
| 战斗 SoA 核心 | `bullet_manager.gd`, `enemy_manager.gd`, `spatial_grid.gd`, `csharp/**`, `combat_s2.gd` | `architecture_design.md §4/§6`, `implementation_plan.md §2.3` |
| 波次/Boss/难度 | `wave_manager.gd`, `enemy_manager.gd`, `settings_manager.gd`, `data/{waves,enemies,balance}.json` | `boss_design.md`, `game_design.md §4/§8`, `numerical_design.md` |
| 状态/区域/召唤/VFX/DPS | `status_manager.gd`, `status_registry.gd`, `zone_manager.gd`, `minion_manager.gd`, `vfx_manager.gd`, `dps_tracker.gd` | `advanced_mechanics_*.md`, `combat_mechanics_*.md`, `consecutive_hits_stacking.md`, `architecture_design.md §8` |
| 数据驱动/存档/经济/元进展 | `config_mgr.gd`, `shop_manager.gd`, `drop_manager.gd`, `profile_manager.gd`, `endless_records.gd`, `player_stats.gd`, `addons/**` | `architecture_design.md §2`, `game_design.md §5/§7/§8`, handbook 02/07 |
| UI/流程/FTUE/i18n/设置/音频 | `combat_s2.gd`, `combat_manager.gd`, `scene_manager.gd`, `locale_manager.gd`, `settings_manager.gd`, `audio_manager.gd`, `scenes/ui/*` | `game_design.md §5/§6`, `tutorial_design.md`, `architecture_design.md §5`, handbook 04 |