11 KiB
11 KiB
CodeX TODO
最后更新:2026-03-13
目标:把当前“随机组件产出 / 掉落 / 商店 / 3 选 1 奖励候选 / Tag 初始化入口”从分散实现收口成清晰模块。 原则:先收运行时入口,再收重复领域逻辑,最后收 UI 编排;不把纯规则层误做成
GameFrameworkComponent。
这次重构要解决的问题
- 商店、敌人掉落、满血 3 选 1 候选都在各自生成组件实例,逻辑分散,后续改规则要改多处。
ShopFormUseCase、旧EnemyDropResolver、CombatSettlementService都曾同时承担“流程 + 规则 + 数据组装”的混合职责。- 重构前
runSeed只稳定了 Tag 生成,没有稳定整个组件产出流程;当前已补齐到商店、掉落、奖励候选与奖励展示顺序。 - Tag 模块本身已经分成
Generation / Aggregation / Combat / Metadata / Presentation,但初始化入口还散在流程代码里。
重构边界
适合抽成 GameFrameworkComponent 的模块
-
InventoryGenerationComponent- 统一作为运行时“组件产出入口”。
- 对外提供:
BuildShopGoods(...)ResolveEnemyDrop(...)BuildRewardCandidates(...)- 统一持有并传递
runSeed、sequenceIndex、随机上下文。
-
TagRegistryComponent- 统一作为 Tag 规则注册与重载入口。
- 负责刷新:
TagDefinitionRegistryTagGenerationRuleRegistryRarityTagBudgetRuleRegistry- 替代旧的
ProcedurePreload直连刷新逻辑,并收口当前主流程初始化入口。
不适合抽成 GameFrameworkComponent 的模块
ComponentTagGenerationServiceTowerTagAggregationServiceTagEffectResolverNumericTagEffectHandlerAttackShapeTagEffectHandlerEnemyStatusTagRegistry
这些都保留为普通领域模块,因为它们本质上是规则计算、数据聚合或战斗解析,不需要全局生命周期。
目标模块结构
组件层
Assets/GameMain/Scripts/CustomComponent/InventoryGeneration/InventoryGenerationComponent.csAssets/GameMain/Scripts/CustomComponent/TagRegistry/TagRegistryComponent.cs
领域模块层
Assets/GameMain/Scripts/Factory/ComponentItemFactory.cs- 唯一负责“从配置行构造
TowerCompItemData”。
- 唯一负责“从配置行构造
Assets/GameMain/Scripts/CustomComponent/InventoryGeneration/InventoryGenerationRandomContext.cs- 统一承载商店 / 掉落 / 奖励候选的随机合同。
Assets/GameMain/Scripts/CustomComponent/InventoryGeneration/ShopGoodsBuilder.cs- 只负责商店货物生成。
Assets/GameMain/Scripts/CustomComponent/InventoryGeneration/DropPoolRoller.cs- 只负责掉落池筛选、权重抽样、稀有度曲线。
Assets/GameMain/Scripts/CustomComponent/InventoryGeneration/RewardCandidateBuilder.cs- 只负责 3 选 1 奖励候选生成。
Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatSettlementCalculator.cs- 只负责结算计算。
Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatSettlementCommitter.cs- 只负责把结算结果提交到玩家库存。
现有职责迁移目标
商店链路
ShopNodeComponent- 保留“节点进入 / 退出 / 发事件 / 打开 UI”职责。
ShopFormUseCase- 删除组件随机生成职责。
- 保留“当前货物模型、购买行为、UI RawData 组装”职责。
- 商店货物来源统一改为
GameEntry.InventoryGeneration.BuildShopGoods(...)。
战斗掉落链路
CombatScheduler- 不再直接持有复杂掉落生成细节。
- 只在敌人死亡时调用
GameEntry.InventoryGeneration.ResolveEnemyDrop(...)。
- 旧
EnemyDropResolver- 已从主链路移除,并已删除旧实现文件。
- 其职责已拆给:
DropPoolRollerComponentItemFactoryRewardCandidateBuilder
战斗结算链路
CombatSettlementService- 从混合类拆成薄流程壳。
- 保留最少流程编排。
- 计算逻辑迁到
CombatSettlementCalculator。 - 库存提交逻辑迁到
CombatSettlementCommitter。 - 奖励候选生成改为调用
GameEntry.InventoryGeneration.BuildRewardCandidates(...)。
Tag 初始化链路
ProcedurePreload- 移除 Tag 注册表刷新细节。
- 只保留资源与数据表预加载职责。
ProcedureMain- 进入主流程时主动调用
GameEntry.TagRegistry.OnInit()。
- 进入主流程时主动调用
TagRegistryComponent- 成为 Tag 相关表与注册表的唯一运行时入口。
分阶段执行
阶段 G1 - 收口组件产出入口
| 状态 | ID | 任务 | 目标 |
|---|---|---|---|
| [x] | G1-01 | 新增 InventoryGenerationComponent |
建立统一组件产出入口 |
| [x] | G1-02 | 新增 ComponentItemFactory |
收口组件实例构造 |
| [x] | G1-03 | 新增 ShopGoodsBuilder |
收口商店货物生成 |
| [x] | G1-04 | 让 ShopFormUseCase 改用组件入口 |
商店不再自己生成组件 |
G1 验收标准
- 商店仍可正常打开、购买、加背包。
- 商店不再直接读取组件表并构造
Muzzle/Bearing/Base实例。 - 商店所有组件实例都通过同一工厂生成。
阶段 G2 - 收口战斗掉落与奖励候选
| 状态 | ID | 任务 | 目标 |
|---|---|---|---|
| [x] | G2-01 | 新增 DropPoolRoller |
收口掉落池与稀有度抽样 |
| [x] | G2-02 | 新增 RewardCandidateBuilder |
收口 3 选 1 候选生成 |
| [x] | G2-03 | 让战斗掉落改走 InventoryGenerationComponent |
战斗不再自己构造组件 |
| [x] | G2-04 | 让满血奖励候选改走统一入口 | 掉落与奖励候选共用产出体系 |
G2 验收标准
- 敌人死亡后仍能正常掉 coin、gold、组件。
- 满血奖励 3 选 1 仍能正常打开并选择。
- 掉落与奖励候选不再重复维护组件实例构造逻辑。
CombatScheduler与CombatSettlementService已改为统一调用GameEntry.InventoryGeneration。
阶段 G3 - 收口结算模块边界
| 状态 | ID | 任务 | 目标 |
|---|---|---|---|
| [x] | G3-01 | 新增 CombatSettlementCalculator |
只保留结算计算 |
| [x] | G3-02 | 新增 CombatSettlementCommitter |
只保留库存提交 |
| [x] | G3-03 | 精简 CombatSettlementService |
只剩流程编排 |
| [x] | G3-04 | 清理奖励 RawData 重复映射 | 候选生成与 UI 组装边界清晰 |
G3 验收标准
- 战斗结算金币、奖励库存、耐久扣减结果保持不变。
- 满血奖励选择后仍能正确并包。
CombatSettlementService不再同时承担计算、提交、候选生成三类职责。
阶段 G4 - 收口 Tag 初始化入口
| 状态 | ID | 任务 | 目标 |
|---|---|---|---|
| [x] | G4-01 | 新增 TagRegistryComponent |
建立 Tag 运行时入口 |
| [x] | G4-02 | 挪出 ProcedurePreload 中 Tag 注册逻辑 |
流程代码不再直接维护 Tag 注册表 |
| [x] | G4-03 | 对齐 Tag 加载时机与重载入口 | 初始化路径明确 |
G4 验收标准
Tag.txt、TagConfig.txt、RarityTagBudget.txt加载后仍能正确刷新运行时。- Tag 展示、Tag 生成、Tag 战斗效果不受影响。
- Tag 相关运行时入口不再散落在预加载流程里。
阶段 G5 - 收口随机合同
| 状态 | ID | 任务 | 目标 |
|---|---|---|---|
| [x] | G5-01 | 统一商店 / 掉落 / 奖励候选的随机上下文 | 全部产出链路使用一致合同 |
| [x] | G5-02 | 补齐整体产出的 runSeed 稳定性 |
不只稳定 Tag,也稳定物品产出 |
| [x] | G5-03 | 增加对应 EditMode 测试 | 同 Run 可复现,跨 Run 可区分 |
G5 验收标准
- 同一
runSeed + sequenceIndex下,商店货物、掉落候选、奖励候选可复现。 - 不同
runSeed下,产出结果可区分。 - 不再出现“Tag 稳定但物品本体不稳定”的混合口径。
具体迁移清单
第一批直接改动文件
Assets/GameMain/Scripts/UI/Shop/UseCase/ShopFormUseCase.csAssets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSettlementService.csAssets/GameMain/Scripts/Procedure/Base/ProcedurePreload.csAssets/GameMain/Scripts/Procedure/ProcedureMain/ProcedureMain.csAssets/GameMain/Scripts/Base/GameEntry.Custom.csAssets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatScheduler.cs
第二批新增文件
Assets/GameMain/Scripts/CustomComponent/InventoryGeneration/InventoryGenerationComponent.csAssets/GameMain/Scripts/CustomComponent/TagRegistry/TagRegistryComponent.csAssets/GameMain/Scripts/Factory/ComponentItemFactory.csAssets/GameMain/Scripts/CustomComponent/InventoryGeneration/InventoryGenerationRandomContext.csAssets/GameMain/Scripts/CustomComponent/InventoryGeneration/ShopGoodsBuilder.csAssets/GameMain/Scripts/CustomComponent/InventoryGeneration/DropPoolRoller.csAssets/GameMain/Scripts/CustomComponent/InventoryGeneration/RewardCandidateBuilder.csAssets/GameMain/Scripts/CustomComponent/CombatNode/CombatSettlementCalculator.csAssets/GameMain/Scripts/CustomComponent/CombatNode/CombatSettlementCommitter.cs
本次重构的限制
- 不在这一轮扩展新的 Tag 功能。
- 不在这一轮扩展新的商店玩法或新的奖励 UI 形态。
- 不为了“统一”而把所有领域逻辑都塞进
GameFrameworkComponent。 - 不改动现有 UI 五层结构以外的职责边界。
当前推荐执行顺序
- 先做
InventoryGenerationComponent + ComponentItemFactory。 - 先替换商店货物生成。
- 再替换战斗掉落与奖励候选生成。
- 再拆战斗结算计算与提交。
- 最后收
TagRegistryComponent与主流程中的 Tag 初始化入口。
通过标准
- 组件实例生成入口只保留一套。
- 掉落、商店、奖励候选不再各自维护相似逻辑。
- Tag 模块保留现有分层,不再继续和流程代码缠在一起。
GameFrameworkComponent只承接运行时入口,不承接纯规则实现。
当前结果
InventoryGenerationComponent已成为商店、战斗掉落、奖励候选的统一运行时入口。- 掉落概率规则与掉落物品构造已继续下沉到
OutGameDropRuleService与OutGameDropItemBuilder,InventoryGenerationComponent保持入口编排职责。 TagRegistryComponent已成为 Tag 运行时入口,并由ProcedureMain主动初始化。TagRegistryComponent已改为 fail-fast 初始化,缺少必要数据表时会直接暴露错误。InventoryGenerationRandomContext已统一商店、掉落、奖励候选的随机合同,并补齐稳定临时实例 Id。Assets/Tests/EditMode/InventoryGenerationStabilityTests.cs已覆盖 G5 的可复现性验收点。