feat(lucky-dice): 提交 demo 前核心流程

This commit is contained in:
JSD\13999
2026-06-23 14:13:08 +08:00
commit 855659bf78
140 changed files with 9267 additions and 0 deletions

View File

@@ -0,0 +1,532 @@
# Lucky Dice 核心流程功能划分
## 文档信息
- 父级 PRD[lucky-dice-core-flow-prd.md](../PRD/lucky-dice-core-flow-prd.md)
- 需求文档:[lucky-dice-core-flow-requirements.md](../Requirements/lucky-dice-core-flow-requirements.md)
- 技术规格:[lucky-dice-core-flow-spec.md](../Specs/lucky-dice-core-flow-spec.md)
- 架构蓝图:[lucky-dice-core-flow-architecture-blueprint.md](../Architecture/lucky-dice-core-flow-architecture-blueprint.md)
- 架构决策:[Docs/Decisions](../Decisions/README.md)
- 生成日期2026-06-22
本文档把 Lucky Dice 核心流程拆成可实现、可验收、可并行推进的功能包。它面向后续开发排期和任务拆分,不替代 PRD、需求或规格文档。
## 总目标
### 问题
FishDice 需要一套可扩展的普通骰子主循环和 Lucky Dice 特殊分支。第一版不能只写死几组骰子结果,也不能把每个组合绑定到独立业务方法,否则后续新增组合、骰子数量、特殊结果或目标玩法模式时会快速失控。
### 解决方案
把核心闭环拆成配置、普通 Roll、组合事实、规则匹配、行为执行、Lucky Dice 筛选随机、目标模式解析、最小表现和追踪测试几个功能包。每个功能包都有明确输入输出和验收口,优先保证玩法闭环、可配置、可测试和可排查。
### 第一版影响
- 玩家能完成普通 Roll并看到普通奖励、Clover bonus 或 Lucky Dice 触发结果。
- 策划能通过规则和候选配置表达基础组合和 Lucky Dice 入口。
- 开发能在不写组合专用方法的前提下扩展新组合。
- 测试能用固定输入和固定随机源验证完整链路。
## 用户角色
| 角色 | 关注点 |
| --- | --- |
| 玩家 | Roll 结果清晰,双 Clover 有惊喜Lucky Dice 能看到目标玩法反馈 |
| 策划 | 骰子数量、组合规则、候选结果、权重和模式可配置 |
| 开发 | 模块边界清晰,新增组合不堆硬编码,随机和追踪可测试 |
| 测试 | 能覆盖组合事实、规则优先级、Lucky Dice 兜底和完整链路 |
| 产品负责人 | 第一版范围收敛,先验证闭环,不被复杂动画和完整短玩法拖散 |
## 功能包总览
| 编号 | 功能包 | 优先级 | 目标 | 依赖 |
| --- | --- | --- | --- | --- |
| F0 | 本地配置与核心常量 | P0 | 提供第一版默认配置和 key 入口 | 无 |
| F1 | 普通 Roll 结果生成 | P0 | 根据 DiceSet 配置生成普通骰子结果 | F0 |
| F2 | 组合事实构建 | P0 | 把 Roll 结果转成可匹配事实 | F0, F1 |
| F3 | 组合规则匹配 | P0 | 按优先级命中普通组合规则 | F0, F2 |
| F4 | 行为执行与分发 | P0 | 按 action type 执行奖励、倍率和 Lucky Dice 触发 | F3 |
| F5 | Lucky Dice 候选筛选与权重随机 | P0 | 从特殊结果池选出目标结果 | F0, F4 |
| F6 | 目标玩法与模式解析 | P0 | 把 Lucky Dice 结果解析成目标玩法模式 | F5 |
| F7 | 最小表现与目标玩法占位入口 | P1 | 展示 Lucky Dice 标题、倍率、结果槽和跳转反馈 | F5, F6 |
| F8 | 追踪与调试信息 | P0 | 用 RollSessionId 串起关键决策 | F1-F6 |
| F9 | 测试套件 | P0 | 覆盖事实、匹配、筛选、随机和链路 | F1-F8 |
| F10 | 后续扩展预留 | P2 | 为更多组合、模式、动画和远端配置留口 | F0-F9 |
P0 是第一版闭环必须完成的功能包。P1 是第一版玩家可见体验的最小表现。P2 是明确预留但不要求第一版完整实现的扩展。
## F0 本地配置与核心常量
### 目标
建立第一版默认配置和统一 key 入口,让后续模块不在业务逻辑里散落裸字符串和硬编码数量。
### 功能需求
- 提供普通骰子集合 `normal_main`
- 普通骰子面为 `2 / 3 / 4 / 5 / 6 / clover`
- 普通骰子数量来自 DiceSet 配置,第一版配置值为 2。
- 提供 Lucky Dice 特殊结果集合 `lucky_dice`
- Lucky Dice 第一版结果至少包含 `rocket``thief`
- Lucky Dice 默认结果槽数量来自配置,第一版配置值为 3。
- 提供普通组合规则配置。
- 提供 Lucky Dice 候选结果配置。
- 提供目标玩法模式映射配置。
### 非功能需求
- 配置结构不能绑定具体 Unity 场景对象。
- key 应集中定义或集中加载,避免业务代码到处裸写。
- 配置加载失败时需要返回结构化错误。
### 验收标准
- 能读取普通骰子集合、Lucky Dice 集合、组合规则、候选结果和模式映射。
- 修改普通骰子数量配置后,核心流程读取到新数量。
- 修改 Lucky Dice 结果槽数量配置后,展示槽构建读取到新数量。
- 普通骰子集合和 Lucky Dice 特殊结果集合有明确类型区分。
### 不在范围内
- 远端配置热更新。
- 策划可视化配置编辑器。
- 完整配置校验工具链。
## F1 普通 Roll 结果生成
### 目标
根据普通 DiceSet 配置生成一次普通 Roll 结果,并携带同一个 `RollSessionId`
### 功能需求
- 接收玩家 Roll 请求。
- 从配置获取普通骰子集合和骰子数量。
- 按配置生成 `DiceRollResult`
- `DiceRollResult` 包含 DiceSetId、DiceSetType、DiceCount、Faces、Multiplier、TriggerSource、RollSessionId。
- 不决定奖励、组合规则或 Lucky Dice 入口。
### 非功能需求
- 支持注入随机源或可控 Roll 输入,方便测试。
- 不写死两颗骰子位置。
- 生成结果数量必须与配置 DiceCount 一致。
### 用户故事
作为玩家,我希望普通掷骰能产出清晰结果,从而知道每次 Roll 都有意义。
### 验收标准
- 给定 `DiceCount = 2`Roll 结果包含 2 个普通骰子面。
- 给定 `DiceCount = 3`Roll 结果包含 3 个普通骰子面。
- Roll 结果携带 `RollSessionId`
- Roll 层不调用奖励、规则匹配或 Lucky Dice 服务。
## F2 组合事实构建
### 目标
把普通 Roll 结果转换成结构化 `ComboFacts`,供规则匹配使用。
### 功能需求
-`DiceRollResult` 构建 `ComboFacts`
- 统计原始面列表、面数量、数字列表、点数和、Clover 数量。
- 生成无序 `NormalizedKey`
- 生成有序 `OrderedKey`
- `2 + clover``clover + 2` 归一为相同无序 key。
- 拒绝或报错处理 Lucky Dice 特殊结果进入普通组合事实构建。
### 非功能需求
- 必须支持 N 颗骰子。
- 不依赖固定左骰、右骰字段。
- 输出字段应可用于日志和测试断言。
### 用户故事
作为开发者,我希望 Roll 结果先转成组合事实,从而规则可以基于数据匹配,而不是依赖固定位置判断。
### 验收标准
- `2 + 3` 生成 `NumberSum = 5``CloverCount = 0``NormalizedKey = 2_3`
- `2 + clover``clover + 2` 生成相同 `NormalizedKey`
- `clover + clover` 生成 `CloverCount = 2`
- `2 + 2 + clover` 能生成 3 骰事实。
- Lucky Dice 特殊结果不会被当成普通组合事实处理。
## F3 组合规则匹配
### 目标
按规则优先级和通用 matcher 匹配普通组合,输出命中规则和 action 列表。
### 功能需求
- 支持规则优先级。
- 第一版默认命中高优先级规则后停止继续匹配。
- 支持首批 matcher
- `ExactCombo`
- `AllNumbers`
- `ContainsFace`
- `FaceCount`
- `FaceCountRange`
- `DiceCount`
- `NumberPair`
- `NumberOfAKind`
- `NumberSumRange`
- 第一版默认规则:
- 双 Clover 触发 Lucky Dice。
- 单 Clover 加数字发普通奖励和 Clover bonus。
- 纯数字发普通奖励。
### 非功能需求
- matcher 只按 matcher type 注册,不按组合 key 注册。
- 规则匹配不执行业务副作用。
- 匹配结果需要包含命中规则 id、优先级、matcher type。
### 用户故事
作为策划,我希望组合规则支持优先级,从而让双 Clover 这类稀有触发优先于普通奖励规则。
### 验收标准
- `clover_clover` 命中 Lucky Dice 规则,而不是泛用 Clover 规则。
- `2_clover` 命中 Clover bonus 规则。
- `2_6` 命中纯数字普通奖励规则。
- 高优先级规则优先于低优先级规则。
- 3 骰事实可以通过统计型 matcher 命中规则。
## F4 行为执行与分发
### 目标
把命中规则中的 action list 按 `ActionType` 分发给通用行为执行器。
### 功能需求
- 支持 `grant_reward`
- 支持 `add_multiplier`
- 支持 `trigger_lucky_dice`
- 支持 `enter_mode` 扩展口。
- 支持 `show_popup` 扩展口。
- 多个 action 按规则配置顺序执行。
- 未注册 action 返回结构化错误并写入追踪。
### 非功能需求
- dispatcher 只维护 `ActionType -> Executor` 注册表。
- 不允许维护 `combo key -> method` 映射。
- executor 不重新做组合匹配判断。
### 用户故事
作为开发者,我希望行为分发按行为类型注册,从而不需要维护巨大的“组合 key 到方法”映射表。
### 验收标准
- 纯数字规则执行普通奖励 action。
- 单 Clover 规则执行普通奖励和倍率或 bonus action。
- 双 Clover 规则执行 Lucky Dice 触发 action。
- 新增组合但复用现有 action 时,不需要新增 executor。
- 未注册 action 能被追踪到。
## F5 Lucky Dice 候选筛选与权重随机
### 目标
Lucky Dice 触发后,从独立特殊结果池中构建候选、筛选候选、处理兜底,并按权重随机选中一个结果。
### 功能需求
- 构建 Lucky Dice 候选池。
- 候选包含 ResultKey、TargetKey、Weight、Enabled、MinLevel、SourceFilter、CooldownRule、IsDefault、ResultSlotCount。
- 支持首批筛选器:
- EnabledFilter
- ProgressFilter
- SourceFilter
- CooldownFilter
- TutorialFilter
- 筛选后按权重随机。
- 权重随机使用可注入随机源。
- 候选池为空时优先使用 default result。
- default result 不可用时降级为普通奖励兜底。
### 非功能需求
- Lucky Dice 特殊结果不与普通骰子集合混用。
- 随机结果可通过固定随机源复现。
- 筛选过程需要记录每个 filter 前后的候选数量。
### 用户故事
作为策划,我希望 Lucky Dice 候选结果可筛选,从而未解锁、未开启或冷却中的目标玩法不会被抽中。
### 验收标准
- 未开启候选会被过滤。
- 玩家进度不足候选会被过滤。
- 来源不匹配候选会被过滤。
- 固定随机源下可以稳定选中预期结果。
- 候选池为空时进入可观测兜底。
- `rocket``thief` 可以作为第一版有效候选。
## F6 目标玩法与模式解析
### 目标
把 Lucky Dice 选中的结果解析为目标玩法和具体模式。
### 功能需求
- 支持 `ResultKey -> TargetKey -> ModeKey` 两级解析。
- `rocket` 解析到 `slap_down_normal`
- `thief` 解析到 `treasure_heist_normal`
- 保留教程模式和 bonus 模式扩展规则。
- 输出 `TargetModeEntry`,包含 TargetKey、ModeKey、ResultKey、Multiplier、TriggerSource、RollSessionId。
### 非功能需求
- 模式解析不参与 Lucky Dice 随机。
- 目标玩法启动不反向影响候选筛选。
- 模式解析失败必须可兜底、可追踪。
### 用户故事
作为玩家,我希望 Rocket 结果进入 Slap Down从而让结果和后续玩法有明确绑定。
### 验收标准
- `rocket` 解析为 `TargetKey = slap_down``ModeKey = slap_down_normal`
- `thief` 解析为 `TargetKey = treasure_heist``ModeKey = treasure_heist_normal`
- 模式解析结果携带原始 `RollSessionId`
- 模式映射失败时进入可观测兜底。
## F7 最小表现与目标玩法占位入口
### 目标
提供第一版玩家可见反馈Lucky Dice 标题、倍率、结果槽图标和目标玩法跳转反馈。
### 功能需求
- 展示 Lucky Dice 标题。
- 展示当前倍率。
- 按结果槽数量展示特殊图标。
- 第一版结果槽可全部展示同一个 ResultKey。
- 触发目标玩法入口反馈。
- 目标玩法结束后能回到主循环。
- Slap Down 和 Treasure Heist 第一版可以是占位入口,不要求完整玩法内容。
### 非功能需求
- 表现层不参与规则匹配、候选筛选和权重随机。
- 动画失败不能改变核心选择结果。
- 结果槽数量来自配置或候选,不写死在 UI 中。
### 用户故事
作为玩家,我希望 Lucky Dice 结果能清楚显示特殊图标,从而知道即将进入哪个短玩法。
### 验收标准
- Lucky Dice 触发后能看到标题、倍率和结果槽。
- 选中 `rocket` 时展示 Rocket 结果并进入 Slap Down 占位入口。
- 选中 `thief` 时展示 Thief 结果并进入 Treasure Heist 占位入口。
- 结果槽数量修改为 2 或 4 时,表现层能按配置展示。
### 不在范围内
- 托盘动画。
- 骰子飞入。
- 粒子爆发。
- 白烟转场。
- 完整 Slap Down 和 Treasure Heist 玩法。
## F8 追踪与调试信息
### 目标
让一次 Roll 从普通结果到最终玩法模式的关键决策可解释、可回放、可排查。
### 功能需求
- 每次 Roll 创建或携带同一个 `RollSessionId`
- 记录普通骰子结果和骰子数量。
- 记录组合事实和 `NormalizedKey`
- 记录命中规则、优先级和执行 action。
- 记录 Lucky Dice 初始候选和筛选结果。
- 记录兜底类型。
- 记录权重随机输入和选中结果。
- 记录最终 TargetKey、ModeKey 和 FinalOutcome。
### 非功能需求
- 追踪层不改变玩法决策。
- 第一版可以使用本地结构化日志或调试数据结构。
- 字段命名应稳定,方便后续接入埋点。
### 用户故事
作为开发者,我希望每次 Roll 都携带同一个会话 id从而普通 Roll、规则匹配、Lucky Dice 结果和目标玩法启动可以串起来排查。
### 验收标准
- 普通奖励链路可以从 trace 解释为什么发奖。
- 双 Clover 链路可以从 trace 解释为什么进入 Lucky Dice。
- Lucky Dice 链路可以从 trace 看到哪些候选被过滤。
- 模式解析失败或候选池为空时trace 中有兜底原因。
## F9 测试套件
### 目标
用测试锁住第一版核心闭环,避免后续扩展组合或结果时破坏基础行为。
### 功能需求
- 组合事实测试。
- 规则匹配测试。
- 行为分发测试。
- Lucky Dice 筛选测试。
- 权重随机测试。
- 目标模式解析测试。
- 完整链路测试。
- 兜底场景测试。
### 非功能需求
- 测试外部行为,不测试私有实现细节。
- 使用固定随机源。
- 关键链路测试应覆盖 `RollSessionId`
### 验收标准
- `2 + 3` 最终发普通奖励。
- `2 + clover` 最终发普通奖励并提供 Clover bonus。
- `clover + clover` 最终进入 Lucky Dice。
- Lucky Dice 选中 `rocket` 后进入 `slap_down_normal`
- Lucky Dice 选中 `thief` 后进入 `treasure_heist_normal`
- 候选池为空时走兜底。
- 普通骰子从 2 改为 3 后,组合事实和 matcher 仍工作。
## F10 后续扩展预留
### 目标
明确第一版不做但架构需要保留的扩展方向,防止第一版把未来道路堵死。
### 扩展方向
- 更多普通组合,例如对子、三连、点数和区间、指定数字组合、有序组合。
- 更多 Lucky Dice 特殊结果,例如 Chest、Bomb、Key。
- 教程模式和 bonus 模式。
- 按活动或关卡调整权重。
- 远端配置热更新。
- 完整表现动画。
- 完整 Slap Down 和 Treasure Heist 玩法内容。
- 埋点管线集成。
### 约束
- 扩展普通组合优先新增配置,不新增组合专用方法。
- 扩展特殊结果优先新增候选和模式映射。
- 扩展动画不能改变核心随机和模式解析结果。
- 接入埋点时复用 `RollSessionId` 和现有 trace 字段。
## 依赖顺序
```mermaid
flowchart TD
F0["F0 本地配置与核心常量"] --> F1["F1 普通 Roll 结果生成"]
F1 --> F2["F2 组合事实构建"]
F2 --> F3["F3 组合规则匹配"]
F3 --> F4["F4 行为执行与分发"]
F4 --> F5["F5 Lucky Dice 筛选与随机"]
F5 --> F6["F6 目标玩法与模式解析"]
F5 --> F7["F7 最小表现"]
F6 --> F7
F1 --> F8["F8 追踪"]
F3 --> F8
F5 --> F8
F6 --> F8
F1 --> F9["F9 测试"]
F2 --> F9
F3 --> F9
F4 --> F9
F5 --> F9
F6 --> F9
```
## 建议迭代切片
### Slice 1普通 Roll 到普通奖励
包含 F0、F1、F2、F3、F4 的普通奖励部分、F8 基础字段、F9 基础测试。
验收:
- 纯数字结果发普通奖励。
- 单 Clover 加数字发普通奖励和 bonus。
- 组合事实和规则命中可追踪。
### Slice 2双 Clover 触发 Lucky Dice
包含 F4 的 `trigger_lucky_dice`、F5、F6、F8 Lucky Dice 字段、F9 Lucky Dice 测试。
验收:
- 双 Clover 不发普通奖励,而是进入 Lucky Dice。
- `rocket` 能解析到 Slap Down 普通模式。
- `thief` 能解析到 Treasure Heist 普通模式。
- 候选池为空有兜底。
### Slice 3最小玩家可见闭环
包含 F7 和链路测试补齐。
验收:
- Lucky Dice 标题、倍率、结果槽可见。
- 目标玩法占位入口可达。
- 目标玩法结束后能回到主循环。
### Slice 4扩展性验证
包含 3 骰配置测试、结果槽数量变化测试、一个统计型 matcher 示例。
验收:
- 普通骰子数量改为 3 后不改核心流程。
- 结果槽数量改为 2 或 4 后表现层按配置展示。
- 新增一个组合规则时复用已有 matcher 和 action。
## 总体验收标准
- 普通骰子结果能转换为结构化组合事实。
- 普通骰子数量和 Lucky Dice 结果槽数量来自配置。
- 规则系统通过少量通用 matcher 命中普通组合。
- 双 Clover 优先触发 Lucky Dice。
- 行为执行层只按 action type 分发。
- Lucky Dice 先筛选候选,再按权重随机。
- `rocket` 进入 `slap_down_normal`
- `thief` 进入 `treasure_heist_normal`
- 候选池为空、模式解析失败、未注册 action 都有可观测兜底。
- `RollSessionId` 能串起完整链路。
## 第一版不做
- 完整复刻参考 Lucky Dice 动画。
- 托盘、飞入、粒子爆发、白烟转场。
- 完整 Slap Down 玩法。
- 完整 Treasure Heist 玩法。
- 所有 Lucky Dice 特殊结果类型。
- 远端配置热更新。
- 复杂运营活动概率策略。
- 正式埋点管线集成。
- 为每个组合 key 编写独立业务方法。
- 假设普通骰子永远只有 2 颗。
- 假设 Lucky Dice 永远只有 3 个结果槽。