355 lines
10 KiB
Markdown
355 lines
10 KiB
Markdown
# Lucky Dice 核心流程需求
|
||
|
||
## 目标
|
||
|
||
本文档定义 FishDice 中普通骰子流程与 Lucky Dice 特殊分支的最小核心逻辑。当前阶段忽略复杂动画表现,只保留玩法闭环、规则扩展口、随机筛选口和目标玩法模式解析口。
|
||
|
||
核心目标:
|
||
|
||
- 普通骰子流程可以通过不同组合触发不同业务行为。
|
||
- 双四叶草组合可以触发 Lucky Dice 特殊流程。
|
||
- Lucky Dice 内部使用独立的特殊骰子结果池,不与普通数字骰混用。
|
||
- 骰子数量和结果槽数量需要可配置,第一版可以使用 2 颗普通骰和 3 个 Lucky Dice 结果槽,但规则系统不能写死这个数量。
|
||
- Lucky Dice 结果进入目标玩法前,需要保留筛选、随机和模式解析扩展点。
|
||
- 执行层避免维护巨大的“组合 key 到方法”的硬编码映射。
|
||
|
||
## 概念边界
|
||
|
||
### 普通骰子
|
||
|
||
普通流程使用一套主循环骰子面:
|
||
|
||
```text
|
||
2 / 3 / 4 / 5 / 6 / Clover
|
||
```
|
||
|
||
其中 `1` 被 `Clover` 替代。普通骰子负责主循环奖励、倍率、特殊触发等常规行为。
|
||
|
||
普通骰子的数量需要由骰子集合配置决定。第一版默认使用 2 颗普通骰,但系统需要支持后续扩展到 3 颗、4 颗或特殊关卡自定义数量。
|
||
|
||
最小组合语义:
|
||
|
||
- 数字 + 数字:普通奖励。
|
||
- 数字 + Clover:普通奖励加小额 bonus 或倍率反馈。
|
||
- Clover + Clover:触发 Lucky Dice。
|
||
|
||
后续可扩展更多组合含义,例如对子、三连、指定数量命中、点数和区间、指定数字组合、顺序组合等。
|
||
|
||
### Lucky Dice 特殊骰子
|
||
|
||
Lucky Dice 进入后使用另一套特殊结果骰子,不再使用普通数字骰。
|
||
|
||
示例特殊结果:
|
||
|
||
```text
|
||
Rocket / Thief / Chest / Bomb / Key
|
||
```
|
||
|
||
这套结果的职责是决定后续玩法入口,而不是做普通点数结算。
|
||
|
||
Lucky Dice 的结果槽数量也需要可配置。竞品拆解中表现为 3 格相同特殊结果,第一版可以固定为 3;但数据结构和播放流程需要允许后续扩展为 2 格、4 格或按玩法目标定义槽数量。
|
||
|
||
最小语义:
|
||
|
||
- Rocket:进入 Slap Down。
|
||
- Thief:进入 Treasure Heist。
|
||
|
||
## 总体流程
|
||
|
||
```text
|
||
玩家触发普通 Roll
|
||
→ 产出普通骰子结果
|
||
→ 提取组合事实 ComboFacts
|
||
→ 按优先级匹配普通组合规则
|
||
→ 执行规则配置的行为列表
|
||
→ 普通奖励:发放奖励并结束
|
||
→ Lucky Dice:进入 Lucky Dice 流程
|
||
|
||
Lucky Dice 流程
|
||
→ 构建特殊结果候选池
|
||
→ 按上下文筛选候选结果
|
||
→ 按权重随机一个结果
|
||
→ 按结果槽数量显示相同或配置指定的特殊结果
|
||
→ 解析目标玩法与进入模式
|
||
→ 启动目标玩法
|
||
→ 目标玩法结束后回到主循环
|
||
```
|
||
|
||
## 普通组合规则需求
|
||
|
||
### 组合 key
|
||
|
||
组合规则允许使用字符串 key 作为数据 ID,例如:
|
||
|
||
```text
|
||
clover_clover
|
||
number_number
|
||
number_clover
|
||
```
|
||
|
||
使用字符串 key 的目的:
|
||
|
||
- 便于配置表、JSON、远端配置和日志使用。
|
||
- 新增组合时不一定需要新增枚举或改代码。
|
||
- 规则识别与执行逻辑可以解耦。
|
||
|
||
约束:
|
||
|
||
- 不允许在业务代码中到处裸写字符串。
|
||
- 组合 key 只作为规则索引或配置 ID。
|
||
- 原始骰子结果、数量统计、是否有序等信息必须保留在结构化数据中。
|
||
|
||
### 组合事实
|
||
|
||
普通 Roll 产出后,需要生成组合事实,供规则匹配器使用。
|
||
|
||
至少包含:
|
||
|
||
```text
|
||
DiceSetType 骰子集合类型,普通骰子或 Lucky Dice
|
||
DiceCount 本次 Roll 实际骰子数量
|
||
Faces 原始骰子面列表
|
||
FaceCounts 每个骰子面的数量
|
||
NumberSum 数字骰点数和
|
||
NumberValues 本次出现的数字点数列表
|
||
CloverCount 四叶草数量
|
||
HasClover 是否包含四叶草
|
||
NormalizedKey 无序归一化 key
|
||
OrderedKey 有序 key
|
||
```
|
||
|
||
组合事实不能假设只有 2 颗骰子。`Faces` 和 `FaceCounts` 必须支持任意数量,规则匹配器应基于数量统计和条件表达,而不是只读取左骰、右骰两个固定位置。
|
||
|
||
普通组合默认按无序处理,例如:
|
||
|
||
```text
|
||
clover + 2
|
||
2 + clover
|
||
```
|
||
|
||
都归一为:
|
||
|
||
```text
|
||
2_clover
|
||
```
|
||
|
||
如果后续需要区分左骰、右骰或先后顺序,可以在规则中显式声明使用有序 key,例如:
|
||
|
||
```text
|
||
clover_then_rocket
|
||
rocket_then_clover
|
||
```
|
||
|
||
### 规则匹配
|
||
|
||
组合系统不应为每个组合写独立方法,而应使用少量通用匹配器。
|
||
|
||
首批匹配器需求:
|
||
|
||
- ExactCombo:精确匹配组合 key,例如 `clover_clover`。
|
||
- AllNumbers:全部为数字骰。
|
||
- ContainsFace:包含指定面,例如包含 1 个 Clover。
|
||
- FaceCount:指定面数量达到要求。
|
||
- FaceCountRange:指定面数量落在区间内,例如至少 2 个 Clover。
|
||
- DiceCount:本次骰子数量满足要求,例如只匹配 2 骰或 3 骰规则。
|
||
- NumberPair:数字对子。
|
||
- NumberOfAKind:N 个相同数字,例如三连、四连。
|
||
- NumberSumRange:点数和落在区间内。
|
||
|
||
规则需要支持优先级,优先级高的规则先匹配。
|
||
|
||
最小规则配置:
|
||
|
||
```text
|
||
优先级 100:clover_clover → trigger_lucky_dice
|
||
优先级 50:contains Clover count 1 → grant_reward + clover_bonus
|
||
优先级 10:all_numbers → grant_reward
|
||
```
|
||
|
||
当后续加入更多骰子数量时,应优先使用统计型规则,例如:
|
||
|
||
```text
|
||
Clover count >= 2 → trigger_lucky_dice
|
||
NumberOfAKind count 3 → grant_reward + combo_bonus
|
||
DiceCount 4 + NumberSumRange 18-24 → grant_reward + high_sum_bonus
|
||
```
|
||
|
||
## 行为执行需求
|
||
|
||
执行层只注册少量通用行为执行器,不维护“所有组合 key 到方法”的巨大 map。
|
||
|
||
规则配置只描述要执行哪些行为,行为执行器按行为类型处理。
|
||
|
||
首批行为类型:
|
||
|
||
- grant_reward:发放普通奖励。
|
||
- add_multiplier:调整倍率或临时倍率。
|
||
- trigger_lucky_dice:进入 Lucky Dice。
|
||
- enter_mode:进入指定玩法模式。
|
||
- show_popup:显示提示或轻量弹窗。
|
||
|
||
执行器注册表只随行为类型增长,不随组合数量增长。
|
||
|
||
示例:
|
||
|
||
```text
|
||
grant_reward → GrantRewardExecutor
|
||
trigger_lucky_dice → TriggerLuckyDiceExecutor
|
||
enter_mode → EnterModeExecutor
|
||
```
|
||
|
||
组合扩展优先通过新增规则配置完成;只有出现新的通用行为类型时,才新增执行器。
|
||
|
||
## Lucky Dice 筛选与随机需求
|
||
|
||
Lucky Dice 结果不能直接从全部特殊结果中随机,必须经过候选池构建、筛选和权重随机。
|
||
|
||
### 候选结果
|
||
|
||
候选结果至少包含:
|
||
|
||
```text
|
||
ResultKey 特殊结果 ID,例如 rocket / thief
|
||
TargetKey 目标玩法 ID,例如 slap_down / treasure_heist
|
||
Weight 随机权重
|
||
Enabled 是否启用
|
||
MinLevel 最低等级或进度要求
|
||
SourceFilter 允许的触发来源
|
||
CooldownRule 冷却或次数限制
|
||
```
|
||
|
||
### 筛选器
|
||
|
||
首批筛选器需求:
|
||
|
||
- EnabledFilter:过滤未开启结果。
|
||
- ProgressFilter:过滤玩家进度不满足的结果。
|
||
- SourceFilter:过滤当前触发来源不允许的结果。
|
||
- CooldownFilter:过滤处于冷却或次数已满的玩法。
|
||
- TutorialFilter:新手期可强制或限制候选结果。
|
||
|
||
筛选器应可组合,筛选后如果候选池为空,需要有兜底策略。
|
||
|
||
兜底策略:
|
||
|
||
- 优先使用配置的 default result。
|
||
- 如果 default result 不可用,走普通奖励兜底。
|
||
- 兜底发生时需要打日志,方便排查配置问题。
|
||
|
||
### 随机选择
|
||
|
||
筛选后的候选结果按权重随机。
|
||
|
||
随机需求:
|
||
|
||
- 支持普通权重随机。
|
||
- 支持按上下文调整权重,例如活动期间提高某结果权重。
|
||
- 支持新手期固定结果或半随机结果。
|
||
- 随机结果需要可记录,方便回放、埋点和问题排查。
|
||
|
||
## 目标玩法与模式解析
|
||
|
||
Lucky Dice 的 `ResultKey` 不直接等于最终进入模式。需要分为两层:
|
||
|
||
```text
|
||
ResultKey → TargetKey → ModeKey
|
||
```
|
||
|
||
含义:
|
||
|
||
- ResultKey:Lucky Dice 抽中的特殊结果,例如 `rocket`。
|
||
- TargetKey:目标玩法,例如 `slap_down`。
|
||
- ModeKey:目标玩法的具体进入模式,例如 `slap_down_normal`。
|
||
|
||
示例:
|
||
|
||
```text
|
||
rocket → slap_down
|
||
slap_down + 新手期 → slap_down_tutorial
|
||
slap_down + 普通状态 → slap_down_normal
|
||
slap_down + 高倍率 → slap_down_bonus
|
||
```
|
||
|
||
首批模式解析规则:
|
||
|
||
- TutorialModeRule:新手期进入教程模式。
|
||
- BonusModeRule:高倍率或特殊上下文进入 bonus 模式。
|
||
- DefaultModeRule:默认进入普通模式。
|
||
|
||
目标玩法启动时,需要携带:
|
||
|
||
```text
|
||
TargetKey
|
||
ModeKey
|
||
ResultKey
|
||
Multiplier
|
||
TriggerSource
|
||
RollSessionId
|
||
```
|
||
|
||
## 最小可交付范围
|
||
|
||
第一版只需要实现以下玩法闭环:
|
||
|
||
### 普通骰子
|
||
|
||
```text
|
||
骰子面:2 / 3 / 4 / 5 / 6 / Clover
|
||
默认骰子数量:2
|
||
骰子数量来源:DiceSet 配置
|
||
```
|
||
|
||
组合行为:
|
||
|
||
```text
|
||
数字 + 数字 → 普通奖励
|
||
数字 + Clover → 普通奖励 + Clover bonus
|
||
Clover + Clover → 触发 Lucky Dice
|
||
```
|
||
|
||
### Lucky Dice
|
||
|
||
特殊结果:
|
||
|
||
```text
|
||
Rocket → SlapDownNormal
|
||
Thief → TreasureHeistNormal
|
||
默认结果槽数量:3
|
||
结果槽数量来源:Lucky Dice 结果或玩法配置
|
||
```
|
||
|
||
表现最小化:
|
||
|
||
```text
|
||
显示 Lucky Dice 标题
|
||
→ 显示倍率
|
||
→ 按结果槽数量显示特殊图标
|
||
→ 进入目标玩法
|
||
```
|
||
|
||
复杂动画如托盘、骰子飞入、粒子爆发、白烟转场等不进入第一版核心逻辑要求。
|
||
|
||
## 非目标
|
||
|
||
第一版不要求:
|
||
|
||
- 完整复刻竞品动画时长和粒子效果。
|
||
- 实现所有特殊结果类型。
|
||
- 实现复杂运营活动权重策略。
|
||
- 实现完整短玩法内容。
|
||
- 实现远端配置热更新。
|
||
|
||
## 验收标准
|
||
|
||
- 普通骰子结果能被转换为结构化组合事实。
|
||
- 普通骰子数量和 Lucky Dice 结果槽数量来自配置,核心规则不写死为 2 骰或 3 格。
|
||
- 规则系统能通过少量通用匹配器命中普通组合。
|
||
- 双四叶草能触发 Lucky Dice,而不是直接发普通奖励。
|
||
- 行为执行层只依赖少量通用执行器,不存在按组合数量增长的大型方法 map。
|
||
- Lucky Dice 能先筛选候选结果,再按权重随机。
|
||
- Lucky Dice 结果能解析到目标玩法和具体模式。
|
||
- Rocket 能进入 Slap Down 普通模式。
|
||
- Thief 能进入 Treasure Heist 普通模式。
|
||
- 候选池为空时存在可观测兜底。
|
||
- 日志或调试信息能追踪一次 Roll 从普通结果到最终行为的关键决策。
|