# Lucky Dice 核心流程 PRD

## 问题陈述

FishDice 需要一套可扩展的骰子主循环和 Lucky Dice 特殊分支。当前目标不是只做一次普通骰子结算，而是让普通骰子的不同组合能够触发不同业务行为，并在双四叶草等稀有组合出现时进入 Lucky Dice。Lucky Dice 需要使用独立的特殊结果池，经过筛选和随机后产出目标结果，再把玩家带入 Slap Down、Treasure Heist 等短玩法。

如果把每个组合直接绑定到一个独立执行方法，后续新增组合、骰子数量、特殊结果或目标玩法时，会形成越来越大的硬编码分支。产品和策划侧也需要能清楚表达“什么组合触发什么行为”“Lucky Dice 怎么筛选结果”“同一个目标玩法进入什么模式”，否则第一版完成后很难继续扩展活动玩法。

## 解决方案

建立一套分层的玩法规则系统。

普通 Roll 使用普通骰子集合。第一版默认骰子面为 `2 / 3 / 4 / 5 / 6 / Clover`，默认投 2 颗骰子，但骰子数量必须来自配置。Roll 结果先转换成结构化组合事实，再由规则匹配器按优先级匹配规则，并执行规则配置的行为列表。

Lucky Dice 使用独立的特殊结果集合，不与普通数字骰混用。它不是“普通骰子再摇一次”，而是一个特殊玩法入口选择流程：构建候选结果池，按玩家上下文筛选候选，按权重随机，生成结果槽展示，再解析目标玩法和具体进入模式。

第一版只保留核心闭环，忽略复杂动画表现。玩家只需要看到 Lucky Dice 标题、倍率、结果槽图标和目标玩法跳转。托盘、骰子飞入、粒子爆发、白烟转场等表现不进入第一版必做范围。

## 用户故事

1. 作为玩家，我希望普通掷骰能产出清晰结果，从而知道每次 Roll 都有意义。
2. 作为玩家，我希望纯数字结果能发放普通奖励，从而保证普通流程有稳定收益。
3. 作为玩家，我希望单个 Clover 也有轻微特殊反馈，从而让 Clover 即使不触发 Lucky Dice 也有价值。
4. 作为玩家，我希望双 Clover 能触发 Lucky Dice，从而让稀有组合带来惊喜。
5. 作为玩家，我希望 Lucky Dice 是一个独立流程，从而明确知道触发了特殊事件。
6. 作为玩家，我希望 Lucky Dice 结果能清楚显示特殊图标，从而知道即将进入哪个短玩法。
7. 作为玩家，我希望 Rocket 结果进入 Slap Down，从而让结果和后续玩法有明确绑定。
8. 作为玩家，我希望 Thief 结果进入 Treasure Heist，从而让不同 Lucky Dice 结果有不同意义。
9. 作为玩家，我希望目标玩法结束后能回到主循环，从而保持游戏流程连续。
10. 作为策划，我希望普通骰子数量可配置，从而未来可以支持 3 颗、4 颗或特殊关卡自定义骰子数量。
11. 作为策划，我希望 Lucky Dice 结果槽数量可配置，从而未来可以支持 2 格、3 格、4 格或按玩法自定义槽位。
12. 作为策划，我希望组合规则数据化，从而新增组合含义时不需要每次都让工程新增独立方法。
13. 作为策划，我希望组合匹配支持精确组合、面数量、对子、N 连、点数和区间等能力，从而覆盖简单和复杂规则。
14. 作为策划，我希望组合规则支持优先级，从而让双 Clover 这类稀有触发优先于普通奖励规则。
15. 作为策划，我希望组合行为由可复用行为组成，从而一个组合可以同时发奖、加倍率、展示反馈或进入 Lucky Dice。
16. 作为策划，我希望 Lucky Dice 候选结果可筛选，从而未解锁、未开启或冷却中的目标玩法不会被抽中。
17. 作为策划，我希望 Lucky Dice 候选结果支持权重，从而可以调节不同结果概率。
18. 作为策划，我希望新手期规则可以影响 Lucky Dice 结果，从而更好地控制早期体验。
19. 作为策划，我希望一个 Lucky Dice 结果先解析目标玩法，再解析具体模式，从而同一玩法可以支持教程、普通、bonus 等模式。
20. 作为策划，我希望 Lucky Dice 候选池为空时有兜底行为，从而配置错误不会卡死玩家流程。
21. 作为开发者，我希望普通骰子和 Lucky Dice 特殊结果分属两套骰子集合，从而避免数字结算和目标玩法入口混用。
22. 作为开发者，我希望 Roll 结果先转成组合事实，从而规则可以基于数据匹配，而不是依赖固定位置判断。
23. 作为开发者，我希望组合事实保留原始骰子、数量统计和归一化 key，从而便于调试和未来扩展。
24. 作为开发者，我希望规则匹配只使用少量通用匹配器，从而系统优先通过配置扩展，而不是不断增加代码分支。
25. 作为开发者，我希望行为分发按行为类型注册，从而不需要维护巨大的“组合 key 到方法”映射表。
26. 作为开发者，我希望 Lucky Dice 随机源可注入，从而测试和回放可以稳定复现。
27. 作为开发者，我希望每次 Roll 都携带同一个会话 id，从而普通 Roll、规则匹配、Lucky Dice 结果和目标玩法启动可以串起来排查。
28. 作为测试人员，我希望组合事实和规则匹配有确定性测试，从而普通组合和稀有组合都稳定可靠。
29. 作为测试人员，我希望兜底场景被覆盖，从而候选池为空、模式映射失败等问题可以被观测到。
30. 作为产品负责人，我希望第一版范围足够收敛，从而先验证玩法闭环，再投入完整动画表现。

## 实现决策

