From ec0bdde7e03a0c9d2b56e3de20e34588e565d6f0 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 15 Sep 2026 23:17:40 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=94=BB=E5=87=BB/=E6=8A=A4=E7=94=B2?= =?UTF-8?q?=E5=91=BD=E5=90=8D=E7=BB=9F=E4=B8=80=E4=B8=8E=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?-=E5=A5=96=E5=8A=B1=E6=8A=BD=E8=B1=A1=E5=88=86=E7=A6=BB?= =?UTF-8?q?=EF=BC=8C=E8=90=BD=E5=9C=B0=E6=A0=BC=E9=9D=A2=E8=B5=84=E6=BA=90?= =?UTF-8?q?=E6=89=B9=E5=B9=B6=E8=A1=A5=E9=AA=8C=E6=94=B6=E6=94=B6=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 命名统一:攻击类型 {base,dmg_a,dmg_b}->{normal,pierce,magic};护甲 {none,a,b}->{light,ward,heavy} - 抽象分离:攻击类型=伤害属性轴,充能投桶归奖励定义 charge_grants(开格/标中旗/踩雷/清图仅作触发源) - 格面资源批(文档+registry):段序七->五、行型 15->10、极性路由取代固定兑付、可选类道具删除 - 验收收口:registry/README/active 登记充能当量折算缺口与两处落差;playtest 陈旧键名注记订正 - 实跑:冒烟 201 项 0 失败,四探针 exit=0 无 FAIL --- CLAUDE.md | 2 +- design/gdd/03-内容规模.md | 2 +- design/gdd/systems/冒险循环/关卡节点地图.md | 8 +- design/gdd/systems/冒险循环/难度曲线与Boss.md | 22 +- design/gdd/systems/战斗循环/奖励道具经济.md | 304 +++++++----------- design/gdd/systems/战斗循环/战斗结算.md | 167 +++++----- design/gdd/systems/战斗循环/敌人系统.md | 8 +- design/gdd/systems/排雷循环/排雷玩法.md | 31 +- design/registry/entities.yaml | 115 ++++--- .../proposal-reward-polarity-2026-09-13.md | 11 + docs/doc-conventions.md | 30 +- .../playtests/playtest-2026-09-12-designer.md | 2 +- production/session-state/active.md | 6 +- .../dungeon-sweeper-vertical-slice/README.md | 58 +++- .../core/battle_orchestrator.gd | 80 +++-- .../core/damage_math.gd | 7 +- .../core/unit_container.gd | 2 +- .../data/schemas/enemy_table.gd | 11 +- .../data/schemas/settlement_table.gd | 42 +-- .../data/tables/enemy.tres | 19 +- .../data/tables/settlement.tres | 54 ++-- .../presentation/views/battle_log_view.gd | 6 +- .../presentation/views/enemy_card_view.gd | 10 +- .../smoke/auto_player.gd | 2 +- .../smoke/damage_probe.gd | 4 +- .../smoke/smoke_all.gd | 62 ++-- 26 files changed, 586 insertions(+), 479 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index c15cbdfc..fe473215 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -41,7 +41,7 @@ - **fail-fast**:数据校验错误一律致命中止,无软回退(D2 Rule 6) - **spec-AC 一致性**:规约与验收标准不得在同一输入上给出不同答案——D2 两轮评审确立的阻塞标准,所有 GDD 同尺度 - GDD 评审纪律:`/design-review` 必须在独立会话跑(与 `/design-system` 隔离) -- **文档写作规范(2026-09-14 成文,写任何文档前必读)**:在编写、修改任何设计文档之前,必须先通读 `docs/doc-conventions.md`(全文权威——整合原用语纪律〔2026-09-09〕、文档形态纪律〔2026-09-13〕、两件套与树形文档体系纪律〔2026-09-14〕、新骨架过渡口径〔2026-09-14〕,并新增可读性第一纪律)。要点:**可读性第一**——读者测试三问(管的是谁/什么?什么情况下?会发生什么?)答不出就重写该节;白话完整句、散文讲道理、表格放数据;禁自造黑话(唯一例外 = 玩家可见专属名词);树形文档体系,文档增删必须同步根索引 `design/gdd/02-系统清单.md`;节点一页纸以内;每个子系统一份设计文档、不建 analysis 推演件;正文只写现行规则,修订只进文末「版本历史」表;跨文档引用纪律(单点定义 / 规范名唯一 / 引用不转述 / 反向边登记 / 删除概念 SOP)见该文第 7 节;已锁数值事实源 = `design/registry/entities.yaml` 与 `data/tables/`。旧体系 lean 格式与 `gdd_lint` 门禁仅用于解读归档(`design/archive/gdd-2026-09-14/`),不约束现行文档。 +- **文档写作规范(2026-09-14 成文,写任何文档前必读)**:在编写、修改任何设计文档之前,必须先通读 `docs/doc-conventions.md`(全文权威——整合原用语纪律〔2026-09-09〕、文档形态纪律〔2026-09-13〕、两件套与树形文档体系纪律〔2026-09-14〕、新骨架过渡口径〔2026-09-14〕,并新增可读性第一纪律)。要点:**可读性第一**——读者测试三问(管的是谁/什么?什么情况下?会发生什么?)答不出就重写该节;白话完整句、散文讲道理、表格放数据;禁自造黑话(唯一例外 = 玩家可见专属名词);树形文档体系,文档增删必须同步根索引 `design/gdd/02-系统清单.md`;节点一页纸以内;每个子系统一份设计文档、不建 analysis 推演件;正文只写现行规则,修订只进文末「版本历史」表;概念封装纪律(概念即对象 / 属性归属唯一 / 包含关系显式 / 状态用枚举 / 附加物独立成对象)见该文第 7 节,跨文档引用纪律(单点定义 / 规范名唯一 / 引用不转述 / 反向边登记 / 删除概念 SOP)见该文第 8 节;已锁数值事实源 = `design/registry/entities.yaml` 与 `data/tables/`。旧体系 lean 格式与 `gdd_lint` 门禁仅用于解读归档(`design/archive/gdd-2026-09-14/`),不约束现行文档。 ## 代码规范(写代码前必读,2026-09-11 用户拍板成文) diff --git a/design/gdd/03-内容规模.md b/design/gdd/03-内容规模.md index e8bd3f7d..1824c091 100644 --- a/design/gdd/03-内容规模.md +++ b/design/gdd/03-内容规模.md @@ -23,7 +23,7 @@ MVP 做到两关:第二层不新造结构,与第一层共用节点链模板 | 熊地精 | 主力,可成群 | 攻击 → 蓄力 → 重击三拍循环 | | 食人魔酋长 | 第一关 Boss,单个 | 攻击 → 攻击 → 蓄力 → 重击四拍循环 | -每种敌人配一档护甲(无甲 / 甲A / 甲B),正好构成"无甲 → 甲A → 甲B"的教学梯度。MVP 不加新敌种,也不做同深度多敌种混搭。 +每种敌人配一档护甲(轻甲 / 魔法护甲 / 重甲),正好构成"轻甲 → 魔法护甲 → 重甲"的教学梯度。MVP 不加新敌种,也不做同深度多敌种混搭。 ## 棋盘 diff --git a/design/gdd/systems/冒险循环/关卡节点地图.md b/design/gdd/systems/冒险循环/关卡节点地图.md index 149cb2a0..4dc34cd0 100644 --- a/design/gdd/systems/冒险循环/关卡节点地图.md +++ b/design/gdd/systems/冒险循环/关卡节点地图.md @@ -30,7 +30,7 @@ |---|---| | 关卡序列与链上有哪些节点(链模板、关数) | [冒险结构](冒险结构.md) | | 关卡大奖励、跨关血量账本、失败重开 | [冒险结构](冒险结构.md) | -| 节点奖励与安全格奖励的内容、库存语义 | [奖励道具经济](../战斗循环/奖励道具经济.md) | +| 节点奖励与格面资源的内容语义 | [奖励道具经济](../战斗循环/奖励道具经济.md) | | 战斗内的结算编排、胜负判定、伤害合成 | [战斗结算](../战斗循环/战斗结算.md) | | 敌人表数据、行为环、开战时按坐标生成单位 | [敌人系统](../战斗循环/敌人系统.md) | | 敌我数值曲线与遭遇投放节奏 | [难度曲线与Boss](难度曲线与Boss.md) | @@ -88,7 +88,7 @@ | 名字 | 指什么 | 归属 | |---|---|---| | 节点奖励 | 奖励点节点给的奖励 | 本文域(机制待设计) | -| 安全格奖励 | 雷图上挖开安全格开出的奖励 | [奖励道具经济](../战斗循环/奖励道具经济.md) | +| 格面资源 | 雷图上格子关联的资源对象(安全格与雷格同池携带,极性由动作决定) | [奖励道具经济](../战斗循环/奖励道具经济.md) | | 节点奖励覆盖层 | 节点奖励的呈现候选形态 | 呈现侧候选,未定稿 | ## 依赖与输出 @@ -98,7 +98,7 @@ | 方向 | 系统 / 文档 | 接口要点 | |---|---|---| | 上游 / 下游 | [冒险结构](冒险结构.md) | 接口契约四件套(开始关卡 / 战斗结果上报 / 治疗封顶回报 / 关卡结束):向下接开始关卡,向上报战斗结果、恢复请求与关卡结束 | -| 上游 | [奖励道具经济](../战斗循环/奖励道具经济.md) | 节点奖励入库:兑付触发归本文,内容与库存语义归它 | +| 上游 | [奖励道具经济](../战斗循环/奖励道具经济.md) | 节点奖励兑付:兑付触发归本文,内容语义归它(库存已随可选类删除下线;未来功能道具的候选渠道之一,见其待拍板) | | 上游 | [敌人系统](../战斗循环/敌人系统.md) | 遭遇坐标的消费方:本文交出坐标,按坐标生成单位归它 | | 上游 | [难度曲线与Boss](难度曲线与Boss.md) | 敌我数值曲线与遭遇投放节奏的调参所有权 | | 下游 | [战斗结算](../战斗循环/战斗结算.md) | 本文是两个调用入口的发起方:战斗发起组装、关卡收束(清库) | @@ -122,7 +122,7 @@ | 优先级 | 内容 | 后置原因 | |---|---|---| | P1 | 遭遇构成细则(哪个节点放哪种遭遇、数量怎么定) | 依赖敌人表键结构的改键裁决(见待拍板);投放节奏的调参所有权归难度曲线与Boss | -| P1 | 节点奖励机制设计 | 名字已拍板、机制未设计;与奖励道具经济的入库接口对齐后展开 | +| P1 | 节点奖励机制设计 | 名字已拍板、机制未设计;与奖励道具经济的兑付接口对齐后展开;用户已定方向(2026-09-15)——长周期功能道具经其他渠道加入,节点奖励为候选渠道 | | P2 | 路径分支地图 | 已拍板后置([不做清单](../../05-不做清单.md)):分支是加分项,当前体量撑不起有意义的岔路 | | P2 | 精英节点与精英遭遇 | 与分支地图联动设计,随精英与 Boss 编码位改键同批 | diff --git a/design/gdd/systems/冒险循环/难度曲线与Boss.md b/design/gdd/systems/冒险循环/难度曲线与Boss.md index 40554a8f..c9bf4557 100644 --- a/design/gdd/systems/冒险循环/难度曲线与Boss.md +++ b/design/gdd/systems/冒险循环/难度曲线与Boss.md @@ -143,9 +143,9 @@ Boss 战的棋盘用本关最大板形(第一关为 12×12),板参数仍 ### 护甲克制:本文锁行值,矩阵本体归战斗结算 -三个首发敌种各配一档护甲类型——地精无甲、熊地精甲、食人魔酋长重甲——构成"无甲 → 甲 → 重甲"的教学梯度:玩家的克制手段随进度逐关解锁。 +三个首发敌种各配一档护甲类型——地精轻甲、熊地精魔法护甲、食人魔酋长重甲——构成"轻甲 → 魔法护甲 → 重甲"的教学梯度:玩家的克制手段随进度逐关解锁。 -伤害类型对护甲类型的克制倍率矩阵(克制 150% / 无甲 100% / 被对位克制 50%,provisional)是[战斗结算](../战斗循环/战斗结算.md)的甲效表,哪个分量克哪档护甲由它定义,本文不重复。本文只锁两件事:敌种的护甲类型行值(见调参表),以及这份矩阵数值的调参所有权在本系统——敌种护甲变更必须复算 Boss 与普通战的击杀区间。 +攻击类型对护甲类型的克制倍率矩阵(克制 150% / 中性 100% / 被克 50%,provisional)是[战斗结算](../战斗循环/战斗结算.md)的甲效表,哪个攻击类型克哪档护甲由它定义,本文不重复。本文只锁两件事:敌种的护甲类型行值(见调参表),以及这份矩阵数值的调参所有权在本系统——敌种护甲变更必须复算 Boss 与普通战的击杀区间。 ### 调参联动:禁独立调参网络与对账重跑义务 @@ -158,7 +158,7 @@ Boss 战的棋盘用本关最大板形(第一关为 12×12),板参数仍 | 密度 ↔ 可推理率 ↔ 生成尝试上限 | [棋盘生成](../排雷循环/棋盘生成.md) | 三元组联动;禁止为难度牺牲可推理率绝对锚 | | 每轮行动点 ↔ 停手转存规模 | [行动经济](../排雷循环/行动经济.md) | 联动评估记录归本文,调参所有权在行动经济 | | 削弱强度 ↔ 当量锚 | [增益状态](../战斗循环/增益状态.md)、[战斗结算](../战斗循环/战斗结算.md) | 联动值禁独立调参,修订须重跑锚对照 | -| 护甲类型 ↔ 充能分量 ↔ 克制矩阵 | [战斗结算](../战斗循环/战斗结算.md) | 敌种护甲变更须复算击杀区间 | +| 护甲类型 ↔ 充能奖励(投桶与量) ↔ 克制矩阵 | [战斗结算](../战斗循环/战斗结算.md) | 敌种护甲变更须复算击杀区间;改充能的投桶或量属奖励侧改动,须重跑本表数值 | 五条经济契约的对账由[战斗结算](../战斗循环/战斗结算.md)闭合验收,其中挖掘风险不等式与清图支配性两条的现行验算已破线或存在缺口(现状见其「待拍板」),重跑义务落在本系统的下一次调参批执行——这是本系统当前最优先的调参义务。完美排雷乘数的调参权在本系统。 @@ -214,12 +214,12 @@ Boss 战的棋盘用本关最大板形(第一关为 12×12),板参数仍 | 坐标 | 敌种(数据键) | 生命 | 攻击(浮动区间) | 数量 | 行为环 | 护甲 | |---|---|---|---|---|---|---| -| 第一关 D0(教学位) | 地精 goblin | 24 | 7 [4,10] | [1,2] | 攻击 | 无甲 | -| 第一关 D1 | 地精 goblin | 13 | 5 [2,8] | [2,3] | 攻击 | 无甲 | -| 第一关 D2(首遇固定) | 熊地精 bugbear | 40 | 9 [6,12] | 1 | 攻击/蓄力/重击 | 甲 | -| 第一关 D3 | 熊地精 bugbear | 18 | 6 [3,9] | [2,3] | 攻击/蓄力/重击 | 甲 | +| 第一关 D0(教学位) | 地精 goblin | 24 | 7 [4,10] | [1,2] | 攻击 | 轻甲 | +| 第一关 D1 | 地精 goblin | 13 | 5 [2,8] | [2,3] | 攻击 | 轻甲 | +| 第一关 D2(首遇固定) | 熊地精 bugbear | 40 | 9 [6,12] | 1 | 攻击/蓄力/重击 | 魔法护甲 | +| 第一关 D3 | 熊地精 bugbear | 18 | 6 [3,9] | [2,3] | 攻击/蓄力/重击 | 魔法护甲 | | 第一关 D4(Boss) | 食人魔酋长 ogre_chief | 150 | 9 [6,12] | 1 | 攻击/攻击/蓄力/重击 | 重甲 | -| 第二关 D0(锚行) | 熊地精 bugbear | 30 | 7 [4,10] | 1 | 攻击/蓄力/重击 | 甲 | +| 第二关 D0(锚行) | 熊地精 bugbear | 30 | 7 [4,10] | 1 | 攻击/蓄力/重击 | 魔法护甲 | 重击倍率全员 2(provisional);单轮伏击授予上限 4(已定稿)。攻击浮动开战时掷定一次、整战持久;数量区间同流掷定,教学位(地精 ×[1,2])与首遇位都不豁免——没有区间上界的行自然取定值,那不是豁免,是区间宽度为零。 @@ -236,9 +236,9 @@ Boss 战的棋盘用本关最大板形(第一关为 12×12),板参数仍 | 参数 | 现行值 | 说明 | |---|---|---| | 血量锚比率 r_boss | 0.98(带内) | 带 [0.5, 1.1];加难走廊 [1.1, 1.35] 待扫描 | -| 伤害A(开格充能)每格 / 单轮封顶 | 1 / 8 | 充能机制归[战斗结算](../战斗循环/战斗结算.md) | -| 伤害B(标中充能)每雷 | 2 | 同上 | -| 克制矩阵 | 克制 150 / 无甲 100 / 被对位克制 50 | 消费归[战斗结算](../战斗循环/战斗结算.md) | +| 开格充能(现投穿刺桶)每格 / 单轮计数上限 | 1 / 8 | 充能奖励定义归[战斗结算](../战斗循环/战斗结算.md);投哪个桶是奖励内容,可改 | +| 标中充能(现投魔法桶)每雷 | 2 | 同上 | +| 克制矩阵 | 克制 150 / 中性 100 / 被克 50 | 消费归[战斗结算](../战斗循环/战斗结算.md) | | 完美排雷乘数 | 200(翻倍) | 调参权本文 | | 当量参考敞口 | 12 | 变更触发全量对账重跑 | | 注入概率初值 / 衰减 | 0.4 / 0.5(加难候选 0.6) | 注入机制归[奖励道具经济](../战斗循环/奖励道具经济.md) | diff --git a/design/gdd/systems/战斗循环/奖励道具经济.md b/design/gdd/systems/战斗循环/奖励道具经济.md index 70bbc69a..687f9b24 100644 --- a/design/gdd/systems/战斗循环/奖励道具经济.md +++ b/design/gdd/systems/战斗循环/奖励道具经济.md @@ -1,37 +1,39 @@ # 奖励道具经济 -> 一句话:奖励产出、道具库存与使用窗口 +> 一句话:格面资源的产出、极性字典与清图奖励封装 > 状态:已定稿(自旧体系迁移) > 旧版参考:../../../archive/gdd-2026-09-14/b4-reward-item-economy.md ## 设计目的 -奖励道具经济是战斗域的奖励层:挖开的格子给什么、值多少、什么时候发、发到哪去,由它统一裁决。世界观上,奖励是前人探险者遗落在地牢里的物件——玩家在淘东西,不是在领系统发放的补偿。它守住三件事:每张图的每格都有货可淘(结构保证,不靠逐次掷运气);好东西留给会规划的人(可选类道具是整个关卡的资产);发出去的每一样都能在结算明细里指回挖开的哪一格。缺了这一层,挖格没有收益语言,"扫雷攒因、战斗结果"的兑现就断在最后一环。 +奖励道具经济是战斗域的资源层:每张雷图上每个格子携带什么资源、资源怎么摇定、正向与负向各兑付成什么效果、清图时整张板发什么,由它统一裁决。核心抽象是**格面资源(CellResource)**——关联到格子上的资源对象:装板时摇定类型身份,安全格与雷格一视同仁、同一类型池;资源本身不分好坏,被当成奖励还是惩罚,由玩家对这一格做的动作在结算期决定——开安全格、标中雷是正向,开雷格、标错安全格是负向(极性矩阵的定义归本文,路由执行归[战斗结算](战斗结算.md))。开局初始展开白送的那批格是**封锁格**——恒无资源,不再有任何加成(定义见[排雷玩法](../排雷循环/排雷玩法.md))。 + +它守住三件事:每个非封锁格都有资源可兑(结构保证,不靠逐次掷运气);类型身份在装板期一次摇定、全程只读(在"数字恒真"的推理之外,类型是第二层规划素材);每个兑付都能在结算明细里指回挖开的哪一格。缺了这一层,挖格没有收益语言,"扫雷攒因、战斗结果"的兑现就断在最后一环。 + +(批注:系统名"奖励道具经济"沿袭可选类道具时代,道具已删除,名实不符——更名候选见「待拍板」。) ## 系统范围 -边界这样划:本系统管"奖励是什么、身份怎么摇定、怎么入库、玩家什么时候能用";发奖与兑付的编排归[战斗结算](战斗结算.md),增益本体归[增益状态](增益状态.md),画成什么样归[HUD 框架](../表现与支撑/HUD框架.md)。本系统零界面、除摇号外零随机:同一串操作驱动两个实例,结果逐位相同。 +边界这样划:本系统管"资源是什么、身份怎么摇定、正向负向各兑付什么、清图对象怎么配";发奖与兑付的编排归[战斗结算](战斗结算.md),增益本体归[增益状态](增益状态.md),画成什么样归[HUD 框架](../表现与支撑/HUD框架.md)。本系统零界面、除摇号外零随机:同一串操作驱动两个实例,结果逐位相同。 负责: | 负责 | 说明 | |---|---| -| 奖励类型封闭枚举 | 五种类型(三种即时、两种可选);表里出现清单外的类型,数据加载直接拒绝 | -| 装板期身份预分配 | 每张图装上时一次摇定全部格子身份与清图身份;只读、无重摇 | -| 奖励表与奖励配置表 | 两张数据表的承载归[数据配置](../表现与支撑/数据配置.md),内容由本系统回填 | -| 可选类供给 | 战斗首件保证加按实际获取件数递减注入;另有按板保底断言(现行默认关闭) | -| 关卡域库存 | 伤害道具与强效治疗包的背包:入库、查询、窗口选用消耗、关卡末清空 | -| 窗口数据面 | 库存投影与"现在用有没有效果"的可用性预判组装;窗口本身的编排归战斗结算 | +| 格面资源类型封闭枚举 | 五型(attack / defense / heal / blast / weaken);表里出现清单外的类型,数据加载直接拒绝 | +| 装板期身份预分配 | 每张图装上时一次摇定全部非封锁格的资源类型身份与清图奖励对象身份;只读、无重摇 | +| 极性矩阵与五型字典 | 「动作 × 格型 → 正负号」的定义,以及每型正向 / 负向各兑付成什么效果 | +| 清图奖励对象 | 板级作用域的独立奖励封装,可配置可替换,按图类型差异化 | +| 未来功能道具的预留结构位 | 长周期、更强力的功能性道具经其他渠道加入;渠道设计未定,本系统只留结构位不预写 | 不负责: | 不负责 | 归谁 | |---|---| -| 结算段序与逐行兑付编排 | [战斗结算](战斗结算.md) | +| 结算段序与逐行兑付编排、极性路由执行 | [战斗结算](战斗结算.md) | | 增益的叠层、衰减与时限 | [增益状态](增益状态.md) | | 敌人数据、目标顺位与血量查询 | [敌人系统](敌人系统.md) | -| 棋盘侧的奖励资格事实 | [排雷玩法](../排雷循环/排雷玩法.md)(经战斗结算转化,两系统无直接接口) | -| 辅助道具的背包与使用 | [辅助道具](../排雷循环/辅助道具.md) | +| 棋盘侧的资源资格事实 | [排雷玩法](../排雷循环/排雷玩法.md)(经战斗结算转化,两系统无直接接口) | | 节点奖励与关卡大奖励 | [关卡节点地图](../冒险循环/关卡节点地图.md)与[冒险结构](../冒险循环/冒险结构.md) | | 数值投值与曲线 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | | 表结构定义与加载机制 | [数据配置](../表现与支撑/数据配置.md)(本系统只回填内容) | @@ -40,147 +42,85 @@ ## 在核心循环中的位置 ``` -装板 ──(一次摇号定全图身份)──▶ 挖掘期(身份恒定可读,只揭晓不发奖)──▶ 轮末授予段 ──▶ 道具使用窗口 ──▶ 道具段 ──▶ 战斗段 +装板 ──(一次摇号定全图资源身份 + 清图对象)──▶ 挖掘期(身份恒定可读,只揭晓不兑付)──▶ 轮末授予段(极性路由逐格兑付)──▶ 战斗段 ``` -本系统横跨挖掘期与轮末结算的头部:装板时全图奖励身份一次摇定;挖掘期只揭晓身份,轮末授予段(结算里逐格发放奖励的段落)把当轮拾取兑现——即时类当场生效,可选类进背包等玩家在窗口里挑时机。授予段与窗口之后的段序编排归[战斗结算](战斗结算.md)。 +本系统横跨挖掘期与轮末结算的头部:装板时全图资源身份一次摇定;挖掘期只揭晓身份,轮末授予段(结算里逐格兑付的段落)按极性矩阵把当轮的因兑现——正向当场生效,负向也当场生效(负向恒即时,无库存语义)。段序编排归[战斗结算](战斗结算.md)。 ## 核心规则 -### 装板期一次摇号:每格必有货,身份绝不翻悔 +### 格面资源:每个非封锁格都带一个,摇号纪律不变 -每张雷图装上时——玩家挖第一下之前——本系统对这张图做且只做一次摇号(像开奖一样一次摇定全部身份):按固定顺序给图上所有够格出奖励的格子逐一摇出各自带什么,同一次摇出清图奖励(开完全部安全格时发的那份),写进这张图的身份映射表(哪格带什么货的对照表)。 +每张雷图装上时——玩家挖第一下之前——本系统对这张图做且只做一次摇号:给图上全部非封锁格逐一摇出资源类型,同一次摇出清图奖励对象的身份(见清图一节),写进这张图的资源映射表。安全格与雷格一视同仁:同一类型池、同一权重分布,不存在"只给谁分配"的分支。封锁格(初始展开白送格)恒无资源——摇号清单里根本没有它们。 -随机只发生在这一次摇号里:之后挖到哪格只是揭晓早已定好的身份,发奖、用道具都不再掷任何骰子。"每格必有货"因此是结构保证——不存在逐次重掷,也不存在查询时现算。部分奖励行的威力是区间值,具体数值也在这次摇号里一并摇定,之后恒定不变。 - -够格出奖励的是挖格事件里带奖励资格事实的安全格;开局初始展开白送的格子恒不带货(见[排雷玩法](../排雷循环/排雷玩法.md))。没挖开的格子在界面上不显示里面是什么——这是[不做清单](../../05-不做清单.md)的裁定;结构上身份已定、随时可查,预读类道具桥接的边界登记于待拍板。 +随机只发生在这一次摇号里:之后挖到哪格只是揭晓早已定好的身份,兑付不再掷任何骰子。部分行的威力是区间值,具体数值也在这次摇号里一并摇定,之后恒定不变。没挖开的格子在界面上不显示里面是什么——这是[不做清单](../../05-不做清单.md)的裁定;结构上身份已定、随时可查,预读类道具桥接的边界登记于待拍板。 | 摇号纪律 | 含义 | |---|---| | 恰一次 | 新图装好后、开挖前摇一次;已摇过的图再调摇号直接拒绝 | -| 专属随机流 | 摇号消费一条名为 reward_roll 的专属随机数流,与其他系统的随机互不干扰;同种子同操作序列必然摇出同一张身份表,可逐位回放 | -| 只读无重摇 | 映射就绪后只读;"重摇一下"的接口不存在,要加就是修订本文档,不是调参数 | +| 专属随机流 | 摇号消费一条名为 reward_roll 的专属随机数流;同种子同操作序列必然摇出同一张身份表,可逐位回放 | +| 只读无重摇 | 映射就绪后只读;"重摇一下"的接口不存在,要加就是修订本文档 | +| 雷安同池 | 安全格与雷格从同一类型池摇定(类型频次 = 该型正向行的权重);分布按格型差异化若未来需要,走本文修订 | ``` -装板 ──▶ 一次摇号(格子批 + 清图批尾)──▶ 只读映射(同图跨轮不变) -换图或战斗结束 ──▶ 映射随之失效:未拾取的身份一并丢弃,不发奖、不进结算 +装板 ──▶ 一次摇号(全部非封锁格的类型批 + 清图对象批尾)──▶ 只读映射(同图跨轮不变) +换图或战斗结束 ──▶ 映射随之失效:未兑付的身份一并丢弃,不发奖、不进结算 ``` 举证:本节为流程与状态规则,无计算。 -### 两级奖励:即时类当场兑现,可选类入包择时 +### 极性矩阵:动作与格型决定符号 -奖励系统发出的一切只从五种类型里出,按交付方式分两级:即时类在发奖那一刻当场兑现,不进背包、不用玩家选,默认占大头;可选类更强,先放进关卡背包,由玩家在道具使用窗口自己挑时机用,占小头。玩家看到的包装是"前人探险者的遗落物";宝箱一类呈现只绑定可使用道具类奖励(归 HUD 框架)。 +资源对象只带类型,不带正负。正负号在结算期由「玩家动作 × 格型」决定——这张矩阵是全部奖励与惩罚的统一路由,取代旧体系的四套固定兑付(踩雷固定伏击、标中固定削弱、标错三选一反噬、可选类道具注入): -| 类型 | 级别 | 玩家拿到什么 | 兑付方式 | -|---|---|---|---| -| 临时增益 | 即时 | 一层增伤或减伤 | 授予段当场挂进[增益状态](增益状态.md)的容器,只活当次结算;叠层已满则这份奖励不生效 | -| 群体伤害 | 即时 | 全体存活敌人各吃一笔固定伤害 | 当场逐个兑现,受击即死;场上没有存活敌人则零兑付 | -| 小额治疗 | 即时 | 主角小额回血,不超上限 | 当场回血;满血时零兑付 | -| 伤害道具(俗称"刀") | 可选 | 更强、可囤可择时的伤害件 | 入关卡背包,窗口选用后在道具段按固定顺位打敌 | -| 强效治疗包 | 可选 | 稀缺的强治疗 | 入关卡背包,窗口选用回血;满血时禁选、不消耗 | +| 玩家动作 | 安全格 | 雷格 | +|---|---|---| +| 开格 | **+类型**:该格资源的正向兑付(奖励) | **−类型**:该格资源的负向兑付(惩罚) | +| 标旗且留到轮末判定 | **−类型**:标错,该格资源的负向兑付(惩罚) | **+类型**:标中,该格资源的正向兑付(奖励) | +| 标旗后当轮撤旗 | 零兑付(行动点已耗 = 变相惩罚,行动经济承载) | 零兑付(同左) | -设计意图:可选类数量少但更强;治疗整体供给变少、决策价值变高——治疗是稀缺奖励。类型清单是封闭的:想加第六种类型等于修订本文档,不是调参数。 +矩阵的定义归本文;把矩阵跑起来的路由(结算队列、抵消过滤、逐行兑付)归[战斗结算](战斗结算.md)的授予段。旧"踩雷→伏击"是本矩阵的退化特例(所有雷同一类型的世界);伏击保留为 blast 型的负向一行。 -凡"发了但没生效"——增益挂满层、满血捡到即时治疗、场上无敌可打——一律在结算明细里明写一行"奖励未生效",不给任何折算补偿,也不静默消失。把拾取的奖励改成即时生效同样在禁止之列:绕过轮末结算的统一兑付,玩家就指不出"这个果是哪步因结出来的"。 +举证:本节为枚举与路由定义,无计算。 + +### 五型字典:每型一行正向一行负向 + +格面资源的一切兑付从五个类型里出,每个类型恰好一行正向、一行负向——正向是玩家操作正确时拿到的东西,负向是操作失误或踩雷时吃到的东西: + +| 类型 | 正向(奖励) | 负向(惩罚) | +|---|---|---| +| attack 增伤 | attack_up 增伤 +50%(hero_offense 池) | enrage 敌方暴走 +25%(enemy_output 池) | +| defense 减伤 | defense_up 减伤 −30%(hero_defense 池) | off_guard 我方失衡 +25%(hero_defense 池,承伤加深) | +| heal 回血 | heal_minor 回血 2–6(满血零兑付照旧) | 直伤:主角 −4(战斗结算直接扣血,不经增益状态) | +| blast 群伤 | spark_aoe 全体存活敌各 −4 | ambush 敌方伏击 +2 层(进伏击池) | +| weaken 削弱 | weaken 敌方输出 −65%(enemy_output 池) | sapped 我方乏力 −25%(hero_offense 池) | + +设计意图:读敌拍板的路线规划——敌方要放大招时抢减伤、怪重叠时抢削弱,惩罚侧则镜像同一批类型。类型清单是封闭的:加第六型等于修订本文档,不是调参数。 + +凡"该兑付但没生效"——增益挂满层、满血捡到 heal 正向、场上无敌可打——一律在结算明细里明写一行"奖励未生效",不给折算补偿,也不静默消失。把兑付改成跳过轮末结算直接生效,同样在禁止之列。 举证:本节为类型枚举与兑付语义,无计算。 -### 道具使用窗口:当轮拾取当轮可用,一次只选一件 +### 负向恒即时:惩罚没有库存语义 -每轮结算发完全部奖励之后、增益减益结算之前,弹出道具使用窗口:背包里有可选类道具时,玩家至多选用一件用掉,或者跳过。当轮刚捡的刀当轮就能用,不必等到下一轮。 +负向兑付全部在授予段当场执行,不入库、不出窗口——惩罚不设库存、不留存量。正向里的 percent 类(增益行)进[增益状态](增益状态.md)的容器;flat 类(群伤、治疗、直伤)当场结算。叠层饱和由战斗结算既有池 clamp 承载;blast 负向(伏击)额外受[敌人系统](敌人系统.md)的伏击上限护栏约束,溢出照既有"溢出未生效"行协议。负向直伤使主角生命归零时,结算按战斗结算的致死短路规则处理。 -``` -授予段(发放奖励,即时类当场兑付) - ──▶ 道具使用窗口(至多选一件,或跳过) - ──▶ 增益减益段 ──▶ 道具段(选用件在此生效)──▶ 战斗段 -``` +举证:本节为兑付语义,无计算。 -| 窗口规则 | 含义 | -|---|---| -| 单件制 | 一次窗口至多选用一件;想一次用多件是改规则,不是调参数 | -| 可用性预判 | "现在用有没有效果"随窗口数据一起呈现:满血时治疗包直接禁选并说明原因;守卫判定归[战斗结算](战斗结算.md),禁选件不会被消耗 | -| 跳过恒合法 | 不选任何东西永远合法;背包为空时窗口可以整个不弹(呈现归 [HUD 框架](../表现与支撑/HUD框架.md)) | -| 用掉不可逆 | 选定即承诺:同一件道具不能选第二次;已选的刀即使出手时已无存活敌人,也照常消耗并记"已消耗未生效"行 | +### 清图奖励对象:板级封装,可配置可替换 -道具段排在战斗段之前,这造就了本作标志性的择时:先把敌人削进"死亡即不动手",敌人的重击就永远不会落地——"重击拍前用刀"由此成立。窗口里玩家的每次选择还会记入结算回放:重放一场战斗时,窗口选了什么和挖了哪格一样是输入的一部分。 +清图奖励不属于任何一格的格面资源——它是作用域为整张板的独立奖励对象:把一张图的雷全部清完(全部安全格开完)时结算发的那一份。装板摇号时与格子资源同批判尾摇定身份;清图批兑付恰好一次;完美排雷(零误标且至少标中一面旗)追加第二份同身份兑付。 -举证:本节为窗口流程与守卫规则,无计算。 - -### 库存是关卡的资产:跨战斗延续,关卡末清空 - -可选类道具的背包属于整个关卡,不属于某一场战斗:换了地图、打完一场战斗,包里的东西都还在;整个关卡打完——无论输赢——才一次性清空。"囤刀待机、看准整个关卡里最好的时机再拍"因此成立:可选类道具是关内资产,不是"这场不花就没了"的消耗品。 - -| 库存规则 | 含义 | -|---|---| -| 来源可归因 | 每件道具记着从哪个格子的哪一轮捡到,结算能指回具体的因 | -| 数量无上限 | 稀缺感靠掉落权重控制,不靠背包容量;囤积是合法策略 | -| 清空恰一次 | 关卡结束由上层编排清空一次,重复清空被拒绝;清空伴随可见反馈(呈现归 HUD 框架) | - -``` -授予入库 ──▶ 在库(跨轮、跨图、跨战斗延续) - 窗口选用 ──▶ 已用(不可逆,仍可只读查询) - 关卡结束(无论输赢)──▶ 在库与已用全部清空 -``` - -战斗道具背包与辅助道具背包是两个正交容器:互不混装,寿命相同(都活到关卡结束)。辅助道具那一侧的背包与使用规则归[辅助道具](../排雷循环/辅助道具.md),本文只管自己这一侧。 - -举证:本节为生命周期规则,无计算。 - -### 恒定表值:刀是刀,增益是增益 - -道具的伤害与治疗是固定表值,不吃任何百分比增减益修正;增攻类增益只乘主角的基础攻击,永远不乘刀。增益叠得再厚,一把刀还是打它表上写的那个数——这条原则防的是乘法叠加失控,也让每个数字可学:玩家见过一次,就永远知道这把刀有多疼。 - -**结论**:道具伤害恒等于表值;治疗不超过血量上限;增攻只作用于基础攻击。 - -``` -伤害道具:D = power(恒定表值) -治疗: hp' = min(hp + power, max_hp) -增攻收益:基础攻击 × (1 + 增幅) ← 唯一消费面是主角先手攻击,不乘刀 -``` - -| 变量 | 含义 | 来源 | -|---|---|---| -| power | 道具威力,表值而非掷出的值 | 奖励表(区间行在摇号时已定具体值) | -| hp / max_hp | 主角当前血量与血量上限 | [敌人系统](敌人系统.md)的查询面 | - -满血使用治疗包被拒绝且不消耗——守卫拦在扣道具之前;缺血少于回复量时部分回复合法,超出上限的部分舍去。伤害道具的目标是固定顺位最前的存活敌人(顺位归[敌人系统](敌人系统.md)),一次性消耗。 - -### 清图奖励必发,首件保底,加载兜底 - -把一张图的雷全部清完时,结算发一份清图奖励:身份早在装板摇号时与格子奖励同批摇好。"清图奖励大于零"是数据加载时强制保证的——奖池里至少要有一行有实际价值的内容,不存在空奖。可选类道具的供给由机制保证而非格子概率:首场战斗内玩家拿到第一件之前每张新图必注入一件,之后注入概率随本战斗实际获取件数递减。 +它是可配置可替换的封装:数据面上是清图池里的一行(现行默认槽 clear_default),换行即换内容,机制零改动。按图类型差异化已留结构位——`clear_<图类型>` 命名空间预留,不同地图类型可以配不同的清图奖励;启用等[棋盘生成](../排雷循环/棋盘生成.md)的图类型词表落定。 | 清图奖励规则 | 含义 | |---|---| -| 恒非空 | 清图奖池加载时校验至少一行有实际价值(伤害不小于 1,或增益引用非空),违例加载致命 | -| 可含即时增益 | 清图槽允许放增益行;兑付时若已满层,零兑付并记"奖励未生效"行(合法例外) | -| 图类型差异化是预留插槽 | 现行只有默认槽;按图类型换奖池的结构位已留,待[棋盘生成](../排雷循环/棋盘生成.md)的图类型词表落定后启用 | +| 恒非空 | 清图池加载时校验至少一行有实际价值,违例加载致命 | +| 批尾摇定 | 身份在装板摇号批的尾部摇出,与格子资源同流同批 | +| 可配置可替换 | 内容 = 池行值;允许即时类(当场兑付,不入库) | +| 图类型差异化是预留插槽 | 现行只有默认槽;结构位已留,启用走棋盘生成词表落定 | -可选类供给:基础刀、进阶刀、强效治疗包三行不进格子权重池,由供给机制注入——注入判定是装板摇号批的一部分:在格子身份与清图槽摇定之后追加一次判定,命中则从本图资格格里均匀随机选一个,**覆盖**它刚摇出的即时类身份、换成注入池摇出的一件可选类(被覆盖的即时身份就此作废,不补摇)。标定目标是平均每场战斗约获得一件,全部 provisional,投值归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)。 - -注入概率随获取件数递减,不随图数递减:每场战斗开始时"已获取件数"清零;本战斗尚未获取过可选类时,每张新图必注入一件(首件保证);已实际获取 j 件时,每张新图的注入概率 = 0.4 × 0.5^(j−1)(j = 本战斗已实际获取件数),概率永不为零。"发放即获取":件数只在可选类实际发放(授予段或节点奖励入账)时加一;注入进图却没被挖到的格子不计数——所以没拿到新件,下一张图的概率不衰减,仍按当前件数的那一档掷。这条语义同时是诚实的另一面:首件保证承诺的是"必注入",不是"必到手"——注入格没被挖开,战斗结束也不补发(名义值与实际期望的落差登记于待拍板)。 - -**结论**:注入判定在装板摇号批内恰一次;注入概率 p(j) = p₀ × d^(j−1),j = 本战斗已实际发放的可选类件数。 - -``` -j = 0(未获取)→ p = 1(必注入) -j ≥ 1 → p = p₀ × d^(j−1)(现行 p₀ = 0.4、d = 0.5:0.4、0.2、0.1、…,永不为零) -``` - -| 变量 | 含义 | 来源 | -|---|---|---| -| j | 本战斗内已实际发放(入账)的可选类件数;注入未挖到不计数,战斗开始清零 | 供给机制的战斗域计数 | -| p₀ / d | 注入概率初值 / 衰减因子 | 奖励配置表 active_p0 / active_decay(provisional) | - -另有一道按板保底断言:一张图的资格格里带伤害道具的数量低于下界时,整批草稿弃用、沿同一条随机流重摇;重摇超过上限(默认 32 次)即致命报错——那说明权重配置坏了。现行下界默认为 0,即断言关闭:刀保底的语义已由首件保证取代,断言结构保留备用。 - -| 加载护栏 | 拦什么 | 命中后果 | -|---|---|---| -| 池空检查 | 每个奖励池至少一行权重为正 | 加载期致命 | -| 清图正当量 | 清图池至少一行有实际价值 | 加载期致命 | -| 增益引用有效 | 增益行的效果引用必须在[增益状态](增益状态.md)表里存在 | 加载期致命 | -| 零伤害后闸 | 保底关闭时,全池仍须至少一行活着的伤害道具行 | 加载期致命——防"零伤害世界"静默上线导致不可通关 | -| 供给闸 | 保底开启时,格子池须有威力不低于下界的活伤害行 | 加载期致命 | +举证:本节为封装与流程规则,无计算。 ## 依赖与输出 @@ -188,31 +128,28 @@ j ≥ 1 → p = p₀ × d^(j−1)(现行 p₀ = 0.4、d = 0.5:0.4 | 方向 | 系统 | 接口要点 | |---|---|---| -| 上游 | [数据配置](../表现与支撑/数据配置.md) | 奖励表与奖励配置表的 schema 承载与加载校验通道;本系统是两表的回填责任方 | -| 上游 | [排雷玩法](../排雷循环/排雷玩法.md) | 间接:挖格是否带奖励资格的事实经[战斗结算](战斗结算.md)转化而来,两系统无直接接口 | +| 上游 | [数据配置](../表现与支撑/数据配置.md) | 奖励表的 schema 承载与加载校验通道;本系统是回填责任方 | +| 上游 | [排雷玩法](../排雷循环/排雷玩法.md) | 间接:挖格是否携带格面资源的事实经[战斗结算](战斗结算.md)转化而来,两系统无直接接口 | | 上游 | [棋盘生成](../排雷循环/棋盘生成.md) | 图类型标签作清图差异化插槽的上下文(静态恒定) | | 上游 | [增益状态](增益状态.md) | 增益行的效果引用指向其状态表(悬空加载致命);施加动作经战斗结算调用 | -| 下游 | [战斗结算](战斗结算.md) | 唯一调用方:摇号、授予、入库、查询、窗口组装、映射退役与库存清空全由其编排;窗口锚点挂在它的结算段序上 | -| 下游 | [敌人系统](敌人系统.md) | 伤害道具的默认目标取其固定顺位;道具段先于战斗段构成"先刀后重击"的窗口 | -| 下游 | [行动经济](../排雷循环/行动经济.md) | 其经济契约的对账以本系统的奖励表行值为原材料;换算与闭合验收归[战斗结算](战斗结算.md) | -| 下游 | [冒险结构](../冒险循环/冒险结构.md) | 关卡结构是库存生命周期的容器;"关卡结束"事件与关卡末剩余道具的处理归其域 | -| 下游 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | 权重、档位、威力、池内容与保底注入参数的调参所有权(全部 provisional) | -| 下游 | [HUD 框架](../表现与支撑/HUD框架.md) | 呈现义务归其:已开格与库存奖励身份常读、道具使用窗口呈现、结算明细四类行、清图奖励行强调、关卡末清空反馈 | -| 下游 | [辅助道具](../排雷循环/辅助道具.md) | 相邻:辅助道具的背包与使用归其管;辅助道具类别进入本系统掉落池属预留结构位(启用走修订) | -| 下游 | [教学引导](../表现与支撑/教学引导.md) | "拾取—囤刀—窗口选用"闭环与"关卡末库存清空"的教学口径来源 | +| 下游 | [战斗结算](战斗结算.md) | 唯一调用方:摇号、身份查询、受理、清图对象、当量供给投影、映射退役全由其编排 | +| 下游 | [敌人系统](敌人系统.md) | 群伤与直伤的目标取其存活集与固定顺位 | +| 下游 | [行动经济](../排雷循环/行动经济.md) | 其经济契约的对账以本系统的资源行值为原材料;换算与闭合验收归[战斗结算](战斗结算.md) | +| 下游 | [冒险结构](../冒险循环/冒险结构.md) | 关卡结构是清图对象生命周期的容器 | +| 下游 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | 权重、档位、威力与池内容的调参所有权(全部 provisional) | +| 下游 | [HUD 框架](../表现与支撑/HUD框架.md) | 呈现义务归其:已开格资源身份常读、类型图标预读的呈现深度、结算明细行、清图奖励行强调 | +| 下游 | [教学引导](../表现与支撑/教学引导.md) | "读敌拍板、抢类型"教学口径的来源 | +| 下游 | [辅助道具](../排雷循环/辅助道具.md) | 相邻:辅助道具的背包与使用归其管;预读类道具读取本系统的身份查询面 | -负空间:本系统不订阅事件、不画界面、除摇号外不用任何随机数;何时调接口、按什么顺序调,全归[战斗结算](战斗结算.md)。 +负空间:本系统不订阅事件、不画界面、除摇号外不用任何随机数;何时调接口、按什么顺序调,全归[战斗结算](战斗结算.md)。库存、道具使用窗口、可选类供给已随可选类道具删除(2026-09-15)整体下线,不再属于本系统。 ## P0 最小闭环 -1. 战斗结算装上新图后、玩家开挖前调用一次摇号:全图格子身份与清图身份摇定,映射进入只读。 -2. 玩家挖掘:挖开的格子当场揭晓身份;已开格与背包道具的身份随时可读。 -3. 轮末授予段逐格发放:即时类当场兑现(增益挂状态、群体伤害逐个结算、小额回血),可选类入库并记来源。 -4. 清图轮兑付清图奖励,恒非空。 -5. 道具使用窗口弹出:玩家至多选用一件或跳过(当轮拾取当轮可用;满血治疗包禁选)。 -6. 道具段执行选用件:刀按固定顺位打敌、治疗包回血不超上限;战斗段"重击拍前用刀"成立。 -7. 战斗结束:板级映射退役,库存原样带入下一场战斗。 -8. 关卡结束(无论输赢):库存一次性清空并给出可见反馈,进入下一关。 +1. 战斗结算装上新图后、玩家开挖前调用一次摇号:全部非封锁格的资源类型与清图对象身份摇定,映射进入只读。 +2. 玩家挖掘:挖开的格子当场揭晓类型身份;已开格的身份随时可读。 +3. 轮末授予段按极性矩阵逐格兑付:正向 percent 挂状态、正向 flat 当场结算,负向全部当场兑付。 +4. 清图轮兑付清图奖励对象,恒非空;完美排雷追加第二份。 +5. 战斗结束:板级映射退役。换图按新板重摇。 ## P1 / P2 后置 @@ -220,60 +157,46 @@ j ≥ 1 → p = p₀ × d^(j−1)(现行 p₀ = 0.4、d = 0.5:0.4 | 优先级 | 内容 | 后置原因 | |---|---|---| +| P1 | 功能道具渠道(长周期、更强力的功能性道具) | 用户已定方向(2026-09-15):数值型伤害/治疗道具已删除,功能道具经其他渠道加入——渠道候选(关卡节点奖励等)归[关卡节点地图](../冒险循环/关卡节点地图.md)域定稿;本系统只留结构位 | | P1 | 清图池按图类型差异化 | 默认槽之外的结构位已留;待[棋盘生成](../排雷循环/棋盘生成.md)的图类型词表落定 | -| P1 | 未开格奖励身份的呈现深度(类别 / 档位 / 完整身份) | 结构前提已备(身份摇定即可查);与推理的界线未拍板,见待拍板 | -| P1 | 增攻增益行是否入默认内容池 | 内容决策,归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | -| P1 | 单次结算道具获取上限(结构位,默认关) | 启用即限制、过低锁死胜局;归难度曲线与Boss 实测裁决 | -| P2 | 关卡末剩余道具折算或继承 | 折算点在关卡末;归[冒险结构](../冒险循环/冒险结构.md)(Alpha) | -| P2 | 窗口触发政策候选(仅可选件触发 / 常驻库存条非模态) | 现行有库存恒弹窗;待窗口摩擦实测数据 | -| P2 | 音频挂钩(拾取音 / 使用音 / 清图奖励音 / 负反馈聚合音) | 归[音频](../表现与支撑/音频.md),Alpha | -| P2 | 内容名录扩展(新奖励行) | 机制与内容分离;现行行集收窄,扩展随内容批 | +| P1 | 未开格资源类型的呈现深度 | 结构前提已备(身份摇定即可查);与推理的界线未拍板,见待拍板 | +| P1 | 增攻(attack)型行值与权重终调 | 内容决策,归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | +| P2 | 音频挂钩(拾取音 / 负向兑付音 / 清图奖励音) | 归[音频](../表现与支撑/音频.md),Alpha | +| P2 | 内容名录扩展(新资源行) | 机制与内容分离;现行行集收窄,扩展随内容批 | ## 调参表 -两张表的承载归[数据配置](../表现与支撑/数据配置.md),内容由本系统回填,数值全部 provisional 归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md);现行行值以 [registry 的 reward_table 与 reward_config 条目](../../../registry/entities.yaml) 为准。 +表的承载归[数据配置](../表现与支撑/数据配置.md),内容由本系统回填,数值全部 provisional 归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md);现行行值以 [registry 的 reward_table 条目](../../../registry/entities.yaml) 为准。 -奖励配置表(单行全局): +默认内容行(奖励表;威力的区间行在摇号时一次摇定,区间中点即原定值——期望不漂移): -| 参数 | 域 | 现行值 | 说明 | -|---|---|---|---| -| active_p0 | float [0,1] | 0.4(provisional) | 注入概率公式的初值因子:本战斗已获取 j 件时,每张新图注入概率 = active_p0 × active_decay^(j−1);标定目标 = 平均每场战斗约得一件 | -| active_decay | float (0,1] | 0.5(provisional) | 注入概率按本战斗实际获取件数减半(已获 1 件后 0.4、2 件后 0.2、3 件后 0.1、…),永不为零;未获取新件不衰减;加难杠杆候选 0.6 | -| k_dmg | int [0,999] | 0(provisional) | 按板伤害保底下界;0 = 断言关闭(现行口径,刀保底语义由首件保证取代) | -| n_draft | int [1,999] | 32(provisional) | 保底重摇上限,超过即致命报错 | -| p_min | int [1,999] | 8 | 保底开启时格子池伤害行的威力下界(即默认最低刀威力) | +| 行 | 类型 | 极性 | 威力 | 权重 | 档位 | 所在池 | +|---|---|---|---|---|---|---| +| attack_up | attack | 正向 | —(不消费) | 20 | 2 | 格面池 | +| defense_up | defense | 正向 | —(不消费) | 16 | 2 | 格面池 | +| spark_aoe | blast | 正向 | 4 | 16 | 1 | 格面池 | +| heal_minor | heal | 正向 | 2–6 | 15 | 1 | 格面池 | +| weaken | weaken | 正向 | —(不消费) | 12 | 1 | 格面池 | +| enrage | attack | 负向 | —(不消费) | —(不参与摇号) | 2 | 格面池 | +| off_guard | defense | 负向 | —(不消费) | —(不参与摇号) | 2 | 格面池 | +| 直伤 | heal | 负向 | 4 | —(不参与摇号) | 1 | 格面池 | +| ambush+2 | blast | 负向 | —(不消费) | —(不参与摇号) | 1 | 格面池 | +| sapped | weaken | 负向 | —(不消费) | —(不参与摇号) | 1 | 格面池 | +| 清障炸药 | — | — | 25–55 | 1 | 2 | 清图槽 | -默认内容行(奖励表,值 provisional;五行的威力是区间,摇号时于下阶与上阶间一次摇定,区间中点即原定值——期望不漂移): +摇号只消费正向行的权重(类型频次由此涌现:attack 20 / defense 16 / blast 16 / heal 15 / weaken 12,合计 79);负向行是纯兑付字典,按(类型,极性)查表取用。清障炸药对全体存活敌各吃一笔大额伤害,当场兑付。奖励配置表(RewardConfigTable)已随可选类删除下线——注入概率、按板保底等参数全部失义。 -| 奖励 | 类型 | 威力 | 池权重 | 档位 | 所在池 | -|---|---|---|---|---|---| -| 增伤增益 | 即时 | —(不消费) | 20 | 2 | 格子池 | -| 减伤增益 | 即时 | —(不消费) | 16 | 2 | 格子池 | -| 群体伤害 | 即时 | 4 | 16 | 1 | 格子池 | -| 小额治疗 | 即时 | 2–6 | 15 | 1 | 格子池 | -| 基础刀 | 可选 | 5–11 | 60 | 1 | 注入池 | -| 进阶刀 | 可选 | 10–22 | 30 | 2 | 注入池 | -| 强效治疗包 | 可选 | 6–18 | 10 | 2 | 注入池 | -| 清障炸药(清图槽专属的当场引爆) | 即时 | 25–55 | 1 | 2 | 清图槽 | - -清障炸药对全体存活敌各吃一笔大额伤害,不入库、不占可选类供给。格子池只出即时类(权重合计 67);可选类三行由注入机制承载(见核心规则)。 - -结构冻结(改动走本文修订流程,不走调参):五类封闭枚举与两级交付、装板期预分配且无重摇、恒定表值不吃修正、满层零兑付无折算、库存关卡域、窗口单件制、清图恒非空、除摇号外零随机。 +结构冻结(改动走本文修订流程,不走调参):五型封闭枚举、雷安同池、极性矩阵、装板期预分配且无重摇、负向恒即时无库存、清图恒非空、除摇号外零随机。 ## 验收标准 -- 每格必有货:装板摇号后,每个资格格恰有一个奖励身份、清图槽恰有一个身份;同图跨轮查询结果逐字相同。 -- 恰一次与确定性:摇号对每张新图恰发生一次,重复调用被拒绝且映射不变;同一条随机流轨迹驱动两套实例,映射、库存与使用回执逐位相同。 -- 保底重摇与致命:按板保底开启而首稿不达标时,整批弃用、沿同流重摇,达标才提交;重摇超过上限时进程报错退出。 -- 首件保证:首场战斗内,玩家获取首件可选类道具之前每张新图必注入 1 件到随机资格格(注入即覆盖该格既有即时类身份);注入格未被挖到则不获得、不补发;此后注入概率随本战斗实际获取件数按表值递减但永不为零,未获取新件时概率不衰减。 -- 未生效可见:满层增益、满血即时治疗、无存活敌的群体伤害,各自在结算明细记"奖励未生效"行,零折算、零补偿。 -- 满血守卫:满血时强效治疗包在窗口禁选;缺血时使用回血不超上限,且道具被消耗。 -- 窗口纪律:一次窗口至多选用一件;跳过恒合法;已选件在无存活敌时照常消耗并记"已消耗未生效"行;同一件不能选用第二次。 -- 库存生命周期:战斗结束与换图都不动库存;关卡结束(无论输赢)一次性清空在库与已用件;清空后一切入库与使用请求被拒绝。 -- 恒定表值:同一件伤害道具在有无增攻增益下打出的伤害相同;增攻只改变主角基础攻击的计算结果。 -- 加载护栏:池空、清图池无正当量、增益引用悬空、全池无活伤害行——任一命中即加载报错中止;默认内容加载通过。 -- 类型封闭:表里出现五类之外的类型或未知池标签,加载拒绝。 -- 表实一致:两张数据表字段与 registry 的 reward_table / reward_config 条目逐字段一致。 +- 每格必有货:装板摇号后,每个非封锁格恰有一个资源类型、清图槽恰有一个对象身份;封锁格恒无资源;同图跨轮查询结果逐字相同。 +- 雷安同池:安全格与雷格从同一类型池、同一权重分布摇定;任何"按格型差异化分配"的分支不存在。 +- 恰一次与确定性:摇号对每张新图恰发生一次,重复调用被拒绝且映射不变;同一条随机流轨迹驱动两套实例,映射与兑付回执逐位相同。 +- 类型封闭与字典完整:表里出现五型之外的类型、或任一型缺正向/负向行,加载拒绝。 +- 未生效可见:满层增益、满血正向治疗、无存活敌的群伤,各自在结算明细记"奖励未生效"行,零折算、零补偿。 +- 加载护栏:池空、清图池无正当量、增益引用悬空——任一命中即加载报错中止;默认内容加载通过。 +- 表实一致:数据表字段与 registry 的 reward_table 条目逐字段一致。 ## 待拍板 @@ -281,18 +204,17 @@ j ≥ 1 → p = p₀ × d^(j−1)(现行 p₀ = 0.4、d = 0.5:0.4 | 条目 | 现状与失义原因 | 建议归属 | |---|---|---| -| 奖励预读与推理的边界 | 预读允许到什么深度未定:[不做清单](../../05-不做清单.md)裁定未开格不显示奖励身份、允许恢复推理原料类道具;现役预读道具探宝罗盘(预读 3×3 窗口内未开格的奖励身份,归[辅助道具](../排雷循环/辅助道具.md))为窄域,更深的呈现(未开格身份常显等)与推理保护之间的界线待拍板 | [辅助道具](../排雷循环/辅助道具.md)定稿批与[HUD 框架](../表现与支撑/HUD框架.md) | -| 注入格未挖到不补发,实际获取期望低于名义首件保证 | 首件保证承诺的是"必注入"而非"必到手":注入格因清图或速杀未被挖到时不获得、战斗末不补发,实际获取期望低于名义值(切片实测约 0.88 件/战 vs 名义 1.0);拟通过修改退出战斗的触发方式优化(清图/战斗结束的时机与注入格的兜底交互),2026-09-15 拍板暂不做,登记待办 | [战斗结算](战斗结算.md)与[难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | -| 速杀退化预警 | 战斗结束时未开资格格占比过高即警:供给过剩使战斗提早结束,奖励身份零发放,奖励系统饿死自己的高光时刻;阈值与联动调参未定 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | -| 窗口摩擦预警 | 窗口跳过率、单次结算平均明细行数未设阈值;结构性缓解已内置(库存只收可选类、窗口单件制),保留观测 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | -| 连锁批量授予的溢出吸收 | 一条大连锁一次给出大量奖励资格,超出增益叠层上限时如何处理(折算、顺延或显式接受)未定;与[排雷玩法](../排雷循环/排雷玩法.md)待拍板同源 | [战斗结算](战斗结算.md)与[增益状态](增益状态.md)条目化 | -| 关卡末剩余道具的折算或继承 | 未选用件在关卡末直接清空,是否改为折算回复或继承下一关,未定(Alpha) | [冒险结构](../冒险循环/冒险结构.md) | -| 窗口触发政策 | 现行有库存恒弹窗;"仅可选件触发""常驻库存条非模态"两个候选待窗口摩擦实测后裁决 | [HUD 框架](../表现与支撑/HUD框架.md) | +| 系统更名 | 可选类道具已删除,"奖励道具经济"名实不符;候选如"格面资源经济"。更名牵动全仓链接与根索引,须整批执行 | 本文与[02-系统清单](../../02-系统清单.md)整批 | +| 功能道具的正式渠道 | 用户已定方向(更强力、更长周期的功能性道具经其他渠道加入),渠道设计未定;节点奖励([关卡节点地图](../冒险循环/关卡节点地图.md)域)是候选之一 | [关卡节点地图](../冒险循环/关卡节点地图.md)定稿批 | +| 资源预读与推理的边界 | 预读允许到什么深度未定:[不做清单](../../05-不做清单.md)裁定未开格不显示奖励身份、允许恢复推理原料类道具;现役预读道具探宝罗盘(预读 3×3 窗口内未开格的奖励身份,归[辅助道具](../排雷循环/辅助道具.md))为窄域,未开格类型图标常显与推理保护之间的界线待拍板 | [辅助道具](../排雷循环/辅助道具.md)定稿批与[HUD 框架](../表现与支撑/HUD框架.md) | +| heal 负向直伤的量级锚 | −4 为 provisional 直觉值,未过行动经济当量对账 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md)调参批 | +| 连锁批量兑付的溢出吸收 | 一条大连锁一次给出大量正向兑付,超出增益叠层上限时如何处理(折算、顺延或显式接受)未定 | [战斗结算](战斗结算.md)与[增益状态](增益状态.md)条目化 | ## 版本历史 | 版本 | 日期 | 改动 | |---|---|---| | v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | -| v0.2 | 2026-09-15 | 可选类注入递减基准对齐代码:逐图减半改为按实际获取件数递减(首件保证 = 未获取则每张新图必注入;p = p₀×d^(j−1));补明注入覆盖即时身份与"发放即获取、未挖到不计数"语义;验收标准首件保证改"必注入"口径;待拍板新增注入格未挖到不补发条目 | -| v0.3 | 2026-09-15 | 雾格残留清理:关闭「待拍板」的雾格相关定价约束三条失义条目(雾内档位下界、清图奖励锚随雾成本上浮、雾板净当量优势带上界)与随之取消的奖励配置表档位过滤门限 t_fog_min。奖励表字段、跨字段校验、默认根行集与窗口规则不变;清图奖励的图类型差异化插槽保留为结构位 | +| v0.2 | 2026-09-15 | 可选类注入递减基准对齐代码:逐图减半改为按实际获取件数递减;补明注入覆盖即时身份与"发放即获取、未挖到不计数"语义;验收标准首件保证改"必注入"口径 | +| v0.3 | 2026-09-15 | 雾格残留清理:关闭「待拍板」的雾格相关定价约束三条失义条目与随之取消的奖励配置表档位过滤门限 t_fog_min | +| v0.4 | 2026-09-15 | **格面资源批(用户拍板,2026-09-15)**:① 核心抽象改为格面资源(CellResource)——安全格与雷格一视同仁、单一类型池装板期摇定,极性由「动作 × 格型」矩阵决定(开安全格/标中雷 = 正向,开雷格/标错安全格 = 负向),取代踩雷固定伏击、标中固定削弱、标错三选一哈希反噬三套固定兑付;② 五型字典(attack/defense/heal/blast/weaken,正负各一行;weaken 负向 sapped 为新行,heal 负向为不经增益状态的直伤);③ 封锁格(初始展开格)恒无资源;④ 清图奖励改述为板级、可配置可替换的清图奖励对象,图类型差异化插槽保留;⑤ **可选类道具(刀/治疗包)整体删除**——供给控制器、注入概率、按板保底、关卡域库存、道具使用窗口的数据面全部下线,RewardConfigTable 随批废止;功能道具经其他渠道加入的结构位登记 P1;⑥ 行动经济对账锚与难度曲线重推义务随批登记(见 registry 修订记录) | diff --git a/design/gdd/systems/战斗循环/战斗结算.md b/design/gdd/systems/战斗循环/战斗结算.md index 6f1934ce..8875f61f 100644 --- a/design/gdd/systems/战斗循环/战斗结算.md +++ b/design/gdd/systems/战斗循环/战斗结算.md @@ -18,8 +18,9 @@ | 负责 | 说明 | |---|---| -| 轮次编排 | 战斗开始序列、每轮七段结算、五种出口分发(继续 / 换图 / 挖掘期刷新 / 战斗结束 / 关卡结束) | -| 结算触发与段序 | 轮末自动触发一次整轮结算;七段顺序为冻结结构,改动走文档修订而非调参 | +| 轮次编排 | 战斗开始序列、每轮五段结算、五种出口分发(继续 / 换图 / 挖掘期刷新 / 战斗结束 / 关卡结束) | +| 结算触发与段序 | 轮末自动触发一次整轮结算;五段顺序为冻结结构,改动走文档修订而非调参 | +| 结算队列与抵消过滤 | 挖掘期动作(开格、标旗、撤旗)入结算队列;结算先做抵消过滤再逐行兑付 | | 明细流水协议 | 结算中的每件事逐行留档并标注来源,是呈现、回放对账、数据导出共读的唯一数据源 | | 收益对照表 | 一张效果档位对照表归一全部收益的折算口径(详见核心规则) | | 伤害与治疗边界 | 修正池合成与封顶、溢杀丢弃、治疗封顶、死亡判定时机 | @@ -34,73 +35,64 @@ | 棋盘怎么生成 | [棋盘生成](../排雷循环/棋盘生成.md) | | 单位血量递减、行动环与存活判定 | [敌人系统](敌人系统.md) | | 增益/减益状态的容器、叠层与效果实例 | [增益状态](增益状态.md) | -| 奖励行值、权重档位与库存内容 | [奖励道具经济](奖励道具经济.md) | +| 格面资源行值、权重档位与极性字典 | [奖励道具经济](奖励道具经济.md) | | 关卡序列、关卡大奖励与失败 | [冒险结构](../冒险循环/冒险结构.md) | | 界面呈现与结算动画 | [HUD 框架](../表现与支撑/HUD框架.md)与[战斗表现](战斗表现.md) | ## 在核心循环中的位置 ``` -挖掘期:玩家挖格 / 插旗 / 停手 ──(事实流 + 账本扣费)──▶ 战斗结算(轮末七段兑现)──▶ 胜负 / 换图 / 冒险推进 +挖掘期:玩家开格 / 标旗 / 撤旗 / 停手 ──(事实流 + 账本扣费)──▶ 战斗结算(轮末五段兑现)──▶ 胜负 / 换图 / 冒险推进 ``` 本系统站在"扫雷结束、结果揭晓"的那一段:挖掘期它只安静缓冲[排雷玩法](../排雷循环/排雷玩法.md)上报的事实流,不做任何兑付;轮末把这一轮攒下的因逐行兑现成战斗的果。再往下游,胜负去向交[冒险结构](../冒险循环/冒险结构.md)接手,明细交[HUD 框架](../表现与支撑/HUD框架.md)呈现。 ## 核心规则 -### 轮末七段结算:一轮从收场走到判定 +### 轮末五段结算:一轮从收场走到判定 -玩家行动点花完、主动停手,或开完整张图时,[行动经济](../排雷循环/行动经济.md)宣布本轮结束,本系统随即自动发起一次整轮结算。结算严格按七段固定顺序执行;核心相对次序"增益减益先于道具、道具先于战斗"不变——先合成修正再动刀,任何结局都能归因。 +玩家行动点花完、主动停手,或开完整张图时,[行动经济](../排雷循环/行动经济.md)宣布本轮结束,本系统随即自动发起一次整轮结算。结算严格按五段固定顺序执行;核心相对次序"增益减益先于战斗"不变——先合成修正再动刀,任何结局都能归因。 ``` -① 授予段 → ② 道具使用窗口 → ③ 增益/减益段 → ④ 道具段 → ⑤ 战斗段 → ⑥ 衰减段 → ⑦ 判定段 +① 授予段 → ② 增益/减益段 → ③ 战斗段 → ④ 衰减段 → ⑤ 判定段 ``` | 段 | 干什么 | |---|---| -| ① 授予段 | 把挖掘期缓冲的事实分批兑换:踩雷、奖励格、旗判定、清图奖励(详见授予段一节) | -| ② 道具使用窗口 | 全流程唯一玩家输入点:从库存至多选一件道具,或跳过 | -| ③ 增益/减益段 | 把主角与敌人身上的活跃效果一次性合成本结算的修正池(同侧百分比修正的加总桶) | -| ④ 道具段 | 执行窗口选中件:伤害道具按恒定表值打顺位最前存活敌;治疗包按表值回复 | -| ⑤ 战斗段 | 主角先手攻击一次,随后敌人按行序逐个还手(详见战斗段一节) | -| ⑥ 衰减段 | 移除到期的临时效果;每轮恰好一次,含末轮——清图奖励先兑付、效果后衰减 | -| ⑦ 判定段 | 先判主角倒下(负),再判敌人清空(胜),都不满足则继续下一轮 | +| ① 授予段 | 结算队列先过滤再分批兑换:开格、旗判定、清图,按极性矩阵路由(详见授予段一节) | +| ② 增益/减益段 | 把主角与敌人身上的活跃效果一次性合成本结算的修正池(同侧百分比修正的加总桶) | +| ③ 战斗段 | 主角先手攻击一次,随后敌人按行序逐个还手(详见战斗段一节) | +| ④ 衰减段 | 移除到期的临时效果;每轮恰好一次,含末轮——清图奖励先兑付、效果后衰减 | +| ⑤ 判定段 | 先判主角倒下(负),再判敌人清空(胜),都不满足则继续下一轮 | -结算本体是纯逻辑步骤流:零随机、零界面依赖、禁止动画等待。触发只读行动经济的相位读数与轮末标记,这条消息有棋盘路径和停手路径两个发射源,到达先后不承载语义。这些性质共同保证结算完全可回放:同样的种子、同样的事件序列加窗口选择序列,跑出的步骤流逐行相同——录像回放与断言复测都建立在它上面。唯一的随机例外是战斗开始时掷骰定敌方实际数量,它发生在结算步骤流之外。 +结算本体是纯逻辑步骤流:零随机、零界面依赖、禁止动画等待。触发只读行动经济的相位读数与轮末标记,这条消息有棋盘路径和停手路径两个发射源,到达先后不承载语义。这些性质共同保证结算完全可回放:同样的种子、同样的事件序列,跑出的步骤流逐行相同——录像回放与断言复测都建立在它上面。唯一的随机例外是战斗开始时掷骰定敌方实际数量,它发生在结算步骤流之外。 -举证:七段为流程编排,无计算;段序常量存配置表,加载时校验与定稿顺序完全一致,不一致拒绝启动。 +举证:五段为流程编排,无计算;段序常量存配置表,加载时校验与定稿顺序完全一致,不一致拒绝启动。 ### 明细流水:每一行都能指回你刚才的哪一步棋 -结算过程中每一件事都写一行明细,每行标注来源——哪个安全格、哪面旗、哪颗雷、清图奖励。这份流水是结算明细屏(玩家逐行查看决策兑现结果的界面)的数据源,也是回放对账与数据导出共读的唯一契约。行型封闭为 15 类,不允许私自增加;新增或下线行型属于行协议变更,必须走本文修订,并同步呈现层的行格式化。 +结算过程中每一件事都写一行明细,每行标注来源——哪个安全格、哪面旗、哪颗雷、清图奖励。这份流水是结算明细屏(玩家逐行查看决策兑现结果的界面)的数据源,也是回放对账与数据导出共读的唯一契约。行型封闭为 10 类,不允许私自增加;新增或下线行型属于行协议变更,必须走本文修订,并同步呈现层的行格式化。 | 行型 | 什么时候写 | |---|---| | 效果行 | 增益/减益段每条效果一行:本次授予贡献值与池合成值分列,防误读 | | 伤害行 | 每次伤害一行:目标、伤害分量、修正终值、击杀标记 | | 治疗行 | 治疗生效一行:封顶后的真实回复量 | -| 道具行 | 道具入库或生效一行 | | 溢出未生效行 | 踩雷超出伏击上限,超出的每颗一行 | | 奖励未生效行 | 满层拒收、满血治疗等合法例外一行 | -| 已消耗未生效行 | 道具消耗了却没产生效果(防御分支) | -| 使用被拒行 | 满血选用治疗包被窗口拒绝 | -| 标旗未中行 | 旗插空的零值归因行,每颗雷只记一次;标错反噬的兑付另记效果行 | +| 标旗未中行 | 旗插空的零值归因行,每颗雷只记一次;标错的负向兑付另记效果行 | | 蓄力行 | 敌人本拍蓄力不动手(攒下一击)时记一行 | | 衰减行 | 到期临时效果移除一行 | | 判定行 | 胜 / 负 / 继续各一行;终局判定行同时是胜负画面的数据锚 | | 高光行 | 完美排雷成立时一行,只记实际有效兑付 | -| 窗口打开锚行(window_open) | 窗口段有候选件、真的弹出时一行;数值 = 本轮候选件数(库存中的在架件数),是"窗口段在案"的打开态锚点 | -| 窗口跳过锚行(window_skip) | 窗口段以跳过收场时一行。两种触发:库存为空、窗口根本不弹,直接跳过;或是窗口弹了而玩家提交零选择主动跳过。两者数值都是 0 | -窗口段的两类锚行只服务一件事:让"这一轮窗口段发生过什么"恒有一行可查,不参与聚合统计(呈现层对它们的格式化与"未生效类"计数无关)。**窗口段恒在案**由此落成——有候选就落窗口打开锚行,没候选就落跳过锚行(空库存触发),玩家零选择再落一条跳过锚行(未选用触发)。 - -每行还携带公共字段:来源类别、来源格、轮次、显示名、数值,以及可空的高光标记(用于强调标中旗、清图奖励这类值得高亮的结果)。没生效也要留痕:四类"未生效 / 被拒"行如实记录合法例外,呈现时聚合计数,不逐行刷屏。 +每行还携带公共字段:来源类别、来源格、轮次、显示名、数值,以及可空的高光标记(用于强调标中旗、清图奖励这类值得高亮的结果)。没生效也要留痕:两类"未生效"行如实记录合法例外,呈现时聚合计数,不逐行刷屏。 任何一行找不到来源即断言失败——宁可报错,也不让"合并到看不出来源"的呈现混过数据层。但有些行天然没有棋盘来源,断言为此留了两层豁免,豁免集合是封闭清单,改动同样走本文修订。 -第一层按行型豁免四类:衰减行(到期移除本就是段级动作,不属于任何一格)、判定行(它是胜负出口的结论,不是棋盘事实)、窗口打开锚行与窗口跳过锚行(记录的是"窗口段发生了什么",不是哪一格)。这四类连来源类别都不必填。 +第一层按行型豁免两类:衰减行(到期移除本就是段级动作,不属于任何一格)、判定行(它是胜负出口的结论,不是棋盘事实)。这两类连来源类别都不必填。 -第二层按来源类别豁免四类:主角攻击行的来源是主角单位本身,敌方行动行的来源是当时动手的那个敌人单位,清图奖励行的来源是"这张板被清掉"这一整板事实,道具行的来源是库存里的那件道具实例——它们都不指向某个棋盘格,来源格校验因此跳过。 +第二层按来源类别豁免三类:主角攻击行的来源是主角单位本身,敌方行动行的来源是当时动手的那个敌人单位,清图奖励行的来源是"这张板被清掉"这一整板事实——它们都不指向某个棋盘格,来源格校验因此跳过。 豁免不等于免检:按行型豁免的行仍要带齐公共字段、守住各自的语义约束(如窗口打开锚行的数值必须是本轮的候选件数),按来源类别豁免的行仍必须写明来源类别,其余行必须指回一个真实存在的棋盘格。豁免只是免掉"来源格必须有效"这一条校验,不是免掉整份行协议。 @@ -108,12 +100,12 @@ ### 收益对照表:所有收益共用同一把尺子 -挖格给主角增益、标旗给敌人削弱、踩雷给敌方强化、清图给奖励——来源不同、形态不同,但玩家必须能回答"挖这一格值不值",所以全部收益用一张效果档位对照表归一换算。折算单位是当量:1 当量等于 1 点主角生命的期望净变化。这张表是[行动经济](../排雷循环/行动经济.md)五条经济契约第一条"单一当量"的载体;本系统是全部五条契约的唯一对账责任方(契约本体见该文档,对账现状见「待拍板」)。 +开安全格给正向、标中旗给正向、踩雷与标错给负向、清图给清图奖励对象——来源不同、形态不同,但玩家必须能回答"挖这一格值不值",所以全部收益用一张效果档位对照表归一换算。折算单位是当量:1 当量等于 1 点主角生命的期望净变化。这张表是[行动经济](../排雷循环/行动经济.md)五条经济契约第一条"单一当量"的载体;本系统是全部五条契约的唯一对账责任方(契约本体见该文档,对账现状见「待拍板」)。 **结论**:单一线性换算全源共用,禁止分源改率;百分比效果按"每个结算的瞬时当量"口径折算。 ``` -flat 与道具类(伤害道具、治疗、伏击): E = 表值本身 +flat 类(直伤、治疗、伏击): E = 表值本身 percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 × 参考敞口 完美排雷的清图奖励: E = 奖励表值 × 完美乘数 ÷ 100 ``` @@ -125,28 +117,33 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 × | 层数 × 行值 | 单条效果的叠层数与行值,读[增益状态](增益状态.md)的实例数据 | 行值归该系统 | | 完美乘数 | 完美排雷给清图奖励的乘数,配置值 | 200,即翻倍(provisional) | -### 授予段兑付:挖到的、标中的、踩到的、清掉的各归各账 +### 授予段兑付:极性路由,四类动作各归各账 -授予段把挖掘期缓冲的事实分三批兑换,每格受理、每雷转化、每旗判定恰好一次。踩雷的兑换产物叫伏击:玩家踩到的雷变成敌人的先手强化,敌人在本结算还手时攻击附带额外伤害。清图批的兑付发生在道具使用窗口之前,所以清图奖励里的道具当轮就能选用。 +授予段消费结算队列。**队列与抵消过滤**:挖掘期玩家对格子的每个动作——开格、标旗、撤旗——都进入结算队列;结算先做一遍遍历过滤再兑付,不走逐动作出栈直算——标旗后被撤旗的,该次标旗动作不结算(零兑付,行动点已耗即变相惩罚);开格事实不可撤(已开格无法回退)。过滤后按触发源分三批兑换,每格受理、每旗判定恰好一次。 + +兑付走**极性矩阵**(定义归[奖励道具经济](奖励道具经济.md)):开安全格 → 该格格面资源的正向;开雷格 → 负向;标中旗 → 该雷格资源的正向;标错旗 → 该安全格资源的负向。五型字典里每型各有一行正向、一行负向——伏击不再是踩雷的固定产物,只保留为 blast 型的负向一行。 | 批 | 兑付 | |---|---| -| 挖格批 | 踩到的雷逐颗转化为伏击;带奖励资格的安全格按类别分流(见下表) | -| 旗判定批 | 标中则敌方削弱当轮生效,每颗雷的资格只兑一次;标空则记"标旗未中"归因行,并触发标错反噬(见下) | -| 清图批 | 清图奖励恰好发一次;完美排雷追加第二份同身份兑付 | +| 挖格批 | 开到的安全格逐格兑该格资源的正向;开到的雷格逐格兑该格资源的负向;同时按奖励定义累加充能计数(现行:开格 → 穿刺桶) | +| 旗判定批 | 标中则兑该雷格资源的正向,每颗雷的资格只兑一次,并同样按奖励定义累加充能计数(现行:标中旗 → 魔法桶);标空则记"标旗未中"归因行,并兑该安全格资源的负向 | +| 清图批 | 清图奖励对象恰好发一次;完美排雷追加第二份同身份兑付 | -| 奖励类别 | 兑付方式 | 拒绝语义 | -|---|---|---| -| 增益 | 进入[增益状态](增益状态.md)的容器,本结算生效 | 叠层已满时拒收,记"奖励未生效"行 | -| 即时全体伤害 | 当场对全体存活敌各扣表值生命 | 当场兑付,不入库存、不进窗口 | -| 即时治疗 | 主角按表值回复并封顶上限 | 满血时零兑付,记"奖励未生效"行 | -| 战斗道具 / 治疗包 | 入关卡库存 | 在道具使用窗口选用时兑付 | +**充能也是奖励,不是攻击类型的一部分**:这两批给的是"充能计数",投进哪个攻击类型桶由奖励定义(`charge_grants`)决定——来源与类型是两条独立抽象,换桶属奖励侧改动,攻击类型与甲效矩阵不参与。 -伏击有上限:本轮踩雷数超出上限时,只有上限内生效,超出的逐颗记"溢出未生效"行。伏击聚成一个池,本结算里多个敌人共享同一池值、互不消耗,且只活一轮、轮末清零。 +| 兑付形态 | 覆盖 | 兑付方式 | 拒绝语义 | +|---|---|---|---| +| 增益(percent) | attack / defense / weaken 的正负两向 | 进入[增益状态](增益状态.md)的容器,本结算生效 | 叠层已满时拒收,记"奖励未生效"行 | +| 即时全体伤害(flat) | blast 正向 | 当场对全体存活敌各扣表值生命 | 场上无敌可打时零兑付,记"奖励未生效"行 | +| 即时治疗(flat) | heal 正向 | 主角按表值回复并封顶上限 | 满血时零兑付,记"奖励未生效"行 | +| 直伤(flat) | heal 负向 | 主角当场扣表值生命,不经增益状态 | 生命归零即走致死短路 | +| 伏击加层 | blast 负向 | 敌方还手附加伤害 +2 层,入伏击池 | 超上限部分记"溢出未生效"行 | + +伏击有上限([敌人系统](敌人系统.md)的反灾难护栏):blast 负向兑付超出上限时只有上限内生效,超出的逐颗记"溢出未生效"行。伏击聚成一个池,本结算里多个敌人共享同一池值、互不消耗,且只活一轮、轮末清零。其余四型的负向不受伏击上限约束,各自受池 clamp 与叠层上限承载。 标中资格认雷不认旗:兑付资格以雷格实例为键——拔旗重插不恢复、同一颗雷跨轮不重复兑付;换图后新雷是新实例,资格自然重置。同一面旗一直插在雷上,每轮都会重新上报标中,去重是本系统的职责。 -标错反噬是标空旗(标了但格不是雷)的已定案惩罚:在旗判定批里,每颗被标空的雷格实例触发一次三选一确定性反噬——暴走(enrage,敌方增伤 +25%)、敌方伏击 +2 层、失衡(off_guard,主角承伤 +25%),三者都是一次性状态(1 结算时效),行值归[增益状态](增益状态.md)的状态表。选哪一项不由掷骰决定,而由载体确定性派生:以标空格的坐标与本场战斗的板序号做哈希((|x|×7 + |y|×13 + 板序号×5) mod 3,0/1/2 依次对应三池),同一坐标同一板永远出同一项。刻意不消费随机数流的理由只有一个:结算全程可回放——同种子同操作序列必须逐位复现同一次反噬,不能为一次惩罚往回放轨迹里塞进新的取号。反噬与"标旗未中"归因行同键去重,每雷格实例只触发一次;叠层已满授予被拒时记"奖励未生效"行,不静默吞掉。 +标错的惩罚不再是独立机制:标空旗(标了但格不是雷)= 该安全格格面资源的负向兑付(极性矩阵的"标错"分支),类型化、确定性、零额外派生——旧三选一哈希反噬(暴走 / 失衡 / 伏击+2 三池,坐标×板序号哈希派生)随格面资源批(2026-09-15)整段下线,三池内容收编为 attack / defense / blast 三型的负向行。负向兑付与"标旗未中"归因行同键去重,每雷格实例只触发一次;叠层已满授予被拒时记"奖励未生效"行,不静默吞掉。 完美排雷全有或全无:一张板零误标且至少标中一面旗,清图奖励加倍(现行倍数为翻倍,provisional)。完美计数从装板起算、换图重置;高光行只记实际有效兑付(首份加被接受的第二份),首份即零兑付则高光行不发。标中旗的兑付行自带高光标记,与完美排雷的独立高光行构成两个强制高光检查点。 @@ -154,16 +151,28 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 × ### 战斗段与胜负判定:谁先动手、怎么扣血、怎么定胜负 -战斗段是兑现的最后一刀。主角的基础攻击恒存在——这是项目拍板:若基线为零,百分比增益乘上去永远是零,增益系统就空转了。攻击力域 [1, 999]、0 于加载期拒绝,现行值 6(provisional)。顺序固定:主角先手攻击顺位最前的存活敌人(道具段的默认目标与之同源),随后按行序逐个存活敌人还手;每个敌人依次走"查攻击、结算伤害、推进行动环"三步且恰好推进一次,主角不在推进范围。主角中途倒下,剩余敌人全部停手,直接进判定段。 +战斗段是兑现的最后一刀。主角的基础攻击恒存在——这是项目拍板:若基线为零,百分比增益乘上去永远是零,增益系统就空转了。攻击力域 [1, 999]、0 于加载期拒绝,现行值 6(provisional)。顺序固定:主角先手攻击顺位最前的存活敌人,随后按行序逐个存活敌人还手;每个敌人依次走"查攻击、结算伤害、推进行动环"三步且恰好推进一次,主角不在推进范围。主角中途倒下,剩余敌人全部停手,直接进判定段。 -主角先手攻击由三个分量逐项取整后相加:基础分量(攻击力经增益修正,可被池封顶压到零)、伤害A、伤害B。后两者是挖掘期充能的附加伤害: +主角先手攻击由三个分量逐项取整后相加:普通分量(攻击力经增益修正,可被池封顶压到零)、穿刺分量、魔法分量。**攻击类型是伤害的属性轴**——它只决定这个分量查甲效表的哪一行,定义里不含任何棋盘来源。分量各自查表后取整相加;甲效表把攻击类型与敌方护甲类型交叉成一张 3×3 克制倍率: -| 充能池 | 累积时机 | 换算与上限 | +| 攻击类型 \ 护甲类型 | 轻甲 | 魔法护甲 | 重甲 | 语义 | +|---|---|---|---|---| +| 普通 | 100 | 100 | 100 | 基线分量:不吃克制,只吃增益修正 | +| 穿刺 | 100 | 150 | 50 | 穿透附魔护甲,破不开重甲 | +| 魔法 | 100 | 50 | 150 | 绕得过重甲,被魔法护甲吸收 | + +倍率只三档:克制 ×150、中性 ×100、被克 ×50。攻击类型是分量的固有属性(每个分量恒属普通 / 穿刺 / 魔法 之一),护甲类型是敌单位的固有属性,两者都不随层数、来源与轮次漂移。矩阵键集 3×3 满格、结构冻结,数值 provisional。主角增益只修正普通分量,两个充能分量不吃百分比修正。 + +普通分量由攻击力基线直接供给;穿刺与魔法分量由**充能**供给——充能是挖掘期攒下、按攻击类型分桶的附加伤害储备,本结算战斗段一次性消费、轮末清零,跨轮零存量。 + +谁往桶里放东西属**奖励的定义**,不属攻击类型的定义:棋盘事实(开格、标中旗、踩雷、清图……)只是奖励的**触发源**,奖励内容怎么定是可改的——改的是"这个源给什么",碰不到"穿刺是什么"。现行供给(provisional): + +| 奖励触发源 | 现行奖励内容 | 换算与上限 | |---|---|---| -| 伤害A | 本轮每挖开一个安全格 | 每格表值,单轮封顶(现行每格 1、封顶 8,provisional;每格 0 即机制关闭) | -| 伤害B | 每面首次标中的旗(与削弱兑付同批判定、每雷只计一次) | 每雷表值,不封顶——行动点预算天然限界(现行每雷 2,provisional) | +| 本轮每挖开一个安全格 | 给穿刺桶充能 | 每格表值,单轮计数上限(现行每格 1、上限 8,provisional;每格 0 = 该奖励关闭,上限 0 = 不封顶) | +| 每面首次标中的旗(与削弱兑付同批判定、每雷只计一次) | 给魔法桶充能 | 每雷表值,无上限——行动点预算天然限界(现行每雷 2,provisional) | -两池都是挖掘期累积、本结算战斗段一次性消费、轮末清零——跨轮零存量。三个分量各自查甲效表(伤害类型对敌方护甲类型的克制倍率表)后取整相加:克制乘 150%、无甲 100%、被对位克制 50%(现行矩阵,provisional)。主角增益只修正基础分量,充能分量不吃百分比修正。 +两条都是奖励侧现行定义(暂存结算表 `charge_grants`,正式归属见「待拍板」):换桶、换量、或把开格奖励换成增益与道具,都不触动攻击类型与甲效矩阵。 **结论**:先合成、再取整、全程非负;溢杀丢弃、治疗封顶、死亡即时判定。 @@ -178,7 +187,7 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 × | 修正池封顶 | 同侧百分比修正加算后每池独立收口 ±100 百分点;乘数可为 0——敌人输出归零、主角本结算免伤,是合法设计态而非异常 | | 零值伤害 | 合成后为 0 时不调扣血接口,改写零值伤害行——免伤与零输出必须可见 | | 溢杀 | 一刀超出目标剩余生命的部分丢弃:不转移给下一个敌人、不存续、无负生命中间态 | -| 治疗 | 生命不溢出上限;满血选用治疗包在窗口即被拒、不消耗 | +| 治疗 | 生命不溢出上限;满血正向治疗零兑付,记"奖励未生效"行 | | 死亡判定 | 生命归 0 即倒下;敌人受击即死;主角倒下战斗段立即短路;判定段先判主角、再判敌人(防御性次序) | | 胜负 | 敌人全灭判胜;主角倒下判负;都不满足则继续下一轮 | @@ -186,21 +195,21 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 × ### 轮次生命周期:换图、刷新、战斗结束与关卡收束 -七段跑完,判定段给出方向,本系统据此推进战斗状态,并把结果发回上游: +五段跑完,判定段给出方向,本系统据此推进战斗状态,并把结果发回上游: ``` 判定段结果 ├─ 继续(敌未清、主角活着)→ 通知"同图继续" → 下一轮开轮 - ├─ 换图(本轮清图)→ 旧板退役 → 生成新板 → 装板 → 奖励预分配恰一次 → 通知"换图" → 下一轮开轮 + ├─ 换图(本轮清图)→ 旧板退役 → 生成新板 → 装板 → 资源预分配恰一次 → 通知"换图" → 下一轮开轮 ├─ 战斗结束(胜 / 负)→ 清理敌人与状态 → 发出战斗结束信号 → 休眠,等下一场战斗 - └─ 关卡结束(上层显式调用)→ 清空两个背包,给出可见反馈 + └─ 关卡结束(上层显式调用)→ 清空辅助道具背包,给出可见反馈 ``` -停手与耗尽收轮的回合恒为同图继续;换图指令只允许出现在清图轮,其他轮发换图属于程序错误、立即上抛。库存以关卡为界:战斗结束不清库存,战斗道具与辅助道具跨战斗延续;关卡结束时两个背包一次性清空,清空前先返回快照计数,作为"剩余道具随关卡结束清空"的可见反馈。 +停手与耗尽收轮的回合恒为同图继续;换图指令只允许出现在清图轮,其他轮发换图属于程序错误、立即上抛。辅助道具背包以关卡为界:战斗结束不清背包,跨战斗延续;关卡结束时一次性清空,清空前先返回快照计数,作为"剩余辅助道具随关卡结束清空"的可见反馈。战斗道具背包已随可选类删除(2026-09-15)下线。 -挖掘期刷新是玩家在挖掘中途主动换图,经[行动经济](../排雷循环/行动经济.md)扣费:扣费成功后按"旧板退役、生成新板、装板、奖励预分配恰一次"编排,本轮不打断——没有结算段、没有轮次结束。储备不足被拒是玩家决策的合法结果,不是编排错误。刷新图不发清图奖励,完美排雷计数随装板重置。 +挖掘期刷新是玩家在挖掘中途主动换图,经[行动经济](../排雷循环/行动经济.md)扣费:扣费成功后按"旧板退役、生成新板、装板、资源预分配恰一次"编排,本轮不打断——没有结算段、没有轮次结束。储备不足被拒是玩家决策的合法结果,不是编排错误。刷新图不发清图奖励,完美排雷计数随装板重置。 -战斗开始按固定序列开张:关上配置热重载的闸门、打开增益状态容器、掷骰定敌方实际数量、生成敌人、装板并预分配奖励恰一次、发开轮通知。上一关的大奖励(如血上限提升)经战斗开始入参的覆盖值通道生效,内容归[冒险结构](../冒险循环/冒险结构.md)。 +战斗开始按固定序列开张:关上配置热重载的闸门、打开增益状态容器、掷骰定敌方实际数量、生成敌人、装板并预分配资源恰一次、发开轮通知。上一关的大奖励(如血上限提升)经战斗开始入参的覆盖值通道生效,内容归[冒险结构](../冒险循环/冒险结构.md)。 举证:本节为编排流程,无计算。 @@ -216,22 +225,21 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 × | 上游 | [棋盘生成](../排雷循环/棋盘生成.md) | 换图时调用其生成接口 | | 上游 | [敌人系统](敌人系统.md) | 单位接口全调用面:生成、查询、扣血、推进、默认目标、伏击授予、清场 | | 上游 | [增益状态](增益状态.md) | 状态容器接口全调用面:开域、授予、读值、衰减、闭域 | -| 上游 | [奖励道具经济](奖励道具经济.md) | 奖励与库存接口:预分配、入库、投影、关卡末清库 | +| 上游 | [奖励道具经济](奖励道具经济.md) | 格面资源接口:预分配、身份查询、受理、清图对象、当量供给投影、映射退役 | | 上游 | [冒险结构](../冒险循环/冒险结构.md) | 战斗触发、遭遇上下文与主角入参覆盖值(provisional,MVP 冒烟直供) | -| 下游 | [HUD 框架](../表现与支撑/HUD框架.md) | 明细流水是结算明细屏与道具窗口的统一数据源;未生效类行须带形状冗余防误读 | +| 下游 | [HUD 框架](../表现与支撑/HUD框架.md) | 明细流水是结算明细屏的统一数据源;未生效类行须带形状冗余防误读 | | 下游 | [战斗表现](战斗表现.md) | 结算步骤流是战斗动画回放的脚本源 | | 下游 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | 五条经济契约的对账结论是其调参约束输入(对账现状见「待拍板」) | ## P0 最小闭环 -1. 战斗开始序列跑完(关闸门、开容器、掷骰定敌数、生成敌人、装板并预分配奖励、发开轮通知),进入第一轮挖掘期。 -2. 挖掘期本系统只缓冲事实流,不做任何兑付。 -3. 轮末自动触发七段结算,触发与事件到达序无关。 -4. 授予段三批兑现:雷转伏击、安全格按类别分流、旗兑削弱或标旗未中行、清图发奖励(完美翻倍)。 -5. 窗口段玩家至多选一件道具或跳过,选择序列记入回放。 -6. 增益合成、道具生效、主角先手加逐敌还手、衰减恰好一次。 -7. 判定段先主角后敌人:继续通知同图、清图换图续轮、胜负走战斗结束清理(库存不清)。 -8. 明细流水全程落行,供呈现、回放与导出。 +1. 战斗开始序列跑完(关闸门、开容器、掷骰定敌数、生成敌人、装板并预分配资源、发开轮通知),进入第一轮挖掘期。 +2. 挖掘期本系统只缓冲事实流(开格、标旗、撤旗入结算队列),不做任何兑付。 +3. 轮末自动触发五段结算,触发与事件到达序无关。 +4. 授予段先做抵消过滤(标旗后被撤旗的不结算),再按极性矩阵三批兑现:开安全格 / 标中旗兑正向、开雷格 / 标错旗兑负向、清图发清图奖励对象(完美翻倍)。 +5. 增益合成、主角先手加逐敌还手、衰减恰好一次。 +6. 判定段先主角后敌人:继续通知同图、清图换图续轮、胜负走战斗结束清理(辅助道具背包不清)。 +7. 明细流水全程落行,供呈现、回放与导出。 ## P1 / P2 后置 @@ -249,10 +257,9 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 × |---|---|---|---| | 参考敞口 | int [1, 999] | 12(provisional) | 当量折算的代表性敞口;变更须重跑全部对账 | | 完美乘数 | percent {100, 200} | 200(provisional) | 100 为仅高光、无第二份;域外加载拒绝 | -| 伤害A每格 / 单轮封顶 | int ≥ 0 | 1 / 8(provisional) | 封顶 0 表示不封顶;每格 0 表示机制关闭 | -| 伤害B每雷 | int ≥ 0 | 2(provisional) | 无封顶,行动点预算天然限界 | -| 甲效矩阵 | percent | 克制 150 / 无甲 100 / 被对位克制 50(provisional) | 键集结构冻结,数值归调参 | -| 段序常量 | 固定七段 | 结构冻结 | 加载期恒等校验,违例拒绝启动 | +| 充能奖励定义 `charge_grants` | Dictionary:触发源 → {attack_type, per_unit, cap} | 开格 → 穿刺 1/格(计数上限 8)· 标中旗 → 魔法 2/雷(无上限)(provisional) | 奖励侧定义:附加伤害储备按攻击类型分桶,本字典决定哪个源投哪个桶、每单位几点、单轮计数上限;整表替换不改攻击类型与甲效矩阵(正式归属见「待拍板」) | +| 甲效矩阵 | percent | 克制 150 / 中性 100 / 被克 50(provisional) | 键集 = 攻击类型 {普通, 穿刺, 魔法} × 护甲类型 {轻甲, 魔法护甲, 重甲},3×3 满格结构冻结;数值归调参 | +| 段序常量 | 固定五段 | 结构冻结 | 加载期恒等校验,违例拒绝启动 | | 池封顶 | ±100 百分点 | 结构冻结 | 乘数域随之 [0, 2] | | 取整方向 | 向下取整 | 结构冻结 | 单一规则,非调参项 | @@ -260,19 +267,20 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 × ## 验收标准 -- 七段全序:任一轮结算的明细行按七段顺序排列;窗口段恒在案——有候选时落窗口打开锚行(数值等于本轮候选件数),无候选时落跳过锚行,玩家零选择也落跳过行。 +- 五段全序:任一轮结算的明细行按五段顺序排列。 - 触发与到达序无关:同一轮末的两条结束消息按任意先后驱动,结算步骤流逐行相同。 -- 每事实恰一次:每格受理、每雷转化、每旗判定恰好一次;重复投递不改变结果。 -- 伏击守恒:踩雷超出上限时兑付数等于上限,超出部分逐颗记"溢出未生效"行;多敌共享同一伏击池值。 +- 抵消过滤:标旗后被撤旗的旗判定不进入兑付、零行零兑付;开格事实不可撤。 +- 每事实恰一次:每格受理、每旗判定恰好一次;重复投递不改变结果。 +- 极性路由正确:开安全格 / 标中旗只兑正向、开雷格 / 标错旗只兑负向;兑付效果与该格资源类型的字典行一一对应。 +- 伏击守恒:blast 负向兑付超出上限时兑付数等于上限,超出部分逐颗记"溢出未生效"行;多敌共享同一伏击池值。 - 完美排雷:零误标且至少一面标中时第二份兑付恰一次并发高光行;出现误标或零标中则无高光;计数换图重置。 -- 窗口单件:一次提交多件只受理首件;满血治疗包被拒且不消耗;空库存记跳过。 - 战斗段次序:主角先手后逐敌"查攻击、结算伤害、推进"各恰一次;主角倒下立即短路,剩余敌人不行动。 - 数值边界:合成后零伤害不扣血、写零值行;溢杀丢弃不转移;治疗封顶不溢出;全程无负值。 - 出口分发:先判主角倒下(负)再判敌清空(胜);停手与耗尽轮恒同图,清图轮才允许换图。 -- 关卡收束:关卡结束清空两个背包恰一次并返回清空前计数;战斗结束不清库存。 +- 关卡收束:关卡结束清空辅助道具背包恰一次并返回清空前计数;战斗结束不清背包。 - 可回放:同种子同输入两遍步骤流逐行相同;结算路径零随机、零界面等待。 -- 无来源即炸:每行明细都能指回一个来源事实(棋盘格、单位、清图、库存件或段级结论);找不到来源即断言失败,行型与来源类别两层豁免清单见明细流水一节,豁免行仍受其它契约约束。 -- 行型封闭:流水只出现本文登记的 15 类行型;新增或下线行型必须走本文修订并同步呈现层行格式化,未登记行型不得落行。 +- 无来源即炸:每行明细都能指回一个来源事实(棋盘格、单位、清图或段级结论);找不到来源即断言失败,行型与来源类别两层豁免清单见明细流水一节,豁免行仍受其它契约约束。 +- 行型封闭:流水只出现本文登记的 10 类行型;新增或下线行型必须走本文修订并同步呈现层行格式化,未登记行型不得落行。 ## 待拍板 @@ -282,8 +290,8 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 × |---|---|---| | 挖掘风险不等式对账破线 | 归档记录现行值链(防御增益时长 1、行值 −30、现行难度曲线)下两参考板形首版验算破线,多敌满配深度破线;破线已升格为曲线级约束,相关参数处禁独立调参联动网络;对账须在难度曲线调参批重跑 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md)提案,本系统闭合共裁 | | 清图支配性保守地板缺口 | "推到底清图不吃亏"的对账未闭合:非完美板形的清图期望收益低于"挖完确定格就弃图刷新";已裁"清图非严格支配"为设计态,保守地板当量缺口仍在案;对账须在难度曲线调参批重跑 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md),奖励量级联动[奖励道具经济](奖励道具经济.md) | -| 标错反噬的正式侧载体 | 标空旗的三选一确定性反噬已定案并上线(2026-09-12 批,机制见授予段一节):三池内容、一次性时效、确定性派生载体均为现行规则;留下的开口是载体实现——现行为坐标×板序号哈希派生、不消费随机数流,正式侧候选 = 改为随机服务新增一条封闭随机流(回放纪律不变,迁移与否未定) | 本系统,随机流结构联动[数据配置](../表现与支撑/数据配置.md) | | 连锁批量奖励的溢出处理 | 一条大连锁给出的奖励超出叠层上限时如何处理未定(现行按显式接受、零补偿执行) | [奖励道具经济](奖励道具经济.md)与本系统条目化 | +| 充能奖励的正式归属 | 充能(按攻击类型分桶的附加伤害储备)现作为奖励定义暂存结算表 `charge_grants`(触发源 → {attack_type, per_unit, cap});奖励的正式载体([奖励道具经济](奖励道具经济.md) 的奖励类别 / 效果面,或数据配置的独立奖励定义表)未定——定稿前由本系统代管 | [奖励道具经济](奖励道具经济.md)与本系统共裁,键位随定稿批迁移 | ## 版本历史 @@ -293,3 +301,6 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 × | v0.2 | 2026-09-15 | 标错反噬机制收编(2026-09-12 批已上线):旗判定批标空分支补"触发三选一确定性反噬",授予段新增反噬规则正文(三池内容、一次性时效、坐标×板序号确定性派生载体、不走随机流的可回放理由);P1 后置删除"标错惩罚落地"条目;待拍板"标错惩罚未定案"改写为已定案描述并保留正式侧载体候选注记 | | v0.3 | 2026-09-15 | 明细流水行型清单 13 → 15:补窗口打开锚行 window_open / 窗口跳过锚行 window_skip 的语义、字段与落行时机,服务"窗口段恒在案、零选择记跳过、空库存记跳过";"无来源即炸"的两层豁免集合(行型四类 / 来源类别四类)成文并说明豁免不等于免检;验收标准窗口段措辞与实现对齐,新增行型封闭与行型新增纪律条目 | | v0.4 | 2026-09-15 | 雾格残留清理:关闭「待拍板」的对账输入雾相关分量失义条目(原对账输入含雾成本负担比与雾板分层等分量)。现行对账输入 = 实测可推理率分布低分位值等现行读数,条款③⑤对账协议与判定式不变 | +| v0.5 | 2026-09-15 | 攻击/护甲命名去位置化(全仓统一,跨文档 + registry + 切片代码同批):攻击分量与充能池 {基础, 伤害A, 伤害B} → {普通, 穿刺, 魔法}(数据键 {base, dmg_a, dmg_b} → {normal, pierce, magic}),敌方护甲 {无甲, 护甲A, 护甲B} → {轻甲, 魔法护甲, 重甲}(数据键 {none, a, b} → {light, ward, heavy},映射沿教学梯度 none→light / a→ward / b→heavy);战斗段把甲效表从"三档措辞"改为 3×3 显式矩阵(行 = 攻击类型、列 = 护甲类型,克制 ×150 / 中性 ×100 / 被克 ×50,普通行恒 100)并补语义列;hero_attack 行分量字段 base/dmg_a/dmg_b → normal/pierce/magic;调参表参数名与措辞同步(伤害A→穿刺、伤害B→魔法、"被对位克制"→"被克");registry 与 敌人系统/难度曲线与Boss/03-内容规模/切片 schema·tres·core·presentation·smoke 同批改键(旧名仅在本次修订与各文件批次注记中作为"原名"留存) | +| v0.6 | 2026-09-15 | **攻击类型与奖励抽象分离**(用户裁定"攻击类型的定义和格子奖励要分离开;开格\|标雷 → 奖励;奖励如何定义是可以修改的;不要将两者绑定"):修正 v0.5 遗留的焊死命名——攻击类型是**伤害的属性轴**(只决定查甲效表哪一行,定义里不含任何棋盘来源);充能是**按攻击类型分桶的附加伤害储备**,"谁能充、充哪个桶"归**奖励定义**,开格 / 标中旗 / 踩雷 / 清图一律只作奖励触发源。战斗段:矩阵表去掉来源措辞(语义列改"穿透附魔护甲…"),新增"谁往桶里放东西属奖励定义"一段与"奖励触发源 × 现行奖励内容 × 换算上限"表;授予段:挖格批与旗判定批改为"按奖励定义累加充能计数"并加一句充能归属说明;调参表:穿刺每格 / 魔法每雷两行合并为「充能奖励定义 `charge_grants`」(触发源 → {attack_type, per_unit, cap}),v0.5 落下的 pierce_per_cell / pierce_cap / magic_per_flag 同批作废;新增「待拍板」条目登记充能奖励的正式归属。切片同批:`charge_grants` 承接三字段、`_charge_counts`(只计数)与 `_charge_points()`(按奖励定义投桶)、round_facts 改 `charge_counts` / `charge_points`、冒烟加"奖励定义在位 ×2 + 改投桶行为断言" | +| v0.7 | 2026-09-15 | **格面资源批(用户拍板四点)**:① 段序七段 → 五段——道具使用窗口与道具段随可选类道具整体删除(2026-09-15 用户裁定)下线,段序常量与 registry settlement_table 同步修订;② 授予段改述为"结算队列 + 抵消过滤":开格 / 标旗 / 撤旗入队,标旗后被撤旗的动作不结算(零兑付、行动点不返);③ 兑付统一走极性矩阵(开安全格 / 标中旗 = 正向,开雷格 / 标错旗 = 负向,字典归奖励道具经济),取代踩雷固定伏击、标中固定削弱、标错三选一哈希反噬三套固定兑付;④ 明细行型 15 → 10(删道具行 / 已消耗未生效行 / 使用被拒行 / 窗口打开锚行 / 窗口跳过锚行),两层豁免集合改两类 + 三类;⑤ 战斗道具背包与库存语义下线,关卡收束只清辅助道具背包;⑥ 收益对照表 flat 类措辞去道具;验收标准改五段全序 + 抵消过滤 + 极性路由正确,删窗口类断言。行动经济 F1 对账锚(伏击共享池)与难度曲线重推义务随批登记(见 registry 修订记录),切片侧修改指导随批产出 | diff --git a/design/gdd/systems/战斗循环/敌人系统.md b/design/gdd/systems/战斗循环/敌人系统.md index 251565b9..265da3d7 100644 --- a/design/gdd/systems/战斗循环/敌人系统.md +++ b/design/gdd/systems/战斗循环/敌人系统.md @@ -80,11 +80,11 @@ | 敌种 | 行为环 | 护甲类型 | 现行定位 | |---|---|---|---| -| 地精 | 攻击(单拍环) | 无 | 首发杂兵;教学位节点 ×[1,2],开战掷定 | -| 熊地精 | 攻击 / 蓄力 / 重击(三拍环) | 甲 | 首发主力;重击倍率 2 | +| 地精 | 攻击(单拍环) | 轻甲 | 首发杂兵;教学位节点 ×[1,2],开战掷定 | +| 熊地精 | 攻击 / 蓄力 / 重击(三拍环) | 魔法护甲 | 首发主力;重击倍率 2 | | 食人魔酋长 | 攻击 / 攻击 / 蓄力 / 重击(四拍 Boss 环) | 重甲 | 首发关底 Boss;重击倍率 2 | -护甲类型(无 / 甲 / 重甲)与伤害类型的克制结算矩阵归[战斗结算](战斗结算.md),本系统只提供每个敌种的护甲类型数据。举证:生成与护甲为数据面规则,无计算。 +护甲类型(轻甲 / 魔法护甲 / 重甲)与攻击类型的克制结算矩阵归[战斗结算](战斗结算.md),本系统只提供每个敌种的护甲类型数据。举证:生成与护甲为数据面规则,无计算。 ### 行为环:敌人按排好的剧本轮流出招,走到哪一拍零随机 @@ -201,7 +201,7 @@ | unit_count | [1, 3] | 1(provisional) | 遭遇数量区间下界;有上界的行开战时在区间内掷定,教学位节点同样掷骰 | | unit_count_max | [unit_count, 3],可省略 | 缺省 = 定值 | 数量区间上界;开战时在区间内掷定本战实际数量 | | atk_min / atk_max | [0, 999] 可选配对 | ±3 浮动(provisional) | 攻击基线区间:开战掷定一次、整战持久;缺省 = 定值行 | -| armor_type | {无, 甲, 重甲},缺省无 | 地精无 / 熊地精甲 / 酋长重甲 | 克制结算归[战斗结算](战斗结算.md) | +| armor_type | {轻甲, 魔法护甲, 重甲},缺省轻甲 | 地精轻甲 / 熊地精魔法护甲 / 酋长重甲 | 克制结算归[战斗结算](战斗结算.md) | | hp | [1, 999] | provisional | 单位生命基线(难度修饰前) | | atk | [0, 999] | provisional | 攻击基线;0 合法 = 纯伏击伤敌种 | | heavy_multiplier | [1, 16] | 2(provisional) | 无重击拍的敌种不消费,非校验项 | diff --git a/design/gdd/systems/排雷循环/排雷玩法.md b/design/gdd/systems/排雷循环/排雷玩法.md index ffa9f0e9..98236eee 100644 --- a/design/gdd/systems/排雷循环/排雷玩法.md +++ b/design/gdd/systems/排雷循环/排雷玩法.md @@ -8,7 +8,7 @@ 排雷玩法是扫雷规则本体:玩家在地牢厅室里做的每个动作——挖格、插旗、移动——都由它裁决,并把发生的事实如实上报给全项目。它不决定每个动作花多少钱(账本归[行动经济](行动经济.md)),也不决定收益怎么兑现成战斗效果(归[战斗结算](../战斗循环/战斗结算.md))——它只保证棋盘上的事实真实、顺序确定:数字从不说谎,每个拒绝有据可查。没有它,[棋盘生成](棋盘生成.md)生成的板没有发生地,战斗结算也没有事实来源。 -玩家看到的说法略有不同:雷格叫**惩罚格**(首发类型是怪物巢穴——惊动则怪物倾巢而出占得先机)、插旗叫**控制**(标中则巢穴废置、怪物被削弱)、连锁展开叫**坍塌显形**(挖穿薄壳,整片塌陷露出)、标错叫**控制失败的失控反噬**。本文对内沿用机制名"挖、旗、雷格"。 +玩家看到的说法略有不同:雷格叫**惩罚格**(首发类型是怪物巢穴——惊动则怪物倾巢而出占得先机)、插旗叫**控制**(标中则巢穴废置、化险为利)、连锁展开叫**坍塌显形**(挖穿薄壳,整片塌陷露出)、标错叫**控制失败**。本文对内沿用机制名"挖、旗、雷格"。 ## 系统范围 @@ -31,7 +31,7 @@ | 行动点价目与扣费 | [行动经济](行动经济.md) | | 棋盘怎么生成、可推理性保证 | [棋盘生成](棋盘生成.md) | | 轮次编排与收益兑现 | [战斗结算](../战斗循环/战斗结算.md) | -| 奖励内容与档位 | [奖励道具经济](../战斗循环/奖励道具经济.md) | +| 格面资源内容与极性兑付档位 | [奖励道具经济](../战斗循环/奖励道具经济.md) | | 界面呈现 | [HUD 框架](../表现与支撑/HUD框架.md) | ## 在核心循环中的位置 @@ -75,7 +75,7 @@ 每个已开安全格都亮着一个数字,恒等于它周围 8 格里的雷数。这条"数字恒真"是全部推理的地基:数据层从不说谎,呈现层怎么遮掩都不改真值——任何让数字失真的实现都在禁止之列。 -挖开一个数字为 0 的格(周围一圈没有雷)时,它周围未插旗的安全格免费连锁全开,一路递推到没有新的 0 格为止——这就是连锁展开,玩家看到的是"坍塌显形":挖穿一层薄壳,整片松动的地面塌陷露出。连锁格只花首格挖掘的 1 点,照常计入清图进度(清图 = 开完全部安全格),奖励资格(挖开这格能不能拿到奖励)也照常。 +挖开一个数字为 0 的格(周围一圈没有雷)时,它周围未插旗的安全格免费连锁全开,一路递推到没有新的 0 格为止——这就是连锁展开,玩家看到的是"坍塌显形":挖穿一层薄壳,整片松动的地面塌陷露出。连锁格只花首格挖掘的 1 点,照常计入清图进度(清图 = 开完全部安全格),格面资源资格也照常——连锁开出的格与单挖的格同权,资源身份归[奖励道具经济](../战斗循环/奖励道具经济.md)、极性兑付归[战斗结算](../战斗循环/战斗结算.md),本系统不区分。 连锁遇到旗就停:旗格不被链开,也不给更远的格当传播跳板。旗花 1 点行动点,正是玩家亲手买下的"链阻断器"——对一片不敢确定的地,提前插一面旗,塌方到它为止。 @@ -85,7 +85,7 @@ |---|---| | 免费 | 只扣首格的 1 点,连锁翻开的格不另收费 | | 计入清图进度 | 连锁开的格照常算进"全部安全格开完"的判定 | -| 奖励资格照常 | 连锁开出的安全格与单挖的安全格同权 | +| 资源资格照常 | 连锁开出的安全格与单挖的安全格同权 | | 遇旗即止 | 旗格不入链、不作传播跳板;旗留在原地,轮末照常判定 | ``` @@ -98,15 +98,15 @@ ### 每张新图白送一片开阔地:开局初始展开 -每装上一张新图,本系统在同一个事务里免费翻开出生 3×3(小人出生的那片安全区),加上与它连成一片的开阔地——凡是与出生区连通的 0 格地带全部亮起。展开完成后,小人落在出生 3×3 的中心格。这片初始展开每次装板只发生一次,跨轮不重放;换新图时按新板重来。 +每装上一张新图,本系统在同一个事务里免费翻开出生 3×3(小人出生的那片安全区),加上与它连成一片的开阔地——凡是与出生区连通的 0 格地带全部亮起。展开完成后,小人落在出生 3×3 的中心格。这片初始展开每次装板只发生一次,跨轮不重放;换新图时按新板重来。这批格是**封锁格**:已开、计入清图进度,但恒不携带格面资源——不再有任何加成(资源分配规则归[奖励道具经济](../战斗循环/奖励道具经济.md))。 初始展开守四条铁律: | 铁律 | 含义 | |---|---| | 免费 | 不扣行动点,账本零写入 | -| 计入清图进度 | 剩余安全格从这片开完后起算 | -| 无奖励 | 这些格不发奖励,下游不得记入奖励 | +| 计入清图进度 | 剩余安全格从这片开完后起算——呈现上即"剩余未探索安全区域"计数 | +| 无格面资源(封锁格) | 这些格恒无资源、不再有任何加成,下游不得对它们做任何兑付 | | 只在装板时发生一次 | 跨轮不重放,防止"每轮白送一遍" | 装板时本系统还当场校验生成产物的结构前提:出生区内无雷、数字恒真、初始展开没有大到直接吞掉全图。任一不过就拒绝装板并报出诊断,绝不停带病运行;这些前提的正常保证由[棋盘生成](棋盘生成.md)负责,本校验只是消费侧的最后一道闸。 @@ -136,9 +136,11 @@ ### 旗立得住、也带不走:旗的生命周期与换图重置 -旗是棋盘状态的一部分,不是背包里的实物:插上的旗跨轮保留、随图存续,没有数量上限。每次轮次结束(行动点耗尽、玩家停手或清图时),本系统对当时在场的每一面旗如实上报一条判定——旗下是雷记标中(玩家看到巢穴被控制、怪物被削弱),不是雷记标空;旗一直插在雷上,就每轮如实重复上报标中,去重是[战斗结算](../战斗循环/战斗结算.md)的事,本系统只报事实。插旗、拔旗本身不发事件,界面反馈走调用返回值。旗不参与清图判定,但带旗的格没挖开就照常挡着——全图标旗一格不挖,永远清不了图。 +旗是棋盘状态的一部分,不是背包里的实物:插上的旗跨轮保留、随图存续,没有数量上限。每次轮次结束(行动点耗尽、玩家停手或清图时),本系统对当时在场的每一面旗如实上报一条判定——旗下是雷记标中(玩家看到巢穴被控制、化险为利),不是雷记标空;旗一直插在雷上,就每轮如实重复上报标中,去重是[战斗结算](../战斗循环/战斗结算.md)的事,本系统只报事实。插旗、拔旗本身不发事件,界面反馈走调用返回值。 -标空就是标错,玩家读到的是控制失败的失控反噬——反噬目前没有定案,见「待拍板」。 +标旗与撤旗都是动作,轮末结算时走[战斗结算](../战斗循环/战斗结算.md)的抵消过滤:标旗后当轮又被撤旗的,该次标旗不进入兑付(判定批以在场旗位为基线,不在场即不判)——零兑付、行动点不返还;开格事实不可撤。旗不参与清图判定,但带旗的格没挖开就照常挡着——全图标旗一格不挖,永远清不了图。 + +标空就是标错,玩家读到的是控制失败——惩罚兑付为该安全格格面资源的负向(极性矩阵,归[奖励道具经济](../战斗循环/奖励道具经济.md)与[战斗结算](../战斗循环/战斗结算.md)),本系统只报"标空"事实。 换图时旗全量消失,两条路径待遇不同:清图换图发生在轮末,旧旗先走完当轮判定、再随旧图清空;挖掘期刷新换图不打断当轮,旧旗没等到判定就失效——零兑付,插旗花的行动点也不返还。战斗结束、整板退役时同样清空。 @@ -171,7 +173,7 @@ | 事件 | 何时发 | 内容 | |---|---|---| -| 挖开格 | 每开一格(初始展开、连锁、单挖各算) | 哪格、安全还是雷、数字、经哪条路开的、有无奖励资格(初始展开的格恒无) | +| 挖开格 | 每开一格(初始展开、连锁、单挖各算) | 哪格、安全还是雷、数字、经哪条路开的、有无格面资源资格(封锁格恒无;安全格与雷格恒有——资源本体与极性兑付归[奖励道具经济](../战斗循环/奖励道具经济.md),本系统不区分) | | 旗判定 | 每次轮次结束时逐旗一条 | 哪面旗、标中还是标空 | | 轮次结束 | 每轮恰一条 | 这轮怎么结束的(清图 / 耗尽)、下一轮换不换图的建议 | @@ -195,7 +197,7 @@ | 上游 | [棋盘生成](棋盘生成.md) | 棋盘产物的消费方;装板时校验结构前提(出生区无雷、数字恒真等),违例拒绝装板 | | 上游 | [行动经济](行动经济.md) | 唯一扣费入口:本系统判棋盘面后请账本扣费,绝不自行扣减;挖成后上报连锁规模与清图事实;停手意图经批次入口转交 | | 下游 | [战斗结算](../战斗循环/战斗结算.md) | 三事件的订阅方、轮末兑现方;换新图指令由它回发 | -| 下游 | [奖励道具经济](../战斗循环/奖励道具经济.md) | 本系统只上报"这格有无奖励资格"的事实;奖励内容与档位不经本系统 | +| 下游 | [奖励道具经济](../战斗循环/奖励道具经济.md) | 本系统只上报"这格有无格面资源资格"的事实;资源内容与极性兑付不经本系统 | | 下游 | [HUD 框架](../表现与支撑/HUD框架.md) | 呈现义务归 HUD 框架 | ## P0 最小闭环 @@ -214,7 +216,6 @@ | 优先级 | 内容 | 后置原因 | |---|---|---| -| P1 | 标错(控制失败)惩罚落地 | 惩罚方案未拍板(见「待拍板」);落地前标空只判"不中",无额外后果 | | P2 | 探测类道具的查询接口 | 接口归[辅助道具](辅助道具.md)定稿,本系统不预写 | | P2 | 地形变异接入的格面规则 | 地形变异尚未定稿;接入时走本文修订流程 | @@ -227,8 +228,8 @@ 每条都可单独验证:构造给定局面,执行动作,核对结果。 - 数字恒真:任意已开安全格的数字恒等于其 8 向相邻雷数;出生区无雷、数字恒真、初始展开不吞全图三条结构前提任一不满足时,装板被拒绝。 -- 初始展开恰等:装板后翻开的格集合恰为"出生 3×3 加连通开阔地"——不止 3×3,也不外扩一圈;全程免费、无奖励、计入清图进度;跨轮不重放。 -- 连锁免费且遇旗即止:一次触发连锁翻开任意多格,扣费恒为 1 点;旗格不被链开、不作传播跳板;连锁格计入清图进度、奖励资格照常。 +- 初始展开恰等:装板后翻开的格集合恰为"出生 3×3 加连通开阔地"——不止 3×3,也不外扩一圈;全程免费、恒无格面资源(封锁格)、计入清图进度;跨轮不重放。 +- 连锁免费且遇旗即止:一次触发连锁翻开任意多格,扣费恒为 1 点;旗格不被链开、不作传播跳板;连锁格计入清图进度、资源资格照常。 - 挖有旗格被拒:拒绝原因可辨("须先拔旗"与"不相邻"数据可分),棋盘与行动点余额不变。 - 已引爆雷格可通行:挖雷后轮次不结束,小人可站、可经已开区穿行续挖;雷格不计清图、不可再挖再插旗。 - 移动合法且预览同源:目标未开或无已开区连通路径时拒绝;路径预览与实际执行逐格相同;移动免费、零事件。 @@ -244,7 +245,6 @@ | 条目 | 现状与失义原因 | 建议归属 | |---|---|---| -| 标错(控制失败)的惩罚 | 未定案:候选为"敌方伏击 +1";旧体系留有原型实测义务,至今未执行。落地前标空只判"不中",无额外后果 | 数值归[敌人系统](../战斗循环/敌人系统.md),兑付归[战斗结算](../战斗循环/战斗结算.md) | | 连锁批量奖励的溢出吸收 | 一条大连锁一次给出大量奖励资格,超出增益叠层上限时如何处理(折算、顺延或显式接受)未定 | [战斗结算](../战斗循环/战斗结算.md)与[奖励道具经济](../战斗循环/奖励道具经济.md)条目化 | ## 版本历史 @@ -253,3 +253,4 @@ |---|---|---| | v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | | v0.2 | 2026-09-15 | 雾格残留清理:关闭「待拍板」三条雾失义登记(连锁开雾格与雾内旗恒不中、开格事件的变异标记透传、四格态中的两个雾态)——现行连锁与旗判定口径已按"全部安全格"写在正文,开格事件仍携带随格只读的变异标记(通用变异框架保留),格态呈现收窄为已开 / 未开两态。规则本体不变 | +| v0.3 | 2026-09-15 | **格面资源批(用户拍板四点)**:① 初始展开格定名**封锁格**(已开、计入清图进度、恒无格面资源、不再有任何加成),铁律表"无奖励"改"无格面资源";② 挖开格事件"奖励资格"字段改"格面资源资格"——安全格与雷格恒有(雷格不再恒无),封锁格恒无;③ 旗生命周期补结算队列口径:标旗 / 撤旗都是动作,轮末经战斗结算抵消过滤(标旗后被撤旗不兑付、行动点不返;开格不可撤);④ 标错惩罚条目与 P1 后置删除——惩罚已定为该安全格格面资源的负向兑付(极性矩阵,归奖励道具经济 / 战斗结算),本系统只报"标空"事实;⑤ 清图呈现口径注记:剩余安全格计数即"剩余未探索安全区域"。玩家说法"失控反噬"随三选一反噬下线改"控制失败" | diff --git a/design/registry/entities.yaml b/design/registry/entities.yaml index b2ae2935..7cd79d39 100644 --- a/design/registry/entities.yaml +++ b/design/registry/entities.yaml @@ -127,8 +127,9 @@ entities: ambush: { display_name: 伏击(敌方增益), target_side: enemy, magnitude: "+3 flat", duration_settlements: 1, max_stack: 16, stack_policy: stack, source_class: mine_hit } weaken: { display_name: 削弱(标中旗 debuff), target_side: enemy, magnitude: "-65 percent", duration_settlements: 1, max_stack: 16, stack_policy: stack, source_class: flag_hit } enrage: { display_name: 暴走(敌方增伤), target_side: enemy, magnitude: "+25 percent", duration_settlements: 1, max_stack: 16, stack_policy: stack, source_class: flag_miss } # 2026-09-12 标错反噬批上线——三池之一(进 enemy_output 池) - off_guard: { display_name: 失衡(我方承伤加深), target_side: hero, magnitude: "+25 percent", duration_settlements: 1, max_stack: 16, stack_policy: stack, source_class: flag_miss } # 2026-09-12 标错反噬批上线——三池之一(进 hero_defense 池,承伤 ×1.25) - value_status: 六行值全部 provisional(2026-09-15 四行→六行——标错反噬批 enrage/off_guard 两行收编;伏击复用为反噬第三池项),验收锚——weaken→行动经济 F1 条款 2(奖励道具经济/战斗结算)· ambush 量纲→敌人系统(条款 3,**量纲已定稿见 ambush_unit_definition**)· 对照表→战斗结算(条款 1)· **weaken 已按 战斗结算 F0 裁决修订 −25→−65(2026-09-10,值域 [60,85]、终值共裁 战斗结算 OQ2——见 anchor_warning 回执)** + off_guard: { display_name: 失衡(我方承伤加深), target_side: hero, magnitude: "+25 percent", duration_settlements: 1, max_stack: 16, stack_policy: stack, source_class: flag_miss } # 2026-09-12 标错反噬批上线——三池之一(进 hero_defense 池,承伤 ×1.25);2026-09-15 格面资源批起 = defense 型负向(标错 defense 型安全格 / 踩到 defense 型雷格兑付) + sapped: { display_name: 乏力(我方输出降低), target_side: hero, magnitude: "-25 percent", duration_settlements: 1, max_stack: 16, stack_policy: stack, source_class: flag_miss } # 2026-09-15 格面资源批新增——weaken 型负向(标错 weaken 型安全格 / 踩到 weaken 型雷格兑付),进 hero_offense 池(attack_up 镜像);值 provisional + value_status: 七行值全部 provisional(2026-09-15 四行→六行——标错反噬批 enrage/off_guard 两行收编;六行→七行——格面资源批 sapped 收编为 weaken 型负向;伏击复用为反噬第三池项〔现为 blast 型负向〕),验收锚——weaken→行动经济 F1 条款 2(奖励道具经济/战斗结算)· ambush 量纲→敌人系统(条款 3,**量纲已定稿见 ambush_unit_definition**)· 对照表→战斗结算(条款 1)· **weaken 已按 战斗结算 F0 裁决修订 −25→−65(2026-09-10,值域 [60,85]、终值共裁 战斗结算 OQ2——见 anchor_warning 回执)** ambush_unit_definition: **量纲已定稿(2026-09-09 敌人系统 GDD Rule 6/F2——registry OQ2 关闭条件兑现)**:+3 flat = 每层伏击为每次攻击类行为(attack/heavy)附加 3 点主角 HP 伤害(后置加法、不进倍乘);charge 拍零兑付(空拍蒸发);值仍 provisional(锚验收归 奖励道具经济/战斗结算——行动经济 F1 条款 3;敌人系统 供给 cap 表值与单结算自然边界口径见 clause3_supply 条目) anchor_warning: weaken 行 vs 行动经济 F1 条款 2 锚两独立线性代理同向预检不过(百分点·结算暴露 25 vs 100;原型战斗量级 ≈1 vs ≈4 当量)——战斗结算 对照验收优先裁决,登记 战斗结算 强制检查点输入。**修复空间不对称(2026-09-09 增补)**:每结算瞬时当量归一 m_w≥51 可行(F2 越域界随移 AP 界 −408%/表界 −816%);每 AP 总暴露归一 m_w>100 被 percent ∈ [-100,100] 域禁止(该分支不可行)——OQ1 前置步骤:战斗结算 先钉死归一口径,口径落定前禁止数值修订;落总暴露则现实解 = 奖励道具经济 重定最低档参照。**参照对象迁移注记(2026-09-09 奖励道具经济 评审;2026-09-11 回迁)**:最低档安全格 buff 当量的参照对象曾迁 defense_up 当量(attack_up 时为死行——奖励道具经济 F4 迁移)——**2026-09-11 用户裁决"基础攻击恒存在"(HeroTable.atk 域 [1,999]、0 加载拒绝、MVP=6)后 attack_up 复活,参照对象回迁 attack_up 当量**(消费面 = 主角战斗段先手攻击——战斗结算 GDD 同批;defense_up 迁移退役为历史记录,attack_up 入池时 tier_min_buff 重算);本条与 clause3_supply.direction_precheck 的 25 vs 100 预检算术系 attack_up 口径历史登记——defense_up |−50|×dur2 与 attack_up 数值巧合全等(100pp),今日结论不变;**迁移后预检未按新参照重跑**的义务已于 2026-09-14 战斗结算 重算批兑现(F0/F1 按 attack_up 当量重跑 + F1 锚对照实物改 attack_up 行——本迁移注记关闭)。**F0 裁决回执(2026-09-10 战斗结算 GDD——红警关闭)**:归一口径 = **每结算瞬时当量**(总暴露分支被 percent schema 域禁止 + 与"单结算自然边界"已锁事实冲突,排除);m_w 修订 −25 → **值域 [60,85]/默认 −65**(mvp_content.weaken 已同批改写——锚两腿 @D_ref=12:7.8 > 6.0 严格大于 ✓ / 7.8 ≥ E_dig 4.5 ✓〔E_dig 读数 2026-09-14 战斗结算 重算批按 难度曲线与Boss v3 曲线重推——原 7.2 随口径退役〕);地板 = 乘数零点 −100pp、交叉层数 = ⌈100/m_w⌉ = 2(原"7 层触地板"预读按 −400% 合成带估读,更正);defense_up 参照保持(总暴露分支的"重定参照"现实解未采纳);终值 = 奖励道具经济/战斗结算 共裁(战斗结算 OQ2);增益状态 GDD 正文不改以本条为准(收编先例) rule4_exemption: 定义表非进度成长表,键 = effect_id(数据配置 Rule 4 豁免,schema 注释承载) @@ -137,7 +138,7 @@ entities: api: notify_battle_start / apply_effect(effect_id, source) -> bool / query_active(side) -> Array(插入序;六归因字段+display_name+授予时快照投影)/ decay_round() -> int / notify_battle_end() -> bool——战斗结算 消费契约,provisional 登记 settlement_obligations: 八项(战斗结算 GDD 门禁评审缺项即 blocking)——① 同轮多授予按确定次序调用 ② 事实→授予恰一次转化(增益状态 不去重)③ percent→乘数换算方向与合成值地板成文 ④ 最后一轮 decay 判定 ⑤ F1 条款 1 效果档位对照表以 增益状态 实例为对照实物 ⑥ 每结算编排恰一次 decay_round(2026-09-09 增——decay 基数=1 先决条件)⑦ 结算明细按授予流水逐条标注来源(合并坍缩归因补偿,2026-09-09 增)⑧ “溢出未生效”行进结算明细协议(Rule 5 后半承载,2026-09-09 增)。**履行回执(2026-09-10)**:八项已全数落位 战斗结算 GDD(Core Rules 3/5/8/10/11 + Formulas F0–F2——落位映射 = 战斗结算 AC 覆盖矩阵"上游义务 23 条"行;③的 AP/表界数值随 F0 修订更新为 −520%/−1040%) presentation_obligations: (2026-09-09 登记 systems-index,缺项即 blocking)HUD框架×4——HUD 常显+EC12 空态规格定稿 / effect_id→icon 映射键契约(形状+色相双通道)/ 有利有害极性呈现映射(数据源 = 战斗结算 SettlementTable 效果语义,非 magnitude 符号)/ 全清状态栏去留;战斗表现×2——溢出行呈现 / origin_cell→玩家可读形态(缩略图/格子高亮);教学引导——“同轮拿满优于跨轮叠”教学(OQ7 配套);奖励道具经济——奖励身份预读(创意风险 #1 切面) - ownership_note: 行动经济 OQ5“标中旗 debuff 档位归 奖励道具经济 表设计”经用户 2026-09-08 拍板收编——初值定稿权归 增益状态(2026-09-15 起为六行:标错反噬批两行随批收编),锚验收权仍归 奖励道具经济/战斗结算,修订走接口漂移回写本条 + ownership_note: 行动经济 OQ5“标中旗 debuff 档位归 奖励道具经济 表设计”经用户 2026-09-08 拍板收编——初值定稿权归 增益状态(2026-09-15 起为七行:标错反噬批两行 + 格面资源批 sapped 一行随批收编),锚验收权仍归 奖励道具经济/战斗结算,修订走接口漂移回写本条 dangling_ref_policy: effect_id 悬空校验**已激活**(2026-09-09 奖励道具经济 RewardTable 首个 effect_id 引用行〔defense_up〕回填——dangling_ref_policy"首个引用字段 owner 补"条款兑现;条件性夹具 = 奖励道具经济 reward_dangling_effect〔AC-17〕) referenced_by: [战斗结算, 奖励道具经济, 敌人系统, HUD框架, 教学引导, 战斗表现] @@ -162,7 +163,7 @@ entities: owner: design/gdd/systems/排雷循环/排雷玩法.md attributes: kind: 三事件回边契约(发射面封闭——TD-SYSTEM-BOUNDARY 回边裁决的 排雷玩法 侧定稿;增删事件 = 接口漂移修订) - cell_revealed: "{cell, kind ∈ {safe, mine}, digit【仅 kind=safe 携带、恒真透传——呈现隐藏归 HUD框架,判定源 = variant_ids,排雷玩法×4③】, variant_ids, channel ∈ {initial, chain, dig}, reward_eligible【initial 恒 false / chain·dig ∧ safe 恒 true / mine 恒 false】}" + cell_revealed: "{cell, kind ∈ {safe, mine}, digit【仅 kind=safe 携带、恒真透传——呈现隐藏归 HUD框架,判定源 = variant_ids,排雷玩法×4③】, variant_ids, channel ∈ {initial, chain, dig}, resource【initial 恒 false(封锁格无资源)/ chain·dig 恒 true——安全格与雷格一视同仁,雷格亦携带格面资源(负向兑付归 战斗结算 极性路由)】}" # 2026-09-15 格面资源批:reward_eligible → resource,旧口径"mine 恒 false"随批作废 flag_judged: "{cell, hit = [cell ∈ M]}×N——轮末统一判定批(基线 = 轮次结束事务开始时旗位,被拔不判;行主序枚举);排雷玩法 诚实重复上报、兑付去重归 战斗结算/奖励道具经济(资格以雷格实例为键——action_economy.flag_rules/行动经济 OQ5)" round_end: "{path_tag ∈ {ap_exhausted, cleared}, continuation_hint}——棋盘路径由 排雷玩法 外发、核心字段逐字段取自 行动经济.last_round_end(读取权 = 接口契约),与 行动经济 stopped 路径 payload 同构;stopped 由 行动经济 直发、排雷玩法 禁双发(action_economy.round_end_carrier 双发射源)" event_order: 同一轮次结束事务内 flag_judged ×N 先于 round_end(全路径统一——stop 腿 排雷玩法 先发旗判定再委托 request_stop,停手不改旗故基线等价);战斗结算 结算触发 = Waiting 相位编排点、不依赖事件到达序(战斗结算×3 强制项之一,systems-index 排雷玩法 门禁块) @@ -204,8 +205,8 @@ entities: 伏击池: 敌方侧共享的伏击层数——本轮踩几颗雷就几层,轮末清零(side-wide 语义,敌人系统 首次定义) 溢出(伏击): 单轮踩雷超过上限(cap)的部分——转为"溢出未生效"明细行可见、不生效(敌人系统 首次定义) 死亡即不动手: 轮到某敌人行动时它已死 → 这一下不打、招式轮转停格(2026-09-09 用户拍板,敌人系统 首次定义) - 资格格: 开出时 reward_eligible=true 的格——排雷玩法 事件面上 chain/dig 通道的安全格;install 期可精确枚举为 S∖R₀(奖励道具经济 首次定义,F1 消费) - 刀: 伤害道具(damage_item)的项目行话,全文同义(奖励道具经济 Rule 5 首次定义);"烧刀/烧包" = 把无法生效的道具白白消耗掉(选定即承诺的成本,奖励道具经济 E10/E12 语境) + 封锁格: 初始展开白送的那批已开格——恒无格面资源、不再有任何加成,但计入清图进度(排雷玩法 首次定义;install 期可精确枚举为 R₀——格面资源摇号清单的排除项;取代旧术语"资格格",2026-09-15 格面资源批) + 格面资源(CellResource): 关联到格子上的资源对象——装板期摇定五型类型身份(attack/defense/heal/blast/weaken),安全格与雷格一视同仁、同池同分布;极性不在资源内,由「动作 × 格型」矩阵在结算期决定正向(奖励)或负向(惩罚)(奖励道具经济 首次定义;取代"安全格奖励"旧名) 批尾: 同一批取号中最后消费的一个号——奖励道具经济 清图奖励身份 = install 批的批尾取号(奖励道具经济 F1 首次定义) 死行: 被当前内容态判定为零消费的表行——加载不致命、不入参考池,复活走 GDD 修订连锁(奖励道具经济 F4 首次定义;历史首例 attack_up〔hero atk=0 时代〕已于 2026-09-11 随"基础攻击恒存在"用户裁决复活,当前内容态暂无在册死行) 预推进: 测试中为到达 scope=σ 而先行丢弃式消费 σ 个 scope 的构造——RngService 全新实例首个 open_stream 恒为 scope 0,derive_at 不推计数器(奖励道具经济 AC 前言首次定义) @@ -242,14 +243,14 @@ entities: unit_count: int [1,3](knob——**遭遇区间下界**〔2026-09-14 难度曲线与Boss 修订批:unit_count 升级区间语义 [unit_count, unit_count_max],战斗结算.begin_battle 实例化期经 RngService encounter 封闭流均匀骰;新敌种首遇/教学位节点固定不加骰〕;默认 1 provisional,多敌语义默认零消费者复验归 关卡节点地图〔敌人系统 OQ2〕) unit_count_max: int [unit_count, 3] 可省略(2026-09-14 难度曲线与Boss 修订批新增——遭遇区间上界;缺省 = 定值,旧行零迁移) atk_min/atk_max: 可选配对 int [0,999](2026-09-14 敌方攻击区间批——上阶/下阶区间随机;缺省 = 定值行向后兼容;跨字段:必成对 · **atk = (min+max)/2 中点锚**;roll 时机 = 遭遇骰同流〔encounter 恰一 scope,数量骰先、atk 骰后〕spawn 期**整战持久**〔每拍抖动否决——数字可读性锚〕,战斗结算.begin_battle roll → 敌人系统.spawn enemy_atk_override 收确定值〔敌人系统 零随机纪律保持〕;MVP 六行 ±3 provisional 归 难度曲线与Boss;验收 = 完美策略档 0 加成通关 ≤40%〔OQ7〕;接口漂移 = 敌人系统.spawn 签名 +1 参数〔正式侧 GDD/registry 修订批随 ADR-0009 同批〕) - armor_type: enum {none, a, b} 缺省 none(2026-09-14 护甲克制批转正登记——伤害类型 × 护甲克制,克制矩阵 = settlement_table.armor_effectiveness〔特化 ×150 / 无甲 ×100 / 对位 ×50〕;MVP 映射 goblin=none / bugbear=a / ogre_chief=b;数值 provisional 归 难度曲线与Boss) + armor_type: enum {light, ward, heavy} 缺省 light(2026-09-14 护甲克制批转正登记——攻击类型 × 护甲克制,克制矩阵 = settlement_table.armor_effectiveness〔克制 ×150 / 中性 ×100 / 被克 ×50〕;MVP 映射 goblin=light / bugbear=ward / ogre_chief=heavy;**2026-09-15 命名统一批:原 enum {none, a, b} 为位置键(无语义、且"无甲/甲A/甲B"在文档间已分裂成四种写法),改 {light, ward, heavy} = 轻甲 / 魔法护甲 / 重甲**;数值 provisional 归 难度曲线与Boss) hp: int [1,999](knob——难度修饰前基线;MVP 18 provisional 出处待查) atk: int [0,999](knob——attack 行为伤害基值;MVP 4 provisional 出处待查;0 = 纯伏击伤敌种合法) heavy_multiplier: int [1,16](knob;无 heavy 拍敌种不消费——非校验项,增益状态 max_stack 先例;MVP 2 provisional) pattern: StringList(行为环;元素 ∈ {attack, charge, heavy} MVP 校验域——guard/boost/hinder/summon 预留值校验拒绝〔棋盘生成 solver_rules 冻结先例〕;环长 [1,8]) advantage_per_round_cap: int [0,16](knob;**MVP 默认 4 定稿**〔2026-09-09——反灾难护栏定位,旧默认 8 溢出协议死码已废弃〕;0 = 免疫伏击合法极端;行动经济 F1 条款 3 供给表值来源字段) rowset_rule: 每行集恰一敌种(行集内 enemy_id 唯一 = 表结构校验,违规加载期致命)——多敌种同深度选择规则归 关卡节点地图/难度曲线与Boss(provisional);精英/Boss 编码位预登记 敌人系统 OQ7(键冻结下同深度第二敌种行触发行集致命——改键走 数据配置 Rule 4 接口漂移,关卡节点地图 定稿时强制核对) - mvp_content: **恰 3 敌种(2026-09-14 难度曲线与Boss 修订批转正——DND 更名批用户指令:grub→goblin / ambusher→bugbear / boss_guardian→ogre_chief;旧两敌种登记由本条替代;敌人系统 AC-16③ 物种集断言随批更新为 {goblin, bugbear, ogre_chief})**:goblin(地精,[attack] 单拍环——L1 D0 24hp/7atk ×[1,2] 教学位固定 ×1、L1 D1 群 13/5 ×[2,3];armor=none)· bugbear(熊地精,[attack,charge,heavy] 三拍环——L1 D2 40/9 ×1、L1 D3 群 18/6 ×[2,3]、L2 D0 锚行 30/7;armor=a)· ogre_chief(食人魔酋长,[attack,attack,charge,heavy] 四拍 Boss 环——L1 D4 150/9 ×1;armor=b);heavy_multiplier=2 全员;出处 = 切片 enemy.tres v3(试玩批次 1 裁决 + 遭遇随机化批),曲线数值归 难度曲线与Boss + mvp_content: **恰 3 敌种(2026-09-14 难度曲线与Boss 修订批转正——DND 更名批用户指令:grub→goblin / ambusher→bugbear / boss_guardian→ogre_chief;旧两敌种登记由本条替代;敌人系统 AC-16③ 物种集断言随批更新为 {goblin, bugbear, ogre_chief})**:goblin(地精,[attack] 单拍环——L1 D0 24hp/7atk ×[1,2] 教学位固定 ×1、L1 D1 群 13/5 ×[2,3];armor=light)· bugbear(熊地精,[attack,charge,heavy] 三拍环——L1 D2 40/9 ×1、L1 D3 群 18/6 ×[2,3]、L2 D0 锚行 30/7;armor=ward)· ogre_chief(食人魔酋长,[attack,attack,charge,heavy] 四拍 Boss 环——L1 D4 150/9 ×1;armor=heavy);heavy_multiplier=2 全员;出处 = 切片 enemy.tres v3(试玩批次 1 裁决 + 遭遇随机化批),曲线数值归 难度曲线与Boss load_bearing_rules: 多敌模型(1–3 同敌种单位,增益状态 单敌假设回验不成立——见 status_effect.single_enemy_assumption)· 行为环确定性轮转(零随机;先作用后推进;死亡即不动手——轮到前被杀本拍不打指针冻结;同步轮转定理)· 效果 side-wide(伏击池 = side 共享,增益状态 零接口变更)· 行值快照抗热重载(增益状态 EC9 同款)· 零随机零 UI 零事件订阅(排雷玩法 事件面不含 敌人系统——事实经 战斗结算 转化) settlement_obligations: 六项(敌人系统 GDD 门禁评审缺项即 blocking)——① 推进每结算恰一次(敌单位专属——主角无环)+ 结算内调用序成文 query_attack→apply_damage→advance ② 雷→伏击恰一次转化 ③ clamp/负值/溢杀与死亡判定时机成文 ④ F1 条款 3 闭合对账(cap 表值 + 量纲 + 棋盘生成 actuals p10 非 target 参数)⑤ 默认目标消费与单体/AOE 分流 ⑥ 伏击 cap 溢出"溢出未生效"明细行协议。**履行回执(2026-09-10)**:六项已全数落位 战斗结算 GDD(Core Rules 5/6/9/10/12 + Formulas F3/F4——落位映射 = 战斗结算 AC 覆盖矩阵) hud_obligations: 四项(视觉推测型呈现,缺项即 blocking)——① enemy_id→图像线索映射清单成文(预告时序=下一拍预告、挖掘期全程可见;含强度档位/环长直觉编码说明;形状+色相双通道)② 映射全局恒定(enemy_id 键——跨 run 禁重掷)③ 顺位与存活可读 ④ 敌方 side 池呈现口径 @@ -272,40 +273,34 @@ entities: type: schema_data owner: design/gdd/systems/战斗循环/奖励道具经济.md attributes: - table: RewardTable(数据配置 承载,键 = reward_id;奖励道具经济 回填 owner,2026-09-09 定稿回填、同日 full 评审增补 display_name——含 use_timing 字段〔game-concept"使用时机"预留的兑现,MVP 单值 pre_settlement 承重,扩枚举走修订〕) + table: RewardTable(数据配置 承载,键 = reward_id;奖励道具经济 回填 owner;**2026-09-15 格面资源批结构性重写**——旧 category / use_timing / 库存 / 供给轴随可选类删除整批下线,五型 × 极性字典取代〔历史结构见底部修订记录〕) fields: reward_id: String(表内主键) - category: enum {buff, damage_item, heal_pack, instant_aoe, instant_heal}——MVP 恰五值(2026-09-11 两级奖励批两类交付轴:即时类 {buff, instant_aoe, instant_heal} 当场兑付不进库存 / 可选类 {damage_item, heal_pack} 入库存走窗口),预留值(resource/aux_item 等)校验拒绝 fail-fast # was: {buff, damage_item, heal_pack} 三值 before 2026-09-12 - effect_id: String 可空——buff 类必填(StatusEffectTable 精确引用,悬空校验已激活);非 buff 类恒空 - display_name: String 非空——玩家可读名(HUD框架 呈现数据源,本地化归 设置与本地化;2026-09-09 评审增补,敌人系统/增益状态 同库惯例) - power: int [0, 999](knob)——item 类加载校验 ≥ 1;buff 类不消费非校验(敌人系统 heavy_multiplier 先例) - power_min/power_max: 可选配对 int [1,999](2026-09-14 伤害量值区间批——上阶/下阶区间随机;缺省 = 定值行向后兼容〔armor_type 先例〕;跨字段:必成对 · buff 行禁止 · **power = (min+max)/2 中点锚**〔行动经济 条款①期望当量不漂移〕;roll 时机 = 身份预分配批内追加取号〔既有取号序零扰动〕,快照 E14 授予时口径不变、战斗结算/呈现零改动) - weight: int [0, 999](knob)——0 = 该池不出此行(合法极端,取号前剔除) - pool_tag: enum {safe_cell, active_inject, clear_default}(2026-09-14 难度曲线与Boss 修订批增补 active_inject——供给控制器注入池〔可选类三行移出格子权重池,由 RewardSupplyController install 期注入:首件保证 + 指数递减〕;clear_ 命名空间预留、校验拒绝——棋盘生成 elite_ 同款) + cell_type: enum {attack, defense, heal, blast, weaken}——五型封闭(格面资源类型身份;表里出现清单外值加载拒绝 fail-fast) # 2026-09-15 新增,取代 category + polarity: enum {positive, negative}——同型两行:正向行参与摇号(权重 = 类型频次),负向行纯兑付字典、不消费权重 # 2026-09-15 新增 + effect_id: String 可空——percent 类行(attack/defense/weaken 正负两向)必填(StatusEffectTable 精确引用,悬空校验已激活);flat 直付行(直伤/群伤/治疗)恒空 + stacks: int [1,16] 可省——多层授予行(blast 负向 ambush ×2 层);缺省 1 + display_name: String 非空——玩家可读名(HUD框架 呈现数据源,本地化归 设置与本地化) + power: int [0, 999](knob)——flat 类加载校验 ≥ 1;percent 类不消费非校验(敌人系统 heavy_multiplier 先例) + power_min/power_max: 可选配对 int [1,999](区间随机;缺省 = 定值行向后兼容;跨字段:必成对 · percent 行禁止 · power = (min+max)/2 中点锚〔行动经济 条款①期望当量不漂移〕;roll 时机 = 身份预分配批内追加取号) + weight: int [0, 999](knob)——正向行 = 类型频次;0 = 该型不出(合法极端,取号前剔除);负向行不消费 + pool_tag: enum {cell, clear_default}(cell = 格面资源单一池——安全格与雷格一视同仁同池同分布;clear_ 命名空间预留、校验拒绝——棋盘生成 elite_ 同款) # 2026-09-15 safe_cell→cell 更名 + active_inject 删除 tier: int [1, 8](knob)——强度档位序数(与当量零耦合) - use_timing: enum {pre_settlement}——MVP 唯一值,扩枚举走 GDD 修订 - cross_field_validation: 加载期致命族——池空(每 pool_tag 各 ≥1 行 weight>0)· clear_default 恒正当量(≥1 活行 ∧ power≥1 ∨ effect_id 非空——行动经济 条款④"清图奖励>0"的行级兑现口径)· item 行 power≥1 · buff 行 effect_id 必填/非 buff 恒空 · safe_cell 活 buff 行集非空(tier_min_buff 定义前提,F1 对偶)· **floor_supply_missing(K_dmg ≥ 1 ∧ safe_cell 池无 power ≥ P_min 活刀行)· no_damage_row(K_dmg = 0 ∧ 全池零活刀行——零伤害世界后闸,敌人系统 OQ9 并案)〔2026-09-09 评审增补,跨 RewardConfigTable 校验〕** - mechanics: 奖励身份 install 期预分配(roll_board 恰一次、行主序、消费 reward_roll 封闭流恰一 scope 批〔格批 + 清图批尾一号 × F5 草稿数——每稿含清图一号、草稿作废连清图一号一并作废〕;Ready 后只读、无重掷 API)· 授予期零随机(身份恒定跨轮;换图映射消亡)· **库存关卡域(2026-09-11 关内延续——跨战斗/跨图延续、关卡末 clear_inventory 清空;原战斗域 battle_over 全清作废)**· **两类交付轴(2026-09-11):即时类 {buff, instant_aoe, instant_heal} 授予段当场兑付不进库存(默认根 75%)/ 可选类 {damage_item, heal_pack} 入库存走窗口(25%、更强)——category 五值枚举**· **窗口单件制(2026-09-11 拍板——至多选用一件)**· **治疗两级:instant_heal 小额即时 + heal_pack 稀缺强治疗(w 25%→6%、p 4→12)**· 道具伤害恒定表值不吃 percent 修正(2026-09-11 后 attack_up 已复活〔消费面 = 主角先手攻击〕、入池随奖励改造批——原死行口径与"锚参照迁 defense_up"注记退役;行动经济 条款 2 锚参照对象 = attack_up 当量)· 道具段照常消耗(选定即承诺:无存活敌的已选刀照常 Used + 零效果 + "已消耗未生效"明细行——理由 2026-09-09 评审更正为守卫所有权不对称 + 反抖动,原"敌 HP 不可见"与 敌人系统 血条数字可读矛盾作废)· **窗口锚点 = 授予段后、增益/减益段前(2026-09-09 评审用户拍板:当轮拾取当轮可用;核心段序 buff/debuff > 道具 > 战斗不变)**· 清图槽允许 buff 行(运行时满层零兑付 = 合法例外 + "奖励未生效"行,预警④监控)· F5 保底 = 草稿-校验-提交重 roll(K_dmg=0 / N_draft=32 provisional——**2026-09-14 难度曲线与Boss 修订批转正:K_dmg=0"禁区默认值"条款解除**,刀保底语义由供给控制器战斗首件保证取代;no_damage_row 后闸仍托底零活刀行世界)· **重复受理幂等(同格重复 grant / 同批次重复 grant_clear → 同一快照/身份 + 诊断;受理/兑付恰一次归 战斗结算×②③)** - api: 封闭枚举 10 入口(provisional,实现期 ADR 定名)——roll_board / query_identity(返回 {reward_id, category, tier} 引用级投影;未开格恒可查——辅助道具 桥接结构前提;清单外坐标 → null + 诊断)/ grant(同格重复受理幂等 + 诊断)/ grant_clear(同批次重调幂等 + 诊断)/ stock(仅受理道具类,未知 item_id/buff 类拒绝;来源 {cell, round} 调用方供给不校验真值)/ use(零游戏态守卫;回执 = 授予时快照投影)/ query_inventory(Used 保留只读;枚举序 = stock 受理序)/ clear_inventory / retire_mapping / equivalence_supply(全活行投影 + tier_min_buff)+ weighted_pick 纯函数面;新增入口 = 接口漂移,**新增入口须随附全输入域语义表(2026-09-09 评审纪律)** - mvp_content: **默认根行集重登记(2026-09-14 难度曲线与Boss 修订批——减伤墙批 + 供给控制器批 + clear_blast 换位批转正;值 provisional 归 难度曲线与Boss;2026-09-11 两级奖励批旧登记由本条替代)**:格子池四行即时类(attack_up_basic buff→attack_up w20 t2 / defense_up_basic buff→defense_up **w16** t2〔减伤墙批 24→16,attack_up 升池内最高行〕/ spark_aoe instant_aoe p4 w16 t1 / heal_minor instant_heal p4 w15 t1——池合计 67)+ 注入池三行可选类(knife_t1 damage_item p8 **w60 active_inject** t1 / knife_adv damage_item p16 **w30 active_inject** t2 / heal_pack heal_pack p12 **w10 active_inject** t2)+ clear_blast(instant_aoe p40 w1 t2 clear_default——**清图槽换位:原 clear_knife 入库刀由当场兑付全体存活敌的 instant_aoe 替代,不入库不占可选类供给;完美板 ×2 = 80**);tier_min_buff = 2;战斗结算 条款⑤计价基元随换位重推(C = power = 40——clause5_dominance.c3_ruling);**2026-09-14 伤害量值区间批:五行 power 区间化**(heal_minor [2,6] / knife_t1 [5,11] / heal_pack [6,18] / knife_adv [10,22] / clear_blast [25,55]——中点恒等原值,身份批内上阶/下阶随机;验收口径 = 完美策略档 0 加成通关率 ≤40%〔OQ7 完美档基线 100%〕) - direction_precheck: **刀供给方向预检(2026-09-09 评审批登记,敌人系统 clause3_supply 先例)**——击杀需求 18(单敌)/ 54(3 敌,敌人系统 EnemyTable 参考行);刀伤供给期望/板 ≈ |资格格| × 40% × 5 = 2|资格格| → |资格格|=10 保守板:单敌 ≈0.9 板、3 敌 ≈2.7 板("单敌无忧 / 2–3 敌贴近下界"现值有锚);输入缺口 |资格格| 分布待 棋盘生成 actuals p10/p50 落地后重跑;治疗对照基准 max_hp=50(原型锚——HeroTable 值出处建议 敌人系统/数据配置 回写补登) - settlement_obligations: 六项(战斗结算 GDD 门禁评审缺项即 blocking,清单全文见 奖励道具经济 GDD Dependencies;2026-09-09 评审同步)——① 结算段序骨架(授予→**窗口**→增益/减益→道具→战斗→衰减→判定;窗口锚点 = 授予段后;窗口选择序 = 回放输入)② 受理分流 + **每格恰一次** + 满层零兑付"奖励未生效"行(含聚合计数字段)③ clear_reward 授予路径(增益状态 OQ4 关闭条件)④ 窗口与道具段编排(usable_now 组装/选定序/满血守卫 + 逐件动态守卫/零效果判定"已消耗未生效"行/**击杀结果进流水**/治疗 clamp)⑤ 生命周期编排(battle_over clear_inventory〔清空反馈计数〕/ retire 映射消亡)⑥ roll_board 恰一次。**履行回执(2026-09-10)**:六项已全数落位 战斗结算 GDD(Core Rules 4/5/7/9/编排专章——落位映射 = 战斗结算 AC 覆盖矩阵;缺口预检 2 阻塞级 deferral 已随 AC-7/AC-15/16/20 承载) - hud_obligations: 五项(缺项即 blocking;2026-09-09 评审 3→5 扩容)——① 已开格 + 库存身份恒定可读(库存常读条 = 挖掘期规划面)② 道具使用窗口呈现(授予段后弹出/选用/跳过/序/usable_now/触发政策注记)③ 结算明细四类行(道具/"奖励未生效"〔聚合计数〕/"已消耗未生效"/"使用被拒")④ H2 清图奖励行强调呈现 ⑤ battle_over 库存清空可见反馈 - high_glow_nodes: H1 开格拾取瞬间 / H2 清图奖励兑付 / H3 道具抢杀窗口(2026-09-09 评审诚实化:H1/H2 = 奖励侧常规节拍登记,H3 = 创意风险 #2 战斗侧执行兑现;**风险 #2 排雷侧"完美排雷爆发结算"机制本体归 战斗结算 强制检查点、#3 标中旗节拍补偿归 战斗结算——奖励道具经济 只交付插槽与明细行数据面**;呈现义务 HUD框架×④⑤) + cross_field_validation: 加载期致命族——池空(cell 池 ≥1 正向行 weight>0)· 五型正向行齐备 · 五型负向行齐备(字典完整性——缺任一极性行致命)· clear_default 恒正当量(≥1 活行 ∧ power≥1 ∨ effect_id 非空——行动经济 条款④"清图奖励>0"的行级兑现口径)· percent 行 effect_id 必填/flat 行恒空 · flat 行 power≥1 # 2026-09-15 重写——旧 floor_supply_missing / no_damage_row 随可选类删除失义退役 + mechanics: 格面资源身份 install 期预分配(roll_board 恰一次、行主序、消费 reward_roll 封闭流恰一 scope 批〔格批 + 清图批尾一号〕;全部非封锁格逐一摇定类型——安全格与雷格同池同分布、封锁格不入摇号清单;Ready 后只读、无重掷 API)· **极性不在资源内**——「动作 × 格型」矩阵(开安全格/标中雷 = 正向、开雷格/标错安全格 = 负向、标旗后撤旗 = 零兑付)字典定义归 奖励道具经济、路由执行归 战斗结算 授予段(结算队列 + 抵消过滤——标旗后被撤旗不结算)· 授予期零随机(身份恒定跨轮;换图映射消亡)· 负向恒即时(不入库、无库存语义——库存已随可选类删除下线)· 满层零兑付 = 合法例外 + "奖励未生效"行 · 重复受理幂等(同格重复 grant / 同批次重复 grant_clear → 同一快照/身份 + 诊断;受理/兑付恰一次归 战斗结算×②③) + api: 封闭枚举入口(provisional,实现期 ADR 定名)——roll_board / query_identity(返回 {reward_id, cell_type, tier} 引用级投影;未开格恒可查——辅助道具 桥接结构前提;清单外坐标 → null + 诊断)/ grant(同格重复受理幂等 + 诊断)/ grant_clear(同批次重调幂等 + 诊断)/ retire_mapping / equivalence_supply(全活行投影 + tier_min_buff)+ weighted_pick 纯函数面;新增入口 = 接口漂移,新增入口须随附全输入域语义表 # 2026-09-15 删 stock/use/query_inventory/clear_inventory(库存轴下线) + mvp_content: 十行(2026-09-15 格面资源批;值 provisional 归 难度曲线与Boss)——格面池正向五行(attack_up buff→attack_up w20 t2 / defense_up buff→defense_up w16 t2 / spark_aoe flat p4 w16 t1〔blast〕/ heal_minor flat [2,6] w15 t1〔heal〕/ weaken buff→weaken w12 t1)+ 负向五行纯字典(enrage attack〔→enemy_output〕/ off_guard defense〔→hero_defense〕/ 直伤 heal flat p4〔不经增益状态〕/ ambush+2 blast〔stacks=2〕/ sapped weaken〔→hero_offense〕)+ clear_blast(flat [25,55] w1 t2 clear_default——完美板 ×2 期望中点 80);类型频次 = 正向行权重(20/16/16/15/12 合计 79);tier_min_buff = 2 + direction_precheck: **刀供给方向预检随可选类删除失义退役(2026-09-15)**——历史读数见底部修订记录;新对账锚 = 行动经济 条款②③ 左臂(正向格面资源当量供给)随格面资源批重推,义务归 难度曲线与Boss 调参批 + settlement_obligations: 四项(战斗结算 GDD 门禁评审缺项即 blocking,清单全文见 奖励道具经济 GDD Dependencies)——① 结算段序骨架(授予→增益/减益→战斗→衰减→判定)② 极性路由受理 + 每格恰一次 + 满层零兑付"奖励未生效"行(含聚合计数字段)③ clear_reward 授予路径(增益状态 OQ4 关闭条件)④ 生命周期编排(battle_over retire 映射消亡)+ roll_board 恰一次 # 2026-09-15 由六项收拢(窗口/道具段与库存编排随可选类删除失义) + hud_obligations: 三项(缺项即 blocking)——① 已开格资源身份恒定可读(挖掘期规划面)+ 未开格类型可查面的呈现深度(预读边界待拍板)② 结算明细行(效果行/"奖励未生效"〔聚合计数〕/标旗未中行/直伤行)③ H2 清图奖励行强调呈现 # 2026-09-15 由五项收拢(库存常读条/道具窗口随可选类删除失义) + high_glow_nodes: H1 开格拾取瞬间 / H2 清图奖励兑付(奖励侧常规节拍登记;**风险 #2 排雷侧"完美排雷爆发结算"机制本体归 战斗结算 强制检查点、#3 标中旗节拍补偿归 战斗结算——奖励道具经济 只交付插槽与明细行数据面**;呈现义务 HUD框架×③) # 2026-09-15 H3 道具抢杀窗口随可选类删除失义 referenced_by: [战斗结算, HUD框架, 难度曲线与Boss, 辅助道具, 战斗表现, 教学引导] - name: reward_config type: schema_data owner: design/gdd/systems/战斗循环/奖励道具经济.md attributes: - table: RewardConfigTable(数据配置 承载,**单行全局**——2026-09-09 奖励道具经济 full 评审接口漂移新增:奖励道具经济 三个标量 knob 的 Rule 1 单一事实源载体,R3 override key 空间随之存在) - fields: - k_dmg: int [0, 999](默认 **0**——2026-09-14 难度曲线与Boss 修订批转正〔切片 reward_config.tres 现值〕:原默认 1 与"难度曲线与Boss 禁区默认值"条款由供给控制器战斗首件保证取代;no_damage_row 加载后闸仍托底零活刀行世界) # was: 默认 1、K=0 = 难度曲线与Boss 禁区默认值 before 2026-09-14 - active_p0: float [0,1](默认 0.4 provisional——供给控制器首件之后每张新板注入概率初值;E[战斗获取] ≈ 1 标定目标,归 难度曲线与Boss) - active_decay: float (0,1](默认 0.5 provisional——注入概率指数递减 0.4→0.2→0.1→…永不绝育;加难杠杆候选 0.6 随 难度曲线与Boss OQ7 扫描) - n_draft: int [1, 999](默认 32)——F5 草稿重 roll 上限 - p_min: int [1, 999](默认 8 = 默认根最低刀 power——2026-09-11 两级奖励批)——K≥1 供给闸刀力下界(floor_supply_missing) # was: 默认 4 before 2026-09-12 - rule4_exemption: 单行全局常量表(HeroTable/ActionEconomyTable 先例) + table: "**已删除(2026-09-15 格面资源批)**——RewardConfigTable 随可选类道具整体删除下线:k_dmg / active_p0 / active_decay / n_draft / p_min 全部供给控制器与按板保底参数失义;清图奖励配置并入 RewardTable clear_default 槽;切片 reward_config.tres 随代码修改批删除(历史字段定义见底部修订记录)" referenced_by: [奖励道具经济, 难度曲线与Boss, 战斗结算] - name: settlement_table @@ -316,18 +311,16 @@ entities: fields: equivalence_ref_damage: int [1,999](knob,默认 12 provisional——当量参考敞口 D_ref,F1 通货;变更触发全对照表 + 条款③⑤对账重跑,禁独立调参) p_perfect: int {100,200} percent(knob,默认 200 provisional——完美排雷清图奖励**第二份兑付触发**;2026-09-10 战斗结算 评审批修订:真实双份交付载体〔Core Rule 13#2〕——100 = 仅高光、200 = 双份交付,非整数倍数乘数无运行时载体、域外加载致命;上界受护栏 B 约束〔双读数:D_ref 口径 24 / DPS 严格读数 ≈8,裁决归 难度曲线与Boss〕) - segment_order: StringList(结构冻结——段序骨架 [grant, item_window, buff_debuff, item, combat, decay, verdict];加载期恒等拍板序校验违例致命,防实现乱序静默漂移) - source_label_map: Dictionary source_class→文案键(结构冻结——P2 归因呈现映射;键集 = 增益状态 source_class ∪ {道具/判定扩展, enemy_action, flag_miss}——2026-09-10 战斗结算 评审批修订;新增键 = 接口漂移) - effect_pool_map: Dictionary effect_id→pool {hero_offense|hero_defense|enemy_output|flat_attach}(结构冻结——F2 效果语义映射,增益状态 Rule 7 载体;键 ⊆ StatusEffectTable 活行集、悬空加载期致命;新 effect_id 上线须随批登记) + segment_order: StringList(结构冻结——段序骨架 [grant, buff_debuff, combat, decay, verdict];加载期恒等拍板序校验违例致命,防实现乱序静默漂移;2026-09-15 格面资源批五段——item_window/item 两段随可选类删除下线,旧七段序见底部修订记录) + source_label_map: Dictionary source_class→文案键(结构冻结——P2 归因呈现映射;键集 = 增益状态 source_class ∪ {判定扩展, enemy_action, flag_miss}——2026-09-10 战斗结算 评审批修订;2026-09-15 格面资源批删"道具"扩展键;新增键 = 接口漂移) + effect_pool_map: Dictionary effect_id→pool {hero_offense|hero_defense|enemy_output|flat_attach}(结构冻结——F2 效果语义映射,增益状态 Rule 7 载体;键 ⊆ StatusEffectTable 活行集、悬空加载期致命;新 effect_id 上线须随批登记——2026-09-15 格面资源批随 sapped 行收编登记:sapped → hero_offense) pool_clamp_lo: int pp(结构冻结 −100——percent 池地板域下界,乘数域随之 [0,2];2026-09-10 统一八字段口径) pool_clamp_hi: int pp(结构冻结 +100——percent 池地板域上界;原"七字段 pool_clamp_lo_hi"措辞作废,数据配置 GDD 行按收编先例以本条为准) round_direction: enum {floor}(结构冻结——单一取整规则) - damage_a_per_cell: int ≥0(knob 默认 1 provisional——伤害A 开格充能/格;2026-09-14 护甲克制批转正登记,机制与结算归 战斗结算、难度曲线与Boss 投值) - damage_a_cap: int ≥0(knob 默认 8——伤害A 单轮充能封顶,防连锁轮失控;0 = 不封顶) - damage_b_per_flag: int ≥0(knob 默认 2——伤害B 标雷充能/首次标中雷,每雷实例一次去重) - armor_effectiveness: Dictionary 伤害类型×护甲→百分比(键集结构冻结 {base, dmg_a, dmg_b} × {none, a, b};默认 base 全 100 / dmg_a→a=150、b=50 / dmg_b→b=150、a=50——特化 ×150 / 无甲 ×100 / 对位 ×50;数值 provisional 归 难度曲线与Boss) + charge_grants: Dictionary 奖励触发源→{attack_type, per_unit, cap}(**2026-09-15 攻击类型/奖励抽象分离批新增**——攻击类型 = 伤害的属性轴(定义不含来源),充能 = 按攻击类型分桶的附加伤害储备;"哪类棋盘事实充哪个桶、每单位多少点"归本字典 = 奖励定义,替换字典即改奖励内容,攻击类型与 armor_effectiveness 不动;现行 safe_cell(开格)→ pierce 1/格 cap 8 · flag_hit(标中旗)→ magic 2/雷 cap 0=不封顶;**原 pierce_per_cell / pierce_cap / magic_per_flag("类型×来源"焊死命名,更早为 damage_a_per_cell / damage_a_cap / damage_b_per_flag)同批作废**;数值 provisional 归 难度曲线与Boss;正式归属(奖励道具经济 的奖励类别/效果面)见 战斗结算「待拍板」) + armor_effectiveness: Dictionary 攻击类型×护甲→百分比(键集结构冻结 {normal, pierce, magic} × {light, ward, heavy};默认 normal 全 100 / pierce→ward=150、heavy=50 / magic→heavy=150、ward=50——克制 ×150 / 中性 ×100 / 被克 ×50;**2026-09-15 命名统一批:改为语义键,原 {base, dmg_a, dmg_b} × {none, a, b} 位置键作废**;数值 provisional 归 难度曲线与Boss) validation: segment_order 违例致命 · effect_pool_map 悬空致命 · p_perfect 域 {100,200}(2026-09-10 载体域——100 = "完美必须 ≥ 不加倍"机制语义下界,200 = 双份交付)——战斗结算 冒烟三行致命 manifest(segorder_violation / poolmap_dangling / pperfect_oob) - mechanics: 结算段序骨架唯一权威载体(授予→道具使用窗口〔授予段后〕→增益/减益→道具→战斗→衰减→判定——用户 2026-09-09 拍板序)· 零随机(rng_service 流封闭不含结算流)· 可回放步骤流(同 master_seed 同意图序列同窗口选择序列 ⇒ 步骤流逐行相同——数据配置 AC-15 deferred→战斗结算 兑现落点)· 调用序钉死 query_attack→apply_damage→advance · 衰减恒执行含末轮 · 高光双落载体(perfect_sweep P_perfect——2026-09-10 修订为真实双份兑付载体 / 标中旗 highlight 标记)· 流水行协议字段分层(公共 7 字段 + 行类型特有 target/effect_id/pool_value/聚合计数——2026-09-10 评审批修订;行类型封闭枚举 15 类——2026-09-15 窗口锚行批由 13 类扩为 15 类,新增窗口打开锚行 window_open〔value = 本轮候选件数,「窗口段恒在案」打开态锚点〕与窗口跳过锚行 window_skip〔空库存不弹窗 / 玩家零选择两触发,value = 0〕,两类均不参与聚合统计;行来源断言两层豁免集合同批成文 = 行型豁免 {decay, verdict, window_open, window_skip} × 来源类别豁免 {hero_attack, enemy_action, clear_reward, item},豁免不等于免检——豁免行仍受公共字段与各自语义约束,清单改动须同步 战斗结算 明细流水一节与 battle_log_view 格式化)· **伤害A/B 充能与护甲克制结算规格 = 战斗结算 GDD F6(W3 补全,2026-09-14 重算批)**——挖掘期充能/战斗段消费/单轮生命周期、不吃 percent、逐分量 armor_effectiveness 查表 floor 相加 + mechanics: 结算段序骨架唯一权威载体(授予→增益/减益→战斗→衰减→判定——2026-09-15 格面资源批五段,item_window/item 两段随可选类删除下线)· 零随机(rng_service 流封闭不含结算流)· 可回放步骤流(同 master_seed 同意图序列 ⇒ 步骤流逐行相同——数据配置 AC-15 deferred→战斗结算 兑现落点)· 调用序钉死 query_attack→apply_damage→advance · 衰减恒执行含末轮 · 高光双落载体(perfect_sweep P_perfect——2026-09-10 修订为真实双份兑付载体 / 标中旗 highlight 标记)· 流水行协议字段分层(公共 7 字段 + 行类型特有 target/effect_id/pool_value/聚合计数——2026-09-10 评审批修订;行类型封闭枚举 10 类——2026-09-15 格面资源批由 15 类收拢:删道具行 / 已消耗未生效行 / 使用被拒行 / 窗口打开锚行 window_open / 窗口跳过锚行 window_skip 五类随可选类删除下线〔2026-09-15 窗口锚行批曾由 13 扩为 15,同日回撤〕;行来源断言两层豁免集合同批修订 = 行型豁免 {decay, verdict} × 来源类别豁免 {hero_attack, enemy_action, clear_reward},豁免不等于免检——豁免行仍受公共字段与各自语义约束,清单改动须同步 战斗结算 明细流水一节与 battle_log_view 格式化)· **穿刺/魔法 充能与护甲克制结算规格 = 战斗结算 GDD F6(W3 补全,2026-09-14 重算批;2026-09-15 命名统一批)**——挖掘期充能/战斗段消费/单轮生命周期、不吃 percent、逐分量 armor_effectiveness 查表 floor 相加 closure_receipt: 行动经济 F1 条款①②③⑤闭合 owner = 战斗结算(2026-09-10 F0–F5 首版验算完成——F0 瞬时当量口径 + m_w 值域裁决见 status_effect.anchor_warning;条款③ clause3_supply 闭合回执;条款⑤ clause5_dominance 条目;actuals p10 交付后强制重跑) referenced_by: [HUD框架, 战斗表现, 音频, 教学引导, 难度曲线与Boss] @@ -582,3 +575,43 @@ entities: # overlay_semantics 显影集标"载体待重定"(三集结构不变); # level_table:L2 层名占位删除(改"未定稿")、mvp_content 去"全程无雾"。 # 本表历史注释行保留各批原文(含已删键与雾时代口径)作为修订留痕,现行口径以上方条目为准——对应文档同批修订见各文档「版本历史」。 +# 2026-09-15 攻击/护甲命名统一批(owner=战斗结算 GDD 发起,敌人系统/难度曲线与Boss/03-内容规模/registry + 切片实现侧同批): +# 位置键 → 语义键。攻击类型(结算表矩阵行键 / hero_attack 行分量){base, dmg_a, dmg_b} → {normal, pierce, magic} = +# 普通 / 穿刺 / 魔法;护甲类型(enemy.armor_type / 矩阵列键){none, a, b} → {light, ward, heavy} = 轻甲 / 魔法护甲 / 重甲 +# (映射沿教学梯度:goblin none→light、bugbear a→ward、ogre_chief b→heavy)。切片 EnemyTable.ARMOR_TYPES、 +# SettlementTable.ARMOR_KEYS(+ COMPONENT_KEYS→ATTACK_TYPE_KEYS)、enemy.tres / settlement.tres、DamageMath / UnitContainer / +# BattleOrchestrator / EnemyCardView / BattleLogView / smoke 全量改键。 +# 理由 = 位置键不承载语义,且"无甲/甲A/甲B"在文档间已分裂成四种写法。 +# 数值零改动(纯改名);旧名仅在本批注记与各文档「版本历史」中作为"原名"留存,不再作为现行词汇使用。 +# 2026-09-15 攻击类型 / 奖励抽象分离批(同日第二批,用户裁定"攻击类型的定义和格子奖励要分离开;开格|标雷 → 奖励; +# 奖励如何定义是可以修改的;不要将两者绑定")——修正同日第一批遗留的焊死命名:结算表字段 damage_a_per_cell / +# damage_a_cap / damage_b_per_flag(及其改名产物 pierce_per_cell / pierce_cap / magic_per_flag)把"攻击类型"与"棋盘来源" +# 焊进同一根命名,属概念错误。现行两轴分离:① 攻击类型 = 伤害的属性轴(normal/pierce/magic,只决定查 armor_effectiveness +# 哪一行,定义里不含任何棋盘来源);② 充能 = 按攻击类型分桶的附加伤害储备,"谁能充 / 充哪个桶" = settlement_table.charge_grants +# (触发源→{attack_type, per_unit, cap})= 奖励定义,整表替换即改奖励内容,攻击类型与矩阵不动。开格 / 标中旗 / 踩雷 / 清图 +# 一律只作奖励触发源。结算快照 round_facts:charge_dmg_a / charge_dmg_b → charge_counts(各触发源计数)+ charge_points +# (按攻击类型分桶点数);切片 BattlerOrchestrator 侧 _charge_counts 只计数、_charge_points() 按奖励定义投桶。 +# 充能奖励的正式归属(奖励道具经济 面)见 战斗结算「待拍板」。 +# 2026-09-15 格面资源批(用户四点拍板:① 结算队列+抵消过滤 ② 雷安一视同仁+可选类整体删除 ③ 封锁格计入清图 ④ 格面资源/清图奖励对象命名与封装; +# owner=奖励道具经济 v0.4 / 战斗结算 v0.7 / 排雷玩法 v0.3 / registry 侧 7 条;切片代码修改随新会话执行、指导已产出)—— +# reward_table 结构性重写:category/use_timing/库存/供给轴下线,新增 cell_type ∈ {attack,defense,heal,blast,weaken} × polarity ∈ {positive,negative} +# 字段对(同型两行;正向行参与摇号 = 类型频次,负向行纯字典)、pool_tag {safe_cell, active_inject} → {cell}、mvp_content 十行(含负向直伤 heal flat p4、ambush+2 +# stacks=2、sapped 行);direction_precheck 旧刀供给预检失义退役;settlement_obligations 六→四、hud_obligations 五→三、high_glow H3 失义下线。 +# reward_config 整条删除(RewardConfigTable 随可选类删除下线,切片 reward_config.tres 随代码批删除)。 +# settlement_table:segment_order 七段→五段 [grant, buff_debuff, combat, decay, verdict](item_window/item 下线)、 +# source_label_map 删"道具"扩展键、effect_pool_map 收编 sapped→hero_offense、mechanics 行型封闭 15→10 类 + 两层豁免集合修订。 +# status_effect:mvp_content 六行→七行(新增 sapped——weaken 型负向)、enrage/off_guard 兑付语义注记改为类型化负向。 +# minesweeper_event_surface.cell_revealed:reward_eligible → resource(雷格恒携带资源,旧"mine 恒 false"作废)。 +# terminology:删"资格格""刀"两词条,新增"封锁格""格面资源(CellResource)"。 +# 遗留回写义务(未随本批执行的文档,下次相应 owner 批次处理):HUD框架(道具窗口/库存条/清图文案"剩余未探索安全区域")、教学引导(囤刀教学)、 +# 增益状态(正文行表对齐七行)、行动经济(条款②③⑤锚对象按类型化负向重议)、难度曲线与Boss(F4/F5/对账重推)、数据配置(RewardTable schema 重写)、 +# 00-游戏概念/01-核心循环/03-内容规模/05-不做清单(旧固定兑付措辞)、UX 文档。历史留痕保留各批原文,现行口径以上方条目为准。 +# +# 2026-09-15 验收/收口批(owner=战斗结算,代用户修订;零数值零机制改动;**不改 v0.7 文件**)——v0.5/v0.6 两批(命名统一 + 抽象分离) +# 验收核对全绿后收口。范围纪律:战斗结算.md / 奖励道具经济.md 属 v0.7 格面资源批所有者文件、口径仍在移动,本批一律不动; +# ③ 收口项登记于此(registry)+ README + active.md,GDD 侧只报告、待 v0.7 批整体收口后回填: +# ① 收益对照表充能当量覆盖缺口:现行 flat/percent/完美乘数三式未覆盖「充能类」;候选口径 = 充能当量 = +# Σ各桶点数 × 当轮目标护甲平均甲效倍率 ÷ 100(与直伤同类 1 伤害 = 1 当量,守 行动经济 条款①单一当量)——补式 / 登记待拍板二选一待回填批裁定。 +# ② 两处已知落差:a) charge_grants 触发源可扩展 vs 切片仅 safe_cell/flag_hit 两处计数埋点(新增源须加埋点); +# b) safe_cell/flag_hit 来源标识跨命名空间同名(结算明细行 source_class / charge_grants 键;RewardTable.pool_tag 已随格面资源批改 cell)。 +# 验收读数:冒烟 201 项 0 失败 · 四探针 exit=0 无 FAIL(切片侧仍为 pre-v0.7 实现,代码同步随格面资源批新会话执行)。 diff --git a/design/research/proposal-reward-polarity-2026-09-13.md b/design/research/proposal-reward-polarity-2026-09-13.md index 7d312f48..e0634546 100644 --- a/design/research/proposal-reward-polarity-2026-09-13.md +++ b/design/research/proposal-reward-polarity-2026-09-13.md @@ -85,3 +85,14 @@ 1. **批 1(数据面 + 路由)**:排雷玩法/奖励道具经济 schema 与行、战斗结算极性路由、冒烟扩展——机制先可玩(占位图标)。 2. **批 2(呈现)**:HUD框架图标族 + 极性视觉 + 教学。 3. **批 3(数值与验证)**:难度曲线与Boss 调平 + level_monte_carlo/defense_scan 复验 + 试玩批次。 + +## 7. v4 用户四点裁决(2026-09-15,架构定稿) + +对本文四条边界确认问题的用户答复,全部并入正文与 GDD 修订批(奖励道具经济 v0.4 / 战斗结算 v0.7 / 排雷玩法 v0.3 / registry 格面资源批): + +1. **兑付时机 = 全部在结算阶段**:开格 / 标旗 / 撤旗都是把动作加入结算队列;结算期先遍历过滤(标旗后被撤旗 → 该次标旗不结算——先过滤再兑付,非逐动作出栈直算)再逐行兑付。实现落点 = 轮末旗判定以在场旗位为基线的既有语义,正文改述为队列 + 抵消过滤口径。 +2. **雷安一视同仁 + 可选类整体删除**:格面资源同一类型池、同一权重分布分配给全部非封锁格,不存在"只注入安全格"的分支;可选类道具(刀 / 治疗包)与供给控制器、注入概率、按板保底、关卡域库存、道具使用窗口整体删除——后续更强力、更长周期的功能道具经其他渠道加入(渠道设计未定,P1 结构位)。R4/R5 的"可选类不入极性域"条款随可选类删除失义;heal 负向直伤按 R3 兑现。 +3. **封锁格计入清图进度**:清图条件 = 全部安全格被打开,初始展开白送格(封锁格)天然在集合内;呈现口径 = "剩余未探索安全区域"计数(归 HUD框架)。 +4. **命名与封装定稿**:格面资源(CellResource)= 地图格子的关联资源对象;清图奖励对象(ClearReward)= 板级、可配置可替换的独立奖励封装(clear_default 默认槽 + clear_<图类型> 命名空间预留,不同地图类型可配不同清图奖励)。 + +实施批次更新:文档侧修订已完成(2026-09-15);切片代码侧修改指导已产出,随新会话执行(批 1 数据面 + 路由起步)。 diff --git a/docs/doc-conventions.md b/docs/doc-conventions.md index 71e34513..f17b1840 100644 --- a/docs/doc-conventions.md +++ b/docs/doc-conventions.md @@ -2,7 +2,7 @@ > **地位**:本文是本项目文档写作的规范权威,与 `docs/code-conventions.md`(代码规范)对等——写代码前必读代码规范,写文档前必读本文。CLAUDE.md 只保留摘要与指针,细则以本文为准。 > **适用范围**:`design/` 下一切现行文档(顶层文档、`systems/` 系统文档、`design/ux/`、`design/art/`、`design/research/`)与 `production/` 会话记录;`docs/` 其他说明文档参照执行。 -> **成文**:2026-09-14。整合来源:用语纪律(2026-09-09 评审确立)· 文档形态纪律(2026-09-13 评审确立)· 两件套与树形文档体系纪律(2026-09-14 用户拍板)· 新骨架过渡口径(2026-09-14 用户拍板)· 可读性纪律(2026-09-14 用户提出)· 引用纪律(2026-09-14 用户提出)。 +> **成文**:2026-09-14。整合来源:用语纪律(2026-09-09 评审确立)· 文档形态纪律(2026-09-13 评审确立)· 两件套与树形文档体系纪律(2026-09-14 用户拍板)· 新骨架过渡口径(2026-09-14 用户拍板)· 可读性纪律(2026-09-14 用户提出)· 引用纪律(2026-09-14 用户提出)· 概念封装纪律(2026-09-15 用户提出)。 ## 0. 总纲 @@ -89,7 +89,7 @@ | 系统范围 | 负责/不负责两张表;表前一段白话说明边界 | | 在核心循环中的位置 | 处于哪一段、上下游是谁(字符画一行 + 两句白话) | | 核心规则 | 领域章节 ×2–6,每节一页纸 | -| 依赖与输出 | 上游/下游/对外事件与接口(表格;引用纪律见第 7 节) | +| 依赖与输出 | 上游/下游/对外事件与接口(表格;引用纪律见第 8 节) | | P0 最小闭环 / P1·P2 后置 | MVP 最小集合与后置清单 | | 调参表 | 参数名/取值域/现行值,provisional 标注 | | 验收标准 | 可验证的判据 | @@ -98,7 +98,26 @@ **命名**:中文、见名知意(如"游戏概念""棋盘生成");禁止 a1_/b1_ 编号前缀;不留纯空目录。正文中指代子系统一律用中文规范名;英文代号(供代码标识符与工具链)对照表见 `design/gdd/02-系统清单.md`,旧代号(a1–d6)仅限解读归档时使用,不得写进现行文档。 -## 7. 引用纪律(跨文档高内聚低耦合) +## 7. 概念封装纪律(概念对象化建模) + +动笔之前先做概念建模:像写代码划分对象那样,把设计切成分界清晰的概念——每个概念有自己的规范名、自己的属性、自己的规则,概念之间靠显式关系(包含、挂载、引用)连接,而不是把所有内容揉进一个概念里。揉团的代价雾格事故已经付过一次(见第 8 节反例对照):概念没有边界,删除修改就得全仓翻找。 + +| 规则 | 内容 | +|---|---| +| 概念即对象 | 核心概念各自独立成体,有规范名、有属性、有规则边界;下笔前先能用一句"它是谁、它管什么"说清,说不清就是还没想完 | +| 属性归属唯一 | 每个属性只归一个概念——离开 A 就没有意义的属性写在 A 名下,禁止上提给容器、也不下压给成员 | +| 包含关系显式写 | 容器与成员的关系明文写出谁是容器、谁是成员、一对几(例:棋盘包含多个格);禁止让读者从散文里反推结构 | +| 概念状态用枚举 | 概念的类型与状态写成封闭枚举并列全成员(例:格的类型 = 安全格 / 雷格,格的状态 = 未开 / 已开);禁止用散文形容词零散罗列状态 | +| 附加物独立成对象 | 挂在概念上的附加内容若自己有一组属性或规则要写(例:格上的奖励/惩罚 = 格面资源),就是独立对象——父概念只保留挂载位(如"有无资源资格"),禁止把附加物摊平成父概念的一堆属性字段 | +| 关系不吸内容 | 概念间关系只写"有没有关系、是什么关系";对方的属性与规则留在对方名下——与第 8 节"引用不转述"同源 | + +**切分正例**(现行排雷循环即按此切分):棋盘是地图级对象,包含多个格;格是成员对象,雷格/安全格是它的枚举属性;格上可能挂的奖励或惩罚(格面资源)是独立对象,本体与规则归奖励道具经济与战斗结算,格只保留"有无资源资格"一个挂载位。反面基准:把奖励的类型、数值、极性全摊开写成格子的属性字段——奖励规则一改,棋盘文档就得跟着改,这便是没封装。 + +**落盘载体**:概念对象登记 `design/registry/entities.yaml`(owner 与 referenced_by 由此机械维护);文档里概念怎么切,registry 就怎么登记,代码里的对象划分与之同构。 + +**与引用纪律的关系**:本节管单个概念的边界与归属(概念级封装),第 8 节管概念之间、文档之间的引用(跨文档解耦)——先有封装,第 8 节的单点定义、反向边与删除 SOP 才有干净的作用对象。 + +## 8. 引用纪律(跨文档高内聚低耦合) 目标:修改或删除一个概念时,只改它的 owner 文档;引用方最多删掉一个链接。反例对照 = 2026-09-14 雾格删除事故——雾格/迷雾/fog 三名并存、雾机制被织进多份文档的规则正文,导致全仓几十处文字修改与大量事后一致性复查。 @@ -118,13 +137,13 @@ **诚实边界**:机制耦合无法靠删链接消灭——别人的规则真的因你的概念而改变时,改内容不可避免。引用纪律保证的是:这类修改有一份现成清单(反向边 + 依赖节),不用事后全仓搜索。 -## 8. 归档与事实源 +## 9. 归档与事实源 - `design/archive/gdd-2026-09-14/` 是旧版 GDD 体系的只读归档:不维护、不修改,**禁止作为事实引用**。 - 旧文档里的概念写进现行文档时,必须翻译成现行术语与现行决策口径(例:雾格已从设计中移除,不得作为现行机制引用)。 - registry 中 owner 仍指向旧 GDD 路径的条目,在对应新系统文档定稿后逐条改指新路径。 -## 9. 会话记录纪律 +## 10. 会话记录纪律 `production/session-state/active.md` 每条进度 ≤3 行(粗体键 + 短句);详情一律外链到对应文档或报告,禁止把定稿摘要、义务清单整段塞进条目。 @@ -136,3 +155,4 @@ | v2 | 2026-09-14 | 新增第 7 节引用纪律(跨文档高内聚低耦合:单点定义 / 规范名唯一 / 引用不转述 / 反向边登记 / 删除概念 SOP),原 7/8 节顺延为 8/9 | | v3 | 2026-09-15 | 命名纪律补充:现行文档代号清偿完毕,子系统统一以中文规范名指代;英文代号对照表落盘 `design/gdd/02-系统清单.md`,旧代号仅限解读归档 | | v4 | 2026-09-15 | 用语纪律正例去雾:第 4 节正例"剔除雾格后的可推理率"改为现行指标"实测可推理率"(原指标随雾格移除已删);规则文字与历史反例"非雾腿"、第 8 节雾格移除去向说明均不动 | +| v5 | 2026-09-15 | 新增第 7 节概念封装纪律(概念对象化建模:概念即对象 / 属性归属唯一 / 包含关系显式写 / 概念状态用枚举 / 附加物独立成对象 / 关系不吸内容),原 7/8/9 节顺延为 8/9/10,第 6 节骨架表与 CLAUDE.md 摘要的章节指针同步改指 | diff --git a/production/qa/playtests/playtest-2026-09-12-designer.md b/production/qa/playtests/playtest-2026-09-12-designer.md index cabbdca8..cd37ac0e 100644 --- a/production/qa/playtests/playtest-2026-09-12-designer.md +++ b/production/qa/playtests/playtest-2026-09-12-designer.md @@ -67,7 +67,7 @@ ## Quantitative Data(遥测实测,playtest_42_20260912T201317.jsonl) - 12 结算轮 / 7 节点 / level_end victory;hero hp 全程 50/50;ambush_layers 恒 0;buffs[] 恒空。 - 敌情:d0/d1 空场;d2 bugbear 40hp(2 轮);d3 bugbear 18hp(2 轮);boss ogre 150hp(6 轮,beat 轮转 attack→attack→charge→heavy→attack,兑付伤害 0)。 -- 输出侧:charge_dmg_a 7–14/轮,boss 逐轮 −21/−16/−53(含 clear_blast 40)/−16/−24/−20——**英雄输出正常,Boss 3–6 轮内可斩**。 +- 输出侧:charge_dmg_a 7–14/轮(快照键现名 charge_counts/charge_points——2026-09-15 两批(命名统一 → 抽象分离);本行保留当时观测键名),boss 逐轮 −21/−16/−53(含 clear_blast 40)/−16/−24/−20——**英雄输出正常,Boss 3–6 轮内可斩**。 - 可选类供给:4 获取(3 heal_pack + 1 knife_t1)/ 1 消耗 / 3 库存残留。 - 20:41 辅助局(调参面板 max_hp 100 + atk 加成):普通敌承伤正常(−34/−9),Boss 仍零承伤;治疗包在缺血时正常消耗。证明消耗通道与攻击链在普通敌上健康,Boss 路径存疑。 diff --git a/production/session-state/active.md b/production/session-state/active.md index 1c1dda89..a657e87c 100644 --- a/production/session-state/active.md +++ b/production/session-state/active.md @@ -93,7 +93,7 @@ 35. **战斗屏 UX 批:评审通过 + pattern 库建立(2026-09-12,/team-ui 管线 solo 模式)**:① **上游契约批落地**——battle.md /ux-review(7 blocking)+ 用户四拍板(弃图刷新=挖掘期当场换图·雷图右上角按钮 / 保留每轮上限 2 / OQ8 本 spec 裁决采纳 tint+雾区全开信号 / 压暗改去饱和+金橙偏移)→ 行动经济/排雷玩法/战斗结算/systems-index/registry 直接修订(refresh 前移挖掘期:行动经济 Active 受理+cap 2、排雷玩法 Active·仅刷新路径装板、战斗结算 `refresh_board` 编排+stopped/ap_exhausted 恒 same_board、旧旗作废、时间税失效预警 OQ3 联动)。**注意与切片 entry 27 命名对账**:切片代码用 provisional 名(`request_refresh_active()`/`can_request_refresh()`/`refresh_max_per_round`/`during_round`),GDD 用正式名(`request_refresh` Active 受理/`refresh_board`/`refresh_cap_per_round` 结构位)——语义一致,正式 HUD框架 批统一命名 ② **/ux-review 独立复检**(全新上下文代理):1 blocking(systems-index:90 旧契约残留)+ 3 advisory 全部同批落稿 → **VERDICT: APPROVED**(§13 台账 27 项义务承接逐项实存验证)③ **interaction-patterns.md 已建**(用户拍板"先写核心 8"):双源拒绝反馈/原位窗口激活/逐行兑现明细带/悬停预承诺光标/点阵资源显示/模态 overlay 层级纪律/破坏性确认异位/禁用态即理由全文 + 12 目录占位(实现期回写义务)④ Phase 2 视觉 spec 跳过(用户拍板,art-bible §1–4 直接驱动)。**下一步 = Phase 3 单次协调实现**:ui-programmer 按 battle.md 改造 presentation/(五区布局/敌人卡/明细带/状态槽/图例/tooltip/教学提示/胜负终局)+ ux_* 遥测 + 探针扩展;solo 模式 Phase 4 总监评审流跳过,产出以冒烟+三探针兜底 36. **战斗屏五区改造落地(2026-09-12,battle.md 落地 ui-programmer 批——entry 35 的 Phase 3)**:core/ 与 data/ 零字节改动,presentation/ 重构为五区(A 28px 进度条 / B 252px 战斗画面〔英雄卡+敌人卡×1–3+轮次指示+明细带改造〕/ C 240px 数据框+状态槽×4 / D 区 AP 点阵条+BoardView 改造+toast+演出层 / E 区库存常读+原位窗口态)+ 全屏 States(去饱和 shader 明度不变/清图演出/Boss 影子/终局 overlay 胜金蜡封·败暮蓝/一次性提示去重)+ ux 遥测行族(round_input_ratio/round_exit/refresh_attempt/window_choice/reject/hint_shown——快照驱动,呈现层只订 战斗结算)。模态统一登记序管理(缺陷⑤纪律),旧 hud_view.gd 删除。**批内发现并修复**:TunePanel 默认 visible=true 靠开始层遮蔽的历史 quirk(缺陷⑤家族,显式初始化);敌卡逐行重建踩掉死亡灰化(改就地更新);库存清空反馈被常读刷新覆盖(持有期);窗口态被 presenter 全量刷新 stomped(窗口期跳过常读重建——click_probe 首跑即抓)。Waiting 刷新代理按 OQ12 退役(UI 仅 Active 受理)。探针:ui_probe 增五区断言+L2 雾段;click_probe 增刷新确认链/图例/tooltip/模态遮挡/去饱和/首格计时(133–151ms ≤500ms)。回归:smoke 149/149 + 三探针 PASS(click_probe 六种子)。占位登记:意图映射/演出/字体(HUD框架 正式化)归 战斗表现/HUD框架 批。 -37. **伤害类型 × 护甲克制批落地(2026-09-12 用户拍板——设计会话设定表定稿"没有问题"后落程序)**:**结构**——敌人护甲类型 {无甲,护甲A,护甲B}(EnemyTable.armor_type,映射 goblin=none/bugbear=a/ogre_chief=b 教学梯度候选)× 主角攻击三段构成(①基础 atk×(1+attack_up) 不吃克制 ②伤害A=本轮资格格充能×克制 ③伤害B=首次标中雷充能×克制,与 weaken 同键每雷实例一次去重;三分量各自 floor 相加,hero_attack 行携带 base/dmg_a/dmg_b)+ 克制矩阵 SettlementTable.armor_effectiveness(特化 150/无甲 100/对位 50;刀/AOE/清图恒定表值不吃克制)+ 伤害A 单轮 cap 8 + **标错旗随机惩罚三选一**(enrage 暴走敌+25% / ambush+2 层 / off_guard 失衡我方+25%,dur=1,零新流确定性派生 (x×7+y×13+板×5)%3 同种子可回放,每雷格实例一次去重沿用)。**数值全部 provisional**(damage_a_per_cell=1/cap=8/damage_b_per_flag=2/矩阵/enrage·off_guard 25%/映射——登记于 .tres 注释,难度曲线与Boss 按 F6 复算)。**验证**:冒烟 161/161(+12 专项断言:护甲三档传播/矩阵表值/三分量字段/flag_miss+反噬行/充能进攻击/派生回放)· ui_probe/tune_probe/click_probe 全 PASS。**实现坑**:enemy_card_view set_intent 引用越作用域变量 d → 类编译失败敌人卡零构建(ui_probe 抓获)——改成员变量 _armor 传递。**正式侧义务(GDD/registry 修订待文档批)**:敌人系统(armor_type)/战斗结算(三分量构成+反噬编排+矩阵载体)/增益状态(六行状态表+flag_miss 授予)/排雷玩法 OQ1(惩罚候选升级三选一+重复性=每雷实例一次)/registry(enemy/settlement/status_effect 条目+行动经济 条款②③锚重推导)/难度曲线与Boss(provisional 数值接管)。**世界观记录**:design/research/lore-nest-metaphor-2026-09-12.md(雷=巢穴/旗=封印、伤害A=地利/伤害B=暴露、反噬=封印失败——6 个开放问题待新会话拍板后写回 game-concept) +37. **攻击类型 × 护甲克制批落地(2026-09-12 用户拍板——设计会话设定表定稿"没有问题"后落程序)**:**结构**(词汇随 2026-09-15 命名统一批 + 抽象分离批改写:攻击类型 = 伤害属性轴、开格/标中旗 = 奖励触发源)——敌人护甲类型 {轻甲,魔法护甲,重甲}(EnemyTable.armor_type,映射 goblin=light/bugbear=ward/ogre_chief=heavy 教学梯度候选)× 主角攻击三段构成(①普通 atk×(1+attack_up) 不吃克制 ②穿刺 / ③魔法 = 充能(按攻击类型分桶,投桶归奖励定义 settlement.charge_grants:开格→穿刺桶、标中旗→魔法桶,后者与 weaken 同键每雷实例一次去重);三分量各自 floor 相加,hero_attack 行携带 normal/pierce/magic)+ 克制矩阵 SettlementTable.armor_effectiveness(克制 150/中性 100/被克 50;刀/AOE/清图恒定表值不吃克制)+ 开格充能单轮计数上限 8 + **标错旗随机惩罚三选一**(enrage 暴走敌+25% / ambush+2 层 / off_guard 失衡我方+25%,dur=1,零新流确定性派生 (x×7+y×13+板×5)%3 同种子可回放,每雷格实例一次去重沿用)。**数值全部 provisional**(charge_grants 现行 开格→穿刺 1/格·计数上限 8、标中旗→魔法 2/雷/矩阵/enrage·off_guard 25%/映射——登记于 .tres 注释,难度曲线与Boss 按 F6 复算)。**验证**:冒烟 161/161(+12 专项断言:护甲三档传播/矩阵表值/三分量字段/flag_miss+反噬行/充能进攻击/派生回放)· ui_probe/tune_probe/click_probe 全 PASS。**实现坑**:enemy_card_view set_intent 引用越作用域变量 d → 类编译失败敌人卡零构建(ui_probe 抓获)——改成员变量 _armor 传递。**正式侧义务(GDD/registry 修订待文档批)**:敌人系统(armor_type)/战斗结算(三分量构成+反噬编排+矩阵载体)/增益状态(六行状态表+flag_miss 授予)/排雷玩法 OQ1(惩罚候选升级三选一+重复性=每雷实例一次)/registry(enemy/settlement/status_effect 条目+行动经济 条款②③锚重推导)/难度曲线与Boss(provisional 数值接管)。**世界观记录**:design/research/lore-nest-metaphor-2026-09-12.md(雷=巢穴/旗=封印、伤害A=地利/伤害B=暴露、反噬=封印失败——6 个开放问题待新会话拍板后写回 game-concept) 38. **呈现层 code-review 修复批(2026-09-12,/code-review CHANGES REQUIRED → 用户拍板全项修复)**:全切片 53 脚本评审(含两 specialist 并行审查 views/ 与 smoke/+schemas/)裁决 7 项必改,本批清偿:① **TunePanel 封装破口**(视图直写 hero 表 + 视图 load smoke 驱动 core → 面板模拟 pct² 口径 + 模拟后表值残留污染真实对局)——重构纯视图信号外发,加成落表收口组合根 `_apply_hero_override` 单一路径(每次从基线幂等重算),模拟编排拆 `tune_sim_controller.gd` ② **意图徽标双翻译**(presenter 译中文投影 vs EnemyCardView 英文 key 匹配 → 色相/重击标记永久失效)——presenter 直传 敌人系统 原键,渲染映射唯一定义处归 EnemyCardView ③ **C 区 RAP 死分支**(presenter 从不投影 a3.rap,行动经济对 HUD框架 的清零反馈不可达)——持续投影 + 视图改 `_last_rap` 成员存储 ④ **smoke_all 恒真断言**改带标签真实断言 ⑤ **level_runner core↔core 接线 lambda ×4 → 方法 Callable**(ADR-0001 S6)⑥ **战斗结算 `diagnostic_snapshot()` 诊断观测面**(main/click_probe 零私有字段直读)⑦ **main.gd 761→667**:节点构建/模态层级/叙事文案/模拟编排四拆分(ui_assembler + modal_stack + battle_narrator + tune_sim_controller,均无 class_name 走 preload;.uid 已生成)——剩余为 ADR 规定组合根职责,进一步压缩登记 HUD框架 批候审。探针同步:ui_tune_probe 重写(真实按钮路径接缝 + 两条双写叠加回归断言)、click_probe 改诊断 API。**验证**:smoke 141/141 · 三探针全 PASS(click 六种子)。登记待办:自动玩家四份复制收口 / schema 溯源行 / S1–S8 扫描脚本化 + S1 豁免口径 / views 转发信号契约头注。 @@ -130,3 +130,7 @@ 48. **文档写作规范成文 + 引用纪律补入(2026-09-14)**:`docs/doc-conventions.md` v1 成文(另一会话,整合全部写作纪律为写文档前必读的单一权威),本会话补第 7 节「引用纪律」(单点定义/规范名唯一/引用不转述/反向边登记/删除概念 SOP,雾格事故为对照反例);CLAUDE.md 挂必读指针与摘要。同批:`systems/排雷循环/行动经济.md`(自归档迁移定稿)与 `systems/表现与支撑/教学引导.md`(范围草案)成文(另一会话)。 49. **命名清偿批(2026-09-15,用户拍板批)**:旧系统代号(a1–d6)全仓清偿为中文规范名——design/gdd(02-系统清单新增「中文规范名↔英文代号↔旧代号」对照表)/ux/art/research 全绿复扫;registry owner 改指新骨架文档 + 前缀键名改领域命名(minesweeper_/aux_/hud_/settlement_/reward_)+ 头部注记;本文件历史条目同步清偿。QA 四份 Closed BUG 记录删除(用户拍板);切片代码变量领域命名批(子 agent 执行,smoke/探针回归见批报);归档维持只读、后续随批删除。 + +50. **两批验收 + 收口批(2026-09-15,本会话)**:对 2026-09-15 两批(攻击/护甲命名统一 v0.5 + 攻击类型/奖励抽象分离 v0.6)做只读核对 + 文档层收口(零数值零机制改动;**不改 v0.7 文件**——战斗结算.md / 奖励道具经济.md 属 v0.7 格面资源批所有者、口径仍在移动,本批不动)。**核对**:9 项口径↔实现全闭合(charge_grants 键与值 / 甲效矩阵 9 格 / armor_type 三值 / hero_attack 分量字段 normal·pierce·magic / round_facts charge_counts·charge_points / 敌卡标签 / 明细行拆行文案 / 攻击类型定义不含来源 / 矩阵数值逐格不动);残留旧名扫描仅命中批次注记原名与历史观测记录(一处 playtest 注记"现名 charge_pierce"陈旧,已订正为 charge_counts/charge_points);来源-类型硬绑扫描确认代码只剩两处计数埋点(`_charge_counts["safe_cell"]` / `["flag_hit"]`)+ charge_grants 键 + 行 source_class 归因。**实跑**:冒烟 201 项 0 失败;四探针 exit=0 无 FAIL。**收口(③,落在 registry + README + 本文件,GDD 侧只报告不改)**:① 收益对照表充能当量覆盖缺口登记(候选口径 = Σ各桶点数 × 当轮目标护甲平均甲效倍率 ÷ 100,1 伤害 = 1 当量守条款①;补式 / 登记待拍板二选一待回填批);② 两处已知落差登记(charge_grants 触发源扩展 vs 切片两处埋点;safe_cell/flag_hit 跨命名空间同名);③ playtest 快照键注记订正。**口径移动注记**:本会话运行期间 **v0.7 格面资源批**已在 GDD(战斗结算 v0.7 / 奖励道具经济 v0.4)+ registry 落地(五段 / 10 行型 / 极性路由 / 可选类删除),切片代码未同步——registry 已注明"切片代码修改随新会话执行、指导已产出";本批核对结论针对 v0.5/v0.6 两批语义,v0.7 代码同步为独立后置批。 + +51. **概念封装纪律入规范(2026-09-15,用户提出)**:`docs/doc-conventions.md` v5 新增第 7 节「概念封装纪律(概念对象化建模)」——概念即对象 / 属性归属唯一 / 包含关系显式写 / 概念状态用枚举 / 附加物独立成对象 / 关系不吸内容;原 7/8/9 节顺延为 8/9/10,第 6 节骨架表与 CLAUDE.md 摘要的章节指针同步改指第 7、8 节。 diff --git a/prototypes/dungeon-sweeper-vertical-slice/README.md b/prototypes/dungeon-sweeper-vertical-slice/README.md index 248446e4..5af41b08 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/README.md +++ b/prototypes/dungeon-sweeper-vertical-slice/README.md @@ -224,25 +224,25 @@ Godot_v4.7.2-stable_win64_console.exe --headless --path . --script res://smoke/s ## 2026-09-12 试玩批次 1 → v3 数值批(F7 流程实践) -## 2026-09-12 伤害类型 × 护甲克制批(用户拍板——三段伤害 + 标错惩罚落地) +## 2026-09-12 攻击类型 × 护甲克制批(用户拍板——三段伤害 + 标错惩罚落地) -**触发**:设计会话(本日)定稿"怪物护甲类型(无甲/护甲A/护甲B)× 角色伤害三段构成(基础/伤害A/伤害B)"的克制对策系统(穿甲弹/高爆弹式三角)+ 标错旗随机惩罚。设定表经用户多轮审阅确认"没有问题"后落程序(GDD 正式修订另批进行——本批以表格结论为实现依据)。 +**触发**:设计会话(本日)定稿"怪物护甲类型(轻甲/魔法护甲/重甲)× 角色伤害三段构成(普通/穿刺/魔法)"的克制对策系统(穿甲弹/高爆弹式三角)+ 标错旗随机惩罚。(本段写于 2026-09-12,原文使用位置名 无甲/护甲A/护甲B 与 基础/伤害A/伤害B——2026-09-15 命名统一批已全仓改为语义名,映射见下方该批小节。)设定表经用户多轮审阅确认"没有问题"后落程序(GDD 正式修订另批进行——本批以表格结论为实现依据)。 **拍板结构 → 落点**: | 设定 | 实现落点 | |---|---| -| 敌人护甲类型:无甲 / 护甲A / 护甲B | EnemyTable 新字段 `armor_type`({none,a,b},缺省 none 向后兼容)· 映射:goblin=none / bugbear=a / ogre_chief=b(教学梯度候选,provisional)· B2.spawn 行值快照入单位字典 | -| 伤害三段:①基础 ②伤害A(开格充能)③伤害B(标雷充能) | B1 战斗段主角先手攻击改三分量:基础 = atk×(1+attack_up)(**不吃克制**,attack_up 消费面不变);伤害A = 本轮开出的资格格计数 ×`damage_a_per_cell`(初始展开格不计——reward_eligible=false);伤害B = 首次标中雷 ×`damage_b_per_flag`(与 weaken 同键每雷实例一次去重——忘拔旗不重复充能);三分量各自 floor 后相加,hero_attack 行携带 base/dmg_a/dmg_b 分量(P2 归因) | -| 克制矩阵:特化 ×150 / 无甲 ×100 / 对位甲 ×50 | SettlementTable 新字段 `armor_effectiveness`({base,dmg_a,dmg_b}×{none,a,b} percent,缺项回退 100)——刀/AOE/清图奖励**恒定表值不吃克制**(道具=万能稳定伤害,暂定待拍板) | -| 伤害A 单轮封顶 | `damage_a_cap = 8`(与 ap_per_round 对齐——防连锁轮一次充能十几个格把特化甲怪一拍秒杀;0 = 不封顶) | +| 敌人护甲类型:轻甲 / 魔法护甲 / 重甲 | EnemyTable 新字段 `armor_type`({light,ward,heavy},缺省 light 向后兼容)· 映射:goblin=light / bugbear=ward / ogre_chief=heavy(教学梯度候选,provisional)· B2.spawn 行值快照入单位字典 | +| 伤害三段:①普通 ②穿刺 ③魔法(后两者由充能供给) | B1 战斗段主角先手攻击改三分量:普通 = atk×(1+attack_up)(**不吃克制**,attack_up 消费面不变);穿刺/魔法 = 充能点数(按攻击类型分桶)×克制(分量各自 floor 后相加);hero_attack 行携带 normal/pierce/magic 分量(P2 归因)。**攻击类型是伤害的属性轴,与来源无关**(2026-09-15 抽象分离批) | +| 充能供给(奖励侧定义,可改) | SettlementTable 字段 `charge_grants`(触发源 → {attack_type, per_unit, cap}):现行 safe_cell(本轮开格,初始展开格不计 reward_eligible=false)→ 穿刺桶 1/格、单轮计数上限 8;flag_hit(首次标中雷,与 weaken 同键每雷实例一次去重)→ 魔法桶 2/雷。换桶/换量/换成增益或道具都只改本字典——攻击类型与矩阵不动 | +| 克制矩阵:克制 ×150 / 中性 ×100 / 被克 ×50 | SettlementTable 新字段 `armor_effectiveness`({normal,pierce,magic}×{light,ward,heavy} percent,缺项回退 100)——刀/AOE/清图奖励**恒定表值不吃克制**(道具=万能稳定伤害,暂定待拍板) | | 标错旗 → 随机轻惩罚三选一(时效 1 结算) | `_apply_miss_backlash()`:① `enrage` 暴走(敌 +25% 进 enemy_output 池)② 敌方伏击 +2 层(复用 ambush 行)③ `off_guard` 失衡(我方 +25% 进 hero_defense 池 = 多挨打);新 B3 行 ×2(dur=1 与 weaken/ambush 同款先兑付后衰减);沿用 `_flag_miss_seen` 每雷格实例一次去重 | | 随机载体 | **零新流确定性派生**:(x×7 + y×13 + 板序号×5) mod 3——同种子可回放、不扰动既有三条封闭流取号序;正式侧候选 = RngService 新增封闭流(待拍板) | -| 呈现 | 敌人卡环点行常驻护甲标签(无甲/护甲A/护甲B——克制对策可读前提)· 结算明细主角攻击行拆"(基础 X + 开格 Y + 标雷 Z)" · 反噬效果行入明细流 · settlement_snapshot 增 armor/charge 字段(JSONL 数值分析面) | +| 呈现 | 敌人卡环点行常驻护甲标签(轻甲/魔法护甲/重甲——克制对策可读前提)· 结算明细主角攻击行拆"(普通 X + 穿刺 Y + 魔法 Z)" · 反噬效果行入明细流 · settlement_snapshot 增 armor/charge 字段(JSONL 数值分析面) | -**数值全部 provisional 待拍板/调参**(登记于 enemy.tres / settlement.tres 注释):damage_a_per_cell=1 · damage_a_cap=8 · damage_b_per_flag=2 · 矩阵 150/100/50 · enrage/off_guard 25% · 伏击 +2 层 · 护甲映射 goblin/bugbear/ogre——C3 调参时按 F6 供给平衡式复算(三段充能是新增伤害供给,裸装败北/基线通关率两条冒烟路径已复验仍成立)。 +**数值全部 provisional 待拍板/调参**(登记于 enemy.tres / settlement.tres 注释):charge_grants(开格→穿刺桶 1/格 · 计数上限 8 · 标中旗→魔法桶 2/雷 · 无上限)· 矩阵 150/100/50 · enrage/off_guard 25% · 伏击 +2 层 · 护甲映射 goblin/bugbear/ogre——C3 调参时按 F6 供给平衡式复算(三段充能是新增伤害供给,裸装败北/基线通关率两条冒烟路径已复验仍成立)。 -**正式侧义务(GDD/registry 修订清单,待文档批)**:B2 GDD(EnemyTable armor_type 字段 + schema)、B1 GDD(F3 主角攻击三分量构成 + flag_miss 反噬编排 + 克制矩阵载体)、B3 GDD(六行 MVP 状态表 + source_class flag_miss 授予)、A2 OQ1(标错惩罚候选升级为三选一随机池 + 重复性口径=每雷格实例一次)、registry(enemy/settlement_table/status_effect 条目 + A3 条款②锚与条款③不等式重推导——标中旗收益从纯 weaken 变"weaken+伤害B 充能")、C3(数值 provisional 接管)。lore 侧:`design/research/lore-nest-metaphor-2026-09-12.md`(伤害A=地利/伤害B=封印暴露、反噬=封印失败——待新会话拍板后写回 game-concept)。 +**正式侧义务(GDD/registry 修订清单,待文档批)**:B2 GDD(EnemyTable armor_type 字段 + schema)、B1 GDD(F3 主角攻击三分量构成 + flag_miss 反噬编排 + 克制矩阵载体)、B3 GDD(六行 MVP 状态表 + source_class flag_miss 授予)、A2 OQ1(标错惩罚候选升级为三选一随机池 + 重复性口径=每雷格实例一次)、registry(enemy/settlement_table/status_effect 条目 + A3 条款②锚与条款③不等式重推导——标中旗收益从纯 weaken 变"weaken+魔法 充能")、C3(数值 provisional 接管)。lore 侧:`design/research/lore-nest-metaphor-2026-09-12.md`(穿刺=地利/魔法=封印暴露、反噬=封印失败——待新会话拍板后写回 game-concept)。 **验证**:冒烟 **161/161**(+12:护甲快照三档传播 / 克制矩阵三行表值 / hero_attack 行三分量字段〔全战斗回放 ×2〕/ 标错旗 flag_miss+反噬效果行 / 标中雷充能进主角攻击 / 反噬派生同种子回放)· ui_probe PASS · ui_tune_probe PASS · ui_click_probe(done=true、选用失效=0、问题=0)。 @@ -383,7 +383,7 @@ Godot_v4.7.2-stable_win64_console.exe --headless --path . --script res://smoke/s **背景**:用户(扫雷强玩家)指出"完全正确开图/标雷、零踩雷 ⇒ 存活无压力"——现行扫描只有弱策略基线档(不标旗/邻格盲挖/朴素选道具),技能轴不可测;registry `calibration_gap`(真人显著强于模拟者)此前只有方向无机制。本批 = 测量工具批。 **落地变更**: -- `auto_player.gd` 增完美策略求解器(`perfect_action`/`_deduce`):single + subset 推理不动点(A1 F1 `measure_inferability` 同族规则集,**去 safe_set oracle**——约束未知邻格含雷格,比生成期闸保守);**零盲挖**(只挖已证安全格 = 构造保证零踩雷,扫描末断言兜底违例 quit(1))· **已证雷格全标旗**(旗先于挖——轮末 weaken + 伤害B 首次充能,雷上旗不阻连锁)· 卡死且资源可 → `b1.player_request_refresh()` 轮内刷新 · 否则停手(残 AP 1:1 入 RAP)。输入只经 A2 查询面(reveal_record/is_revealed/has_flag),**禁读棋盘雷区真值**——测推理上界,非全知作弊。core 层零改动; +- `auto_player.gd` 增完美策略求解器(`perfect_action`/`_deduce`):single + subset 推理不动点(A1 F1 `measure_inferability` 同族规则集,**去 safe_set oracle**——约束未知邻格含雷格,比生成期闸保守);**零盲挖**(只挖已证安全格 = 构造保证零踩雷,扫描末断言兜底违例 quit(1))· **已证雷格全标旗**(旗先于挖——轮末 weaken + 魔法 首次充能,雷上旗不阻连锁)· 卡死且资源可 → `b1.player_request_refresh()` 轮内刷新 · 否则停手(残 AP 1:1 入 RAP)。输入只经 A2 查询面(reveal_record/is_revealed/has_flag),**禁读棋盘雷区真值**——测推理上界,非全知作弊。core 层零改动; - `window_selection` 增 `heal_no_waste` 选项(缺口 < 治疗量不用;完美档启用)+ 完美档轮次门解除(round_gate=0); - `level_autoplay.gd` 增 `policy` 参数(默认 "normal"——tune_sim_controller/defense_scan/level_debug 既有调用零改动);完美档驱动 `_autoplay_battle_perfect`(move/dig/flag 走 A2 settle_batch、refresh 走 B1 编排、连续拒绝 ≥3 停手防死循环);st 增 `mine_hits`/`refreshes` 计数(mine_hit 证据行埋点); - `level_monte_carlo.gd` 增第 3 CLI 参 `[policy]`(normal/perfect/both,缺省 normal 兼容既有文档命令)+ 策略/踩雷/刷新列;脚注 F5 带文案同步 [30,50] 带锚定稿。 @@ -409,3 +409,41 @@ Godot_v4.7.2-stable_win64_console.exe --headless --path . --script res://smoke/s - **验收结论:≤40% 线用数值区间杠杆族到不了**——完美玩家结构性优势(零踩雷 = 零直伤 + 全标旗 = weaken −65% 顶格 + 快杀 = 敌出手次数最少)不受值域方差影响。三选待裁决:①承伤硬地板(每结算不可减免平伤——S_min 压缩,B1/B2 域);②weaken 饱和/递减语义(拆"全标旗顶格"基石,B3/B1 域);③极端宽度(数值可用但毁基线档与可读性锚——建议否决)。**本批区间机制保留**(对普通玩家方差体验有效,中点锚不伤当量)。 **验证**:冒烟 **154/149+5 全绿**(区间批 5 新断言 + 既有全部回归含遭遇骰分布/回放)。 + +## 2026-09-15 攻击/护甲命名统一批(用户拍板"一并修改,统一称呼"——纯改名,数值零改动) + +**触发**:GDD 评审(战斗结算)问题 1——位置键 `{base, dmg_a, dmg_b}` / `{none, a, b}` 不承载语义(a/b 是纯位置占位符:既说不出来源,也说不出来克制谁),且同一件事在仓内已分裂成四种写法(敌人系统 `{无, 甲, 重甲}` / 03-内容规模 `无甲/甲A/甲B` / registry `{none, a, b}` / 本 README `无甲/护甲A/护甲B`)。 + +**新词汇(全仓唯一现行词)**: + +| 面 | 新 | 旧(作废) | +|---|---|---| +| 攻击类型(结算表矩阵行键 / hero_attack 行分量) | `normal` / `pierce` / `magic` = 普通 / 穿刺 / 魔法 | `base` / `dmg_a` / `dmg_b` = 基础 / 伤害A / 伤害B | +| 护甲类型(`armor_type` / 矩阵列键) | `light` / `ward` / `heavy` = 轻甲 / 魔法护甲 / 重甲 | `none` / `a` / `b` = 无甲 / 护甲A / 护甲B | +| 结算表字段 | `charge_grants`(触发源→{attack_type, per_unit, cap},同日第二批抽象分离后定型) | `damage_a_per_cell` / `damage_a_cap` / `damage_b_per_flag`("类型×来源"焊死命名;同名批曾短暂改 `pierce_per_cell` / `pierce_cap` / `magic_per_flag`,随即作废) | +| 结算快照 round_facts | `charge_counts`(各触发源计数)+ `charge_points`(按攻击类型分桶点数) | `charge_dmg_a` / `charge_dmg_b`(既有 JSONL 留存文件仍用旧键) | + +映射沿教学梯度:goblin `none`→`light`、bugbear `a`→`ward`、ogre_chief `b`→`heavy`;**矩阵数值逐格不动**(pierce→ward 150 / pierce→heavy 50 / magic→heavy 150 / magic→ward 50 / normal 全 100)。 + +**同日第二批 · 攻击类型与奖励抽象分离**(用户裁定"攻击类型的定义和格子奖励要分离开;开格|标雷 → 奖励;奖励如何定义是可以修改的;不要将两者绑定"):攻击类型 = 伤害的属性轴(普通 / 穿刺 / 魔法,只决定查甲效矩阵哪一行,定义里不含任何棋盘来源);充能 = 按攻击类型分桶的附加伤害储备,**谁能充、充哪个桶 = 奖励定义**(`charge_grants`;开格 / 标中旗 / 踩雷 / 清图一律只作奖励触发源)。原 `pierce_per_cell` / `magic_per_flag` 式命名(类型与来源焊在一根名字里)作废。冒烟新增三条断言:奖励定义在位 ×2 + 行为断言(把"标中旗"奖励改投穿刺桶 → 同一战斗魔法分量归零;还原后步骤流逐行相同——证明改道唯一入口是奖励定义)。 + +**落点**:GDD(战斗结算 v0.5 / 敌人系统 / 难度曲线与Boss / 03-内容规模)+ registry(`enemy.armor_type`、`settlement_table.armor_effectiveness` 与三字段 + 批次注记)+ 切片(`enemy_table.gd` `ARMOR_TYPES`、`settlement_table.gd` `ARMOR_KEYS` / `ATTACK_TYPE_KEYS`〔原 `COMPONENT_KEYS`〕、`enemy.tres`、`settlement.tres`、`damage_math.gd`、`unit_container.gd`、`battle_orchestrator.gd`、`enemy_card_view.gd`〔敌卡常驻标签改 轻甲 / 魔法护甲 / 重甲〕、`battle_log_view.gd`〔拆行文案改"(普通 X + 穿刺 Y + 魔法 Z)"〕、`smoke_all.gd` / `damage_probe.gd` / `auto_player.gd`);playtest 观测记录保留当时键名并附现名。 + +**验证(本批实跑)**:冒烟 **201 项检查 0 失败**(含分离批三条新断言:奖励定义在位 ×2 + 行为断言"标中旗奖励改投穿刺桶 → 魔法分量归零、还原后步骤流逐行相同")· `ui_probe` PASS · `ui_tune_probe` PASS · `ui_click_probe`(done=true、选用失效=0、问题=0)· `ui_layout_probe` PASS——四探针 exit=0、FAIL 行 0。命名批纯改名零行为变更;分离批为结构重构,数值链路等价(旧"计数×每单位×克制"与现行"计数→按奖励定义折算点数→×克制"结果相同,冒烟全量回归含回放断言未动)。 + +## 2026-09-15 验收 + 收口批(两批改动闭合核对;零数值零机制改动;不碰 v0.7 文件) + +**背景**:2026-09-15 两批(攻击/护甲命名统一 v0.5 + 攻击类型/奖励抽象分离 v0.6)已完成;本批只读核对"文档口径 ↔ 切片实现"是否闭合,并收口遗留开口。**范围纪律**:`战斗结算.md` / `奖励道具经济.md` 属 v0.7 格面资源批所有者文件、口径仍在移动——本批不改;③ 收口项落在 `registry` + 本 README + `active.md`,GDD 侧只报告、待 v0.7 批整体收口后回填。 + +**核对结论(两批核心语义 9 项全闭合)**:`charge_grants` 键与值(safe_cell→pierce 1/格 cap 8 · flag_hit→magic 2/雷 cap 0)· 甲效矩阵 9 格(normal 全 100 / pierce→ward 150、heavy 50 / magic→heavy 150、ward 50)· `armor_type` 三值(light/ward/heavy)· `hero_attack` 行分量字段(normal/pierce/magic)· round_facts 键(`charge_counts`/`charge_points`)· 敌卡标签文案(轻甲/魔法护甲/重甲)· 明细行拆行文案"(普通 X + 穿刺 Y + 魔法 Z)"· 攻击类型定义不含来源 · 矩阵数值逐格不动——GDD/registry/tres/代码逐项一致。残留旧名扫描仅命中批次注记"原名"与历史观测记录;来源-类型硬绑扫描确认代码只剩两处计数埋点(`_charge_counts["safe_cell"]` / `["flag_hit"]`)+ `charge_grants` 键 + 行 `source_class` 归因。 + +**实跑(本批)**:冒烟 **201 项检查 0 失败**;四场景探针 `ui_probe` / `ui_tune_probe` / `ui_click_probe` / `ui_layout_probe` 全部 **exit=0、无 FAIL 行**。 + +**收口(③,落在非 GDD 文件)**: +- ① **收益对照表充能当量覆盖缺口**:登记于本 README + registry + `active.md`(GDD 收益对照表回填待 v0.7 批收口后)。候选口径 = 充能当量 = Σ各桶点数 × 当轮目标护甲平均甲效倍率 ÷ 100(与直伤同类 1 伤害 = 1 当量,守 行动经济 条款①单一当量);补式 / 登记待拍板二选一待回填批裁定。 +- ② **两处已知落差登记**:a) `charge_grants` 触发源可扩展 vs 切片仅两个触发源计数埋点(新增源须加埋点);b) `safe_cell`/`flag_hit` 来源标识跨命名空间同名(明细行 `source_class` / `charge_grants` 键;RewardTable.pool_tag 已随格面资源批改 `cell`)。 +- ③ playtest 观测记录的快照键"现名"注记由中间名订正为现行名 `charge_counts`/`charge_points`。 + +**注意(口径移动)**:本批运行期间 **v0.7 格面资源批**已在 GDD(战斗结算 v0.7 / 奖励道具经济 v0.4)与 registry 落地——段序七→五、行型 15→10、极性路由取代三套固定兑付、可选类道具删除。切片代码尚未同步(registry 注明"切片代码修改随新会话执行、指导已产出"),故本文以上各历史批次条目保留当时陈述。 + +**两轴分离措辞不变**:攻击类型 = 伤害属性轴(定义不含来源);充能 = 按攻击类型分桶的附加伤害储备,投桶归奖励定义 `charge_grants`;开格/标中旗/踩雷/清图只作奖励触发源。 diff --git a/prototypes/dungeon-sweeper-vertical-slice/core/battle_orchestrator.gd b/prototypes/dungeon-sweeper-vertical-slice/core/battle_orchestrator.gd index 0113bde0..984f19b3 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/core/battle_orchestrator.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/core/battle_orchestrator.gd @@ -61,8 +61,7 @@ var _perfect_hit_false := 0 var _enemy_cap := 0 # EnemyTable 行值快照(伏击 cap) var _m_amb := 0 # StatusEffectTable.ambush.magnitude 快照 var _hero_atk := 0 # 主角攻击基值快照(encounter.hero_atk;E4 收口——表值运行期不可变) -var _charge_dmg_a := 0 # 伤害A 充能:本轮开出的资格格计数(轮末结算消费后随 facts 重置) -var _charge_dmg_b := 0 # 伤害B 充能:本轮首次标中雷计数 ×damage_b_per_flag(每雷实例一次) +var _charge_counts: Dictionary = {} # 本轮充能计数 {奖励触发源: 计数}——投哪个攻击类型桶由 settlement.charge_grants(奖励定义)决定,本类不认识"开格=穿刺"这类绑定 func _init(db_ref, rng_ref, shared_reward_economy = null) -> void: @@ -206,7 +205,7 @@ func _settle() -> void: if evt.kind == "mine": mine_cells.append(evt.cell) elif evt.kind == "safe" and evt.reward_eligible: - _charge_dmg_a += 1 # 伤害A 充能:探索本身计费,与该格奖励是否兑付成功无关(初始展开格 reward_eligible=false 不计) + _charge_counts["safe_cell"] = int(_charge_counts.get("safe_cell", 0)) + 1 # 充能计数(开格 = 奖励触发源;只计数,投哪个桶由 charge_grants 决定);初始展开格 reward_eligible=false 不计 _grant_cell(evt.cell, ri, "safe_cell", evt.get("reward_snapshot")) # reward_eligible=false(initial 通道)不入库——战斗结算 义务②(行动经济 EC5 委派闭环) for evt in _facts_flags: @@ -352,7 +351,7 @@ func _judge_flag(evt: Dictionary, ri: int) -> void: return # 去重跳过(资格以雷格实例为键——排雷玩法 诚实重复上报的对侧);零明细行 _flag_consumed[cell] = true _perfect_hit_true += 1 - _charge_dmg_b += int(db.settlement.damage_b_per_flag) # 伤害B 充能:与 weaken 消费同键(每雷实例一次——忘拔旗不重复充能) + _charge_counts["flag_hit"] = int(_charge_counts.get("flag_hit", 0)) + 1 # 充能计数(标中旗 = 奖励触发源;与 weaken 消费同键,每雷实例一次——忘拔旗不重复充能) var ok: bool = _status_effects.apply_effect("weaken", {"source_class": "flag_hit", "origin_cell": cell, "round_index": ri}) if ok: var row: Dictionary = db.status_effect_row("weaken") @@ -511,23 +510,33 @@ func _apply_selected_item(window_index: int, ri: int) -> void: func _combat_segment(ri: int) -> void: var L := _status_effects.pool_layers("ambush") # 授予段后的当轮值;池共享不消耗 # ⓪ 主角先手攻击(基础攻击恒存在——2026-09-11 用户裁决;先于敌方行动)。 - # 三段伤害构成(2026-09-12 用户拍板):基础(atk×(1+attack_up),不吃克制)+ 伤害A(开格充能×克制)+ 伤害B(标雷充能×克制), - # 按目标护甲类型分别乘克制系数后 floor 相加;attack_up 仍只乘基础攻击(刀/AOE 恒定表值不吃修正不变)。 + # 三段伤害构成(2026-09-12 用户拍板;2026-09-15 命名统一批 + 攻击类型/奖励抽象分离批):普通(atk×(1+attack_up),不吃克制) + # + 穿刺/魔法(由充能供给——充能按攻击类型分桶,谁能充/充哪个桶归奖励定义 charge_grants)。攻击类型只管查甲效矩阵哪一行,与来源无关。 var hero_target = _enemy_system.default_target() if hero_target != null: - var armor: String = String(hero_target.get("armor_type", "none")) + var armor: String = String(hero_target.get("armor_type", "light")) var up := clampi(_pool_effective("attack_up"), int(db.settlement.pool_clamp_lo), int(db.settlement.pool_clamp_hi)) - var base := maxi(0, int(floor(float(_hero_atk) * (100.0 + float(up)) / 100.0))) - var comp_a := _charge_damage_component("dmg_a", _charge_dmg_a, armor) - var comp_b := _charge_damage_component("dmg_b", _charge_dmg_b, armor) - var d_hero: int = base + comp_a + comp_b + var points := _charge_points() # {攻击类型: 充能点数}——奖励定义投递的结果(本段不认识"开格/标雷") + var comp: Dictionary = {} + var d_hero := 0 + for atk_type in SettlementTable.ATTACK_TYPE_KEYS: + var c: int = 0 + if atk_type == "normal": + c = maxi(0, int(floor(float(_hero_atk) * (100.0 + float(up)) / 100.0))) # 普通分量走攻击力基线:吃增益、不吃克制 + else: + c = _charge_component(int(points.get(atk_type, 0)), atk_type, armor) + comp[atk_type] = c + d_hero += c + var payload: Dictionary = {"target": hero_target.display_name} + payload.merge(comp) if d_hero > 0: _enemy_system.apply_damage(hero_target, d_hero) - _emit_row("damage", "hero_attack", Vector2i(-1, -1), ri, "主角攻击", d_hero, {"target": hero_target.display_name, "killed": not hero_target.alive, "base": base, "dmg_a": comp_a, "dmg_b": comp_b}) + payload["killed"] = not hero_target.alive # 击杀标记在扣血后取(原语义不变) + _emit_row("damage", "hero_attack", Vector2i(-1, -1), ri, "主角攻击", d_hero, payload) else: # 零值伤害行(战斗结算 边界表:"合成后为 0 时不调扣血接口,改写零值伤害行——免伤与零输出必须可见"; - # 敌方侧同款口径已就绪——照抄。三分量字段齐备保 P2 归因不断链) - _emit_row("damage", "hero_attack", Vector2i(-1, -1), ri, "主角攻击(被减伤归零)", 0, {"target": hero_target.display_name, "base": base, "dmg_a": comp_a, "dmg_b": comp_b}) + # 敌方侧同款口径已就绪——照抄。分量字段齐备保 P2 归因不断链) + _emit_row("damage", "hero_attack", Vector2i(-1, -1), ri, "主角攻击(被减伤归零)", 0, payload) for u in _enemy_system.query_alive("enemy"): if int(_enemy_system.hero_unit().hp) <= 0: break # hero hp=0 立即短路(死尸挨打行是归因噪音——用户拍板) @@ -552,19 +561,33 @@ func _resolve_damage(d_raw: int) -> int: return DamageMath.pool_damage(d_raw, p_hero, p_enemy) -# 伤害A/B 充能分量:充能 × 每单位值 × 克制 percent → floor(伤害A 先套单轮充能上限——防连锁轮失控) -func _charge_damage_component(component: String, count: int, armor: String) -> int: - var per: int = int(db.settlement.damage_a_per_cell) if component == "dmg_a" else int(db.settlement.damage_b_per_flag) - var charge := count - if component == "dmg_a" and int(db.settlement.damage_a_cap) > 0: - charge = mini(charge, int(db.settlement.damage_a_cap)) - return DamageMath.charge_component(charge, per, _armor_effectiveness(component, armor)) +# 充能点数合成:奖励定义(charge_grants:触发源→{attack_type, per_unit, cap})× 本轮各源计数 → {攻击类型: 点数} +# cap = 单轮计数上限(0 = 不封顶);投桶只读 attack_type 字段——换桶/换量是奖励侧改动,本类不认识"开格=穿刺"这类绑定 +func _charge_points() -> Dictionary: + var pts: Dictionary = {} + for src in db.settlement.charge_grants.keys(): + var g: Dictionary = db.settlement.charge_grants[src] + var attack_type: String = String(g.get("attack_type", "")) + var per: int = int(g.get("per_unit", 0)) + var cap: int = int(g.get("cap", 0)) + var n: int = int(_charge_counts.get(src, 0)) + if cap > 0: + n = mini(n, cap) + if attack_type == "" or per <= 0 or n <= 0: + continue + pts[attack_type] = int(pts.get(attack_type, 0)) + n * per + return pts -# 克制矩阵读值(SettlementTable.armor_effectiveness:{分量: {护甲: percent}}——缺项回退 100 中性) -func _armor_effectiveness(component: String, armor: String) -> int: +# 充能分量:点数(已含 per_unit × 计数换算)× 克制 percent → floor +func _charge_component(points: int, attack_type: String, armor: String) -> int: + return DamageMath.charge_component(points, _armor_effectiveness(attack_type, armor)) + + +# 克制矩阵读值(SettlementTable.armor_effectiveness:{攻击类型: {护甲: percent}}——缺项回退 100 中性) +func _armor_effectiveness(attack_type: String, armor: String) -> int: var tbl: Dictionary = db.settlement.armor_effectiveness - var row: Dictionary = tbl.get(component, {}) + var row: Dictionary = tbl.get(attack_type, {}) return int(row.get(armor, 100)) @@ -602,7 +625,7 @@ func _emit_composition_effects(side: String, ri: int) -> void: func _emit_settlement_snapshot(verdict: String) -> void: var enemies: Array = [] for u in _enemy_system.query_alive("enemy"): - enemies.append({"id": String(u.enemy_id), "hp": int(u.hp), "max_hp": int(u.max_hp), "atk": int(u.atk), "beat": query_beat_of(u), "armor": String(u.get("armor_type", "none"))}) + enemies.append({"id": String(u.enemy_id), "hp": int(u.hp), "max_hp": int(u.max_hp), "atk": int(u.atk), "beat": query_beat_of(u), "armor": String(u.get("armor_type", "light"))}) var buffs: Array = [] for eff in _status_effects.query_active("hero"): buffs.append({"id": eff.effect_id, "side": "hero", "layers": eff.layers, "left": eff.remaining_settlements}) @@ -636,7 +659,7 @@ func _emit_settlement_snapshot(verdict: String) -> void: "buffs": buffs, "ambush_layers": _status_effects.pool_layers("ambush"), "inventory_in_stock": _reward_economy.in_stock_count(), - "round_facts": {"path": _facts_path, "safe": safe_n, "mines": mines_hit, "flag_events": _facts_flags.size(), "charge_dmg_a": _charge_dmg_a, "charge_dmg_b": _charge_dmg_b}, + "round_facts": {"path": _facts_path, "safe": safe_n, "mines": mines_hit, "flag_events": _facts_flags.size(), "charge_counts": _charge_counts.duplicate(), "charge_points": _charge_points()}, }) @@ -719,7 +742,7 @@ func presentation_snapshot() -> Dictionary: "display_name": String(u.display_name), "hp": int(u.hp), "max_hp": int(u.max_hp), "enemy_id": String(u.enemy_id), - "armor_type": String(u.get("armor_type", "none")), + "armor_type": String(u.get("armor_type", "light")), "beat": String(_enemy_system.query_beat(u)) if alive else "", "ring_size": ring.size(), "ring_index": int(u.get("steps", 0)) % maxi(ring.size(), 1), @@ -794,8 +817,7 @@ func _reset_round_facts() -> void: _facts_reveals.clear() _facts_flags.clear() _facts_path = "" - _charge_dmg_a = 0 # 三段伤害充能随轮 facts 重置(每轮重新充能——结算段消费当轮值) - _charge_dmg_b = 0 + _charge_counts.clear() # 充能计数随轮 facts 重置(每轮重新攒——结算段按奖励定义折算当轮点数) # ---- 行协议(Core Rule 14:公共字段 + 行类型特有字段)---- diff --git a/prototypes/dungeon-sweeper-vertical-slice/core/damage_math.gd b/prototypes/dungeon-sweeper-vertical-slice/core/damage_math.gd index a83f4bd0..5f654b7d 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/core/damage_math.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/core/damage_math.gd @@ -13,7 +13,6 @@ static func pool_damage(d_raw: int, p_hero: int, p_enemy: int) -> int: return maxi(0, v) -# 伤害A/B 充能分量:充能(调用方已套单轮充能上限)× 每单位值 × 克制 percent → floor -static func charge_component(charge: int, per_unit: int, effectiveness_percent: int) -> int: - var pts := charge * per_unit - return int(floor(float(pts) * float(effectiveness_percent) / 100.0)) +# 充能分量:充能点数(调用方已按奖励定义换算点数、并按源套单轮计数上限)× 克制 percent → floor +static func charge_component(points: int, effectiveness_percent: int) -> int: + return int(floor(float(points) * float(effectiveness_percent) / 100.0)) diff --git a/prototypes/dungeon-sweeper-vertical-slice/core/unit_container.gd b/prototypes/dungeon-sweeper-vertical-slice/core/unit_container.gd index 529e53a3..303d56f3 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/core/unit_container.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/core/unit_container.gd @@ -67,7 +67,7 @@ func spawn(level_index: int, node_depth: int, hero_hp: int, unit_count_override: "heavy_multiplier": int(row.heavy_multiplier), "pattern": Array(row.pattern), # 行值快照(拷贝) "advantage_per_round_cap": int(row.advantage_per_round_cap), - "armor_type": String(row.get("armor_type", "none")), # 护甲类型快照(克制矩阵消费面——战斗结算·战斗段) + "armor_type": String(row.get("armor_type", "light")), # 护甲类型快照(克制矩阵消费面——战斗结算·战斗段;2026-09-15 命名统一批:light/ward/heavy) "steps": 0, "alive": true, "is_hero": false, diff --git a/prototypes/dungeon-sweeper-vertical-slice/data/schemas/enemy_table.gd b/prototypes/dungeon-sweeper-vertical-slice/data/schemas/enemy_table.gd index 042143c5..44637f82 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/data/schemas/enemy_table.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/data/schemas/enemy_table.gd @@ -10,8 +10,9 @@ extends Resource const PATTERN_MVP := ["attack", "charge", "heavy"] const PATTERN_RESERVED := ["guard", "boost", "hinder", "summon"] -# 护甲类型封闭枚举(伤害类型 × 护甲克制批——克制矩阵本体在 SettlementTable) -const ARMOR_TYPES := ["none", "a", "b"] +# 护甲类型封闭枚举(攻击类型 × 护甲克制批——克制矩阵本体在 SettlementTable; +# 2026-09-15 命名统一批:位置键 {none, a, b} → 语义键 {light, ward, heavy} = 轻甲 / 魔法护甲 / 重甲) +const ARMOR_TYPES := ["light", "ward", "heavy"] func validate() -> Array: @@ -77,10 +78,10 @@ func validate() -> Array: var cap: int = int(row.get("advantage_per_round_cap", -1)) if cap < 0 or cap > 16: errs.append({"category": "domain", "message": "%s advantage_per_round_cap 越域 [0,16]" % eid}) - # armor_type(可省略——缺省 none 向后兼容) - var at: String = String(row.get("armor_type", "none")) + # armor_type(可省略——缺省 light 向后兼容) + var at: String = String(row.get("armor_type", "light")) if not ARMOR_TYPES.has(at): - errs.append({"category": "enum", "message": "%s armor_type 未知枚举: %s(域 {none, a, b})" % [eid, at]}) + errs.append({"category": "enum", "message": "%s armor_type 未知枚举: %s(域 {light, ward, heavy})" % [eid, at]}) # 每行集恰一敌种(行集内 enemy_id 唯一) var rk := "%d_%d" % [L, D] if rowset_species.has(rk): diff --git a/prototypes/dungeon-sweeper-vertical-slice/data/schemas/settlement_table.gd b/prototypes/dungeon-sweeper-vertical-slice/data/schemas/settlement_table.gd index b9b20a78..9662c583 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/data/schemas/settlement_table.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/data/schemas/settlement_table.gd @@ -14,15 +14,16 @@ extends Resource @export var pool_clamp_lo: int = -100 # 结构冻结 @export var pool_clamp_hi: int = 100 # 结构冻结 @export var round_direction: String = "floor" # 结构冻结——单一取整规则 -# ---- 伤害类型 × 护甲克制批(2026-09-12 用户拍板结构;数值 provisional 待调参)---- -# 主角攻击 = 基础(atk×(1+attack_up),不吃克制)+ 开格充能×克制 + 标雷充能×克制(分量各自 floor 后相加) -@export var damage_a_per_cell: int = 1 # 伤害A 充能:本轮每开 1 资格格(reward_eligible 安全格)+N -@export var damage_a_cap: int = 8 # 伤害A 单轮充能上限(0 = 不封顶;8 与 ap_per_round 对齐) -@export var damage_b_per_flag: int = 2 # 伤害B 充能:每颗首次标中雷 +N(沿用每雷实例一次去重——结构上限) -@export var armor_effectiveness: Dictionary = {} # 克制矩阵 percent:{分量 {base|dmg_a|dmg_b}: {护甲 {none|a|b}: percent}} +# ---- 攻击类型 × 护甲克制批 + 充能奖励定义(2026-09-12 用户拍板结构;2026-09-15 命名统一批 / 抽象分离批;数值 provisional)---- +# 主角攻击 = 普通(atk×(1+attack_up),不吃克制)+ 穿刺 + 魔法(后两者由充能供给),三分量各自 floor 后相加。 +# 【两条抽象分离,勿焊死】攻击类型 = 伤害的属性轴,只决定查 armor_effectiveness 哪一行,定义里不含任何棋盘来源; +# 充能 = 按攻击类型分桶的附加伤害储备,"谁往桶里放东西"属**奖励的定义**(开格/标雷只是奖励触发源,奖励内容可改)。 +# 原 damage_a_per_cell / damage_a_cap / damage_b_per_flag 三字段即"类型×来源"焊死的产物,已由 charge_grants 取代。 +@export var charge_grants: Dictionary = {} # 奖励侧定义:触发源 → {attack_type(投哪个桶), per_unit(每单位点数), cap(单轮计数上限,0 = 不封顶)} +@export var armor_effectiveness: Dictionary = {} # 克制矩阵 percent:{攻击类型 {normal|pierce|magic}: {护甲 {light|ward|heavy}: percent}} -const ARMOR_KEYS := ["none", "a", "b"] -const COMPONENT_KEYS := ["base", "dmg_a", "dmg_b"] +const ARMOR_KEYS := ["light", "ward", "heavy"] +const ATTACK_TYPE_KEYS := ["normal", "pierce", "magic"] const FROZEN_SEGMENT_ORDER := ["grant", "item_window", "buff_debuff", "item", "combat", "decay", "verdict"] const P_PERFECT_DOMAIN := [100, 200] @@ -41,17 +42,22 @@ func validate() -> Array: errs.append({"category": "frozen", "message": "round_direction 结构冻结 floor: %s" % round_direction}) if pool_clamp_lo != -100 or pool_clamp_hi != 100: errs.append({"category": "frozen", "message": "pool_clamp 域结构冻结 [-100,+100]"}) - # 伤害类型 × 护甲克制批新字段域校验 - if damage_a_per_cell < 0 or damage_a_per_cell > 999: - errs.append({"category": "domain", "message": "damage_a_per_cell 越域 [0,999]: %d" % damage_a_per_cell}) - if damage_a_cap < 0 or damage_a_cap > 999: - errs.append({"category": "domain", "message": "damage_a_cap 越域 [0,999](0 = 不封顶): %d" % damage_a_cap}) - if damage_b_per_flag < 0 or damage_b_per_flag > 999: - errs.append({"category": "domain", "message": "damage_b_per_flag 越域 [0,999]: %d" % damage_b_per_flag}) - for comp in COMPONENT_KEYS: - var row: Dictionary = armor_effectiveness.get(comp, {}) + # 充能奖励定义域校验(触发源 → {attack_type, per_unit, cap}) + for src in charge_grants.keys(): + var g: Dictionary = charge_grants[src] + var g_at: String = String(g.get("attack_type", "")) + if not ATTACK_TYPE_KEYS.has(g_at): + errs.append({"category": "enum", "message": "charge_grants.%s.attack_type 未知攻击类型: %s(域 %s)" % [src, g_at, str(ATTACK_TYPE_KEYS)]}) + var g_per: int = int(g.get("per_unit", -1)) + if g_per < 0 or g_per > 999: + errs.append({"category": "domain", "message": "charge_grants.%s.per_unit 越域 [0,999]: %d" % [src, g_per]}) + var g_cap: int = int(g.get("cap", -1)) + if g_cap < 0 or g_cap > 999: + errs.append({"category": "domain", "message": "charge_grants.%s.cap 越域 [0,999](0 = 不封顶): %d" % [src, g_cap]}) + for atk_type in ATTACK_TYPE_KEYS: + var row: Dictionary = armor_effectiveness.get(atk_type, {}) for armor in ARMOR_KEYS: var pct: int = int(row.get(armor, -1)) if pct < 0 or pct > 999: - errs.append({"category": "domain", "message": "armor_effectiveness.%s.%s 越域 [0,999]: %d" % [comp, armor, pct]}) + errs.append({"category": "domain", "message": "armor_effectiveness.%s.%s 越域 [0,999]: %d" % [atk_type, armor, pct]}) return errs diff --git a/prototypes/dungeon-sweeper-vertical-slice/data/tables/enemy.tres b/prototypes/dungeon-sweeper-vertical-slice/data/tables/enemy.tres index 9452a5a5..bb3532ef 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/data/tables/enemy.tres +++ b/prototypes/dungeon-sweeper-vertical-slice/data/tables/enemy.tres @@ -18,7 +18,7 @@ rows = [{ "heavy_multiplier": 2, "pattern": ["attack"], "advantage_per_round_cap": 4, -"armor_type": "none" +"armor_type": "light" }, { "level_index": 1, "node_depth": 1, @@ -33,7 +33,7 @@ rows = [{ "heavy_multiplier": 2, "pattern": ["attack"], "advantage_per_round_cap": 4, -"armor_type": "none" +"armor_type": "light" }, { "level_index": 1, "node_depth": 2, @@ -47,7 +47,7 @@ rows = [{ "heavy_multiplier": 2, "pattern": ["attack", "charge", "heavy"], "advantage_per_round_cap": 4, -"armor_type": "a" +"armor_type": "ward" }, { "level_index": 1, "node_depth": 3, @@ -62,7 +62,7 @@ rows = [{ "heavy_multiplier": 2, "pattern": ["attack", "charge", "heavy"], "advantage_per_round_cap": 4, -"armor_type": "a" +"armor_type": "ward" }, { "level_index": 1, "node_depth": 4, @@ -76,7 +76,7 @@ rows = [{ "heavy_multiplier": 2, "pattern": ["attack", "attack", "charge", "heavy"], "advantage_per_round_cap": 4, -"armor_type": "b" +"armor_type": "heavy" }, { "level_index": 2, "node_depth": 0, @@ -90,7 +90,7 @@ rows = [{ "heavy_multiplier": 2, "pattern": ["attack", "charge", "heavy"], "advantage_per_round_cap": 4, -"armor_type": "a" +"armor_type": "ward" }] ; 切片调参登记 v3(2026-09-12 试玩批次 1 触发——F7 流程;C3 GDD F5 对照): @@ -103,9 +103,10 @@ rows = [{ ; 遭遇随机化批(2026-09-12 用户拍板):D0 [1,2]/D1 [2,3] hp13/D3 [2,3] hp18——数量区间骰(encounter 流,B1 掷骰); ; D2/Boss 固定(新敌种首遇教学位不加骰——C3 GDD Core Rule 8)。期望总量 ≈304(+8%),F6 带内。 ; -; 护甲类型批(2026-09-12 用户拍板:伤害类型 × 护甲类型克制——无甲/护甲A/护甲B): -; armor_type ∈ {none, a, b}(缺省 = none 向后兼容);克制矩阵本体在 settlement.tres.armor_effectiveness。 -; 映射(教学梯度:无甲→甲A→甲B):goblin=none · bugbear=a · ogre_chief=b(L2 bugbear 同 a)——候选方案, +; 护甲类型批(2026-09-12 用户拍板:攻击类型 × 护甲类型克制;2026-09-15 命名统一批——原位置键/位置名作废): +; armor_type ∈ {light, ward, heavy} = 轻甲 / 魔法护甲 / 重甲(缺省 = light 向后兼容;原 {none, a, b}); +; 克制矩阵本体在 settlement.tres.armor_effectiveness。 +; 映射(教学梯度:轻甲→魔法护甲→重甲):goblin=light · bugbear=ward · ogre_chief=heavy(L2 bugbear 同 ward)——候选方案, ; 数值与映射均 provisional 待用户调参。 ; 敌方攻击区间批(2026-09-14 用户拍板②第二步——"上限掺运气"敌方侧:atk 上阶/下阶,中点恒等行值; diff --git a/prototypes/dungeon-sweeper-vertical-slice/data/tables/settlement.tres b/prototypes/dungeon-sweeper-vertical-slice/data/tables/settlement.tres index 673fa0d1..7593f7f7 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/data/tables/settlement.tres +++ b/prototypes/dungeon-sweeper-vertical-slice/data/tables/settlement.tres @@ -28,32 +28,46 @@ effect_pool_map = { pool_clamp_lo = -100 pool_clamp_hi = 100 round_direction = "floor" -damage_a_per_cell = 1 -damage_a_cap = 8 -damage_b_per_flag = 2 +charge_grants = { +"safe_cell": { +"attack_type": "pierce", +"per_unit": 1, +"cap": 8 +}, +"flag_hit": { +"attack_type": "magic", +"per_unit": 2, +"cap": 0 +} +} armor_effectiveness = { -"base": { -"none": 100, -"a": 100, -"b": 100 +"normal": { +"light": 100, +"ward": 100, +"heavy": 100 }, -"dmg_a": { -"none": 100, -"a": 150, -"b": 50 +"pierce": { +"light": 100, +"ward": 150, +"heavy": 50 }, -"dmg_b": { -"none": 100, -"a": 50, -"b": 150 +"magic": { +"light": 100, +"ward": 50, +"heavy": 150 } } -; 伤害类型 × 护甲克制批(2026-09-12 用户拍板结构,数值 provisional 待用户/C3 调参): -; 主角攻击 = 基础(atk×(1+attack_up),对全部护甲 100%)+ 伤害A(开格充能×克制)+ 伤害B(标雷充能×克制), -; 三分量各自 floor 后相加;克制语义 = 特化甲 ×150 / 无甲 ×100 / 对位甲 ×50(穿甲弹/高爆弹式对策三角)。 -; damage_a_per_cell=1 · damage_a_cap=8(单轮充能封顶,防连锁轮失控;0 = 不封顶)· damage_b_per_flag=2 -; (每颗首次标中雷充能——沿用每雷实例一次去重,忘拔旗不重复充能)。 +; 攻击类型 × 护甲克制批(2026-09-12 用户拍板结构;2026-09-15 命名统一批 + 抽象分离批,数值 provisional 待用户/C3 调参): +; 主角攻击 = 普通(atk×(1+attack_up),对全部护甲 100%)+ 穿刺 + 魔法(后两者由充能供给),三分量各自 floor 后相加; +; 克制语义 = 克制 ×150 / 中性 ×100 / 被克 ×50(穿甲弹/高爆弹式对策三角)。 +; 【两条抽象分离,勿焊死】攻击类型 {normal, pierce, magic} = 普通 / 穿刺 / 魔法(原 {base, dmg_a, dmg_b})= +; 伤害的属性轴,只决定查矩阵哪一行,定义里不含任何棋盘来源;护甲类型 {light, ward, heavy} = 轻甲 / 魔法护甲 / 重甲 +; (原 {none, a, b})是敌单位属性。充能 = 按攻击类型分桶的附加伤害储备:谁能充、充哪个桶 = 奖励定义。 +; charge_grants 现行供给(奖励侧定义,可整体替换——换桶/换量/换成增益或道具都不触动攻击类型与矩阵): +; safe_cell(本轮每开 1 资格格)→ 穿刺桶 1/格、单轮计数上限 8(0 = 不封顶); +; flag_hit(每颗首次标中雷,每雷实例一次去重——忘拔旗不重复充能)→ 魔法桶 2/雷,无上限。 +; 原位置字段 damage_a_per_cell / damage_a_cap / damage_b_per_flag("类型×来源"焊死的命名)已废除。 ; enrage(敌方暴走 +25% 进 enemy_output 池)/ off_guard(我方失衡 +25% 进 hero_defense 池)= ; 标错惩罚池两行(第三项 = 复用 ambush +2 层);时效均 1 结算(用户拍板"短点,比如 1 回合")。 ; 减伤墙调参批(2026-09-13,playtest-2026-09-12 报告 Q1 触发):拟改 pool_clamp_lo=-60 被 schema diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/battle_log_view.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/battle_log_view.gd index dec49f62..9d24531e 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/battle_log_view.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/battle_log_view.gd @@ -172,9 +172,9 @@ func _format_row(row: Dictionary, agg_count := -1) -> String: var extra := "" if row.get("baseline", null) != null: extra = "(基线 %d + 伏击 %d)" % [int(row.baseline), int(row.attach)] - elif row.get("dmg_a", null) != null: - # 主角攻击三分量拆行(伤害×护甲克制批——P2 归因:这刀里哪段是开格/标雷挣的) - extra = "(基础 %d + 开格 %d + 标雷 %d)" % [int(row.base), int(row.dmg_a), int(row.dmg_b)] + elif row.get("pierce", null) != null: + # 主角攻击三分量拆行(攻击类型×护甲克制批——P2 归因:这刀里哪段是穿刺/魔法挣的) + extra = "(普通 %d + 穿刺 %d + 魔法 %d)" % [int(row.normal), int(row.pierce), int(row.magic)] var kill := " ⚔击杀!" if row.get("killed", false) else "" var body := "%s -%d%s%s%s%s" % [name_, v, extra, tail, kill, suffix] var body_col := "#e07050" if row.get("killed", false) else ("#9a8a72" if v == 0 else "#e0a050") diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/enemy_card_view.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/enemy_card_view.gd index d95dcb37..2a1475af 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/enemy_card_view.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/enemy_card_view.gd @@ -12,8 +12,8 @@ extends PanelContainer const COL_INK := Color8(51, 38, 27) const COL_BEAT := {"attack": Color8(198, 61, 34), "charge": Color8(90, 108, 140), "heavy": Color8(143, 47, 106)} const BEAT_NAMES := {"attack": "攻击", "charge": "蓄力", "heavy": "重击"} -# 护甲类型呈现(伤害×护甲克制批——可读性前提:玩家须能看出该用开格还是标雷打它) -const ARMOR_NAMES := {"none": "无甲", "a": "护甲A", "b": "护甲B"} +# 护甲类型呈现(攻击类型×护甲克制批——可读性前提:玩家须能看出该用穿刺还是魔法打它) +const ARMOR_NAMES := {"light": "轻甲", "ward": "魔法护甲", "heavy": "重甲"} var _portrait: Label var _name_label: Label @@ -21,7 +21,7 @@ var _hp_bar: ProgressBar var _intent_badge: Label var _ring: Label var _status_label: Label -var _armor := "none" # 护甲类型快照(set_data 写入、set_intent 渲染——环点行常驻标签) +var _armor := "light" # 护甲类型快照(set_data 写入、set_intent 渲染——环点行常驻标签) var _dead := false @@ -71,7 +71,7 @@ func set_data(d: Dictionary) -> void: _hp_bar.max_value = maxi(1, int(d.get("max_hp", 1))) _hp_bar.value = int(d.get("hp", 0)) _set_order(int(d.get("order", 1))) - _armor = String(d.get("armor_type", "none")) + _armor = String(d.get("armor_type", "light")) set_intent(String(d.get("beat", "")), int(d.get("ring_size", 0)), int(d.get("ring_index", 0))) var ambush: int = int(d.get("ambush_layers", 0)) _status_label.text = "伏击池 ×%d(全体共享)" % ambush if ambush > 0 else "" @@ -111,7 +111,7 @@ func set_intent(beat: String, ring_size: int, ring_index: int) -> void: func _armor_tag(armor: String) -> String: - return String(ARMOR_NAMES.get(armor, "无甲")) + return String(ARMOR_NAMES.get(armor, "轻甲")) # 死亡呈现:卡体灰化 + 碎裂退场(禁瞬消)——灰化残位 + 裂纹字符 + 击破标记 diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/auto_player.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/auto_player.gd index 73c81777..06fbe0a1 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/auto_player.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/smoke/auto_player.gd @@ -71,7 +71,7 @@ static func window_selection(s: Dictionary, items: Array, opts: Dictionary = {}) # ==================== 完美策略档(2026-09-14 用户拍板:OQ7 技能轴上界测量仪——只作测量,非玩法数值) ==================== # 策略语义:零盲挖(只挖已证安全格 ⇒ 构造保证零踩雷)· 已证雷格全标旗(旗先于挖——旗 = 纯收益 -# 〔轮末 weaken + 伤害B 首次充能〕且雷上旗不阻连锁)· 卡死且刷新资源可用 → 轮内刷新 +# 〔轮末 weaken + 魔法 首次充能〕且雷上旗不阻连锁)· 卡死且刷新资源可用 → 轮内刷新 # (经 settlement.player_request_refresh 核心编排)· 否则停手(残 AP 1:1 转存 RAP——下轮刷新资源)。 # 推理规则集 = 棋盘生成 F1 measure_inferability 同族(single + subset——solver_rules=single_subset 冻结域); # 口径差异 = unknown 集不含 棋盘生成 生成期 safe_set oracle(真实玩家约束的未知邻格含雷格)——比生成期闸 diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/damage_probe.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/damage_probe.gd index 6794e97e..c565631a 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/damage_probe.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/smoke/damage_probe.gd @@ -211,8 +211,8 @@ func _analyze_round(db, math, rows: Array, beats: Dictionary) -> Dictionary: String(beats.get(int(row.get("round_index", 0)), "?")), baseline, attach, raw, pd, pe, tick, expected, zeroed]) ticks.append({"raw": raw, "tick": tick, "expected": expected, "ok": tick == expected}) elif t == "damage" and String(row.get("source_class", "")) == "hero_attack": - lines.append("主角攻击 %d(base %d + 开格 %d + 标雷 %d)→ %s" % [ - int(row.get("value", 0)), int(row.get("base", 0)), int(row.get("dmg_a", 0)), int(row.get("dmg_b", 0)), String(row.get("target", ""))]) + lines.append("主角攻击 %d(普通 %d + 穿刺 %d + 魔法 %d)→ %s" % [ + int(row.get("value", 0)), int(row.get("normal", 0)), int(row.get("pierce", 0)), int(row.get("magic", 0)), String(row.get("target", ""))]) return {"pd": pd, "pe": pe, "grants": grants, "lines": lines, "ticks": ticks} diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/smoke_all.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/smoke_all.gd index 5e6313e5..107a757c 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/smoke_all.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/smoke/smoke_all.gd @@ -332,12 +332,12 @@ func _smoke_full_battle(L: int, D: int, label: String) -> void: has_verdict = true if row.get("source_class", "") == "hero_attack": hero_attacks += 1 - # 三段伤害构成行(伤害×护甲克制批):hero_attack 行必须携带 base/dmg_a/dmg_b 分量(P2 归因) - if not (row.has("base") and row.has("dmg_a") and row.has("dmg_b")): + # 三段伤害构成行(攻击类型×护甲克制批):hero_attack 行必须携带 normal/pierce/magic 分量(P2 归因) + if not (row.has("normal") and row.has("pierce") and row.has("magic")): hero_breakdown_ok = false check(has_verdict, "%s 步骤流含判定行" % label) check(hero_attacks >= 1, "%s 主角先手攻击行存在(2026-09-11 拍板①)×%d" % [label, hero_attacks]) - check(hero_breakdown_ok, "%s 主角攻击行携带三分量 base/dmg_a/dmg_b(克制批)" % label) + check(hero_breakdown_ok, "%s 主角攻击行携带三分量 normal/pierce/magic(克制批)" % label) if run1.terminated and run1.result == "victory": var lc = _last_settlement.level_clear() # 拍板③:关卡结束清库路径(战斗域不再清) check(lc.has("remaining"), "%s level_clear 返回快照计数(剩余 %d)" % [label, int(lc.get("remaining", -1))]) @@ -609,39 +609,63 @@ func _smoke_difficulty_table() -> void: _db.difficulty.rows.clear() # 还原空表(后续冒烟/关卡断言基线) -# ---- 伤害类型 × 护甲克制 + 标错惩罚冒烟(2026-09-12 克制批:护甲快照/克制矩阵/充能/反噬三选一)---- +# ---- 攻击类型 × 护甲克制 + 标错惩罚冒烟(2026-09-12 克制批:护甲快照/克制矩阵/充能/反噬三选一)---- func _smoke_damage_types() -> void: - print("--- 伤害类型 × 护甲克制 + 标错惩罚 ---") + print("--- 攻击类型 × 护甲克制 + 标错惩罚 ---") # ① 护甲类型快照传播(spawn 行值 → 单位字典) var enemy_system = load("res://core/unit_container.gd").new(_db) - check(enemy_system.spawn(1, 0, 50) and String(enemy_system.all_enemies()[0].armor_type) == "none", "goblin 护甲 = none(教学位无甲)") + check(enemy_system.spawn(1, 0, 50) and String(enemy_system.all_enemies()[0].armor_type) == "light", "goblin 护甲 = light(轻甲——教学位)") var enemy_system_b = load("res://core/unit_container.gd").new(_db) - check(enemy_system_b.spawn(1, 2, 50) and String(enemy_system_b.all_enemies()[0].armor_type) == "a", "bugbear 护甲 = a") + check(enemy_system_b.spawn(1, 2, 50) and String(enemy_system_b.all_enemies()[0].armor_type) == "ward", "bugbear 护甲 = ward(魔法护甲)") var enemy_system_c = load("res://core/unit_container.gd").new(_db) - check(enemy_system_c.spawn(1, 4, 50) and String(enemy_system_c.all_enemies()[0].armor_type) == "b", "ogre_chief 护甲 = b") - # ② 克制矩阵表值在位(三角:特化 150 / 中性 100 / 对位 50) + check(enemy_system_c.spawn(1, 4, 50) and String(enemy_system_c.all_enemies()[0].armor_type) == "heavy", "ogre_chief 护甲 = heavy(重甲)") + # ② 克制矩阵表值在位(三角:克制 150 / 中性 100 / 被克 50) var am: Dictionary = _db.settlement.armor_effectiveness - check(int(am.dmg_a.a) == 150 and int(am.dmg_a.b) == 50 and int(am.dmg_a.none) == 100, "伤害A 克制行:甲A 150 / 无甲 100 / 甲B 50") - check(int(am.dmg_b.b) == 150 and int(am.dmg_b.a) == 50 and int(am.dmg_b.none) == 100, "伤害B 克制行:甲B 150 / 无甲 100 / 甲A 50") - check(int(am.base.none) == 100 and int(am.base.a) == 100 and int(am.base.b) == 100, "基础伤害全护甲中性 100(不吃克制)") - # ③ 标错惩罚 + 标雷充能(Boss 行 150HP 多轮样本;板真相直读保证 hit/miss 确定性) + check(int(am.pierce.ward) == 150 and int(am.pierce.heavy) == 50 and int(am.pierce.light) == 100, "穿刺克制行:魔法护甲 150 / 轻甲 100 / 重甲 50") + check(int(am.magic.heavy) == 150 and int(am.magic.ward) == 50 and int(am.magic.light) == 100, "魔法克制行:重甲 150 / 轻甲 100 / 魔法护甲 50") + check(int(am.normal.light) == 100 and int(am.normal.ward) == 100 and int(am.normal.heavy) == 100, "普通攻击全护甲中性 100(不吃克制)") + # ②′ 充能奖励定义在位(抽象分离批:触发源 → 攻击类型桶;攻击类型定义里不含任何来源) + var grants: Dictionary = _db.settlement.charge_grants + var g_safe: Dictionary = grants.get("safe_cell", {}) + var g_flag: Dictionary = grants.get("flag_hit", {}) + check(String(g_safe.get("attack_type", "")) == "pierce" and int(g_safe.get("per_unit", 0)) == 1 and int(g_safe.get("cap", -1)) == 8, "充能奖励定义:开格 → 穿刺桶 1/格(单轮计数上限 8)") + check(String(g_flag.get("attack_type", "")) == "magic" and int(g_flag.get("per_unit", 0)) == 2 and int(g_flag.get("cap", -1)) == 0, "充能奖励定义:标中旗 → 魔法桶 2/雷(无计数上限)") + # ②″ 奖励可改(行为断言):把「标中旗」奖励从魔法桶改投穿刺桶 → 同一战斗魔法分量归零;还原后步骤流逐行相同 + # (证明改道唯一入口 = 奖励定义,攻击类型与甲效矩阵不参与;玩家可见语义见 战斗结算 GDD 战斗段) + var run_base = _run_flag_backlash_round(20260912) + var base_magic := 0 + for row in run_base.rows: + if String(row.get("source_class", "")) == "hero_attack": + base_magic += int(row.get("magic", 0)) + var save_grant: Dictionary = _db.settlement.charge_grants["flag_hit"] + _db.settlement.charge_grants["flag_hit"] = {"attack_type": "pierce", "per_unit": 2, "cap": 0} + var run_swap = _run_flag_backlash_round(20260912) + var swap_magic := 0 + for row in run_swap.rows: + if String(row.get("source_class", "")) == "hero_attack": + swap_magic += int(row.get("magic", 0)) + _db.settlement.charge_grants["flag_hit"] = save_grant + check(base_magic >= 1, "充能落桶基线:标中旗奖励进魔法桶(魔法分量合计 %d)" % base_magic) + check(swap_magic == 0, "改投穿刺桶后:主角攻击行魔法分量归零(×%d——改奖励即改道,攻击类型定义未动)" % swap_magic) + check(JSON.stringify(run_base.rows) == JSON.stringify(_run_flag_backlash_round(20260912).rows), "还原奖励定义后步骤流逐行相同(改道只经奖励定义,矩阵零改动)") + # ③ 标错惩罚 + 标中充能(奖励定义现投魔法桶;Boss 行 150HP 多轮样本;板真相直读保证 hit/miss 确定性) var run1 = _run_flag_backlash_round(20260912) var miss_rows := 0 var backlash_rows := 0 - var dmg_b_round := -1 - var dmg_b_seen := 0 + var magic_round := -1 + var magic_seen := 0 for row in run1.rows: if row.get("type", "") == "flag_miss": miss_rows += 1 if row.get("type", "") == "effect" and String(row.get("source_class", "")) == "flag_miss": backlash_rows += 1 # 反噬效果行(暴走/伏击/失衡三选一) - if row.get("source_class", "") == "hero_attack" and int(row.get("dmg_b", 0)) >= 1: - dmg_b_round = int(row.get("round_index", -1)) - dmg_b_seen = int(row.get("dmg_b", 0)) + if row.get("source_class", "") == "hero_attack" and int(row.get("magic", 0)) >= 1: + magic_round = int(row.get("round_index", -1)) + magic_seen = int(row.get("magic", 0)) check(miss_rows >= 1, "标错旗产生 flag_miss 行(×%d)" % miss_rows) check(backlash_rows >= 1, "标错旗触发随机反噬效果行(×%d——敌增伤/敌buff/我方debuff 三选一)" % backlash_rows) - check(dmg_b_round >= 1, "标中雷充能进主角攻击(dmg_b=%d @R%d——每雷实例一次)" % [dmg_b_seen, dmg_b_round]) + check(magic_round >= 1, "标中雷充能进主角攻击(magic=%d @R%d——每雷实例一次)" % [magic_seen, magic_round]) # ④ 同种子回放(确定性派生反噬——零新流同种子逐行相同) var run2 = _run_flag_backlash_round(20260912) check(JSON.stringify(run1.rows) == JSON.stringify(run2.rows), "标错惩罚轮回放断言:同种子步骤流逐行相同(反噬派生确定性)")