Files
gplan-2/design/gdd/b3-status-effect.md
T
2026-09-14 18:18:49 +08:00

534 lines
73 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.
# B3 增益/状态系统(Status Effect System)
> **状态**:Approved · lean 格式
> **版本**:v1.1-lean · 2026-09-13 · 作者:user + agents(systems-designer〔Formulas〕· qa-lead〔AC〕;三结构决策〔单一计数/按行叠层/四行定稿权收编〕为用户拍板)
> **承载支柱**:P2 主(可归因兑现的机制落点)· P3(敌方增益/debuff 的兑付面)· P1(时限透明的规划素材)· P4(间接)
> **Layer**: 1 Foundation · **Milestone**: MVP · **设计顺序**: 第 4 位
> **一句话**:B3 是战斗域统一状态容器——三向效果同构实例的时限/叠层/衰减机制唯一 owner,兑付接口供 B1 结算逐行消费。
> **复核注记**:lean 门禁下 systems-designer / qa-lead 已委托起草(Formulas / AC);creative-director 与 art-director 未经咨询——生产前人工复核体验锚点情绪定位与视觉数据面规格同 art-bible 的一致性。
## 速览
| 关键问题 | 答案 |
|---|---|
| 定位 | 战斗域统一状态容器:不在当场一次性、而要在若干次结算里持续起作用的战斗效果(安全格增益 / 踩雷敌方增益 / 标中旗削弱 / 清图奖励 buff)作为同构状态实例的唯一存放与生命周期 owner——统一容器让"效果"成为一门单一语言:四源统一当量的对照载体(A3 条款 1)、B1 结算的单一对接面、可回放步骤流的状态侧前提 |
| 拥有 | 机制:时限/叠层/衰减语义、状态实例生命周期(战斗域)· 兑付接口五 API 与 P2 归因字段 · StatusEffectTable 回填 owner · MVP 四行初值定稿权(Rule 10 收编——锚验收权留 B4/B2/B1);机制与内容分离是结构原则——B3 只拥有机制,效果内容的经济归属归各锚 owner |
| 不拥有 | 效果内容经济归属(安全格 buff 与标中旗 debuff 档位锚验收归 B4、敌方增益上限归 B2)· 效果语义到结算公式的映射与兑付作用顺序(B1 SettlementTable)· 呈现(D1/B5)· 教学(D5)· 渲染面与事件外发(零) |
| 上游输入 | D2 StatusEffectTable(hard——数据通道,本 GDD 回填 owner);无其他玩法上游(Foundation 层) |
| 下游输出 | 五 API(B1 结算编排消费)· query_active 投影(D1 HUD 数据源)· 实例六字段 + display_name + 授予时快照(B1 结算明细 / B5 呈现数据源) |
| 硬约束 | 零随机(无 RNG 流消费)· 零 UI 依赖 · 零信号外发(纯被动容器)· 全 API 布尔/计数返回、无 await——可回放步骤流的状态侧前提 |
## 体验锚点
| 支柱 | 关键词 | 机制承诺 |
|---|---|---|
| P2 可归因的兑现感 | "我攒下的东西正在替我打架" | 每个状态实例携带来源标注(安全格/标中旗/清图/雷),结算明细逐行生效——P2 准话测试"这个结果是我哪步扫雷带来的?"在 B3 字段里就有答案;"规划的延迟兑现"从口号变成可见事实的机制落点 |
| P3 雷的两面 | "雷是赌桌不是陷阱" | 踩雷的敌方增益行与标中旗的削弱行在结算明细里使用同一呈现语言,玩家由此学会雷的两面;旗标对的即时回报部分补偿 chord 缺席的兑现节拍缺失(CD 创意风险 #3 的关联缓解,正式高光设计归 B1/B4) |
| P1 规划素材 | "还剩几次结算、何时到期" | 增益携带明确的剩余结算次数与到期时机,玩家才能把它纳入挖哪格的推理——时限语义的透明度是规划感的前提;满层溢出行可见("满层时别再拿同款") |
反向护栏:状态效果绝不能是无感的暗账——玩家说不出一行结算"从哪来",来源标注即失职(违反 P2);任何让 buff 时限/剩余次数不可读的设计默认砍掉。参考感受:杀戮尖塔的增益图标(时机与层数一目了然,是决策素材而非装饰)、Peglin 神器在关键时刻叠加生效的"攒出来的强大"。
## 全局流程
### 效果生命周期(授予 → 存续 → 兑付/衰减 → 出口)
```
B1 结算编排(唯一授予入口 apply_effect——A2/B4 与 B3 零直接接口)
│ 事实来源:A2 开格/标中/开雷事件 → B1 收集 round facts → 转化授予(挖掘期不直接写容器)
▼
授予(编排期入容器,无 pending 态——首个结算就是它的第一次兑付)
│ merge(effect_id) 三分支:independent 新建实例 / stack L+1(L=M 拒绝) / refresh R←D
│ 实例载荷 = 六归因字段 + display_name + 授予时数值快照 (magnitude, unit)
▼
Active(存续——跨轮次、跨扫雷图延续;换图/刷新不清空,旗标记随图消亡不影响实例)
│ 每轮结算:B1 query_active(side) 只读兑付(作用顺序归 B1 SettlementTable)
│ → decay_round() 恰一次:全实例 R−1,R=0 销毁(先兑付后衰减)
▼
出口 ─┬ R=0 → Expired:实例销毁(明细流水已由 B1 记录,B3 不留历史)
├ notify_battle_end → Cleared:全实例销毁、容器回空 → BattleClosed(不跨战斗)
└ 拒绝路径:域闭 / 未知 effect_id / 满层 → false + 容器零写(溢出行归 B1 结算明细)
```
### 出口分发
| 出口 | 触发 | 动作/去向 | 约束 |
|---|---|---|---|
| 受理入容器 | apply_effect 受理(新实例/叠层/刷新) | 即入 Active——无 pending 态,首个结算是第一次兑付 | 域闭 / 未知 id / 满层 → false 拒绝(见边界情况) |
| 到期移除 | decay_round 后 R=0 | 实例销毁 → Expired | 明细流水已由 B1 记录,B3 不留历史 |
| 战斗清空 | notify_battle_end() | 全实例销毁、容器回空 → BattleClosed | 不跨战斗;除本 API 外无任何清空入口 |
| 满层拒绝 | stack 行 L=M 再授予 | 返回 false、容器逐字不变;"溢出未生效"行归 B1 结算明细(含来源) | 拒绝原子性——无半写、无溢出落层 |
## 核心规则
> 每条规则两段:**人话**(作用于哪个系统、什么情况下、谁触发、触发后发生什么;效果与情况用枚举表)→ **举证**(计算方法/公式;纯流程规则明写"无计算")。
#### 规则 1:所有持续效果共用一个容器、一套机制
**人话**:战斗里不在当场一次性生效、要管上几回结算的效果——主角的增益、敌人的增益、敌人受到的削弱、清图奖励——全都作为同一种"状态实例"存进同一个容器,用同一套计时、叠层、衰减的规矩管理,没有哪类效果走特殊通道。容器自身有四条硬规矩:
| 规矩 | 含义 |
|---|---|
| 寿命 = 一场战斗 | 战斗开始时容器为空,战斗结束全部清空——不跨到下一场战斗 |
| 跨轮、跨图延续 | 同一场战斗里跨轮次、跨扫雷图都在;换图/刷新不清空(旗标记随旧图消亡归棋盘系统 A2 管,状态实例不随图走) |
| 全程零随机 | 容器不掷任何骰子:授予、合并、衰减、列举顺序全部确定 |
| 敌方侧共享 | MVP 敌人为 1–3 个同种敌单位(敌情系统 B2 定):对敌状态一律对全体存活敌人生效,层数全体共享一份 |
**举证**:无计算。"不跨战斗"为 game-concept 定稿口径;多敌共享读法按 registry single_enemy_assumption 登记,现接口零变更兼容。
#### 规则 2:状态的寿命按"还剩几次结算"倒数
**人话**:每个状态实例都自带一个倒数计数——剩余结算次数。它不承诺"活几轮",而是数"经历过几次结算":每轮结算先让状态起作用,随后计数减 1,减到 0 状态即被移除。因此一次性的状态(标中旗削弱、踩雷伏击这类,初始计数 = 1)恰好在授予它的那轮结算里生效一次、轮末消失,MVP 四行内容全部是一次性;将来若有跨轮持续的增益,寿命由表行的初始值表达——给几就活几次结算。停手不挖的轮、弃图刷新的轮也照常算一次结算、计数照减——不存在"不结算就不掉次数"的免费延时。
**举证**:计数量纲 = remaining_settlements(剩余结算次数),初始值 = 表行 duration_settlements(一次性 = 1);衰减的精确机制(每轮恰 −1、归 0 即销毁)与"先兑付后衰减"时序契约见「数值结论与推导」F3;时限语义逐要点见下方实现参照表。
### 规则 2 的实现参照——单一结算次数量纲(时限语义)
| 要点 | 内容 |
|---|---|
| 计数量纲 | remaining_settlements(剩余结算次数)——全部状态唯一时限单位 |
| 初始值 | duration_settlements = 授予时初始剩余结算次数(实例持有快照、不受表重载影响——EC9) |
| 衰减 | 每轮结算兑付后统一 −1(先兑付后衰减——B1 兑付完才调 decay_round);归 0 即移除 |
| 一次性 | duration=1 → 授予当轮编排期入容器 → 同轮兑付恰一次 → 轮末移除(MVP 四行全部 D=1——当次结算语义) |
#### 规则 3:状态只在结算时发放,每笔都记着从哪来
**人话**:挖掘期的挖格、插旗、踩雷不会直接改状态容器:棋盘(A2)只上报"发生了什么"的事实,战斗结算编排(B1)在每轮结算时统一把事实兑换成状态、发给容器。这是容器唯一的进货口,棋盘与奖励背包(B4)都没有直通容器的通道。每笔状态随身携带归因信息:哪类来源(安全格奖励/标中旗/踩雷/清图奖励四选一)、从哪个格子来、发生在第几轮——结算明细能逐行回答"这效果是我哪步扫雷带来的"。状态一经发入立即生效(没有"待生效"中间态):同一场结算就是它的第一次兑付。
**举证**:无计算。授予动作 = apply_effect(规则 6 五接口之一);四类来源的授予路径与目标侧逐源对照见下方实现参照表;来源取值封闭枚举见「枚举」节 source_class 表。
### 规则 3 的实现参照——三向效果映射(授予路径)
| 事实来源 | source_class | 授予路径 | 目标侧 | MVP 行 |
|---|---|---|---|---|
| 安全格奖励 | safe_cell | A2 开格事实 → B1 转化 apply_effect | hero | attack_up / defense_up |
| 踩雷 | mine_hit | A2 开雷事实 → B1 转化 apply_effect | enemy(side-wide) | ambush |
| 标中旗 | flag_hit | A2 标中判定 → B1 转化 apply_effect;兑付资格(雷格实例键)判定在 A3/A2 域——资格判定不过 B3,B3 无从重复兑付同雷(每次 flag_hit 授予由 B1 保证资格合法) | enemy(side-wide) | weaken |
| 清图奖励 | clear_reward | B4/B1 清图槽含 buff 时授予(B4 期定稿) | 随行 | B4 差异化插槽(OQ4) |
#### 规则 4:同名状态重复拿到,怎么合并由数据表说了算
**人话**:同一种状态还没消失时又拿到一份怎么办?答案不在代码里,而在数据表每行的"叠层策略"字段,共三种:叠加(层数 +1,寿命不动——只有第一次授予定时钟)、刷新(寿命重新计满、层数不变)、并存(各算各的一份、互不影响)。合并在授予那一刻由容器内部完成;多个状态在结算里按什么先后起作用,是结算编排的职责——两件事互不干扰。叠加的作用是纯加法:几层就是几倍的行值(单一线性换算)。MVP 四行内容全部用叠加;刷新与并存的语义已定义、实现已承载,未来内容行按需启用。
**举证**:三分支的逐分支语义(含满层/溢出行为与 MVP 消费)见下方实现参照表;合并执行的伪代码见「数值结论与推导」F1;"有效值 = 层数 × 行值"的加算合成见 F2。
### 规则 4 的实现参照——按行叠层三分支(stack_policy——授予时合并)
| stack_policy | 重复授予行为 | 满层/溢出 | MVP 消费 |
|---|---|---|---|
| stack | 层数 +1(R 不动——只有初始授予定钟) | L=M → 拒绝 false + 容器零写,"溢出未生效"行归 B1 | 四行全用(attack_up/defense_up M=2、ambush/weaken M=16) |
| refresh | 剩余次数重置为实例授予时快照 D、层数不变(含 R 已 = D 的空刷新——恒返回 true,无满层/溢出语义、不消费 max_stack) | 无 | 语义已定义、实现承载——MVP 无内容行(零消费者) |
| independent | 并存独立实例(append 入列) | 无满层语义——实例数上界 = 受理授予数(有界确定) | 同上 |
#### 规则 5:叠满了再给同款不生效,但会明说"这层浪费了"
**人话**:一种叠加型状态已叠到上限(层数 = 上限值)时,再授予同类不生效:容器拒绝、内容一个字不变。但这份奖励不会被无声吞掉——结算明细会多一行"溢出未生效",连来源一起写明;玩家看得到"这层白拿了",下次就懂得满层时别再拿同款——奖励的浪费是诚实的、可规划的。无论这份重复来自玩家直接踩出的格子、结算转化、还是连锁展开自动开出的奖励格,都走同一个授予入口,满层时同样产生溢出行、同样留痕。
**举证**:无计算(判定 = 一次"层数 == 上限"比较)。拒绝原子性(false + 容器逐字不变、无半写无溢出落层)见 F1 推导极端行为段;"溢出未生效"行进结算明细协议由 B1 义务⑧承载、呈现归 B5/D1。
#### 规则 6:结算系统只用五个固定接口读写容器
**人话**:状态容器是纯被动的仓库,自己不主动做任何事;战斗结算编排(B1)要用它,只有五个固定接口:
| 接口 | 干什么 | 返回 |
|---|---|---|
| 告知战斗开始 | 打开容器、进入可用状态 | 是/否 |
| 发一笔状态 | 唯一进货口:受理即新建实例/叠层/刷新 | 是/否 |
| 查询生效状态 | 某一方当前生效清单,按发放先后排列且顺序永远稳定 | 只读清单 |
| 轮末衰减 | 全部实例寿命 −1、归 0 即销毁 | 本轮移除数 |
| 告知战斗结束 | 全实例清空、容器回空 | 是/否 |
**举证**:五接口 = notify_battle_start() / apply_effect(effect_id, source) → bool / query_active(side) → Array / decay_round() → int / notify_battle_end() → bool(签名见「验收标准」测试口径)。
- 查询返回 = 六归因字段 + display_name + 授予时数值快照 (magnitude, unit) 的只读投影(qa-lead 载荷口径)。
- 结算作用顺序(哪个效果先乘)归 B1 SettlementTable,B3 只保证枚举确定性;最后一轮(敌人全灭)是否 decay 归 B1 判定次序域——A3 EC8 同款〔末轮 decay 判定次序域〕。
- 全部 API 布尔/计数返回、无 await、无表现面——可回放步骤流的状态侧前提。
#### 规则 7:容器只管"有多少量、还剩几次",不管这量怎么用
**人话**:容器记录每个状态的量(幅度数值 + 量纲标签:百分比还是固定值)和它还剩几次结算,仅此而已。"增伤到底加在哪个算式上、先乘后乘、地板怎么收"这类"效果如何兑现"的问题,一律由结算编排的顺序映射表按状态 id 作答。一句话:容器知道"现在还有 +50、还剩 1 次结算",但不知道这 +50 会变成主角攻击里的什么。
**举证**:无计算。语义映射的承载面 = B1 SettlementTable(effect_id 为键);B3 只承载 magnitude/unit 两个通用数值字段。
#### 规则 8:已生效的状态玩家动不了——不能驱、不能延、不能转
**人话**:状态一旦生效,玩家没有任何手段把它摘掉、往后延、或挪给别人——容器没有提供这类接口。"不能做"和"能做"同样是明确的设计决定:省掉一整类界面与规则复杂度。将来若要加驱散/延时/转移,属于新增接口的修订,不是调参数。
**举证**:无计算。负空间规则——验收形态 = API 面封闭枚举 + 接口漂移修订门(见「验收标准」节测试口径 out-of-scope 行)。
#### 规则 9:所有数值写在数据表里,代码零写死
**人话**:容器本身不认识任何具体数值:哪个状态加多少、活几次、最多叠几层,全部写在状态表里(表结构由本文档定义、数据层 D2 承载),程序运行时统一从配置库 ConfigDB 读表。代码里不出现任何玩法数值字面量——调平衡只改表、不改代码。
**举证**:无计算。表 = StatusEffectTable(本 GDD 为回填 owner,schema 逐字段见「Tuning Knobs」节);依据 = D2 Rule 1〔数值字面量禁令〕。
#### 规则 10:四个 MVP 状态的初值由本文档定稿,验收权留在对口系统
**人话**:MVP 上线的四行内容(增伤、减伤、伏击、削弱)的初始数值由本文档定稿,值域快照见「枚举」节内容行表。但"值合不合适"的验收权留在对口系统(奖励经济 B4、敌情 B2、结算 B1):削弱档位按"必须严过最低档增益"的当量锚验收、伏击按敌方惩罚上限验收、对账由结算闭合。要改初值,走接口漂移规则回写登记库(registry),不是随手调参——初值定稿权归本文档、锚验收权仍归上述三方,这是对"档位归奖励表设计"的显式收编。
**举证**:无计算(定稿权条款非公式)。依据 = A3 F1 条款 2〔debuff 严格 > 最低档 buff 当量,参照对象 = attack_up 行当量〕· 条款 3〔B2 惩罚上限〕· A3 OQ5 收编〔registry ownership_note〕;A3 GDD 正文不改,以本条 + registry ownership_note 为准。
## 枚举
### source_class(封闭枚举——P2 归因字段)
| 值 | 产出点 | 语义 |
|---|---|---|
| safe_cell | 安全格奖励授予 | 主角增益来源 |
| flag_hit | 标中旗授予 | 怪物削弱来源 |
| mine_hit | 踩雷授予 | 敌方增益来源 |
| clear_reward | 清图奖励授予 | 清图槽 buff 来源(B4 期定稿) |
新增值 = 接口漂移。B3 不校验 source_class 与行的对应(dumb 账本——EC6 同族);内容行表"来源"列为内容档案(provenance),非 schema 字段、非运行时约束。
### target_side / unit / stack_policy(schema 枚举域)
| 字段 | 值域 | 语义 |
|---|---|---|
| target_side | hero / enemy | 作用侧;enemy 侧 side-wide = 全体存活敌单位(层数 = side 共享池) |
| unit | percent / flat | percent = 百分比修正(百分点线性叠加);flat = 固定值(伏击类——量纲已定稿:每层伏击为每次攻击类行为附加 m_amb 点主角 HP 伤害、后置加法不进倍乘、charge 拍零兑付,B2 GDD 定稿) |
| stack_policy | stack / refresh / independent | 同 id 重复授予的合并策略(见核心规则子表) |
### StatusEffectTable MVP 内容行(四行值域快照——值全部 provisional,验收锚见 Rule 10)
| effect_id | 名称 | side | magnitude(现行值) | duration | stack/max | 来源 | provisional 依据 |
|---|---|---|---|---|---|---|---|
| attack_up | 增伤 | hero | +50 percent | 1(当次结算) | stack / 2 | safe_cell | 原型临时值 1.5× 换算(D2 knobs 占位);消费面 = 主角战斗段先手攻击(HeroTable.atk 基础攻击恒存在) |
| defense_up | 减伤 | hero | −30 percent | 1(当次结算) | stack / 2 | safe_cell | 减伤墙批 C3 投值(−50→−30,叠满两层 −60 帽——defense_scan 墙轮 39%/真人 12 轮零承伤定量坐实后回调) |
| ambush | 伏击(敌方增益) | enemy | +3 flat | 1 | stack / 16 | mine_hit | 原型临时值 +3;量纲已定稿(B2 GDD——registry ambush_unit_definition);条款 3 锚验收归 B2/B1 |
| weaken | 削弱(标中旗 debuff) | enemy | −65 percent(值域 [60, 85]) | 1 | stack / 16 | flag_hit | F0 裁决值——回执以 B1 GDD F0 为准(registry anchor_warning);须过条款 2 锚(严格 > 最低档 buff 当量,B1 对照验收) |
## 数值结论与推导
> 章节纪律:结论先行(加粗一行),下接「推导」小标题给公式代码块、Variables 表与验算/示例。systems-designer 代理起草(lean 门禁):只含机制公式,平衡归属见显式排除声明。
### F0 weaken 锚裁决回执(m_w 值域与归一口径)
**结论**:m_w 值域 [60, 85]、默认 −65;归一口径 = 每结算瞬时当量(每 AP 总暴露分支被 percent schema 域禁止,排除);地板交叉层数 = ⌈100/m_w⌉ = 2(值域内恒 2);B3 接口零修订、值变更走 registry 回写——**回执以 B1 GDD F0 为准**(registry status_effect.anchor_warning F0 裁决回执)。
#### 推导
| 分支 | schema 可行性 | 后果 | 裁决 |
|---|---|---|---|
| 每结算瞬时当量 | 可行(m_w ≥ 51 即过锚——percent 域内) | F2 越域界随移(AP 界 8×m_w / 表界 16×m_w);地板交叉层数 = ⌈100/m_w⌉ = 2;上调的连带成本(地板提前到达、边际层贬值)入裁决 | 采纳 |
| 每 AP 总暴露 | 不可行——需 m_w > 100,被 percent ∈ [−100, 100] schema 域禁止 | 现实解 = B4 重定最低档参照(非上调)——未采纳 | 排除 |
- 同分母性:瞬时口径下 weaken 与 hero 侧 buff 作用于同一伤害流,"严格大于"在百分点读法与 HP 读法下等价,锚判定无量纲歧义;总暴露口径引入时长权重,把 duration knob 泄漏进锚判定。
- 机制同构:B3 本就按结算逐次兑付,瞬时口径是容器原生口径;总暴露需跨结算累计账本,与已锁的"单结算自然边界"(dur=1 每结算清零无存量)冲突。
- 值域依据(@D_ref=12):下界 60 = 条款 2 两腿可行交集(腿一 m_w ≥ 51——65 > 50 严格大于 attack_up 当量〔参照对象,registry 回迁口径〕;腿二随 E_dig 口径修正放宽——m_w ≥ 38,以 B1 GDD F0 重算回执为准);上界 85 = 超出仅在连锁贫瘠板增加裕度、地板交叉层数恒 2;schema 顶 100 保留为绝对上界。
- 红警关闭:原 −25 值在两个独立线性代理下同向预检不过(条款 2 锚差约 4×,且"单一线性换算"堵死分源改率、"无单档上限"堵死 max_stack 豁免)——F0 修订后锚两腿通过(瞬时当量 7.8 > 6.0 严格大于 ✓ / 7.8 ≥ E_dig 4.5 ✓——E_dig 读数随重算批口径更新);终值共裁与 registry 终值确认联动 B1 OQ2(见开放问题 #1)。
### F1 同 id 叠层合并(same_id_merge,授予时执行)
**结论**:授予时按行 stack_policy 三分支合并——stack 加层不触碰 R(只有初始授予定钟)、refresh 重置 R 取实例授予时快照 D、independent 并存新实例;满层拒绝原子(false + 容器逐字不变)。
#### 推导
```
merge(effect_id) —— 前置拒绝(域闭 / 未知 effect_id)沿用 States 节 API 口径,不入分支。
行 = StatusEffectTable[effect_id],按 行.stack_policy 三分支:
independent → 恒新建实例 {L=1, R=D},append 入列(同 id 并存多实例)
stack → 无存活实例 :新建 {L=1, R=D}
有存活实例 ∧ L < M :L ← L+1(R 不动,见注)
有存活实例 ∧ L = M :返回 false(满层拒绝;容器零写入,溢出行归 B1 结算明细)
refresh → 无存活实例 :新建 {L=1, R=D}
有存活实例 :R ← D(L 不变;含 R 已 = D 的空刷新,恒返回 true——
refresh 无满层/溢出语义,不消费 max_stack)
```
注(spec 决议):stack 授予不触碰 R——duration_settlements 只有初始授予定钟;若 stack 也重置 R,则 stack ≡ refresh + 加层,三分支失去区分性。refresh 的重置目标 D 取实例持有的授予时快照(与 EC9 快照语义一致——实例不受表重载影响)。
**Variables:**
| 变量 | 符号 | 类型 | 范围 | 说明 |
|---|---|---|---|---|
| effect_id | e | String | 表主键 | StatusEffectTable 行键;未知 = 拒绝 |
| stack_policy | P | enum {stack, refresh, independent} | 表列 | 合并分支选择器(Rule 4) |
| max_stack | M | int [1, 16] | 表列 | 仅 stack 分支消费;refresh/independent 不读(未来 refresh 行配 M>1 时行为 = 忽略) |
| duration_settlements | D | int [1, 99] | 表列 | 新建实例初始 R;refresh 的重置目标即此值 |
| layers | L | int | stack 行 [1, M];其余恒 1 | 实例层数(越界 = debug 断言,States 节不变式) |
| remaining | R | int | 存活态 [1, D] | 剩余结算次数;归 0 移除(F3) |
- **Output Range:** 正常域——stack/refresh 行同 id 存活实例数 ≤ 1(不变式);independent 行实例数 = 受理授予数(有界确定);返回值 bool。极端行为——满层授予恒 false 且容器逐字不变(拒绝原子性:无半写、无溢出落层);同轮批量授予的先到先得次序由调用方保证(B1 编排须按确定次序调用 apply_effect——B3 只保证插入序枚举稳定,B1 验收项义务①)。
- **Example:** attack_up(stack,D_a=1、M=2):轮 3 同轮授予批次两个安全格事实 → apply_effect×2 → L=2、R=1;同轮第 3 个授予 → L=2=M → **false**(明细"溢出未生效"行);兑付 +100%(F2)→ 轮末 decay R=0 移除。weaken(stack,D_w=1、M=16):轮 3 三旗命中三雷(雷格实例键,三次授予均合法)→ L=3、R=1;兑付 3×m_w(默认 65 → −195%)→ decay 移除;轮 4 一旗命中新雷 → 旧实例已销毁,**新建** {L=1, R=1}——dur=1 行的层只在单轮授予批次内累积,跨轮必为新实例。dur ≥ 2 行(策略探针 D_f=3):跨轮 R 逐轮 −1,refresh 腿见 AC-5。
### F2 有效值合成(effective_value_composition,兑付时只读)
**结论**:有效值 = L × m 加算(unit 量纲标签原样随值输出、不进乘法);合成值不 clamp、可越出 percent 域——地板/clamp 归 B1 SettlementTable。
#### 推导
```
effective_value(实例) = L × m (unit 随行声明,量纲标签原样随值输出、不进乘法)
stack 行:L ∈ [1, M];refresh / independent 行:L ≡ 1(每实例恒一倍)
加算语义:percent 行的 L×m 是百分点线性叠加(+50 × 2 层 = +100 个百分点);
乘算读法(1.5^L)在 B3 语义域外。
表注:行值出处(provenance,如"原型 1.5×")是数值来历标注,非合成语义。
```
**Variables:**
| 变量 | 符号 | 类型 | 范围 | 说明 |
|---|---|---|---|---|
| layers | L | int | 同 F1 | 叠层数 |
| magnitude | m | int | percent ∈ [-100,100] ∧ ≠0;flat ≥ 1(单行字段域,D2 校验) | 行值;合成值不继承此域(见 Output Range) |
| unit | u | enum {percent, flat} | 表列 | 量纲标签;percent = 百分比修正、flat = 固定值;消费语义(乘除侧、地板、单位定义)不在 B3(见排除声明) |
- **Output Range:** 正常域——percent 行有效值 ∈ [1, 100×M],**可越出 [-100, 100],B3 不 clamp**(合成值地板/clamp 归 B1 SettlementTable——B1 验收项义务③);flat 行 effective ≥ 1。极端行为——weaken 合成下界两档并列:**AP 界 = 8×m_w**(默认 65 → −520%;默认经济下 flag_hit 单轮 ≤ ap_per_round=8 次授予、dur=1 层只在单轮累积 → L=8)与**表界 = 16×m_w**(默认 65 → −1040%;仅非 AP 源如 clear_reward 授予、或 ap_per_round 调参后可达 L=16)——两档均越域,均不在本系统内收口;m_w 值域见 F0。跨 effect_id 聚合、percent 与 flat 混算 = B1 SettlementTable 域(Rule 7)。
- **Example:** attack_up L=2 → +100 percent(兑换成 2.0× 与否的读法归 B1);defense_up L=2 → −60 percent(B1 换算 0.4×——现行值链下不触地板,"归零"读法须 B1 定义);weaken L=8 → 8×m_w(默认 −520 percent);ambush L=3 → **+9 flat**(3×m_amb——B3 不解释单位)。
### F3 结算衰减(settlement_decay,轮末执行)
**结论**:先兑付后衰减——每实例每轮恰 −1、归 0 即销毁(不留 0 值实例)、返回本轮移除数 k;无参数、无豁免实例。
#### 推导
```
decay_round() -> k:
k ← 0
for 实例 ∈ 容器(插入序枚举,零随机):
R ← R − 1
if R = 0:销毁实例;k ← k + 1
return k
```
时序契约:**先兑付后衰减**——B1 经 query_active(side) 完成本轮兑付后才调用;duration=1 实例的落点由此完整确定 = 授予当轮编排期入容器 → 同轮兑付恰一次 → 轮末 R=0 移除("一次性"语义的全部机制内容)。停手轮/弃图轮同为结算、照常衰减(Rule 2,无免费延时);最后一轮(敌人全灭)是否 decay 归 B1 判定次序域(Rule 6,A3 EC8 同款——battle_end 全清兜底,两种次序产生同终态)。
**Variables:**
| 变量 | 符号 | 类型 | 范围 | 说明 |
|---|---|---|---|---|
| 容器 | — | 实例多重集 | 存活实例全体 | 枚举序 = 插入序(Rule 1 确定性) |
| remaining | R | int | 存活态 [1, D];decay 后 ∈ [0, D−1] | 单调递减;refresh 的 R←D 发生在授予时(F1),不在本式内——两序分离 |
| 返回值 | k | int | [0, 容器规模] | 本轮移除数 |
- **Output Range:** 正常域——每实例每轮恰 −1,无参数、无豁免实例;k ≤ 调用前容器规模。极端行为——空容器 → k=0;全 dur=1 轮 → k=容器规模(全清);R 恒不因 decay 变负(归 0 即销毁,不留 0 值实例——与不变式 remaining ∈ [0, D] 相容)。
- **Example:** 轮 3:编排期授予 attack_up(L=1、R=D_a=1)→ 兑付 +50% → decay_round()=1(移除);轮 4 query_active(hero) 已不含 attack_up。dur ≥ 2 行(策略探针 D_f=3):授予后逐轮兑付、R 逐轮 −1、第 3 轮末移除——R 轨迹与 k 全由表读值推导。
### 显式排除声明(R4 式)
本 GDD **无平衡公式**——F1–F3 只承载机制数学(合并/合成/衰减),不含任何"值该多大"的判断;四行 MVP 值全部 provisional(Rule 10)。平衡与语义归属逐一列明:
| 对象 | 归属 | 依据 |
|---|---|---|
| 效果档位当量对照表(四源统一当量、单一线性换算) | **B1**(出表方兼闭合对账单一签字人) | A3 F1 条款 1 |
| weaken 档位锚(debuff 当量严格 > 最低档安全格 buff 当量,参照对象 = attack_up 行当量;基准 = 连锁放大边际挖掘收益,provisional 1:1) | **B4 表设计 + B1 对照验收** | A3 F1 条款 2 |
| 挖掘风险不等式(P(安全)×buff 当量下界 > P(雷)×敌方增益当量上界;B2 惩罚上限表值) | **B2 供给上限表值,B1 单一闭合对账** | A3 F1 条款 3 |
| 奖励定价(清图奖励及 B4 三硬约束:雾内档位下界 / 锚随雾成本上浮 / 净当量优势带上界) | **B4** | A4 pricing_constraints;A3 F1 条款 4/5 |
| percent 的消费侧换算与地板(乘除侧读法、合成值越域 clamp);flat 的量纲定义 | percent → **B1 SettlementTable**(Rule 7);flat 量纲 → **B2**(已定稿——registry ambush_unit_definition:每层伏击为每次攻击类行为附加 3 点主角 HP 伤害、后置加法) | Rule 7 + F2 Output Range;Schema 说明列 |
| MVP 四行初值定稿权 | **B3**(Rule 10);B4/B2/B1 持锚验收权,修订走接口漂移回写 registry | Rule 10 |
B3 只对"L×m 线性合成 + R 计数"负责:合成值多大算强、多弱算废、floor 在哪、+3 打谁——均不在本 GDD 语义域。
## 状态
容器为**纯逻辑类**(非 autoload、无场景依附),每场战斗实例化一次(B1 编排前提;冒烟经 class_name 直引构造)。容器无运行时大状态机——实例生命周期四态(战斗域):
| 状态 | 进入条件 | 行为/出口 |
|---|---|---|
| BattleClosed(域闭) | 构造后未开域 / notify_battle_end() 后 | apply_effect 全拒绝(false);唯一出口 notify_battle_start() |
| Active(存续) | apply_effect 受理(新实例/叠层/刷新) | 每轮结算被 B1 兑付消费;decay_round() 后 remaining −1 |
| Expired(移除) | remaining_settlements = 0 | 实例销毁(明细流水已由 B1 记录,B3 不留历史) |
| Cleared(清空) | notify_battle_end() | 全实例销毁、容器回空 → BattleClosed(不跨战斗) |
不变式(debug 断言口径):remaining ∈ [0, duration_settlements];stack 行 layers ∈ [1, max_stack];stack/refresh 策略下同 id 至多一个实例——违反即 debug 断言中止;API 违规(域闭授予、未知 effect_id、满层授予)= 拒绝(false)+ debug 诊断,不进程致命(承 A3 拒绝口径;进程致命保留给 D2 数据通道)。
## 边界情况
| 条件 | 行为 | 依据 |
|---|---|---|
| EC1 域闭状态授予(BattleClosed 下 apply_effect) | 拒绝(false)、容器不变 + debug 诊断——B1 过早/过晚调用 = 编排错误显式暴露,不静默吞 | States 节 API 口径 |
| EC2 未知 effect_id | 拒绝(false)+ debug 诊断;表行删除/改名后旧引用的暴露点——悬空引用加载校验 = 首引激活条款:B4 RewardTable 首个 effect_id 引用已回填、校验已激活(registry dangling_ref_policy;条件性夹具 = B4 b4_dangling_effect) | A4 counter_item_ids 同款 · D2 首引兑现 |
| EC3 满层授予 | 恒 false 且容器逐字不变(拒绝原子性——无半写、无溢出落层);"溢出未生效"行归 B1 结算明细;同轮多授予谁被拒取决于 B1 授予次序——授予次序确定性是 B1 编排义务 | F1 Output Range · Rule 5 · 义务① |
| EC4 空刷新(refresh 行 R 已 = D 再授予) | 返回 true、无任何变化——合法空操作(refresh 无满层/溢出语义);MVP 无 refresh 内容行 = 该语义零消费者,首个 refresh 行上线时须补冒烟 AC;空刷新静默返 true 与 Rule 5"不静默蒸发"存在原则张力(stack 有溢出行、refresh 无对应物)——MVP 零消费者故休眠,首个 refresh 内容行上线时其授予可见性语义由 B4/B1 随 OQ3 一并裁决 | F1 决议 · systems-index 登记 |
| EC5 同轮 dur=1 行多次授予 | 层在单轮授予批次内累积(L=N)→ 同轮兑付一次(合成 L×m)→ 轮末全移除;跨轮必为新实例——"N 旗 = N debuff 总吞吐"在 B3 侧的呈现 = 单轮层和,对账归 B1 | F1 Example · A3 条款 2 |
| EC6 同一事实被重复授予(同 effect_id + origin_cell + round_index 两次 apply) | B3 不去重——容器是 dumb 账本,无从辨别事实合法性,两次授予 = 两层/两实例;事实→授予的恰一次转化归 B1 编排义务(round_end 双发射源同族问题,A3 先例) | 义务② |
| EC7 合成值越域(L×m 越出 [-100, 100] 或穿越地板) | B3 不 clamp、值 + unit 标签原样输出——收口归 B1 SettlementTable(B1 验收项:percent→乘数换算方向与地板规则须成文——weaken AP 界/表界、defense_up 叠满三例已在 F2 登记) | F2 Output Range · 义务③ |
| EC8 清图换图/弃图刷新 | 容器不清空——状态跨图延续(战斗域非图域);旗标记随图消亡(A2 域)不影响已授予实例;已消费兑付资格的雷格随图消亡(A3 域),新图新雷自然新资格——B3 无从感知也无须感知 | Rule 1 · AC-10 |
| EC9 战斗中热重载 StatusEffectTable | 走 D2 既有门(战斗中 reload 拒绝);已授予实例不受任何表重载影响——实例在授予时从表行拷贝数值快照(m/D/unit),热重载只影响后续授予 | A4 EC8"快照非活引用"同款 |
| EC10 refresh/independent 行配置 max_stack > 1 | 行为 = 忽略(F1 分支不读 M)——内容约定非校验项,validate() 不拒绝(防过度约束锁死未来内容) | F1 · AC-13 |
| EC11 notify_battle_start / notify_battle_end 重复或错序 | Active 下再 start → false + 诊断;BattleClosed 下再 end → false + 诊断(bool 口径统一,承 A3 输入×相位矩阵同款) | A3 同款 |
| EC12 query_active 空 side 或空容器 | 返回空 Array——合法状态非错误;D1 HUD 据此渲染"无状态" | D1 空态义务 |
| EC13 decay_round 在域闭时被调用 | 返回 0——域闭时容器恒空(battle_end 已清),0 是自然结果、无独立分支、不诊断(幂等安全的兜底读法) | F3 极端域 |
| EC14 independent 行被高频授予 | 实例数上界 = 受理授予数(有界、确定,无满层语义)——MVP 无此内容行;未来 DOT 类高频授予的容量语义归扩展(接口漂移),本 GDD 不预写 | F1 Output Range |
## 依赖
**上游**(Foundation 层,无其他玩法上游):
| 系统 | 性质 | 接口要点 |
|---|---|---|
| D2 | hard(数据通道) | StatusEffectTable schema 承载 + ConfigDB 读取;本 GDD 为该表回填 owner(schema + 四行已定稿);新字段走接口漂移规则。systems-index 分层表按其惯例不列纯数据读取边(事实依赖同口径)——两处相容非矛盾 |
**下游**:
| 依赖方 | 性质 | 接口要点 |
|---|---|---|
| B1 | hard | 结算编排期调用五 API:notify_battle_start / apply_effect(三源授予——B1 从 A2/A3 事件收集 round facts 后转化)/ query_active(side) 兑付消费 / decay_round() 轮末衰减 / notify_battle_end() 清空;结算明细来源标注数据源 = 实例字段(P2);效果语义映射与结算作用顺序归 B1 SettlementTable(effect_id 键);F1 条款 1 对照表的"实物"供给方;最后一轮 decay 与否归 B1 判定次序域;义务清单 8 项见下表 |
| B4 | soft | 安全格 buff 行值与 weaken 档位的锚验收权(条款 2 + A4 三定价硬约束引用"最低档安全格 buff 当量"——参照对象 = attack_up 行当量);清图奖励若含 buff 经 apply_effect(source=clear_reward,B4 期定);RewardTable 引用 effect_id 的悬空校验已随首引激活(EC2) |
| B2 | soft | ambush 行量纲/上限验收锚(条款 3:B2 惩罚上限表 vs B3 行值,对账归 B1 闭合;量纲已定稿——registry ambush_unit_definition);未来敌人词条引用状态(免疫/抗性)为预留注记,不预写 |
| A3 | 契约相邻(零运行时接口) | A3 不调用 B3;条款 1 四源当量对照以 B3 实例为对照实物;标中旗兑付资格(雷格实例键)判定在 A3/A2 域,B3 只接收 B1 转化的授予——资格判定不过 B3 |
| A2 | 间接(零直接接口) | 开格/标中/开雷事实经事件 → B1 收集 → apply_effect;A2 不感知状态容器 |
| D1 | soft | query_active(hero) 为 HUD 状态栏数据源(display_name/层数/剩余结算次数常显;EC12 空态渲染);层数/到期变化反馈——义务清单 ×4 见下表 |
| B5 | soft | 结算明细/战斗动画的实例字段数据源(经 B1 结算流水;MVP 明细行即呈现,动画归垂直切片)——义务 ×2 见下表 |
| D5 | soft | 教学口径:按结算次数计时("还剩 N 次结算"式读法随行值)、战斗结束全清(防"我的 buff 哪去了"误读——A3 RAP 清零教学同款)、满层溢出浪费提示、"同轮拿满优于跨轮叠"教学项(stack 时序补偿——OQ7 证伪项配套,证伪成立前以中性提示形态) |
### B1 侧义务清单(登记 B1 GDD 验收项,缺项即 blocking——A4 对 A1/A2 登记先例)
| 编号 | 内容 | 对侧 | 状态 |
|---|---|---|---|
| ① | 同轮多授予按确定次序调用(EC3) | B1 | 已落位 B1 GDD(履行回执) |
| ② | 事实→授予恰一次转化(EC6) | B1 | 已落位 B1 GDD(履行回执) |
| ③ | percent→乘数换算方向与合成值地板成文(EC7/F2——AP/表界数值随 F0 修订更新为 −520%/−1040%) | B1 | 已落位 B1 GDD(履行回执) |
| ④ | 最后一轮 decay 判定(F3) | B1 | 已落位 B1 GDD(履行回执) |
| ⑤ | F1 条款 1 效果档位对照表以 B3 实例为对照实物 | B1 | 已落位 B1 GDD(履行回执) |
| ⑥ | 每结算编排恰一次 decay_round()——decay 基数 = 1 是 dur=1 一次性语义与全部衰减语义的先决条件;Active 相位 double-decay 在 B3 侧无守卫(信任 B1 编排,误编排经本义务验收与可回放步骤流暴露) | B1 | 已落位 B1 GDD(履行回执) |
| ⑦ | 结算明细按授予流水逐条标注来源(F1 合并坍缩归因的兑付面补偿——合并实例只持首授 origin_cell/round_index,per-layer 来源还原的数据源 = B1 授予流水) | B1 | 已落位 B1 GDD(履行回执) |
| ⑧ | "溢出未生效"行进结算明细协议(Rule 5 后半的 B1 侧承载;呈现归 B5/D1) | B1 | 已落位 B1 GDD(履行回执) |
### 呈现与教学义务清单(已登记 systems-index,缺项即 blocking,随各 GDD 门禁评审核对)
| 编号 | 内容 | 对侧 | 状态 |
|---|---|---|---|
| D1-① | HUD 常显 + EC12 空态规格定稿(隐藏栏 vs 空槽由 D1 裁决但须成文) | D1 | 已登记 |
| D1-② | effect_id→icon 映射键契约(art-bible 形状+色相双通道) | D1 | 已登记 |
| D1-③ | 有利/有害极性呈现映射(数据源 = B1 SettlementTable 效果语义,非 magnitude 符号——负值增益存在) | D1 | 已登记 |
| D1-④ | 战斗结束全清的状态栏去留 | D1 | 已登记 |
| B5-① | 溢出行呈现(数据源 = B1 义务⑧明细协议) | B5 | 已登记 |
| B5-② | origin_cell→玩家可读形态(缩略图/格子高亮映射——坐标值本身不直接呈现) | B5 | 已登记 |
| D5 | "同轮拿满优于跨轮叠"教学项(OQ7 证伪项配套) | D5 | 已登记 |
| B4 | 奖励身份预读(stack 时序规划的推理原料——创意风险 #1 切面,OQ7 配套补偿载体) | B4 | 已登记 |
### 一致性核对与注记
| 项 | 内容 |
|---|---|
| 双向一致性 | B4 ← A2, B3, D2 ✓ · B1 ← A3, B2, B3, B4, D2 ✓ · B3 ∈ Foundation、无上游 ✓(systems-index 依赖分层表) |
| B2 无边说明 | 索引无 B2←B3 边与上表 B2 行不矛盾——敌方状态的承载在 B3,但授予路径经 B1,B2 与 B3 之间是验收锚关系非运行时依赖,故不列边 |
| D2 hard 措辞 | "hard"指 ConfigDB 读表的数据通道事实依赖(registry config_db referenced_by=[all-systems] 同口径);索引分层表不列纯数据读取边——相容非矛盾 |
| Rule 10 回写 | 对 A3 OQ5"档位归 B4 表设计"的收编(初值定稿权归 B3、锚验收权留 B4/B1)已回写 systems-index 门禁记录与 registry ownership_note |
### 呈现与 UI 契约(数据面义务——B3 无自有渲染面,呈现归 D1/B5)
| # | 数据面义务 | 归属 |
|---|---|---|
| 1 | HUD 状态栏数据源三要素:图标(effect_id→icon 映射归 D1/art-bible)、层数(L)、剩余结算次数(R)必须可读——时限/剩余次数不可读 = 违反 P1 规划素材与 P2 兑现可见性 | D1 |
| 2 | 结算明细行数据源:display_name + 有效值(L×m)+ unit 标签 + 来源标注(source_class→文案映射归 B1/D1,P2 归因)——"增伤 +100%(第 3 轮 · 安全格)"式逐行读法;origin_cell 玩家可读形态(缩略图/格子高亮)归 B5(坐标值本身不直接呈现);满层溢出提示 = "溢出未生效"行含来源(Rule 5 诚实语义) | B1/D1/B5 |
| 3 | 视觉身份锚适用(game-concept):数值可读性优先于氛围(锚 1)——状态数值在暗色底上须高对比;增益/削弱图标不得只靠色相区分(锚 2 形状+颜色双通道);有利/有害极性不得由 magnitude 符号推导(负值增益存在——数据源 = B1 SettlementTable 效果语义) | D1 |
| 4 | 零信号外发:纯被动容器不发任何事件——呈现刷新点 = B1 结算编排完成后的界面刷新(D1/B5 域);到期/层数变化反馈经 decay 前后查询差分或 B1 流水(D1 裁决);无音频需求(到期/叠加音效归 D4 Alpha 期) | D1/B5/D4 |
## Tuning Knobs
### StatusEffectTable schema(D2 承载,B3 回填 owner——Rule 4 豁免:定义表非进度成长表,无 (level_index, node_depth) 维度;未来随关卡成长的效果走接口漂移加列,A4 先例)
| 字段 | 类型/范围 | 说明 |
|---|---|---|
| effect_id | String(主键唯一) | 状态标识;B1 SettlementTable 语义映射的键 |
| display_name | String | 图例/HUD/明细用名(本地化归 D6) |
| target_side | enum {hero, enemy} | 作用侧(enemy 侧 side-wide = 全体存活敌单位) |
| magnitude | int | 域随 unit:percent ∈ [-100, 100] 且 ≠0 / flat ≥ 1(跨字段校验) |
| unit | enum {percent, flat} | percent = 百分比修正;flat = 固定值(伏击类) |
| duration_settlements | int [1, 99] | 授予时初始剩余结算次数(一次性 = 1) |
| stack_policy | enum {stack, refresh, independent} | 同 id 重复授予的合并策略(Rule 4) |
| max_stack | int [1, 16] | 层数上限;仅 stack 消费——refresh/independent 行约定恒 1(内容约定,非校验项) |
加载校验(表非空——D2 Rule 6,四行即满足):effect_id 唯一(重复键致命——本表唯一致命夹具 dup_key);枚举域校验(target_side/unit/stack_policy 出域致命);duration/max_stack 域校验;跨字段 percent ≠ 0 / flat ≥ 1。
**F0 裁决回执注记(m_w)**:weaken.magnitude 现行值域 [60, 85]、默认 −65——**回执以 B1 GDD F0 为准**(registry status_effect.anchor_warning);F2 越域界随移 AP 界 −520% / 表界 −1040%;AC-14 腿 3 非平凡性复查通过(16×65 = 1040 越出 percent 域)。原 −25 值的裁决关系与修订轨迹见版本历史。
### Knob 表
| Knob(表行值,D2 承载) | 默认 | 调过高 | 调过低 |
|---|---|---|---|
| attack_up.magnitude | +50 | 叠满 +100%,敌方 HP 池相对贬值(战斗时长曲线压向 B1 对账) | 安全格奖励空心化——A3 条款 3 左臂(P(安全)×buff)塌方 |
| defense_up.magnitude | −30 | 叠满 −60%(免伤轮不再由 defense_up 单侧可达——B1 地板规则压力同步解除) | 减伤无感,防御型奖励萎缩(回调下界 = 减伤墙复发——观测锚 = C3 承伤带复验与 B1 条款③重跑) |
| weaken.magnitude | −65(值域 [60, 85]) | 越域界加深(表界 16×m_w)、地板交叉层数 ⌈100/m_w⌉ 恒 2、边际层贬值 | 值域下界 60 = 条款 2 锚两腿可行交集——越界即破锚(修订方向 B4/B1 裁决) |
| ambush.magnitude | +3 flat | 量纲已定稿(每攻击类行为 +3 HP)——踩雷痛感随值放大,条款 3 上限对账归 B1 | 踩雷无痛感——P3"风险与收益同源"失衡 |
| duration_settlements(四行) | 1/1/1/1(当次结算) | 窗口拉长恢复跨轮延续(规划变简单、衰减感消失) | 已在下界 1(一次性语义——再低无定义) |
| max_stack(四行) | 2/2/16/16 | 合成越域幅度增大(B1 地板压力↑) | 叠层机制边缘化(重复奖励变溢出浪费) |
- **非 knob(结构冻结)**:stack_policy 三分支语义、unit 语义、source_class 枚举、时限量纲 = 剩余结算次数(game-concept 定稿)、先兑付后衰减时序、拒绝原子性、零随机——修订走本 GDD 流程非调参。
- **Knob 交互**:attack_up 与 weaken 是条款 2/3 对账的**两端**——禁止独立调参,联动评估归 B1 闭合对账;A3 的 ap_per_round 是 weaken 单轮层和的经济上限(F2 AP 界 8×m_w 的来源);效果档位当量对照表(B1)落定前,四行 magnitude 的任何调整都须**重跑条款 2/3 锚预检**并同步 registry(接口漂移义务)。defense_up 叠满 −60% = 当次结算 0.4× 承伤(消费读法归 B1);减伤窗口强度与 attack_up 同入 B1 对账联动评估(B1 地板规则 × 战斗时长曲线 × 条款③ V_safe),禁止独立调参——defense_up.magnitude/duration 已纳入"禁独立调参"联动网络(m_w↔D_ref↔m_d↔duration_d,与 B1 Knob 交互同口径);减伤墙批(−50→−30)即该联动的实证回调(免伤轮现行可达路径 = weaken 饱和,见 F2)。
## 验收标准
### 测试口径
| 口径 | 要点 |
|---|---|
| 测试载体 | B3 是纯行为容器——无场景、无表现面、无加载期自有校验类别。冒烟载体 = `godot --headless --script`(承 D2 冒烟框架;脚本 extends SceneTree 以获得 quit(code)、ConfigDB autoload 由脚本显式实例化);容器经 class_name 直引实例化(每用例全新实例、无跨用例状态——A4 AC-5 直引先例同款;AC-19 扫描对该实例化路径豁免) |
| 被测面 | B1 就绪前冒烟直接驱动 B3 最小 API 面(承 A3"直接驱动最小 API 面"先例);B1 就绪后改走真实调用方(结算编排),断言口径不变。API 面:notify_battle_start() · apply_effect(effect_id, source) → bool · query_active(side) → Array · decay_round() → int · notify_battle_end() → bool |
| 返回口径 | 全部布尔/计数返回 = 受理/拒绝(A3 全 API 布尔口径同款)——"拒绝"直接断言返回值,附 debug 诊断、非进程致命(承 A3 拒绝口径;进程致命保留给 D2 数据通道);decay_round 返回值 = 本轮移除数断言;apply_effect 是唯一授予入口(Rule 3),冒烟直接构造合法 source = {source_class, origin_cell, round_index}(B1 转化产物的冒烟等价——信任方向同 A3 对 chain_size/clears_map 的处理);query_active 为只读、任意相位合法 |
| 只读观测量 | 实例六字段 effect_id · layers · remaining_settlements · source_class · origin_cell · round_index;query_active(side) 元素 = 结算面向载荷投影:六字段 + display_name + 授予时数值快照 (magnitude, unit)(EC9 快照语义 + B5/D1 数据源)——有效值 = layers × 快照 magnitude、unit 标签原样随值输出(F2);枚举序 = 插入序(Rule 6)。相位无字段观测量:BattleClosed/Active 由 API 返回值推断;Expired/Cleared 为销毁态不可观测(瞬态纪律同 A3 RoundEnd) |
| 时序口径 | B3 无 round_start/settlement API——"轮边界"在冒烟中 = 相邻两次 decay_round() 调用之间的授予/查询窗口(B1 编排在 B3 侧的可见面恰为这五个 API);多步 GIVEN 均给出构造序列 |
| 期望值纪律 | magnitude / duration_settlements / max_stack 均为 knob(Tuning Knobs 节)——各 AC 的 THEN 具体数值按当前 ConfigDB 表值推导、不写死(正文以 D_a / M_a / m_w 等表读值记号书写);结构字段(effect_id 集合、target_side、unit、stack_policy)非 knob、定值断言合法;行表"来源"列为内容档案(provenance)非 schema 字段、非运行时约束——B3 不校验 source_class 与行的对应(EC6 dumb 账本同族) |
| 夹具策略 | ① 默认根(干净检出四行 MVP 内容)承载全部分支行为 AC;② 程序构造(schema 类 class_name 直引实例)承载 AC-13 域校验——不经 load()/preload();③ 行为夹具根经 --data-root 注入(仅 debug、不入 data/tables/——D2 夹具纪律),承载 MVP 无行的语义(refresh/independent)。显式声明:夹具测试行非 MVP 内容(Rule 10 四行全 stack;测试行仅供冒烟)。选夹具根而非程序构造注入表的理由:容器经 ConfigDB 单点读表(Rule 2/9)、无表注入 API——--data-root 是 debug/test 构建的既定注入通道;各 AC 声明其表根(默认根/下列三根),用例间无顺序依赖、每用例先 reset_diagnostics()(D2 冒烟协议,全局声明) |
| 致命类收窄 | 恰一根致命夹具 status_effect_dup_key(重复键类别):runner manifest 退出码行 dup→≠0(独立 headless 进程、游戏通道,D2 AC-2b 协议同型)——"游戏内真的会死"在本表上的落点由此腿实证;其余致命类别(枚举域/域校验/跨字段)由 D2 AC-2 同类别 loader 级夹具承载(表无关,豁免声明收窄保留);schema 侧以程序构造断言域类别(AC-13) |
| out-of-scope | deferral 生效条件 = B1 义务清单(依赖节,均已落位):① 同轮多授予先到先得次序(EC3 后半——冒烟单调用方次序即构造序,B1 编排次序 = 义务①)② 事实→授予恰一次转化(EC6 后半——义务②)③ percent→乘数换算方向与合成值地板(EC7 收口半——义务③)④ 最后一轮 decay 判定次序(F3 时序契约的 B1 半——battle_end 全清兜底使两序同终态,冒烟不构造)⑤ 效果档位对照表以 B3 实例为对照实物(义务⑤,对账归 B1)。另有:结算明细"溢出未生效"行与来源标注呈现(冒烟无明细观测量——对侧承载已登记:B1 义务⑧ + B5×2,deferral 生效条件成立);D1 HUD 状态栏与 EC12 空态渲染(D1×4 已登记);效果语义到结算公式映射(Rule 7——B1 SettlementTable 域);Rule 8 负空间(无驱散/延时/转移 API——"无对应 API"不可 GIVEN-WHEN-THEN,验收形态 = 前言 API 面封闭枚举 + 接口漂移修订门);D2 schema 校验致命端到端(双通道协议承载);悬空引用校验(EC2——D2 双通道条件性夹具);EC9 reload 门腿(D2 AC-16 既有覆盖 + B1 是置位/复位唯一调用方——B3 无断言义务);EC8 端到端换图腿(B1 编排合规,AC-10 裁决) |
夹具规格(登记值即相关 AC 的推导基准):
| 根 | 内容 | 用途 |
|---|---|---|
| status_effect_policy_rows | refresh_probe(display_name="刷新探针" · hero · percent · magnitude=+10 · duration=3 · stack_policy=refresh · max_stack=4——故意违反"refresh 行恒 1"内容约定)+ independent_probe(display_name="独立探针" · enemy · flat · magnitude=+2 · duration=3 · stack_policy=independent · max_stack=1)——全字段域内合法数据 | AC-5 / AC-6(EC4 / EC10 / EC14 载体) |
| status_effect_policy_rows_reloaded | 仅 fresh_probe 一行(hero · percent · magnitude=+20 · duration=9 · stack · max_stack=1);根规格 = D2 全表清单拷贝 + 仅置换 StatusEffectTable 为本单行(缺任一表文件即触发 D2 EC1 文件缺失致命、GIVEN 不可构造——"仅一行"指该表内容非根内容) | AC-15 重载腿 |
| status_effect_dup_key | D2 全表清单拷贝 + StatusEffectTable 置换为默认四行 + 追加一行与 attack_up 同 effect_id 的重复键行(其余字段域内合法)——唯一致命夹具(A4 variation_dup_key 同型):loader 集成缝(loader 是否对本表调用校验)的进程级落点 | runner manifest dup→≠0 |
### AC 清单(Given-When-Then,编号不变)
| AC | Given | When | Then |
|---|---|---|---|
| AC-1 | 全新容器(BattleClosed、空;表根 = 默认根) | ① 依次 apply_effect(attack_up, 合法 source)、query_active(hero)、query_active(enemy)、decay_round();② notify_battle_start();③ 再次 notify_battle_start() | ① apply 返回 **false**(EC1 域闭拒绝)、双侧 query 均 = **空 Array**(EC12)、decay 返回 **0** 且诊断收集器零新增(EC13——空容器域闭的兜底读法,非独立分支不诊断);② **true** 且 query 仍双侧空(战斗开始时为空——Rule 1);③ **false**、相位与容器不变(EC11 前半——Active 再 start) |
| AC-2 | Active 且已建账(构造:apply_effect(attack_up) ×1 + apply_effect(weaken) ×1,query 断言含两实例) | ① notify_battle_end();② 再次 notify_battle_end();③ decay_round();④ apply_effect(attack_up, …);⑤ notify_battle_start() | ① **true**、query 双侧空(Cleared 全清、不跨战斗——Rule 1);② **false**(EC11 后半——Closed 再 end);③ **0** 且诊断零新增(EC13 域闭腿);④ **false**(EC1 全场战后腿);⑤ **true** 且容器空(唯一出口——下一场战斗重启,States 表) |
| AC-3 | Active | apply_effect("attack_up", {safe_cell, (3,4), round_index=2}) | true 且 query_active(hero) 恰 1 实例,其六字段逐一相等:effect_id="attack_up"、layers=1、remaining=D_a(attack_up.duration_settlements 表读值)、source_class="safe_cell"、origin_cell=(3,4)、round_index=2(P2 归因字段授予即携带——Rule 3,结算明细逐行标注的数据源) |
| AC-4(stack 分支前两腿 + "R 不动" spec 决议) | Active;D_a / M_a 为表读值 | 腿 1:无存活实例时 apply_effect(attack_up, …);腿 2(前提 D_a ≥ 2 ∧ M_a ≥ 2——默认表值 D_a=1 不满足,本腿默认退化跳过 + 显式 SKIP 标记防 CI 静默、不假失败,前提满足时执行;构造 = 腿 1 实例经 decay_round() 一次至 R=D_a−1)再 apply_effect(attack_up, …) | 腿 1:true、新实例 **L=1、R=D_a**;腿 2:true 且 **L=2、R 仍 = D_a−1**——**stack 授予不触碰 R**(F1 注 spec 决议:只有初始授予定钟;实现若重置 R 即三分支失去区分性,本腿即其暴露点) |
| AC-5(refresh 分支 + EC4 + EC10;表根 = status_effect_policy_rows,测试行非 MVP 内容) | Active;D_f=3、m_f=+10(夹具规格登记值) | ① apply_effect(refresh_probe, …);② decay_round() 后 apply_effect(refresh_probe, …);③ R 已 = D_f 时再 apply_effect(refresh_probe, …);④ 再 apply_effect ×2;⑤ 该根经测试通道加载 | ① true、新实例 L=1、R=D_f、载荷 = 1×m_f(refresh 行 L≡1——F2);② 返回 0(R=D_f−1)后 **true、R 重置 = D_f、L 不变**(F1 refresh 正常腿);③ **true 且实例六字段 + 载荷逐字不变**(EC4 空刷新 = 合法空操作——refresh 无满层/溢出语义);④ 均 true(max_stack=4 从不被消费——**EC10 行为 = 忽略**);⑤ 诊断为零(内容约定非校验项——EC10 非校验半句) |
| AC-6(independent 分支 + EC14;同夹具根,测试行非 MVP 内容) | Active;D_i=3(夹具规格登记值) | 同轮授予批次内以互异 origin_cell((1,1)/(2,2)/(3,3)——插入序可观测的前提)apply_effect(independent_probe, …) ×3;再 decay_round() | 全部 true 且 query_active(enemy) 恰 **3 个并存独立实例**(各 L=1、R=D_i、**投影序列 = 授予序** (1,1)→(2,2)→(3,3)——互异 origin_cell 使插入序成为可判定断言,Rule 6 枚举确定性);decay 返回 0(D_i≥2 无移除)且三实例各自 R=D_i−1(F3 逐实例、无豁免);实例数上界 = 受理授予数(**EC14 有界确定**——无满层语义) |
| AC-7(EC6 不去重) | Active 且已有 attack_up 存活实例(L=1,构造同 AC-3) | 以完全相同的 (effect_id, source)(同 origin_cell、同 round_index——同一事实重复转化的模拟)再次 apply_effect | true 且同实例 **L=2**——B3 **不去重**(dumb 账本,无从辨别事实合法性,EC6);out-of-scope:事实→授予恰一次转化归 B1 编排(义务②,deferral 生效条件 = 依赖节清单) |
| AC-8(F3 主式) | Active(构造:apply_effect(weaken) ×2 → 单实例 L=2、R=1;apply_effect(attack_up) ×1 → R=D_a;前提 D_a ≥ 2——第二 WHEN 腿依赖,默认表值 D_a=1 不满足 → 本条退化跳过 + 显式 SKIP 标记(同 AC-4 口径、防 CI 静默),前提满足时执行) | ① decay_round();② 再 decay_round();③ 对空容器 decay_round() | ① 返回 **1**(= 构造中 dur=1 实例数,由表读值推导;weaken 实例移除)、attack_up R=D_a−1 仍在、容器插入序不变;② 返回 1(attack_up 移除——**R 归 0 即销毁,容器无 0 值实例**,与不变式 remaining ∈ [0, D] 相容);③ 0(F3 极端域)。R 轨迹与 k 全部由表值推导 |
| AC-9(EC5 dur=1 单轮叠层 + 一次性全落点) | Active(新轮) | 同轮授予批次内 apply_effect(weaken, …) ×3(N=3 为构造选择,≤M_w 表读值);decay_round();下一轮边界再授予 weaken ×1 | 全部 true、单实例 **L=3、R=1(=D_w 表读值)**、载荷 = 3×m_w(同轮兑付一次的合成输入;N 旗 = N debuff 总吞吐的对账归 B1 条款 2——义务⑤邻接,out-of-scope);decay 返回 1、实例移除;再授予 → **新建**实例 L=1——**跨轮必为新实例**(旧实例已销毁,F1 Example weaken 腿) |
| AC-10(EC8 跨轮/跨图延续——结构性裁决) | Active,attack_up 授予 ×1(R=D_a) | 连续多轮边界仅 decay、无新授予(停手轮/弃图轮的 B3 视角——B3 无图概念、换图/刷新零专用信号);逐步 query | 实例 R 逐轮 −1 **不停摆**(无豁免实例、无参数——**无"不结算就不掉次数"的免费延时**,Rule 2),且每步 query 断言容器非空直至 R 自然归 0——**除 notify_battle_end 外无任何 API 入口使容器清空**(先轮授予的实例按 R 存续至自然到期)。裁决:EC8 的"换图不清空"对 B3 的可测内容 = 本条两句(跨轮延续 + 唯一清空入口);"换图"事件对 B3 不可观测(零接口)——端到端"真实换图下容器仍存续"归 B1 集成(编排契约:仅 battle_over 调 end——B1 API 合规半句,B1 GDD 域,非新增义务) |
| AC-11(EC3 满层拒绝与原子性) | Active;M_a 为 attack_up.max_stack 表读值;构造叠满(M_a 次授予——次数由表值推导、不写死),前 M_a 次均 true、单实例 L=M_a | 第 M_a+1 次 apply_effect(attack_up, …) | **false** 且容器逐字不变——query_active(hero) 恰 1 实例,其六字段 + 载荷 + display_name 与授予前快照**逐项相等**(拒绝原子性:无半写、无溢出落层,F1 Output Range);"溢出未生效"明细行归 B1(out-of-scope,义务①邻接) |
| AC-12(EC2 未知 effect_id) | Active | apply_effect("no_such_effect", 合法 source);表行改名后的旧 id 同理 | **false**、容器不变。政策声明:悬空引用加载校验 = 首引激活条款——B4 RewardTable 首个 effect_id 引用已回填、校验已激活(registry dangling_ref_policy;条件性夹具 = B4 b4_dangling_effect;out-of-scope,D2 双通道) |
| AC-13(加载期域校验全谱——程序构造,class_name 直引,A4 AC-5 同型) | StatusEffectTable schema 类直引实例(不经 load()/preload()) | validate() 分别作用于非法组:percent=0(跨字段 percent≠0)/ percent=101 / percent=−101、flat=0(flat ≥ 1)、duration ∈ {0, 100}、max_stack ∈ {0, 17}、stack_policy/target_side/unit 各一出域枚举值、两行同 effect_id(重复键);再作用于域内代表值 percent ∈ {100, −100, 1, −1}、flat=1、duration ∈ {1, 99}、max_stack ∈ {1, 16} 及 stack_policy=refresh 且 max_stack=4 的行(EC10) | 非法组:各含对应域错误类别;合法组:零诊断(EC10——内容约定非校验项,防过度约束锁死未来内容) |
| AC-14(F2 合成 + EC7 不 clamp) | Active;m 各值为表读值 | 腿 1(percent·stack):apply_effect(attack_up) ×2(前提 M_a ≥ 2——默认满足,M_a=1 时退化为单层恒等断言 + SKIP 标记);腿 2(flat):apply_effect(ambush) ×3;腿 3(越域,EC7):同轮 apply_effect(weaken) ×M_w(M_w 表读值、≤16 同轮批授予合法);腿 4:refresh/independent 行载荷 L≡1 | 腿 1:载荷 = **2×m_a** 且 unit="percent" 标签随值输出(量纲标签不进乘法——F2);腿 2:载荷 = 3×m_amb、unit="flat"(B3 不解释单位——排除声明);腿 3:载荷 = **M_w×m_w 原样输出、无 clamp**("不 clamp"的可判定形式 = 载荷与表值推导值恒相等,任何地板都会使其不等;承载声明:本腿非平凡性依赖默认基线——M_w=16、m_w=−65 → −1040 越出 percent 域;knob 调参使 M_w×m_w 绝对值 ≤ 100 时退化为恒等断言、不假失败,退化时用例输出显式退化标记 SKIP 日志、CI 可见防静默失真;地板/clamp 与换算方向归 B1 SettlementTable——out-of-scope,义务③);腿 4:已由 AC-5①/AC-6 承载(引用不重复) |
| AC-15(EC9 快照 vs 表重载——机制口径) | 表根 = status_effect_policy_rows、Active、已授予 refresh_probe ×1 并 decay 一次(R=D_f−1、载荷 1×m_f) | 冒烟脚本经测试通道换根加载 status_effect_policy_rows_reloaded(load_tables(root, collect_only=true) 直调——非 D2 reload() 路径:不过 set_reload_gate、不发 config_reloaded、无 EC16 语义,门语义归 D2 AC-16/B1〔OQ5〕;reloaded 根规格 = D2 全表清单拷贝 + 仅置换 StatusEffectTable,见前言夹具规格);再 apply_effect(fresh_probe, …)(新 id、无存活实例——refresh 重置目标取实例快照 D 的口径见 F1 注,本腿不涉存活实例重置) | **已授予实例六字段与载荷逐字不变**(授予时拷贝 m/D/unit 数值快照——EC9"快照非活引用",A4 EC8 同款语义;实例为 B3 自持,故 B3 冒烟自测、无需 deferral);fresh_probe → true 且新实例 **R=9、载荷 1×(+20)**(夹具登记值)——**换根只影响后续授予** |
| AC-16(MVP 内容四行) | ConfigDB 默认根加载完成 | 读 StatusEffectTable | **恰含 4 行**、effect_id 集合 = {attack_up, defense_up, ambush, weaken}(定值);target_side:attack_up/defense_up=hero、ambush/weaken=enemy,unit:percent/percent/flat/percent,stack_policy=stack ×4(均非 knob 结构、定值断言合法——Rule 10"四行全 stack");display_name 四值非空(精确值对账归 AC-18);magnitude/duration_settlements/max_stack 仅作类型域断言、期望 = 表读值(knob 纪律——A4 AC-1 同款,防调参打假;行表"来源"列为 provenance 非表字段、不作断言) |
| AC-17(确定性——A3 AC-17 同型;可观测序腿) | 全新容器实例 ×2(同 ConfigDB 默认根;每遍新实例、无跨实例状态) | 同一定长序列驱动两遍:start → defense_up×1 → attack_up×1(同侧双实例、授予序 = 字典序**逆序**——区分"插入序实现"与"字母排序实现"的判别性前提)→ query 投影(hero 恰 2 实例,**投影序列 = [defense_up, attack_up] 定值断言**——插入序的行为级观测点)→ weaken×1 → decay → query 投影 → attack_up×1(并入腿——前提 D_a ≥ 2 成立时并入 L=2;默认表值 D_a=1 时旧实例已销毁,退化为新建 L=1 断言 + SKIP 标记,同 AC-4 口径)→ decay → end → query | 两遍的 query_active 投影序列(**含插入序**)与 decay_round 返回值序列**逐项相同**,且 hero 侧投影序恒 = 授予序(非字典序——零随机 + 插入序枚举的双重行为级证据——Rule 1;D2 AC-15 的 B3 层前身) |
| AC-18(registry 一致——A3 AC-10a 同型,无条件断言;registry 逐字段键) | ConfigDB 默认根加载完成 | 脚本解析 design/registry/entities.yaml 的 status_effect 条目(**逐字段 YAML 键**——机器对账前提,action_economy 同构) | ① fields 八键与 ConfigDB schema 字段名逐一相等、各键的类型/域/枚举描述与 schema 定稿相等(**缺任一键即失败**);② mvp_content 四键 id 集合与表行 id 集合相等,**非 knob 结构字段**(target_side/unit/stack_policy)逐一相等;③ rule4_exemption / dangling_ref_policy 注记存在性断言。knob 活值(magnitude/duration_settlements/max_stack)**不作定值对账**(A4 AC-8 同款——对账口径 = registry 随调参同步〔接口漂移义务〕,本 AC 豁免其值)。生效前提:本条目为定稿回填 + registry 逐字段键重构的产物,AC 生效前提 = 重构回填完成(不写"若存在"软口径——条件化使一致性检查落空,A3/A4 均无条件) |
| AC-19(静态扫描——D2 AC-9/AC-10 模式引用,A3 AC-10b 同型) | B3 文件集(容器/schema/冒烟脚本/夹具规格)纳入 D2 AC-9 模式项目级扫描域 | 静态扫描:randomize() / RandomNumberGenerator / ConfigDB 外 data 表加载 / extends Control / .tscn preload;+ D2 AC-14 人工三要素字面量扫描 | 全部**零命中**(schema 与容器的 class_name 直引实例化豁免——AC-13 前提,A4 AC-7 同款);字面量扫描引用不另设硬 THEN(字面量判定误报率高——D2 已定性 warning 级 + 人工复核);零随机的行为级硬证据 = AC-17 |
### 覆盖矩阵(qa-lead 交付,验收评审用)
| 类别 | 映射 |
|---|---|
| Core Rules | Rule 1→AC-1/2/10/17/19 · Rule 2→AC-8/9/10 · Rule 3→AC-3+前言 API 封闭 · Rule 4→AC-4/5/6 · Rule 5→AC-11(明细行→B1 义务⑧+B5×2 已登记)· Rule 6→AC-1/2(decay 次序 OOS)· Rule 7→OOS(载荷只读面 AC-14)· Rule 8→前言 API 封闭+OOS · Rule 9→AC-13/16/19 · Rule 10→AC-16/18 |
| Formulas | F1→AC-4/11(stack)/AC-5(refresh)/AC-6(independent)· F2→AC-14+AC-5①/AC-6 · F3→AC-8/9/10 |
| 边界情况 | EC1→AC-1/2 · EC2→AC-12 · EC3→AC-11 · EC4→AC-5③ · EC5→AC-9 · EC6→AC-7 · EC7→AC-14 腿 3 · EC8→AC-10 · EC9→AC-15 · EC10→AC-5④+AC-13 · EC11→AC-1/2 · EC12→AC-1 · EC13→AC-1/2 · EC14→AC-6——无洞 |
## 开放问题
| # | 问题 | owner | 状态/时机 |
|---|---|---|---|
| 1 | weaken 条款 2 锚裁决——归一口径已由 F0 裁决关闭(每结算瞬时当量;总暴露分支被 schema 域禁止排除),m_w 值域 [60, 85]/默认 −65 已入文。余项:终值共裁确认 + registry 终值回写,裁决时复查 AC-14 腿 3 非平凡性 | B4/B1(deadline:B1 GDD 强制检查点) | 余项随 B1 OQ2 联动 |
| 2 | ambush 量纲——已定稿(B2 GDD:每层伏击为每次攻击类行为附加 m_amb 点主角 HP 伤害、后置加法、charge 拍零兑付——registry ambush_unit_definition)。余项:B1 条款 3 上限检验 | B2 → B1 | 随 B1 对账闭合 |
| 3 | 首个 refresh/independent 内容行的 AC 补全——EC4 登记义务:奖励池引入非 stack 行时补真实内容行冒烟 AC,夹具探针行退役;其授予可见性语义(空刷新 vs Rule 5)随批由 B4/B1 裁决 | B4 | 奖励池引入非 stack 行时 |
| 4 | clear_reward 源授予——清图奖励若含 buff 的授予路径确认(apply_effect source=clear_reward;A3 条款 4 差异化插槽) | B4 | B4 期 |
| 5 | EC9 reload gate 的 B1 侧落点——防"战斗中真的被置位"零落点(qa-lead 缺口 #4) | B1 GDD 门禁评审 | 随 systems-index 门禁记录登记 |
| 6 | 效果当量对照表的预检重跑——条款 1 对照表落定时按预检重跑 weaken/ambush 方向性预检(正式对账载体);C3 首次调参即须按现行参照(attack_up 当量)复算条款 2 预检 | B1 | B1 对照表落定 / C3 首调 |
| 7 | stack-不重置 R 的 playtest 证伪项——F1 注决议(用户拍板、结构冻结)的体验面反例检验:"早拿必亏"(分轮拿满总暴露 150pp vs 同轮拿满 200pp——算例基线 = dur=2 行值;现行四行 D=1 下两读法总暴露相等、不对称休眠,dur ≥ 2 内容行上线时激活)叠加奖励身份不可预读(创意风险 #1)是否伤害"把 buff 纳入挖掘推理"的规划感(P1)。补偿载体先行:B4 奖励身份预读 + D5"同轮拿满"教学;证伪成立则走结构冻结修订流程回炉(合并/重定义 stack 分支)——非调参 | 垂直切片前置 playtest 批次 | playtest |
## 版本历史
| 版本 | 日期 | 改动 |
|---|---|---|
| 跨评审 B3 接口漂移批 | 2026-09-14 | /review-all-gdds 🔴-1 前半(减伤墙批回写缺口,registry 同批):defense_up.magnitude −50→**−30**(减伤墙批 C3 投值——叠满两层 −60 帽,defense_scan 墙轮 39%/真人 12 轮零承伤定量坐实)——MVP 内容行/Tuning Knobs/F2 Example 同步;免伤轮叙述同步(defense_up 单侧不可达 D'=0,现行可达路径 = weaken 饱和;F2 三例第三例改 defense_up 叠满读法——对侧 B1 F2 同批);Knob 交互:defense_up.magnitude/duration 纳入"禁独立调参"联动网络(m_w↔D_ref↔m_d↔duration_d);核心规则表增依据列(lint R8 引用列迁移) |
| v1.1-lean | 2026-09-13 | 格式迁移:legacy 原稿按 lean 样例重排——修订注记出正文收敛至本表;散文/枚举/边界/AC 转表格;流程转字符画;公式本体、Variables 表与验算数据全保留;语义与 registry 现行值对齐(weaken −65 = F0 值域 [60,85] · 四行 duration 1/1/1/1 = 当次结算 · enemy 侧 side-wide 多敌读法),零规则变更 |
| 两级奖励批 | 2026-09-11 | attack_up/defense_up duration 2→1(当次结算语义:授予结算兑付后即衰减);attack_up 复活(HeroTable.atk 域 [1,999]、0 加载拒绝——基础攻击恒存在,消费面 = 主角战斗段先手攻击);条款 2 锚参照对象回迁 attack_up 当量;正文原 D=2 行注记与 Knob 表 2/2/1/1 旧行按本批现行值改写 |
| F0 裁决回执批 | 2026-09-10 | weaken −25 → 值域 [60, 85]/默认 −65(B1 GDD F0:归一口径 = 每结算瞬时当量,总暴露分支被 percent schema 域禁止排除——条款 2 锚红警关闭,锚两腿 7.8 > 6.0 / 7.8 ≥ E_dig 7.2 通过);B1 义务①–⑧履行回执落位;B3 正文回执以 B1 GDD F0 为准(registry status_effect.anchor_warning) |
| 单敌假设回验批 | 2026-09-09 | B2 定多敌模型(1–3 个同敌种敌单位)——Core Rule 1 单敌假设回验不成立,效果 side-wide 语义改"全体存活敌单位"(层数 = side 共享池,B3 现接口零变更兼容);target_ref 单体寻址 = 扩展位义务(首个单体效果上线时 B3 补列,随批 B1 归集语义/D1 呈现裁决)——registry single_enemy_assumption |
| Rev 1 | 2026-09-09 | design-review 7 项 blocking 同日核销:enemy 侧单敌假设入文(后经上批回验改写)· B1 义务 5→8 · D1/B5/D5 呈现义务登记 systems-index · AC-15 机制更正 + reloaded 根全清单规格 · 致命夹具补根 dup_key · AC-18 随 registry 逐字段键重构 · weaken 红警补修复空间不对称 + OQ1 归一口径前置 · stack-不重置 R 登记 OQ7 playtest 证伪项——明细见 reviews/b3-status-effect-review-log.md |
| v1 | 2026-09-08 | 一次会话定稿:三结构决策(单一计数/按行叠层/四行定稿权收编)用户拍板;lean 门禁 systems-designer 起草 Formulas · qa-lead 起草/验证 AC;CD-GDD-ALIGN 按 lean 跳过 |