geometry-tower-defense/docs/CodeX-TODO.md

359 lines
39 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CodeX TODO
最后更新2026-03-12
> 目标:基于当前仓库现状,为 `docs/TODO.md` 的 M1 收口补一份更可执行的补充顺序。
> 原则:先收主流程,再补硬规则,最后统一文档与验收口径。
## 执行规则
1. 优先完成会阻塞 M1 验收的内容,不提前展开 M2 深度功能。
2. 每一项先收“流程可走通”,再收“规则完整”,最后再做表现层补齐。
3. `ProcedureMain + NodeMapForm + PlayerInventory + CombatNode` 视为当前主链路,后续补充都围绕这条链路推进。
## 阶段 S1 - 收口主流程
| 状态 | ID | 任务 | 交付物路径 | 验收标准 |
|-----|-------|--------------------------------|----------------------------------------------------------------------------|--------------------------|
| [x] | S1-01 | 统一梳理 M1 当前状态与文档口径 | `docs/CodeX-TODO.md`<br>`docs/TODO.md` | 当前实现、目标状态、未完成项三者口径一致 |
| [x] | S1-02 | 收口 `ProcedureMain` 的 Run 推进主链路 | `Assets/GameMain/Scripts/Procedure/` | 从开始游戏到 Boss 结算可稳定走完整条链 |
| [x] | S1-03 | 收口节点进入、完成、失败后的统一回流 | `Assets/GameMain/Scripts/Procedure/`<br>`Assets/GameMain/Scripts/Event/` | 战斗 / 事件 / 商店都能统一推进当前 Run |
| [x] | S1-04 | 收口 Run 完成后的正式结束态 | `Assets/GameMain/Scripts/Procedure/`<br>`Assets/GameMain/Scripts/UI/Game/` | 10 节点完成后有明确的结束表现与收尾逻辑 |
## S1 验收清单
### 手工流程验收
- [x] 从主菜单进入游戏后,能进入 `ProcedureMain`,并看到 `NodeMapForm + MainForm`
- [x] 当前节点可进入,非当前节点不可进入。
- [x] 普通战斗节点胜利后,会返回节点地图;当前节点变 `Completed`,下一节点变可进入。
- [x] 普通战斗节点在正常非胜利结算后(例如基地血量归零),会返回节点地图;当前节点仍按 `Completed` 处理,并推进到下一节点。
- [x] 战斗节点只在出现异常回退时,才会返回节点地图并把当前节点标记为 `Exception`;不会错误推进到下一节点。
- [x] 事件节点完成后,会返回节点地图,并推进到下一节点。
- [x] 商店节点退出后,会返回节点地图,并推进到下一节点。
- [x] 连续完成到第 10 个 Boss 节点后,不会再回普通 `NodeMapForm`
- [x] Boss 完成后,会弹出正式结束对话框,而不是只停在流程内部状态。
- [x] 点击结束对话框确认后,会切回 `Menu` 场景并重新进入主菜单。
- [x] 回到主菜单后,不残留 `NodeMapForm`、`MainForm`、`DialogForm`。
### 运行时状态验收
- [x] `Hub` 阶段下,只允许当前节点进入。
- [x] `NodeActive` 阶段下Hub UI 已关闭,不能重复从节点地图进入节点。
- [x] 普通节点成功后,会回到 `Hub`
- [x] 节点发生异常回退后,会回到 `Hub`,但不会推进下一节点。
- [x] Boss 成功完成后,会进入 `RunCompletedPendingFinish`,并由正式结束态接管。
- [x] 正式结束态确认后,会走 `ProcedureChangeScene -> ProcedureMenu` 的回菜单链路。
### 回归测试验收
- [x] Unity Test Runner 的 `Assets/Tests/EditMode` 全部通过。
- [x] `RunState` 创建、固定序列、成功推进、异常标记相关测试全部通过。
- [x] `NodeCompleteEventArgs` 正常完成、正常非胜利、异常回退三种语义与库存快照 clone 测试全部通过。
- [x] `ProcedureMainRunFlowService` 的成功推进、异常回退、`RunCompleted`、`NoChange` 分支测试已补齐并全部通过。
- [x] `ProcedureMainRunCompletionService` 的“只弹一次结束对话框”和“只在完成态允许回菜单”测试已补齐并全部通过。
> 2026-03-09 更新:已补 `NodeCompleteEventArgs` 三种语义测试,以及 `ProcedureMain` 当前节点匹配守卫测试;你已确认本轮在 Unity Test Runner 中重新实跑 `Assets/Tests/EditMode` 且全部通过。
### S1 通过标准
- [x] 从主菜单开始,一条 Run 可以稳定经历“节点进入 -> 节点完成 / 异常回流 -> Boss 完成 -> 正式结束态 -> 返回主菜单”且过程中不会出现错误推进、重复进入、Boss 后回到普通 Hub、或 UI 残留。
## S1-01 对齐结论
### 当前实现
- `ProcedureMain + NodeMapForm` 已能创建固定 10 节点 Run并驱动战斗 / 事件 / 商店三类节点的主流程入口。
- `RunState`、`FixedRunNodeSequenceBuilder`、`RunStateAdvanceService` 与对应 Editor 测试已存在,说明 Run 模型、固定序列、节点推进基础能力已经落地。
- 战斗节点已有结算、奖励选择、失败返回;事件和商店节点也会发出 `NodeEnterEventArgs / NodeCompleteEventArgs`,主流程闭环已能稳定走通。
- `P0-10 ~ P0-12` 已完成当前 M1 口径收口:
- 出战前已按“三组件完整且未损坏”的统一规则校验合法参战塔;
- 品质 / Tag 已完成统一生成、汇总、展示与首发 7 个 Tag 的战斗生效;
- 耐久已完成“每场固定扣 1、归零失效、自动移出参战区”的最小闭环。
### M1 目标状态
- M1 验收口径应以“从开始游戏到 Boss 节点结算结束,当前 Run 能稳定走完整条链”为准。
- `NodeMapForm` 已可视为 M1 所需的节点流程界面M1 不额外要求节点地图选择 UI 或表现层打磨。
- 战斗 / 事件 / 商店都需要统一节点进入、完成、失败后的回流方式,避免每类节点各走一套。
- 出战合法性需要从“至少有参战塔”收口为“满足完整三组件条件才可出战”。
### 当前剩余缺口
- `S3` 已完成收口,不再把“三组件完整合法参战”视为 `P0-10` 的功能缺口;对应文档与状态已同步。
- 品质 / Tag / 耐久不再是“只有局部实现”的状态:`S4-02 ~ S4-07` 与 `S5-01 ~ S5-04` 已落地M1 主功能侧当前已无未收口项,后续重点转入测试补强与旧文档清理。
## 阶段 S2 - 对齐节点流程 UI 的 MVP 口径
| 状态 | ID | 任务 | 交付物路径 | 验收标准 |
|-----|-------|--------------------------------|------------------------------------|------------------------|
| [x] | S2-01 | 确认 `NodeMapForm` 已满足 M1 所需的节点流程界面 | `docs/CodeX-TODO.md`<br>`docs/TODO.md` | 不再把“正式节点地图表现”视为 M1 阻塞项 |
| [x] | S2-02 | 明确 M1 不扩展节点地图选择 UI 与表现层打磨 | `docs/CodeX-TODO.md`<br>`docs/MVP-Scope.md` | 与 `MVP-Scope.md` 的范围口径一致 |
## 阶段 S3 - 收口出战合法性
| 状态 | ID | 任务 | 交付物路径 | 验收标准 |
|-----|-------|------------------|--------------------------------------------------------------------------------------------------|--------------------|
| [x] | S3-01 | 定义“合法参战塔”的最终判定口径 | `docs/CodeX-TODO.md`<br>`Assets/GameMain/Scripts/Definition/` | 流程层与 UI 层共用同一套判定口径 |
| [x] | S3-02 | 收口组装区与参战区的合法性校验 | `Assets/GameMain/Scripts/UI/Game/`<br>`Assets/GameMain/Scripts/CustomComponent/PlayerInventory/` | 不合法塔不能进入参战区 |
| [x] | S3-03 | 在战斗入口补齐最终出战校验 | `Assets/GameMain/Scripts/Procedure/` | 不满足完整条件时无法进入战斗节点 |
| [x] | S3-04 | 给出 UI / 日志层明确反馈 | `Assets/GameMain/Scripts/UI/Game/`<br>`Assets/GameMain/Scripts/Procedure/` | 玩家知道为什么不能出战 |
### S3-01 判定口径
- `S3-01` 只收口 M1 所需的最小合法参战规则:塔实例存在,且能解析到枪口 / 轴承 / 底座三个组件实例。
- 当前阶段不把品质、Tag、耐久、属性强度纳入“合法参战塔”定义这些仍分别留在 `S4`、`S5` 收口。
- 流程层、库存层、UI 层后续都必须共用同一个判定入口,不能再分别维护“至少有塔”“参战区非空”“组件看起来完整”这类分散判断。
- 判定结果不能只返回 `bool`,还要能区分至少以下失败原因:塔不存在、缺枪口、缺轴承、缺底座。
- 批量校验参战区时,需要同时给出“合法参战塔列表”“非法参战塔及原因”“是否至少存在一座合法参战塔”三个结果,供 `S3-02 ~ S3-04` 直接复用。
> 2026-03-09 更新:`CombatParticipantTowerValidationService`、`CombatParticipantTowerValidationResult`、`CombatParticipantTowerValidationSummary` 已落地Unity Test Runner 已确认相关 EditMode 测试通过。
### S3-02 当前落地状态
- 参战分配链路已统一改为返回结果对象,而不是只返回 `bool`
- `RepoFormUseCase`、`PlayerInventoryComponent`、`PlayerInventoryTowerRosterService`、`InventoryParticipantUtility` 已接入 `S3-01` 的统一合法性校验入口。
- 当前可稳定区分以下分配失败原因:塔不存在、塔缺少三组件之一、已在参战区、参战区已满。
- 组装区 / 参战区 UI 仍保持“失败时静默拦截”的当前策略;战斗入口已补最终二次校验,避免旧快照、脏状态或外部改动绕过 `S3-02` 直接进入战斗。
- 战斗入口校验失败时,`ProcedureMain` 现在会同时写明失败日志,并弹出 `DialogForm` 给出明确原因;空参战区会提示“至少需要 1 座完整装配了枪口、轴承、底座的塔”,脏数据则会列出具体缺失组件。
> 2026-03-09 更新:你已在 Unity Test Runner 中确认 `Assets/Tests/EditMode` 全部通过,其中包含 `CombatParticipantTowerValidationServiceTests` 与 `ParticipantTowerAssignResultTests`。
>
> 2026-03-09 更新:`ProcedureMainCombatEntryValidationService` 与战斗入口拦截已落地;你已确认 Unity Test Runner 全部通过,并手工验证了“空参战区开始战斗”会被拦截且弹出明确提示。
## 阶段 S4 - 收口品质 / Tag 规则
| 状态 | ID | 任务 | 交付物路径 | 验收标准 |
|-----|-------|-------------------------|--------------------------------------------------------------------------------------------------------------------------------------|-----------------------------|
| [x] | S4-01 | 先确定 M1 需要的品质 / Tag 规则边界 | `docs/CodeX-TODO.md`<br>`docs/TODO.md` | 文档先对齐,再落代码 |
| [x] | S4-02 | 把品质计算整理成单一入口 | `Assets/GameMain/Scripts/Definition/`<br>`Assets/GameMain/Scripts/CustomComponent/PlayerInventory/` | 组装、掉落、商店使用一致结果 |
| [x] | S4-03 | 先固化 Tag 系统设计与首发范围 | `docs/TagSystemDesign.md`<br>`docs/CodeX-TODO.md` | Tag 的来源、汇总、生效与首发集合口径固定 |
| [x] | S4-04 | 实现组件实例 Tag 的统一生成入口 | `Assets/GameMain/Scripts/Definition/`<br>`Assets/GameMain/Scripts/CustomComponent/PlayerInventory/` | 掉落、商店、初始种子、事件奖励共用同一生成结果 |
| [x] | S4-05 | 实现组塔后的 Tag 汇总与展示入口 | `Assets/GameMain/Scripts/Definition/`<br>`Assets/GameMain/Scripts/CustomComponent/PlayerInventory/`<br>`Assets/GameMain/Scripts/UI/` | 组件 Tag 可汇总为塔级结果,且 UI 展示口径一致 |
| [x] | S4-06 | 实现首批基础 Tag 的战斗生效 | `Assets/GameMain/Scripts/Entity/`<br>`Assets/GameMain/Scripts/Components/`<br>`Assets/GameMain/Scripts/Definition/` | 首发 6~8 个基础 Tag 至少完成一批可验证效果,且战斗入口与状态运行时结构可继续扩展 |
| [x] | S4-07 | 补齐 Tag 规则与数据表的映射关系 | `Assets/GameMain/Scripts/DataTable/`<br>`Assets/GameMain/Scripts/Definition/` | 三表职责、默认值、运行时消费链与文档口径一致Tag 参数可配置可解释 |
> 2026-03-09 更新:`InventoryRarityRuleService` 已落地;塔品质计算与组件品质归一化已统一收口,`PlayerInventoryTowerAssemblyService`、`ShopFormUseCase`、`EnemyDropResolver`、`InventorySeedUtility` 已接入同一规则入口。你已确认 Unity Test Runner 中 `Assets/Tests/EditMode` 全部通过,其中包含新增的 `InventoryRarityRuleServiceTests`。
>
> 2026-03-09 更新:`S4-03` 文档口径已冻结;`TagSystemDesign.md` 已明确组件实例生成、塔级 `Stack` 汇总、四段触发阶段,以及 MVP 正式首发 7 个 Tag`Fire`、`Ice`、`Crit`、`Execution`、`Shatter`、`Inferno`、`AbsoluteZero`。`BurnSpread` 已明确后移。后续 `S4-07` 已进一步把配置层固定为 `Tag.txt + RarityTagBudget.txt + TagConfig.txt` 三表方案。
>
> 2026-03-09 更新:`S4-04` 已落地 `ComponentTagGenerationService` 与 `InventoryTagSourceType`;组件实例 Tag 现在统一按 `PossibleTag + Tag.txt.MinRarity + 品质预算` 生成,并只保留当前正式首发 7 个 Tag。`ShopFormUseCase`、`EnemyDropResolver`、`InventorySeedUtility` 已接入该入口,样例库存的组件与塔展示 Tag 已同步为统一结果;同时新增 `ComponentTagGenerationServiceTests`。当前 CLI 下 `dotnet build GeometryTD.sln` 仍因本机缺少 Unity 引用和 `Unity.SourceGenerators*.dll` 失败,未能替代 Unity Test Runner 完成最终验证。
>
> 2026-03-09 更新:`S4-05` 已新增 `TagRuntimeData` 与 `TowerTagAggregationService`;组塔与样例塔现在统一生成塔级 `TagRuntimes`,并保留兼容 `Tags` 投影。`RepoForm`、`CombatFinishForm`、`ItemDescForm` 的塔展示已切到聚合结果,重复 Tag 以 `xN` 文本显示;组件展示仍沿用组件实例 `Tags`。同时新增 `TowerTagAggregationServiceTests`;本轮改动后的最终验证仍以 Unity Test Runner 实跑结果为准。
>
> 2026-03-10 更新:`S4-06` 已完成第一段落地。战斗链现在已从旧的 `damage + AttackPropertyType` 入口提升为携带 `TagRuntimeData[]` 的命中载荷;`AttackPayload`、`HitContext`、`TagEffectResolver`、`EnemyTagStatusRuntime` 已接入主命中链。当前已实际生效的基础 Tag 为 `Fire`、`Ice`、`Crit`、`Execution`:其中 `Fire` 已改为独立 DOT 公式,并按 `EnemyEntity` 每帧提供的 `deltaTime` 连续结算;`Ice` 已有独立减速状态;`Crit` 与 `Execution` 已进入命中前数值修正。状态类 Tag 已按“每个 Tag 各自配置文件、状态文件、效果文件”的方式拆开,`EnemyTagStatusRuntime` 只负责按激活 Tag 动态 Tick不再持有具体 Tag 字段。
>
> 2026-03-10 更新:`S4-06` 已补齐首发剩余 3 个 Tag。`Shatter` 已接入命中前数值修正链,并按“目标已减速”口径增伤;`Inferno` 与 `AbsoluteZero` 已按首发方案作为 `Fire` / `Ice` 的强化 Tag 落地,分别增强 DOT 时长/伤害与减速时长/强度;对应 EditMode 测试已同步补齐。`BurnSpread`、`IgniteBurst`、`FreezeMask`、`Pierce`、`Overpenetrate` 仍保持分类与占位路由,没有实际战斗效果,因此仍属于后续扩展,不计入 `S4-06` 当前完成标准。
>
> 2026-03-11 更新:`S4-07` 已完成最终收口。当前仓库已明确采用 `Tag.txt + RarityTagBudget.txt + TagConfig.txt` 三表方案作为正式配置口径,其中 `Tag.txt -> DRTag -> TagGenerationRuleRegistry` 负责基础字典、生成门槛、权重与启用态,`RarityTagBudget.txt -> DRRarityTagBudget -> RarityTagBudgetRuleRegistry` 负责按品质的 Tag 数量预算,`TagConfig.txt -> DRTagConfig -> TagDefinitionRegistry` 负责触发阶段、描述与首发 7 个 Tag 的效果参数。`ComponentTagGenerationService`、`ShopFormUseCase`、`EnemyDropResolver`、`InventorySeedUtility`、`ItemDescForm` 与战斗运行时均已接入对应消费链;同时已把 registry 默认值对齐到三表当前数值,避免加载顺序或回退路径重新暴露旧口径。
### S4-01 边界结论
- `S4-01` 只收口 M1 所需的最小规则闭环先统一“品质如何算、Tag 如何生成/过滤、哪些链路必须共用同一结果”,当前阶段不要求 Tag 立即产生战斗效果。
- 品质在当前仓库中不是空白功能:组件实例已有 `Rarity` 字段,掉落、商店、初始种子都已能给组件实例赋品质;塔组装时也已有“三组件品质取平均并四舍五入”的现有实现。
- M1 对品质的目标口径是:塔品质必须由枪口 / 轴承 / 底座三个组件品质决定,且结果在组装、掉落、商店、展示、事件条件筛选等链路中可复现、可解释、口径一致。
- M1 当前不把“品质决定配件槽位数量”视为阻塞项;配件系统本体尚未进入主链路,这部分仍保留在后续深度阶段,而不是作为 `S4-01` 当下必须落地的规则。
- Tag 在当前仓库中也不是空白功能:组件表已有 `PossibleTag`,实例数据与展示链路也已有 `Tags` 字段与名称展示,但现在更接近“静态拷贝 + 展示消费”,还没有统一生成 / 过滤入口。
- M1 对 Tag 的目标口径是Tag 结果必须有统一来源,且在组装、掉落、商店、展示链路中可复现、可解释;不能再继续分散为“哪边方便哪边直接复制 `PossibleTag`”。
- `Tag.txt``MinRarity` 与三张组件表的 `PossibleTag` 都应视为 `S4-03 ~ S4-04` 的规则输入,而不是已经被完整消费的既成事实;当前文档必须明确这一点,避免误判为“表字段已落地”。
- 设计稿中的深度规则暂不纳入 M1 必收口范围:不要求现在就实现按品质随机 Tag 数量、不要求实现 Tag 等级成长,也不要求实现 Tag 的战斗数值效果。
### S4 拆分方案
- `S4-02` 只处理品质入口统一,不与 Tag 生成细节耦合;目标是把“塔品质计算、组件品质输入、展示品质”都收口到统一规则服务。
- `S4-03` 对应 `docs/TagSystemDesign.md` 的文档收口阶段:固定 Tag 的候选池、实例生成时机、组塔汇总方式、战斗触发阶段、以及 MVP 正式首发 7 个基础 Tag 的集合。
- `S4-04` 是 Tag 系统的第一段代码落地:为组件实例引入统一的 Tag 生成入口,不再直接复制 `PossibleTag` 全量候选;掉落、商店、初始种子、事件奖励必须共用同一套生成逻辑与随机口径。
- `S4-05` 负责把三组件 Tag 汇总为塔级结果,并统一背包、组装、商店、详情面板的展示口径;此阶段不要求完成全部战斗效果,但不能再停留在“简单并集去重”的临时实现上。
- `S4-06` 只落首批基础 Tag 的战斗效果,不一次展开全部 12 个 Tag优先级按 `TagSystemDesign.md` 收口为状态类和数值修正类,例如 `Fire`、`Ice`、`Crit`、`Execution`、`Shatter`、`Inferno`、`AbsoluteZero`。
- `S4-07` 负责把 Tag 设计真正映射回数据表与 DataRow不再只保留 `MinRarity``PossibleTag` 两个弱约束字段;至少要支持权重、触发阶段、说明或效果参数中的一部分配置化消费。
### S4-03 首发范围结论
- MVP 首发 Tag 总量仍受 `docs/MVP-Scope.md``6~8` 个约束,但当前正式首发集合已固定为 7 个。
- 首批优先做状态类与数值修正类,不优先做穿透、传播、爆炸、多命中等高侵入效果。
- 当前正式首发基础集合为:`Fire`、`Ice`、`Crit`、`Execution`、`Shatter`、`Inferno`、`AbsoluteZero`。
- `BurnSpread`、`Pierce`、`Overpenetrate`、`FreezeMask`、`IgniteBurst` 默认放到后续扩展阶段,不作为 `S4` 当前完成标准。
### S4 当前进度结论2026-03-10
- `S4-02 ~ S4-05` 已完成,品质、组件实例 Tag 生成、塔级 `TagRuntimeData` 汇总、以及 UI 展示口径都已收口。
- `S4-06` 已完成:战斗链已支持 Tag 透传与统一结算,正式首发 7 个 Tag `Fire`、`Ice`、`Crit`、`Execution`、`Shatter`、`Inferno`、`AbsoluteZero` 均已有可验证效果。
- `Shatter` 已接入命中前数值修正链;`Inferno`、`AbsoluteZero` 已按“强化现有 `Fire` / `Ice` 状态”的首发口径落地,状态类 Tag 的内部结构继续保持注册式运行时。
- `BurnSpread`、`IgniteBurst`、`FreezeMask`、`Pierce`、`Overpenetrate` 已进入分类与配置骨架,但仍属于后续扩展,不计入当前 `S4` 的完成标准。
- `S4-07` 已完成。当前仓库已具备 `Tag.txt -> DRTag -> TagGenerationRuleRegistry -> ComponentTagGenerationService`、`RarityTagBudget.txt -> DRRarityTagBudget -> RarityTagBudgetRuleRegistry -> ComponentTagGenerationService`、`TagConfig.txt -> DRTagConfig -> TagDefinitionRegistry -> 展示 / 战斗运行时` 三条正式消费闭环。
- 三表方案已经固定为本阶段正式口径,不再把单独的 `TagRule` 表视为当前 M1 的待决定项。
- `S4-07` 当前通过标准是“表字段被实际消费、参数可解释、运行时与文档口径一致”;这一标准已满足。
### S4-06 当前代码状态
- 命中链路已统一为 `AttackPayload -> HitContext -> TagEffectResolver`,子弹命中时不再只传裸 `damage`
- `Tower` 侧的 `TagRuntimes` 已能透传到战斗,且保留了旧 `Tags -> TagRuntimes` 的兼容入口,避免旧塔或旧展示数据在战斗中完全失效。
- 状态类 Tag 现在按职责目录拆分:
- `Metadata/Config`:每个 Tag 一个配置类
- `Combat/States`:每个状态类 Tag 一个运行时状态类
- `Combat/StatusEffects`:每个状态类 Tag 一个效果类
- `EnemyTagStatusRuntime` 已不再硬编码 `burn/slow` 字段,而是按激活的状态类 Tag 动态调度 Tick。
- `Fire` 已改为独立 DOT 公式:当前使用独立 `BurnDamagePerSecondPerStack`,并按敌人实体每帧提供的 `deltaTime` 连续结算,不再依赖命中伤害或内部 `TickInterval`
- `Ice` 仍是独立减速状态,移速倍率通过状态运行时聚合得到。
- `Crit`、`Execution`、`Shatter` 已通过数值修正链路生效;`Shatter` 当前按“目标已减速时增伤”收口。
- `Inferno``AbsoluteZero` 已不再是独立状态效果,而是分别在 `Fire` / `Ice` 生效时读取同次命中的强化 Tag 层数,增强 DOT 时长/伤害与减速时长/强度。
### S4 审计结论2026-03-12
- `S4-02 ~ S4-07` 的 M1 闭环已完成,当前不回滚其完成状态。
- 但本轮对 Tag 系统的静态审查确认:当前实现还存在 5 个会放大后续返工成本的结构问题。
- 这些问题分别是:
- 配置真相源与 DataTable 加载顺序仍不稳定,`IsImplemented` 的最终结果会受加载先后影响。
- 组件 Tag 随机口径还没有把 `RunSeed` 作为正式输入,当前“同 Run 可复现、跨 Run 可区分”的合同未完全落地。
- `AttackPayload + HitContext` 还不是稳定的统一战斗上下文,数值类 Tag 仍依赖散装参数扩展。
- `TagConfig.txt` 中一部分字段已进入配置层,但还没有成为运行时真实消费字段,存在“表能改、逻辑不跟”的风险。
- `TagSystemDesign.md` 里仍混有旧的 12 Tag / 流派草稿,正式口径与历史预案没有彻底拆开。
- 因此,`S4` 后续不再继续扩展新 Tag 功能,而是先进入新的审计整改阶段,优先修掉上述结构问题。
## 阶段 S5 - 收口耐久规则
| 状态 | ID | 任务 | 交付物路径 | 验收标准 |
|-----|-------|-----------------------|-------------------------------------------------------------------------------------------------|------------------------------|
| [x] | S5-01 | 先确认 M1 是否保留完整耐久闭环 | `docs/CodeX-TODO.md`<br>`docs/TODO.md` | 已明确按“最小耐久闭环”推进,不扩展维修/折价/自动销毁 |
| [x] | S5-02 | 若保留,定义耐久对属性/出战资格的影响方式 | `Assets/GameMain/Scripts/Definition/`<br>`Assets/GameMain/Scripts/Entity/` | 已统一为“归零失效、不可参战、非归零不衰减” |
| [x] | S5-03 | 实现耐久扣减后的实际生效 | `Assets/GameMain/Scripts/CustomComponent/PlayerInventory/`<br>`Assets/GameMain/Scripts/Entity/` | 已按“每场固定扣 1、仅扣本场参战塔”接进主链 |
| [x] | S5-04 | 实现 `0` 耐久失效闭环 | `Assets/GameMain/Scripts/CustomComponent/PlayerInventory/`<br>`Assets/GameMain/Scripts/UI/` | 已实现失效不可参战、仓库提示、节点结束后自动踢出参战区 |
### S5 规划结论
- `S5` 当前按“最小耐久闭环”推进,不展开维修、折价、复杂恢复、耐久与 Tag 联动等后续深度系统。
- M1 保留耐久规则,但当前目标只收口到“战斗后真实扣减 + 归零后真实失效 + UI 可解释”,不要求一并实现完整维修玩法。
- 本阶段优先保证耐久从展示字段变成实际规则入口,而不是继续增加额外经济系统或复杂数值衰减。
- `S5-01 ~ S5-04` 当前代码口径已完成:战斗后会真实扣减本场参战塔耐久,`0` 耐久会拦截参战与战斗入口,仓库详情会显示损坏状态,节点结束后会自动把损坏塔移出参战区并弹提示。
### S5-01 范围结论
- `S5-01` 建议明确保留耐久闭环,但只做组件实例级耐久,不新开修理站、维修货币、商店修复等额外系统。
- 当前阶段只处理战斗节点的耐久消耗;事件、商店、其他特殊节点暂不引入额外耐久变更。
- `0` 耐久当前建议先按“失效但不立即销毁实例”收口,避免在本阶段同时引入背包移除、组装解绑、自动清空参战区等高耦合逻辑。
### S5-02 推荐规则口径
- 耐久数据仍挂在组件实例上,塔本身不额外维护独立耐久池。
- 一座塔只要已装配的枪口 / 轴承 / 底座中任意一个组件耐久 `<= 0`,就视为损坏塔。
- 损坏塔不能进入参战区,也不能通过战斗入口最终校验。
- 当前阶段不实现“耐久越低属性越差”的连续衰减;在 `> 0` 耐久时,组件与塔仍按当前属性正常工作。
- 当前阶段不把耐久纳入品质、Tag、掉落或商店价格公式避免把 `S5` 扩成新的综合规则层。
### S5-03 推荐实现口径
- 每次战斗节点结算后,对本场实际参战塔所装配的三个组件各扣 `1` 点耐久。
- 扣减结果必须真实回写到库存快照 / 当前 Run 库存,而不是只改战斗内临时对象。
- 参战合法性统一复用现有校验入口扩展,不额外再造一套“耐久专用判断链”。
- 战斗入口仍需要保留最终二次校验,避免旧快照或外部改动绕过组装区 / 参战区限制。
- 当前仓库实现已经按此口径落地:不再沿用旧的“低血量才扣耐久、且扣全库存塔”的逻辑。
### S5-04 推荐闭环口径
- 组件耐久归零后,当前版本按“失效不可参战”收口,不立即自动销毁实例。
- 装配了 `0` 耐久组件的塔在 UI 上需要给出明确提示,例如“组件已损坏”或“耐久为 0无法参战”。
- 若塔已在参战区且组件在上一场战斗后归零,需要在后续刷新中把该塔视为非法参战塔,并通过统一校验入口阻止再次进入战斗。
- “自动销毁组件”与“自动拆塔”保留到后续阶段再决定,当前不作为 `S5` 通过标准。
- 当前仓库实现已经进一步收口:节点结束时会自动检查损坏参战塔,将其移出 `ParticipantTowerInstanceIds`,并通过 `DialogForm` 明确提示玩家。
- Boss 完成导致 Run 正式结束时仍会执行损坏塔清理但当前不会额外插入第二个耐久提示弹窗去覆盖“Run 完成”弹窗。
### S5 当前结论
1. `S5-01 ~ S5-04` 已按当前 M1 口径完成,不再作为 `P0-12` 的主阻塞项。
2. 当前未实现的是长期设计里的维修、自动销毁、耐久折价、连续属性衰减,这些后续若要恢复,应作为新的增强项重新拆分,而不是回滚当前 MVP 口径。
3. `CodeX-TODO`、`TODO`、`MVP-Scope`、`GameDesign`、`TagSystemDesign` 当前已经同步到同一执行口径;后续若继续调整 M1 / M2 边界,应同步回写这些设计文档。
## 阶段 S6 - 回归与文档收尾
| 状态 | ID | 任务 | 交付物路径 | 验收标准 |
|-----|-------|-------------------------|---------------------------------------|------------------------------------------------------------------------------------------|
| [x] | S6-01 | 补主链路回归测试 | `Assets/Tests/EditMode/` | Run 推进、节点回流、Boss 完成可回归验证 |
| [x] | S6-02 | 补规则侧测试 | `Assets/Tests/EditMode/` | 合法性、品质、Tag、耐久关键公式可验证 |
| [x] | S6-03 | 回写 `docs/TODO.md` 的真实状态 | `docs/TODO.md` | 文档状态与仓库现状一致 |
| [x] | S6-04 | 清理临时描述、过期 TODO、命名偏差 | `docs/`<br>`Assets/GameMain/Scripts/` | `CodeX-TODO`、`TODO`、`TagSystemDesign`、`MVP-Scope`、`GameDesign` 已完成主要口径同步;其余文档仅保留后续阶段设计描述 |
> 2026-03-11 更新:`S6` 的自动化测试实际落点已统一到 `Assets/Tests/EditMode`,不再使用 `Assets/GameMain/Tests/` 作为当前仓库测试路径口径。
>
> 2026-03-11 更新:本轮已补 `CombatSettlementServiceTests` 的结算金币、奖励选择失败分支、奖励库存写入与提交幂等测试;同时补 `ProcedureMainServicesTests` 的非终态快照替换行为、`ProcedureMainParticipantTowerCleanupServiceTests` 的“缺件不移出/空结果提示”分支,以及 `TowerTagAggregationServiceTests`、`TagCombatRuntimeTests` 的基础工具回归。你已确认本轮在 Unity Test Runner 中重新实跑后全部通过。
>
> 2026-03-11 更新:`S6-01` 已完成主链路流程编排回归收口。新增 `ProcedureMainFlowTests`,覆盖 `OnNodeEnter` 的 Hub -> NodeActive 切换、`OnNodeComplete` 的正常推进 / 异常回流 / Boss 完成、损坏塔清理不覆盖 Run 完成弹窗,以及 `OnNodeMapNodeEnterRequested` 的主要忽略条件与战斗入口阻塞对话框分支;你已确认本轮在 Unity Test Runner 中重新实跑后全部通过。
>
> 2026-03-11 更新:`S6-02` 已完成规则侧测试收口。除已有的出战合法性、品质、组件 Tag 生成、塔 Tag 聚合与 Tag 战斗运行时测试外,本轮继续补了 `CombatSettlementServiceTests` 的失败结算掉落金保留、奖励组件并包闭环,以及 `PlayerInventoryTowerAssemblyServiceTests` 的“三组件组塔 -> 品质 / 属性数组 / TagRuntimes / Tags”装配回归你已确认本轮在 Unity Test Runner 中重新实跑后全部通过。
>
> 2026-03-11 更新:`S6-04` 已完成。`MVP-Scope.md`、`GameDesign.md`、`TODO.md`、`CodeX-TODO.md` 与 `TagSystemDesign.md` 现已统一回写到当前真实实现口径:战斗奖励改为“敌人概率掉落 + 结算金币 + 满血额外 3 选 1”商店改为“当前 M1 只保留基础购买”并移除了“开局二选三组件组两塔”“M1 不做耐久 / 红色品质”“组件/配件混写”等已过期描述。当前 docs 下未再发现会误导 M1 开发的主冲突项,剩余内容仅保留明确标注为后续阶段的设计预案。
## 阶段 S7 - Tag 系统审计整改
| 状态 | ID | 任务 | 交付物路径 | 验收标准 |
|-----|-------|------------------------------|---------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------|
| [ ] | S7-01 | 收口 Tag 配置真相源与加载顺序 | `Assets/GameMain/Scripts/Procedure/`<br>`Assets/GameMain/Scripts/Definition/Tag/`<br>`Assets/Tests/EditMode/` | `IsImplemented`、默认值与运行时定义不再受 DataTable 加载顺序影响 |
| [ ] | S7-02 | 补齐组件 Tag 随机上下文与 `RunSeed` 合同 | `Assets/GameMain/Scripts/Definition/Tag/Generation/`<br>`Assets/GameMain/Scripts/UI/Shop/`<br>`Assets/GameMain/Scripts/CustomComponent/CombatNode/`<br>`Assets/Tests/EditMode/` | 同 Run 可复现、跨 Run 可区分,且掉落 / 商店 / 种子共用同一随机合同 |
| [ ] | S7-03 | 收口 `AttackPayload / HitContext` 结算合同 | `Assets/GameMain/Scripts/Definition/DataStruct/`<br>`Assets/GameMain/Scripts/Definition/Tag/Combat/`<br>`Assets/GameMain/Scripts/Entity/`<br>`Assets/Tests/EditMode/` | Tag 结算统一只读上下文对象,不再继续靠散装参数扩展 |
| [ ] | S7-04 | 对齐 `TagConfig` 字段与运行时真实消费 | `Assets/GameMain/DataTables/TagConfig.txt`<br>`Assets/GameMain/Scripts/Definition/Tag/Metadata/`<br>`Assets/GameMain/Scripts/Definition/Tag/Combat/`<br>`Assets/Tests/EditMode/` | 保留字段要么真实生效,要么明确标注为占位且不会误导配置方 |
| [ ] | S7-05 | 清理 Tag 设计文档中的过期草稿 | `docs/TagSystemDesign.md`<br>`docs/CodeX-TODO.md` | 正式口径、当前实现、后续预案三者分层清晰 |
### S7 立项原因
- 当前 Tag 系统已经满足 M1 最小闭环,但还没有达到“可稳定继续扩展第二批 Tag”的结构状态。
- 如果现在直接继续做 `BurnSpread`、`Pierce`、`Overpenetrate` 一类高侵入 Tag会把当前加载顺序、随机上下文和命中结算接口里的隐患一起放大。
- 因此 `S7` 的目标不是新增玩法,而是先把 Tag 系统的配置真相源、随机合同、战斗上下文合同与文档口径收稳。
### S7-01 整改口径
- `Tag.txt`、`TagConfig.txt`、registry 默认值三处不能再各自持有一份“是否首发 / 是否启用”的真相。
- `ProcedurePreload``Tag``TagConfig` 的加载完成顺序不能再影响 `TagDefinitionRegistry` 最终状态。
- 至少补一组 EditMode 测试覆盖“先加载 `Tag` 再加载 `TagConfig`”与“先加载 `TagConfig` 再加载 `Tag`”两种顺序,确认结果一致。
- 本项完成后,`ComponentTagGenerationService` 的首发过滤与展示 / 战斗的定义读取必须共享同一份最终状态。
### S7-02 整改口径
- `ComponentTagGenerationService` 需要正式接收并消费 `RunSeed` 或等价的显式随机上下文,而不是只依赖 `rarity + sourceType + itemInstanceId + configId`
- 掉落、商店、初始种子、事件奖励四条链路必须明确各自如何构造同构的 Tag 随机上下文。
- `EnemyDropResolver` 当前按 `Reset()` 把掉落实例 Id 重置为 `1` 的做法,只能作为局部实现细节,不能继续承担跨 Run 区分责任。
- 本项通过标准是:同一 Run 下同一实例上下文结果稳定;不同 Run 即使出现相同配置与实例序号,也能由 `RunSeed` 拉开结果空间。
### S7-03 整改口径
- `HitContext` 需要补齐当前文档已经承诺的统一结算上下文职责,例如目标状态、击杀结果、攻击来源与后续第二批 Tag 需要的命中信息。
- `TagEffectResolver.ResolveBeforeHit` 不再继续新增 `targetCurrentHealth`、`targetHasSlowStatus` 这类散装参数。
- 数值类、状态类、攻击形态类 Tag 统一从上下文对象读取所需信息,避免每补一个 Tag 就再改一轮函数签名。
- 本项优先级高于第二批 Tag 落地;在 `S7-03` 完成前,不推进 `BurnSpread`、`Pierce`、`Overpenetrate` 的真实战斗效果。
### S7-04 整改口径
- `TagConfig.txt` 中当前保留的字段必须逐项确认:哪些已经是正式运行时字段,哪些只是占位。
- 例如 `Fire.MaxEffectiveStack` 这类已经进入表与配置类、但尚未参与实际结算的字段,需要二选一:
- 要么接入真实逻辑;
- 要么从当前正式口径中移除,避免形成“表能改、逻辑不跟”的假配置。
- `Inferno`、`AbsoluteZero` 这类强化 Tag 也需要明确:它们是继续走独立 `TriggerPhase` 路由,还是正式定义为“依附主状态 Tag 的修饰器”。
- 本项完成后,`TagConfig.txt`、`TagDefinitionRegistry`、`TagEffectResolver` 与实际战斗行为必须一一对应。
### S7-05 整改口径
- `docs/TagSystemDesign.md` 需要把“当前正式口径”“已实现状态”“后续预案 / 历史草稿”彻底拆开。
- 当前正式口径只保留 M1 已收口与 `S7` 审计确认后的内容,不再在同一文件主路径里混写旧的 12 Tag 流派设计草稿。
- `CodeX-TODO.md` 继续只记录执行顺序与整改项,不重复承担大段玩法设计说明。
- 本项完成后,后续继续改 Tag 时,开发与策划应能只看文档主干就拿到当前真实执行口径。
## 推荐执行顺序
1. `S1 ~ S3` 已完成,不再作为当前主阻塞项。
2. `S4` 已完成,当前不再把三表方案作为 M1 主阻塞项。
3. `S5` 已完成,当前无需继续按旧耐久设计拆任务。
4. `S6` 已完成本轮“测试补强 + 文档清理”收尾。
5. 当前优先进入 `S7-01 ~ S7-03`,先收口 Tag 的配置真相源、随机合同与战斗上下文合同。
6. 再推进 `S7-04 ~ S7-05`,把配置字段与文档口径收稳。
7. `S7` 完成前,不提前展开 `BurnSpread`、`IgniteBurst`、`FreezeMask`、`Pierce`、`Overpenetrate` 的真实战斗效果。
8. 后续若继续推进维修、自动销毁、耐久折价、更多 Tag 元数据配置化等长期设计,应作为新的增强阶段单独拆项。
## 本周建议开工顺序
1. 先做 `S7-01`,把 `Tag.txt / TagConfig.txt / registry` 的真相源与加载顺序问题收掉
2. 再做 `S7-02 ~ S7-03`,补齐 `RunSeed` 随机合同和命中上下文合同
3. 然后做 `S7-04 ~ S7-05`,把配置字段与设计文档统一回写
## 备注
- 这份清单只规划补充顺序,不试图在文档里展开所有实现细节。
- 如果后续确认 M1 不做完整品质 / Tag / 耐久闭环,应先改 `docs/TODO.md`,再调整本清单。