从框架设计看玩法、模块、服务和管理器如何拆分
FishDice 的扩展方式不是“给每个组合写一个 if 分支”,而是把变化拆到配置行、Matcher、ActionExecutor、候选定义和 TargetMode 映射里。
核心开发原则
组合变化优先改规则配置
新增“什么组合触发什么行为”时,优先新增 ComboRuleDefinition。只有现有 matcher 表达不了新语义时,才新增 IComboMatcher。
行为变化按 ActionType 扩展
新增通用行为时,新增 IRollActionExecutor 并注册到 context。Dispatcher 只知道 ActionType,不知道具体组合 key。
特殊玩法入口走候选池
Lucky Dice 的结果和目标玩法由 LuckyDiceCandidateDefinition 与 TargetModeDefinition 定义。
目标玩法内部不反向污染 Lucky Dice
目标玩法模式由 TargetModeResolver 解析,Lucky Dice 选择层只负责选结果和 target key,不关心玩法内部实现。
新增内容应该放哪里
| 开发需求 | 推荐位置 | 实现方式 | 测试重点 |
|---|---|---|---|
| 新增普通骰子组合 | Config | 新增 ComboRuleDefinition,复用已有 matcher 和 action。 | 规则命中、优先级、action 顺序。 |
| 新增组合匹配能力 | Rules/Matchers | 实现 IComboMatcher,放入 ComboMatcherRegistry 或自定义 validation context。 | MatcherType 唯一、边界输入。 |
| 新增奖励或业务行为 | Actions | 实现 IRollActionExecutor,通过 ActionType 注册。 | 未注册 action 失败记录、effect 输出。 |
| 新增 Lucky Dice 结果 | Config + 资源层 | 新增 candidate 和 target mode,并补图标/展示资源。 | 默认候选、权重、source filter、target mode 存在。 |
| 新增目标玩法模式 | TargetMode 接入层 | 新增 TargetModeDefinition 或后续扩展 resolver 规则。 | 缺失映射失败原因、成功解析 mode key。 |
服务和“管理器”的边界
当前 Runtime 里没有传统 Unity 式单例 Manager,而是小服务组合:DiceRollService 做随机 Roll,ComboRuleMatcher 做规则匹配,RollActionDispatcher 做行为分发,LuckyDiceFlowService 做特殊候选选择,TargetModeResolver 做模式解析。
这让“管理器”职责被拆散:没有一个巨大的 LuckyDiceManager 同时管随机、规则、奖励、UI、场景跳转。
扩展入口
LuckyDiceRuntimeFactory.CreateFlow 支持传入规则、候选和目标模式定义;LuckyDiceConfigValidationContext 支持传入自定义 matcher 与 action executor。测试里已经覆盖“自定义 matcher/action 能被同一 context 用于校验和运行时分发”。
证据
- LuckyDiceDefaultConfig.cs:151-238:默认规则、候选、目标模式定义。
- ComboMatcherRegistry.cs:5-20:默认 matcher 注册表。
- RollActionExecutorRegistry.cs:默认 action executor 注册表。
- LuckyDiceConfigValidationContext.cs:8-30:自定义 matcher/action 的上下文入口。
- LuckyDiceCoreFlowTests.cs:446-487:自定义 matcher/action 走完整 flow。