- 使用两套骰子集合：普通 Roll 骰子和 Lucky Dice 特殊结果骰子。
- 普通 Roll 第一版使用 `2 / 3 / 4 / 5 / 6 / Clover`。
- 普通 Roll 第一版默认 2 颗骰子，但数量必须来自骰子集合配置。
- Lucky Dice 第一版默认 3 个结果槽，但数量必须来自候选结果、目标玩法或骰子集合配置。
- 普通 Roll 结果必须先转换成组合事实，再进入规则匹配。
- 组合事实必须包含骰子数量、原始骰子面、面数量统计、数字列表、点数和、Clover 数量、无序归一化 key、有序 key。
- 普通组合默认按无序组合匹配。
- 只有规则明确声明需要顺序语义时，才使用有序 key。
- 不允许每个组合 key 绑定一个独立方法。
- 使用少量可复用匹配器注册表。
- 首批匹配器包括精确组合、全数字、包含指定面、指定面数量、指定面数量区间、骰子数量、数字对子、N 连、点数和区间。
- 规则必须支持优先级。
- 第一版默认命中高优先级规则后停止继续匹配，除非规则配置另有声明。
- 使用少量可复用行为执行器注册表。
- 首批行为包括发放奖励、增加倍率、触发 Lucky Dice、进入玩法模式、显示弹窗。
- 第一版双 Clover 触发 Lucky Dice。
- 第一版单 Clover 加数字发放普通奖励并提供 Clover bonus。
- 第一版纯数字结果发放普通奖励。
- Lucky Dice 必须先构建候选池，再做随机。
- Lucky Dice 必须先筛选候选池，再做随机。
- 首批筛选器包括是否开启、玩家进度、触发来源、冷却状态、新手期控制。
- Lucky Dice 筛选后按权重随机。
- Lucky Dice 候选池为空时必须有可观测兜底。
- 第一优先兜底是配置的默认结果。
- 如果默认结果也不可用，则降级为普通奖励兜底。
- Lucky Dice 随机结果按 `ResultKey → TargetKey → ModeKey` 解析。
- Rocket 第一版解析到 Slap Down 普通模式。
- Thief 第一版解析到 Treasure Heist 普通模式。
- 教程模式和 bonus 模式作为扩展设计保留，第一版只要求普通模式可用。
- 第一版表现层只需要 Lucky Dice 标题、倍率显示、可配置结果槽和目标玩法跳转反馈。
- 每次 Roll 必须产出追踪信息，包括原始结果、命中规则、执行行为、Lucky Dice 候选决策、选中结果和最终模式。

## 测试决策

最高层测试口应放在完整 Roll 解析流程：给定 Roll 请求、骰子集合配置、组合规则、Lucky Dice 候选池和受控随机源，系统应产出最终结果，例如普通奖励、Lucky Dice 进入 Slap Down、Lucky Dice 进入 Treasure Heist。

低层测试仍然需要，但它们应服务于完整流程测试，而不是替代完整流程测试。

- 测试外部行为，不测试私有实现细节。
- 测试可见骰子结果能正确生成组合事实。
- 测试 `2 + Clover` 和 `Clover + 2` 都能归一为同一个无序组合。
- 测试至少一个 3 骰组合事实，确保系统不写死 2 颗骰子。
- 测试双 Clover 优先级高于泛用 Clover 行为。
- 测试纯数字结果发放普通奖励。
- 测试单 Clover 加数字发放普通奖励并提供 Clover bonus。
- 测试行为分发按行为类型执行，而不是按组合 key 执行。
- 测试双 Clover 能进入 Lucky Dice。
- 测试 Lucky Dice 筛选器能过滤未开启、未解锁或来源不匹配的候选。
- 测试固定随机源下的权重随机结果可预测。
- 测试 Lucky Dice 候选池为空时进入兜底。
- 测试 Rocket 解析到 Slap Down 普通模式。
- 测试 Thief 解析到 Treasure Heist 普通模式。
- 测试 Lucky Dice 结果槽数量来自配置。
- 测试普通骰子数量从 2 改为 3 后，组合事实和匹配器仍按统计结果工作。
- 测试追踪信息足够解释最终结果。

当前项目还没有既有玩法测试套件和生产 C# 模块，因此这些是第一版实现建议采用的测试口，而不是对现有测试的引用。

## 不在范围内

- 完整复刻参考 Lucky Dice 动画。
- 托盘动画、骰子飞入、粒子爆发、白烟转场和完整表现节奏。
- 完整实现 Slap Down 玩法。
- 完整实现 Treasure Heist 玩法。
- 实现所有 Lucky Dice 特殊结果类型。
- 远端配置热更新。
- 复杂运营活动概率策略。
- 埋点管线集成，第一版只要求本地追踪字段。
- 为每个组合 key 写独立业务方法。
- 假设普通骰子永远只有 2 颗。
- 假设 Lucky Dice 永远只有 3 个结果槽。

## 补充说明

本地 HTML 拆解中的竞品流程应作为产品参考，而不是第一版逐帧复刻目标。第一版核心价值是建立可扩展闭环：

```text
普通 Roll
→ 组合事实
→ 规则匹配
→ 行为执行
→ 触发 Lucky Dice
→ 候选筛选
→ 权重随机
→ 目标玩法模式解析
→ 回到主循环
```

第一版应优先保证清晰和可调试。每个关键决策都应能从追踪信息中解释：为什么命中某个组合、为什么进入 Lucky Dice、哪些候选被过滤、最终选中了什么结果、启动了哪个玩法模式。

`to-prd` 技能说明中提到需要发布到 issue tracker 并添加 `ready-for-agent` 标签。但当前项目没有暴露 issue tracker 集成或 triage label 配置，所以本 PRD 先作为本地项目文档落地。
