312 lines
18 KiB
Markdown
312 lines
18 KiB
Markdown
# B1 战斗结算规则(lean 格式样例)
|
||
|
||
> **状态**:格式样例——用新格式重排现有 `b1-settlement.md` 的内容域,供评审,非生效文档(行协议计数等现行口径以 `design/gdd/systems/战斗循环/战斗结算.md` 为准)
|
||
> **版本**:lean-sample · 2026-09-13 · 作者:user + agents
|
||
> **一句话**:B1 把每轮扫雷的结果逐行兑现为战斗结果,并判定胜负。
|
||
|
||
## 速览
|
||
|
||
| 关键问题 | 答案 |
|
||
|---|---|
|
||
| 定位 | 战斗域编排与结算中枢;轮次生命周期唯一 owner |
|
||
| 拥有 | 段序、判定时机、伤害消费侧语义、明细流水协议、上游义务账本(B3×8 / B2×6 / A2×3 / B4×6) |
|
||
| 不拥有 | 单位状态(B2)· 状态实例(B3)· 奖励内容(B4)· 行动价目(A3)· 棋盘规则(A1/A2)· 呈现(D1/B5) |
|
||
| 上游输入 | A2 三事件流 · A3 相位观测量 · 各表值快照 |
|
||
| 下游输出 | 结算步骤流(D1/B5/D4 消费)· 条款③⑤对账结论(C3 约束输入) |
|
||
| 硬约束 | 零随机 · 零 UI 依赖 · 结算禁 await——同种子同输入 ⇒ 步骤流逐行相同 |
|
||
|
||
## 体验锚点
|
||
|
||
| 支柱 | 关键词 | 机制承诺 |
|
||
|---|---|---|
|
||
| P2 因果归因 | "都是我算出来的" | 每行明细携带来源标注;无来源行 = 断言失败(AC-42) |
|
||
| P1 掌控感 | "挖下去值得" | 条款③不等式由本系统闭合签字 |
|
||
| P3 雷的两面 | "赌桌不是陷阱" | 敌方伏击行与标中旗削弱行同框、同呈现语言 |
|
||
| 高光节拍 | "完美被加倍兑现" | 完美排雷双份兑付 + 标中旗行高光 |
|
||
|
||
## 全局流程
|
||
|
||
### 战斗开始
|
||
|
||
```
|
||
begin_battle(encounter)
|
||
│ ① set_reload_gate(true) [D2] 调试门置位
|
||
│ ② notify_battle_start() [B3] 容器开域
|
||
│ ③ spawn(L, D, hero_hp) [B2] 行值快照实例化
|
||
│ ④ install_board + roll_board [A2/B4] 恰一次;资格格清单 = S ∖ R₀
|
||
│ ⑤ notify_round_start() [A3] → Active
|
||
▼
|
||
RoundActive(挖掘期,B1 只缓冲事件流)
|
||
```
|
||
|
||
### 每轮结算(七段骨架,全序执行、段序结构冻结)
|
||
|
||
```
|
||
轮末触发:Waiting 相位编排点(只读 A3 相位观测量,不依赖事件到达序)
|
||
│
|
||
▼
|
||
①授予段 ──── cell_revealed 批 → flag_judged 批 → 清图奖励(仅 cleared 轮)
|
||
│ (转化规则见下方两表)
|
||
▼
|
||
②道具使用窗口 ─ 玩家至多选一件或跳过(全流程唯一玩家输入点)
|
||
│ 满血禁选治疗包;空库存可整体不弹窗
|
||
▼
|
||
③增益/减益段 ─ query_active 双侧读值 → SettlementTable 语义映射 → 效果明细行
|
||
│
|
||
▼
|
||
④道具段 ───── 伤害道具:恒定表值打 default_target;治疗包:clamp 回复
|
||
│ 施加时无存活敌 → 照常消耗 + "已消耗未生效"行
|
||
▼
|
||
⑤战斗段 ───── 主角先手攻击(D_hero = atk ×(1+attack_up))
|
||
│ → 逐存活敌(行主序):query_attack → apply_damage → advance
|
||
│ ※ hero hp=0 → 立即短路,剩余敌不作用,直入 ⑦
|
||
▼
|
||
⑥衰减段 ───── decay_round() 恰一次(含末轮;先兑付后衰减的时序契约)
|
||
│
|
||
▼
|
||
⑦判定段 ───── hero hp=0 → 失败 │ 存活敌=∅ → 胜利 │ 否则 → 下一轮
|
||
```
|
||
|
||
### 出口分发
|
||
|
||
| 结局 | 触发 | 动作序列 | 约束 |
|
||
|---|---|---|---|
|
||
| 继续 | 判定=下一轮 | `notify_settlement_done(same_board)` → `notify_round_start()` | 同图续轮 |
|
||
| 换图 | cleared 轮 | `retire_board` → `retire_mapping` → A1 `generate` → `install_board` → `roll_board` 恰一次 → `notify_settlement_done(new_board)` → `notify_round_start()` | stopped/ap_exhausted 恒 same_board,违约 fail-fast |
|
||
| 挖掘期刷新 | 玩家经 D1 发起 | A3 `request_refresh` 扣费 → 换图全序(无结算段、无 round_end、轮次不终结) | RAP 不足→拒绝上抛;每图 cap 2;刷新图无清图奖励 |
|
||
| 战斗结束 | 判定=胜/负 | `retire_mapping` → `despawn_all` → `notify_battle_end` → `notify_combat_end` → `set_reload_gate(false)` | 库存不清(关内延续) |
|
||
| 关卡结束 | 上层显式调用 | `clear_inventory()` 恰一次,清空前快照计数返回 | victory/defeat 皆然 |
|
||
|
||
## 核心规则
|
||
|
||
| # | 规则 | 要点 |
|
||
|---|---|---|
|
||
| 1 | 编排唯一性 | B1 是战斗域全部跨系统调用的唯一发起方;B2/B3/B4 零相互直调 |
|
||
| 2 | 结算触发 | Waiting 相位编排点;不依赖事件到达序 |
|
||
| 3 | facts 缓冲 | 按轮缓冲事件、轮末统一转化;事实→授予恰一次(B4 幂等仅兜底) |
|
||
| 4 | 段序骨架 | 七段全序(见上图);修订走 GDD 流程,非调参 |
|
||
| 5 | 授予段 | 三批转化,见下两表 |
|
||
| 6 | 伏击转化 | `ambush_grant_plan(mines_r, cap)`;前 granted_r 颗逐颗授予;池 L side 共享、dur=1 轮末清零 |
|
||
| 7 | 道具窗口 | B4 `query_inventory` 投影 + B1 守卫预判;至多一件;选择序列入回放 |
|
||
| 8 | 增益/减益 | 读值→语义映射→池合成(F2);明细按授予流水逐条标注来源 |
|
||
| 9 | 道具段 | 伤害恒定表值不吃修正;满血守卫拒治疗;零效果判定读 B2 存活集 |
|
||
| 10 | 战斗段 | 主角先手攻击 + 逐敌循环(调用序钉死);死亡即不动手;hero 死亡短路 |
|
||
| 11 | 衰减段 | 恰一次、恒执行、含末轮 |
|
||
| 12 | 判定段 | hero 先判(防御性优先级);胜负明细行 |
|
||
| 13 | 高光节点 | #2 完美排雷=清图奖励双份兑付;#3 标中旗=行字段 highlight(见枚举表) |
|
||
| 14 | 明细流水协议 | 13 类行封闭枚举 + 公共字段(见枚举表)——D1/B5/D4 的统一数据源契约 |
|
||
| 15 | 可回放性 | 零随机 + 确定性输入 + 表值快照 ⇒ 同种子同输入步骤流逐行相同 |
|
||
| 16 | 数值承载 | 全部数值在 D2 SettlementTable;B1 代码零数值字面量;战斗中热重载被门拒绝 |
|
||
|
||
### 授予段:三批转化
|
||
|
||
| 批 | 输入 | 转化 | 产出 |
|
||
|---|---|---|---|
|
||
| cell_revealed | `kind=mine` | 调 `ambush_grant_plan`,事件规范序逐颗 `apply_effect(ambush)` | 伏击池 L;溢出产"溢出未生效"行 |
|
||
| cell_revealed | `kind=safe ∧ reward_eligible` | 按 category 分流(见下表) | 每格受理恰一次 |
|
||
| flag_judged | `hit=true` 且资格未消费 | `apply_effect(weaken)` + 资格消费 | 标中旗行(highlight=`flag_hit`) |
|
||
| flag_judged | `hit=true` 且资格已消费 | 去重跳过(每雷实例一次) | 零新增行 |
|
||
| flag_judged | `hit=false` | 零兑付 | "标旗未中"零值行(highlight=`perfect_broken`) |
|
||
| cleared 轮 | — | `grant_clear()` 恰一次;完美板(零误标 ∧ ≥1 标中)追加第二份同身份兑付 | 清图奖励行;完美高光行 |
|
||
|
||
### 授予段:奖励分流
|
||
|
||
| category | 兑付方式 | 拒绝语义 |
|
||
|---|---|---|
|
||
| buff | `apply_effect`(入池,结算段生效) | 满层 → "奖励未生效"行,无折算 |
|
||
| instant_aoe | 全体存活敌各 `power` 点(逐个 apply_damage) | 当场兑付,不进库存 |
|
||
| instant_heal | 主角回复 `power`(clamp) | 满血 → "奖励未生效"行 |
|
||
| damage_item / heal_pack | `stock()` 入关卡域库存 | 窗口选用时兑付 |
|
||
|
||
## 枚举
|
||
|
||
### 明细行类型(封闭枚举,13 类)
|
||
|
||
| 行类型 | 特有字段 | 产出点 | 说明 |
|
||
|---|---|---|---|
|
||
| 效果行 | `effect_id` `pool_value` | 增益/减益段 | value=该次授予贡献值;pool_value=池合成值(防 −130%×2 行误读为 −260%) |
|
||
| 伤害行 | `target` | 道具段 / 战斗段 | 分量二元组 + 减伤终值 + 击杀标记 |
|
||
| 治疗行 | — | 道具段 | clamp 后真实回复量 |
|
||
| 道具行 | `target` | 授予段 / 道具段 | 入库 / 生效 / 语境注记 |
|
||
| 奖励未生效行 | 聚合计数 | 授予段 | 满层拒绝、满血、雾板等合法例外 |
|
||
| 已消耗未生效行 | — | 道具段 | 施加时已无存活敌(Used 不可逆) |
|
||
| 使用被拒行 | — | 道具段 | 满血治疗包守卫 |
|
||
| 溢出未生效行 | — | 授予段 | 伏击/奖励族同名协议 |
|
||
| 标旗未中行 | highlight=`perfect_broken` | 授予段 | 零值归因行;每雷实例一次去重 |
|
||
| 蓄力行 | — | 战斗段 | charge 拍零作用 |
|
||
| 衰减行 | — | 衰减段 | 移除数 k(呈现聚合归 D1) |
|
||
| 判定行 | — | 判定段 | 胜负 / 继续 |
|
||
| 高光行 | — | 授予段(清图) | 完美排雷;value=实际有效兑付,禁记名义值 |
|
||
|
||
**公共字段**(13 类全必有):`type` `source_class` `origin_cell`(板级行可空)`round_index` `display_name` `value` `highlight?`
|
||
**断言**:无来源行 = 失败(AC-42)。
|
||
|
||
### source_class(封闭枚举)
|
||
|
||
| 值 | 来源 |
|
||
|---|---|
|
||
| safe_cell / flag_hit / mine_hit / clear_default | B3 既有四源 |
|
||
| 道具/判定扩展 | B4 交付语义 |
|
||
| enemy_action | 敌方行动行(伤害/蓄力) |
|
||
| flag_miss | 标旗未中零值行 |
|
||
| hero_attack | 主角先手攻击伤害行 |
|
||
|
||
新增值 = 接口漂移,须同步 `source_label_map` 键集。
|
||
|
||
### highlight(可空枚举)
|
||
|
||
| 值 | 含义 |
|
||
|---|---|
|
||
| `flag_hit` | 标中旗削弱兑付行强调 |
|
||
| `clear_reward_h2` | 清图奖励行强调 |
|
||
| `perfect_broken` | 本板完美谓词已破的归因锚 |
|
||
|
||
## 数值结论与推导
|
||
|
||
> 章节纪律:**结论先行**(加粗一行),下接「推导」小标题给公式与验算表。F1 对照表 / F3 伤害合成迁移时同模式展开(Variables 表 + Example 一行)。
|
||
|
||
### F0 当量归一口径(weaken 锚裁决)
|
||
|
||
**结论**:采用"每结算瞬时当量"口径;m_w 值域 [60, 85]、默认 −65;地板交叉层数 = 2;B3/B4 零接口修订(值变更走 registry 回写)。
|
||
|
||
#### 推导
|
||
|
||
- **同分母性**:weaken 与 defense_up 作用于同一伤害流,"严格大于"在百分点读法与 HP 读法下等价,锚判定无量纲歧义。
|
||
- **机制同构**:B3 本就按结算逐次兑付,瞬时口径是容器原生口径;"每 AP 总暴露"需跨结算累计账本,与已锁的"单结算自然边界"冲突。
|
||
- **schema 禁止**:总暴露口径需 m_w > 100,越出 percent ∈ [−100, 100] 域,改域 = 三侧换算连锁,成本不成比例。
|
||
|
||
### F2 乘区合成
|
||
|
||
**结论**:池内加算 → 每池独立 clamp [−100, +100] → 池间乘算 → floor 单一取整;免伤轮(D'=0)是合法设计态,产零值伤害行、不调 apply_damage。
|
||
|
||
#### 公式
|
||
|
||
```
|
||
P_pool = Σ(同池实例 L×m) 池内加算
|
||
P_pool ← clamp(P_pool, −100, +100) 每池独立地板
|
||
M_pool = 1 + P_pool ÷ 100 域 [0, 2]
|
||
D' = floor(D_raw × M_hero × M_enemy) 池间乘算,单一取整
|
||
```
|
||
|
||
例:D_raw=20、weaken L=2 → P=−130 → clamp −100 → M=0 → D'=0(零值伤害行)。
|
||
|
||
### F4 条款③挖掘风险不等式
|
||
|
||
**结论**:默认行值通过(锚行口径 L1≈2.0× / L2≈2.6×;跨行期望口径 1.2× / 1.5×,二元结论一致);满配 unit_count=3 破线 → 登记 C3 调参约束。actuals p10 交付后强制重跑。
|
||
|
||
#### 公式与验算
|
||
|
||
```
|
||
主式:P(安全) × V_safe > P(雷) × V_mine (决策单位=单格挖掘;评估点=残余盲猜端最坏点)
|
||
P(雷) = |M| ÷ (|M| + (1−ι)×|S|) (残余盲猜端上界)
|
||
V_safe = D_ref(锚行满寿命恒等式);V_mine = unit_count × m_amb
|
||
域守卫:(1−ι)×|S| < 1 ⇒ 主式不评估,信息端平凡腿接管
|
||
```
|
||
|
||
| 板形 | P(雷) | 左臂 | 右臂 | 裕度 | 判定 |
|
||
|---|---|---|---|---|---|
|
||
| L1(\|M\|=9,\|S\|=91,ι=0.95) | 0.664 | 4.03 | 1.99 | ≈2.0× | ✓ |
|
||
| L2(\|M\|=16,\|S\|=128,ι=0.92) | 0.610 | 4.68 | 1.83 | ≈2.6× | ✓ |
|
||
| 满配(unit_count=3,V_mine=9) | 0.664 | 4.03 | 5.98 | <1 | ✗ 破线 → C3 约束 |
|
||
|
||
注:C3 不得以锚行读数(2.0×/2.6×)作为 unit_count=2 的放行依据。
|
||
|
||
### F5 条款⑤清图支配性
|
||
|
||
**结论**:**未闭合**(挖穿残余池计价,两态为负)→ C3/B4 约束包:C 量级上调,或裁"清图非严格支配"为设计态,二选一归 C3。
|
||
|
||
#### 公式
|
||
|
||
```
|
||
Δ_clear = [R_res + C_eff] − [X_res + Δr × s_ref] (主判式,≥0 为闭合)
|
||
E[踩雷] = |M| × n_s ÷ (n_s + 1) (挖穿残余池期望,均匀交错模型)
|
||
```
|
||
|
||
### 边界参数总表
|
||
|
||
| 参数 | 边界 | 默认 | 出处 |
|
||
|---|---|---|---|
|
||
| percent 池 clamp | [−100, +100] pp,每池独立收口 | — | F2 |
|
||
| 池乘数域 | [0, 2](= 1 + pp/100) | — | F2 |
|
||
| m_w(weaken 行值) | [60, 85] | −65 | F0 裁决(瞬时当量口径) |
|
||
| 地板交叉层数 | ⌈100/m_w⌉ = 2(值域内恒 2) | — | F0 |
|
||
| P_perfect 载体域 | **{100, 200}**,域外加载致命 | 200(×2 双份交付) | Core Rule 13 |
|
||
| D_ref(当量参考敞口) | [1, 999] | 12 | SettlementTable |
|
||
| HeroTable.atk | [1, 999],0 加载拒绝 | 6 | 2026-09-11 拍板 |
|
||
| 伤害 D' | 整数 [0, ∞),零负值分支 | — | F3 |
|
||
| D' = 0 | **不调** apply_damage,产零值伤害行 | — | 负值分支禁令 |
|
||
| 取整 | floor,单一规则(结构性,非 knob) | — | F2 |
|
||
| 溢杀 | 丢弃,不转移、无负 hp 态 | — | F3 |
|
||
| 治疗 | hp' = min(hp + power, max_hp) | — | F3 |
|
||
|
||
### SettlementTable schema(单行全局,B1 回填 owner)
|
||
|
||
| 字段 | 类型/域 | 默认 | knob |
|
||
|---|---|---|---|
|
||
| equivalence_ref_damage(D_ref) | int [1,999] | 12 | ✓(变更触发全对账重跑) |
|
||
| p_perfect | percent {100, 200} | 200 | ✓ |
|
||
| effect_pool_map | effect_id → {hero_offense, hero_defense, enemy_output, flat_attach} | — | ✗ |
|
||
| rounding_direction | floor(结构性) | floor | ✗ |
|
||
| pool_clamp_lo / pool_clamp_hi | int | −100 / +100 | ✗ |
|
||
| source_label_map | 键集 = source_class 全集 | — | 随接口漂移 |
|
||
|
||
## 状态
|
||
|
||
| 状态 | 进入条件 | 行为/出口 |
|
||
|---|---|---|
|
||
| Uninit | 冷启动 / 清理完成 | 唯一出口 `begin_battle` |
|
||
| BattleSetup | `begin_battle` 受理 | 战斗开始序列;任一步拒绝 = fail-fast 上抛 |
|
||
| RoundActive | `notify_round_start` | 不干预挖掘,只缓冲事件流 |
|
||
| RoundWaiting | 轮次结束事务达成 | 执行七段结算;窗口段为唯一玩家输入点 |
|
||
| BattleOver | 判定段产胜负 | 战斗结束序列 → Uninit |
|
||
|
||
不变式:同时刻至多一个结算事务在飞;段序恒全序(短路是段内规则非跳段);跨系统调用集中在 B1。
|
||
|
||
## 边界情况
|
||
|
||
| 条件 | 行为 | 依据 |
|
||
|---|---|---|
|
||
| 末图清图即胜利 | 清图奖励先兑付 → 窗口可选用 → 战斗段空转 → 衰减 → 判胜 | B4 E15 |
|
||
| 战斗段 hero hp=0 | 立即短路,剩余敌不作用不产行 | 用户拍板 |
|
||
| 判定时敌我双 hp=0 | 结构不可达;防御规则 hero 先判 | Core Rule 12 |
|
||
| 合成后 D'=0 | 不调 apply_damage,产零值伤害行 | 负值分支禁令 |
|
||
| 伤害溢出 | 溢出丢弃;行 value=D'、击杀布尔,不记溢出量 | F3 |
|
||
| charge 拍本轮踩雷 | 伏击授予照常;战斗段零伤害,池 dur=1 蒸发 | B2 EC8 |
|
||
| 全体存活敌同拍 charge | N 行蓄力行、零伤害——合法状态 | B2 EC |
|
||
| 伏击池 L=0 时敌攻击 | D_raw=纯基线 atk,自然读值非缺失分支 | B2 F2 |
|
||
| 刀施加时已无存活敌 | 照常消耗 + "已消耗未生效"行 | B4 E10 |
|
||
| 窗口打开时库存空 | 跳过合法;D1 可不弹窗;段序零停顿 | B4 E8 |
|
||
| 挖掘期刷新 RAP 不足 | `request_refresh` 返回 false,原样上抛拒绝 | A3 EC13 |
|
||
| 同轮多次刷新(cap 内) | 每次独立走换图全序,取新 scope | A3 EC15 |
|
||
| 清图槽 buff 且满层 | 零兑付 + "奖励未生效"行;完美高光降级不发 | B4 E11 |
|
||
| 完美谓词在刷新图上 | 刷新图无兑付点,不触发;flag 计数随 install 重置 | Core Rule 13 |
|
||
| 板内既有标中又有误标 | 完美不成立;首个误标产"标旗未中"行(perfect_broken) | 单档完美,两档扩展被否 |
|
||
| 多敌同结算攻击 | 行主序逐敌、共享 L;任一作用后 hero 死 → 短路 | Core Rule 10 |
|
||
| battle_over 清理中被拒 | 诊断 + 幂等兜底;清理序列必须完成 | 防半清理态泄漏 |
|
||
| 战斗中热重载请求 | 门已置位 → D2 拒绝返回 false | D2 EC8 |
|
||
|
||
## 依赖
|
||
|
||
**上游**(除 C1/C2 外全部 Approved——B1 是首个上游全就绪的系统):
|
||
|
||
| 系统 | 性质 | 接口要点 |
|
||
|---|---|---|
|
||
| D2 | hard | SettlementTable(B1 回填)+ `set_reload_gate` 唯一调用方 |
|
||
| A3 | hard | 五条款下游契约(B1 为①②③⑤闭合 owner)+ 结算回发 + `last_round_end` |
|
||
| A2 | hard(订阅) | 三事件流 + `install_board`/`retire_board` + Waiting 观测量 |
|
||
| B2 / B3 / B4 | hard | 全调用面 + 各自义务清单(义务明细在 registry,不在本文) |
|
||
| A1 | 间接 hard | `generate` 换图 + actuals p10 对账输入 |
|
||
| C1/C2 | provisional(未设计) | encounter 上下文由 `begin_battle` 入参封装隔离 |
|
||
|
||
**下游**:D1(明细流水=统一数据源契约,呈现义务台账在 registry)· B5(步骤流=动画回放脚本源)· D4/D5(音频/教学事件源)· C3(对账结论=调参约束)。
|
||
|
||
## 版本历史
|
||
|
||
| 版本 | 日期 | 改动 |
|
||
|---|---|---|
|
||
| lean-sample | 2026-09-13 | 格式重排样例:修订注记出正文→版本表;规则/枚举/边界/边界情况转表格;流程转字符图。语义与 b1-settlement.md Rev 1 对齐,未改任何现行规则 |
|
||
| Rev 1 | 2026-09-10 | design-review 8 项 blocking 核销(完美排雷双份载体、条款⑤计价模型重推、流水协议分层、hit=false 零值行、P_perfect 换算成文等)——明细见 review log |
|
||
| v1 | 2026-09-10 | 一次会话定稿(F0–F5 + 43 条 AC + 23 条上游义务落位) |
|
||
| D4 修订 | 2026-09-12 | 刷新决策前移挖掘期:新增"挖掘期刷新"出口行,作废原 Waiting 期代理调用 |
|
||
| 2026-09-11 拍板批 | 2026-09-11 | 主角先手攻击(hero_attack 来源)、两级奖励、窗口单件制、库存关内延续 |
|