diff --git a/README.md b/README.md new file mode 100644 index 0000000..3ef2e90 --- /dev/null +++ b/README.md @@ -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.6ms(16.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` 常量解耦 +- **数据布局**:SoA(Structure 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)(S0–S6 垂直切片) · [`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` 并在此说明。 diff --git a/docs/README.md b/docs/README.md index e5f8d5e..54d67a3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -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/`) | --- diff --git a/docs/design/core_wand_design.md b/docs/design/core_wand_design.md index 44c4f7b..df72642 100644 --- a/docs/design/core_wand_design.md +++ b/docs/design/core_wand_design.md @@ -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 复制到 SpellContext(SpellContext 不持有 Core 引用;ctx.core_feature_tags 不存在)。 +# ⚠️ 实现现状(2026-07-20):真实签名 execute_compiled(compiled, caster_id: int, spawn_pos: Vector2)——不传 ctx/core,feature_tags 从 CompiledDeck 编译期快照读取 func execute_compiled(compiled: CompiledDeck, ctx: SpellContext, core: CoreDefinition) -> void: _run_deck(compiled, ctx) # SpellEvaluator 不感知拓扑,仅执行线性化节点序列 diff --git a/docs/design/game_design.md b/docs/design/game_design.md index 50a3bc1..af4c3b1 100644 --- a/docs/design/game_design.md +++ b/docs/design/game_design.md @@ -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** 触发里程碑事件: | 里程碑 | 即时奖励 | 解锁内容 | diff --git a/docs/design/numerical_design.md b/docs/design/numerical_design.md index 1fb2d6c..c022806 100644 --- a/docs/design/numerical_design.md +++ b/docs/design/numerical_design.md @@ -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发/秒时)}$$ diff --git a/docs/design/tutorial_design.md b/docs/design/tutorial_design.md index f35728c..7a20afb 100644 --- a/docs/design/tutorial_design.md +++ b/docs/design/tutorial_design.md @@ -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 专用,已定义)。 diff --git a/docs/handbook/02_content_authoring.md b/docs/handbook/02_content_authoring.md index 357f6f9..142c5c7 100644 --- a/docs/handbook/02_content_authoring.md +++ b/docs/handbook/02_content_authoring.md @@ -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 迁移删除,请勿参照。 --- diff --git a/docs/handbook/05_release_guide.md b/docs/handbook/05_release_guide.md index 40103d4..0c813bd 100644 --- a/docs/handbook/05_release_guide.md +++ b/docs/handbook/05_release_guide.md @@ -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` --- diff --git a/docs/handbook/README.md b/docs/handbook/README.md index e8fb1f5..5e81535 100644 --- a/docs/handbook/README.md +++ b/docs/handbook/README.md @@ -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/ ← 开发计划 / 认证清单 / 归档草案 ``` --- diff --git a/docs/mechanics/advanced_mechanics_summons_and_environment.md b/docs/mechanics/advanced_mechanics_summons_and_environment.md index ffaad44..428aa6f 100644 --- a/docs/mechanics/advanced_mechanics_summons_and_environment.md +++ b/docs/mechanics/advanced_mechanics_summons_and_environment.md @@ -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) diff --git a/docs/mechanics/combat_mechanics_depth.md b/docs/mechanics/combat_mechanics_depth.md index 6a7e777..d548889 100644 --- a/docs/mechanics/combat_mechanics_depth.md +++ b/docs/mechanics/combat_mechanics_depth.md @@ -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)** 系统。 本文档详细定义了扩展战斗深度所需的关键维度和判断逻辑。 diff --git a/docs/mechanics/consecutive_hits_stacking.md b/docs/mechanics/consecutive_hits_stacking.md index f6334bb..7d15c1a 100644 --- a/docs/mechanics/consecutive_hits_stacking.md +++ b/docs/mechanics/consecutive_hits_stacking.md @@ -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 tick(COMBO_MARK 不误触发 DoT)。详见 [审计报告](../../docs_dev/doc_code_audit_2026-07-20.md)。 + ## 需求分析 用户希望实现“对同一个目标,同一种伤害在一定间隔内认定为持续多次伤害,从而可以制作伤害叠加”。 diff --git a/docs/mechanics/weapon_system_expansion.md b/docs/mechanics/weapon_system_expansion.md index e60aadd..a2ea5e2 100644 --- a/docs/mechanics/weapon_system_expansion.md +++ b/docs/mechanics/weapon_system_expansion.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** 架构,可以进一步扩展的玩法机制。 当前的系统已经支持了基础的投射物、霰弹、激光,以及修正器(多重施法、弹射、追踪、穿透、连锁、冰冻)。在此基础上,我们可以引入更高级的策略组合和“涌现式”玩法。 diff --git a/docs/technical/architecture_design.md b/docs/technical/architecture_design.md index 5b4ddb8..be6d151 100644 --- a/docs/technical/architecture_design.md +++ b/docs/technical/architecture_design.md @@ -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-only,Node 池档位已无意义,此简化为**代码更优**。详见 [审计报告](../../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-01;C# 热路径 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)。 + 商业 Roguelite(Hades / Slay the Spire / Balatro)均支持中途退出后恢复到当前波次起始状态。 **存档时机**: diff --git a/docs/technical/boss_design.md b/docs/technical/boss_design.md index 88ba49a..a7d1679 100644 --- a/docs/technical/boss_design.md +++ b/docs/technical/boss_design.md @@ -5,6 +5,10 @@ --- +> **⚠️ 实现现状 (2026-07-20 审计)**:本文档描述的整套 Boss 架构(`BossManager` Autoload、`BossDef`/`BossPhaseDef`/`.tres` 资源、`BossAttackRegistry` 攻击模式注册表、场地机制如冰墙/场地收缩、多阶段弹幕、状态机 `BossInstance`)**均为设计蓝图,代码 0% 实现**。现状 Boss 只是 `EnemyManager` SoA 中 `type=4`(Mini Boss,Wave 8)/`type=5`(Final Boss,Wave 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.5;enrage_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+)——**均未实现** | --- diff --git a/docs_dev/README.md b/docs_dev/README.md new file mode 100644 index 0000000..ce4b36f --- /dev/null +++ b/docs_dev/README.md @@ -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/` 下。 diff --git a/docs/architecture_design.md b/docs_dev/archived_cocos_architecture_draft.md similarity index 99% rename from docs/architecture_design.md rename to docs_dev/archived_cocos_architecture_draft.md index 3376273..01f0ee4 100644 --- a/docs/architecture_design.md +++ b/docs_dev/archived_cocos_architecture_draft.md @@ -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) --- diff --git a/docs/plan/certification_checklist.md b/docs_dev/certification_checklist.md similarity index 100% rename from docs/plan/certification_checklist.md rename to docs_dev/certification_checklist.md diff --git a/docs/plan/development_plan.md b/docs_dev/development_plan.md similarity index 100% rename from docs/plan/development_plan.md rename to docs_dev/development_plan.md diff --git a/docs_dev/doc_code_audit_2026-07-20.md b/docs_dev/doc_code_audit_2026-07-20.md new file mode 100644 index 0000000..723f453 --- /dev/null +++ b/docs_dev/doc_code_audit_2026-07-20.md @@ -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% GDScript,C# 为死骨架 | 🔴/顺延(R-08);实测 500 敌 1500 弹 ≈0.6ms,GDScript 够用 | +| 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)⌋`(floor,P6-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 到 0;GDScript 版 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 07(JSON 编辑器) | 早已 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 bug(D1 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 |