- design 件只装结论:v2 骨架(设计目的/系统范围/核心循环/领域章节/依赖与输出/P0 闭环/P1·P2 后置/调参表/GWT 验收/版本历史),AC/EC/OQ/义务台账编号全部保留 - 新建 design/gdd/analysis/ 13 份推演件:候选取舍/公式推导/数值锚定论证/已裁决争议按问题节组织,文末附去向映射表(零丢失审计) - v1 原文备份于 design/gdd/legacy-2026-09-14-v1/(13 份) - systems-index 文档树补 analysis 目录导航行 - gdd_lint 全量 PASS(14 文件 0 不通过);迁移零裁决——19+1 项待拍板已登记各 analysis 开放问题区
66 KiB
B3 增益/状态系统(Status Effect System)
状态:Approved · 版本:v2 · 2026-09-14 承载支柱:P2 主(可归因兑现的机制落点)· P3(敌方增益/debuff 兑付面)· P1(时限透明的规划素材)· P4(间接)· Layer:1 Foundation · Milestone:MVP · 设计顺序:第 4 位 一句话:战斗域统一状态容器——三向效果同构实例的时限/叠层/衰减机制唯一 owner,兑付接口供 B1 结算逐行消费。 推演件:
design/gdd/analysis/b3-status-effect.md(本文件只收结论,理由在那里)
设计目的
战斗里不在当场一次性、而要在若干次结算里持续起作用的战斗效果(安全格增益 / 踩雷敌方增益 / 标中旗削弱 / 清图奖励 buff)需要一个统一的存放与生命周期 owner。少了它,四类效果各写一套计时叠层逻辑,结算明细无法逐行归因,"规划的延迟兑现"无从落地。
- 玩家指着任意一行结算明细,能答出"这效果是我哪步扫雷带来的"——来源标注随行(P2)。
- 玩家能读到每个增益"还剩几次结算、何时到期",把它纳入挖哪格的推理(P1)。
- 叠满再拿同款时玩家看得到"这层白拿了"——浪费诚实、可规划(P2)。
- 踩雷的敌方增益与标中旗的削弱用同一呈现语言,玩家由此学会雷的两面(P3)。
- 结算编排只对接五个固定接口;新增效果只加表行、不改容器代码。
系统范围
负责:
- 状态实例生命周期(战斗域):授予受理、存续、到期移除、战斗结束清空;机制与内容分离——B3 只拥有机制,效果内容的经济归属归各锚 owner
- 时限/叠层/衰减机制语义:单一结算次数量纲、按行叠层三分支、先兑付后衰减
- 兑付接口五 API 与 P2 归因字段(实例六字段 + display_name + 授予时数值快照)
- StatusEffectTable 回填 owner:schema + 四行 MVP 初值定稿权(锚验收权留 B4/B2/B1)
- 硬约束:零随机(无 RNG 流消费)· 零 UI 依赖 · 零信号外发(纯被动容器)· 全 API 布尔/计数返回、无 await——可回放步骤流的状态侧前提
不负责:
- 效果内容经济归属——安全格 buff 与标中旗 debuff 档位锚验收(B4)、敌方增益上限(B2)
- 效果语义到结算公式的映射、兑付作用顺序、合成值地板/clamp、percent→乘数换算方向(B1 SettlementTable)
- flat 量纲定义(B2——已定稿,registry ambush_unit_definition)
- 呈现与渲染面——HUD 状态栏/结算明细呈现/图标映射(D1/B5/art-bible)、教学(D5)、本地化(D6)
- 事实产生与资格判定——开格/标中/开雷事件(A2)、标中旗兑付资格判定(A3/A2 域)、事实→授予恰一次转化(B1)
- 数据加载、校验、热重载门(D2)
- 事件外发(零——纯被动容器)
核心循环
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 结算明细(含来源) | 拒绝原子性——无半写、无溢出落层 |
实例状态
容器为纯逻辑类(非 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 数据通道)
设计意图:四态封闭、清空入口唯一,"容器何时为空"永远可答。
枚举与数据字段
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 schema(D2 承载,B3 回填 owner)
规则:
- Rule 9 容器本身不认识任何具体数值——哪个状态加多少、活几次、最多叠几层全部写在状态表里,运行时统一从 ConfigDB 读表;代码零玩法数值字面量,调平衡只改表、不改代码。
| 字段 | 类型/范围 | 说明 |
|---|---|---|
| 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 重复授予的合并策略 |
| max_stack | int [1, 16] | 层数上限;仅 stack 消费——refresh/independent 行约定恒 1(内容约定,非校验项) |
- 表为定义表非进度成长表,无 (level_index, node_depth) 维度(D2 Rule 4 豁免,A4 先例);未来随关卡成长的效果走接口漂移加列
- 加载校验:表非空(D2 Rule 6,四行即满足);effect_id 唯一(重复键致命——本表唯一致命夹具 dup_key);枚举域校验(target_side/unit/stack_policy 出域致命);duration/max_stack 域校验;跨字段 percent ≠ 0 / flat ≥ 1
举证:Rule 9 依据 = D2 Rule 1〔数值字面量禁令〕;本 GDD 为该表回填 owner,新字段走接口漂移规则。
StatusEffectTable MVP 内容行(四行值域快照——值全部 provisional)
规则:
- Rule 10 四行 MVP 内容(增伤、减伤、伏击、削弱)的初始数值由本文档定稿;"值合不合适"的验收权留在对口系统——削弱按"必须严过最低档增益"的当量锚验收、伏击按敌方惩罚上限验收、对账由结算闭合;要改初值走接口漂移规则回写登记库(registry),不是随手调参。
| 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 对照验收) |
举证:Rule 10 依据 = A3 F1 条款 2〔debuff 严格 > 最低档 buff 当量,参照对象 = attack_up 行当量〕· 条款 3〔B2 惩罚上限〕· A3 OQ5 收编〔registry ownership_note——A3 GDD 正文不改,以本条 + registry ownership_note 为准〕;初值定稿权归本文档、锚验收权留 B4/B2/B1,是对"档位归奖励表设计"的显式收编。
设计意图:机制归容器、数值归表、档位归锚 owner——三方权责不混。
授予、合并与接口
规则(原编号保留):
- Rule 1 战斗里不在当场一次性生效、要管上几回结算的效果——主角增益、敌人增益、敌人受到的削弱、清图奖励——全部作为同一种状态实例存进同一个容器,用同一套计时、叠层、衰减规矩管理,没有哪类效果走特殊通道;容器四条硬规矩见下表。
- Rule 3 状态只在结算时发放:挖掘期的挖格、插旗、踩雷不直接改容器,棋盘只上报"发生了什么"的事实,结算编排在每轮结算时统一把事实兑换成状态发给容器——这是唯一进货口,棋盘与奖励背包都没有直通通道;每笔状态随身携带归因(来源类别四选一、来自哪个格子、第几轮);状态一经发入立即生效,没有"待生效"中间态,同一场结算就是它的第一次兑付。
- Rule 4 同一种状态还没消失时又拿到一份,怎么合并由数据表每行的叠层策略字段说了算——叠加(层数 +1、寿命不动)、刷新(寿命重新计满、层数不变)、并存(各算各的一份);合并在授予那一刻由容器内部完成,多个状态在结算里按什么先后起作用是结算编排的职责,两件事互不干扰;叠加是纯加法——几层就是几倍的行值。
- Rule 5 叠加型状态叠到上限再授予同款不生效:容器拒绝、内容一个字不变;但这份奖励不会被无声吞掉——结算明细多一行"溢出未生效"、连来源一起写明;无论重复来自玩家直接踩出的格子、结算转化、还是连锁展开自动开出的奖励格,都走同一个授予入口、同样产生溢出行、同样留痕;不做覆盖、不做溢出落层。
- Rule 6 状态容器是纯被动的仓库,自己不主动做任何事;结算编排要用它只有五个固定接口(下表);查询返回按发放先后排列且顺序永远稳定;全部 API 布尔/计数返回、无 await、无表现面。
- Rule 8 状态一旦生效,玩家没有任何手段把它摘掉、往后延、或挪给别人——容器没有提供这类接口;将来若要加驱散/延时/转移,属于新增接口的修订,不是调参数。
容器四条硬规矩:
| 规矩 | 含义 |
|---|---|
| 寿命 = 一场战斗 | 战斗开始时容器为空,战斗结束全部清空——不跨到下一场战斗 |
| 跨轮、跨图延续 | 同一场战斗里跨轮次、跨扫雷图都在;换图/刷新不清空(旗标记随旧图消亡归棋盘系统 A2 管,状态实例不随图走) |
| 全程零随机 | 容器不掷任何骰子:授予、合并、衰减、列举顺序全部确定 |
| 敌方侧共享 | MVP 敌人为 1–3 个同种敌单位(敌情系统 B2 定):对敌状态一律对全体存活敌人生效,层数全体共享一份 |
三向效果映射(授予路径):
| 事实来源 | 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) |
按行叠层三分支(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 入列) | 无满层语义——实例数上界 = 受理授予数(有界确定) | 同上 |
五个固定接口:
| 接口 | 干什么 | 返回 |
|---|---|---|
| notify_battle_start() | 告知战斗开始:打开容器、进入可用状态 | 是/否 |
| apply_effect(effect_id, source) | 发一笔状态——唯一进货口:受理即新建实例/叠层/刷新 | 是/否 |
| query_active(side) | 查询生效状态:某一方当前生效清单,按发放先后排列且顺序永远稳定 | 只读清单 |
| decay_round() | 轮末衰减:全部实例寿命 −1、归 0 即销毁 | 本轮移除数 |
| notify_battle_end() | 告知战斗结束:全实例清空、容器回空 | 是/否 |
举证:
| 编号 | 举证 |
|---|---|
| Rule 1 | 无计算;"不跨战斗"为 game-concept 定稿口径;多敌共享读法按 registry single_enemy_assumption 登记,现接口零变更兼容 |
| Rule 3 | 无计算;授予动作 = apply_effect(五接口之一);四类来源授予路径与目标侧见上表;来源取值封闭枚举见 source_class 表 |
| Rule 4 | 三分支逐分支语义见上表;合并执行伪代码见 F1;"有效值 = 层数 × 行值"加算合成见 F2 |
| Rule 5 | 无计算(判定 = 一次"层数 == 上限"比较);拒绝原子性(false + 容器逐字不变、无半写无溢出落层)见 F1 Output Range;"溢出未生效"行进结算明细协议由 B1 义务⑧承载、呈现归 B5/D1 |
| Rule 6 | 五接口签名见验收标准测试口径;查询返回 = 六归因字段 + display_name + 授予时数值快照 (magnitude, unit) 只读投影(qa-lead 载荷口径);结算作用顺序(哪个效果先乘)归 B1 SettlementTable,B3 只保证枚举确定性;最后一轮(敌人全灭)是否 decay 归 B1 判定次序域——A3 EC8 同款〔末轮 decay 判定次序域〕 |
| Rule 8 | 无计算;负空间规则——验收形态 = API 面封闭枚举 + 接口漂移修订门(验收标准测试口径 out-of-scope 行) |
设计意图:授予单口、合并查表、接口封五——结算编排与效果种类解耦。
时限与衰减
规则:
- Rule 2 每个状态实例自带一个倒数计数——剩余结算次数:它不承诺"活几轮",而是数"经历过几次结算",每轮结算先让状态起作用、随后计数减 1,减到 0 状态即被移除;一次性状态(初始计数 = 1)恰好在授予它的那轮结算里生效一次、轮末消失,MVP 四行内容全部是一次性;将来跨轮持续的增益寿命由表行初始值表达——给几就活几次结算;停手不挖的轮、弃图刷新的轮也照常算一次结算、计数照减——不做"不结算就不掉次数"的免费延时。
时限语义要点(单一结算次数量纲):
| 要点 | 内容 |
|---|---|
| 计数量纲 | remaining_settlements(剩余结算次数)——全部状态唯一时限单位 |
| 初始值 | duration_settlements = 授予时初始剩余结算次数(实例持有快照、不受表重载影响——EC9) |
| 衰减 | 每轮结算兑付后统一 −1(先兑付后衰减——B1 兑付完才调 decay_round);归 0 即移除 |
| 一次性 | duration=1 → 授予当轮编排期入容器 → 同轮兑付恰一次 → 轮末移除(MVP 四行全部 D=1——当次结算语义) |
举证:衰减的精确机制(每轮恰 −1、归 0 即销毁)与"先兑付后衰减"时序契约见 F3。
设计意图:倒计时单位与"兑付次数"同物——玩家读到的剩余次数就是规划素材本身。
数值结论(F0–F3)
本系统为数学承载系统:公式结论与表达式在此;推导过程、候选取舍与锚定论证全部在推演件。本节只含机制公式,平衡归属见显式排除声明。
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 裁决回执)
- AC-14 腿 3 非平凡性复查通过(16×65 = 1040 越出 percent 域);原 −25 值的裁决关系与修订轨迹见版本历史
F1 同 id 叠层合并(same_id_merge,授予时执行)
结论:授予时按行 stack_policy 三分支合并——stack 加层不触碰 R(只有初始授予定钟)、refresh 重置 R 取实例授予时快照 D、independent 并存新实例;满层拒绝原子(false + 容器逐字不变)。
merge(effect_id) —— 前置拒绝(域闭 / 未知 effect_id)沿用实例状态节 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)
Variables:
| 变量 | 符号 | 类型 | 范围 | 说明 |
|---|---|---|---|---|
| effect_id | e | String | 表主键 | StatusEffectTable 行键;未知 = 拒绝 |
| stack_policy | P | enum {stack, refresh, independent} | 表列 | 合并分支选择器 |
| 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 断言,不变式) |
| remaining | R | int | 存活态 [1, D] | 剩余结算次数;归 0 移除(F3) |
- Output Range: 正常域——stack/refresh 行同 id 存活实例数 ≤ 1(不变式);independent 行实例数 = 受理授予数(有界确定);返回值 bool。极端行为——满层授予恒 false 且容器逐字不变(拒绝原子性:无半写、无溢出落层);同轮批量授予的先到先得次序由调用方保证(B1 编排须按确定次序调用 apply_effect——B3 只保证插入序枚举稳定,B1 验收项义务①)。验算示例(attack_up / weaken / dur≥2 探针三例)见推演件问题 3。
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)。验算示例(attack_up/defense_up/weaken/ambush 四例)见推演件问题 5。
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 移除("一次性"语义的全部机制内容)。停手轮/弃图轮同为结算、照常衰减(无免费延时);最后一轮(敌人全灭)是否 decay 归 B1 判定次序域(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] 相容)。验算示例(轮 3 授予-兑付-移除全落点与 dur≥2 探针 R 轨迹)见推演件问题 2。
显式排除声明
本 GDD 无平衡公式——F1–F3 只承载机制数学(合并/合成/衰减),不含任何"值该多大"的判断;四行 MVP 值全部 provisional。平衡与语义归属:
| 对象 | 归属 | 依据 |
|---|---|---|
| 效果档位当量对照表(四源统一当量、单一线性换算) | 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;flat 量纲 → B2(已定稿——registry ambush_unit_definition:每层伏击为每次攻击类行为附加 3 点主角 HP 伤害、后置加法) | F2 Output Range;schema 说明列 |
| MVP 四行初值定稿权 | B3;B4/B2/B1 持锚验收权,修订走接口漂移回写 registry | Rule 10 |
规则:
- Rule 7 容器只记录每个状态的量(幅度数值 + 量纲标签:百分比还是固定值)和还剩几次结算——"增伤加在哪个算式上、先乘后乘、地板怎么收"一律由结算编排的顺序映射表按状态 id 作答;容器知道"现在还有 +50、还剩 1 次结算",不知道这 +50 会变成主角攻击里的什么;B3 只对"L×m 线性合成 + R 计数"负责,合成值多大算强、floor 在哪、+3 打谁,均不在本 GDD 语义域。
举证:Rule 7 无计算;语义映射承载面 = B1 SettlementTable(effect_id 为键);B3 只承载 magnitude/unit 两个通用数值字段。
边界情况
| 编号 | 条件 | 行为 | 依据 |
|---|---|---|---|
| EC1 | 域闭状态授予(BattleClosed 下 apply_effect) | 拒绝(false)、容器不变 + debug 诊断——B1 过早/过晚调用 = 编排错误显式暴露,不静默吞 | 实例状态节 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"不静默蒸发"存在原则张力——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 |
依赖与输出
| 方向 | 系统 | 性质 | 接口要点 |
|---|---|---|---|
| 上游 | 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 | 已登记 |
呈现与 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 |
P0 最小闭环
- B1 战斗开始调 notify_battle_start()——容器开域(空容器)。
- A2 开格/标中/开雷事件 → B1 收集 round facts → 转化 apply_effect(唯一进货口)。
- 容器按表行 stack_policy 合并受理(新建/叠层/刷新),实例即入 Active、携六归因字段与授予时数值快照。
- B1 每轮 query_active(side) 只读兑付——有效值 = L×m(快照)加算合成。
- 轮末 B1 调 decay_round():全实例 R−1、归 0 到期销毁(先兑付后衰减)。
- 域闭/未知 id/满层授予被拒(false + 容器零写),"溢出未生效"行归 B1 结算明细。
- B1 战斗结束调 notify_battle_end():全实例清空、容器回空 → BattleClosed,不跨战斗。
P1 / P2 后置
| 优先级 | 内容 | 后置原因 |
|---|---|---|
| P1 | refresh / independent 首批内容行启用(语义已定义、实现已承载;首个 refresh 行上线时补真实内容行冒烟 AC、夹具探针退役,授予可见性语义随 OQ3 由 B4/B1 裁决) | MVP 四行全 stack、非 stack 语义零消费者——待奖励池引入非 stack 行(B4 期) |
| P1 | clear_reward 源授予路径确认(清图槽含 buff 时经 apply_effect,source=clear_reward;A3 条款 4 差异化插槽——OQ4) | B4 期定稿 |
| P1 | target_ref 单体寻址列(首个单体效果上线时补列;随批 B1 归集语义 / D1 呈现裁决——registry single_enemy_assumption 扩展位义务) | MVP 敌情 side-wide 语义够用,无单体效果内容行 |
| P2 | 驱散 / 延时 / 转移接口(Rule 8 负空间) | 省掉一整类界面与规则复杂度是明确的设计决定;新增 = 接口漂移修订,非调参 |
| P2 | independent 行高频授予(DOT 类)的容量语义(EC14——实例数上界 = 受理授予数,有界确定) | MVP 无此内容行;归扩展(接口漂移),本 GDD 不预写 |
| P2 | 敌人词条引用状态(免疫/抗性) | 预留注记,不预写(B2 域随批裁决) |
| P2 | 随关卡成长的效果行((level_index, node_depth) 维度) | 定义为表非进度成长表(Rule 4 豁免);需要时走接口漂移加列,A4 先例 |
调参表
| 字段 | 域 | 默认 | owner | 说明 |
|---|---|---|---|---|
| attack_up.magnitude | percent ∈ [-100,100] 且 ≠0 | +50(provisional——原型 1.5× 换算占位) | B3 定稿;B4/B1 锚验收 | 条款 2 锚参照对象;消费面 = 主角战斗段先手攻击 |
| defense_up.magnitude | percent ∈ [-100,100] 且 ≠0 | −30(provisional——减伤墙批 C3 投值,原 −50) | B3 定稿;B4/B1 锚验收 | 叠满两层 −60 帽;禁独立调参(联动网络见下) |
| ambush.magnitude | flat ≥ 1 | +3(provisional——原型临时值) | B3 定稿;B2/B1 锚验收(条款 3) | 量纲已定稿(B2):每层每攻击类行为附加 m_amb 点主角 HP、后置加法、charge 拍零兑付 |
| weaken.magnitude | percent ∈ [-100,100] 且 ≠0 | −65(provisional,值域 [60, 85]——F0 裁决) | B3 定稿;终值 B4/B1 共裁 | 回执以 B1 GDD F0 为准(registry anchor_warning);越界即破条款 2 锚 |
| duration_settlements(四行) | int [1, 99] | 1/1/1/1(当次结算;provisional) | B3 | 一次性语义;窗口拉长 = 恢复跨轮延续(规划变简单、衰减感消失) |
| max_stack(四行) | int [1, 16] | 2/2/16/16(provisional) | B3 | 仅 stack 消费;调低 = 叠层机制边缘化(重复奖励变溢出浪费) |
- 非 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.magnitude/duration 已纳入"禁独立调参"联动网络(m_w↔D_ref↔m_d↔duration_d,与 B1 Knob 交互同口径);减伤墙批(−50→−30)即该联动的实证回调;defense_up 叠满 −60% = 当次结算 0.4× 承伤(消费读法归 B1);免伤轮现行可达路径 = weaken 饱和(见 F2)。
- 逐 knob 调过高/调过低的后果论证见推演件。
验收标准
测试口径
| 口径 | 要点 |
|---|---|
| 测试载体 | 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(调参表节)——各 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 且容器空(唯一出口——下一场战斗重启,实例状态表) |
| 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——无洞 |
版本历史
| 版本 | 日期 | 改动 |
|---|---|---|
| v2 | 2026-09-14 | 两件套迁移:按模板 v2 重排为 design(结论)+ analysis(推演)两件——公式推导与锚定论证、数值锚定过程、体验锚点论证、候选方案取舍、已裁决设计争议、开放问题(OQ1–7)与审计注记移入 design/gdd/analysis/b3-status-effect.md;速览/体验锚点/核心规则两段式重排为设计目的/系统范围/领域章节;零规则变更、零数值变更、AC/EC/F/义务编号全部保留 |
| 跨评审 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 跳过 |