# FishDice 设计精妙点

← 返回总览 设计精妙点

# 框架设计中值得保留的精妙部分

这些亮点都来自源码证据，不是泛泛的架构赞美。它们共同服务一个目标：让 Lucky Dice 的核心闭环可测、可扩展、可追踪。

## 亮点列表

### 1. Runtime 纯 C#

`noEngineReferences: true` 把 Unity 生命周期、场景和资源从核心中剥离，极大降低测试成本。

### 2. 两套骰子语义隔离

`DiceSetType.Normal` 和 `DiceSetType.Lucky` 分开，`ComboFactBuilder` 明确拒绝 Lucky 结果进入普通组合事实。

### 3. 先事实化再匹配

`ComboFacts` 生成 normalized key、ordered key、face count、number sum，避免 matcher 直接读“左骰/右骰”。

### 4. 按类型注册扩展

Matcher 按 `MatcherType`，Action 按 `ActionType` 注册，扩展点清晰。

### 5. 随机源可注入

`IRandomSource` 让 Roll 和 Lucky Dice 权重随机都能用固定序列测试。

### 6. 配置先校验再运行

`LuckyDiceConfigValidator` 提前捕获未知 matcher、未知 action、重复 id、坏候选和缺失 target mode。

### 7. Trace 贯穿链路

`RollTrace` 用同一个 session 记录决策链，便于复盘线上问题。

### 8. Demo 和核心解耦

DemoRunner 和 Controller 只消费核心结果，证明表现层可以替换。

## 最关键的架构判断

框架没有急着做“完整玩法管理器”，而是先把最容易膨胀的部分拆成事实、规则、行为、候选和模式解析。这让第一版虽然小，但变化方向是可控的。

## 为什么这些设计对游戏框架重要

游戏玩法框架最怕两类增长：一类是组合数量增长导致 if/else 爆炸，另一类是表现层倒灌核心导致每次改动画都影响规则。FishDice 当前通过规则配置、Action 分发和纯核心边界，把这两类风险先压住了。

## 证据

- ComboFactBuilder.cs:14-24：拒绝 Lucky set 和 dice count 不一致。
- ComboFactBuilder.cs:26-36：构建统计事实和 normalized key。
- ComboRuleMatcher.cs:26-45：按优先级匹配并支持 StopAfterMatched。
- DiceRollService.cs:5-16：`IRandomSource` 抽象。
- LuckyDiceConfigValidator.cs:13-154：配置校验覆盖规则、候选、target mode、注册表。
- LuckyDiceCoreFlowTests.cs:26-63：完整 Lucky Dice 到 target mode 的链路测试。