Files
Fishdice/FishDice/Docs/Decisions/adr-001-separate-normal-and-lucky-dice-sets.md
2026-06-23 14:13:08 +08:00

117 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR-001: 普通骰子和 Lucky Dice 特殊结果分成两套集合
## Status
Accepted
## Date
2026-06-22
## Context
FishDice 第一版需要同时支持普通骰子主循环和 Lucky Dice 特殊分支。普通 Roll 的骰子面是 `2 / 3 / 4 / 5 / 6 / clover`它们的职责是参与组合事实、规则匹配、普通奖励、Clover bonus 和触发 Lucky Dice。
Lucky Dice 进入后使用的是特殊结果,例如 `rocket``thief`。这些结果的职责不是点数结算,而是决定后续进入哪个短玩法,以及进入该玩法的哪个模式。
如果两类结果混用同一套裸字符串或同一个骰子集合,会带来几个风险:
- 普通组合匹配器可能错误处理 Lucky Dice 特殊结果。
- 策划配置容易把数字奖励结果和玩法入口结果混在一起。
- 日志中很难判断某个 key 是普通骰子面还是 Lucky Dice 入口。
- 后续扩展更多特殊结果时,会污染普通 Roll 的规则空间。
## Decision
普通骰子和 Lucky Dice 特殊结果使用两套独立集合,并在数据模型中保留集合类型。
建议在代码中使用等价于以下概念的结构:
```csharp
public enum DiceSetType
{
Normal,
Lucky
}
public readonly struct DiceFace
{
public DiceSetType SetType { get; }
public string Key { get; }
public int? NumberValue { get; }
}
```
普通骰子集合只包含主循环 Roll 面。Lucky Dice 集合只包含特殊入口结果。普通组合事实构建器只接受 `DiceSetType.Normal` 的 Roll 结果,遇到 Lucky Dice 特殊结果时必须拒绝或返回结构化错误。
## Alternatives Considered
### 使用同一个 DiceFace 字符串集合
优点:
- 第一版实现最省事。
- 配置表字段少。
缺点:
- `clover``rocket``thief`、数字面都会落在同一个匹配空间。
- 普通 matcher 需要不断写排除逻辑,防止特殊结果进入普通奖励结算。
- 日志和调试工具无法从类型上识别语义边界。
结论:拒绝。它会把第一版的简单实现成本转化成后续规则扩展和排查成本。
### 使用同一个集合,但通过 key 前缀区分
示例:`normal_2``normal_clover``lucky_rocket`
优点:
- 比裸字符串更可读。
- 不需要额外枚举字段。
缺点:
- 类型边界依赖命名约定,配置错误时很难在编译或校验阶段发现。
- matcher 仍然会看到同一批 key需要人工遵守前缀规则。
- 后续如果出现多套普通骰子或多套特殊结果,前缀会越来越复杂。
结论:拒绝。前缀可以作为日志展示或配置命名辅助,但不能替代结构化集合类型。
### 使用两套独立数据模型
普通骰子面和 Lucky Dice 特殊结果完全使用不同 class。
优点:
- 类型隔离最强。
- 不容易误用。
缺点:
- Roll、展示槽、日志等通用结构需要重复建模。
- 第一版通用流程会变得偏重。
结论:暂不采用。当前使用共同的 `DiceFace` 概念加 `DiceSetType` 已能满足隔离需求。
## Consequences
正向影响:
- 普通 Roll 和 Lucky Dice 的语义边界清晰。
- 普通组合 matcher 不需要理解特殊玩法入口。
- 日志可以明确记录本次处理的是 `Normal` 还是 `Lucky` 集合。
- 后续新增特殊结果不会污染普通奖励规则。
代价和约束:
- 配置工具和调试界面必须展示集合类型。
- 配置加载需要校验普通集合不能包含 Lucky Dice 特殊结果。
- 代码中不能到处裸写 key需要集中定义 key 或配置入口。
## Related Documents
- [Lucky Dice 核心流程 PRD](../PRD/lucky-dice-core-flow-prd.md)
- [Lucky Dice 核心流程规格](../Specs/lucky-dice-core-flow-spec.md)
- [Lucky Dice 核心流程架构蓝图](../Architecture/lucky-dice-core-flow-architecture-blueprint.md)