From 88a204635fc8b0641c980825a4ab562452489019 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 15 Sep 2026 21:10:27 +0800 Subject: [PATCH] =?UTF-8?q?refactor(slice):=20=E9=9B=BE=E6=A0=BC=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=E6=95=B4=E4=BD=93=E6=B8=85=E7=90=86=EF=BC=88=E4=BB=A3?= =?UTF-8?q?=E7=A0=81/=E6=95=B0=E6=8D=AE=E8=A1=A8/=E6=96=87=E6=A1=A3/regist?= =?UTF-8?q?ry=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 雾格已于 2026-09-14 从设计中永久移除(05-不做清单),本批把残留从实现到文档清干净。 代码与数据表: - 删:雾布置管线(区域生长/厚度约束/safe_nonzero 强制)、雾预算核算、雾指标输出 (actual_fog_ratio / fog_burden_ratio / delta_budget_fog)、求解器"雾元知识"信息通道、 硬编码 "fog" 变异、雾池加载护栏、雾格渲染/tint/雾区全开信号、雾图例条目、雾首遇提示、 雾教学断言;variation/board_gen/reward_config 三表雾字段与雾校验 - 删 inferability_core(雾移除后恒等于主指标,留着会制造双判据假象)及其 3 处消费方 - 留:变异框架面(variants/variant_ids/候选池门控/变异表加载通道与通用字段/ 出生区无变异不变式/事件载荷 variant_ids 空槽),MVP 下恒空;加行即生效承诺不变 - 验证:冒烟 196/196(+3 变异框架面断言)、三场景探针全 PASS、 期望扫描与清理前同种子逐位相同(L2 板去雾后可推理率 0.908→0.951) 文档与 registry: - 十份系统文档的雾失义登记与待拍板条目按删除概念 SOP 关闭并补版本历史;03/02 顶层同步 - design/ux/battle.md 与 interaction-patterns.md 去雾(格态收窄两态)+ 修订记录表 - registry:删 t_fog_min / fog_region_count / fog_target_ratio / terrain_variation_acceptance_mapping / pricing_constraints 等键;指标集八项→四项;hint_id 去 fog_first; variation_table 反向边收敛为三个真实引用方 - 连带:art-bible 雾资产占位、tests/README 示例测试名、doc-conventions 第 4 节正例、 研究件失效注记、切片 README 现状陈述与补记 --- design/art/art-bible.md | 5 +- design/gdd/02-系统清单.md | 9 +- design/gdd/03-内容规模.md | 13 +- design/gdd/systems/冒险循环/冒险结构.md | 3 +- design/gdd/systems/冒险循环/难度曲线与Boss.md | 4 +- design/gdd/systems/战斗循环/奖励道具经济.md | 4 +- design/gdd/systems/战斗循环/战斗结算.md | 2 +- design/gdd/systems/排雷循环/地形变异.md | 24 +-- design/gdd/systems/排雷循环/排雷玩法.md | 4 +- design/gdd/systems/排雷循环/棋盘生成.md | 15 +- design/gdd/systems/表现与支撑/HUD框架.md | 6 +- design/gdd/systems/表现与支撑/教学引导.md | 9 +- design/gdd/systems/表现与支撑/数据配置.md | 2 +- design/registry/entities.yaml | 92 ++++---- .../research/lore-nest-metaphor-2026-09-12.md | 1 + design/ux/battle.md | 51 +++-- design/ux/interaction-patterns.md | 14 +- docs/architecture/architecture.md | 14 +- .../architecture/requirements-traceability.md | 4 +- docs/doc-conventions.md | 3 +- .../dungeon-sweeper-vertical-slice/README.md | 12 +- .../core/battle_orchestrator.gd | 2 +- .../core/board_data.gd | 20 -- .../core/board_generator.gd | 200 ++---------------- .../core/config_db.gd | 14 +- .../core/minesweeper_rules.gd | 10 +- .../core/reward_economy.gd | 14 +- .../data/schemas/board_gen_table.gd | 7 - .../data/schemas/reward_config_table.gd | 3 - .../data/schemas/variation_table.gd | 4 +- .../data/tables/board_gen.tres | 16 +- .../data/tables/level.tres | 2 +- .../data/tables/reward_config.tres | 1 - .../data/tables/variation.tres | 15 +- .../presentation/debug_session.gd | 2 +- .../presentation/main.gd | 14 +- .../presentation/views/board_view.gd | 64 +----- .../presentation/views/board_zone_view.gd | 2 - .../presentation/views/legend_overlay.gd | 14 +- .../presentation/views/toast_stack.gd | 2 +- .../smoke/dump_battle.gd | 4 +- .../smoke/experiment_density.gd | 23 +- .../smoke/reward_expectation.gd | 2 +- .../smoke/smoke_all.gd | 26 ++- .../smoke/ui_click_probe.gd | 8 +- .../smoke/ui_probe.gd | 15 +- tests/README.md | 2 +- 47 files changed, 232 insertions(+), 545 deletions(-) diff --git a/design/art/art-bible.md b/design/art/art-bible.md index fec2195b..737dd973 100644 --- a/design/art/art-bible.md +++ b/design/art/art-bible.md @@ -1,6 +1,6 @@ # 美术圣经(Art Bible)— Dungeon Sweeper -> 项目:Dungeon Sweeper(扫雷 × 自动战斗 闯关 Roguelike)· 状态:**第 1–4 节定稿**(2026-09-10 初稿;2026-09-13 增补批定稿——徽章栈位/雷格隐喻换轴同步/格子样张验收成文/图标键契约冻结/雾格占位);第 5–9 节(角色/环境/UI/资产标准/参考方向)待后续补全 +> 项目:Dungeon Sweeper(扫雷 × 自动战斗 闯关 Roguelike)· 状态:**第 1–4 节定稿**(2026-09-10 初稿;2026-09-13 增补批定稿——徽章栈位/雷格隐喻换轴同步/格子样张验收成文/图标键契约冻结;2026-09-15 去雾——雾格已从设计中永久移除,样张清单与 §3.2 的雾格资产占位同批删除);第 5–9 节(角色/环境/UI/资产标准/参考方向)待后续补全 > > **Art Director Sign-Off (AD-ART-BIBLE)**:SKIPPED — Lean mode(2026-09-10;非 PHASE-GATE,第 5–9 节补全或重大改版时建议跑 full 门禁);2026-09-13 增补批 SKIPPED — Solo mode(review-mode.txt = solo,出稿待人工复核) > 风格基调(2026-09-10 用户定稿):地牢题材但**非暗黑风**——轻快明亮的幻想冒险风,全年龄;像素风;角色 2~3 头身 @@ -52,7 +52,7 @@ > 对应 game-concept"早期风险登记"第 1 条(扫雷数字可读性 × 暗色氛围的冲突 → 一次格子样张测试定风格)与视觉锚原则 5("具体形态由格子样张测试定稿")。**样张** = 一张按本圣经参数画成的格子风格试验图,是砖面形态的定稿闸——样张通过前,§3.2/§4.1 的一切参数只是候选,通过后冻结为制作标准。 -**样张内容清单**(一图齐备,缺项即无效):未开格(覆尘完整砖)、已开格(碎裂裸露,含 0 格与 1–8 全档数字)、雷格(被惊动的巢穴)、旗、小人两态(独立占格 + 与数字同格——后者须验"边框高亮不覆盖文本",game-concept 原则 3)、biome 色板变体组(§4.3 四槽换色,至少两套)。雾格不在样张范围(§3.2 雾格资产占位——内容封禁期)。 +**样张内容清单**(一图齐备,缺项即无效):未开格(覆尘完整砖)、已开格(碎裂裸露,含 0 格与 1–8 全档数字)、雷格(被惊动的巢穴)、旗、小人两态(独立占格 + 与数字同格——后者须验"边框高亮不覆盖文本",game-concept 原则 3)、biome 色板变体组(§4.3 四槽换色,至少两套)。 **验收项按序判定,第一项不过 = 整张否决(数字可读性定风格,风格服从可读)**: @@ -166,7 +166,6 @@ - **地砖**:一切环境体由同一圆角方形衍生:未开=完整凸砖,已开=同形缺角碎裂,雷=碎裂加巢穴纹(被惊动的巢穴——2026-09-12 换轴,旧称"机关纹"退役);只以"完整度"叙事,不为状态新造形。←原三;P4 - **墙体**:圆角砌块堆叠,禁尖刺装饰——尖刺专属危险语义,装饰不得伪装逻辑差异。←原三 - **变异格形状通道**(双通道之"形",与色无关):底砖圆角外轮廓不变,砖面内缘绘一圈定宽专属几何纹带(纹带形全作不与他类共用),砖心留白予数字与旗;验收标准=**灰度截图下仍可分类**。纹带对应哪些变异、种类清单,待《地形变异》定夺。←原一(纹理位次第 4,让位于数字/小人/旗);原三 -- **雾格资产规格**:内容封禁期暂缓,雾重设计批再启(占位一行,不展开设计)。 ### 3.3 UI 形状语法 diff --git a/design/gdd/02-系统清单.md b/design/gdd/02-系统清单.md index 7b6c819a..b8bd1bf5 100644 --- a/design/gdd/02-系统清单.md +++ b/design/gdd/02-系统清单.md @@ -22,7 +22,7 @@ | `棋盘生成.md` | 棋盘怎么生成、怎么保证可推理可通关 | 已定稿·自旧体系迁移 | | `排雷玩法.md` | 挖格、插旗、连锁展开等扫雷规则本体 | 已定稿·自旧体系迁移 | | `行动经济.md` | 每轮行动点怎么花、停手与刷新的代价 | 已定稿·自旧体系迁移 | -| `地形变异.md` | 格子的非雾变异(岩浆/冰冻等,待定);**雾格已从设计中移除** | 已定稿·自旧体系迁移 | +| `地形变异.md` | 格子的非雾变异(岩浆/冰冻等,待定) | 已定稿·自旧体系迁移 | | `辅助道具.md` | 扫雷侧辅助道具(显影、探测类) | 已定稿·自旧体系迁移 | ### 战斗循环(`systems/战斗循环/`) @@ -85,3 +85,10 @@ > 四个循环本身的英文代号为 `MINESWEEPER_CYCLE`(排雷循环)、`COMBAT_CYCLE`(战斗循环)、`ADVENTURE_CYCLE`(冒险循环)、`PRESENTATION_SUPPORT`(表现与支撑)。 > 旧版参考:`../archive/gdd-2026-09-14/systems-index.md` + +## 版本历史 + +| 版本 | 日期 | 改动 | +|---|---|---| +| v0.1 | 2026-09-15 | 根索引随新骨架建立:循环 × 子系统总表 + 子系统命名对照表 | +| v0.2 | 2026-09-15 | 雾格残留清理:`地形变异.md` 概要行去掉"雾格已从设计中移除"的迁移期注记(移除事实以[不做清单](05-不做清单.md)为单一出处)。文档树形状不变 | diff --git a/design/gdd/03-内容规模.md b/design/gdd/03-内容规模.md index 37684af7..e8bd3f7d 100644 --- a/design/gdd/03-内容规模.md +++ b/design/gdd/03-内容规模.md @@ -34,7 +34,7 @@ MVP 做到两关:第二层不新造结构,与第一层共用节点链模板 | 小板 | 10×10 | 25% | 第一关前两战 | | 大板 | 12×12 | 25% | 第一关后三战(含 Boss) | -不做密度爬坡——Boss 战的台阶靠换大板制造,可推理率目标全程恒 0.88。地形变异暂无内容:雾格已从设计中移除,岩浆/冰冻等只登记了名字。 +不做密度爬坡——Boss 战的台阶靠换大板制造,可推理率目标全程恒 0.88。地形变异暂无内容:岩浆/冰冻等只登记了名字,机制未定。 ## 战斗道具 @@ -52,7 +52,7 @@ MVP 就这么多:两个增益、两件小救急、两把刀、一个清图大 registry 登记 **六种**(数据表未建,属待落地内容):显影尘、工兵令、探宝罗盘、探巢摆钟、地穴全图卷、爆破工兵包——四个常规单功能加两个稀有组合。MVP 不新增第七种。 -待定一句:显影尘与地穴全图卷的现行效果定义绑定雾格,雾格移除后这两件的效果定位待重定;其余四件不依赖雾格,定义有效。 +待定一句:显影尘与地穴全图卷的原效果绑定已从设计中移除的地形变异类型(见[不做清单](05-不做清单.md)),两件的效果定位待重定;其余四件定义有效。 ## 增益与状态 @@ -75,7 +75,7 @@ MVP 不加新状态。 - 更多关卡(N>2)与关内分支路线——第二层先按线性模板跑通 - 精英节点与词缀系统——只预留了字段位,不定义语义 -- 地形变异内容——雾格已移除,其余变异只有名字 +- 地形变异内容——岩浆/冰冻等只登记了名字,机制未定 - 道具/增益之间的组合协同(遗物式联动) - 战后自动回复——回复只有道具与恢复点两个来源 - 元进度与跨局成长 @@ -83,3 +83,10 @@ MVP 不加新状态。 - 第七种辅助道具、第七种状态 > 旧版参考:../archive/gdd-2026-09-14/gdd.md + +## 版本历史 + +| 版本 | 日期 | 改动 | +|---|---|---| +| v0.1 | 2026-09-15 | 顶层六文档成文:关卡 / 敌人 / 棋盘 / 战斗道具 / 辅助道具 / 状态六项体量 | +| v0.2 | 2026-09-15 | 雾格残留清理:棋盘、辅助道具、暂不做三处去掉"雾格已移除 / 不依赖雾格"的迁移期注记,改指[不做清单](05-不做清单.md)。体量数字不变 | diff --git a/design/gdd/systems/冒险循环/冒险结构.md b/design/gdd/systems/冒险循环/冒险结构.md index fb772a8c..2fc09cdc 100644 --- a/design/gdd/systems/冒险循环/冒险结构.md +++ b/design/gdd/systems/冒险循环/冒险结构.md @@ -253,7 +253,7 @@ MVP 的序列是两关线性:第一关是地牢基线,第二关在基线上 | 条目 | 现状 | |---|---| -| 第二关"解锁新元素"的解锁语义 | 原表述绑定雾(雾格已从设计中移除,见[不做清单](../../05-不做清单.md)),第二关解锁什么待定;第二关的暂定层名也仍沿用已移除机制的用字,终稿随第二关内容批重定 | +| 第二关"解锁新元素"的解锁语义 | 原表述绑定已从设计中移除的机制(见[不做清单](../../05-不做清单.md)),第二关解锁什么待定;第二关的层名未定稿,随第二关内容批重定 | | 两关序列未生效 | 第二关深度轴行值填充批落地前,两关序列未生效,冒险以单关运行(合法态;扩展批已排 P1) | | 代币与钥石的关系 | 钥石 = 关底 Boss 掉落的跨局资源(见[游戏概念](../../00-游戏概念.md));本文的代币记账是关卡通关发的另一种记账。两者是否同一资源、如何汇入元进度,归[元进度](元进度.md)定稿 | | 大奖励数值随难度曲线联动 | 上限提升与恢复比例同通关率带、换算率锚的联动复验,随难度曲线与Boss的调参批执行 | @@ -263,3 +263,4 @@ MVP 的序列是两关线性:第一关是地牢基线,第二关在基线上 | 版本 | 日期 | 改动 | |---|---|---| | v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | +| v0.2 | 2026-09-15 | 雾格残留清理:第二关"解锁新元素"条目改引用「已从设计中移除的机制」(见不做清单),并明确第二关层名未定稿、随第二关内容批重定。关卡序列与节点模板不变 | diff --git a/design/gdd/systems/冒险循环/难度曲线与Boss.md b/design/gdd/systems/冒险循环/难度曲线与Boss.md index e0ba0797..40554a8f 100644 --- a/design/gdd/systems/冒险循环/难度曲线与Boss.md +++ b/design/gdd/systems/冒险循环/难度曲线与Boss.md @@ -267,9 +267,8 @@ Boss 战的棋盘用本关最大板形(第一关为 12×12),板参数仍 | 基线通关率越带,加难杠杆扫描未执行 | 现行扫描读数 60%,越 [30%, 50%] 上界。三类杠杆候选已登记:血量锚走廊 r_boss [1.1, 1.35](Boss 生命 180–207)、群战上探、注入衰减 0.5 → 0.6;扫描步未执行。落带前全部现行行值维持 provisional-pending-scan | 本文调参批,扫描执行与[棋盘生成](../排雷循环/棋盘生成.md)工具交付联动 | | 完美策略档的结构性加难杠杆 | 零加成的完美策略模拟通关率 100%、几乎满血通关——承伤带对这类高端玩家档位已无分辨力,数值杠杆族被实测证伪。结构候选(承伤硬地板、削弱饱和语义等)未裁决 | 本文提案,用户裁决 | | 真人通关率标定 | 试玩批次 1 实测真人显著强于模拟者(真人 100% vs 模拟 80%);带按模拟口径定义,真人修正系数待后续试玩批次定量 | playtest 批次 | -| 雾相关供给验算失义 | 原供给与对账验算含雾板分层、雾成本负担比等输入分量,随雾格自设计中移除(见[不做清单](../../05-不做清单.md))整体失义;重跑对账须以现行输入重建判据 | 本文调参批,与挖掘风险不等式、清图支配性重跑同批 | | 第二关深度轴行值未填充 | 第二关仅有 D0 锚行,D1–D4 敌人行与棋盘行待填;这是两关序列生效的前提,填齐前冒险按单关运行(合法态) | 本文,随第二关内容批 | -| 第二关的新内容投放缺口 | 曲线规则要求每关至少投放一项新内容;三敌种已全部在第一关登场,原表述中第二关的"解锁新元素"绑定已移除的雾格——第二关投放什么待定,现行口径填不上 | 本文提案,用户裁决 | +| 第二关的新内容投放缺口 | 曲线规则要求每关至少投放一项新内容;三敌种已全部在第一关登场,原表述中第二关的"解锁新元素"绑定已从设计中移除的机制(见[不做清单](../../05-不做清单.md))——第二关投放什么待定,现行口径填不上 | 本文提案,用户裁决 | | 区间平移换算率数值未定 | "生命上限 +10 ≈ 多撑约 1 轮、攻击翻倍 ≈ 击杀区间约减半"是量级估算(provisional);作为元进度接入口,数值待实测标定 | 随[元进度](元进度.md)定稿 | | 速杀退化预警阈值未定 | 高加成档速杀低难度行是成长兑现的合法形态、不做修复,但"战斗结束未开资格格占比"预警的阈值与联动调参未定(登记见[奖励道具经济](../战斗循环/奖励道具经济.md)「待拍板」) | 本文调参批 | @@ -279,3 +278,4 @@ Boss 战的棋盘用本关最大板形(第一关为 12×12),板参数仍 |---|---|---| | v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | | v0.2 | 2026-09-15 | 教学位掷骰自洽(用户拍板:代码不动、文档对齐):删除"教学位/首遇位固定不掷"豁免口径,教学位地精数量明确为开战掷骰区间 [1,2];D0 行数量列改 [1,2];Boss 血量锚 Σ=153.5 补逐数验算(区间期望口径下闭合) | +| v0.3 | 2026-09-15 | 雾格残留清理:关闭「待拍板」的雾相关供给验算失义条目(原供给与对账验算含雾板分层、雾成本负担比等输入分量);第二关新内容投放缺口条目改为引用「已从设计中移除的机制」(见不做清单)。曲线规则、供给带与对账义务不变 | diff --git a/design/gdd/systems/战斗循环/奖励道具经济.md b/design/gdd/systems/战斗循环/奖励道具经济.md index 47cf3dff..70bbc69a 100644 --- a/design/gdd/systems/战斗循环/奖励道具经济.md +++ b/design/gdd/systems/战斗循环/奖励道具经济.md @@ -243,8 +243,6 @@ j ≥ 1 → p = p₀ × d^(j−1)(现行 p₀ = 0.4、d = 0.5:0.4 | n_draft | int [1,999] | 32(provisional) | 保底重摇上限,超过即致命报错 | | p_min | int [1,999] | 8 | 保底开启时格子池伤害行的威力下界(即默认最低刀威力) | -注:奖励配置表现行登记还有一个档位过滤门限字段,其过滤对象随旧地形设计移除而失义,登记于待拍板,不列为现行可调项。 - 默认内容行(奖励表,值 provisional;五行的威力是区间,摇号时于下阶与上阶间一次摇定,区间中点即原定值——期望不漂移): | 奖励 | 类型 | 威力 | 池权重 | 档位 | 所在池 | @@ -284,7 +282,6 @@ j ≥ 1 → p = p₀ × d^(j−1)(现行 p₀ = 0.4、d = 0.5:0.4 | 条目 | 现状与失义原因 | 建议归属 | |---|---|---| | 奖励预读与推理的边界 | 预读允许到什么深度未定:[不做清单](../../05-不做清单.md)裁定未开格不显示奖励身份、允许恢复推理原料类道具;现役预读道具探宝罗盘(预读 3×3 窗口内未开格的奖励身份,归[辅助道具](../排雷循环/辅助道具.md))为窄域,更深的呈现(未开格身份常显等)与推理保护之间的界线待拍板 | [辅助道具](../排雷循环/辅助道具.md)定稿批与[HUD 框架](../表现与支撑/HUD框架.md) | -| 雾格相关定价约束三条失义 | 旧体系三条定价约束——雾内档位下界、清图奖励锚随雾成本上浮、雾板净当量优势带上界——随雾格于 2026-09-14 从设计中移除(见[不做清单](../../05-不做清单.md))整体失义;奖励配置表的档位过滤门限 t_fog_min(登记默认 2)过滤对象随之消失。清图锚是否需按图类型或难度上浮、优势带上界是否重建,均未定 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md) 调参批 | | 注入格未挖到不补发,实际获取期望低于名义首件保证 | 首件保证承诺的是"必注入"而非"必到手":注入格因清图或速杀未被挖到时不获得、战斗末不补发,实际获取期望低于名义值(切片实测约 0.88 件/战 vs 名义 1.0);拟通过修改退出战斗的触发方式优化(清图/战斗结束的时机与注入格的兜底交互),2026-09-15 拍板暂不做,登记待办 | [战斗结算](战斗结算.md)与[难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | | 速杀退化预警 | 战斗结束时未开资格格占比过高即警:供给过剩使战斗提早结束,奖励身份零发放,奖励系统饿死自己的高光时刻;阈值与联动调参未定 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | | 窗口摩擦预警 | 窗口跳过率、单次结算平均明细行数未设阈值;结构性缓解已内置(库存只收可选类、窗口单件制),保留观测 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | @@ -298,3 +295,4 @@ j ≥ 1 → p = p₀ × d^(j−1)(现行 p₀ = 0.4、d = 0.5:0.4 |---|---|---| | v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | | v0.2 | 2026-09-15 | 可选类注入递减基准对齐代码:逐图减半改为按实际获取件数递减(首件保证 = 未获取则每张新图必注入;p = p₀×d^(j−1));补明注入覆盖即时身份与"发放即获取、未挖到不计数"语义;验收标准首件保证改"必注入"口径;待拍板新增注入格未挖到不补发条目 | +| v0.3 | 2026-09-15 | 雾格残留清理:关闭「待拍板」的雾格相关定价约束三条失义条目(雾内档位下界、清图奖励锚随雾成本上浮、雾板净当量优势带上界)与随之取消的奖励配置表档位过滤门限 t_fog_min。奖励表字段、跨字段校验、默认根行集与窗口规则不变;清图奖励的图类型差异化插槽保留为结构位 | diff --git a/design/gdd/systems/战斗循环/战斗结算.md b/design/gdd/systems/战斗循环/战斗结算.md index 2fd52cfa..6f1934ce 100644 --- a/design/gdd/systems/战斗循环/战斗结算.md +++ b/design/gdd/systems/战斗循环/战斗结算.md @@ -282,7 +282,6 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 × |---|---|---| | 挖掘风险不等式对账破线 | 归档记录现行值链(防御增益时长 1、行值 −30、现行难度曲线)下两参考板形首版验算破线,多敌满配深度破线;破线已升格为曲线级约束,相关参数处禁独立调参联动网络;对账须在难度曲线调参批重跑 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md)提案,本系统闭合共裁 | | 清图支配性保守地板缺口 | "推到底清图不吃亏"的对账未闭合:非完美板形的清图期望收益低于"挖完确定格就弃图刷新";已裁"清图非严格支配"为设计态,保守地板当量缺口仍在案;对账须在难度曲线调参批重跑 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md),奖励量级联动[奖励道具经济](奖励道具经济.md) | -| 对账输入的雾相关分量失义 | 原对账输入含雾成本负担比、雾板分层等分量,随雾格移除(见[不做清单](../../05-不做清单.md))失义;重跑对账时需以现行输入重建判据 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | | 标错反噬的正式侧载体 | 标空旗的三选一确定性反噬已定案并上线(2026-09-12 批,机制见授予段一节):三池内容、一次性时效、确定性派生载体均为现行规则;留下的开口是载体实现——现行为坐标×板序号哈希派生、不消费随机数流,正式侧候选 = 改为随机服务新增一条封闭随机流(回放纪律不变,迁移与否未定) | 本系统,随机流结构联动[数据配置](../表现与支撑/数据配置.md) | | 连锁批量奖励的溢出处理 | 一条大连锁给出的奖励超出叠层上限时如何处理未定(现行按显式接受、零补偿执行) | [奖励道具经济](奖励道具经济.md)与本系统条目化 | @@ -293,3 +292,4 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 × | v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | | 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 | 雾格残留清理:关闭「待拍板」的对账输入雾相关分量失义条目(原对账输入含雾成本负担比与雾板分层等分量)。现行对账输入 = 实测可推理率分布低分位值等现行读数,条款③⑤对账协议与判定式不变 | diff --git a/design/gdd/systems/排雷循环/地形变异.md b/design/gdd/systems/排雷循环/地形变异.md index 91c524db..4a7061e4 100644 --- a/design/gdd/systems/排雷循环/地形变异.md +++ b/design/gdd/systems/排雷循环/地形变异.md @@ -1,6 +1,6 @@ # 地形变异 -> 一句话:格子的非雾变异(岩浆/冰冻等,待定);雾格已从设计中移除 +> 一句话:格子的非雾变异(岩浆/冰冻等,待定) > 状态:已定稿(自旧体系迁移) > 旧版参考:../../../archive/gdd-2026-09-14/a4-terrain-variation.md @@ -112,9 +112,9 @@ P0 阶段本系统不产出任何可玩内容:变异类型清单为空,没 ## 调参表 -本系统现行没有可调参数。归档文档曾为变异表登记过参数与行内容(如首类变异的解锁关号、地形主题标签),它们未随本定稿迁移;是否以新变异类型重定、如何重定,见「待拍板」。 +本系统现行没有可调参数,变异表是空清单。归档文档曾为变异表登记过参数与行内容(如首类变异的解锁关号、地形主题标签),它们未随本定稿迁移;是否以新变异类型重定、如何重定,随首批类型定稿批一并拍板。 -变异表的结构历史(字段定义、反制道具回填现状、条目归属)见 [registry 的 variation_table 条目](../../../registry/entities.yaml)。该条目目前仍把归档文档登记为事实源,本系统首批类型定稿后应改指本文并同步重定内容。 +变异表的结构历史(字段定义、条目归属)见 [registry 的 variation_table 条目](../../../registry/entities.yaml)。该条目现行字段定义沿用归档期口径且无反制道具回填值(空清单无引用行),本系统首批类型定稿后应随该批重定内容。 ## 验收标准 @@ -123,25 +123,9 @@ P0 阶段本系统不产出任何可玩内容:变异类型清单为空,没 - 数据生命周期:格子携带的变异是只读数据——随图生成、随图消亡,生效期零运行时写入,无跨图存续。 - 配套义务闭环:任何一类变异的定稿批,若不含至少一件反制道具的定稿条目,验收不通过。 -## 待拍板 - -以下条目出自上一版设计,内容绑定了已被移除的雾格,随移除失义。本文不为它们编造替代机制,只逐条登记失义原因与建议归属,待归属系统修订时处理。条目中的「可推理率」是棋盘生成的生成质量参数(一张雷图能靠逻辑推理而非猜测解出的程度)。 - -| 条目 | 失义原因 | 建议归属 | -|---|---|---| -| 雾区布置约束族(雾区只允许布置在非 0 安全格——区内无雷、无 0 格;出生区及其初始展开可达域永不含变异等生成期硬约束) | 约束谓词绑定雾格的格类构造;岩浆/冰冻的布置约束未定,不能默认沿用 | [棋盘生成](棋盘生成.md) | -| 承重数学(雾区厚度不大于 2——等价于任意 3×3 窗口非全雾;雾面积占比不大于 8 倍雷密度的必要上界;k 格雾区的外环必含至少 ⌈k/8⌉ 颗雷——⌈ ⌉ 为向上取整,"雾边 = 推理锚"的定量形式;占比与可推理率下限的联动参数) | 全部由"雾格 = 非 0 安全格"的结构推论导出,前提随雾移除失效 | [棋盘生成](棋盘生成.md) | -| 雾占比上限 0.25(生成参数域的占比校验,结构冻结值) | 校验对象是雾面积占比,对象已不存在 | [棋盘生成](棋盘生成.md) | -| 可推理率"剔除雾格"双向净效应建模(雾边线索减少的减项与雾边推理锚的增项两边都算,禁单向补偿) | 建模对象是雾格对可推理率的扰动;未来变异若扰动信息量,须重新建模 | [棋盘生成](棋盘生成.md) | -| 清图预算的雾增量核算(链不可达雾格数 × 挖格单价,计入清图总预算的设计期核算) | 增量分子是雾格的挖掘成本,雾移除后分子失义 | [棋盘生成](棋盘生成.md),联动[战斗结算](../战斗循环/战斗结算.md) | -| 雾板两态验算与两条方向性护栏(支配性不等式须雾板/无雾板分别验算;雾板净当量优势带上界、防刷新钓鱼护栏) | 验算与护栏都以"雾板"这一图类型为对象 | [战斗结算](../战斗循环/战斗结算.md) | -| 雾板三条定价硬约束(雾内奖励档位下界、清图奖励锚随雾成本上浮、雾板优势带上界) | 三条都以雾板为定价对象 | [奖励道具经济](../战斗循环/奖励道具经济.md) | -| 雾图例条目、首遇一次性提示、已开雾格底色残留(tint)与雾区全开完成信号等呈现义务 | 呈现对象全是雾格本身 | [HUD 框架](../表现与支撑/HUD框架.md) | -| 雾教学条目("雾区无雷"口径、雾内插旗警示、连锁止于雾界的解释等) | 教学对象是雾机制 | [教学引导](../表现与支撑/教学引导.md) | -| registry 变异表的反制道具回填值 [probe_dust](显影尘,玩家可见道具名;现行效果定义为雾区显影) | 显影尘是雾的反制道具,随雾失义待重定;名称暂按登记保留 | [辅助道具](辅助道具.md) | - ## 版本历史 | 版本 | 日期 | 改动 | |---|---|---| | v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | +| v0.2 | 2026-09-15 | 雾格残留清理:删除上一版设计遗留的「待拍板」失义条目十条(雾区布置约束族、承重数学、雾占比上限、剔除雾格的双向净效应建模、清图预算雾增量、雾板两态验算与护栏、雾板定价硬约束、雾呈现义务、雾教学条目、变异表反制道具回填值)与文首说明;调参表删除指向该节的指引。变异框架本体(清单加行即生效、零特判、随图只读生命周期、候选池门控、反制道具配套义务)不变 | diff --git a/design/gdd/systems/排雷循环/排雷玩法.md b/design/gdd/systems/排雷循环/排雷玩法.md index 2d2ac49c..ffa9f0e9 100644 --- a/design/gdd/systems/排雷循环/排雷玩法.md +++ b/design/gdd/systems/排雷循环/排雷玩法.md @@ -245,9 +245,6 @@ | 条目 | 现状与失义原因 | 建议归属 | |---|---|---| | 标错(控制失败)的惩罚 | 未定案:候选为"敌方伏击 +1";旧体系留有原型实测义务,至今未执行。落地前标空只判"不中",无额外后果 | 数值归[敌人系统](../战斗循环/敌人系统.md),兑付归[战斗结算](../战斗循环/战斗结算.md) | -| 连锁开雾格、雾内旗恒不中 | 雾格已整体从设计中移除([不做清单](../../05-不做清单.md)第一条),两条规则失去作用对象;连锁与旗判定的现行口径已按"全部安全格"改写进正文 | 无需恢复;地形变异若定稿再议 | -| 开格事件携带变异标记、板持生成期快照 | 原为雾变异设计的透传与抗热重载机制,随雾格移除失去承载对象;未来地形变异是否复用"随格只读标记"未定 | [地形变异](地形变异.md)定稿时裁决 | -| 四格态呈现中的两个雾态 | 旧呈现要求四种格态一眼可辨,其中两个是雾态,随雾格移除失义;剩余"已开 / 未开"两态的呈现要求归 HUD 框架 | [HUD 框架](../表现与支撑/HUD框架.md) | | 连锁批量奖励的溢出吸收 | 一条大连锁一次给出大量奖励资格,超出增益叠层上限时如何处理(折算、顺延或显式接受)未定 | [战斗结算](../战斗循环/战斗结算.md)与[奖励道具经济](../战斗循环/奖励道具经济.md)条目化 | ## 版本历史 @@ -255,3 +252,4 @@ | 版本 | 日期 | 改动 | |---|---|---| | v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | +| v0.2 | 2026-09-15 | 雾格残留清理:关闭「待拍板」三条雾失义登记(连锁开雾格与雾内旗恒不中、开格事件的变异标记透传、四格态中的两个雾态)——现行连锁与旗判定口径已按"全部安全格"写在正文,开格事件仍携带随格只读的变异标记(通用变异框架保留),格态呈现收窄为已开 / 未开两态。规则本体不变 | diff --git a/design/gdd/systems/排雷循环/棋盘生成.md b/design/gdd/systems/排雷循环/棋盘生成.md index 534ecf0a..8d558460 100644 --- a/design/gdd/systems/排雷循环/棋盘生成.md +++ b/design/gdd/systems/排雷循环/棋盘生成.md @@ -231,22 +231,11 @@ - 降级诚实:零合法板照常出图,必带非法产物标记与最高级告警;进程不死锁,玩家界面得到诚实告知。 - 加载期校验:布雷数下限、计数可行性、标签非空等违例组合加载期致命。 - 黄金图回归:手工核验小板集的可推理率输出与登记整数对逐位相等(整数对比对,禁浮点容差);换生成参数(推理定义、信息源、定义版本号)必须重制向量并入版本库。 -- 表实一致:配置表字段定义与 registry `board_gen_table` 条目一致;两条已失义字段的清理登记见「待拍板」。 - -## 待拍板 - -雾格机制已整体移除(见[不做清单](../../05-不做清单.md)),下列归档条目随之失去依附对象,本文一律不装载,去留与归属待拍板: - -| 条目 | 失义原因 | 建议归属 | -|---|---|---| -| 雾参数两字段(fog_region_count / fog_target_ratio)、雾占比绝对上限 0.25 与雾域跨字段校验 | 依附已移除的雾格机制;registry `board_gen_table` 条目(只读)仍载有这两字段 | registry 条目修订:owner 改指本文档时同步清理字段与校验 | -| 双判据与 inferability_core(剔除雾格后的可推理率) | 判据的分子分母都绑定雾格集,本体失义;现行规则已回归单一判据(可推理率 ≥ 及格线) | registry 条目的指标与批量断言口径同步修订 | -| 雾相关生成约束(雾区仅落非 0 安全格、3×3 窗口非全雾、初始展开不触雾) | 全部以雾格集为载体 | 随机制移除废弃;地形变异若定稿出类似结构约束,在其文档重立 | -| 雾致清图预算增量(Δbudget_fog 与 fog_burden_ratio 两指标) | 计算对象是连锁不可达的雾格 | 废弃;行动经济清图支配性对账若需同类量,以地形变异的新载体重立 | -| 黄金图向量中的 core 整数对 | 依附双判据的第二腿 | 向量协议下次重制时一并清理 | +- 表实一致:配置表字段定义与 registry `board_gen_table` 条目一致。 ## 版本历史 | 版本 | 日期 | 改动 | |---|---|---| | v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | +| v0.2 | 2026-09-15 | 雾格残留清理:删除「待拍板」五项旧版失义条目(雾参数两字段与雾域跨字段校验、双判据与 inferability_core、雾相关生成约束、雾致清图预算增量两指标、黄金图向量的 core 整数对);验收标准「表实一致」条去掉指向该节的清理登记。参数表、五阶段管线与三分支出图等现行规则不变 | diff --git a/design/gdd/systems/表现与支撑/HUD框架.md b/design/gdd/systems/表现与支撑/HUD框架.md index e69cd843..5f096e11 100644 --- a/design/gdd/systems/表现与支撑/HUD框架.md +++ b/design/gdd/systems/表现与支撑/HUD框架.md @@ -245,11 +245,6 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻 | 条目 | 失义原因 / 现状 | 建议归属 | |---|---|---| -| 雾图例条目 | 旧图例面板的"迷雾 = 无雷盲区"恒在条目,随雾格机制移除整体失义 | 未来非雾地形变异定稿时由[地形变异](../排雷循环/地形变异.md)提新条目,[教学引导](教学引导.md)承接内容 | -| 雾首遇一次性提示 | 旧三要点首遇提示随雾格移除失义;一次性提示的触发框架保留待新内容 | [地形变异](../排雷循环/地形变异.md)提出、[教学引导](教学引导.md)承接 | -| 四格态中的两个雾态 | 旧"四种格态一眼可辨"要求中两个是雾态,随雾格移除失义;现行已收窄为已开 / 未开两态 | 两态口径已落本文,失义部分无需恢复 | -| 雾纹带与已开雾格 tint 残留 | 雾纹理双通道资产规格与残留染色随雾格移除失义 | [地形变异](../排雷循环/地形变异.md)——未来非雾变异的纹带沿用形状通道重定 | -| 雾区全开合并域完成信号 | "整片雾区开完只报一次"的信号单元随雾格移除失义 | [地形变异](../排雷循环/地形变异.md)——若未来变异需要同类信号再议 | | 敌种线索键集差异 | 切片临时敌名与文档冻结键集(蛆虫 / 伏击兽)不一致,映射表以文档键集为锚 | [敌人系统](../战斗循环/敌人系统.md)修订批对齐 | | 未开格类型徽章呈现时机 | [art-bible](../../../art/art-bible.md) §4.6.3(提案已拍板待实施)要求未开格呈现家族类型徽章;[奖励道具经济](../战斗循环/奖励道具经济.md)现行锁定 MVP 只在已开格呈现——两口径未对齐 | [奖励道具经济](../战斗循环/奖励道具经济.md)极性提案实施批与本文共裁 | | 呈现只读面契约登记缺口 | 终局快照、战斗存活查询、库存计数、奖励身份查询等呈现面函数已随切片实现,现行[战斗结算](../战斗循环/战斗结算.md)文档未登记对应对外契约 | [战斗结算](../战斗循环/战斗结算.md)修订批补登记 | @@ -260,3 +255,4 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻 | 版本 | 日期 | 改动 | |---|---|---| | v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | +| v0.2 | 2026-09-15 | 雾格残留清理:关闭「待拍板」五条雾失义登记(雾图例条目、雾首遇一次性提示、四格态中的两个雾态、雾纹带与已开雾格 tint 残留、雾区全开合并域完成信号)。现行口径 = 格态两态一眼可辨(已开 / 未开)、图例面板只载现行格态与变异语义;通用变异框架的纹带形状通道保留为未来变异类型的呈现位 | diff --git a/design/gdd/systems/表现与支撑/教学引导.md b/design/gdd/systems/表现与支撑/教学引导.md index b964ded1..e59c7095 100644 --- a/design/gdd/systems/表现与支撑/教学引导.md +++ b/design/gdd/systems/表现与支撑/教学引导.md @@ -100,17 +100,11 @@ HUD 框架定稿时已为教学留好两个承载位,本系统的内容将来 - 玩家能在结算明细里指出至少一行收益来自他刚才的哪一步操作。 - 首次提示不重复轰炸:同一提示每场冒险至多出现一次。 -## 待拍板 - -| 条目 | 内容 | -|---|---| -| 雾格失义:雾类教学条目 | 原设计的图例条目"迷雾 = 无雷盲区"与雾格首遇三要点提示,随雾格机制移除整体失义,不迁入。未来非雾地形变异(岩浆 / 冰冻等)定稿时,需要补对应的图例条目与首遇提示——届时归[地形变异](../排雷循环/地形变异.md)提出、本系统承接 | - ## 待设计问题清单 1. 教学形态:线性开局教程,还是全部走情景触发式提示? 2. 因果教学顺序:先教扫雷操作,还是先教读结算明细?两者如何衔接? -3. 图例面板的条目全集与分组方式(雾条目删除后剩什么结构)。 +3. 图例面板的条目全集与分组方式。 4. 教学文案的定稿权归属,以及与本地化流程的分工。 5. 是否提供"再教一次"的入口(图例面板是否兼任手册)。 @@ -119,3 +113,4 @@ HUD 框架定稿时已为教学留好两个承载位,本系统的内容将来 | 版本 | 日期 | 改动 | |---|---|---| | v0.1 | 2026-09-14 | 自归档线索整合为范围草案(旧体系未单独成文) | +| v0.2 | 2026-09-15 | 雾格残留清理:删除「待拍板」的雾类教学条目失义登记(图例条目"迷雾 = 无雷盲区"与雾格首遇三要点提示),"待设计问题清单"第 3 条去掉雾条目删除的限定。教学条目清单与承载设施不变 | diff --git a/design/gdd/systems/表现与支撑/数据配置.md b/design/gdd/systems/表现与支撑/数据配置.md index 055e7542..b30ec6a2 100644 --- a/design/gdd/systems/表现与支撑/数据配置.md +++ b/design/gdd/systems/表现与支撑/数据配置.md @@ -211,7 +211,6 @@ | 条目 | 现状与失义原因 | 建议归属 | |---|---|---| -| 棋盘生成参数表的雾字段与雾校验清理 | 表内两个雾参数字段(fog_region_count / fog_target_ratio)、雾占比绝对上限与雾域跨字段校验,随雾格机制移除而失义;registry 的棋盘生成表条目(只读)仍载有这些字段与校验 | 随[棋盘生成](../排雷循环/棋盘生成.md)清理批删除字段与校验,registry 条目同步修订 | | 变异表旧字段集是否沿用 | 归档的字段集(信息规则、布置约束、反制道具绑定等)取值语义绑定具体变异类型;现行空清单下字段集沿用与否未定 | [地形变异](../排雷循环/地形变异.md)首批类型定稿批 | | 关卡表与冒险表未入表清单 | 两表已在 registry 登记由本文承载、[冒险结构](../冒险循环/冒险结构.md)回填,但尚未建结构占位、未纳入加载清单(归档表清单之外的新增表) | 表结构类与加载清单登记随冒险结构定稿批建账 | | 元进度表键结构未定 | 占位表只登记了归属,键结构待元进度定稿 | [元进度](../冒险循环/元进度.md) | @@ -221,3 +220,4 @@ | 版本 | 日期 | 改动 | |---|---|---| | v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | +| v0.2 | 2026-09-15 | 雾格残留清理:关闭「待拍板」的棋盘生成参数表雾字段清理登记(fog_region_count / fog_target_ratio 两字段、雾占比绝对上限与雾域跨字段校验)——字段与校验随雾格移除同批删除,registry `board_gen_table` 条目同步修订。表清单与校验纪律不变 | diff --git a/design/registry/entities.yaml b/design/registry/entities.yaml index c1cf4e84..b2ae2935 100644 --- a/design/registry/entities.yaml +++ b/design/registry/entities.yaml @@ -89,15 +89,12 @@ entities: attributes: table: VariationTable(数据配置 承载,键 = variant_id;地形变异 回填 owner,2026-09-08 定稿回填) fields: variant_id(String 主键唯一)/ display_name / unlock_level(int [1,999],knob)/ scope(enum region|global,global 预留 难度曲线与Boss)/ info_mask(enum none|hide_numbers)/ cell_constraint(enum any|safe_nonzero)/ biome_tag(StringList,∅=通配,knob)/ counter_item_ids(StringList,辅助道具 预留,非 knob——2026-09-08 re-review 修正 ✓ 误标) - mvp_content: 恰含 fog 一行(unlock_level=2【knob 活值,事实以表为准;调参须回写本条】 · info_mask=hide_numbers · cell_constraint=safe_nonzero · biome_tag=∅【knob 活值,同上】 · counter_item_ids=[probe_dust]【辅助道具 定稿回填登记——数据配置 表值与悬空校验激活随 数据配置/辅助道具 修订批同批落地;回填前为 ∅】);岩浆/冰冻无 MVP 行(垂直切片随关卡解锁建行,建行批随批配 ≥1 反制道具——aux_items 框架内容契约) - load_bearing_rule: 生成期布置约束——雾区只能布置在非 0 安全格(区内无雷、无 0 格,棋盘生成 生成期强制);"雾区无雷"为玩家可见知识(教学引导 教学义务);结构推论(2026-09-08 full 评审入文,同日 re-review 钉死度量):雾区厚度≤2【≡任意 3×3 窗口非全雾,非直线行程读法】、雾面积占比 f≤8d 必要上界——棋盘生成 参数域硬边界(棋盘生成 验收清单 15 项之⑫) + mvp_content: 空清单(合法态)——无任何机制已定稿的变异类型;岩浆/冰冻只登记名字、无 MVP 行(垂直切片随关卡解锁建行,建行批随批配 ≥1 反制道具——aux_items 框架内容契约) zero_special_casing: 连锁/数字计数/清图/旗/价目/结算零特判——既有系统行为不感知变异状态(排雷玩法 执行逻辑无变异分支;地形变异 Rule 3 的推论) rule4_exemption: 定义表非进度成长表,键 = variant_id,进度语义承载于 unlock_level 列(数据配置 Rule 4 豁免,schema 注释承载) cross_field_validation: info_mask=hide_numbers ⇒ cell_constraint=safe_nonzero——VariationTable schema validate() 跨字段类别,违规加载期致命(2026-09-08 re-review 增;防未来 hide_numbers+any 行静默击穿 EC4 连锁停止;地形变异 夹具 variation_mask_constraint 承载) - dangling_ref_policy: counter_item_ids 为 数据配置 首个引用型字段——**首引已由 辅助道具 定稿(probe_dust,2026-09-14 辅助道具 GDD)**:悬空校验激活 + 表值回填同批(数据配置 修订批;条件性夹具 aux_dangling_counter 登记 辅助道具 GDD AC-13——地形变异 测试口径"首个道具 id 回填时补校验"条款即 辅助道具-1 义务,闭环) - fog_ap_note: (2026-09-08 full 评审改两态;同日 re-review 改增量构成)雾不改 AP 价目但改清图预算构成,雾格 AP 成本两态——链可达雾格(邻非雾 0 格)免费链开、链不可达雾格全价 dig_ap_cost;雾致预算增量 = 链不可达雾格数 × dig_ap_cost,计入清图总预算需求参与 棋盘生成 BoardGenTable 设计期核算(原"≤ 轮数上限 × ap_per_round"不等式作废——"轮数上限"无定义;lean 版"全价结算"表述作废);行动经济 F1 条款 5 对账 = 三腿入账非消解:雷险腿消解(雾区无雷无 50/50)+ 信息腿双向净效应(雾边寂静减项 × 雾边推理锚增项,禁单向补偿)+ AP 腿(链不可达全价抬高清图成本)——战斗结算 条款 5 强制检查点输入,雾板/无雾板两态验算 + 两条方向性护栏(雾板净当量优势带上界·防福利 / 防钓鱼·对账 行动经济 OQ6) - pricing_constraints: 奖励道具经济 三条定价硬约束(2026-09-08 re-review 定稿三条)——① 雾内奖励档位下界 ≥ 最低档安全格 buff 当量(反淹没下界,per-AP 平价归 战斗结算/奖励道具经济 对账)② 清图奖励锚随雾成本负担上浮(链不可达同分母,防面积/成本分母脱钩)③ 雾板净当量优势带上界(防福利)——奖励道具经济 GDD 验收项 - referenced_by: [棋盘生成, 排雷玩法, 辅助道具, 战斗结算, 奖励道具经济, 难度曲线与Boss, HUD框架, 教学引导] + dangling_ref_policy: counter_item_ids 为 数据配置 的引用型字段——现行空清单下无引用行,取值悬空;首个真实引用随未来变异行建行批回填,届时激活悬空校验(数据配置 修订批;条件性夹具 aux_dangling_counter 登记 辅助道具 GDD AC-13) + referenced_by: [棋盘生成, 排雷玩法, 辅助道具] - name: variant_pool_gate type: formula @@ -105,9 +102,9 @@ entities: attributes: variables: [unlock_level, level_index, biome_tag, board_biome] rule: pool = {v ∈ VariationTable | unlock_level ≤ level_index ∧ (biome_tag=∅ ∨ biome_tag ∩ board_biome ≠ ∅)};直接整数比较(无 数据配置 R1 floor);∅ = 通配语义 - output_range: pool 集合(MVP ≤1);空池合法——棋盘生成 静默布置普通图,不报错 - board_biome_type: StringSet(值域与来源归 棋盘生成 BoardGenTable biome 字段;非空为 F1 输入前提——域校验登记 棋盘生成 验收⑮,fail-fast 闭合) - downstream: 棋盘生成 布置候选池门控(棋盘生成 验收清单 15 项之首——2026-09-08 full 评审由 11 项扩容,清单已登记 systems-index 门禁记录);多变异选取须消费 board_gen 流(回放确定性) + output_range: pool 集合(现行空集——无内容行;空池合法——棋盘生成 静默布置普通图,不报错) + board_biome_type: StringSet(值域与来源归 棋盘生成 BoardGenTable biome 字段;非空为 F1 输入前提——域校验登记 棋盘生成 验收标准,fail-fast 闭合) + downstream: 棋盘生成 布置候选池门控(棋盘生成 依赖与输出节);多变异选取须消费 board_gen 流(回放确定性) referenced_by: [棋盘生成] - name: status_effect @@ -149,16 +146,15 @@ entities: owner: design/gdd/systems/排雷循环/棋盘生成.md attributes: table: BoardGenTable(数据配置 承载,键 (level_index, node_depth) + depth-0 锚行——首个进度键表;棋盘生成 回填 owner,2026-09-09 定稿回填;第三轴登记约定〔B7 修订〕——Boss 图 = 各 level Dmax 行、elite_/boss_ 字段命名空间预留、关卡节点地图/难度曲线与Boss 定稿强制重审 OQ6,改键退路 = 数据配置 Rule 4 接口漂移通道) - fields: board_width/board_height(int [8,64],knob)/ mine_density(float (0,0.5],knob——雷量参数形态=密度浮点,尺寸解耦;布雷数下限 round(d×(W×H−9)) ≥ 1,R3 修订)/ inferability_target(float **[0.85,1]**,knob——P1 门槛承重参数+绝对锚,战斗结算 修订收窄)/ solver_rules(enum single|single_subset,**冻结 single_subset**——推理定义域非调参)/ min_safe_count(int [1,999],knob——行动经济 EC5 退化板对冲)/ max_gen_attempts(int [1,32],knob)/ fog_region_count(int [0,32],knob)/ fog_target_ratio(float [0,1),knob——**≤ min(8d, 0.25) 绝对上限,战斗结算 修订**)/ board_biome(StringSet **非空**,域校验致命——地形变异⑮;词表 owner 未定稿前只校验非空)+ elite_/boss_ 前缀字段命名空间预留(非 knob,B7——语义归 关卡节点地图/难度曲线与Boss) - cross_field_validation: fog_domain_ok(F2 规范形——count=0⇔ratio=0 或 0 命名空间预留、校验拒绝——棋盘生成 elite_ 同款) - tier: int [1, 8](knob)——地形变异 雾内档位下界约束载体 + 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 后闸仍托底零活刀行世界)· F2 雾档过滤(T_fog_min 默认 2 provisional;地形变异 约束①为验收锚非运行时校验——AC-19 档位序检查,战斗结算 对照表落定后升级)· **重复受理幂等(同格重复 grant / 同批次重复 grant_clear → 同一快照/身份 + 诊断;受理/兑付恰一次归 战斗结算×②③)** + 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;雾池 = {defense_up_basic, attack_up_basic, knife_adv, heal_pack}(AC-19 对账对 (knife_adv, attack_up_basic) 不变);战斗结算 条款⑤计价基元随换位重推(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%〕) + 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 库存清空可见反馈 - pricing_constraints: 地形变异 三条定价硬约束承接——① 雾内档位下界(AC-19 档位序检查夹具对账型,战斗结算 对照表落定后升当量对账)② 清图锚随雾成本上浮(**MVP 结构性不可闭合——clear_default 常量池无法随雾负担变化,非 deferral;激活载体 = clear_ 插槽,战斗结算 检查点仅对常量判 pass/fail**)③ 雾板净当量优势带上界(**MVP 静默绿灯风险——②缺位 + 仅 tier 下界加成下近乎必然平凡通过**;战斗结算 强制检查点 + 预警⑤雾板分层/⑥速杀退化观测对冲)〔②③状态 2026-09-09 评审显式宣告〕 high_glow_nodes: H1 开格拾取瞬间 / H2 清图奖励兑付 / H3 道具抢杀窗口(2026-09-09 评审诚实化:H1/H2 = 奖励侧常规节拍登记,H3 = 创意风险 #2 战斗侧执行兑现;**风险 #2 排雷侧"完美排雷爆发结算"机制本体归 战斗结算 强制检查点、#3 标中旗节拍补偿归 战斗结算——奖励道具经济 只交付插槽与明细行数据面**;呈现义务 HUD框架×④⑤) referenced_by: [战斗结算, HUD框架, 难度曲线与Boss, 辅助道具, 战斗表现, 教学引导] @@ -306,7 +300,6 @@ entities: attributes: table: RewardConfigTable(数据配置 承载,**单行全局**——2026-09-09 奖励道具经济 full 评审接口漂移新增:奖励道具经济 三个标量 knob 的 Rule 1 单一事实源载体,R3 override key 空间随之存在) fields: - t_fog_min: int [1, 8](默认 2)——F2 雾档过滤门限 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 扫描) @@ -355,11 +348,10 @@ entities: owner: design/gdd/systems/战斗循环/战斗结算.md attributes: rule: 行动经济 F1 条款⑤清图 vs 弃图支配性闭合(战斗结算 单一闭合 owner,战斗结算 GDD F5;**2026-09-10 评审批模型修订:挖穿残余池计价**——E[踩雷] = |M|×n_s/(n_s+1) 均匀交错模型、Δr = ⌈(n_s+E[踩雷])÷AP_r⌉;旧模型按每格独立赌 P(雷) 漏计全池挖掘量、系统性偏乐观)——主判式 Δ_clear = [R_res + C_eff] − [X_res + Δr × s_ref] ≥ 0;E_dig = 默认根加权 7.2 HP(刀 40%/治疗 25%/defense_up 35%);C_eff = C ×(perfect ? P_perfect÷100 : 1)(×2 = 真实双份交付);s_ref = D_ref;**停手侧 RAP 机会收益按零计价(显式假设登记——零价假设下 verdict 已为负,为 RAP 计价只会更负)**;域守卫 n_s < 1 ⇒ 主判式不评估、信息端平凡腿接管 - first_pass: **条款⑤未闭合(2026-09-10 模型修订重推——旧"两态通过"读数作废)**:L1 −5.3 / L2 −10.1(完美双份 +2.7/−2.1);满配语境 unit_count=3 深度为负(−49.6/−97.5,与 clause3_supply 破线同向联动);实现率折减口径(E_dig×0.6)更差(−18.5/−39.5);保守地板需求 L1 ≥ 46.1 / L2 ≥ 91.8(vs C=8/完美 16——缺口 −38.1/−75.8)。**难度曲线与Boss/奖励道具经济 约束包**:① C 量级上调整向(护栏 B 口径联动复核)② 或裁"清图非严格支配"为设计态(与 地形变异 定价硬约束②同向;如裁设计态须同步声明 行动经济 条款⑤ P1 对冲弱化 + 奖励道具经济 预警⑤加权监控)——①②二选一归 难度曲线与Boss 裁;③ 多敌放行判据 = 条款③⑤在全部登记行组合下同时成立。判据函数角色 = 调参约束生成器(AC-40 断言输出与约束包一致) - c3_ruling: **约束包②采信(非支配设计态)+ 计价基元换位重推(2026-09-14 难度曲线与Boss 修订批)**——clear_default 槽由 clear_knife(入库刀 C=8/完美 16)换位为 clear_blast(instant_aoe 当场兑付全体存活敌,C = power = 40):保守地板需求缺口重推 = 46.1−40 = 6.1(L1)/ 91.8−40 = 51.8(L2);C 量级不上调 ✓;P1 对冲弱化同步声明(② 条件)+ 弃图率加权监控随 OQ4 持续;本条 first_pass 旧读数(C=8/16 口径)留作模型演进记录;**区间批义务(2026-09-14)**:C 语义改区间 [25,55](期望中点 40 不变——期望口径缺口 6.1/51.8 维持);保守地板口径(min=25)缺口重推 = 21.1/66.8——战斗结算 修订批对齐条款⑤措辞(义务登记,未兑现前 战斗结算 文本 C=40 按期望中点读)。**重算回执(2026-09-14 战斗结算 重算批——v3 曲线 d0.25/t0.88 × E_dig=4.5 重推,参考板形换锚 难度曲线与Boss MVP 行值总表)**:主判式 L1 −28.7/+11.3(完美翻正)、L2 −67.4/−27.4、满配 −153.2/−113.2 与 −257.1/−217.1;保守地板需求 L1 ≥ 110.3 / L2 ≥ 166.8(缺口 70.3/126.8,对 clear_blast);上段 46.1/91.8 需求系 v1 曲线旧值链产物退役;**难度曲线与Boss 裁决②非支配设计态维持**(qualitative 结构不变——非完美态负、完美态 L1 翻正、L2 全负);护栏 A 方向性复核 ≈−1.1 越下界(E_dig 修正 + 雾池构成变更)/ 护栏 B C=40 越线——W2 复核三选一裁决随 难度曲线与Boss 收口批;actuals 交付后按 clear_blast 语义强制重跑(战斗结算 AC-40 同批口径) - guardrails: 护栏 A 雾板净当量优势带(每链不可达雾格 +2.4 ∈ (0, 3]——地形变异 pricing_constraints③ 判据;与残余池模型无关读数不变;突破条件 E_fog > 11.7 → 难度曲线与Boss 雾池联动禁区)· 护栏 B 防钓鱼(**2026-09-10 输入登记更正 + 双读数**:|S|_min = 棋盘生成 行级 knob 禁写死;|R₀|_max 无登记供给方——登记 棋盘生成 产出义务〔R₀ 规模分布上界,报告 C 扩列〕;s_ref=D_ref=12 比真实敌方 DPS 期望松 2.5–3×→ D_ref 口径上界 24〔C_eff=16 ✓〕/ DPS 严格读数 ≈8〔C_eff=16 越〕——两读数裁决归 难度曲线与Boss,与约束包①联动;结构承载 = 棋盘生成 min_safe_count + 布雷数下限 + 排雷玩法 R₀≠S 三闸的对账复核,非运行期校验) - a4_three_legs: 条款⑤三腿入账核对(雷险消解〔雾区无雷〕+ 信息双向净效应 + AP 腿〔链不可达全价 Δr 增量〕)——variation_table.fog_ap_note 消费面 - rerun_obligation: actuals p10 / fog_burden_ratio p50·p90 交付后强制重跑(战斗结算 AC-40);难度曲线与Boss 每次调参重跑(D_ref/P_pf/C 联动) + first_pass: **条款⑤未闭合(2026-09-10 模型修订重推——旧"两态通过"读数作废)**:L1 −5.3 / L2 −10.1(完美双份 +2.7/−2.1);满配语境 unit_count=3 深度为负(−49.6/−97.5,与 clause3_supply 破线同向联动);实现率折减口径(E_dig×0.6)更差(−18.5/−39.5);保守地板需求 L1 ≥ 46.1 / L2 ≥ 91.8(vs C=8/完美 16——缺口 −38.1/−75.8)。**难度曲线与Boss/奖励道具经济 约束包**:① C 量级上调整向(护栏 B 口径联动复核)② 或裁"清图非严格支配"为设计态(如裁设计态须同步声明 行动经济 条款⑤ P1 对冲弱化 + 奖励道具经济 预警加权监控)——①②二选一归 难度曲线与Boss 裁;③ 多敌放行判据 = 条款③⑤在全部登记行组合下同时成立。判据函数角色 = 调参约束生成器(AC-40 断言输出与约束包一致) + c3_ruling: **约束包②采信(非支配设计态)+ 计价基元换位重推(2026-09-14 难度曲线与Boss 修订批)**——clear_default 槽由 clear_knife(入库刀 C=8/完美 16)换位为 clear_blast(instant_aoe 当场兑付全体存活敌,C = power = 40):保守地板需求缺口重推 = 46.1−40 = 6.1(L1)/ 91.8−40 = 51.8(L2);C 量级不上调 ✓;P1 对冲弱化同步声明(② 条件)+ 弃图率加权监控随 OQ4 持续;本条 first_pass 旧读数(C=8/16 口径)留作模型演进记录;**区间批义务(2026-09-14)**:C 语义改区间 [25,55](期望中点 40 不变——期望口径缺口 6.1/51.8 维持);保守地板口径(min=25)缺口重推 = 21.1/66.8——战斗结算 修订批对齐条款⑤措辞(义务登记,未兑现前 战斗结算 文本 C=40 按期望中点读)。**重算回执(2026-09-14 战斗结算 重算批——v3 曲线 d0.25/t0.88 × E_dig=4.5 重推,参考板形换锚 难度曲线与Boss MVP 行值总表)**:主判式 L1 −28.7/+11.3(完美翻正)、L2 −67.4/−27.4、满配 −153.2/−113.2 与 −257.1/−217.1;保守地板需求 L1 ≥ 110.3 / L2 ≥ 166.8(缺口 70.3/126.8,对 clear_blast);上段 46.1/91.8 需求系 v1 曲线旧值链产物退役;**难度曲线与Boss 裁决②非支配设计态维持**(qualitative 结构不变——非完美态负、完美态 L1 翻正、L2 全负);护栏 A 方向性复核 ≈−1.1 越下界(E_dig 修正)/ 护栏 B C=40 越线——W2 复核三选一裁决随 难度曲线与Boss 收口批;actuals 交付后按 clear_blast 语义强制重跑(战斗结算 AC-40 同批口径) + guardrails: 护栏 B 防钓鱼(**2026-09-10 输入登记更正 + 双读数**:|S|_min = 棋盘生成 行级 knob 禁写死;|R₀|_max 无登记供给方——登记 棋盘生成 产出义务〔R₀ 规模分布上界,报告 C 扩列〕;s_ref=D_ref=12 比真实敌方 DPS 期望松 2.5–3×→ D_ref 口径上界 24〔C_eff=16 ✓〕/ DPS 严格读数 ≈8〔C_eff=16 越〕——两读数裁决归 难度曲线与Boss,与约束包①联动;结构承载 = 棋盘生成 min_safe_count + 布雷数下限 + 排雷玩法 R₀≠S 三闸的对账复核,非运行期校验) + rerun_obligation: actuals p10 交付后强制重跑(战斗结算 AC-40);难度曲线与Boss 每次调参重跑(D_ref/P_pf/C 联动) referenced_by: [难度曲线与Boss, 奖励道具经济, 棋盘生成] # 占位表中的原型参考值(伏击 +3、清图 +10、敌 18HP/4ATK 等)为 provisional, @@ -438,7 +430,7 @@ entities: write_paths: settle_batch(stop 亦经此,禁直调 行动经济)/ submit_window_selection(窗口条目位置序,非库存句柄) / 刷新意图 → 战斗结算 refresh_board 编排 / runner 推进——**全部唯一发生在组合根** subscription_discipline: 呈现层永不直接订阅 排雷玩法/行动经济——只订 战斗结算 步骤流/快照与 runner 信号(ADR-0001 固化);接线全部在组合根 imperative_refresh_faces: 零事件外发动作的刷新 = 命令式回执驱动(白话:动作调用返回后组合根立刻重查一次只读面刷新界面,不等通知信号)——旗插拔/移动成功(排雷玩法)/ AP·RAP 读数(行动经济 无推送)/ 状态效果(增益状态 零信号,绑 战斗结算 结算完成时点)/ 库存(奖励道具经济 查询面)五面成文 - payload_schema_index: HUD框架 GDD Core Rule 17 表 13 项——排雷玩法 三事件/战斗结算 流水行协议/奖励道具经济 窗口载荷等均为引用既有 schema;HUD框架 自有成文 = ux 遥测六行(ux_round_input_ratio/ux_round_exit/ux_refresh_attempt/ux_window_choice/ux_reject/ux_hint_shown)+ hint_id 封闭枚举 {fog_first, chord, no_adjacent} + payload_schema_index: HUD框架 GDD Core Rule 17 表 13 项——排雷玩法 三事件/战斗结算 流水行协议/奖励道具经济 窗口载荷等均为引用既有 schema;HUD框架 自有成文 = ux 遥测六行(ux_round_input_ratio/ux_round_exit/ux_refresh_attempt/ux_window_choice/ux_reject/ux_hint_shown)+ hint_id 封闭枚举 {chord, no_adjacent} lifetime_visibility_rule: 销毁前捕获(终局/死亡数据 despawn 前已入流水与快照)/ 载荷自包含(行协议自带来源/值/目标,禁按行序反推)/ 禁回读核心生命周期态(唯一观测口 = is_battle_live() 与 phase 投影)——切片缺陷②教训转正 naming_unification: 正式名 request_refresh(行动经济)/ refresh_cap_per_round(结构位默认 2)——切片 provisional 名 request_refresh_active/can_request_refresh/refresh_max_per_round/during_round 退役(AC grep 断言零残留) drift_registrations: ① 行动经济 只读观测量缺轮内已用刷新次数(刷新按钮"本轮剩 N 次"读数缺口——行动经济 修订批补)② 切片 settlement_snapshot 信号 战斗结算 GDD 未登记契约(HUD框架 现行消费 = 步骤流判定行 + presentation_snapshot(),独立信号须回 战斗结算 补登记)③ 极性提案实施批 HUD框架 义务条目(未开格类型图标/极性视觉语言/负向文案族——随批入 systems-index HUD框架 台账) @@ -453,19 +445,19 @@ entities: item_id: String 主键唯一——奖励道具经济 RewardTable.effect_id(aux 行)与 VariationTable.counter_item_ids 的引用键 display_name: String 非空(HUD框架 呈现数据源,本地化归 设置与本地化——敌人系统/增益状态/奖励道具经济 同库惯例) dimension_tags: StringList ⊆ {info, risk, action, plan, counter} 非空——维度覆盖断言载体(F2:五维度各 ≥1 活行 = "每维度都有对应道具"的机器可查形态) - effect_kinds: StringList ⊆ {fog_reveal, mine_reveal, reward_preview, ap_grant} 非空、无重复(MVP ≤2——稀有多维组合行的 schema 承载) - target: enum {none, fog_region, area_3x3, board_wide}——校验 = target ∈ 各空间 kind 支持域交集(全非空间 ⇒ 恒 none) + effect_kinds: StringList ⊆ {mine_reveal, reward_preview, ap_grant} 非空、无重复(MVP ≤2——稀有多维组合行的 schema 承载;显影尘与地穴全图卷的原显影半边随雾格移除失义,效果待重定——辅助道具 待拍板,名称保留) + target: enum {none, area_3x3, board_wide}——校验 = target ∈ 各空间 kind 支持域交集(全非空间 ⇒ 恒 none);原 fog_region 域随显影效果待重定一并重立 magnitude: int [0,999](knob)——仅 ap_grant 行消费(= AP 点数,加载校验 ≥1);空间行不消费非校验项 use_phase: enum {active_dig}——MVP 单值(扩枚举走 辅助道具 GDD 修订;奖励道具经济 use_timing 扩值 during_dig 同批对齐——奖励道具经济×③) - mvp_content: 六行(值 provisional 归 难度曲线与Boss)——probe_dust 显影尘〔info+counter / fog_reveal / fog_region / w5 t2〕· sapper_order 工兵令〔action / ap_grant / none / mag 2 / w5 t2〕· loot_compass 探宝罗盘〔plan / reward_preview / area_3x3 / w4 t2〕· nest_pendulum 探巢摆钟〔risk / mine_reveal / area_3x3 / w4 t2〕· catacomb_scroll 地穴全图卷〔info+plan / fog_reveal+reward_preview / board_wide / w1 t3〕· blast_kit 爆破工兵包〔action+risk / ap_grant+mine_reveal / area_3x3 / mag 4 / w1 t3〕——四常规单维(t2)+ 两稀有多维高数值(t3;稀有读数 ≈0.17 件/板,F1) - load_bearing_rules: 真视窄域护栏(承重)——mine_reveal 支持域 ≤area_3x3、board_wide 仅 fog_reveal/reward_preview(恢复推理可全图、替代推理必窄域——P1 防塌方;schema 校验强制,夹具 aux_target_violation)· 效果时效随 kind 派生无独立字段(空间 kind 恒本图持续、ap_grant 恒当轮一次性)· 零随机(零 RNG 流消费——信息全部来自 排雷玩法 恒真数字/奖励道具经济 Ready 映射/行动经济 账本三既有事实源)· 零特判延伸(排雷玩法 代码零 辅助道具 分支)· 无效/零信息目标不可用不消耗(可用性门——2026-09-14 用户拍板:板级判据 → 图标灰/入口禁用〔奖励道具经济 usable_now 先例〕、点击级 → 拒绝零消耗、组合行判据取 OR——爆破包 ap_grant 恒可用、真视零雷恒有效;与 奖励道具经济 E10 照常消耗区分——挖掘期非结算管线、守卫 辅助道具 本地可判)· area_3x3 边缘窗口 resolved_target = 窗口 ∩ 板内格(2026-09-14 用户拍板——护栏只缩不扩)· 使用零 AP 成本(不经 try_spend)· 库存关卡域(与 奖励道具经济 库存正交两容器、生命周期同构)· Used 不可逆 - overlay_semantics: 板级叠加层三集(辅助道具 自持派生信息层、零回写 排雷玩法/奖励道具经济 状态、随图消亡)——digit_reveal 显影集(HUD框架 显示雾格数字,本体 = 排雷玩法 恒真数字)/ mine_reveal 真视集(真视≠自动兑付——插旗仍花 1 AP 走既有 flag_hit 路径)/ reward_preview 预读集(徽章数据源 = 战斗结算 query_reward_identity 既有读面——辅助道具 零 奖励道具经济 数据复制) + mvp_content: 六行(值 provisional 归 难度曲线与Boss;显影尘与地穴全图卷的原显影半边随雾格移除失义、效果与目标待重定——辅助道具 待拍板,名称保留)——probe_dust 显影尘〔info+counter / 效果待重定 / w5 t2〕· sapper_order 工兵令〔action / ap_grant / none / mag 2 / w5 t2〕· loot_compass 探宝罗盘〔plan / reward_preview / area_3x3 / w4 t2〕· nest_pendulum 探巢摆钟〔risk / mine_reveal / area_3x3 / w4 t2〕· catacomb_scroll 地穴全图卷〔info+plan / reward_preview + 显影半边待重定 / board_wide / w1 t3〕· blast_kit 爆破工兵包〔action+risk / ap_grant+mine_reveal / area_3x3 / mag 4 / w1 t3〕——四常规单维(t2)+ 两稀有多维高数值(t3;稀有读数 ≈0.17 件/板,F1) + load_bearing_rules: 真视窄域护栏(承重)——mine_reveal 支持域 ≤area_3x3、board_wide 仅恢复推理原料类效果(显影/预读,显影载体待重定;恢复推理可全图、替代推理必窄域——P1 防塌方;schema 校验强制,夹具 aux_target_violation)· 效果时效随 kind 派生无独立字段(空间 kind 恒本图持续、ap_grant 恒当轮一次性)· 零随机(零 RNG 流消费——信息全部来自 排雷玩法 恒真数字/奖励道具经济 Ready 映射/行动经济 账本三既有事实源)· 零特判延伸(排雷玩法 代码零 辅助道具 分支)· 无效/零信息目标不可用不消耗(可用性门——2026-09-14 用户拍板:板级判据 → 图标灰/入口禁用〔奖励道具经济 usable_now 先例〕、点击级 → 拒绝零消耗、组合行判据取 OR——爆破包 ap_grant 恒可用、真视零雷恒有效;与 奖励道具经济 E10 照常消耗区分——挖掘期非结算管线、守卫 辅助道具 本地可判)· area_3x3 边缘窗口 resolved_target = 窗口 ∩ 板内格(2026-09-14 用户拍板——护栏只缩不扩)· 使用零 AP 成本(不经 try_spend)· 库存关卡域(与 奖励道具经济 库存正交两容器、生命周期同构)· Used 不可逆 + overlay_semantics: 板级叠加层三集(辅助道具 自持派生信息层、零回写 排雷玩法/奖励道具经济 状态、随图消亡;现行有效的 = 真视集与预读集,显影集载体待重定)——digit_reveal 显影集(HUD框架 显示被隐藏的数字,本体 = 排雷玩法 恒真数字;载体待重定)/ mine_reveal 真视集(真视≠自动兑付——插旗仍花 1 AP 走既有 flag_hit 路径)/ reward_preview 预读集(徽章数据源 = 战斗结算 query_reward_identity 既有读面——辅助道具 零 奖励道具经济 数据复制) api: 封闭枚举 8 入口(provisional,实现期 ADR 定名)——add_item(item_id, source) / query_inventory(枚举序 = 受理序,Used 保留只读,逐件含 usable 板级零信息可用性预判)/ validate_use(handle, target?) → 效果投影(只读不消耗;目标校验谓词 = 越板/点击级零信息拒绝 + 边缘窗口裁剪 resolved_target = 窗口 ∩ 板内格)/ apply_overlay(kind, target, mag)(战斗结算 逐 kind 调用)/ consume(handle)(Used 不可逆 + 快照回执)/ query_overlays(三集只读投影)/ retire_overlays(战斗结算 编排——与 奖励道具经济 retire_mapping 同点)/ clear_inventory(关卡末幂等);负空间 = 无自动使用入口/无重掷/无事件订阅/无 RNG 直连/无 排雷玩法/奖励道具经济 写入口 use_orchestration: 战斗结算 use_aux 规范序(唯一调用权)= 相位 gate(Active——行动经济 phase getter)→ validate_use(目标校验读 排雷玩法 只读面——使用目标校验谓词表见 辅助道具 GDD)→ 逐 kind 应用(顺序钉死:空间先、ap_grant 后——effect_kinds 列表序非运行时语义)→ consume——序即原子(validate 拦下全部可失败输入;apply/grant 域内无失败路径 → consume 恒达) formulas: F1 aux 渗透供给(E[N_aux/板] = |U|×Σw_aux/W_total,默认根 ≈1.7 件/板、稀有 ≈0.17;|U| 分布缺口待 棋盘生成 actuals——奖励道具经济 预检 11 同批重跑)· F2 维度覆盖谓词 coverage(d) · F3 信息价值方向预检(显影 ι↑ → 残余盲猜端 n_s = (1−ι)|S| 收缩 → 盲赌暴露下降 → 期望踩雷↓——P(雷) = |M|/(|M|+n_s) 对 ι 递增,单赌命中率上行属正常,收益在"少赌"非"单赌更安全";与 战斗结算 F4 同式 + n_s<1 适用域守卫;2026-09-14 评审修正原"P(雷)↓"方向误写;定量当量归 战斗结算 条款①对照表扩列——战斗结算×④注记,MVP 不入对照表) - obligations: 21 项跨 GDD 义务清单(辅助道具 GDD Dependencies 全文,对侧修订批逐项核对、缺项即 blocking)——战斗结算×①②③(use_aux 编排/生命周期/授予路由,缺项即 blocking)+ 战斗结算×④(对照表扩列注记)· 奖励道具经济×①…⑤(category 扩值 aux_item/effect_id 双表校验+夹具 reward_dangling_aux/use_timing 扩 during_dig/默认根六行+池总权重算/OQ2 收口注记)· 行动经济×①(grant_ap 第 9 API 接口漂移预授权——Active 受理、无上限域、零随机)· 地形变异×①②③(fog.counter_item_ids=[probe_dust] 回填/悬空校验激活+夹具 aux_dangling_counter/未来变异随批配 ≥1 反制)· HUD框架×①…④(库存条/使用交互/叠加层三集呈现/清空反馈)· 数据配置×①②(AuxItemTable 登记/两处表值回填+校验激活)· 教学引导×①(教学候选,非 blocking)· art-bible×①(§4.6 键扩容:item_id 六键+叠加层标记三族) + obligations: 21 项跨 GDD 义务清单(辅助道具 GDD Dependencies 全文,对侧修订批逐项核对、缺项即 blocking)——战斗结算×①②③(use_aux 编排/生命周期/授予路由,缺项即 blocking)+ 战斗结算×④(对照表扩列注记)· 奖励道具经济×①…⑤(category 扩值 aux_item/effect_id 双表校验+夹具 reward_dangling_aux/use_timing 扩 during_dig/默认根六行+池总权重算/OQ2 收口注记)· 行动经济×①(grant_ap 第 9 API 接口漂移预授权——Active 受理、无上限域、零随机)· 地形变异×①②③(counter_item_ids 首引回填随未来变异行建行批/悬空校验激活+夹具 aux_dangling_counter/未来变异随批配 ≥1 反制——原雾行绑定随移除悬空,显影尘效果待重定)· HUD框架×①…④(库存条/使用交互/叠加层三集呈现/清空反馈)· 数据配置×①②(AuxItemTable 登记/两处表值回填+校验激活)· 教学引导×①(教学候选,非 blocking)· art-bible×①(§4.6 键扩容:item_id 六键+叠加层标记三族) ux_flag: 有 UI 贡献(库存条/使用交互/叠加层呈现)——Phase 4 前置 /ux-design;asset-spec 候选(art-bible 样张批后) - closures: 地形变异 EC6 显影语义定稿(=fog_reveal,恢复推理原料非排雷;时效 = 本图持续)· 地形变异 OQ2 收口(时效/定价/首引回填/悬空校验)· 奖励道具经济 OQ2 辅助道具 侧收口(呈现深度 = 道具驱动预读;未预读格不呈现、自动寻路不做——终态与否 OQ6)· 创意风险 #1 道具侧兑现(plan 维度预读——结构闭环最后一块,呈现归 HUD框架) + closures: 奖励道具经济 OQ2 辅助道具 侧收口(呈现深度 = 道具驱动预读;未预读格不呈现、自动寻路不做——终态与否 OQ6)· 创意风险 #1 道具侧兑现(plan 维度预读——结构闭环最后一块,呈现归 HUD框架)· 显影语义(原为雾格显影 = fog_reveal)随雾格移除失义、载体待重定(辅助道具 待拍板) warnings: 预警①…④ playtest 预注册归 难度曲线与Boss(道具依赖度/预读覆盖率/AP 转存联动/稀有感知) referenced_by: [战斗结算, 奖励道具经济, 地形变异, 行动经济, HUD框架, 数据配置, 教学引导, art-bible] @@ -507,12 +499,12 @@ entities: table: LevelTable(数据配置 承载,键 = level_index 行、行内 nodes 节点链数组——切片建表,冒险结构 定稿转正为行集内容 owner) fields: level_index: int 行主键(冒险序列序号,从 1 连续递增——线性序列无跳关) - display_name: String(玩家可读层名——L1"第一层 · 苔藓回廊"切片现行;L2 provisional"第二层 · 雾漫巢径",终稿随 L2 内容批) + display_name: String(玩家可读层名——L1"第一层 · 苔藓回廊"切片现行;L2 层名未定稿〔provisional,终稿随 L2 内容批〕) rest_heal_pct: int [0,100](knob 默认 30——恢复点回复 max_hp_eff 的百分比,随上限加成同步放大防高上限档恢复失效;数值复验归 难度曲线与Boss) nodes: 节点链数组——node_kind ∈ {battle, reward, rest, boss}(切片字段名 type);battle/boss 携带 node_depth;reward/rest 不占深度 rowset_rule: Boss 恒末节点(schema 校验);战斗节点深度 = 前序战斗节点计数、Boss = Dmax(棋盘生成 第三轴约定兑现面);MVP 链模板 = battle D0 → battle D1 → reward → battle D2 → battle D3 → rest → boss D4(7 节点 5 战斗深度,L1/L2 同构复用) cross_table_validation: battle/boss 节点 (L,D) 在 board_gen/enemy 两表存在精确行(数据配置 跨表校验⑧复用 + 冒险结构 AC-7 冒烟断言——序列关数 ⊆ 内容覆盖,越界关卡 = 内容生产缺口) - mvp_content: L1 全行(切片转正——7 节点链、rest_heal_pct=30、全程无雾);L2 行 = N=2 扩展批(同构模板 + 难度曲线与Boss 深度轴行值同批填充——冒险结构 GDD 生效前提,未落地前冒险以单关行集运行 N=1 合法态) + mvp_content: L1 全行(切片转正——7 节点链、rest_heal_pct=30);L2 行 = N=2 扩展批(同构模板 + 难度曲线与Boss 深度轴行值同批填充——冒险结构 GDD 生效前提,未落地前冒险以单关行集运行 N=1 合法态) referenced_by: [冒险结构, 关卡节点地图, 难度曲线与Boss, 棋盘生成, 数据配置] - name: adventure_table @@ -578,3 +570,15 @@ entities: # clause3_supply.direction_precheck 增 2026-09-14 重算回执(现行值链破线 ≈0.48×/0.47×、约束升格曲线级—— # 禁独立调参联动网络 m_w↔D_ref↔m_d↔duration_d);clause5_dominance 增重算回执(v3 曲线四态 + 需求 110.3/166.8 + # 裁决②维持 + 护栏 W2 待重推注记);settlement_table.mechanics 增 战斗结算 F6 充能与护甲克制结算规格登记(W3)。 +# 2026-09-15 雾格移除清理批(owner=地形变异/棋盘生成/排雷玩法/奖励道具经济/战斗结算/辅助道具/冒险结构/GDD 代用户修订, +# 文档侧与代码侧分头执行)——variation_table:mvp_content 改空清单、删 load_bearing_rule 与 fog_ap_note 与 pricing_constraints +# 三键、dangling_ref_policy 改"首个真实引用随未来变异行建行批回填"、referenced_by 收敛为 {棋盘生成, 排雷玩法, 辅助道具}; +# board_gen_table:fields 删 fog_region_count/fog_target_ratio、cross_field_validation 删 fog_domain_ok、mechanics 改单一达标判据 +# 与信息源穷举{数字约束}、metrics 改四项、batch_assertions 删 B′ 无雾行、mvp_reference_rows 删雾列、golden_vectors 删 core 整数对、 +# 删 terrain_variation_acceptance_mapping;minesweeper_event_surface.cell_revealed 与 minesweeper_initial_expansion 去雾限定; +# terminology 删"档位序检查";reward_table 删 pricing_constraints 与雾池登记、tier 说明改写;reward_config 删 t_fog_min; +# clause5_dominance 删护栏 A 与 a4_three_legs、重跑义务去 fog_burden_ratio;hud_presentation_surface.hint_id 枚举改 {chord, no_adjacent}; +# aux_items:effect_kinds 去 fog_reveal、target 去 fog_region、mvp_content 两行效果改"效果待重定"(schema 枚举取值待重定批落定)、 +# overlay_semantics 显影集标"载体待重定"(三集结构不变); +# level_table:L2 层名占位删除(改"未定稿")、mvp_content 去"全程无雾"。 +# 本表历史注释行保留各批原文(含已删键与雾时代口径)作为修订留痕,现行口径以上方条目为准——对应文档同批修订见各文档「版本历史」。 diff --git a/design/research/lore-nest-metaphor-2026-09-12.md b/design/research/lore-nest-metaphor-2026-09-12.md index b59ff6af..0c76f69f 100644 --- a/design/research/lore-nest-metaphor-2026-09-12.md +++ b/design/research/lore-nest-metaphor-2026-09-12.md @@ -3,6 +3,7 @@ > 日期:2026-09-12 > 性质:世界观设定记录(叙事 / 隐喻层)——**非机制定案**。本稿不触碰任何已锁机制数值、接口与 GDD 正文(排雷循环与战斗循环各系统、难度曲线与Boss 已定稿内容不受影响);涉及机制侧的事项仅在 ③ 末行以"边界提醒"列出。 > 状态:**已拍板并采纳(2026-09-12),概念层修订已执行**——game-concept 世界观与命名节 + 视觉锚原则 5 已带 2026-09-12 版本注记改写;旧版 systems-index 备注·概念层增补已登记;⑤节六问拍板结论已逐条回写(含两处修正案:⑤-1 惩罚格类型化、⑤-2 对外动词"控制")。原状态:草案,待用户反馈。 +> 失效注记(2026-09-15):本文中"雾格的叙事身份 / 净化之雾"相关提案(1.3-3 及 ②/③/④ 表中的相关行)所指向的机制——雾格——已从设计中永久移除(见[不做清单](../gdd/05-不做清单.md));相关内容仅作历史研究留档,不再作为现行设计依据。 > 素材来源:用户提案(雷图 = 地牢 / 雷 = 怪物巢穴 / 插旗 = 封印或火把 / 安全格 = 探索安全区 / 道具 = 宝箱)+ 新拍板机制"标错旗 → 随机敌增伤 / 敌 buff,或我方 debuff(时效约 1 回合)"的包装需求。 > 关联:`game-concept.md`(世界观与命名,定稿 2026-09-09)· `game-pillars.md`(P1–P4)· 旧版《敌人系统》`b2-enemy-system.md`(Overview / Player Fantasy)· 旧版索引 `systems-index.md`(概念层增补块)· 旧版《排雷玩法》`a2-minesweeper-rules.md`(OQ1 / EC5 / GD-1 / Rule 11)· 旧版《地形变异》`a4-terrain-variation.md`(雾区无雷)· 旧版《奖励道具经济》`b4-reward-item-economy.md`(install 期预分配)· 旧版《战斗结算》`b1-settlement.md`(完美排雷 / 标中旗 highlight / flag_miss 行)。以上旧版文件均已迁入 `design/archive/gdd-2026-09-14/`(只读归档)。 diff --git a/design/ux/battle.md b/design/ux/battle.md index bbde7daf..2e9dfc85 100644 --- a/design/ux/battle.md +++ b/design/ux/battle.md @@ -2,12 +2,12 @@ > **Status**: Complete — /ux-review 修订落稿(2026-09-12,blocking 7 项已修,待复检) > **Author**: user + ux-designer -> **Last Updated**: 2026-09-12 +> **Last Updated**: 2026-09-15(雾格残留清理:格态两态化、图例/首遇/纹带雾条目与遥测提示枚举同步,见文末修订说明) > **Platform Target**: PC (Steam)——Keyboard/Mouse 主(全部操作纯鼠标可完成)、Gamepad Partial 非 MVP、Touch None(同 technical-preferences) > **上游修订依赖**: 弃图刷新挖掘期受理已随布局决策 4 落稿上游(2026-09-12:行动经济 Active 受理 + 每轮上限 2 次、排雷玩法 Active·仅刷新路径装板、战斗结算 `refresh_board` 编排 + 恒 same_board、registry `rap_rules` 同步——见 OQ12) > **Template**: UX Spec > **覆盖子屏**: 挖掘阶段主界面 · 轮末自动战斗结算(战斗结算明细屏) · 道具使用窗口(奖励道具经济/战斗结算域屏) · 胜利/失败终局 · 结算明细回看 -> **输入义务**: 排雷玩法×6 + 行动经济 + 地形变异×3 + 战斗结算×3 + 敌人系统×4 + 增益状态×4 + 奖励道具经济×5(旧版 systems-index 门禁增补记录,缺项即 blocking——承接落点见 §13 义务对照表) +> **输入义务**: 排雷玩法×6 + 行动经济 + 战斗结算×3 + 敌人系统×4 + 增益状态×4 + 奖励道具经济×5(旧版 systems-index 门禁增补记录,缺项即 blocking——承接落点见 §13 义务对照表) --- @@ -19,7 +19,7 @@ - 扫雷图区承载 P1(推理掌控感):数字是主角,一切服务信息可读 - 战斗画面区承载 P2(规划的延迟兑现):扫雷之因逐行兑现为战果,全程可见可归因 -- 角色信息/道具区承载规划面:状态、资源、库存常读,支撑"往雾区推进/囤刀待机"类决策(奖励道具经济可证伪信号的 MVP 观测面) +- 角色信息/道具区承载规划面:状态、资源、库存常读,支撑"往未开区推进/囤刀待机"类决策(奖励道具经济可证伪信号的 MVP 观测面) 若此屏缺失或难用:推理与兑现分裂(自动战斗沦为无聊过场——已登记创意风险)、逐行归因不可见(P2 失败)、AP/RAP/库存不可读(规划失去原料)。 @@ -27,7 +27,7 @@ ## Player Context on Arrival -- **首次到达**:从关卡首节点(战×2 的第一战)进入。MVP 无引导流,地形变异雾首遇提示、chord 肌肉记忆提示等非模态提示承担首次教学(见 §States) +- **首次到达**:从关卡首节点(战×2 的第一战)进入。MVP 无引导流,chord 肌肉记忆提示等非模态提示承担首次教学(见 §States) - **到达前刚在做**:关卡节点链上点击战斗节点(LevelRunner 推进);或上一场战斗胜利后点下一节点 - **情绪状态**:棋手式清明专注(art-bible §2.1,能量 2/10)——挖掘期画面必须无杂音;结算期转为清算爽感(7/10) - **到达方式**:游戏推进送入(非自愿导航),进入即处于挖掘阶段(棋盘已 install、初始 3×3 已展开、小人出生) @@ -79,11 +79,11 @@ 本屏必须传达的全部信息,按注视优先级分五层: -1. **扫雷图本体**(第一注视点,挖掘期占视觉预算大头):四格态(已开 0 格地板/已开雾格无字/未开格/未开雾格——排雷玩法×6② 一眼可辨)、数字、旗、小人、可挖域(8 向相邻常驻指示)、变异纹理(迷雾) +1. **扫雷图本体**(第一注视点,挖掘期占视觉预算大头):两格态(已开格 / 未开格——排雷玩法×6② 一眼可辨)、数字、旗、小人、可挖域(8 向相邻常驻指示)、变异纹理 2. **本轮行动资源**:AP 余量(决定还能挖几格)、停手/弃图刷新按钮——紧贴棋盘上缘(动作发生地) 3. **战果兑现面**(结算期为第一注视点):敌人血条变化、逐行结算明细、高光(完美排雷/标中旗) 4. **规划面**(边缘注视,常读):HP、攻击、RAP 池、状态效果(己方/敌方)、库存列表、敌人意图徽标与顺位 -5. **进度语境**:轮次/阶段指示、关卡节点进度、雾图例入口 +5. **进度语境**:轮次/阶段指示、关卡节点进度、图例入口 依据:挖掘期玩家视线锚定棋盘(art-bible §2.1"视线始终被数字牵引");结算期视线转向战斗画面区(§2.2"兑现光带逐行横扫")。规划信息必须常读但不得抢焦——这正是用户布局图三分下栏的合理性:**动作区居中,规划区两翼**。 @@ -119,12 +119,12 @@ | C | HP/攻击/RAP 显示 | 直角细线数据框 | 当前值/上限、修正来源角标 | 只读;RAP 清零有可见反馈 | HUDView 拆分 | | C | 状态效果槽 ×4 | 图标槽 | effect_id→icon(形状+色相双通道)、层数角标、剩余结算次数点 | 悬停 tooltip(来源+语义) | 新建(增益状态×①) | | D | AP 条 | 点阵 + 按钮组 | 本轮 AP 点阵、停手按钮(左)、弃图刷新按钮(右端·雷图右上角;RAP−8 · 本轮剩 N 次——上限 2 次已随行动经济 2026-09-12 修订生效) | 点击提交意图 | HUDView 拆分 | -| D | BoardView | 网格 | 棋盘全部格态 + 小人 + 旗 + 雾纹带 + 奖励身份 icon(已开格;绘制优先级 数字>小人>旗>奖励徽章>变异纹带>底色——徽章不进数字区,样张验收项) | 左/右键意图提交 | ✅ board_view.gd 迁移 | +| D | BoardView | 网格 | 棋盘全部格态 + 小人 + 旗 + 变异纹带 + 奖励身份 icon(已开格;绘制优先级 数字>小人>旗>奖励徽章>变异纹带>底色——徽章不进数字区,样张验收项) | 左/右键意图提交 | ✅ board_view.gd 迁移 | | D | 悬停预承诺光标 | 光标态 | 移动/挖/旗三语义光标 + 目标格边框高亮 | 自动 | 新建(排雷玩法×6③) | | D | 可挖域指示 | 常驻微高亮 | 小人 8 向相邻可操作格 | 自动 | 新建(排雷玩法×6③) | | D | 移动路径预览 | 路径高亮 | 悬停已开格显示 BFS 路径(合法性指示) | 自动 | 新建(排雷玩法×6⑤,裁决见下) | -| D | toast 槽 | 非模态提示 | 拒绝原因(双源)、voided、满层溢出、雾首遇、chord 提示、零合法板告知 | 自动消退 2.5s | 新建 | -| D | 图例按钮 + 面板 | 按钮+模态 overlay | 格态/变异/雾语义图例("迷雾 = 无雷盲区"条目恒在) | 开/关 | 新建(地形变异×②) | +| D | toast 槽 | 非模态提示 | 拒绝原因(双源)、voided、满层溢出、chord 提示、零合法板告知 | 自动消退 2.5s | 新建 | +| D | 图例按钮 + 面板 | 按钮+模态 overlay | 格态/变异语义图例 | 开/关 | 新建 | | E | 库存列表 | 固定槽高列表 | 逐件:icon+名称+属性简述+状态;枚举序 = stock 受理序(旧版台账 E21) | 悬停 tooltip(完整描述+触发注记);窗口期点选 | item_window_overlay.gd 改造 | | E | 道具使用窗口态 | 面板原位激活态 | "轮末道具窗口 · 至多选 1 件"+ 时机指示 + usable_now 禁选态 + 跳过按钮 + 触发政策注记 | 点选/跳过 | ✅ item_window_overlay.gd 改造(形态裁决见下) | | 全屏 | 胜利/失败 overlay | 模态 | 金蜡封/暮蓝收旗 + 判定行 + 明细回看入口 | 继续/下一节点 | node_overlay.gd 扩展 | @@ -182,7 +182,7 @@ │ │ (槽×4 固定) │ │ │ 12 █ 1 1 2 ▓▓ ▓▓ │ │ │ 高伤 · 一次性 │ │ │ ├──────────────────┤ │ │ 1 2 2 🚩 █ 2 1 │ │ ├─────────────────┤ │ │ │ [小人立绘占位] │ │ │ ░ 1 ▓▓ 👫 1 1 ░ │ │ │ ❤ 治疗包 ×1 │ │ -│ │ │ │ │ ▓▓雾 1 1 ░ ░ 2 ▓▓ │ │ │ 回复 12 · 可用 │ │ +│ │ │ │ │ ▓▓ 1 1 ░ ░ 2 ▓▓ │ │ │ 回复 12 · 可用 │ │ │ └──────────────────┘ │ │ ( █=可挖域微光 👫=小人) │ │ └─────────────────┘ │ │ │ └───────────────────────────┘ │ │ └───────────────────────┴───────────────────────────────┴─────────────────────┘ @@ -217,7 +217,6 @@ | **胜利终局** | verdict=win | 金蜡封落于**扫雷图区中央**(§2.4 字面锚定),全屏暖白金 overlay;判定行 + 「下一节点」;明细回看入口;状态槽全清可见反馈(增益状态×4④——逐槽化光收回 + 微文案「状态随战斗结束消散」,防「我的 buff 哪去了」误读) | | **失败终局** | verdict=lose(hero hp=0,战斗段短路) | 明度不变的暮蓝 #5A6C8C 氛围 overlay(全作唯一暮蓝档);小人坐砖掸灰、插过的旗逐面化光点收回(§2.5);判定行 + 明细回看(学习用途)+「返回」;状态槽全清可见反馈(增益状态×4④,同胜利) | | **Boss 遭遇变体** | encounter=boss(遗迹守卫) | 战斗开始一次性演出:紫赤 #8F2F6A 影子爬过棋盘(§2.6);敌人卡体量最大+锐角剪影;阶段指示附 Boss 名 | -| **雾图变体(第二层起)** | 板含雾格 | 雾纹带双通道呈现;首次含雾板进入挖掘阶段触发一次性首遇提示(每 run 一次);图例恒可回看;**已开雾格保留底色层淡雾 tint**(与已开 0 格可判定区分——OQ8 裁决采纳 2026-09-12;tint 处视觉锚 3 最低层,不遮挡数字);**雾区全开一次性完成信号**(视觉合并域 = 信号单元,禁实例级双响;排雷玩法 EC11:双雾区呈现合并、实例独立) | | **空态:无状态效果** | 增益状态 EC12 | 状态槽隐藏 or 空槽占位——**裁决:槽位隐藏,HP/攻击/RAP 上移补位**(角色信息区纵向空间紧张,空槽占位浪费);图例面板载空态说明(增益状态×① 成文项) | | **空态:零库存** | 关卡初/清空后 | E 区显示「道包空空——安全格里藏着补给」(指引性空态,非报错) | | **调试变体** | 测试模式 | TunePanel 入口(demo 保留,正式侧元进度退役);Playtest 诊断按钮(卡死转储) | @@ -240,7 +239,7 @@ | 未开格 | 插旗 / 已旗格拔旗 | 右键 | 旗落下/移除(旗朱) | 意图入批(1 AP / 免费) | | 停手按钮 | 主动结束轮次 | 左键 | 按钮下压 + AP→RAP 飞行数字 | `settle_batch([stop])`(**经排雷玩法批次,不直调行动经济**——单意图帧批次契约) | | 弃图刷新按钮(雷图右上角) | 当轮就地换图继续挖 | 左键 | 确认微交互(RAP−8 代价显式 + 旧板弃置提示);RAP<8 → 资源面拒绝可见(行动经济 EC13) | `request_refresh`(**Active 相位当场换图继续挖**——AP 不重置、本轮剩 N 次扣减;**上游已修订受理——见布局决策 4/OQ12**) | -| 图例按钮 | 开图例 | 左键 | 模态 overlay | 恒可开(地形变异 图例条目恒在) | +| 图例按钮 | 开图例 | 左键 | 模态 overlay | 恒可开(图例条目恒在) | | 结算明细带 | 展开回看 | 左键 | 明细 overlay | 只读 | | 状态/道具 tooltip | 悬停 | hover | 状态 tooltip(来源+语义+剩余);道具 tooltip(完整描述+触发注记——不含来源) | 只读 | | 道具(窗口态可用件) | 选用 | 左键 | 选中态高亮 → 窗口关闭回结算流 | `submit_window_selection(窗口位置)`——**传窗口条目位置,非库存句柄**(缺陷④契约) | @@ -249,7 +248,7 @@ | 胜利 overlay | 下一节点 | 左键 | → NodeOverlay / 关卡结算 | LevelRunner 推进 | | 失败 overlay | 返回 | 左键 | → 存档/营地 | 冒险终结 | -**单意图帧纪律**(排雷玩法×6⑥):一帧内 collected 意图整批提交,stop 点击终结当帧收集;F4 语义序仲裁为防御性兜底。悬停预承诺三态光标:移动(箭头)/挖(镐)/旗(旗形)——左键双义(移动 vs 挖)的消歧完全依赖四格态一瞥可辨 + 光标区分(误挖不可逆的感知保险)。 +**单意图帧纪律**(排雷玩法×6⑥):一帧内 collected 意图整批提交,stop 点击终结当帧收集;F4 语义序仲裁为防御性兜底。悬停预承诺三态光标:移动(箭头)/挖(镐)/旗(旗形)——左键双义(移动 vs 挖)的消歧完全依赖格态一瞥可辨 + 光标区分(误挖不可逆的感知保险)。 **复合意图(排雷玩法评估项留痕)**:点击远格 = 自动 move+dig 的两击摩擦消解——**MVP 不做**(留痕 2026-09-12:免费移动高频,两击摩擦符合 P4 ≤2 观测假设;排雷玩法 L298 评估项)。 @@ -270,7 +269,7 @@ | 弃图刷新(挖掘期,非轮出口) | `ux_refresh_attempt` | {result: accepted/rejected_rap/rejected_cap, round_refresh_index: 1..2}——刷新使用(难度曲线与Boss OQ6)与行动经济 OQ3 预警阈值观测;每轮 0–2 次(布局决策 4 cap=2) | | 窗口选用/跳过 | `ux_window_choice` | {selected_item_id, usable_now, skip} | | 拒绝/voided | `ux_reject` | {source: board/resource/phase, sub_reason} | -| 提示触发/关闭 | `ux_hint_shown` | {hint_id: fog_first/chord/no_adjacent} | +| 提示触发/关闭 | `ux_hint_shown` | {hint_id: chord/no_adjacent} | | 呈现订阅(不改核心) | 排雷玩法三事件 / [战斗结算](../gdd/systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)步骤流(15 类行协议,含终局判定行) / battle_over / level_clear | 载荷 schema 成文义务见 §Data Requirements——旧版台账 entry 17①(HUD框架硬性要求) | **持久状态写入**全部经组合根唯一路径(settle_batch / submit_window_selection / request_refresh / runner 推进)——UI 层禁直调核心写(架构七原则"依赖单向组合根")。 @@ -300,7 +299,7 @@ | Data | Source System | Read / Write | Notes | |---|---|---|---| -| 棋盘四格态/数字/雾/可挖域 | 排雷玩法 只读面(query) | Read | 呈现刷新面 = 排雷玩法 三事件信号(载荷 schema 成文——旧版台账 entry 17①) | +| 棋盘格态/数字/可挖域 | 排雷玩法 只读面(query) | Read | 呈现刷新面 = 排雷玩法 三事件信号(载荷 schema 成文——旧版台账 entry 17①) | | BFS 移动路径 | 排雷玩法 `compute_move_path` | Read | 布局决策 3 合法性指示消费 | | 拒绝原因 | 排雷玩法 `sub_reason` 封闭枚举 + 行动经济 资源面 | Read | 三源(board/resource/phase)映射文案——呈现层契约成文;资源面原因无上游载荷(行动经济 仅 bool + debug 诊断),客户端按动作上下文推断 | | AP / RAP / 本轮刷新计数 | 行动经济 | Read | 常显;刷新入口可用性 = RAP 读数客户端预判(RAP≥8)+ `request_refresh` 返回值(行动经济 无 `can_request_refresh` API——仅 bool 返回 + 只读观测量;行动经济 EC13 拒绝合法可见) | @@ -327,8 +326,8 @@ 项目尚未建 `design/accessibility-requirements.md`(gate-check 缺口,见 Open Questions)。本 spec 内建基线承诺: - **对比**:全部格底/面板底对数字墨 ≥4.5:1(WCAG AA)——art-bible §4.1 硬指标已可测(#33261B/#C9AF83 = 6.9:1 实测);UI 数据一律墨族素面 -- **色弱冗余**:无任何信息仅靠色相承载——四格态靠完整/碎裂形+纹带形;奖励金 vs 危险红靠剪影+运动;UI 红/金强调对加图标+文案冗余;Boss 靠形状独占(art-bible §4.5 清单逐项成立) -- **灰度可辨**:变异格纹带、四格态在灰度截图下可分类(art-bible §3.2 验收标准) +- **色弱冗余**:无任何信息仅靠色相承载——格态靠完整/碎裂形;奖励金 vs 危险红靠剪影+运动;UI 红/金强调对加图标+文案冗余;Boss 靠形状独占(art-bible §4.5 清单逐项成立) +- **灰度可辨**:变异格纹带、格态在灰度截图下可分类(art-bible §3.2 验收标准) - **非色彩破坏性确认**:弃图刷新(消耗 RAP 8 点)的确认交互与常规确认**不同位**(位置通道,色弱清单 #7) - **字号下限**:棋盘数字 ≥18px、明细带正文 ≥14px、tooltip ≥13px(1280×800 基座) - **运动**:无闪烁 >3次/秒;结算光带为方向性扫动非频闪;提供减动效选项(§Transitions) @@ -352,7 +351,7 @@ - [ ] 1280×800 与 16:9 全屏(canvas_items/expand)下五区无遮挡、无重叠、无内容裁切(棋盘 12×12 全部格子 + 数字完整可见) - [ ] 进入战斗屏 ≤500ms 内可交互(棋盘 install 淡入完成后首格可点);同屏 draw calls < 200(technical-preferences 预算) -- [ ] 四种格态(已开 0 格地板/已开雾格无字/未开格/未开雾格)灰度截图下一眼可辨(排雷玩法×6②) +- [ ] 两种格态(已开格 / 未开格)灰度截图下一眼可辨(排雷玩法×6②) - [ ] 悬停光标区分移动/挖/旗三语义;可挖域(8 向相邻)常驻指示;非相邻格悬停显禁止反馈(排雷玩法×6③) - [ ] 已引爆雷格呈"可通行可读"(排雷玩法×6④) - [ ] 全部数字对所在格底对比 ≥4.5:1;明度恒定规则无违例(art-bible §4.1) @@ -372,9 +371,8 @@ - [ ] 结算逐行明细实时可见、战斗后可回看完整流水(P2 逐行归因);四类行(道具语境/奖励未生效/已消耗未生效/使用被拒)按 奖励道具经济×③ 呈现 - [ ] 敌人意图徽标挖掘期全程可见、映射全局恒定、含顺位与环长直觉编码(敌人系统×4①②③) - [ ] 状态效果:极性呈现映射成文且非 magnitude 符号;空态渲染成文(裁决:槽隐藏);满层溢出经明细行可见(增益状态×①③④) -- [ ] 图例面板「迷雾 = 无雷盲区」条目恒在可随时回看;雾首遇提示一次性(每 run)且非模态不劫持输入,必含三要点(无雷盲区不赌命/雾格不传播连锁/雾内插旗纯损)(地形变异×②) +- [ ] 图例面板条目恒在可随时回看、非模态提示不劫持输入 - [ ] 零合法板(棋盘生成 EC5 降级)出现时玩家侧诚实提示(toast,非静默) -- [ ] 已开雾格与已开 0 格灰度截图下可判定区分(底色层 tint 残留——OQ8 裁决采纳);雾区全开完成信号以视觉合并域为单元、无实例级双响(排雷玩法 EC11;样张须含宽度 1 雾带两侧毗邻数字格等最坏用例——地形变异 AC-9) - [ ] 效果行 value 为单次贡献值,不得与 pool_value(池合成值)相加呈现;零值伤害行可见不被吞;衰减行按聚合计数呈现(战斗结算 呈现细则) - [ ] 未生效类行(奖励未生效/已消耗未生效/使用被拒/溢出未生效)携带形状冗余(icon/划线),非色相独载 - [ ] 奖励徽章绘制优先级:旗之下、变异纹带之上、不进数字区;拾取瞬间 tier 档位可读(奖励道具经济 H1) @@ -401,7 +399,7 @@ 8. **Gamepad 导航序**:Partial 支持(非 MVP 门禁)——焦点环顺序待 gamepad 批次定 9. **NodeOverlay / 关卡结算屏**:相邻域屏,建议后续 spec `design/ux/node-reward.md` + `design/ux/level-clear.md`(本 spec 只锁出口锚点) 10. **TunePanel 退役计划**:正式侧归元进度(天赋树),切片调试入口在《HUD框架》标注退役时点 -11. **提示文案定稿**:雾首遇三要点/chord 提示/空态文案归实现期文案 pass,本 spec 只锁必含要点与形态约束 +11. **提示文案定稿**:chord 提示/空态文案归实现期文案 pass,本 spec 只锁必含要点与形态约束 12. **弃图刷新上游修订(已落稿 2026-09-12,布局决策 4)**:行动经济(Active 相位受理 + 每轮上限 2 次 + Waiting 代理退役 + 旧旗作废裁决 + 时间税失效预警)、排雷玩法(Active·仅刷新路径装板受理)、战斗结算(stopped/ap_exhausted 恒 same_board + `refresh_board` 挖掘期刷新编排;AC-29 改写/AC-30 恒 same_board)、registry `rap_rules` 同步、旧版 systems-index 修订块登记。遗留观察项:当场刷新的节奏健康由行动经济 OQ3 弃图率/刷新率预警承载,playtest 复核 13. **教学引导缺口挂靠(成文时教学引导 GDD 尚未建,留痕)**:挖到雷 = 敌方优势而非死亡(排雷玩法登记「经典扫雷玩家最大预期违背」)、旗挡链(连锁止于旗属正常)、首次蓄力姿态一次性提示(敌人系统)、窗口拾取→囤刀→选用闭环教学(奖励道具经济)——本屏 toast 体系为落点候选,随教学引导批次定 @@ -414,16 +412,23 @@ | 义务源 | 条目 | 本 spec 承载落点 | |---|---|---| | 排雷玩法×6 | ① stop 经批次 | §Interaction Map 停手行 + AC | -| 排雷玩法×6 | ② 四格态可辨 | §Layout 格态 + AC | +| 排雷玩法×6 | ② 格态可辨(已开 / 未开两态) | §Layout 格态 + AC | | 排雷玩法×6 | ③ 悬停预承诺+可挖域+chord 提示 | §Interaction Map + §States | | 排雷玩法×6 | ④ 引爆雷格可通行可读 | §AC | | 排雷玩法×6 | ⑤ 路径预览裁决 | 布局决策 3 | | 排雷玩法×6 | ⑥ 单意图帧+voided+拒绝可感知 | §Interaction Map + §States 拒绝子态 + AC | | 行动经济 | AP/RAP 常显+刷新入口+清零反馈+双源 | §Layout C/D 区 + §Transitions + AC | -| 地形变异×3 | 雾纹理/图例+首遇/已开雾格+tint | §States 雾图变体 + 图例组件 + AC | | 战斗结算×3 | ①高光行强调呈现(标中旗金框行/清图 H2 金框行)②完美排雷呈现形态 ③棋盘生成 EC5 零合法板提示/补偿/回退形态(toast 提示;补偿/回退不提供——三形态选型留痕 2026-09-12) | §States 高光/清图 + §States 拒绝子态 + §AC;注:结算明细屏+道具窗口 = 战斗结算 UX Flag 事项(本 spec 即其 /ux-design 产物),非 战斗结算×3 台账 | | 敌人系统×4 | 意图映射/恒定/顺位/敌方池 | §Component Inventory 敌人卡 + **意图线索映射目录(敌人系统×4① 成文占位,资产定稿归战斗表现)** + AC | | 增益状态×4 | 常显+空态/来源标注/溢出/去留 | §States 空态 + §AC | | 奖励道具经济×5 | 身份恒读/窗口/四类行/清图强调/清空反馈 | §Component Inventory E 区 + §States 清图/高光 + AC | | 棋盘生成 | EC5 零合法板诚实呈现(数据面经 战斗结算×3③ 上抛) | §States 拒绝子态(toast)+ AC | | 敌人系统资产下限 | 受击反馈/死亡表现/顺位标记 | §Transitions 受击 + §States 敌人死亡呈现(禁瞬消)+ §Component 顺位徽标;呈现语义在本 spec(同等 blocking),动画密度归战斗表现 | + +--- + +## 修订记录 + +| 日期 | 改动 | +|---|---| +| 2026-09-15 | 雾格残留清理:格态收窄为已开 / 未开两态(删除雾图变体状态行、四格态 AC 与已开雾格 tint / 雾区全开信号两条 AC);图例面板与 toast 槽去掉雾条目与雾首遇提示;BoardView 纹带、绘制优先级与色弱冗余改按通用变异纹带表述;`ux_hint_shown` 的 hint_id 枚举去掉 fog_first;输入义务与 §13 义务对照表去掉 地形变异×3 一项;目标感知示例与提示文案 OQ 措辞同步。本 spec 不装载被移除机制的呈现义务 | diff --git a/design/ux/interaction-patterns.md b/design/ux/interaction-patterns.md index 97198c8d..7a629278 100644 --- a/design/ux/interaction-patterns.md +++ b/design/ux/interaction-patterns.md @@ -2,7 +2,7 @@ > **Status**: Complete(核心 8 成文 + 12 目录占位) > **Author**: user + ux-designer -> **Last Updated**: 2026-09-12 +> **Last Updated**: 2026-09-15(雾格残留清理:pattern 4 / 10 同步格态两态与提示枚举,见文末修订记录) > **Template**: Interaction Pattern Library > **来源**: `design/ux/battle.md`(2026-09-12 /ux-review APPROVED)已拍板内容的成文固化——本库不引入新设计决策 @@ -30,7 +30,7 @@ | 7 | 破坏性确认异位 | Feedback | **成文 ✓** | | 8 | 禁用态即理由 | Feedback | **成文 ✓** | | 9 | 常驻意图徽标 | Data Display | **已实现**(enemy_card_view.gd——规格全文待补) | -| 10 | 一次性非模态教学提示 | Feedback | **已实现**(雾首遇/chord——规格全文待补) | +| 10 | 一次性非模态教学提示 | Feedback | **已实现**(chord 提示——规格全文待补) | | 11 | tooltip 规范 | Feedback | **已实现**(状态/道具悬停——规格全文待补) | | 12 | 单意图帧批次提交 | Input | **已实现**(main.gd 组合根——规格全文待补) | | 13 | 状态效果槽 | Data Display | **已实现**(status_slot_row.gd——规格全文待补) | @@ -117,7 +117,7 @@ MVP 未使用标准控件(不入库):toggle / dropdown / input field / tab **Category**: Input **Used In**: 扫雷图 BoardView -**Description**: 左键双义(已开格=移动 / 未开相邻格=挖)的消歧完全依赖四格态一瞥可辨 + 悬停光标区分——**误挖不可逆**(1 AP + 可能触雷)的感知保险。 +**Description**: 左键双义(已开格=移动 / 未开相邻格=挖)的消歧完全依赖格态一瞥可辨 + 悬停光标区分——**误挖不可逆**(1 AP + 可能触雷)的感知保险。 **Specification**: - 光标三态:移动(箭头)/挖(镐)/旗(旗形)——按悬停格态与键位自动切换 @@ -225,3 +225,11 @@ MVP 未使用标准控件(不入库):toggle / dropdown / input field / tab 1. 目录占位项的补全时点 = 实现期随批回写(owner:ui-programmer → ux-designer 复核) 2. Gamepad 批次引入时,需为 pattern 4/12/15 增补手柄映射节(焦点序已在 battle.md OQ8 留位) + +--- + +## 修订记录 + +| 日期 | 改动 | +|---|---| +| 2026-09-15 | 雾格残留清理:pattern 1 无改;pattern 4 的悬停预承诺消歧依据改按格态两态表述;目录 #10 一次性非模态提示的已实现说明去掉雾首遇、只留 chord 提示。pattern 库不引入新决策 | diff --git a/docs/architecture/architecture.md b/docs/architecture/architecture.md index 73db40cd..4d7ecb6c 100644 --- a/docs/architecture/architecture.md +++ b/docs/architecture/architecture.md @@ -2,8 +2,8 @@ ## Document Status -- Version: 1.0 -- Last Updated: 2026-09-12 +- Version: 1.1 +- Last Updated: 2026-09-15(雾格移除清理:variation 定义、生成期指标口径、D1 呈现义务台账同步现行文档) - Engine: Godot 4.7.2-stable(GDScript 单语言;2026-09-07 锁定) - Review Mode: solo(`production/review-mode.txt`,2026-09-12 用户拍板——TD/LP 门禁按 solo 跳过,用户授权架构产出自主推进、迭代期回调) - GDDs Covered: game-concept · game-pillars · systems-index · d2-data-config · a3-action-economy · a4-terrain-variation · b3-status-effect · a1-board-generation · a2-minesweeper-rules · b2-enemy-system · b4-reward-item-economy · b1-settlement(12 份;A5/C1–C4/B5/D3–D6 未设计,按 systems-index 依赖分层预留) @@ -91,7 +91,7 @@ | **ConfigDB**(autoload,D2) | 全部玩法数值表(`data/tables/*.tres` + `data/schemas/*.gd`);SCHEMA_VERSION;加载/校验/override/诊断状态机 | 类型化属性读取;`load_tables(root, collect_only)`;`resolve()`(R1 floor);debug override;`set_reload_gate()`;诊断收集器 | 无(Foundation 顶点) | Resource/.tres 加载、autoload 生命周期——LOW | | **RngService**(autoload,D2) | master_seed、各流 scope 计数器(封闭流:board_gen / reward_roll;增流走 P1 评审) | `set_master_seed()`(唯一调用方 C2);`open_stream(stream)` 有状态门面;`derive_at(stream, scope)` 纯函数;只读计数器 | ConfigDB(无) | 无——纯逻辑 | | **action_economy**(A3) | AP/RAP 账本、last_round_end、轮次相位机 {Idle, Active, Waiting}、结束仲裁 | 8 API 全布尔面:notify_round_start / request_dig / request_flag_place / request_flag_pull / request_stop / request_refresh / notify_settlement_done / notify_combat_end;ap/rap/phase 只读 | ConfigDB(ActionEconomyTable);B1 回发 next_round_mode/battle_over | 无 | -| **variation 定义**(A4) | VariationTable schema 与 MVP fog 行、F1 候选池门控谓词 | `variant_pool_gate(level_index, board_biome)` | ConfigDB(VariationTable) | 无 | +| **variation 定义**(A4) | VariationTable schema(现行空清单,合法态)与 F1 候选池门控谓词 | `variant_pool_gate(level_index, board_biome)` | ConfigDB(VariationTable) | 无 | | **status_container**(B3) | 状态实例容器(战斗域生命周期、跨轮跨图延续) | 5 API:notify_battle_start / apply_effect / query_active / decay_round / notify_battle_end | ConfigDB(StatusEffectTable) | 无(RefCounted) | | **save_system**(D3,Alpha) | 存档格式与版本比较 | (未设计——契约锚:SCHEMA_VERSION + master_seed + 各流 scope 计数器快照,须在无在飞 open_stream 实例时切出) | ConfigDB、RngService 只读计数器 | FileAccess——LOW | | **settings/localization**(D6,愿景) | 设置项、翻译数据 | (未设计) | ConfigDB | 无 | @@ -100,7 +100,7 @@ | 模块 | Owns | Exposes | Consumes | 引擎 API | |---|---|---|---|---| -| **board_generator**(A1) | 生成算法(五阶段管线)、BoardGenTable 回填、八项生成期指标、合法性谓词(clearable / R₀≠S / min_safe)、可推理率度量(metric_version) | `generate(L, D, rng) -> Board`;度量独立入口×3(推理器 / F3 度量 / 合法性谓词——独立纯函数、同一实现) | ConfigDB(BoardGenTable/VariationTable);board_gen 流(一次 open_stream = 一张图);dig_ap_cost 只读 | 无 | +| **board_generator**(A1) | 生成算法(五阶段管线)、BoardGenTable 回填、生成期指标集、合法性谓词(clearable / R₀≠S / min_safe)、可推理率度量(metric_version) | `generate(L, D, rng) -> Board`;度量独立入口×3(推理器 / F3 度量 / 合法性谓词——独立纯函数、同一实现) | ConfigDB(BoardGenTable/VariationTable);board_gen 流(一次 open_stream = 一张图);dig_ap_cost 只读 | 无 | | **minesweeper_rules**(A2) | 棋盘状态(已开集 O / 旗集 G / 小人位)、三事件面、批次仲裁、install 四不变式 | `install_board(board)`;`settle_batch(intents)`(唯一提交入口);try_dig / try_flag_place / try_flag_pull / try_move(便捷形);`compute_move_path(cell)` 只读;`retire_board()`;三源拒绝(board_face / resource_face / phase)+ sub_reason 封闭枚举 | A1 产物(Board class_name 数据契约);A3 try_spend / last_round_end / 相位 | 无(零表读取、零 UI——切片实证) | | **unit_container**(B2) | hero/enemy 单位实例(hp/atk/行为环指针)、行值快照 | 9 API:spawn / query_alive / query_beat / query_attack / apply_damage / advance / default_target / ambush_grant_plan / despawn_all | ConfigDB(EnemyTable/HeroTable) | 无 | | **reward_economy**(B4) | 板级身份映射(install 期预分配、Ready 只读)、关卡域库存(逐件实例)、**RewardSupplyController**(切片新增私有组合件:注入占比 + 指数递减、行值快照、零自有随机) | 10 API:roll_board / query_identity / grant / grant_clear / stock / use / query_inventory / clear_inventory / retire_mapping / equivalence_supply;另 query_full_snapshot(轮内刷新 facts 隔离)、grant_node_active(C1-lite 接口漂移) | ConfigDB(RewardTable/RewardConfigTable);reward_roll 流(scope = 每次 install 批) | 无 | @@ -120,10 +120,10 @@ | 模块 | Owns | Exposes | Consumes | 引擎 API | |---|---|---|---|---| -| **D1 HUD**(切片 lite 已拆 9 单元:BoardView / HUDView / HudPresenter / BattleLogView / ItemWindowOverlay / NodeOverlay / LevelStripView / TunePanel / UiKit + 组合根 main.gd) | 全部 Control/CanvasLayer、输入→意图翻译(**唯一提交路径 = settle_batch,不直调 A3**)、呈现义务台账(A2×6 / B2×4 / B3×4 / B4×5 / B1×3 / A4×2) | 视图单元接口(信号外发、setter 只读注入) | A2 compute_move_path / ActionOutcome;A3 ap/rap;B1 步骤流行协议(数据源);ConfigDB display_name | **MEDIUM**:Control / CanvasLayer / draw_* / InputEvent / RichTextLabel——对照 breaking-changes.md 4.5–4.7 条目(CanvasItem 线条无抗锯齿羽化、设备 ID 常量、RichTextLabel 图片参数两轮变化) | +| **D1 HUD**(切片 lite 已拆 9 单元:BoardView / HUDView / HudPresenter / BattleLogView / ItemWindowOverlay / NodeOverlay / LevelStripView / TunePanel / UiKit + 组合根 main.gd) | 全部 Control/CanvasLayer、输入→意图翻译(**唯一提交路径 = settle_batch,不直调 A3**)、呈现义务台账(A2×6 / B2×4 / B3×4 / B4×5 / B1×3) | 视图单元接口(信号外发、setter 只读注入) | A2 compute_move_path / ActionOutcome;A3 ap/rap;B1 步骤流行协议(数据源);ConfigDB display_name | **MEDIUM**:Control / CanvasLayer / draw_* / InputEvent / RichTextLabel——对照 breaking-changes.md 4.5–4.7 条目(CanvasItem 线条无抗锯齿羽化、设备 ID 常量、RichTextLabel 图片参数两轮变化) | | **battle_presentation**(B5,垂直切片后) | 结算动画 / 伤害数字 / 战斗舞台 | (未设计——前置"战斗表现美术测试"锁双舞台陷阱) | B1 步骤流(回放脚本源)、D1 | **MEDIUM**:AnimationPlayer(String→StringName 变更)/ Tween | | **audio**(D4,Alpha) | 音频挂点 | (挂点 = B1 明细行类型流;负反馈聚合——单结算至多一次) | B1 流水 | AudioStreamPlayer(4.7 area_mask 默认 1→0 注意) | -| **tutorial**(D5,Alpha) | 教学条目 | (口径来源:A2/A3/A4/B3/B1 各教学条目) | 各上游 | 无 | +| **tutorial**(D5,Alpha) | 教学条目 | (口径来源:A2/A3/B3/B1 各教学条目) | 各上游 | 无 | **依赖单向性**:上层可消费下层,禁止反向(C3 禁调用 A1 生成、D1 不直调 A3、A2/B3/B4 零相互直调)。全项目唯一回边 = A2 事件订阅面。 @@ -191,7 +191,7 @@ D1 ◀──呈现数据源:A2 事件流 / B1 步骤流 / A3 ap-rap / ConfigDB | B1 ↔ A3 | 编排期代理 `request_refresh`(玩家意图,禁 RAP 满自动刷);回发 next_round_mode/battle_over | stopped/ap_exhausted 未刷新回发 new_board = 违约 fail-fast | 刷新受理契约(同 Waiting 多次合法) | | 各系统 → D2 | ConfigDB 类型化属性单点读取 | 禁绕过 ConfigDB load 表、禁缓存副本、禁玩法数值字面量、禁 randomize()/自建 RNG | 校验双通道 + fail-fast 致命 | | A1 → A2 | Board 产物 class_name 数据契约 | install 四不变式校验(violation = 拒绝 + 五类诊断枚举) | 生成期合法性闸(R₀≠S / clearable / min_safe) | -| A1 ↔ B1 | attempt 边界非 scope 事件;actuals p10 为对账输入(非 target 参数) | 编排不把重试当取号 | 八项指标输出(含 fog_burden_ratio) | +| A1 ↔ B1 | attempt 边界非 scope 事件;actuals p10 为对账输入(非 target 参数) | 编排不把重试当取号 | 生成期指标集输出(实测可推理率 / 实际雷数与安全格数 / 重试次数 / 降级与非法产物标记) | | B4 → B3 | buff 类经 B1 调 apply_effect(B4 零跨系统读、零直接接口) | 满层拒绝 = 零兑付 + 明细行(无折算) | 授予时数值快照(抗热重载) | | B1 → D1 | [步骤流行协议](../../design/gdd/systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)(15 类封闭枚举 + 公共字段 type/source_class/origin_cell/round_index/display_name/value/highlight? + 特有字段 target/effect_id/pool_value) | 无来源行 = 断言失败;呈现侧禁按行序重演 B2 状态机 | 可回放步骤流(同种子逐行相同) | diff --git a/docs/architecture/requirements-traceability.md b/docs/architecture/requirements-traceability.md index 2afaf459..624b9459 100644 --- a/docs/architecture/requirements-traceability.md +++ b/docs/architecture/requirements-traceability.md @@ -1,6 +1,6 @@ # Requirements Traceability Matrix — Dungeon Sweeper -> 生成:2026-09-12 · 源:`docs/architecture/architecture.md` §Technical Requirements Baseline(63 条)+ ADR-0001~0005 +> 生成:2026-09-12 · 源:`docs/architecture/architecture.md` §Technical Requirements Baseline(63 条)+ ADR-0001~0005 · 2026-09-15 雾格移除清理(a4-001/002 需求文本与载体同步现行文档) > 门检查口径:**Foundation 层零缺口** = 每条 Foundation TR 都有明确裁决载体(专项 ADR,或经 design-review 门禁的 Approved GDD 契约 + 本架构文档章节),无未决项。 > 状态图例:✅ 已覆盖 · 🔶 待 ADR(非 Foundation,随对应系统开工前裁决)· ⏳ 随未设计系统 @@ -32,7 +32,7 @@ | **d2-016** | 项目级静态扫描域 | **ADR-0004**(S1–S8) | | a3-001~003/005~008 | AP/RAP 账本、仲裁、相位机、refresh、表承载、last_round_end | A3 GDD(Approved)+ architecture.md | | **a3-004** | round_end 双发射源 | **ADR-0001**(round_end_board / round_end_stopped) | -| a4-001/002 | 变异框架 + 雾行跨字段校验 | A4 GDD(Approved) | +| a4-001/002 | 变异框架(原雾行跨字段校验已随雾格移除) | A4 GDD(Approved)+ 现行《地形变异》 | | a4-003/004 | 生成期布置执行归 A1 / 零特判 | A4 GDD + A1/A2 GDD | | b3-001~006 | 统一容器 / 时限量纲 / 五 API / 三分支 / 快照 / 不 clamp | B3 GDD(Approved) | diff --git a/docs/doc-conventions.md b/docs/doc-conventions.md index bad4f2db..71e34513 100644 --- a/docs/doc-conventions.md +++ b/docs/doc-conventions.md @@ -52,7 +52,7 @@ 文档、评审输出、日志与一切沟通中**禁止自造黑话**——比喻性生造词、只有作者自己懂的缩略语(历史反例:"非雾腿""双闸")。 - 只能使用:(a)人人可懂的直白语言,或(b)游戏行业通用术语(如 flood fill、战争迷雾、连锁展开、结算、增益/减伤)。 -- 需要指代新概念时,用直白的描述性短语(正例:"剔除雾格后的可推理率")。 +- 需要指代新概念时,用直白的描述性短语(正例:"实测可推理率"——限定语与规范名绑定)。 - 确需给新概念命名时:首次出现处必须附一句白话定义,并登记 `design/registry` 术语条目——不得让读者猜测比喻含义。 - 唯一例外:玩家在游戏里也会看到的专属名词(道具名、界面用语,如"显影尘""探巢摆钟")。文档内部的机制概念不得造词。 @@ -135,3 +135,4 @@ | v1 | 2026-09-14 | 首版成文:整合用语纪律、文档形态纪律、两件套与树形文档体系、新骨架过渡口径,新增可读性第一纪律与系统文档骨架 | | v2 | 2026-09-14 | 新增第 7 节引用纪律(跨文档高内聚低耦合:单点定义 / 规范名唯一 / 引用不转述 / 反向边登记 / 删除概念 SOP),原 7/8 节顺延为 8/9 | | v3 | 2026-09-15 | 命名纪律补充:现行文档代号清偿完毕,子系统统一以中文规范名指代;英文代号对照表落盘 `design/gdd/02-系统清单.md`,旧代号仅限解读归档 | +| v4 | 2026-09-15 | 用语纪律正例去雾:第 4 节正例"剔除雾格后的可推理率"改为现行指标"实测可推理率"(原指标随雾格移除已删);规则文字与历史反例"非雾腿"、第 8 节雾格移除去向说明均不动 | diff --git a/prototypes/dungeon-sweeper-vertical-slice/README.md b/prototypes/dungeon-sweeper-vertical-slice/README.md index bb6ae66d..248446e4 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/README.md +++ b/prototypes/dungeon-sweeper-vertical-slice/README.md @@ -163,7 +163,7 @@ Godot_v4.7.2-stable_win64_console.exe --headless --path . --script res://smoke/s - **奖励点随机主动道具的体感**:roll 池 = 小刀 8 / 精工短刀 16 / 治疗包 12(等权);到手的刀是否改变了 Boss 战规划(囤刀 vs 即用)。 - **恢复点(30% max_hp)时机**:位于战4 与 Boss 之间——是否制造"要不要省治疗包给 Boss"的决策。 - **Boss 战节拍**:遗迹守卫环 [attack,attack,charge,heavy]——蓄力拍是否被玩家用作"安全挖掘拍";重击 14 点是否构成规划压力。 -- 节点进度条/奖励恢复覆盖层可读性;v1 遗留观测项(结算逐行归因、雾池体感、完美排雷可达性)继续有效。 +- 节点进度条/奖励恢复覆盖层可读性;v1 遗留观测项(结算逐行归因、完美排雷可达性)继续有效(原"雾池体感"一项随雾格移除作废)。 ## 2026-09-11 用户拍板(四条,已落地本切片) @@ -250,18 +250,20 @@ Godot_v4.7.2-stable_win64_console.exe --headless --path . --script res://smoke/s **背景**:`design/ux/battle.md`(/ux-review APPROVED)+ `design/ux/interaction-patterns.md`(核心 8 pattern)落地到切片呈现层。**core/ 与 data/ 零改动**(本批纯 presentation/ + smoke/)。 -**五区布局**(1280×800 基座):A 区 28px 顶栏关卡进度条(`level_strip_view.gd` 改造:暗金已过/奖励金当前高亮);B 区 252px 战斗画面(`battle_stage_view.gd` 新建 = `hero_card_view.gd` + 轮次·阶段指示 + 兑现演出区 + `enemy_card_view.gd` ×1–3〔顺位徽标/意图徽标常驻/环点拍数/伏击共享池/死亡灰化+碎裂残位禁瞬消〕+ 底部结算明细带);C 区 240px `hero_info_panel_view.gd`(直角细线数据框 + 修正来源角标 + RAP 点阵 + `status_slot_row.gd` ×4〔形状+色相双通道/层数角标/剩余结算点/悬停 tooltip 来源+语义+剩余/空态槽隐藏〕);D 区 `board_zone_view.gd`(`ap_bar_view.gd` 44px〔AP 点阵+停手居左;图例+弃图刷新居右——确认 chips 异位 pattern 7〕+ `board_view.gd` 改造〔悬停三语义自绘光标/目标格边框/BFS 路径蓝点预览/可挖域 8 向呼吸微光/奖励徽章 R₀ 域外/已开雾格 tint 残留/雾区全开一次性信号/去饱和 shader〕+ `toast_stack.gd` 2.5s 消退 + `board_fx_view.gd` 演出层)+ `desaturation.gdshader`(去饱和+金橙偏移、明度不变);E 区 280px `inventory_panel_view.gd`(常读列表固定槽高 + 原位窗口态 pattern 2/8:描边金光/标题切换/时机指示/usable_now 禁选+原因/跳过/政策注记;属性简述投影、来源不呈现)。**旧 `hud_view.gd` 删除**(HUDView 职责由 B/C/D 三区视图承接)。 +**五区布局**(1280×800 基座):A 区 28px 顶栏关卡进度条(`level_strip_view.gd` 改造:暗金已过/奖励金当前高亮);B 区 252px 战斗画面(`battle_stage_view.gd` 新建 = `hero_card_view.gd` + 轮次·阶段指示 + 兑现演出区 + `enemy_card_view.gd` ×1–3〔顺位徽标/意图徽标常驻/环点拍数/伏击共享池/死亡灰化+碎裂残位禁瞬消〕+ 底部结算明细带);C 区 240px `hero_info_panel_view.gd`(直角细线数据框 + 修正来源角标 + RAP 点阵 + `status_slot_row.gd` ×4〔形状+色相双通道/层数角标/剩余结算点/悬停 tooltip 来源+语义+剩余/空态槽隐藏〕);D 区 `board_zone_view.gd`(`ap_bar_view.gd` 44px〔AP 点阵+停手居左;图例+弃图刷新居右——确认 chips 异位 pattern 7〕+ `board_view.gd` 改造〔悬停三语义自绘光标/目标格边框/BFS 路径蓝点预览/可挖域 8 向呼吸微光/奖励徽章 R₀ 域外/去饱和 shader〕+ `toast_stack.gd` 2.5s 消退 + `board_fx_view.gd` 演出层)+ `desaturation.gdshader`(去饱和+金橙偏移、明度不变);E 区 280px `inventory_panel_view.gd`(常读列表固定槽高 + 原位窗口态 pattern 2/8:描边金光/标题切换/时机指示/usable_now 禁选+原因/跳过/政策注记;属性简述投影、来源不呈现)。**旧 `hud_view.gd` 删除**(HUDView 职责由 B/C/D 三区视图承接)。 -**全屏 States 与模态**:`legend_overlay.gd`(图例,「迷雾 = 无雷盲区」恒在 + 状态槽空态说明)/ `settlement_review_overlay.gd`(明细回看)/ `battle_end_overlay.gd`(胜=金蜡封落于棋盘中央+判定行+回看入口;败=暮蓝 #5A6C8C+旗化光点收回)——统一模态登记序管理(`_open_modal` 打开时显式隐藏上方遮挡层,缺陷⑤纪律)。清图金粒喷泉+彩纸 / 完美排雷金光带+横幅 / 标中旗加重弹道 / Boss 紫赤影子爬棋盘 / 零合法板诚实 toast / 雾首遇·chord·非相邻一次性提示(每 run 去重,`ux_hint_shown` 遥测)。**发现并修复历史 quirk**:TunePanel 默认 `visible=true` 靠被不透明开始层遮蔽的树序巧合——已显式初始化 false(缺陷⑤家族)。 +**全屏 States 与模态**:`legend_overlay.gd`(图例,状态槽空态说明)/ `settlement_review_overlay.gd`(明细回看)/ `battle_end_overlay.gd`(胜=金蜡封落于棋盘中央+判定行+回看入口;败=暮蓝 #5A6C8C+旗化光点收回)——统一模态登记序管理(`_open_modal` 打开时显式隐藏上方遮挡层,缺陷⑤纪律)。清图金粒喷泉+彩纸 / 完美排雷金光带+横幅 / 标中旗加重弹道 / Boss 紫赤影子爬棋盘 / 零合法板诚实 toast / chord·非相邻一次性提示(每 run 去重,`ux_hint_shown` 遥测)。**发现并修复历史 quirk**:TunePanel 默认 `visible=true` 靠被不透明开始层遮蔽的树序巧合——已显式初始化 false(缺陷⑤家族)。 **遥测**(playtest_logger 增 ux 行族,呈现层观测不改 core):`ux_round_input_ratio`(原始输入:AP 消耗,快照驱动)/ `ux_round_exit{path_tag}`(快照 round_facts.path——呈现层只订 B1 的 ADR 纪律下唯一合法源)/ `ux_refresh_attempt{result, round_refresh_index}` / `ux_window_choice` / `ux_reject{source, sub_reason}` / `ux_hint_shown{hint_id}`。 -**探针**:ui_probe 增五区构建断言 + L2 雾图段(雾首遇提示/雾区连通分量);ui_click_probe 增刷新确认链/图例开关/tooltip 触发/模态遮挡断言(图例/回看/窗口态/终局)/窗口期去饱和断言/首格可点计时(进入战斗屏口径 133–151ms ≤500ms AC;场景冷启动 ~700ms 为脚本首载编译域,观测项)——既有全部断言保留。** Waiting 刷新代理已按 OQ12 退役**:UI 刷新按钮仅挖掘期 Active 受理(presenter 门禁),原探针"窗口期点刷新"行为由 Active 确认链测试替代。 +**探针**:ui_probe 增五区构建断言;ui_click_probe 增刷新确认链/图例开关/tooltip 触发/模态遮挡断言(图例/回看/窗口态/终局)/窗口期去饱和断言/首格可点计时(进入战斗屏口径 133–151ms ≤500ms AC;场景冷启动 ~700ms 为脚本首载编译域,观测项)——既有全部断言保留。** Waiting 刷新代理已按 OQ12 退役**:UI 刷新按钮仅挖掘期 Active 受理(presenter 门禁),原探针"窗口期点刷新"行为由 Active 确认链测试替代。 **回归**:smoke_all 149/149 · ui_probe PASS · ui_tune_probe PASS · ui_click_probe PASS(PROBE_SEED 7/11/23/99/42/77 六种子 done=true、选用失效=0、问题=0)。 **占位登记**:敌人意图视觉映射按 enemy_id 程序化占位(资产定稿归 B5);D区演出(喷泉/彩纸/弹道/影子)全部程序化占位;CJK 字体依赖系统回退(Windows 可用,随包字体归 D1 正式化硬性前置——ADR-0003);金蜡封/暮蓝氛围为色块占位级。 +**2026-09-15 补记(雾格移除)**:雾格机制已整体移除(见[不做清单](../../design/gdd/05-不做清单.md))——本节五区规格里的已开雾格 tint 残留、雾区全开一次性信号、图例「迷雾 = 无雷盲区」条目与雾首遇提示已随机制同批从实现与探针中删除(现行格态收窄为已开 / 未开两态,一次性提示只余 chord 与非相邻两项)。本文以上各历史批次条目保留当时陈述,现行实现与呈现义务以[战斗屏规格](../../design/ux/battle.md)与 [HUD框架](../../design/gdd/systems/表现与支撑/HUD框架.md)等现行文档为准。 + ## 2026-09-12 呈现层 code-review 修复批(/code-review CHANGES REQUIRED → 全项清偿) **触发**:全切片 53 脚本 ~9400 行 /code-review(CLAUDE.md 代码规范 + ADR-0001/0003/0004 对照),裁决 CHANGES REQUIRED(7 项必改)。core/ 12 文件与 smoke 断言面整体健康;病灶集中于 tune_panel 封装破口、main.gd 结构回涨、三处呈现契约错位。 @@ -304,7 +306,7 @@ Godot_v4.7.2-stable_win64_console.exe --headless --path . --script res://smoke/s **组织修复(P1/P2/P3)**: -- **O1/O2 调试模式抽离**:main.gd 调试分支(单场/连续两层/HP 携带/共享 B4)拆 `presentation/debug_session.gd`——调试语义单一实现点(O2 双实现漂移收口);组合根保留接线(battle_created 先于 begin_battle 发出,ADR-0001 接线唯一归组合根 + 缺陷①时序义务)与终局 UI 决策。ui_probe 抓获初版时序缺陷(battle_ready 才接手 b1 → 雾首遇提示丢失)——即缺陷①同款,battle_created 接手修复。 +- **O1/O2 调试模式抽离**:main.gd 调试分支(单场/连续两层/HP 携带/共享 B4)拆 `presentation/debug_session.gd`——调试语义单一实现点(O2 双实现漂移收口);组合根保留接线(battle_created 先于 begin_battle 发出,ADR-0001 接线唯一归组合根 + 缺陷①时序义务)与终局 UI 决策。ui_probe 抓获初版时序缺陷(battle_ready 才接手 b1)——即缺陷①同款,battle_created 接手修复。 - **O3 DamageMath 抽取**:B1 伤害公式族(F2 乘区/充能分量,零状态纯算术)拆 `core/damage_math.gd`(规范 1.2 工具函数挂宿主类);board_generator 同一合法板重复调用两次 measure_inferability 合并为一次(全库最贵求解器)。 - **P3 清债**:头注溯源补齐 ×4(board_data/config_db/rng_service/reward_supply_controller——规范 1.4);B4 grant/grant_clear/stock/use 失败返回统一 `false`→`null`(E6 消费方 `is Dictionary` 判定天然兼容);equivalence_supply 表行 duplicate 防配置源泄漏;load()→preload/类名直引 ×3(main logger/runner、tune_sim autoplay)。 diff --git a/prototypes/dungeon-sweeper-vertical-slice/core/battle_orchestrator.gd b/prototypes/dungeon-sweeper-vertical-slice/core/battle_orchestrator.gd index e4d7da38..0113bde0 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/core/battle_orchestrator.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/core/battle_orchestrator.gd @@ -147,7 +147,7 @@ func _install_new_board(during_round := false) -> bool: for c in board.safe_cells(): if r0.has(c): continue - eligible.append({"cell": c, "fog": board.variant_ids(c).size() > 0}) + eligible.append({"cell": c}) if not _reward_economy.roll_board(eligible): _fatal("奖励道具经济 roll_board 被拒") return false diff --git a/prototypes/dungeon-sweeper-vertical-slice/core/board_data.gd b/prototypes/dungeon-sweeper-vertical-slice/core/board_data.gd index 0e8d5d9d..59213586 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/core/board_data.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/core/board_data.gd @@ -86,14 +86,6 @@ func safe_cells() -> Array: return out -func fog_cells() -> Array: - var out: Array = [] - for c in all_cells(): - if not variants.get(c, []).is_empty(): - out.append(c) - return out - - # R₀ = 出生 3×3 ∪ (出生 3×3 经 0 格的 flood 闭包)——与 排雷玩法 F3 逐字同构(棋盘生成 F1 求解器初始态)。 func compute_r0() -> Array: var b3 := spawn_cells() @@ -109,15 +101,3 @@ func compute_r0() -> Array: r0[n] = true queue.append(n) return r0.keys() - - -# 棋盘生成 Rule 4 排除域(以最终产物板计):R₀ ∪ 外扩 1 环——生成期确定性计算。 -func exclusion_domain() -> Dictionary: - var r0 := compute_r0() - var dom := {} - for c in r0: - dom[c] = true - for c in r0: - for n in neighbors8(c): - dom[n] = true - return dom diff --git a/prototypes/dungeon-sweeper-vertical-slice/core/board_generator.gd b/prototypes/dungeon-sweeper-vertical-slice/core/board_generator.gd index b87e5010..327a9472 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/core/board_generator.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/core/board_generator.gd @@ -1,8 +1,8 @@ # VERTICAL SLICE - NOT FOR PRODUCTION # Validation Question: 玩家能否无指导在一场完整战斗中经历「开战→挖掘规划→轮末结算逐行兑现→胜/负」并逐行归因(P2) # Date: 2026-09-10 -# 确定性棋盘生成器:五阶段管线(参数→布雷→变异→验证循环→产出)+ F1 可推理率度量 -# (single_subset 求解器)+ F3 雾预算 + F5 验收算子(达标即出/接受最优/接受最不坏)。 +# 确定性棋盘生成器:五阶段管线(参数→布雷→变异布置→生成-验证→产出)+ F1 可推理率度量 +# (single_subset 求解器)+ F5 验收算子(达标即出/接受最优/接受最不坏)。 # 切片裁剪登记:黄金向量回归套件与 F4 批量工具不做(难度曲线与Boss 调参期工具域)。 # 实现 GDD:design/archive/gdd-2026-09-14/a1-board-generation.md(系统 ID A1·棋盘生成——registry 追溯锚,命名规范见 CLAUDE.md) class_name BoardGenerator @@ -28,8 +28,6 @@ func generate(L: int, D: int, rng_stream: RandomNumberGenerator, db) -> BoardDat "solver_rules": String(row.solver_rules), "min_safe": int(row.min_safe_count), "max_attempts": int(row.max_gen_attempts), - "fog_count": int(row.fog_region_count), - "fog_ratio": float(row.fog_target_ratio), "biomes": Array(row.board_biomes), } var best_legal: BoardData = null @@ -111,12 +109,11 @@ func _attempt(params: Dictionary, rng_stream: RandomNumberGenerator, db) -> Boar b.mines.erase(c) removed += 1 _compute_digits(b) - # ③ 变异布置(先雷后雾;排除域以最终产物板计) - var shortfall := _place_variants(b, params, rng_stream, db) + # ③ 变异布置(地形变异 框架面):布置约束与算法随首批变异类型定稿(生成期布置接口结构位), + # 定稿前零布置——清单为空是合法态(P0),静默产出无变异图。 b.metrics = { "metric_version": METRIC_VERSION, "ring_removed": removed, - "shortfall": shortfall, } return b @@ -132,99 +129,13 @@ func _compute_digits(b: BoardData) -> void: b.digits[c] = d -# 变异布置:候选池门控 + cell_constraint 生成期强制 + 排除域排除 + 厚度≤2;返回 shortfall -func _place_variants(b: BoardData, params: Dictionary, rng_stream: RandomNumberGenerator, db) -> int: - if params.fog_count <= 0 or params.fog_ratio <= 0.0: - return 0 - var pool: Array = db.variant_pool(params.L, params.biomes) - if pool.is_empty(): - return 0 # EC1 空池静默——合法非错误 - var exclusion := b.exclusion_domain() - var total_target := int(round(params.fog_ratio * float(params.w * params.h))) - var placed_total := 0 - var achieved := 0 - var placed := {} - for r in range(params.fog_count): - var region_target: int = total_target / params.fog_count - if r < total_target % params.fog_count: - region_target += 1 - if region_target <= 0: - achieved += 1 # 零目标区视为达成(不消耗布置) - continue - var region := _grow_region(b, region_target, exclusion, placed, rng_stream) - if region.is_empty(): - continue # EC2:无种子 → 该区布置失败(shortfall) - for c in region.keys(): - b.variants[c] = ["fog"] - placed[c] = true - placed_total += 1 - if region.size() >= region_target: - achieved += 1 - return params.fog_count - achieved - - -# 区域生长:随机种子 + 随机边界扩张(连通域);厚度≤2 = 任意 3×3 窗口非全雾 -func _grow_region(b: BoardData, target: int, exclusion: Dictionary, placed: Dictionary, rng_stream: RandomNumberGenerator) -> Dictionary: - var candidates: Array = [] - for c in b.all_cells(): - if _valid_fog_cell(b, c, exclusion, placed): - candidates.append(c) - if candidates.is_empty(): - return {} - var region := {} - var seed_c: Vector2i = candidates[rng_stream.randi_range(0, candidates.size() - 1)] - region[seed_c] = true - while region.size() < target: - var frontier: Array = [] - for c in region.keys(): - for n in b.neighbors8(c): - if not region.has(n) and not placed.has(n) and _valid_fog_cell(b, n, exclusion, placed) and not _breaks_thickness(region, n, b): - frontier.append(n) - if frontier.is_empty(): - break # 尽力布置——部分区域合法(shortfall 上报) - var pick: Vector2i = frontier[rng_stream.randi_range(0, frontier.size() - 1)] - region[pick] = true - return region - - -# cell_constraint=safe_nonzero 生成期强制:非雷、非 0(⟺ 8 邻含雷)、不在排除域 -func _valid_fog_cell(b: BoardData, c: Vector2i, exclusion: Dictionary, placed: Dictionary) -> bool: - if placed.has(c) or exclusion.has(c): - return false - if not b.is_safe(c): - return false - if b.digit_of(c) <= 0: - return false - return true - - -func _breaks_thickness(region: Dictionary, candidate: Vector2i, b: BoardData) -> bool: - # 加入 candidate 后是否出现全雾 3×3 窗口 - for dy in range(-1, 2): - for dx in range(-1, 2): - var origin := Vector2i(candidate.x + dx - 1, candidate.y + dy - 1) - var all_fog := true - for wy in range(3): - for wx in range(3): - var c := Vector2i(origin.x + wx, origin.y + wy) - var is_fog := (region.has(c) and c != candidate) or c == candidate - if not is_fog: - all_fog = false - if all_fog: - return true - return false - - # ==================== F1 可推理率度量(独立入口——与内嵌调用同一实现) ==================== -# 返回 {r0, r_inf, inferability, inferability_core} +# 返回 {r0, r_inf_count, inferability} func measure_inferability(b: BoardData) -> Dictionary: var safe_set := {} for c in b.safe_cells(): safe_set[c] = true - var fog_set := {} - for c in b.fog_cells(): - fog_set[c] = true var r := {} for c in b.compute_r0(): r[c] = true @@ -232,23 +143,15 @@ func measure_inferability(b: BoardData) -> Dictionary: var changed := true while changed: changed = false - # 算子① 连锁:0 格的 8 邻安全格全入 R(雾格可被链开但不传播——雾恒非 0,天然为叶) + # 算子① 连锁:0 格的 8 邻安全格全入 R var frontier: Array = r.keys() for x in frontier: - if safe_set.has(x) and not fog_set.has(x) and b.digit_of(x) == 0: + if safe_set.has(x) and b.digit_of(x) == 0: for n in b.neighbors8(x): if safe_set.has(n) and not r.has(n): r[n] = true changed = true - # 信息源(b)雾元知识:与 R 邻接的雾格必非雷 → 入 R - for f in fog_set.keys(): - if not r.has(f): - for n in b.neighbors8(f): - if r.has(n): - r[f] = true - changed = true - break - # 信息源(a)数字约束:single + subset(solver_rules=single_subset 冻结域) + # 信息源:数字约束 single + subset(solver_rules=single_subset 冻结域) var constraints := _build_constraints(b, r, known_mines, safe_set) # single 规则 for con in constraints: @@ -286,28 +189,19 @@ func measure_inferability(b: BoardData) -> Dictionary: changed = true var r_inf := r.keys() var s_count := safe_set.size() - var s_nonfog := 0 - var r_nonfog := 0 - for c in safe_set.keys(): - if not fog_set.has(c): - s_nonfog += 1 - if r.has(c): - r_nonfog += 1 var inferability: float = float(r_inf.size()) / float(maxi(1, s_count)) - var core: float = float(r_nonfog) / float(maxi(1, s_nonfog)) return { "r0": b.compute_r0().size(), "r_inf_count": r_inf.size(), "inferability": inferability, - "inferability_core": core, } func _build_constraints(b: BoardData, r: Dictionary, known_mines: Dictionary, safe_set: Dictionary) -> Array: var out: Array = [] for c in r.keys(): - if not safe_set.has(c) or b.variant_ids(c).size() > 0: - continue # 雾格数字不可见(hide_numbers)——零特判数据面:变体格不产约束 + if not safe_set.has(c): + continue # 只对已开安全格的数字建约束 var d := b.digit_of(c) var unknown := {} var known_here := 0 @@ -349,40 +243,6 @@ func _diff_constraint(big: Dictionary, small: Dictionary) -> Dictionary: return {"mines": big.mines - small.mines, "unknown": diff} -# ==================== F3 雾预算(独立入口) ==================== - -func measure_fog_budget(b: BoardData, dig_ap_cost: int) -> Dictionary: - var safe_set := {} - for c in b.safe_cells(): - safe_set[c] = true - # Chain₀ = R₀ 经算子①单独闭包 - var chain0 := {} - for c in b.compute_r0(): - chain0[c] = true - var queue: Array = chain0.keys() - while not queue.is_empty(): - var c: Vector2i = queue.pop_front() - if safe_set.has(c) and b.digit_of(c) == 0 and b.variant_ids(c).is_empty(): - for n in b.neighbors8(c): - if safe_set.has(n) and not chain0.has(n): - chain0[n] = true - queue.append(n) - var u_count := 0 - for c in b.fog_cells(): - if not chain0.has(c): - u_count += 1 - var pay := 0 - for c in safe_set.keys(): - if not chain0.has(c): - pay += 1 - return { - "chain0_count": chain0.size(), - "u_count": u_count, - "delta_budget_fog": u_count * dig_ap_cost, - "fog_burden_ratio": float(u_count) / float(maxi(1, pay)), - } - - # ==================== 合法性闸(独立入口;F5 legality + R₀≠S 修订义务) ==================== func is_clearable(b: BoardData) -> bool: @@ -438,18 +298,6 @@ func _legality_faults(b: BoardData, params: Dictionary) -> Array: var min_safe: int = int(params.get("min_safe", params.get("min_safe_count", 0))) if b.safe_cells().size() < min_safe: faults.append("min_safe_short") - # 雾结构:cell_constraint / 厚度 / f≤8d / 排除域 - var fog := b.fog_cells() - var exclusion := b.exclusion_domain() - for c in fog: - if b.is_mine(c) or b.digit_of(c) <= 0: - faults.append("fog_cell_constraint") - if exclusion.has(c): - faults.append("fog_in_exclusion") - if _has_all_fog_window(b, fog): - faults.append("fog_thickness") - if fog.size() > 8 * b.mines.size(): - faults.append("fog_over_8d") return faults @@ -461,49 +309,25 @@ func _neighbor_mine_count(b: BoardData, c: Vector2i) -> int: return d -func _has_all_fog_window(b: BoardData, fog: Array) -> bool: - var fog_set := {} - for c in fog: - fog_set[c] = true - for y in b.height: - for x in b.width: - var all_fog := true - for wy in range(3): - for wx in range(3): - var c := Vector2i(x + wx, y + wy) - if not b.in_bounds(c) or not fog_set.has(c): - all_fog = false - if all_fog: - return true - return false - - # ==================== 产出上报(生成期指标集) ==================== -func _finalize(b: BoardData, params: Dictionary, attempts_used: int, accept_mode: String, db) -> void: +func _finalize(b: BoardData, params: Dictionary, attempts_used: int, accept_mode: String, _db) -> void: var m := measure_inferability(b) - var fog_budget := measure_fog_budget(b, db.action_economy.dig_ap_cost) - var fog := b.fog_cells() # 产物断言(棋盘生成 出生区安全与反退化布雷):实际雷数 ≤ 目标雷数 N——先布后删只减不增,失败即致命 var n_target: int = int(round(float(params.density) * float(params.w * params.h - 9))) if b.mines.size() > n_target: _fatal("产物断言违例:实际雷数 %d > 目标雷数 N=%d(先布后删只减不增)" % [b.mines.size(), n_target]) - var attempt_facts := b.metrics # 保留尝试期事实(ring_removed / shortfall) + var attempt_facts := b.metrics # 保留尝试期事实(ring_removed) b.metrics = { "metric_version": METRIC_VERSION, "inferability": m.inferability, - "inferability_core": m.inferability_core, - "actual_fog_ratio": float(fog.size()) / float(b.width * b.height), "actual_mines": b.mines.size(), "target_mines": n_target, "actual_safe_count": b.safe_cells().size(), - "fog_burden_ratio": fog_budget.fog_burden_ratio, - "delta_budget_fog": fog_budget.delta_budget_fog, "attempts_used": attempts_used, "accept_mode": accept_mode, "degraded_product": accept_mode == "accept_best", "illegal_product": accept_mode == "accept_worst", - "shortfall": attempt_facts.get("shortfall", 0), "ring_removed": attempt_facts.get("ring_removed", 0), "r0_count": m["r0"], } diff --git a/prototypes/dungeon-sweeper-vertical-slice/core/config_db.gd b/prototypes/dungeon-sweeper-vertical-slice/core/config_db.gd index ba0b0cc8..f4a491cf 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/core/config_db.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/core/config_db.gd @@ -122,8 +122,7 @@ func _cross_validate(loaded: Dictionary) -> void: var eff: String = row.get("effect_id", "") if eff != "" and not effect_ids.has(eff): push_diag("error", "dangling_effect", "RewardTable %s 引用不存在的 effect_id: %s" % [row.get("reward_id"), eff]) - # ② 池空护栏:safe_cell × 雾/非雾两态各 ≥1 活行;活 buff 行集非空 - var t_fog: int = rc.t_fog_min + # ② 池空护栏:safe_cell 池须 ≥1 活行;活 buff 行集非空 var safe_rows: Array = [] var clear_rows: Array = [] for row in rt.rows: @@ -133,15 +132,8 @@ func _cross_validate(loaded: Dictionary) -> void: safe_rows.append(row) elif row.get("pool_tag", "") == "clear_default": clear_rows.append(row) - var nonfog_pool := safe_rows - var fog_pool: Array = [] - for row in safe_rows: - if int(row.get("tier", 0)) >= t_fog: - fog_pool.append(row) - if nonfog_pool.is_empty(): - push_diag("error", "pool_empty_safe", "safe_cell 非雾池无活行") - if fog_pool.is_empty(): - push_diag("error", "pool_empty_fog", "safe_cell 雾态池无活行(tier ≥ t_fog_min)") + if safe_rows.is_empty(): + push_diag("error", "pool_empty_safe", "safe_cell 池无活行") var has_buff := false for row in safe_rows: if row.get("category", "") == "buff": diff --git a/prototypes/dungeon-sweeper-vertical-slice/core/minesweeper_rules.gd b/prototypes/dungeon-sweeper-vertical-slice/core/minesweeper_rules.gd index 6acfdf79..d56f72e7 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/core/minesweeper_rules.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/core/minesweeper_rules.gd @@ -94,7 +94,7 @@ func install_board(b: BoardData, during_round := false) -> Dictionary: _spawn = {} for c in b.spawn_cells(): _spawn[c] = true - # 初始展开:O₀ = R₀ 恰等(免费/计入清图/无奖励/永不触雷触雾);板级一次跨轮不重放 + # 初始展开:O₀ = R₀ 恰等(免费/计入清图/无奖励/永不触雷);板级一次跨轮不重放 for c in _initial_expansion_order(b): _revealed[c] = {"kind": "safe", "digit": b.digit_of(c)} cell_revealed.emit({ @@ -157,7 +157,7 @@ func _initial_expansion_order(b: BoardData) -> Array: var queue: Array = order.duplicate() while not queue.is_empty(): var c: Vector2i = queue.pop_front() - if b.is_safe(c) and b.digit_of(c) == 0 and b.variant_ids(c).is_empty(): + if b.is_safe(c) and b.digit_of(c) == 0: for n in b.neighbors8(c): if b.is_safe(n) and not seen.has(n): seen[n] = true @@ -248,7 +248,7 @@ func _do_dig(c: Vector2i) -> Dictionary: # 资源面/相位 + cleared 仲裁在 行动经济 事务内原子完成 if not action_economy.request_dig(chain_size, clears): return _outcome(false, "rejected", "resource_face", "") - # 事务内执行:首格 + 连锁新格揭示(BFS 规范序,含链开雾格——零特判);事件 = O′ ∖ O + # 事务内执行:首格 + 连锁新格揭示(BFS 规范序,零特判);事件 = O′ ∖ O var reveal_order: Array = _chain_reveal_order(c, _flags) for rc in reveal_order: if _revealed.has(rc): @@ -290,7 +290,7 @@ func _chain_closure(start: Vector2i, flag_set: Dictionary) -> Dictionary: var queue: Array = [start] while not queue.is_empty(): var c: Vector2i = queue.pop_front() - if _board.is_safe(c) and not flag_set.has(c) and _board.digit_of(c) == 0 and _board.variant_ids(c).is_empty(): + if _board.is_safe(c) and not flag_set.has(c) and _board.digit_of(c) == 0: for n in _board.neighbors8(c): if _board.is_safe(n) and not flag_set.has(n) and not chain.has(n): chain[n] = true @@ -305,7 +305,7 @@ func _chain_reveal_order(start: Vector2i, flag_set: Dictionary) -> Array: var queue: Array = [start] while not queue.is_empty(): var c: Vector2i = queue.pop_front() - if _board.is_safe(c) and not flag_set.has(c) and _board.digit_of(c) == 0 and _board.variant_ids(c).is_empty(): + if _board.is_safe(c) and not flag_set.has(c) and _board.digit_of(c) == 0: for n in _board.neighbors8(c): if _board.is_safe(n) and not flag_set.has(n) and not seen.has(n): seen[n] = true diff --git a/prototypes/dungeon-sweeper-vertical-slice/core/reward_economy.gd b/prototypes/dungeon-sweeper-vertical-slice/core/reward_economy.gd index 9dc4f69f..789c811f 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/core/reward_economy.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/core/reward_economy.gd @@ -17,7 +17,7 @@ var rng var _supply: RewardSupplyController # 可选类供给状态机(组合件——战斗域计数) var _phase := "unrolled" # unrolled → ready → retired;clear_inventory 后 _inventory_cleared var _inventory_cleared := false -var _eligible: Array = [] # [{cell, fog}] 行主序规范序 +var _eligible: Array = [] # [{cell}] 行主序规范序 var _mapping := {} # Vector2i → reward_id var _power_roll := {} # Vector2i → 区间行 roll 值(伤害量值区间批——身份批内追加取号) var _clear_power := -1 # 清图槽区间行 roll 值(-1 = 定值行) @@ -59,7 +59,7 @@ func roll_board(eligible: Array) -> bool: push_warning("[奖励道具经济] 资格清单重复格已去重: %s" % str(c)) continue seen[c] = true - list.append({"cell": c, "fog": bool(e.get("fog", false))}) + list.append({"cell": c}) list.sort_custom(func(a, b): return a.cell.y * 1000 + a.cell.x < b.cell.y * 1000 + b.cell.x) _eligible = list _granted.clear() # 新批重置映射受理面(旧图快照消亡) @@ -71,19 +71,15 @@ func roll_board(eligible: Array) -> bool: var safe_rows: Array = _pool_rows("safe_cell") var clear_rows: Array = _pool_rows("clear_default") var inject_rows: Array = _pool_rows("active_inject") - # ① 身份批:每资格格恰一即时类身份(可选类已退出格子池——供给控制器批;雾档过滤不变) + # ① 身份批:每资格格恰一即时类身份(可选类已退出格子池——供给控制器批) var draft := {} for e in list: - var pool := safe_rows.filter(func(row): - if e.fog and int(row.tier) < int(db.reward_config.t_fog_min): - return false # F2 雾档过滤 - return true) - draft[e.cell] = weighted_pick(pool, stream.randi_range(0, _pool_weight(pool) - 1)) + draft[e.cell] = weighted_pick(safe_rows, stream.randi_range(0, _pool_weight(safe_rows) - 1)) # ② 清图槽:一次性高额伤害(当场兑付类——不入库、不占可选类供给;2026-09-11 用户拍板) var clear_rid := weighted_pick(clear_rows, stream.randi_range(0, _pool_weight(clear_rows) - 1)) # ③ 可选类供给注入(替代旧 F5 刀保底):首件保证 / p0×decay^(j-1) 指数递减——判定恰一取号 if _supply.should_inject(stream): - var target = list[stream.randi_range(0, list.size() - 1)] # 均匀随机(拍板③——雾格不加权) + var target = list[stream.randi_range(0, list.size() - 1)] # 均匀随机(拍板③) draft[target.cell] = weighted_pick(inject_rows, stream.randi_range(0, _pool_weight(inject_rows) - 1)) # ④ 伤害量值区间批(2026-09-14):身份定稿后逐格 roll power(区间行恰一取号,定值行零取号); # 授予期零随机纪律不变——快照 E14 口径,战斗结算/呈现零改动 diff --git a/prototypes/dungeon-sweeper-vertical-slice/data/schemas/board_gen_table.gd b/prototypes/dungeon-sweeper-vertical-slice/data/schemas/board_gen_table.gd index 12484743..107005fb 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/data/schemas/board_gen_table.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/data/schemas/board_gen_table.gd @@ -8,7 +8,6 @@ extends Resource @export var rows: Array = [] # Array[Dictionary] const SOLVER_RULES := ["single", "single_subset"] -const FOG_RATIO_ABS_CAP := 0.25 # 战斗结算 修订——雾占比绝对上限 const COST_BUDGET := 16384 # F2c provisional 量级护栏(禁墙钟逃生) const TARGET_ABS_FLOOR := 0.85 # 战斗结算 修订——target 域下限(P1 绝对锚) @@ -51,12 +50,6 @@ func validate() -> Array: var att: int = int(row.get("max_gen_attempts", 0)) if att < 1 or att > 32: errs.append({"category": "domain", "message": "(%d,%d) max_gen_attempts 越域 [1,32]" % [L, D]}) - var fc: int = int(row.get("fog_region_count", 0)) - var fr: float = float(row.get("fog_target_ratio", 0.0)) - # F2 规范合取形 + 雾占比绝对上限(战斗结算 修订) - var fog_ok := (fc == 0 and fr == 0.0) or (fc >= 1 and fr > 0.0 and fr <= minf(8.0 * d, FOG_RATIO_ABS_CAP) and fr < 1.0) - if not fog_ok: - errs.append({"category": "cross_field", "message": "(%d,%d) fog_domain_ok 违例(count=%d ratio=%.3f)" % [L, D, fc, fr]}) # 布雷数下限(R3)——零雷板拒绝 var n_mines := int(round(d * float(w * h - 9))) if n_mines < 1: diff --git a/prototypes/dungeon-sweeper-vertical-slice/data/schemas/reward_config_table.gd b/prototypes/dungeon-sweeper-vertical-slice/data/schemas/reward_config_table.gd index c2853235..0d0c81ce 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/data/schemas/reward_config_table.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/data/schemas/reward_config_table.gd @@ -5,7 +5,6 @@ class_name RewardConfigTable extends Resource -@export var t_fog_min: int = 2 # [1,8] F2 雾档过滤门限 @export var k_dmg: int = 0 # [0,999] 旧 F5 格池刀保底——2026-09-11 可选类供给控制器批置 0(语义由"战斗首件保证"取代) @export var n_draft: int = 32 # [1,999] 旧 F5 草稿重 roll 上限(随 k_dmg=0 休眠——字段保留) @export var p_min: int = 4 # [1,999] K≥1 供给闸刀力下界(随 k_dmg=0 休眠——字段保留) @@ -15,8 +14,6 @@ extends Resource func validate() -> Array: var errs: Array = [] - if t_fog_min < 1 or t_fog_min > 8: - errs.append({"category": "domain", "message": "t_fog_min 越域 [1,8]: %d" % t_fog_min}) if k_dmg < 0 or k_dmg > 999: errs.append({"category": "domain", "message": "k_dmg 越域 [0,999]: %d" % k_dmg}) if n_draft < 1 or n_draft > 999: diff --git a/prototypes/dungeon-sweeper-vertical-slice/data/schemas/variation_table.gd b/prototypes/dungeon-sweeper-vertical-slice/data/schemas/variation_table.gd index af512c15..8d2550e5 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/data/schemas/variation_table.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/data/schemas/variation_table.gd @@ -14,10 +14,8 @@ const CELL_CONSTRAINTS := ["any", "safe_nonzero"] func validate() -> Array: + # 空清单是合法状态(地形变异 P0)——零行即零变体格,配置加载零错误、零警告 var errs: Array = [] - if rows.is_empty(): - errs.append({"category": "empty_table", "message": "VariationTable 为空"}) - return errs var seen := {} for row in rows: var vid: String = row.get("variant_id", "") diff --git a/prototypes/dungeon-sweeper-vertical-slice/data/tables/board_gen.tres b/prototypes/dungeon-sweeper-vertical-slice/data/tables/board_gen.tres index 622cda3f..7de8bc21 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/data/tables/board_gen.tres +++ b/prototypes/dungeon-sweeper-vertical-slice/data/tables/board_gen.tres @@ -14,8 +14,6 @@ rows = [{ "solver_rules": "single_subset", "min_safe_count": 50, "max_gen_attempts": 16, -"fog_region_count": 0, -"fog_target_ratio": 0.0, "board_biomes": ["dungeon"] }, { "level_index": 1, @@ -27,8 +25,6 @@ rows = [{ "solver_rules": "single_subset", "min_safe_count": 50, "max_gen_attempts": 16, -"fog_region_count": 0, -"fog_target_ratio": 0.0, "board_biomes": ["dungeon"] }, { "level_index": 1, @@ -40,8 +36,6 @@ rows = [{ "solver_rules": "single_subset", "min_safe_count": 60, "max_gen_attempts": 24, -"fog_region_count": 0, -"fog_target_ratio": 0.0, "board_biomes": ["dungeon"] }, { "level_index": 1, @@ -53,8 +47,6 @@ rows = [{ "solver_rules": "single_subset", "min_safe_count": 60, "max_gen_attempts": 24, -"fog_region_count": 0, -"fog_target_ratio": 0.0, "board_biomes": ["dungeon"] }, { "level_index": 1, @@ -66,8 +58,6 @@ rows = [{ "solver_rules": "single_subset", "min_safe_count": 60, "max_gen_attempts": 24, -"fog_region_count": 0, -"fog_target_ratio": 0.0, "board_biomes": ["dungeon"] }, { "level_index": 2, @@ -79,16 +69,14 @@ rows = [{ "solver_rules": "single_subset", "min_safe_count": 60, "max_gen_attempts": 24, -"fog_region_count": 1, -"fog_target_ratio": 0.10, "board_biomes": ["dungeon"] }] ; 切片调参登记(SLICE-TUNED provisional,调参所有权仍归 C3): ; A1 GDD 参考行(d0.10/0.12)经"先布后删"环内移除后仅幸存 2-3 雷、R0/|S|约0.97、残余挖掘 2-4 格—— ; 掘近退化板(A2 反例 B 机制的低密度放大)。实验数据(8 种子均值,smoke/experiment_density.gd): -; d0.25 → L1 幸存雷 11/残余 13/inf 0.925/att 2.9 · L2 雷 19/残余 21/inf 0.908/att 7.9(seed42 实测 core 0.889→target 定 0.88 首过),零降级告警。 +; d0.25 → L1 幸存雷 11/残余 13/inf 0.925/att 2.9 · L2 雷 19/残余 21/inf 0.908/att 7.9(seed42 实测 inf 0.889→target 定 0.88 首过),零降级告警。 ; target 收窄至 0.88/0.88(不低于 0.85 绝对锚)为密度上移的对价——B1 条款③⑤对账重跑义务随调参触发。 -; 2026-09-11 关卡扩展批:L1 增 D1–D4 行(Boss=Dmax=4)。L1 全程无雾——A4 迷雾 unlock_level=2(已锁事实), +; 2026-09-11 关卡扩展批:L1 增 D1–D4 行(Boss=Dmax=4)。 ; Boss 板以 12×12 区分(d0.28/t0.87 实测达不到推理率门槛——best≈0.81 降级告警,回退 0.25/0.88; ; 密度轴上调留给 C3 与求解器能力一起解)。 diff --git a/prototypes/dungeon-sweeper-vertical-slice/data/tables/level.tres b/prototypes/dungeon-sweeper-vertical-slice/data/tables/level.tres index 72033ec8..28bae962 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/data/tables/level.tres +++ b/prototypes/dungeon-sweeper-vertical-slice/data/tables/level.tres @@ -34,4 +34,4 @@ rows = [{ ; 节点链 = 用户 2026-09-11 拍板的线性第一关(战×2 → 随机主动道具 → 战×2 → 血量恢复点 → Boss)。 ; node_depth 轴 = 节点深度(难度 = f(关卡序号, 节点深度)——game-concept 锁定口径);Boss = Dmax 行(A1 第三轴登记约定)。 ; rest_heal_pct = 30:恢复点回复 max_hp 的百分比(随生命天赋同步放大,防高生命档恢复失效)。 -; L1 全程无雾:A4 迷雾 unlock_level=2(已锁事实——迷雾自第二层解锁),Boss 板以 12×12 加密板区分。 +; Boss 板以 12×12 加密板区分。 diff --git a/prototypes/dungeon-sweeper-vertical-slice/data/tables/reward_config.tres b/prototypes/dungeon-sweeper-vertical-slice/data/tables/reward_config.tres index e0b0ab51..c4218246 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/data/tables/reward_config.tres +++ b/prototypes/dungeon-sweeper-vertical-slice/data/tables/reward_config.tres @@ -4,7 +4,6 @@ [resource] script = ExtResource("1") -t_fog_min = 2 k_dmg = 0 n_draft = 32 p_min = 8 diff --git a/prototypes/dungeon-sweeper-vertical-slice/data/tables/variation.tres b/prototypes/dungeon-sweeper-vertical-slice/data/tables/variation.tres index fc5819bd..ec475565 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/data/tables/variation.tres +++ b/prototypes/dungeon-sweeper-vertical-slice/data/tables/variation.tres @@ -4,13 +4,8 @@ [resource] script = ExtResource("1") -rows = [{ -"variant_id": "fog", -"display_name": "迷雾", -"unlock_level": 2, -"scope": "region", -"info_mask": "hide_numbers", -"cell_constraint": "safe_nonzero", -"biome_tags": [], -"counter_item_ids": [] -}] +rows = [] + +; 地形变异 清单为空是合法态(地形变异 P0):零变体行 → 棋盘生成零布置,行为与不存在本系统时一致。 +; 首批变异类型(岩浆/冰冻,机制未定)定稿时在本清单加一行声明即应生效,无需改代码。雾格已整体 +; 移除(见 design/gdd/05-不做清单.md)——本表不再有 fog 行。 diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/debug_session.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/debug_session.gd index 5d7ce125..81b005f1 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/debug_session.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/debug_session.gd @@ -37,7 +37,7 @@ func is_level_mode() -> bool: return _level_mode -# 单场遭遇原语(2026-09-13 用户裁决:单场用户入口已删——本方法仅 ui_probe 雾板变体段使用; +# 单场遭遇原语(2026-09-13 用户裁决:单场用户入口已删——本方法仅 ui_probe 单场段使用; # 无库存延续、standalone 终局语义保留供探针战斗收尾) func start_single(level: int) -> bool: _level_mode = false diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/main.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/main.gd index e0a3fdca..4c45220f 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/main.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/main.gd @@ -55,7 +55,7 @@ var tune_panel: TunePanel var _modals = null # 模态层级状态机(modal_stack.gd——缺陷⑤纪律载体) var _tune_sim = null # 调整板批量模拟控制器(tune_sim_controller.gd) -var _hints_shown := {} # 一次性非模态提示去重(每 run 一次:fog_first/chord/no_adjacent) +var _hints_shown := {} # 一次性非模态提示去重(每 run 一次:chord/no_adjacent) var _refresh_used_round := 0 # 本轮已受理刷新次数(遥测 round_refresh_index——每轮 round_started 归零) var _boss_active := false # Boss 遭遇变体(阶段指示附 Boss 名) var _window_payload: Array = [] # 窗口投影缓存(ux_window_choice 遥测读 usable_now/item_id) @@ -97,7 +97,6 @@ func _build_ui() -> void: board_zone.legend_toggled.connect(_on_legend_toggled) board_zone.hover_forbidden.connect(_on_hover_forbidden) board_zone.chord_attempted.connect(_on_chord_attempted) - board_zone.fog_region_completed.connect(_on_fog_region_completed) inventory_panel.item_selected.connect(_on_window_item_selected) inventory_panel.skipped.connect(_on_window_skipped) inventory_panel.reject_reason.connect(_on_inventory_reject) @@ -291,7 +290,7 @@ func _start_debug_levels() -> void: func _on_debug_battle_created(settlement_ref, _level: int, _carry: int) -> void: # begin_battle 前接手 + 接线(ADR-0001:signal.connect 唯一归组合根)。settlement 必须先于 begin_battle - # 就位——begin 期间发出的 board_changed 要用新板重建棋盘并触发雾首遇提示(缺陷①同款时序义务) + # 就位——begin 期间发出的 board_changed 要用新板重建棋盘并触发一次性提示(缺陷①同款时序义务) settlement = settlement_ref _wire_battle(settlement_ref) @@ -414,10 +413,6 @@ func _check_board_hints() -> void: # 接受最优降级(有合法板但无一达标)——降级标记独立于非法产物标记,同走诚实告知 elif board.degraded_product: board_zone.toast.show_toast("本板为接受最优降级产物(未达可推理率及格线)——数据面诚实告知", "warn") - # 雾首遇(每 run 一次;必含三要点:无雷盲区不赌命 / 雾格不传播连锁 / 雾内插旗纯损——地形变异 D1×②) - if not board.fog_cells().is_empty() and not _hints_shown.has("fog_first"): - _hints_shown["fog_first"] = true - _show_hint("迷雾=无雷盲区,不赌命开雾;雾格不传播连锁;雾内插旗纯损。", "fog_first") func _on_hover_forbidden(_cell: Vector2i) -> void: @@ -430,11 +425,6 @@ func _on_chord_attempted(_cell: Vector2i) -> void: _show_hint("本作无双击快开——插旗后轮末自动判定标中;点数字格可移动小人", "chord") -func _on_fog_region_completed(region_size: int) -> void: - # 雾区全开一次性完成信号(视觉合并域 = 连通分量,禁实例级双响——EC11) - board_zone.toast.show_toast("雾区已全开(%d 格)——迷雾域尽收眼底" % region_size, "gold") - - func _show_hint(text: String, hint_id: String) -> void: _hints_shown[hint_id] = true logger.log_ux("ux_hint_shown", {"hint_id": hint_id}) diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/board_view.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/board_view.gd index e01201ae..ddb91792 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/board_view.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/board_view.gd @@ -1,9 +1,9 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# 实现 GDD:design/ux/battle.md(战斗屏 D 区 BoardView——四格态/悬停预承诺光标/可挖域呼吸微光/ -# BFS 路径预览/奖励徽章/雾区全开一次性完成信号/结算期去饱和锁输入)。 +# 实现 GDD:design/ux/battle.md(战斗屏 D 区 BoardView——格态/悬停预承诺光标/可挖域呼吸微光/ +# BFS 路径预览/奖励徽章/结算期去饱和锁输入)。 # Date: 2026-09-12(battle.md 五区改造批;基础 = 2026-09-11 HUD框架-lite 版) -# 棋盘视图:格子渲染(art-bible 明亮风、数字高对比、雾形状+色相双通道、 -# 绘制优先级 数字>小人>旗>奖励徽章>变异纹带>底色)+ 玩家输入意图翻译 + 悬停预承诺三态。 +# 棋盘视图:格子渲染(art-bible 明亮风、数字高对比、 +# 绘制优先级 数字>小人>旗>奖励徽章>底色)+ 玩家输入意图翻译 + 悬停预承诺三态。 # 高内聚边界:只读 排雷玩法 查询面(+奖励道具经济 身份解析回调)做渲染与意图识别,动作经信号外发——不调用核心写接口 # (settle_batch 归组合根编排),不持久持有战斗态(minesweeper 引用随 refresh 更新,仅作只读查询)。 # 缺陷①回归约束:格子控件常驻、逐格重绘在 refresh 内完成,无布局回流(格控件/子标记定长,不增删)。 @@ -14,12 +14,9 @@ extends Control signal action_requested(cell: Vector2i, kind: String) # kind ∈ {dig, move, flag_place, flag_pull} signal hover_forbidden(cell: Vector2i) # 非相邻未开格悬停(首遇 toast 归组合根去重) signal chord_attempted(cell: Vector2i) # 双击快开尝试(chord 肌肉记忆提示锚) -signal fog_region_completed(region_size: int) # 雾区全开一次性信号(视觉合并域=连通分量,EC11) const COL_BRICK := Color8(201, 175, 131) # 未开——掩尘完整地砖(色板原语 #C9AF83) -const COL_BRICK_FOG := Color8(150, 136, 196) # 未开雾格——色相 + "雾"字双通道 const COL_FLOOR := Color8(179, 154, 120) # 已开——裸土 #B39A78(碎裂裸露地面) -const COL_FLOOR_FOG := Color8(216, 208, 234) # 已开雾格——底色层淡雾 tint 残留(OQ8 裁决;无字) const COL_DIGIT := Color8(51, 38, 27) # 数字——墨族 #33261B(对格底 ≥4.5:1 硬指标) const COL_HERO := Color8(46, 110, 142) # 小人边框——小人蓝 #2E6E8E const COL_FLAG := Color8(198, 61, 34) # 旗朱 #C63D22 @@ -48,8 +45,6 @@ var _breath_t := 0.0 var _dig_glow := false # 挖掘期才允许唯一在动元素(art-bible §2.1) var _hover := Vector2i(-9, -9) var _last_click := {"cell": Vector2i(-9, -9), "ms": -100000} -var _fog_done := {} # 本板已完成雾区连通分量(键 = 分量最小格) -var _fog_parts: Array = [] # 本板雾区连通分量(rebuild 期计算——合并呈现域) var _r0 := {} # 出生展开区 R₀(奖励道具经济 mapping 资格域 = S∖R₀——徽章查询跳过,防 E19 诊断噪音) var _desat_mat: ShaderMaterial var _desat_tween: Tween @@ -117,15 +112,12 @@ func rebuild(board: BoardData, minesweeper) -> void: _cells.clear() _cell_sb.clear() _marker.clear() - _fog_done.clear() - _fog_parts.clear() _r0.clear() _hover = Vector2i(-9, -9) for c in _board.compute_r0(): _r0[c] = true if _board == null: return - _compute_fog_parts() _grid.columns = _board.width for y in _board.height: for x in _board.width: @@ -155,7 +147,6 @@ func refresh() -> void: for y in _board.height: for x in _board.width: _paint_cell(Vector2i(x, y), hero) - _check_fog_completion() _refresh_hover_after_paint() @@ -296,14 +287,13 @@ func _badge_glyph(category: String) -> String: return BADGE_PLACEHOLDER -# ---- 四格态渲染(灰度截图可辨:完整覆尘/碎裂裸土/雾纹带/已开雾 tint) ---- +# ---- 格态渲染(灰度截图可辨:完整覆尘 / 碎裂裸土 / 已开数字) ---- func _paint_cell(c: Vector2i, hero: Vector2i) -> void: var btn: Button = _cells.get(c) if btn == null: return var revealed: bool = _minesweeper.is_revealed(c) - var fog: bool = _board.variant_ids(c).size() > 0 var flag: bool = _minesweeper.has_flag(c) var is_hero: bool = c == hero var text := "" @@ -315,8 +305,6 @@ func _paint_cell(c: Vector2i, hero: Vector2i) -> void: bg = COL_FLOOR text = "雷" digit_col = Color8(150, 44, 36) - elif fog: - bg = COL_FLOOR_FOG # 已开雾格 = 淡雾 tint 残留 + 无字(OQ8 裁决——与已开 0 格可判定区分) else: bg = COL_FLOOR var d: int = rec.get("digit", 0) @@ -327,10 +315,6 @@ func _paint_cell(c: Vector2i, hero: Vector2i) -> void: bg = COL_BRICK text = "旗" digit_col = COL_FLAG - elif fog: - bg = COL_BRICK_FOG - text = "雾" - digit_col = Color8(238, 232, 250) else: bg = COL_BRICK var sb := StyleBoxFlat.new() @@ -395,44 +379,6 @@ func _reset_breath() -> void: sb.border_color = sb.bg_color.darkened(0.15) -# ---- 雾区全开一次性完成信号(视觉合并域 = 连通分量;实例独立、呈现合并——EC11) ---- - -func _compute_fog_parts() -> void: - var seen := {} - for y in _board.height: - for x in _board.width: - var c := Vector2i(x, y) - if seen.has(c) or _board.variant_ids(c).is_empty(): - continue - var comp: Array = [] - var queue: Array = [c] - seen[c] = true - while not queue.is_empty(): - var cur: Vector2i = queue.pop_front() - comp.append(cur) - for n in _board.neighbors8(cur): - if not seen.has(n) and not _board.variant_ids(n).is_empty(): - seen[n] = true - queue.append(n) - comp.sort_custom(func(a, b): return a.y * 1000 + a.x < b.y * 1000 + b.x) - _fog_parts.append(comp) - - -func _check_fog_completion() -> void: - for comp in _fog_parts: - var key: Vector2i = comp[0] - if _fog_done.has(key): - continue - var all_open := true - for c in comp: - if not _minesweeper.is_revealed(c): - all_open = false - break - if all_open: - _fog_done[key] = true - fog_region_completed.emit(comp.size()) - - # ---- 子标记层(不参与命中测试) ---- func _build_markers(btn: Button) -> Dictionary: diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/board_zone_view.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/board_zone_view.gd index d1135cfd..38c24f99 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/board_zone_view.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/board_zone_view.gd @@ -17,7 +17,6 @@ signal refresh_confirmed signal legend_toggled signal hover_forbidden(cell: Vector2i) signal chord_attempted(cell: Vector2i) -signal fog_region_completed(region_size: int) func _init() -> void: @@ -43,7 +42,6 @@ func _init() -> void: board_view.action_requested.connect(func(c: Vector2i, kind: String): action_requested.emit(c, kind)) board_view.hover_forbidden.connect(func(c: Vector2i): hover_forbidden.emit(c)) board_view.chord_attempted.connect(func(c: Vector2i): chord_attempted.emit(c)) - board_view.fog_region_completed.connect(func(n: int): fog_region_completed.emit(n)) ap_bar.stop_pressed.connect(func(): stop_pressed.emit()) ap_bar.refresh_confirmed.connect(func(): refresh_confirmed.emit()) ap_bar.legend_toggled.connect(func(): legend_toggled.emit()) diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/legend_overlay.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/legend_overlay.gd index de26757f..05dbe9c7 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/legend_overlay.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/legend_overlay.gd @@ -1,6 +1,6 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# 实现 GDD:design/ux/battle.md(D 区图例按钮 + 模态 overlay——格态/变异/雾语义图例, -# 「迷雾 = 无雷盲区」条目恒在〔地形变异 D1×②〕;状态槽空态说明成文载入〔增益状态 D1×①〕)。 +# 实现 GDD:design/ux/battle.md(D 区图例按钮 + 模态 overlay——格态语义图例; +# 状态槽空态说明成文载入〔增益状态 D1×①〕)。 # Date: 2026-09-12 # pattern 6 模态 overlay 层级纪律:打开时由组合根隐藏上方遮挡层 + 锁棋盘输入; # 本类自持开关(toggle),探针断言"打开后自身 visible"——遮挡物断言归场景探针。 @@ -12,11 +12,9 @@ signal closed const ENTRIES := [ ["#C9AF83", "完整覆尘地砖", "未开格——左键挖开(1AP,须相邻)· 右键插旗(1AP)"], ["#B39A78", "碎裂裸土", "已开 0 格——可通行,左键移动(免费)"], - ["#9691C4", "雾纹带(色相+\"雾\"字)", "未开雾格——数字被迷雾遮蔽,雾=无雷盲区"], - ["#D8D0EA", "淡雾残留(无字)", "已开雾格——与已开 0 格同规则,雾不传播连锁"], - ["#C63D22", "旗", "插旗标记——轮末自动判定标中;雾内插旗纯损"], + ["#C63D22", "旗", "插旗标记——轮末自动判定标中"], ["#2E6E8E", "小人", "探险者——8 向相邻未开格常驻微光 = 可挖域"], - ["#F0A828", "金徽章", "已开格奖励身份 icon(旗之下、纹带之上,不进数字区)"], + ["#F0A828", "金徽章", "已开格奖励身份 icon(旗之下、数值之上,不进数字区)"], ["#33261B", "状态槽空态", "无状态效果时槽位隐藏,数据框上移补位——非异常"], ] @@ -40,9 +38,7 @@ func _init() -> void: box.custom_minimum_size = Vector2(520, 0) box.add_theme_constant_override("separation", 6) _panel.add_child(box) - box.add_child(UiKit.label("图例 · 格态与变异", 20, true)) - # 「迷雾 = 无雷盲区」条目恒在(地形变异 图例条目恒在义务) - box.add_child(UiKit.label("迷雾 = 无雷盲区:雾格不藏雷,不需要赌命开雾。", 14, true)) + box.add_child(UiKit.label("图例 · 格态", 20, true)) box.add_child(HSeparator.new()) for e in ENTRIES: var row := HBoxContainer.new() diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/toast_stack.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/toast_stack.gd index aade2a8d..8736fbee 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/toast_stack.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/toast_stack.gd @@ -1,5 +1,5 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# 实现 GDD:design/ux/battle.md(D 区 toast 槽——非模态提示:拒绝原因双源/voided/雾首遇/chord/ +# 实现 GDD:design/ux/battle.md(D 区 toast 槽——非模态提示:拒绝原因双源/voided/chord/ # 零合法板;自动消退 2.5s;pattern 1/10 呈现通道)。 # Date: 2026-09-12 # 高内聚边界:纯呈现——组合根决定何时弹什么文案;本类只管槽位堆叠与消退动画。 diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/dump_battle.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/dump_battle.gd index 2990369c..82bcf022 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/dump_battle.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/smoke/dump_battle.gd @@ -28,8 +28,8 @@ func _initialize() -> void: settlement.begin_battle({"level_index": level, "node_depth": 0, "hero_hp": db.hero.max_hp}) print("=== 棋盘摘要 L%d ===" % level) var bd = settlement.minesweeper.current_board() - print("尺寸 %dx%d · 雷 %d · 安全格 %d · 雾格 %d · R₀ %d" % [bd.width, bd.height, bd.mines.size(), bd.safe_cells().size(), bd.fog_cells().size(), bd.metrics.r0_count]) - print("指标: inferability=%.3f core=%.3f attempts=%s accept=%s" % [bd.metrics.inferability, bd.metrics.inferability_core, bd.metrics.attempts_used, bd.metrics.accept_mode]) + print("尺寸 %dx%d · 雷 %d · 安全格 %d · R₀ %d" % [bd.width, bd.height, bd.mines.size(), bd.safe_cells().size(), bd.metrics.r0_count]) + print("指标: inferability=%.3f attempts=%s accept=%s" % [bd.metrics.inferability, bd.metrics.attempts_used, bd.metrics.accept_mode]) var rounds := 0 while settlement.battle_result == "" and rounds < 40: rounds += 1 diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/experiment_density.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/experiment_density.gd index 4bad3ab5..78005d44 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/experiment_density.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/smoke/experiment_density.gd @@ -7,22 +7,20 @@ func _initialize() -> void: var db = load("res://core/config_db.gd").new() db.load_tables("res://data/tables", true) var board_generator = load("res://core/board_generator.gd").new() - print("=== 密度实验(L1 10×10 target0.95 / L2 12×12 雾 target0.92,各 5 种子)===") - print("d\t|M|/N\tR₀\tR₀/|S|\t残余挖掘\tinf\tcore\tatt") + print("=== 密度实验(L1 10×10 target0.88 / L2 12×12 target0.90,各 8 种子)===") + print("d\t|M|/N\tR₀\tR₀/|S|\t残余挖掘\tinf\tatt") for d in [0.22, 0.25, 0.28, 0.30, 0.33]: - for cfg in [[10, 10, 0, 0.88, 50], [12, 12, 1, 0.90, 60]]: + for cfg in [[10, 10, 0.88, 50], [12, 12, 0.90, 60]]: var w: int = cfg[0] var h: int = cfg[1] - var fc: int = cfg[2] - var t: float = cfg[3] - var ms: int = cfg[4] - var agg := {"m": 0, "r0": 0, "rem": 0, "inf": 0.0, "core": 0.0, "att": 0, "n": 0} + var t: float = cfg[2] + var ms: int = cfg[3] + var agg := {"m": 0, "r0": 0, "rem": 0, "inf": 0.0, "att": 0, "n": 0} for s in range(8): var row := { "level_index": 1, "node_depth": 0, "board_width": w, "board_height": h, "mine_density": d, "inferability_target": t, "solver_rules": "single_subset", "min_safe_count": ms, "max_gen_attempts": 16, - "fog_region_count": fc, "fog_target_ratio": 0.10 if fc > 0 else 0.0, "board_biomes": ["dungeon"], } _patch_row(row, d) @@ -36,13 +34,12 @@ func _initialize() -> void: agg.r0 += int(b.metrics.r0_count) agg.rem += b.safe_cells().size() - int(b.metrics.r0_count) agg.inf += float(b.metrics.inferability) - agg.core += float(b.metrics.inferability_core) agg.att += int(b.metrics.attempts_used) agg.n += 1 if agg.n > 0: var n := float(agg.n) var n_placed: int = int(round(d * float(w * h - 9))) - print("%.2f %dx%d f%d\t%d/%d\t%d\t%.2f\t%d\t%.3f\t%.3f\t%.1f" % [d, w, h, fc, int(agg.m / n + 0.5), n_placed, int(agg.r0 / n + 0.5), agg.r0 / n / (w * h - int(agg.m / n + 0.5)), int(agg.rem / n + 0.5), agg.inf / n, agg.core / n, agg.att / n]) + print("%.2f %dx%d\t%d/%d\t%d\t%.2f\t%d\t%.3f\t%.1f" % [d, w, h, int(agg.m / n + 0.5), n_placed, int(agg.r0 / n + 0.5), agg.r0 / n / (w * h - int(agg.m / n + 0.5)), int(agg.rem / n + 0.5), agg.inf / n, agg.att / n]) quit(0) # --- 简易 db 替身:只供给本实验的行 --- @@ -56,17 +53,13 @@ func _params_from(row: Dictionary) -> Dictionary: "L": 1, "D": 0, "w": int(row.board_width), "h": int(row.board_height), "density": float(row.mine_density), "target": float(row.inferability_target), "solver_rules": "single_subset", "min_safe": int(row.min_safe_count), - "max_attempts": int(row.max_gen_attempts), "fog_count": int(row.fog_region_count), - "fog_ratio": float(row.fog_target_ratio), "biomes": ["dungeon"], + "max_attempts": int(row.max_gen_attempts), "biomes": ["dungeon"], } class FakeDB: var row: Dictionary func resolve_board_gen(_L: int, _D: int) -> Dictionary: return row - func variant_pool(_L: int, _b: Array) -> Array: - return [{"variant_id": "fog", "unlock_level": 1, "scope": "region", "info_mask": "hide_numbers", "cell_constraint": "safe_nonzero", "biome_tags": [], "counter_item_ids": []}] - var action_economy := {"dig_ap_cost": 1} func status_effect_row(_id: String) -> Dictionary: return {} diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/reward_expectation.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/reward_expectation.gd index 541e5bb4..66d3aead 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/reward_expectation.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/smoke/reward_expectation.gd @@ -42,7 +42,7 @@ func _initialize() -> void: var reward_economy = reward_economy_factory.new(db, rng) var list: Array = [] for c in eligible: - list.append({"cell": c, "fog": board.variant_ids(c).size() > 0}) + list.append({"cell": c}) if not reward_economy.roll_board(list): continue var n_active := 0 diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/smoke_all.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/smoke_all.gd index 74d0bf2d..5e6313e5 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/smoke_all.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/smoke/smoke_all.gd @@ -63,8 +63,9 @@ func _run_core_smoke(db, rng) -> void: _rng = rng _smoke_wall_zero_guard() _smoke_board_generator() - _smoke_full_battle(1, 0, "L1 · grub(无雾)") - _smoke_full_battle(2, 0, "L2 · ambusher(雾图)") + _smoke_variation_framework() + _smoke_full_battle(1, 0, "L1 · grub") + _smoke_full_battle(2, 0, "L2 · ambusher") _smoke_level() _smoke_flag_ap_exhausted() _smoke_supply() @@ -87,10 +88,10 @@ func _smoke_supply() -> void: var rng = load("res://core/rng_service.gd").new() rng.set_master_seed(20260911) var reward_economy_factory = load("res://core/reward_economy.gd") - # 合成资格清单:6 格含 1 雾格(fog=true) + # 合成资格清单:6 格 var eligible: Array = [] for i in range(6): - eligible.append({"cell": Vector2i(i, 0), "fog": i == 0}) + eligible.append({"cell": Vector2i(i, 0)}) # ① 首件保证 + 每板恰 1 注入 + 注入占比(j=0 恒注入;种子固定 → 分布确定,宽容差断言) var reward_economy = reward_economy_factory.new(_db, rng) var ok_roll: bool = reward_economy.roll_board(eligible) @@ -260,13 +261,13 @@ func _smoke_board_generator() -> void: check(board_generator.legality(b1, row, _db), "L%d legality 全过" % L) var inf := float(b1.metrics.get("inferability", 0.0)) var mode := String(b1.metrics.get("accept_mode", "")) - print(" L%d 实测:inferability=%.3f / inferability_core=%.3f / attempts_used=%d / accept_mode=%s / target=%.2f" % [ - L, inf, float(b1.metrics.get("inferability_core", 0.0)), int(b1.metrics.get("attempts_used", -1)), mode, float(row.inferability_target)]) + print(" L%d 实测:inferability=%.3f / attempts_used=%d / accept_mode=%s / target=%.2f" % [ + L, inf, int(b1.metrics.get("attempts_used", -1)), mode, float(row.inferability_target)]) # 出图验收(棋盘生成 登记口径):first_pass 必须 ≥ target;accept_best(重试耗尽接受最优)允许低于 target # 但必须打印实测值(正常出口);accept_worst 由下方 illegal_product 断言承担。 check(inf >= float(row.inferability_target) or mode == "accept_best", "L%d inferability %.3f %s target %.2f(accept_mode=%s)" % [L, inf, "≥" if inf >= float(row.inferability_target) else "<", float(row.inferability_target), mode]) - check(b1.metrics.has("inferability_core"), "L%d 指标集输出 inferability_core(单一判据下仅作观测,不参与门槛)" % L) + check(b1.variants.is_empty(), "L%d 零变体格(地形变异 清单为空 → 生成期零布置)" % L) check(b1.metrics.has("degraded_product") and b1.metrics.has("target_mines"), "L%d 指标集输出降级标记与目标雷数(三分出口表)" % L) check(b1.degraded_product == (mode == "accept_best"), "L%d 降级产物标记 = (accept_mode==accept_best)(%s→%s)" % [L, mode, str(b1.degraded_product)]) check(b1.illegal_product == (mode == "accept_worst"), "L%d 非法产物标记 = (accept_mode==accept_worst)(%s→%s)" % [L, mode, str(b1.illegal_product)]) @@ -288,6 +289,15 @@ func _mk_stream(stream_name: String, scope: int) -> RandomNumberGenerator: return rg +# ---- 地形变异 框架面(P0 空清单合法 + 候选池门控通道在位——框架惰性非废弃)---- + +func _smoke_variation_framework() -> void: + print("--- 地形变异 框架面(空清单合法 + 候选池门控通道)---") + check(_db.variation.rows.is_empty(), "变异清单为空(P0 合法态——零变体格)") + check(_db.variant_pool(1, ["dungeon"]).is_empty(), "候选池为空——棋盘生成静默产出无变异图(不报错、不警告)") + check(_db.variation.row_by_id("nonexistent").is_empty(), "清单外 variant_id 返回空(读取通道在位)") + + func _board_dump(b) -> String: var parts: Array = [str(b.width), str(b.height), str(b.spawn_center)] for y in b.height: @@ -427,7 +437,7 @@ func _smoke_power_interval() -> void: var reward_economy_factory = load("res://core/reward_economy.gd") var eligible: Array = [] for i in range(6): - eligible.append({"cell": Vector2i(i, 0), "fog": false}) + eligible.append({"cell": Vector2i(i, 0)}) var seen := {"heal_minor": {}, "knife_t1": {}, "heal_pack": {}, "knife_adv": {}, "clear_blast": {}} # rid → {roll 值集} var in_domain := true var fixed_ok := true diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_click_probe.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_click_probe.gd index ed0feb8a..c14b2493 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_click_probe.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_click_probe.gd @@ -122,8 +122,12 @@ func _run_modal_probes_once() -> void: _problems.append("图例打开时上方遮挡层未隐藏(缺陷⑤复发)") if not main._input_locked(): _problems.append("图例打开时棋盘输入未锁定") - if not main.legend_overlay.ENTRIES[2][2].contains("无雷盲区"): - _problems.append("图例缺『迷雾 = 无雷盲区』恒在条目") + var legend_has_flag := false + for e in main.legend_overlay.ENTRIES: + if String(e[1]) == "旗": + legend_has_flag = true + if not legend_has_flag: + _problems.append("图例缺『旗』格态条目(格态图例基线)") main.legend_overlay.close() if main.legend_overlay.is_open() or main._input_locked(): _problems.append("图例关闭后未恢复输入/可见性") diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_probe.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_probe.gd index d487dd52..d1b047aa 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_probe.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_probe.gd @@ -97,24 +97,17 @@ func _ready() -> void: if ic_off.text == "?" or ic_off.text == "": problems.append("失衡图标键未映射(icon=%s)" % ic_off.text) slots_row.set_effects([]) - # ---- L2 雾图变体段(地形变异:雾首遇一次性提示 / 雾格呈现 / 去饱和接口可用性)---- + # ---- L2 单场段(debug_session 单场原语 + 去饱和接口可用性;雾格机制已整体移除,不再断言变体呈现)---- # 2026-09-13 单场用户入口已删——探针直调 debug_session 原语(battle_created/ready 仍经组合根接线; - # _reset_run_scope 复现原 _start_single 的提示去重复位,保证 fog_first 断言前置态) + # _reset_run_scope 复现原 _start_single 的提示去重复位) main._reset_run_scope() main._debug.start_single(2) await get_tree().process_frame await get_tree().process_frame if main.board_view.board() == null: problems.append("L2 单场未启动(board=null)") - elif main.board_view.board().fog_cells().is_empty(): - problems.append("L2 板无雾格(地形变异 变体缺失)") - elif not bool(main._hints_shown.get("fog_first", false)): - problems.append("雾首遇一次性提示未触发(fog_first)") - else: - if main.board_zone.toast._slot_box.get_child_count() < 1: - problems.append("雾首遇 toast 未呈现") - if main.board_view._fog_parts.is_empty(): - problems.append("雾区连通分量未计算(合并呈现域)") + elif not main.board_view.board().variants.is_empty(): + problems.append("L2 板出现变体格(地形变异 清单为空 → 零布置)") main.board_view.set_desaturated(true) main.board_view.set_desaturated(false) if problems.is_empty(): diff --git a/tests/README.md b/tests/README.md index 0822321a..1c0599c9 100644 --- a/tests/README.md +++ b/tests/README.md @@ -43,7 +43,7 @@ timeout 120s godot --headless --script tests/run_all.gd - **Files**: `[system]_[feature]_test.gd`(领域命名,禁 ID 前缀——docs/code-conventions.md) - **Functions**: `test_[scenario]_[expected]` -- **Example**: `reward_roll_test.gd` → `test_fog_cell_filters_below_tier_min()` +- **Example**: `reward_roll_test.gd` → `test_power_interval_rolls_within_bounds()` ## Story Type → Test Evidence