diff --git a/AGENTS.md b/AGENTS.md index 7625154c..84dfeef5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -62,6 +62,7 @@ - 闸机轮次纪律:新码先孤立验证 → 出红只跑红件最小单元 → 长批先最小参数试车 → 开工扫坑册(process-conventions §6) - 变异验证——新增/改写验收函数必须变异变红才算验收成立;无变异红记录只写「已实现,拦截能力未证」(test-conventions §6) - 中间产物吸收即死——结论先吸收进权威文档、未决先迁 06,文件即删且永不提交(doc-conventions 第 11 节) +- **禁写变更记录**——文档与代码文件内一律禁设「版本历史/修订记录/变更记录/修改记录/更新记录/更新日志」节或表格,禁写「本版改了哪些条款」式逐版本叙述与 `# 2026-xx-xx 缺陷修批——` 式行内修订注记;沿革只进 git commit log。版本号可作文档现行身份标记留在文首状态行与正文引用中(doc-conventions 第 5 节,机检闸 gdd_lint R4 反转拦截) - 用语红线——一切对用户输出禁自造黑话,需要作者解释的词必须展开成完整白话句(doc-conventions 第 4 节三形态表) - 呈报六问——What 现状差异 / Why 动机与不做代价 / How 方案与全部备选 / Where 影响面 / 验收判据 / 不确定点单列收尾;Who/When 不进正文;仅首次描述需求/bug/方案适用 - 真人检测只登记不阻塞——登记进 07 清单/实现报告即完成义务,禁以等目检为停工理由或收口前置 diff --git a/design/art/art-assets-checklist.md b/design/art/art-assets-checklist.md index d8637a26..fb18c2f6 100644 --- a/design/art/art-assets-checklist.md +++ b/design/art/art-assets-checklist.md @@ -1,7 +1,7 @@ # 美术资源依赖清单(Art Assets Checklist) > **性质**:表现层升级批与战斗表现批的生产侧清单——把散在战斗表现 / HUD框架 / 关卡节点地图 / 敌人系统里的资产需求收拢成一张可执行的工单视图,**兼资产维度单一登记处**。**规范效力归各 owner 文档**(战斗表现、美术圣经、04-美术音频方向),本文只补「生产视角的需求规格」,冲突时以 owner 文档为准。 -> **建立**:2026-09-18 场景一(战斗画面呈现)讨论产物。**2026-09-22 GDD 过期账清偿批**:原 asset-checklist.md 并入本文后删除,本文自此为两份清单合并后的唯一清单;同批修正敌人键集/徽章数量/样张状态等过期事实(详见 art-bible 版本历史 v1.3)。**2026-09-22 §5 角色设计落地批**:剪影引用迁 art-bible §5.1、护甲区分方案落 §5.3(清偿两处待设计项)、提示词卡 v2.0 重生成(详见 art-bible 版本历史 v1.6)。**2026-09-23 复用盘点批**:立素材站复用渠道与复用闸(§0);新增 §3.4–3.6 三条此前漏登记的需求(增益状态效果图标 / 营地与元进度件 / 字体);各条目标注来源渠道。**2026-09-23 §5 抽离批**:角色设计内容迁独立文档 `character-design.md`(art-bible §5 自此为引用存根,小节号不变),本文 §5.x 剪影/护甲引用经存根仍可达;主角特征批(直剑→挖掘铲、加旗朱背旗)顺带,主角形象锚见 character-design.md §5.4。**2026-09-23 §6–9 补全批**:art-bible 四章成文(§6 环境/§7 UI/§8 资产规范/§9 参考与反参考);本文 §0 交付格式与像素尺寸行、参考图行、§6 依赖链顺带改指 §8/§9 现行。 +> **建立**:2026-09-18 场景一(战斗画面呈现)讨论产物。**2026-09-22 GDD 过期账清偿批**:原 asset-checklist.md 并入本文后删除,本文自此为两份清单合并后的唯一清单;同批修正敌人键集/徽章数量/样张状态等过期事实(详见 art-bible 的 git 提交史)。**2026-09-22 §5 角色设计落地批**:剪影引用迁 art-bible §5.1、护甲区分方案落 §5.3(清偿两处待设计项)、提示词卡 v2.0 重生成(详见 art-bible 的 git 提交史)。**2026-09-23 复用盘点批**:立素材站复用渠道与复用闸(§0);新增 §3.4–3.6 三条此前漏登记的需求(增益状态效果图标 / 营地与元进度件 / 字体);各条目标注来源渠道。**2026-09-23 §5 抽离批**:角色设计内容迁独立文档 `character-design.md`(art-bible §5 自此为引用存根,小节号不变),本文 §5.x 剪影/护甲引用经存根仍可达;主角特征批(直剑→挖掘铲、加旗朱背旗)顺带,主角形象锚见 character-design.md §5.4。**2026-09-23 §6–9 补全批**:art-bible 四章成文(§6 环境/§7 UI/§8 资产规范/§9 参考与反参考);本文 §0 交付格式与像素尺寸行、参考图行、§6 依赖链顺带改指 §8/§9 现行。 > **更新纪律**:各条目「现状」行顺带更新(未开始 / 候选已出 / 已裁决 / 已交付);做完不删条目,改状态。与 06-待办清单的联动:本文是资产维度明细,06 只留指路存根。 ## 0. 生产渠道、规格与风格宪法 @@ -199,9 +199,3 @@ ### 复用四闸(状态记录 130,现行) 色板量化 / 禁入带吸色 / 灰度可辨 / 授权干净(SA 不可、来路不明不可)。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-10-10 | 补建版本表(本文件此前无版本表)+首笔登记:§3.5 柜台场景贴图括注「道具工坊」改「秘宝匣」(2026-10-10 天赋树设计会话裁) | diff --git a/design/art/art-bible.md b/design/art/art-bible.md index de129b82..c402355c 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–9 节定稿**(§6 环境/§7 UI/§8 资产规范/§9 参考与反参考已于 2026-09-23 v1.8 按 D1/D2/D4/D5 框架成文;D3=§5 角色已于 v1.6 落地、v1.7 抽离独立文档;框架 2026-09-22 用户拍板,原登记于中间产物修订指导,经裁决不入库,明细归状态记录 125);历次修订明细见文末版本历史(现行为 v3.15) +> 项目:Dungeon Sweeper(扫雷 × 自动战斗 闯关 Roguelike)· 状态:**第 1–9 节定稿**(§6 环境/§7 UI/§8 资产规范/§9 参考与反参考已于 2026-09-23 v1.8 按 D1/D2/D4/D5 框架成文;D3=§5 角色已于 v1.6 落地、v1.7 抽离独立文档;框架 2026-09-22 用户拍板,原登记于中间产物修订指导,经裁决不入库,明细归状态记录 125);现行为 v3.15,历次修订明细见 git 提交史 > > **Art Director Sign-Off (AD-ART-BIBLE)**:历次批均 SKIPPED(v1.8 §6–9 补全亦 SKIPPED)— Lean/Solo mode(非 PHASE-GATE;§6–9 已成文,full 门禁签核时机待用户表态) > 风格基调(2026-09-10 用户定稿):地牢题材但**非暗黑风**——轻快明亮的幻想冒险风,全年龄;像素风;角色 2~3 头身 @@ -42,9 +42,7 @@ *设计测试:当新图类型或新变异格需要新视觉时,先换色板加形状,再谈新资产;当格子多样化与"好看/有雷"之辨冲突时,砍装饰,不动逻辑通道。* -### 1.3 修订记录(已迁出) -早期"对 brainstorm 视觉锚的修订记录"整节并入文末**版本历史**(v1.0/v1.1/v1.2/v1.3 条目承载);本节留号占位,正文只描述现行规则(状态记录 109 纪律)。 ### 1.4 格子样张测试(验收标准,2026-09-13 成文) @@ -165,7 +163,7 @@ - **地砖**:一切环境体由同一圆角方形衍生:未开=完整凸砖,已开=同形缺角碎裂,雷=碎裂加巢穴纹(危险格玩家说法见《排雷玩法》);只以"完整度"叙事,不为状态新造形。←原三;P4 - **装饰变体(未开格氛围层)**:覆尘完整砖之上叠加裂纹/碎石斑/物件级点缀等装饰;2026-09-29 v3.0 物件级解禁——物件级装饰(小石块/陶片/骨殖等)须走**专属装饰形状家族**(与信息元素形状语言隔离、灰度下不与任何逻辑元素同形),数量配额按图类型定(候选 3–5 种,样张 v3 冻结),一律残缺、内凹、低对比而自然后退(§3.4);零信息纪律(分布随机、与雷/安/类型零相关、灰度下禁止制造新分类特征、分布每板一次跨轮不复掷)以原则三为准,此处不赘。←原三 - **结果整格表达(已开格)**:已开格按当格结果整格表达(结果清单见原则三);画法——产资源格的家族物件纹样用 §3.1 道具点剪影语言(直线几何体)角嵌于砖缘,砖心与数字字形占位区留白(已开格仍承载数字);危险格巢穴纹较已开格更凶一档,形状+颜色双通道不变。←原三;P3 -- **未开格预读通道(微光单通道)**:类型预读 = 类型微光单通道(色相+明度双码,色带 §4.2);色弱类型主通道 = 微光明度梯度(组粒度——组间互辨;§2 微光明度例外);格内零角嵌/箭头/加号类附加形(2026-09-28 用户裁「微光格只留微光」,退役史见版本历史 v2.12)。←原一;原三 +- **未开格预读通道(微光单通道)**:类型预读 = 类型微光单通道(色相+明度双码,色带 §4.2);色弱类型主通道 = 微光明度梯度(组粒度——组间互辨;§2 微光明度例外);格内零角嵌/箭头/加号类附加形(2026-09-28 用户裁「微光格只留微光」,退役史见 git 提交史)。←原一;原三 - **旗(封印印记)**:插旗动作的叙事呈现 = **封印**(玩家可见专名,术语定义见 [术语表](../gdd/术语表.md)「封印」条;插旗动作面见《排雷玩法》)——旗 = 封印印记;封印色(§4.1,现行封印黑)与格内优先级栈位(§1.2)不变。封印特效(施印瞬间 + 印记常显形态)资产归清单 §4 演出类;旗印记纹理已落位、字形占位退役(迭代 9 卡⑬兑现;原 06 债务条目已完成移除)。←原一;P2;术语批 2026-09-25;封印紫批 2026-09-26;封印黑批 2026-09-28 - **可挖域接触带微光(交互反馈层,2026-09-25 用户拍板)**:挖掘期,英雄格周界与可挖域(概念见《排雷玩法》动作合法性节;呈现义务见《HUD框架》可挖域指示)的接触面画呼吸微光——正交邻墙=该侧整条边,斜向邻墙=共享角点+向两侧各延伸半条边;光只画英雄格(空间)一侧、不进墙格(与装饰变体零冲突,数字砖心不涉);微光=空间的灯光边界(画法口径)。色相=蓝族浅一档(§4.2 蓝条;与主角蓝框的分层归样张批);呼吸=§2.1 挖掘期唯一在动元素,减动效停格。角点为斜墙与正交墙共享、不逐格归因,逐格指认=悬停金框(呈现交互归《HUD框架》悬停指示域)。←§2.1;§4.2;P1 - **墙体**:圆角砌块堆叠,禁尖刺装饰——尖刺专属危险语义,装饰禁止伪装逻辑差异。←原三 @@ -543,50 +541,3 @@ | **传统扫雷 1–8 八色分色** | §4.1 数字墨三档 | 八色必撞红/金/蓝/紫赤语义色段;数字只走墨族三档色温,字形为唯一数值载体 | --- - -## 版本历史 - -- **v3.15(2026-10-17)未开格类型微光明度档 provisional 值登记(迭代 30 卡①实装随批;§4.2/§4.6.3 权威面零改动、§2.1 不追加)**:①**五组明度档 provisional 值登记**(色相零移动——样张 v2 冻结的五组色相本身不动,本批只定各组明度档,归「待定现用」第三态〔v3.10 立〕,复核转正归战斗一屏样张〔迭代 30 序位②〕):通用增益芥末黄 `#F7DF43`(冻结 `#D6C13A` 提亮档)、治疗黄绿 `#68D042`(冻结 `#5CB83A` 提亮档)、穿刺青 `#30A6A6`(冻结 `#2E9E9E` 提亮档)、魔法紫罗兰 `#7B5BD6`(与冻结值同)、群伤绯红 `#A61D37`(冻结 `#FF2D55` 的 V=0.65 暗档);五组 ΔH ≤0.13° 全数只动明度;实装落点 = `ui_kit.gd` TG_GLOW_* 五常量,呈现参数 α170/带宽 cell÷8 维持 §4.2 v2 口径不动;②**明度排档口径**——阶梯在渲染合成空间(伽马)排档:引擎 canvas 混合在帧缓冲 sRGB 域做线性插值,按 CIE L* 线性排档曾把群伤/魔法两档排反;相邻组对比度(CR)四对模型值 1.245/1.234/1.239/1.270 全数过判据线 1.20,实测最弱对 1.232;③**停机呈报留痕**(契约 5):群伤暗档初版 `#FF1A31`(ΔH 5.40° 超差)作废,用户裁「换更暗档」→ `#A61D37`(色相零移动);④连带=头注「现行为」漏更订正(v3.12–v3.14 三代未回头注,本批订正为 v3.15)。零素材新增,微光语义零改动 -- **v3.14(2026-10-14)迭代 24/25/26 反哺写入批(用户裁「全部按呈报写入文档」——qa 收尾批)**:①**§4.1 新入三 token**(GOLD_BRIGHT #E0B860 收益金亮档 / HERO_BLUE_BRIGHT #7EBAF0 小人蓝亮档 / SLOT_BACKDROP_SOFT #806A4E 图标槽柔和档——迭代 26 反哺③语义岗登记转正,色板计数 42→45);②**§7.6 新增「引擎原生控件与按钮状态规格」节**(迭代 25 反哺①+迭代 26 反哺①④——原无条款,两批实现临时权威转正:按钮五态矩阵〔悬停 modulate 1.06/按下本族下沉/禁用 α0.45 幽灵化/焦点 INK 2px 内缩 1px 环〕+原生控件组件规格〔滚动条 StyleBox 柄/滑轨两段可辨/气泡/输入件/预盖件/字体防御〕+氛围层平滑件与抖动派并存留样张批+主题色值双源注记〔迭代 25 反哺④〕);③**§8.2 增全局纹理过滤与平滑渐变件例外条款**(迭代 26 反哺②——Nearest 全局+三件 LINEAR 豁免清单);④连带 = §7 白话章节清单补 §7.6。色值遵守定值单点纪律指路 theme README 溯源表,零复述 -- **v3.13(2026-10-10)营地柜台名扫改(2026-10-10 天赋树设计会话裁「道具工坊」改名「秘宝匣」)**:§2.8 承载元素与 §6.2 场景构成两处三柜台括注改名。零素材新增 -- **v3.12(2026-10-07)类型微光组粒度批(用户裁——道具三层重设计·地图层顺带)**:§4.2 类型微光色带「组内明度梯度分型」降为「组间五色相+组内不细分」——逐型明度映射从未定义、cell÷8 泛光上五级明度物理不可读;色弱通道随迁组粒度(§2 验收2/§4.5⑨ 同批措辞同步);gp 不拆独立色相(用户裁:攻击三类+治疗+通用=五色已达玩家记忆上限);五组色相本身不动(样张 v2 冻结维持) -- **v3.11(2026-10-06)文档层三小活收尾(审计 §07 吸收对账后剩余项)**:①**§8 头注新增「定值单点纪律」**(审计 §07-1 落规——数字定值只落 §4.1 主色板 + §8.2 两张表,其余章节指路禁复述;character-design §5.5 数值指路 §8.2);②**§8.3 检查器挂点补 standee_asset_check 硬闸升级规格**(审计 §07-2/3——按 §8.2 逐键定档校验/色数 ≤32/无非整数缩放痕迹/描边亮度达标,现「宽 1–75」虚设区间退役,实现归 PRD 工具批);③连带 = art-status-checklist 状态图标行悬空路径(candidates/status-icons-2026-09-23/)按归档纪律改描述性出处;审计 §07-3 体量分区数字表建议**改判作废**(已被「生物体型+逐键定档」语义取代)。 -- **v3.10(2026-10-06)两拍板写入文档批(P2 收尾)**:①**§4.1 色板数值改「待定现用」态**(用户立第三态,非候选非死规——现行即执法、需求引入时走修订并登记;释义随条);②**头注新增「条款验收标注纪律」**——全文条款尾部三档标注(←机检/←目检/←方向性,用户拍板「符合工作流程」),新条款按此书写,存量口号型分章补标(06 挂账批执行);③连带 = 06「口号型条款机检化批」状态补格式已拍板注记。 -- **v3.9(2026-10-06)P2 清理项文档处置批(审计 04 节四项;零素材新增)**:①**§4.1 新增色板增量纪律**——硬上限 48 色(现行 ≈42)+新色双门(§4.2 语义检查 / 与既有色 RGB 三通道差 ≥8/255,反例 #3A2E22↔#362B20 差 <5),不过门走「换色合并」禁加色绕行;数值候选待样张批冻结。②asset-path-map.md 三处悬空/过时更正——candidates 目录注「按需创建非作废」、废路径 production/mockups/** 改 `artwork/mockups/**`(实存)、board/ 现役改 terrain_floor__ + flag_seal(旧 board_floor/wall 退役)。③P2-1 草稿整理批(3349 个)与 P2-4 口号型条款机检化批登记 06 待办(前者执行须 dry-run 先行)。④待决项 A/B/C 前批已全部完成,本批零遗留。 -- **v3.8(2026-10-06)零定义资产族契约批(P1-2,用户拍板「写进圣经、不另立文件」)**:零素材新增,纯契约登记——①§4.6.2 奖励徽章 19 枚资产契约(`ui/icons/reward_.png`,源 40×40,显示 20/40 双档候选);②§4.6.3 新增地形变异纹带族资产契约(`board/band_.png`,键集事实源 = 地形变异 GDD region 六行,源 64×64 无缝,已开变异格标识层);③§6.1 舞台背景插画资产契约(`stage/stage_bg.png` 基准一张 1280×270,三关换挡走 wall_ambient tint 槽不出三张)。三族照抄状态图标「键→文件名→尺寸」模式(§4.6.1 全链唯一完全合规族,审计点名可复制);程序化占位在役,出图工单归 PRD;art-status-checklist 看板随交付 ✅。 -- **v3.7(2026-10-06)立绘八敌定档批+方案二排版写入文档+归档纪律(P0 完成讨论批;工作流程铁律 = 讨论期只动文档,代码实装另批走 PRD→迭代)**:①**§8.2 画布基准——站桩立绘源档八敌逐键定档**(goblin 36/giant_spider 38/duergar 46/hook_horror 58/bugbear 62/ogre_chief 74/drider 90/duergar_king 94,×2 整数显示;原三档 48/64/96 候选与 v3.0 档位上调方向候选一并完成;依据 = 用户三体型约束+定档总图确认;可读性门槛源高 ≥32 实测;派生管线 = pixel-1→紧裁→dom_block_resize);②**§8.2 缩放纪律——站桩立绘排版 = 方案二**(B 区 270 ≈1/3/C 区 530 ≈2/3/扫雷盘 438 不缩;立绘底锚落台+血条状态落底排全场对齐+大体档探顶;原「血条悬浮头顶」退役——高盒空洞用户点名否决);③**§8.3 归档纪律**(P0-1 用户口径:图片不入 git/归档+对象存储/主文档禁引用 artwork 散路径);④连带 = character-design.md §5.2 体量语义修订(强度先验→生物体型)+§5.5 源档注记+钩爪恐魔宽≥高豁免登记、battle.md 区表/组件/线框/空态/修订记录顺带。 -- **v3.6(2026-10-04)站桩槽「高定宽随」条款落规(UI 重设计原型审计教训)**:§8.2 缩放纪律新增**站桩立绘槽位=高定宽随**条——槽位只定高度的整数倍档、宽度随源图宽高比自适应,禁统一方框强拉(纵横倍率恒等;实例=原型 88×92 方框把 23×48 地精横拉 3.83×/纵拉 1.92×、26×48 熊地精 3.38×/1.92× 压扁,46×48 主角近方恰等比独活;三层成因=窄条源图/方框一刀切/非整数倍 pixelated 发花);**乙类非整数豁免口径收窄注记=只覆盖等比缩放,不含纵横异倍变形**。同批原型侧修复=站槽 height:96 width:auto(48px 源 2×)+开始屏背景怪/大立绘/庆祝像/旗/图标显示尺寸整数倍对齐。文档核查=battle.md/HUD框架 均无强制方框条文(缺口是规则本身缺位,本批补) -- **v3.5(2026-10-03)视野迷雾黑暗区域渲染规格批(迭代 11 第④批实施批 T1;上位裁决=《HUD框架》「视野迷雾」节 v0.13,现行事实源已定论照抄)**:新增 §6.5——菱形灯光区=曼哈顿距离 ≤LIGHT_RADIUS(基准 8,表值/常量参数化;两圈分立注=类型微光仍贴身 8 邻格不随灯光区扩;提灯 +2 插值位预留不接效果);区外未开格全黑不渲染(照抄现行事实源「全黑不渲染」,非高遮蔽档,三档信息阶梯理由在节内);区外已开格暗淡记忆态(记忆板 #3A3A3A/记忆墨 #C4C4C4 provisional,数字 ≥4.5:1,三通道可辨判据在案,色牌格退牌归板,旗印记随未开格全黑隐没);过渡边=硬边逐格二值(禁渐变晕边);结算期去饱和叠加互斥口径(记忆态为终态档);§2 光照氛围允许域自查注记在节内;§6 开篇枚举行补「棋盘视野迷雾遮蔽」一词。纯呈现层零素材新增(程序化遮罩/调制),微光语义零改动,明度值 provisional(样张/实机自检锚,代拍板白名单内) -- **v3.4(2026-10-01)数字呈现三态修订(甲案深墨族方案渲染帧取证证伪后改版)**:v3.3 的「L2/L3 切深墨族直画」经 board_shot_probe 渲染帧取证证伪——underdark 系地板双峰纹理(近黑斑 p10 0.011+近白筋 p90 0.40+)上深墨直画融黑斑隐形(用户实机复测「还是看不清」实证),任何墨族直画不可救;改**三态**:dungeon 亮族直画(门 p90≥4.5/均值≥2.5)/中暗板深墨直画(门 p90≥4.5/均值≥3.0)/双峰板**色牌垫底**(素牌+深墨 12:1,v2 色牌形制复役);机检三关呈现模式断言 19/19;目视验证面=board_shot_probe 渲染帧取证入流程(机检≠看得清)。§1.4 样张闸第四验收项判读随三态口径件注记。 -- **v3.3(2026-10-01)数字墨按板自适应修订(L2/L3 亮瓦融字缺陷修复,用户裁甲案「墨色按关自适应+补三关对比断言」)**:§4.1 数字墨双色制①改**按板自适应双族**——暗纹理板维持亮族三档(样张 v3 冻结原样),亮筋纹板(underdark/deep_underdark)切深墨族三档(青墨/赭墨/锈墨复役);选族判据=所选族对归一后地板 p90 亮斑 ≥4.5:1 且对均值 ≥2.0:1,落码单点 `board_view._digit_ink_mode`,机检=`terrain_tile_sets_test` 三关对比断言 21/21;缺盘平色回退默认深墨族。§4.1 其余条款(字形唯一载体/三档色温/垫牌后备)不变。 -- **v3.1(2026-09-30)越权清理批(用户指令:按域内审查修订案修改,概念定义归还 GDD 权威文档)**:①**微光口径四处改指路**——§1.2 原则三/§1.4 样张清单去「常显」、§4.2 色带条去「常显」、§4.6.3 去「全部未开格」,统一指路《HUD框架》「未开格类型微光」节(2026-09-30 完成批落位的唯一事实源,他文只许指路);②**概念越权剥离**——危险格叙事属名与换轴史、封印插旗语义(→registry「封印」条+《排雷玩法》玩家说法)、极性定义(→《地图战斗资源》极性提案)、完美排雷定义与兑付结构(→同)、敌意图预告语义与「待机即预示」(→《敌人系统》意图线索节)、奖励 weight 与兑付/库存语义(→《地图战斗资源》)、键名沿革史(empower/fortify 来源=敌方技能施放、alert 2026-09-20 八型批换装、ac_up 2026-09-16 换装——自 §4.6.1 移除留痕)、甲档 armor 数据实态(L1 全轻甲/L2 除 drider 外全轻甲/L3 duergar·duergar_king 重甲)与旧键集史({grub, ambusher} 随 DND 更名退役——自 §4.6.4 移除留痕)、「敌不占格」断言、「类型分布即先验」机制 rationale、「分布属初始化随机」归属断言(改画法口径「分布每板一次跨轮不复掷」);③**实装状态与排期注记移本历史留痕**——游戏 UiKit.HERO_BLUE 已同步 #2E6E8E→#2E86DE、UiKit.CONTACT_GLOW 同值 #D6ECFF、旧可挖域绿相 DIG_EDGE 已随接触带方案退役、死亡表现切片实装=程序化 tween(灰化罩+碎块弹飞 5 块 0.45s,挂 unit_died)、封印特效「待表现批」、§6.1 背景插画「排期归表现层升级批」、panel_stone/button_stone 接线归最近表现批、§7.2 对比度违例「修复归表现批」、§7.5「占位不空窗」注记;④**角嵌退役条改写**为现行「未开格预读通道(微光单通道)」条(退役史见 v2.12);⑤**残留矛盾清除**——§3.2 呈现基准条「装饰变体一律纹理级」旧措辞随 v3.0 物件级解禁同步;⑥§2.8 营地承载元素/§7.5 钥石呈现位改指 §6.2(事实源边界在该节);⑦**补漏五处(同批完工审计发现,同类剥离留痕)**——§4.1 危险红「机关红」更名史、§6.2 营地贴图「排期归 UI 贴图重构批」与「占位不空窗」注记、§7.4 字体「接入归表现批」注记、§8.1 扩板与 1920 档换算值「归表现层升级批成文」(改债务指路 06「分辨率档位与棋盘格边长口径」条)、§8.3 「终稿目录归表现批定」注记、§1.4 整屏样张闸「表现层落码批开工前」改屏级落码开工前、§7.1 「样式终稿归样张后表现批」改随样张闸后定稿。**零美术信息损失**:全部色值/机检断言/纹样描述/画法参数不动,样张 v2 四冻结之②③维持 -- **v3.2(2026-09-30)样张 v3 冻结批+缩放分级修订+案甲落定(迭代 9 T1/T2/T9;需求卡片已退役(git 710f9b7 出口批))**:①§1.4 补**样张 v3 冻结记录**——机检 17/17 全绿,断言定值两件(A3b 图底分离定值 Δ≥30〔实测 38〕/A4 尺寸基线硬等冻结 立绘 46×48+小人源 32×32),F6 沿用 v3.4;**四冻结①④重冻**——①砖面形态=E 格高墙 30% 词表扩展+格底明度分档(世界底层档 L≈0.10)+装饰物件级解禁/④数字形制=亮墨三档直画+色牌后备;②色板③动画维持冻结。产物 `artwork/mockups/sample-batch-v3-final-2026-09-30.png`+机检报告【冻结】;气质终审=2026-09-29 用户验收豁免(状态记录 281)。②**§8.2 缩放纪律分级修订**(2026-09-26 用户裁「改规则不豁免」写入文档,修订窗口=v3.0 已入库):甲类文本语义件(数字/图标/旗/砖面/纹样)维持严格整数倍;乙类角色精灵允许运行时非整数倍(NEAREST 不变,判据=实机目检可感不适即回整数档);1920 档策略经三裁决**案甲落定**(全局等比 stretch keep——v3.2 当日 T9 写入文档,详见 §8.2)。头注「现行为」顺带 v3.2。 -- **v3.0(2026-09-29)中修批(案 B,用户拍板;审视报告=git fbaadb8(已退役),六病根+三案呈报)**:①**§2 明度恒定→明度分层**——三档明度带(信息面层/世界中层/世界底层),情绪与状态明暗禁令保留(状态区分仍只走色相/饱和/运动/元素),空间纵深/光照/形体塑造开允许域;§2.1/2.2/2.3/2.5/2.7 各状态条措辞随改,§2.7 增「明度带随深度微移」候选。②**原则二色牌降级**——「明亮为皮,色牌为骨」改「明度分档为骨」:已开格走世界底层档(候选 L 0.20–0.32),棋盘数字墨亮族直画(候选 L≥0.75,冷亮/暖白/金亮三档色温承袭密度语义),色牌仅复杂格底后备(垫牌场景用深墨族,12.3:1 实测保留);§1.4 验收 1/2/4 与判定回退口径同步,样张 v2 四冻结之①④(砖面形态之数字承载面/数字形制)**解冻待样张 v3 重冻**(②③冻结〔色板/动画〕不受影响)。③**语义色适用域限定**——§4.2 各条「X 只说 Y」约束信息层与语义物件,纯环境氛围解禁(焦点预算与低饱和后退接管防抢焦);紫赤禁入带环境层低饱和可入、高饱和独占不变;§4.3 换皮槽与不变槽口径随改。④**装饰变体物件级解禁**——专属装饰形状家族+零信息纪律不变+焦点预算约束,配额候选 3–5 种(原则三/§3.2)。⑤**§6.1 舞台正面目标**——B 区=地窟看台(地台/落影/光源氛围候选),补原条只有负面约束之缺。⑥**§1.4 整屏样张闸新增**——战斗/关卡/菜单/营地四屏,验收四项(全局文字 ≥4.5:1/明度三档带/整屏焦点预算/文字禁压纹理),闸形=方向稿目检先行→机检冻结。⑦**§7 三件**——7.1 占位完成条款(占位=临时态,终稿闸=整屏样张)/7.2 全局文字可读性硬指标/7.4 字号下限 16/14px 对齐 ux-designer PC 规范+层级手段解禁(字号档差+墨色+字重)。⑧**§8.2 档位上调方向候选**(主角 64×96/敌 64/96/128 评估,归整屏样张闸,本批不重产资产)。⑨**§9 参考表**——Moonlighter 取列增光照层次、§9.2 DD 条款改名+新增「传统扫雷白牌」反面行。⑩**§3.4 焦点双机制**(完整度+明度带)。**连带文档同步**:character-design.md(提灯点亮解禁候选)/interaction-patterns.md/level-map.md/art-assets-checklist.md/battle.md/04-美术音频方向.md 引用口径顺带。**挂账(06 登记)**:样张 v3 重跑批(断言改造+新参数冻结)/ui_kit 与棋盘渲染落码批(明度分层/格底分档/亮墨/UI 对比度修复)/资产升档重产批/mockup v3 方向稿(按 v3.0 重出)。**代拍板三项 2026-09-29 当日已追认**(闸形两段式/色牌后备范围/升档只立方向)。 -- **v2.15(2026-09-28)人设旗脱钩批(用户拍板)**:§5.4 速览背包旗改旗朱红矩形旗+§4.1 封印黑条红族口径限定棋盘侧;封印黑仍为棋盘封印专属色不变;人设侧详见 character-design 对应版本行(v1.7) -- **v2.14(2026-09-28)关卡画面样张 v1 冻结批(M-2 迭代 4 T1–T4,机检闸形 A——11/11 全绿即冻结)**:§7.2 增「暗底呈现态双色墨制」条(暗底系图标/读数=暖白 #F0E2C8、当前金底转深墨 #181410,各态 ≥4.5:1;已过节点暗金冻结 **GOLD_DONE #68562C** 专用呈现态值——旧 GOLD_DIM #8C743C 对双色墨均不达标;Boss 描边=紫赤 2px+外缘 1px 深墨环灰度冗余通道——§4.2 色相独占本色不变);冻结面=节点图标形制(♻ kenney-board-game-icons 五键 bow/award/campfire/crown_b/pouch,20px 烘焙 1:1 消费,WARM 单色,复用闸①②③④)+通道质感(折线 2/3/4px 直角肘形)+画布公式(70+层×122+34/52+槽×58+26+8 下限 620×240——routebug 83c11a1 根修件同源)+底栏样式(暗数据框 WARM/WARM_SOFT 双墨)+屏底(BG_ROOT+backdrop_stone);换层色板渐变挂点落码(§2.7 切片档——level_index→tint 表候选值随 §6.3 方向,明度带归一,终值归色板样张批)。规格承载=level-map.md(修订记录同日行);产物=`artwork/mockups/level-map-sheet-v1-2026-09-28.png`,机检报告=git 提交 9a79927;气质终审=M-2 出口闸真人目检 -- **v2.9(2026-09-26)高墙瓦片体系定稿批**(高墙批全程收官,用户拍板;状态记录 163/164):§3.2 新增「高墙瓦片体系」条——未挖格=一整块 32×32 自含凸起岩体(方案甲核心定义)+术语(墙瓦片/地面瓦片)+墨线边界纪律(1px 深墨线直线零锯齿,职责=分隔不融合)+单一北受光(北缘 1px 微亮棱/南缘立面窄暗条/凹角角点+立面侧 1px 齐平收头),定稿=`game/assets/art/board/terrain_*` 21 枚;§8.5 增「生产分工」条——材质归模型(AI 只出无缝填充纹理)、结构归程序(autotile 拼接约束超 2D 生图能力,实证在案)+镜像规则(只许 flip_h 禁旋转)。条口径=样张批追认(与 §8.4 方向集先例同)。词表与查表逻辑、搜包评估记录归 design/research 两档;过程文档顺带清退(中间产物不入库先例,状态记录 127)。 -- **v2.10(2026-09-26)封印紫批**(用户拍板:插旗色 旗朱 #C63D22 → **封印紫 #7C3AA8**,色相 ≈267°):§4.1 旗朱条改写为封印紫条(候选值样张批冻结;禁入带合规+与魔法微光/妨害紫间距登记)、§4.2 红只说危险改单档(旗朱预告档退役)、§3.2 旗条/§1.4 验收 4/§4.3 不变槽/§3.2 变异互辨/§5.4 速览顺带。**语义面**——封印自术语批(2026-09-25)获专属色相,红族收敛为危险红单档;攻击预告/弹道/拒绝等非封印红统一归危险红族(RED_MINE)。**连带**——character-design §5.4 背旗、battle.md 三处、关卡节点地图 Boss 描边、清单封印特效行顺带;comfyui-prompts 生图卡颜色词随样张 v2 重生成。 -- **v2.11(2026-09-28)封印黑批**(用户拍板:封印色 封印紫 #7C3AA8 → **封印黑 #000000**——紫色与微光蓝族色相冲突,黑色无色相天然合规):§4.1 封印紫条改写封印黑条、§3.2 旗条/§1.4 不变槽/§4.3/§5.4 速览顺带;代码 UiKit.SEAL_PURPLE→SEAL_BLACK 改名迁移+board_view/board_fx_view 换色+样张脚本同步;胜利彩带装饰紫位改亮金(紫赤系 Boss 独占不入装饰);远程生图单主角旗 purple→black 十六进制锁色重锁。历史行(v2.10 等)按文档纪律留痕不改 -- **v2.12(2026-09-28)角嵌退役批**(用户裁「微光的展示只有微光,不要加额外的箭头或者加号在格子里面」——样张 v1 否决原因之一):未开格类型角嵌纹样**彻底退役**——类型预读改类型微光单通道(色相+明度双码),§2 微光明度恒定开例外(明度梯度承载类型,梯度不压格底明度档/三态分类),色弱类型主通道=微光双码;§1.2 优先级栈/§1.4 样张清单与验收 2/§3.2 角嵌条(标退役)/§3.4/§4.2 色带条/§4.5⑨/§4.6.3 呈现约束同步;已开格物件纹样(角嵌于砖缘画法动词)不在退役面;机检新增「微光格零墨色附加像素」断言;角嵌误读率指标转微光误读率 | -- **v2.13(2026-09-28)样张 v2 冻结批(M-1 迭代 2 T1,机检闸形 A——全过即冻结)**:§1.4 增样张 v2 记录(机检 16/16:现行 13 条+A3 上调 Δ≥55/F6 顶面立面双明度带 Δ≥18/F7 悬崖 DEPTH_PX 同源/A6 观感密度梯度 ≥4.70=v1 实测 4.09×1.15——v1 四否决原因断言化收官);**四冻结写入文档**——①砖面形态:§3.2 高墙瓦片体系条增「D 投影档+整板悬崖」定稿参数(口沿高光 2px Color8(196,172,132)/立面双段暗带 0.16+0.25 格边 α0.60·0.82/地面投影 0.22 格边三段渐隐 α0.28/悬崖 DEPTH_PX 8px board_world 同款);②色板:§4.1 小人蓝候选→定稿 #2E86DE(UiKit 同步)+§4.2 接触带微光色值 #D6ECFF 定稿+类型微光五组候选→定稿(v2 呈现 α170/带宽 cell÷8);③动画方案:§8.4 帧数规格候选档→冻结(待机 4/攻击 6/受击 2/死亡=灰化+程序化碎块弹飞 5 块 0.45s,序列帧归缺料清单);④数字形制:色牌形制定稿(#F5EAD3 直角小牌+Fusion Pixel+字号 max(18,ceil(格边×0.5))+墨三档)。产物命名带 v2(v1 被覆盖欠账清偿),报告迁 `design/research/`;连带=图例旗色封印黑漏网修正(#C63D22→#000000) | -- **v2.8(2026-09-25)可挖域接触带微光定稿批**(用户两拍板:①画法=接触带·空间侧——光画英雄格周界,正交邻墙=整边、斜向邻墙=角点+两半边;②色相=蓝族浅一档,顺路清偿旧 DIG_EDGE 绿相违 §4.2 绿禁则):§3.2 新增「可挖域接触带微光」条(画法/光只住空间一侧/角点不逐格归因、指认=悬停金框/呼吸与减动效守 §2.1/实现切换归表现批);§2.1 承载元素、§4.2 蓝条顺带;battle.md 注记顺带。背景=用户世界观口径「未开格=墙、已开格=挖出的空间」,微光=空间的灯光边界。 -- **v2.7(2026-09-25)封印术语批**(用户拍板:Node2D 实现后「插旗」动作等价为**封印**——玩家对未开格插旗即对该格巢穴实施封印,旗 = 封印印记;机制键与规则全不变):§3.2 新增「旗(封印印记)」条——呈现语义/旗朱与栈位不变/封印特效(施印瞬间+印记常显形态)待表现批/现行占位 = 旗朱「旗」字形;§2.5 失败承载元素措辞顺带(插过的旗 = 封印印记)。**登记面**——registry terminology 新增「封印」词条、00-游戏概念 术语层级专名表随收;连带同步:battle.md 呈现注记、art-assets-checklist §4 演出类新增封印特效两件(施印特效+印记常显)、art-status-checklist P3 行、character-design.md §5.4 插旗条注记(主角即插旗者)。**关联面**——可挖域接触带微光方案(用户同日提出:微光画英雄格周界接触面,正交整边/斜向角点+两半边)评估可行,实现归表现批,未入本批。 -- **v2.6(2026-09-25)世界观对齐扫描批(甲档回填 + 完美排雷钩子完成 + 引用锚内联;用户三拍板)**:①**§4.6.4 敌种甲档回填数据实态**——bugbear(ward→light)/ ogre_chief(heavy→light)/ drider(heavy→ward),并注记甲档事实源 = `enemy.tres` armor_type(2026-09-18 甲重配批后 L1 全轻甲、L2 除 drider 外全轻甲、L3 duergar/duergar_king 重甲);连带修订 character-design.md §5.5(熊地精轻甲化/食人魔弃金属甲板改裸身皮条/卓尔改魔法甲符纹)与 comfyui-prompts.md v2.8(熊地精/食人魔/卓尔三卡提示词随改)——食人魔视觉重设计经用户拍板「按最新设定,裸身+魔法甲符纹」。②**§2.2 完美排雷钩子完成**——「若…落实…待 GDD 定夺」改现行事实(零误标且至少标中一面旗→追加第二份清图兑付+结算高光行,地图战斗资源 GDD 已定稿)。③**引用锚内联**——§3/§4 尾注 P1–P4 支柱语义内联(概念期 brainstorm 编号,现行 GDD 树不单列),§1.4 两处 game-concept 编号引用改语义内联。扫描背景=用户发起的圣经×关卡/世界观对齐审计;变异六类型/格面九类/状态九键/奖励 19 键/敌种八键/三柜台钥石/三关色板方向经核对全部一致,零其余不符。 - -- **v2.5(2026-09-25)装饰变体纹理级修订批**(地形高墙瓦片批复审发现,见 `candidates/terrain-walls-2026-09-25/0-需求规格与验收闸.md` §八;用户裁定):§1.2 原则三与 §3.2 装饰变体条——例子「苔藓/裂纹/碎屑」改「裂纹/碎石斑等纹理级氛围层」(苔藓在三个现行关卡 dungeon/underdark/灰矮人矿城设定中不存在);新增约束——装饰变体一律为纹理级、禁物件级(巨石/小石堆等读作"格子里有个东西"的元素与"格子=内容舞台"冲突,会跟奖励/旗子抢读),数量保持最少(约 2 种),用途仅为破除大面积同砖平铺的重复感;随机分布/与危险格与安全格类型零相关/禁止构成可读线索等既有约束不动。§3.2 雷图棋盘呈现基准连带同步——「装饰小立牌=装饰变体的立体档」改「本作不采用立体小立牌档」。§1.4 样张清单「至少两种装饰变体」与约束一致,不动。 -- **v2.4(2026-09-24)结构件完整性与参考核验纪律批**:新增 §8.5——①格面立体结构(顶面/缘件/角件/周界轮廓)必须来自素材本体绘制的结构件拼装,禁以调色/渐变/滤镜/跨格投影伪造缺失结构,样稿暴露缺件即停报「换素材/自产缺件」由用户裁决;②宣称「参考 X 游戏」前必须取得并像素级查看 X 截图证据并存档,仅凭文字/印象的断言无效;③图底分离由素材选型承载。立规动因=beast-cave 高墙批 G(渐变)/I(阴影)两稿以调色伪造结构、且参考 Necesse 未看截图,被用户两次纠偏返工。 -- **v2.3(2026-09-24)棋盘小人方向集批**:§8.4 增方向集条款——4 向(下/上/侧,侧向左右镜像共用画稿)+斜向移动/挖掘按主导轴吸附最近正交向,不出 45° 斜向帧(用户拍板;镜像豁免「旗恒画右」纪律为代拟口径、样张批追认)。 -- **v2.2(2026-09-24)效果图标纹样系统定稿批**:§4.6.1 九行纹样描述由用户逐键口述定稿(主体三轴白剑/白盾/白眼+右下角箭头语言绿↑红↓双绿↑,同族键共用同图);旧语义锚文字退役。 -- **v2.1(2026-09-23)停点前移批连带同步(批内代拍板②引用,worktree stoppoint-shift-20260923,状态记录 142)**:§6 开篇与 §7.2 结构行「双舞台四区」改「双舞台三区(B/C/D,字母保持不重编)」、扫雷图区锚点 1036×476→1036×504——战斗屏 A 区进度条随停点前移批退役(战后返回关卡画面,节点链进度由关卡画面选路覆盖层节点态承载),28px 纵向空间归 C/D 底行;裁决权与事实源归属 battle.md/HUD框架 不变,历次版本历史行不动。 -- **v2.0(2026-09-23)UI 章迁入批 + 画布定档 + 色板方向裁定(用户对 v1.8 代拍板四项逐条表态+五缺口给口径;worktree art-ch69-amend-20260923,状态记录 138)**:①**§3.3/§4.4 物理迁入 §7**(用户拍板:UI 具体选择须在 UI 章定义,三/四章只留简单定义与方向指导——v1.8 代拍板①「按引用整合」据此推翻):§3.3/§4.4 降为方向指导节(各留一段+指路),细则全文迁 **§7.1 形状语法细则/§7.2 UI 色板细则**;§7 重排号 7.1–7.5(原 7.4 组件库语义并入 7.1,零内容损失);§6.2/§7.3/§7.5 与清单引用随改。②**§8.2 画布基准暂定值**(用户缺口一裁定):主角人设原图=48×72、主角战斗状态图(侧向)=48×72〔v1.9 待决注记「主角立绘档空缺」完成〕、棋盘小人=32×32 二头身独立派生资产(允许更小;36px 板占比摩擦沿「独立小源档」路线样张批定终值)、敌种立绘三档 48/64/96=普通怪(小)/精英(中)/Boss(大)对应关系经确认保留候选;旧「像素基准 32px」通用候选退役;1920 档缩放策略与帧数规格维持待裁决,登记 06-待办清单(表现与支撑/HUD框架节新条目),样张批时提醒。③**§6.3 三关色板方向**(用户裁定):underdark 幽暗地域=**冷调幽暗**(灰白蓝主调+少量紫黑点缀,紫系取紫罗兰域 ≈256° 候选、禁入带 300°–345° 不变)、deep_underdark 灰矮人矿城=**灰黑主调+矿脉金属色点缀**(金属质感族冷银/铜灰候选,奖励金亮金禁上格底 §4.2 不变)——替换 v1.8 苔绿/冷灰岩方向草案。④**§9.1 扩池候选否决**(Forager/杀戮尖塔不入池且撤登记——用户裁定美术参考意义不足;代拍板④完成)。⑤命名规范草案获确认(代拍板②完成)。清单 §0 像素行与风格宪法表指向顺带。 -- **v1.9(2026-09-23)§8.2 待决注记批**(侧会话用户指令「你在这里直接把这件事给做了吧」;worktree art-s82-note-20260923,状态记录 137):§8.2 增两条待决注记——①**36px 板 × 32px 源摩擦**:32px 源在 45px 格 1× 占 ≈71% 合规、在 36px 格 1× 占 ≈89% 超「≤0.75 格边」红线且禁非整数缩放回退,出路二选一(棋盘小人独立更小源档如 24px 级 vs 两种板各出一版),样张批随格边长终值一并裁决,裁决前棋盘小人源图不排产;②**主角立绘档空缺**:主角 B 区站桩立绘未单独立档(现行 48/64/96px 阶梯按敌种 archetype 写),随战斗一屏样张锁「角色剪影方向/战斗空间」时一并定。头注「现行为」顺带 v1.9。 -- **v1.8(2026-09-23)§6–9 四章补全批(D 框架 D1/D2/D4/D5 落地,圣经全章成文;worktree art-ch6-9-20260923,状态记录 136)**:**§6 环境与场景**——6.1 战斗舞台背景(明亮地窟/低对比自然后退/明度恒定适用/`wall_ambient` 联动/紫赤仅 Boss 战)、6.2 营地场景(烛光黄×木色/三柜台一字排开/亮起走饱和不动明度/系统语义归元进度 GDD)、6.3 三关图类型色板候选(dungeon 暖石棕基准档/underdark 苔绿偏灰/deep_underdark 冷灰岩,方向候选归样张批重跑 §1.4 冻结,增「与五组微光互辨」抽测)、6.4 下探过渡(渐变取下一关槽值,只动色相饱和);**§7 UI 设计**——7.1 视觉基准(§3.3/§4.4 上位法**按引用整合**,D5 框架「迁入」不物理迁移——保持形状/色彩两章完整性,物理迁移待用户另有裁决)、7.2 布局栅格(四区结构事实源归 battle.md+4px 步进档候选)、7.3 字体字号(Kenney CC0/Fusion Pixel OFL 候选+整数倍缩放+下限 18/14/13 事实源 HUD框架+禁字重区分)、7.4 组件库三类容器语义+极性冗余、7.5 营地界面;**§8 资产与技术规范**——8.1 两档定案+格边长口径(锚点 45/36px 事实源 battle.md,扩板与 1920 档换算归表现批)、8.2 像素基准 32px 候选(active.md 58 条挂账清偿入章)+整数倍缩放纪律+1920 档适配策略候选+画布档位候选、8.3 导出 PNG/SpriteFrames+命名规范候选草案(对象键=数据表主键,图标键契约的文件侧延伸)、8.4 帧数规格候选档;**§9 参考与反参考**——9.1 正面三款取/弃表+扩池候选(Forager/杀戮尖塔)仅登记不入池、9.2 反面四条绑条款(Darkest Dungeon 压暗/Gungeon 粒子色相爆炸/Hades 特效密度/传统扫雷八色),反面图证待素材生成。**同步面**——头注状态行/Sign-Off 注记/参考池行、art-assets-checklist §0 像素尺寸行与参考图行及 §6 依赖链、04-美术音频方向.md 参考指引顺带。**代拍板四项待追认**——①D5「迁入」按引用整合不物理迁移;②命名规范候选草案;③栅格/画布/帧数候选值系起草非裁决;④扩池候选两款不入池仅登记。 -- **v1.7(2026-09-23)§5 抽离批 + 主角特征批**(用户两拍板:①角色设计自圣经 §5 抽离成独立文档 `character-design.md`,圣经 §5 改引用存根,小节号 §5.1–§5.6 不变、既有 §5.x 引用经存根可达;②主角特征改动——背后加扫雷联动旗、直剑换挖掘铲):§3.1 迁移注改指人物设计文档;主角两特征与三态措辞修订明细归 character-design.md 版本历史 v1.0,提示词执行侧归 comfyui-prompts.md v2.1。 -- **v1.6(2026-09-22)§5 角色设计落地批(D 框架 D3)+ 提示词卡重生成**(用户拍板走正序:先补 §5 角色章,再重生成 comfyui-prompts.md;worktree art-char-s5-20260922):**新增 §5 角色设计**——§5.1 角色剪影与轮廓通道(自 §3.1 迁入:角色四类 archetype + 轮廓通道硬规则,「禁黑描边」顺带固化;道具点剪影留在 §3.1 并改题「道具点剪影」);§5.2 头身比与体量档位(2~3 头身两档、体量单调递增、像素画布归 §8 另批);§5.3 护甲类型视觉区分(候选方案待样张批冻结:通道 = 甲面覆盖率×甲材质色——轻甲裸、魔法护甲符纹饰带、重甲冷灰金属甲板;天然甲壳不计甲档;灰度按覆盖率三档可辨;清偿 §4.6.4 强度档位行挂起的待设计项);§5.4 主角三态规格(形象锚站姿样张/三态约束/小人蓝同族明暗/蓝族敌方禁入);§5.5 八敌种逐卡(键集随 registry,主色域物种本色豁免语义禁则、禁入带与蓝族两例外;兄弟精换色板不换形);§5.6 意图准备动画三档规格承载(自 2026-09-18 拍板与清单 §2.3 收编)。**引用随迁**——§4.5⑤/§4.6.4 两处 §3.1 改指 §5.1,§4.6.4 强度档位行改指 §5.3;art-assets-checklist §0/§2.2 引用与待设计项表述、战斗表现 §3.1 引用两处顺带。**comfyui-prompts.md 重生成 v2.0**(主角三态+八敌种逐资产自包含完整提示词——正向底座/主体/动作已拼妥、负向底座/增补已并妥,整段可直贴;继承 seed 纪律/禁入带/#F2F2F2 生成底色;主角蓝族随 v1.1 换装 #2E86DE;新增 duergar/hook_horror/duergar_king 三卡;护甲视觉短语按 §5.3 注入各卡;bugbear 主体改敦实圆肩守 §5.1 普通怪宽≥高;兄弟精变体配色弃冷蓝灰改灰褐战纹,避与小人蓝同屏混淆)。§6–9(D4/D5/D1/D2)仍待后续批。 - -- **v1.5(2026-09-22)中间产物引用解挂批**(用户裁决:修订指导与审计报告系中间产物不入库,工作区未跟踪留存;worktree midprod-unref-20260922):头注 D1–D5 框架引用改内联编号映射(明细归状态记录 125);本历史 v1.3 条目中的修订指导路径引用自此不再可达(历史文本如实保留);art-assets-checklist 两处「交接要点存审计报告」改指路状态记录 125。 -- **v1.4(2026-09-22)gungeon 退场批**(用户拍板:gungeon 两张移出即可,暂不设反面案例——反面参考待素材生成后另批增补;worktree gungeon-exit-20260922):`references/gungeon_1/2.jpg` 删除;头注参考池行定稿三款×2 张,目录自此与点名池一一对应。 -- **v1.3(2026-09-22)GDD 过期账清偿批 + 类型微光裁决**(用户四拍板:①未开格类型预读采纳彩色常显微光;②分辨率档位已定案两档 1280×800+1920×1080〔清单侧承载〕;③§5–9 按 D1–D5 框架分批补全,框架登记于 `art-docs-revision-guide-2026-09-22.md` 第 6 节;④两份美术清单合并以 art-assets-checklist 为底〔清单侧承载〕;worktree art-docs-settlement-20260922):**§4.6 契约表对齐数据实态**——§4.6.1 效果键七行→九行(ac_up/alert/empower/fortify 入表,defense_up/ambush 死键清除,sapped「待实施」旧注删除);§4.6.2 奖励徽章键整表重写为九型字典正负 18 行+清图槽 clear_blast(旧可选类三键/attack_up_basic/defense_up_basic/clear_knife 清除,「群伤 40」数值删除归配置事实源;gp 组键名按 reward.tres 勘误为 gp_coin/gp_lose);§4.6.4 敌种线索键整节重写(键集 {grub,ambusher}→八敌种现行键集,意图姿态改 2026-09-18 动画三档,Rule 8/伏击池/OQ7 退役表述清除);**微光改向**——§4.6.3 呈现约束由「墨族单色」单一通道改「角嵌纹样(形状)+类型常显微光(色彩)」双通道(R3 不泄危险格与安全格约束不变),§4.2 增「类型微光色带」分域条款与五组候选色相(芥末黄/黄绿/青/紫罗兰/绯红,避 300°–345° 禁入带与既有语义色段,样张批冻结),红/绿/紫赤/金条款加微光分域例外,§4.5⑨/§3.2 角嵌纹样条/§1.2 原则一/§1.4 样张清单与验收 2·4/§3.4 同步;**过期挂点清偿**——§3.2/§4.3 变异挂点落地(六类型定稿,纹带形按轴两分:伤害轴刺缺形/信息轴遮蔽形,同轴只做色板变体;样张批增岩浆橙红与危险红/旗朱互辨、信息轴遮蔽不入色牌占位区两项检查);§2.8 营地改三柜台+钥石(「天赋树」退役);**更名**——biome/board_biome/biome_tag 正文全量更名图类型(board_type),§4.3 标题顺带(键名事实源 = 棋盘生成 GDD 与 board_gen.tres);**结构收敛**——§1.3「对 brainstorm 视觉锚的修订记录」整节并入本版本历史(正文留号占位,状态记录 109 正文零历史纪律),头注压缩(状态行与 Sign-Off 并行),原则三与 §3.2 重复条款收敛(零信息纪律/结果清单单点成文)。gungeon 两张参考图去留待表态(T2)。 -- **v1.2(2026-09-22)雷图棋盘呈现基准批**(用户拍板:雷图要有 ITB 参考图的战棋棋盘质感,但 45° 摆正成正俯视角——「摆正视角方格」读法):§3.2 增「雷图棋盘呈现基准」条——ITB 地表质感骨架(纹理多样/起伏体块/岛缘砖缘厚度/格上装饰立牌)× 相机正上方垂直向下、格线屏轴对齐、禁等距斜视与菱形格;砖缘厚度/岛缘立体面显式划为形体塑造、不触 §2 明度恒定(该规则禁的是状态/情绪明暗表达),顶面格底仍守 §4.1 参数域;装饰立牌 = 装饰变体立体档、零信息纪律不变;头部参考池行与资产清单样张要求顺带。**勘误**——v1.1 状态记录所记「参考池资产失配」判断有误:references/ 中 itb/moonlighter/peglin(点名池)+gungeon(未点名)四款×2 张一直在库,删除的十张系额外五款(CatQuest3/Dicey/Roundguard/Tangledeep/WonderBoy)退场,参考池本身无失配;gungeon 两张点名与否待用户表态。 -- **v1.1(2026-09-22)视觉自由度修订批**(用户三拍板:①原则二改数字色牌方案;②已开后表达+零信息装饰变体;③只换主角蓝微调其余):原则二更名「明亮为皮,色牌为骨」——数字可读性改由数字色牌(素色直角小牌)承载,格底压素让路条款退役、饱和上限 0.40→0.55(候选),§1.2 优先级栈/§1.4 验收 1·2·4/§3.3/§3.4/§4.1 硬指标/§4.3 同步改查牌;原则三增格子多样化——已开格按当格结果整格表达(九类型物件纹样/纯安全格裸土/危险格巢穴更凶),未开格加零信息装饰变体(随机分布、禁逐轮重掷),未开格类型预读由小徽章升级为角嵌纹样(R3 不泄危险格与安全格约束不变),§3.2/§4.5⑨/§4.6 同步;主色板——小人蓝 `#2E6E8E`→`#2E86DE`、新增数字色牌 `#F5EAD3`(均候选值,样张批冻结终值),格面类型表五类→九类对齐(pierce/magic/action/gp)。§2 氛围层与明度恒定硬规则未动;§4.6 其余键表(效果 §4.6.1/奖励 §4.6.2/敌种 §4.6.4)数据过期账未清,另批处理;执行侧 ui_kit `HERO_BLUE` 等色值同步义务已登记,归样张批冻结后的表现批。 -- **v1.0**(2026-09-10 初稿;2026-09-13 增补批——徽章栈位/危险格隐喻换轴/格子样张验收成文/图标键契约冻结;2026-09-15 去雾批)。 diff --git a/design/art/art-prompts.md b/design/art/art-prompts.md index 2af20e41..b51a9470 100644 --- a/design/art/art-prompts.md +++ b/design/art/art-prompts.md @@ -289,22 +289,3 @@ Seamless tileable pixel art texture of dry dirt ground, top-down, for a dungeon - **意图准备动画三档、战斗演出类**:动画序列帧,等一屏样张锁动画方案后另立规格卡。 - **格面徽章 19 枚 / 关卡节点图图标 / 砖面终稿 / 地形变异纹带**:脚本管线,规格锚 art-bible §4.6(图标键契约)、§1.4(样张验收)与 §3.2,不需要生成提示词。 - **音乐音效**:清单已明确排除。 - -## 版本历史 - -- **v3.1(2026-10-06)渠道定位+拼表制主选批(用户拍板)**:①**渠道定位更正——远程对话式生图为主、本地 ComfyUI 为备选**(v2.7「彻底关闭」为当时口径,现行更正为备选;§0 使用流程随改);②**§4bis 纪律 3 改制**——地形瓦片出图 = 拼表制主选(三步流程:程序占位样图参考 → 整图生成 → 裁切+统一降采样;操作单 remote-gen-prompts §3),分张降为回退路径(裸拼表画框实证教训归因于缺参考锚定,非拼表制本身);③与 remote-gen-prompts 分工写明:本文件 = 词库正文、remote-gen = 对话操作单,正文不双处维护。 -- **v3.0(2026-10-06)地形色值对齐批(审计 P1-1,用户拍板色值现行事实源 = 圣经 §4.1)**:§4bis 四张地形卡色值漂移修正——岩石系 `#8B755B`→**`#C9AF83`(掩尘/未开格)**、地面系 `#564232`→**`#B39A78`(裸土/已开格)**;remote-gen-prompts.md 2×2 拼图卡同批对齐。提示词侧色值自此以圣经 §4.1 为唯一事实源。 - -- **v2.9(2026-09-26)地形填充纹理节批**(高墙批收官,用户拍板):新增 §4bis——地形类首张卡(墙顶基面/裂纹/碎石斑/地面四张自包含英文卡)+对话式生图控制纪律四条(编辑模式/英文优先/分张跑/否定约束);分工纪律转写 art-bible §8.5「生产分工」(模型只出无缝填充纹理,结构件程序化)。 - -- **v2.8(2026-09-25)敌种甲档回填批**(圣经×关卡/世界观对齐扫描发现,规格上游 character-design.md v1.6 同批;用户拍板「按最新设定」):三卡随 `enemy.tres` 甲档实态修订——①熊地精 3.2 两版(A/B)正向:魔法甲「暖白符纹饰带」措辞退役,改轻甲「粗陋皮条+裸蓬毛无甲板」;②食人魔酋长 3.3:标题重甲→轻甲,正向「冷灰金属肩胸甲板」改「皮条骨饰+裸厚皮无甲板」,规格注随改;③蛛化卓尔精灵 3.5:标题重甲→魔法护甲,正向加「卓尔上体暖白秘法符纹饰带」(蛛腹几丁质保留、属天然甲壳),规格注随改。duergar/duergar_king 重甲卡与数据一致不动。 - -- **v2.7(2026-09-23)真像素硬化 + 本地通道清退批**(用户拍板:本地 ComfyUI 生图路线彻底关闭,生图一律线上 API 自跑;gg1 风格诊断后硬化方案顺带写入):①全部 13 张正向卡触发词后插入真像素约束段——`true pixel art game sprite / tiny 48x72 pixel canvas / chunky square pixels / strict pixel grid alignment / hard edges / no anti-aliasing / no gradients / limited 16-color palette / aseprite style`;②各卡负向底座并入平滑系禁词——`smooth lines / anti-aliasing / gradient shading / painterly / glossy / high detail / vector illustration`;③§0「现行管线」句(Z-Image-Turbo GGUF + 像素 LoRA + 母版工作流 `art-t2i-master.json`,成因见 v2.1/v2.5)改写为线上 API 口径,自然语言类模型改写指引顺带;④「ComfyUI 通道」措辞改「生图通道」(文件名沿用不改)。同日 repo 侧清退:`production/comfy/` 已删、comfy-mcp 注册已移除。 -- **v2.6(2026-09-23)配装修订批**(用户四拍板:①弃全蓝——蓝只在兜帽,上衣暖米白、长裤深棕工装,与掩尘棋盘协调;②兜帽取下披肩、露棕色短发;③待机姿势改"铲插地+扶柄";④旗加大到比头大、插背包一侧、可被头部分遮挡):主角三卡正向提示词整体重写(形象锚措辞随改,2.2"斗篷飘动"改"兜帽布料飘动");线上 API 试生成由用户自跑,规格上游 character-design.md 同批升 v1.5。 -- **v2.5(2026-09-23)触发词+肤色批**(用户三拍板:①LoRA 触发词 `Pixel art style.` **加入**——全部正向提示词(主角三卡+八敌种各卡)一律以触发词开头;②肤色改**白皙**(fair skin,弃小麦色),主角三卡随改;③提灯腰挂定案、棋盘小人定案归 character-design.md 同批 v1.4):§0 模型适配注由"待拍板"改"已加入";版本历史承接 v2.4。 -- **v2.4(2026-09-23)衣着细节批**(用户拍板:半指手套 + 卷裤脚皮护膝):主角三卡正向提示词顺带插入 `brown fingerless gloves` 与 `leather knee pads with trouser legs rolled up above them`(皮革族小件,不占剪影预算);§2 形象锚随改;规格上游 character-design.md §5.4 同批升 v1.3。 -- **v2.3(2026-09-23)背包具形批 + 装备彩蛋池**(用户三拍板:①背包措辞与体量——弃"鼓胀掳获袋"改结构式帆布冒险背包,宽 ≈1.5× 体宽,正面参照合金弹头双主角大背包/奇诺比奥队长、反面禁特里式 3× 超宽;②护目镜推额前、头灯退役、灯改小号铜色提灯挂腰间(不点亮);③随身件=魔法道具形象候选池——铲/旗/背包/提灯,道具语义归魔法道具批):主角三卡正向提示词顺带更新(背包短语+护目镜+腰灯);§2 形象锚随改;规格上游 character-design.md §5.4 同批升 v1.2。 -- **v2.2(2026-09-23)掳获包裹批**(用户拍板:背旗改"背负大号鼓胀布包裹、旗杆插于包裹顶"——"地牢扫荡者满载而归"的角色化):主角三卡正向提示词顺带更新(包裹短语 `large bulging tan canvas loot sack tied with rope on his back` + 旗改插于包裹顶);§2 形象锚随改(包裹、旗与铲三态恒在);规格上游 character-design.md §5.4 同批升 v1.1。 -- **v2.1(2026-09-23)主角特征批**(用户两拍板:直剑→圆头挖掘铲——挖安全格动作语义角色化,攻击表现即挥铲;背后加旗朱三角旗——与棋盘插旗同物同色 `#C63D22`):主角三卡正向提示词顺带更新(铲+背旗短语,三态同旗同形象,背旗为主角唯一破对称件);§2 形象锚与 2.1/2.2 规格措辞随改(2.2"刀光"改"铲击光效");规格上游改指 character-design.md §5.4(人物设计自圣经 §5 抽离成独立文档,圣经 §5 为存根);§0 模型适配注补现行管线(Z-Image-Turbo GGUF + 像素 LoRA 已挂母版工作流,触发词 `Pixel art style.` 入正向待拍板)。 -- **v2.0(2026-09-22)重生成批**(用户拍板正序:美术圣经 §5 角色设计落地(v1.6)后重写本卡;v1.0 于同日经裁决移除,状态记录 125):六敌种→**八敌种**(新增灰矮人/钩爪恐魔/灰矮人石君王三卡);**逐资产提示词改自包含完整串**(正向底座+主体+动作拼妥、负向底座+增补并妥,整段可直贴,零拼装);主角蓝族随 art-bible v1.1 换装(`#2E86DE`,同族候选 `#5FA8E8`/`#1C5CA4`);护甲视觉短语按 §5.3 注入各卡(轻甲无甲板/魔法护甲暖白符纹/重甲冷灰甲板,天然甲壳不计甲档);bugbear 主体由「高瘦」改「敦实圆肩」守 §5.1 普通怪宽≥高;兄弟精备选配色弃冷蓝灰(蓝族禁入敌方)改灰褐战纹;验收速查五关→六关(增甲档);引用基线改 art-assets-checklist 单清单(asset-checklist 已随合并批删除)。 -- v1.0(2026-09-20):首版。主角三态 + 六敌种提示词卡成文;兄弟精改荐脚本换色通道;候选入库/后处理/转正五步流程成文。(2026-09-22 移除,本版为重生成。) diff --git a/design/art/character-design.md b/design/art/character-design.md index 14c2ffeb..dfd73c33 100644 --- a/design/art/character-design.md +++ b/design/art/character-design.md @@ -80,16 +80,3 @@ - **终稿帧规格**(帧数/时长/结算节拍对齐)归圣经 §8 资产规范与战斗一屏样张批(清单 §2.3);占位符号(—/⚔/✦/蓄力)现行在役,动画到位后原位替换。 --- - -## 版本历史 - -- **v1.9(2026-10-06)主角描边例外条款批(审计报告待决项 B 用户拍板)**:§5.1 新增**主角描边例外**条——主角四态硬描边 = 深褐 `(40,19,13)` 显式例外(浅砖面对比更高/主角更突出),敌人维持暖白族;系描边不一致的定性完成(不一致源自早期生成素材,按用户口径以约束条款认可为有意设计,素材不改);样张批终审复核义务登记 06 待办。 -- **v1.8(2026-10-06)体量语义修订+立绘源档定档批(P0 完成讨论批;工作流程铁律 = 只动文档,代码实装另批走 PRD→迭代)**:①**§5.2 体量档位改「生物体型通道」**——原「强度先验·普通 < 精英 < Boss 单调递增」读法退役,依据 = 用户三体型约束(钩爪恐魔>灰矮人/灰矮人<熊地精/食人魔>熊地精,小体型精英与大体型普通怪并存);强度先验读法改由意图徽标(§5.6)与甲档(§5.3)承担;②**§5.5 新增立绘源档高注记**(八敌 36–94 定档、主角 48 不变、显示 ×2 整数档;圣经 §8.2 v3.7 同批)+**钩爪恐魔「宽≥高」豁免登记**(58 高窄条束状剪影,待样张批终审)。 -- **v1.7(2026-09-28)人设旗脱钩批**(用户三拍板:①背包旗与棋盘封印色脱钩——封印色沿革〔旗朱 #C63D22→封印紫 2026-09-26→封印黑 2026-09-28〕仅作用于棋盘格封印旗,封印黑仅棋盘格,人设旗回归旗朱红 `#C63D22`;②旗形三角→矩形,以 normal/hit 定稿成图为基准;③兜帽=披肩式披于颈肩非垂背):§5.4 形象锚/背包旗条顺带。 -- **v1.6(2026-09-25)甲档核对回填批**(圣经×关卡/世界观对齐扫描发现;用户拍板「按最新设定」:食人魔裸身、卓尔魔法甲符纹):§5.5 三行甲档回填 `enemy.tres` 数据实态(2026-09-18 甲重配批后未回填的过期账)——bugbear 魔法护甲→轻甲(粗陋皮条无甲板无符纹)、ogre_chief 重甲→轻甲(弃冷灰金属甲板,改甲面覆盖率≈0 的裸身皮条/骨饰)、drider 重甲→魔法护甲(加符纹饰带);§5.5 头注事实源措辞随改;提示词卡 v2.8 熊地精/食人魔/卓尔三卡顺带。giant_spider/hook_horror 的几丁质天然甲壳纪律不变(不计甲档,§5.3)。同日封印术语批:§5.4 插旗条附「插旗动作呈现名 = 封印」注记(详见 art-bible v2.7)。 -- **v1.5(2026-09-23)配装修订批**(用户四拍板:①弃全蓝配色——蓝只保留在兜帽等明显处,上衣改暖米白、长裤改深棕工装,与掩尘棋盘协调;②兜帽不戴头上、取下披于肩上,露棕色短发与脸;③待机姿势改"铲插立地上、一手扶铲柄";④旗子加大到比头大、插在背包一侧,可被头部分遮挡):§5.4 形象锚/配色条/铲条/背包旗条/护目镜条顺带;提示词卡 v2.6 三卡顺带。线上 API 试生成渠道由用户自跑(本地 ComfyUI 通道同日停用)。 -- **v1.4(2026-09-23)肤色+定案批**(用户四拍板:①肤色**白皙**(fair skin,弃小麦色);②LoRA 触发词 `Pixel art style.` 加入——执行侧提示词卡 v2.5 全卡正向以触发词开头;③提灯腰挂定案不手持(备选撤销);④棋盘小人定案 = 主角人设图压缩至二头身的简化版像素小人,随人设派生、同款装备剪影):§5.4 形象锚/腰灯条/棋盘小人条顺带。 -- **v1.3(2026-09-23)衣着细节批**(用户拍板:半指手套 + 卷裤脚皮护膝):§5.4 形象锚顺带,新增衣着细节条(棕色半指手套/裤脚卷起+棕皮护膝,皮革木色族,不占剪影预算);提示词卡 v2.4 三卡顺带。 -- **v1.2(2026-09-23)背包具形批 + 装备彩蛋池**(用户三拍板:①背包措辞与体量——弃"鼓胀掳获袋",改结构式帆布冒险背包(翻盖+皮扣带),宽 ≈1.5× 体宽两侧各露一点,正面参照合金弹头双主角大背包/奇诺比奥队长、反面禁特里式 3× 超宽;②头部饰品唯一化——护目镜推额前,头灯退役,灯改**小号铜色提灯挂腰间**(不点亮,备选另手持);③随身件=魔法道具形象候选池登记——铲/旗/背包/提灯四件,道具语义归魔法道具批):§5.4 形象锚/身份件条/三态①顺带,新增护目镜与腰灯条、候选池条。 -- **v1.1(2026-09-23)掳获包裹批**(用户拍板:背旗改"背负大号鼓胀布包裹、旗杆插于包裹顶"——"地牢扫荡者满载而归"的角色化;包裹帆布暖卡其色+绳索捆扎):§5.4 形象锚/身份件条/三态①记账顺带,旗朱三条纪律不变(破例组改按"包裹+旗"整组)。 -- **v1.0(2026-09-23)§5 抽离批 + 主角特征批**(用户两拍板:①人物设计自圣经 §5 抽离成独立文档、圣经留引用存根——人设高频改动免动圣经;②主角两特征改动——背后加扫雷联动旗帜、直剑换挖掘铲):§5.1–§5.3/§5.5/§5.6 自 art-bible v1.6 原文迁移(圣经内部节引用改注"圣经 §x"前缀,小节号不变);**§5.4 重写**——形象锚"直剑"改"圆头挖掘铲"(挖安全格动作语义角色化,攻击表现即挥铲),新增"旗朱背旗"(与棋盘插旗同物同色 `#C63D22`,主角唯一破对称件、旗面恒定画右、凹凸预算 +1),三态②"刀光"措辞改"铲击光效";新增生成顺序口径(先人设后状态图,侧背身状态卡按卡摘负向禁侧背条)与棋盘小人同旗开放项(归样张批)。执行侧 comfyui-prompts.md 主角三卡顺带更新(v2.1)。 diff --git a/design/engineering/code-conventions.md b/design/engineering/code-conventions.md index 528abb7c..fdee417a 100644 --- a/design/engineering/code-conventions.md +++ b/design/engineering/code-conventions.md @@ -95,6 +95,6 @@ ## 6. 流程纪律 -1. **大改动三段走**:设计稿/伪代码 → 用户审阅 → 实现;实现禁止先于审阅。修改记录落切片 README。 -2. **实现批完成后的登记义务**:切片 README 写修改记录,06 条目按 doc-conventions §12.1 推进状态,批次过程与结论进 git 提交信息与 `reports/`(2026-10-18 用户裁:根目录会话状态文件已废除,禁止再在其中登记条目)。 +1. **大改动三段走**:设计稿/伪代码 → 用户审阅 → 实现;实现禁止先于审阅。改动明细只进 git 提交信息,README 与代码内不写修改记录(doc-conventions 第 5 节「禁写变更记录」)。 +2. **实现批完成后的登记义务**:06 条目按 doc-conventions §12.1 推进状态,批次过程与结论进 git 提交信息与 `reports/`(2026-10-18 用户裁:根目录会话状态文件已废除,禁止再在其中登记条目)。 3. **呈现层缺陷的教训回写 D1 GDD 设计输入**(信号载荷 schema / 场景级测试 / 时点状态可见性)。 diff --git a/design/engineering/doc-conventions.md b/design/engineering/doc-conventions.md index 127be8e5..c6321303 100644 --- a/design/engineering/doc-conventions.md +++ b/design/engineering/doc-conventions.md @@ -66,7 +66,7 @@ | 一系统一文档 | 不建 analysis 推演件;两三句能说清的"为什么"直接写进设计目的或规则正文 | | 正文只写现行规则 | 禁删除线、"(作废)"、"(日期+拍板)"式注记;审计信息入对应文档附录 | | 正文单点维护 | 一条规则句只写在定义它的那份文档(owner 文档);其他文档要引用时写指针或语义概括,禁复制色值、尺寸、路径等可核对的具体值——上一句管不住数值之外的双写,本句补上。豁免面 = 执行侧文件必须带字面值才能工作时(生图提示词里的十六进制色、脚本参数),转写不算双写,但该文件头部必须写明"冲突时以 owner 文档为准" | -| 后置 ≠ 删除 | P1/P2 后置内容逐条列出;复活后置项 = 修订文档,禁静默加回 | +| 禁写变更记录 | 文档与代码文件内一律禁设「版本历史/修订记录/变更记录/修改记录/更新记录/更新日志」节或表格,禁逐版本叙述「改了哪些条款」;沿革与改动明细只进 git commit log。版本号可作为文档现行身份标记出现在文首状态行与正文引用中,但不得再挂变更表 || 后置 ≠ 删除 | P1/P2 后置内容逐条列出;复活后置项 = 修订文档,禁静默加回 | **数值纪律**:正文定规则、取值域、单位;平衡值进 `data/tables/`,provisional 必须标注;已锁数值事实源 = `game/data/tables/*.tres`(现行值)与 owner 文档正文(规则、取值域、单位)。 @@ -93,7 +93,7 @@ | `06-待办清单.md` | 流水线唯一登记处:条目=登记元数据标题+四属性正文,状态随流水线段推进(格式与状态机见第 12.1 节);各系统文档「待办」节只留指路存根 | | `roadmap.md`(根目录) | 里程碑表+迭代总表,一行一迭代,记录编排与实现进度(六列格式见第 12.2 节) | -**系统文档骨架**(`systems/` 下统一采用):文首引言(一句话定位+状态+旧版链接)/设计目的(2-4 句白话)/系统范围(负责/不负责两表)/在核心循环中的位置(字符画一行+两句白话)/核心规则(领域章节 ×2–6,每节一页纸)/依赖与输出(表格;引用纪律见 concept-conventions)/P0 最小闭环与 P1·P2 后置/调参表(取值域+provisional 标注)/验收标准(可验证判据)/待办(指路存根)/版本历史(表格)。 +**系统文档骨架**(`systems/` 下统一采用):文首引言(一句话定位+状态)/设计目的(2-4 句白话)/系统范围(负责/不负责两表)/在核心循环中的位置(字符画一行+两句白话)/核心规则(领域章节 ×2–6,每节一页纸)/依赖与输出(表格;引用纪律见 concept-conventions)/P0 最小闭环与 P1·P2 后置/调参表(取值域+provisional 标注)/验收标准(可验证判据)/待办(指路存根)。 **命名**:中文、见名知意;禁 a1_/b1_ 编号前缀;不留纯空目录。正文指代子系统一律用中文规范名;英文代号对照表见 `02-系统清单.md`,旧代号(a1–d6)仅限解读归档。 diff --git a/design/gdd/00-游戏概念.md b/design/gdd/00-游戏概念.md index fa20b253..f1ed365b 100644 --- a/design/gdd/00-游戏概念.md +++ b/design/gdd/00-游戏概念.md @@ -60,13 +60,3 @@ 注意:上表六件秘宝为旧目录,已全数退役、只作素材库(新现行事实源=[秘宝](systems/跨局循环/秘宝.md)「目录(重设计 v1)」节——新目录 15 件为代号制、正式命名归用户);新目录正式命名定稿后本表同步。 另:元进度系统资源定名**钥石**——每一层关底 Boss 看守他那块区域的钥石,击杀即取走,用于在存档内解锁永久提升(属性 / 怪物遭遇 / 道具池)。2026-09-14 用户拍板,registry 术语登记随元进度设计批补登。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v1.0 | 2026-09-14 | 初版随 GDD 骨架建立:一句话概念、目标受众、世界观命名、术语层级 | -| v1.1 | 2026-09-25 | 术语「封印」定稿(用户拍板):插旗动作呈现名落术语表,出处条目 terminology | -| v1.2 | 2026-10-03 | R3 清账批(gdd_lint 分域随批):术语表日期批注括注迁出至本表 v1.1 行;语义零变更 | -| v1.3 | 2026-10-09 | 文档正确性审查批:专名表下「部分秘宝效果待重定」注过期——六件旧目录秘宝已随目录重设计全数退役、只作素材库,注改写为退役指路(新现行事实源=秘宝.md「目录(重设计 v1)」节,registry 登记行随实装批迁移);表格登记事实本体不动 | -| **v1.4** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:「元进度资源定名钥石」→「元进度系统资源定名钥石」——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/01-核心循环.md b/design/gdd/01-核心循环.md index d05f0625..124f3178 100644 --- a/design/gdd/01-核心循环.md +++ b/design/gdd/01-核心循环.md @@ -160,19 +160,3 @@ **获取概率提升**是元进度/营地的合法提升轴(可提升=奇物高档位出现率/秘宝解锁进度/地图 T3/T4 权重),但**不动保底**——保底是承诺不是概率,禁止任何概率件改变 T3「每板必有回复」类承诺。 **专长 rarity 语义约束**:Boss 三选一候选按档配比或加权抽取,使罕见度对出现率生效(字段双脱钩修复——此前 rarity 不影响抽选也不稳代表幅度);具体配比归调参批。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v1.0 | 2026-09-14 | 初版随 GDD 骨架建立:一场战斗 / 一场冒险 / 死了之后三节 | -| v1.1 | 2026-09-18 | 「数值语言」节定稿(用户拍板:整数加减核、百分比仅三处既有粗档、全局 floor) | -| v1.2 | 2026-10-03 | R3 清账批(gdd_lint 分域随批):节标题日期批注迁出至本表 v1.1 行;语义零变更 | -| v1.3 | 2026-10-07 | **生命周期轴(五档)节新立(道具重设计框架讨论用户裁决落文)**:五档定义(存档/冒险/关卡=预留档/节点=一次停点不按类型分档/回合)、节点链 DAG 前提(只向前·无环·只进一次)、一次性结算与持续态结算模型(跨层=转换非横跨,类A→类C)、总线与抽屉两类结算目标、道具定义卡 3+1 句、GP 与钥石两条平行独立资源;AP 两账/刷新两账/增益容器各归域内现行事实源(行动经济/秘宝/冒险结构/元进度同批落文) | -| v1.4 | 2026-10-07 | **道具三层职责与分界定稿(用户裁决——哈迪斯2 塔罗牌/祝福同构分界)**:新节落三句职责(秘宝=营地装配的角色机能件/奇物=冒险途中当局清零的增益/地图战斗资源=回合内获取并结算的格面兑付,地图层坐标经用户纠正——装板期生成、回合内获取与结算)+ 机能/机制/属性值判定尺 + 分层准入约束(新建秘宝必检:不出裸属性值、不改战斗结算机制;战斗机制改写只走专长);现行秘宝目录机制向三件(淬毒刃纹/标中殉爆/惊巢反制)经用户点名与本约束不符,归留秘宝层重设计批处置,冻结期内维持现状 | -| v1.5 | 2026-10-07 | **跨层档位框架落文(用户裁——道具三层重设计)**:分界节新增「档位与获取规则」分节——稀有度四级统一=**普通/优秀/稀有/传说**(「优秀」=用户认可的「非普通」优化:无双否定、WoW 绿装先例、正面积木递进;DND 六级梯子中取四、跳档表意头奖级);分层语义=秘宝档位越高解锁越苛刻/奇物越高概率越低/地图=概率位+保底上限;获取概率提升=元进度/营地合法轴但**不动保底**(保底=承诺非概率);专长 rarity 语义约束=Boss 三选一按档配比或加权(字段双脱钩的文档面修复,配比归调参批) | -| v1.6 | 2026-10-07 | **同调位分档批(用户裁——道具三层重设计·秘宝层)**:档位与获取规则节秘宝行扩装配面——同调位分三档(普通格/优秀格/稀有格),槽位可装 ≤ 槽位档位的件(向下兼容不惩罚早解锁);里程碑分档发槽(m1 普通格/m2 优秀格/m3 稀有格);费用制落选留档(槽位仅 3 组合太小);现行事实源落点=[秘宝](systems/跨局循环/秘宝.md)速览节同批 | -| v1.7 | 2026-10-10 | 分界尺措辞精确化(2026-10-10 用户澄清):秘宝行「不出裸属性值」精确为「不出角色战斗属性值」+操作包络正向列举(经济与操作参数不在此限)——「属性值」定义行(生命/护甲/攻击/伤害)不变;机制零改动 | -| v1.8 | 2026-10-11 | 文档一致性修复批(定时检查呈报项):「生命周期轴(五档)」节补五档嵌套字符画(R5 实指——lint 报错因工具 prev/cur 错位误记到「死了之后」节名下,工具已同批修正);「死了之后」节顺带补死亡与重开循环字符画(内容补强);版本历史同号冲突顺延——2026-10-10 分界尺措辞行 v1.5→v1.7(R10);v1.6 行秘宝链接改指跨局循环新位(死链修复) | -| v1.9 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 6 处——「若干行动点」改指路行动经济/删「模板 C 骨架+模板 A 成长语言」无出处括注/DAG 首现补全称有向无环图/buff 换代增益 3 处/「不得改变」改「禁止」/「对标哈迪斯」改「参照」;版本历史行序修复(v1.7 行归位 v1.6 后)。句式句长不动(STC 文体豁免) | -| **v1.10** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:新立「系统资源」节(原「两条独立资源」):成员带寿命档标注+总线/抽屉两坐标,保留「GP 与钥石平行独立、不立统一上位概念」原裁论断,显式排除增益容器;总线/抽屉/一次性结算/五档表/各域指针节同步换代;旧称「账/账本」「独立资源」「系统数值」全库退役——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/02-系统清单.md b/design/gdd/02-系统清单.md index fe27cb1e..a2e7f08c 100644 --- a/design/gdd/02-系统清单.md +++ b/design/gdd/02-系统清单.md @@ -118,43 +118,3 @@ > 2026-10-05 消歧更名批注记(用户拍板):`AUXILIARY_ITEMS` 的中文规范名「魔法道具」→「**秘宝**」(理由与代码不同步的欠债登记见[秘宝](systems/跨局循环/秘宝.md) v0.9 版本行)。英文代号**继续沿用 `AUXILIARY_ITEMS` 不变**——代码标识符与工具链口径不动,对齐另批。 > 四个循环本身的英文代号为 `MINESWEEPER_CYCLE`(排雷循环)、`COMBAT_CYCLE`(战斗循环)、`ADVENTURE_CYCLE`(冒险循环)、`PRESENTATION_SUPPORT`(表现与支撑)。 - -## 版本历史 - -| v0.1 | 2026-09-15 | 根索引随新骨架建立:循环 × 子系统总表 + 子系统命名对照表 | -| v0.2 | 2026-09-15 | 雾格残留清理:`地形变异.md` 概要行去掉"雾格已从设计中移除"的迁移期注记(移除事实以[不做清单](05-不做清单.md)为单一出处)。文档树形状不变 | -| v0.3 | 2026-09-16 | 更名批(用户拍板 2026-09-16):两个系统中文规范名更名——"奖励道具经济"→"地图战斗资源"、"辅助道具"→"魔法道具";循环表文件行与命名对照表中文规范名同步(文件重命名 地图战斗资源.md / 魔法道具.md);英文代号暂沿用更名前名称,对齐另批 | -| v0.4 | 2026-09-16 | 格面资源批 UI 欠账收口(2026-09-15 格面资源批删除可选类道具后,本索引与 UX 文档的随批修订):`地图战斗资源.md` 概要行由"奖励产出、道具库存与使用窗口"(格面资源批前旧描述)改为与其 GDD 头部一致的一句话口径"格面资源的产出、极性字典与清图奖励封装";同批收口 battle.md / HUD框架.md 中随可选类道具删除而失义的道具窗口条款(文档本体修订见各文版本历史) | -| v0.5 | 2026-09-16 | 待拍板收编批:新建顶层文档 `06-待拍板清单.md`,把 systems/ 各系统文档「待拍板」章节的条目与三份文档的散落未定项统一收编;各系统文档「待拍板」节改为指路存根,其后新增条目直接登记清单 | -| v0.6 | 2026-09-16 | 06 清单改版(用户拍板):「待拍板」术语全仓改「待办」,顶层文档更名 `06-待办清单.md`;本表 06 行同步,各系统文档存根节随批由「待拍板」改名「待办」(各文版本历史不另记存根改名) | -| v0.7 | 2026-09-17 | 关卡节点地图定稿批:`关卡节点地图.md` 状态行改**已定稿**(v1.0——分支节点图形态重开〔用户拍板重开 05 清单路径分支后置裁定〕、四类节点封闭枚举、全节点确认选路、遭遇构成编排面三条、节点奖励=功能道具正式渠道;概要行"节点链"改"节点图";配套 05 清单移除路径分支条目、06 清单三悬案收口 + 两条新增、registry level_table 与术语回填) | -| v0.8 | 2026-09-21 | 元进度实现批:`元进度.md` 状态列「范围草案·待设计」→「已定稿·已实现」(2026-09-21 实现批落地,数值 provisional 归设计批标定) | -| v0.9 | 2026-09-27 | UX 文档欠账处置批:`ux/` 目录入索引(battle.md / interaction-patterns.md / 新建 level-clear.md);四项欠账处置——player-journey 不建、accessibility-requirements 不另立(改指 HUD框架 基线 + 设置与本地化)、node-reward 挂魔法道具内容重定批(06 登记)、level-clear 建档 | -| v1.0 | 2026-09-27 | 节点图生成立项批(用户拍板立项——06 条目「关卡内结构随机生成」随批改状态):`systems/冒险循环/` 新建 `关卡节点图生成.md` 设计草案 v0.1(图模板/模板池/抽签三概念、三级台阶路线、MC 测量对账条款、五拍板点);文档树补行 + 命名对照表补 `NODE_MAP_GENERATION` 行 | -| v1.1 | 2026-09-27 | 关卡画面 UX spec 建档(关卡画面 UX 批):`ux/` 表补 `level-map.md` 行——选路枢纽三停点布局、GP 常驻徽章、交互映射与 AC 成文,三项设计提案挂 06 待拍板 | -| v1.2 | 2026-10-03 | R3 清账批(gdd_lint 分域随批):四处状态单元格日期批注迁出——敌人系统行事件见敌人系统.md 版本历史 v0.5(技能池批);元进度行见本表 v0.8;camp/shop 行=两文 v1.0 落文(2026-09-30 三裁决执行批);语义零变更 | -| v1.3 | 2026-10-05 | **消歧更名批(用户拍板 2026-10-05)**:a5 行中文规范名「魔法道具」→「**秘宝**」,文档树文件名同步(systems/排雷循环/魔法道具.md → 秘宝.md);英文代号 `AUXILIARY_ITEMS` 沿用不变(代码标识符不同步属已知欠债,另批);旧代号列不变(a5 仍指 2026-09-14 归档快照)。更名理由为「魔法」一词已被本作征用为敌方侧伤害/护甲语汇(`魔法矢`/`魔法族`/`魔法护甲`),详见[秘宝](systems/跨局循环/秘宝.md) v0.9。历史定稿文档(research/qa/archive)原样保留 | -| v1.4 | 2026-10-05 | 立《特性》:一次冒险内角色自身得到的提升——此前按内部分类被叫成三个名字(规则类称"流派件"、属性类称"数值件"、界面称"本关强化"),现收敛为一个对象的两种形态枚举;文档树冒险循环补行 + 命名对照表补 `ADVENTURE_FEATURE` 行 | -| v1.5 | 2026-10-05 | 《特性》v1.1 分类重构:两类由"规则改写型 / 属性加成型"改为"属性提升(ASI)/ 专长(Feat)",属性提升内部再分纯属性组与特殊组;获取途径由两口共用池改为三条分工渠道(专长走特定节点、属性提升走奖励节点与商店)+罕见旁路"专长获取" | -| v1.6 | 2026-10-05 | 《特性》改名为《奖励》并升 v2.0:顶层概念改为"一次冒险内各渠道给予玩家的增益总称",边界判据由"自身提升 vs 持有物"改为生命周期(当局清零的是奖励,跨局带走的是魔法道具);分类由两类扩为三个枚举(专长 / 属性值提升 / 资源与机会类),并新增分类 × 渠道交叉开关表——两根轴互不决定。文档树冒险循环行改名 + 命名对照表 `ADVENTURE_FEATURE` → `ADVENTURE_REWARD` | -| v1.7 | 2026-10-05 | 《奖励》v2.1 交叉表收口:Boss 渠道只出专长(终局 Boss 不给),另两类在此不出现;新增「计价物不自售」规则处理金币不进商店——不拆第四个分类、不开特例,而是两轴交叉处的一条约束 | -| v1.8 | 2026-10-05 | 《奖励》v2.2:专长在非 Boss 渠道改为「专长获取」凭证形式(不直接给专长);渠道约束重构为三层(分类白名单/可计算谓词/显式例外清单),并承认「计价物不自售」形式上是白名单外的一道过滤、与死特判的区别在可计算;立默认原则——除已登记规则外分类内的都要在池子里,据此回复应在商店内(现行货架缺它,须补) | -| v1.9 | 2026-10-05 | 《奖励》改名为《奇物》并升 v2.4:顶层定名 Wondrous Item(DND 魔法物品九分类中的兜底杂类,官方中文译名「奇物」)。文档树冒险循环行改名;命名对照表 `ADVENTURE_REWARD` → `ADVENTURE_CURIO`(**不用 `reward_*`**——`reward_pick` 流 / `reward_node` context / `reward_preview` kind 已占用该词族) | -| v1.10 | 2026-10-05 | 《奇物》v2.5:第三类定名「资源」(资源偏泛,故在命名出处节写死判据句——给的是可消耗或可重掷的余量,不是属性永久抬升);回复归属定案留在本类不拆第四类;修复 1.5 段末与渠道轴标题粘连 | -| v1.11 | 2026-10-05 | 《奇物》v2.7 三个子节点正式定名:专长(Feat)/ 属性值提升(ASI)/ 资源——去「类」字后缀,此前是描述式叫法不是专名;新增 1.6 节「三层结构与命名」,定玩家可见的三层(奇物 / 三个分类 / 具体单件),并明确命名与呈现是两件事 | -| v1.12 | 2026-10-06 | 生涯设计立项批(迭代 17 卡④,纯文档):新建 `systems/跨局循环/生涯.md` 设计提纲 v0.1(信息架构 / 承载内容清单 / 与既有界面关系 / 分期实装建议 / 待裁点五节;状态=范围草案待评审——P0-P5 已裁结论落文,新发现待裁点 P6 营地最近冒险条带去留)。文档树跨局循环补行 + 命名对照表补 `CAREER` 行(无代码实现面,代号随实装批对齐) | -| v1.13 | 2026-10-07 | 道具三层职责分界批随批(用户裁——规则现行事实源=[核心循环](01-核心循环.md)「道具三层职责与分界」节 v1.4):秘宝行概要由「扫雷侧秘宝(显影、探测类)」(同调形态起已滞后)换代为「营地装配、整局冒险生效的角色机能件」;状态列随去迁移注记 | -| v1.14 | 2026-10-07 | 奇物层重设计落地随批(现行事实源=[奇物](systems/冒险循环/奇物.md)版本历史 v2.9-v3.4——专长体系推倒重建+资源转换源+池结构案D+跨层档位框架):奇物行概要与状态同步——概要补「专长=触发器句式的机制件/资源=转换源凭证」,状态改「已实现·2026-10-07 专长体系重设计落地(18 件基础框架+池结构案D)」 | -| v1.15 | 2026-10-09 | 旧档引用摘除批(用户令——旧版 GDD 归档 design/archive/gdd-2026-09-14/ 已删,全部指涉摘除):「旧代号」句不再指涉归档路径(仅解读 2026-09-14 之前历史记录);旧骨架索引参考行整行摘除。语义零变更 | -| v1.16 | 2026-10-09 | 文档正确性审查批(ux 表五行在役态对齐):node-reward 行「v1.0·切片期过渡形态随同调实施批退役改写」过期——退役改写已兑现,改 v2.5 令牌池在役口径;level-map 行「占位升格版·视觉终稿后置」过期——改定稿版(独立屏+样张 v1 冻结);shop 行「三商品卡全陈列」过期——pool 模式在役,改令牌级货架+v1.1;camp/settlement-summary 行版本号顺延 v1.1/v1.2。文件清单一轮只读核对零死链 | -| v1.17 | 2026-10-09 | B1 裁决落文(用户令——天赋树独立成文):跨局循环区补 `天赋树.md` 行(系统随迭代 12 实装在役,文档 v0.1 补写——机制以代码实态与迭代 12 落地裁决为据);命名对照表本批不动(代码标识符面 meta_tree 在役,代号登记另批) | -| v1.19 | 2026-10-10 | **系统目录归位批(用户发现结构问题)**:`秘宝.md` 自排雷循环区迁入跨局循环区——生命周期裁定=解锁(秘宝匣+解锁条件表)/装配(营地柜台)/存档持久全在跨局侧,排雷循环仅生效现场;成因=前身「辅助道具」系切片期掉落形态故旧置排雷循环,同调换代未随迁。文档树两区换行+系统总表行移区+命名对照表不动(代号 AUXILIARY_ITEMS/旧代号 a5 不变);全仓引用路径 33 处随批同步(版本历史与注记行内的历史路径按纪律保留) | 武器锻造成文批(用户令「完成文档编写、代码不实现、记录待办」):跨局循环区补 `武器锻造.md` 行(v0.1 设计定案待实装——按 2026-10-07 提案推荐案落文,17 裁点开放在册待逐点裁决);系统总表补行(无代码实现面,代号随实装批对齐) | -| v1.20 | 2026-10-11 | **术语表建立+全库术语统一批(用户令「专用术语表查表阅读」+危险格/整图/专长凭证三更名)**:顶层文档表补 `术语表.md` 行(v1.0——四节术语+退役词对照);同批全库更名=雷格/惩罚格→危险格、板级→整图、门票→专长凭证(清扫 7 文件约 270 处;排雷玩法定义句换代、秘宝.md v2.5 可读性批随批) | -| v1.21 | 2026-10-11 | 文档一致性修复批(定时检查呈报项):顶层文档表术语表行多余版本列摘除(R6 列数一致);奇物/天赋树/武器锻造三行状态格修订注记改写为现行事实白话句并换代版本号(天赋树 v0.4 换代定稿 29 节点、武器锻造 v0.2),日期批注归本表版本历史承载(R3) | -| v1.24 | 2026-10-12 | **迭代 20 反哺落文批·奇物行换代(用户裁④确认)**:奇物行状态格「基础框架 27 件,自爆流与生存件扩容后」→「迭代 20 专长实装批落地(29 行=基础 27+迁入 2,流派机制退役;池结构案D 四级 104,通关兑付=专长三选一按档配比加权)」 | -| v1.22 | 2026-10-11 | 锻造工坊更名批随迁:`武器锻造.md` 改名 `锻造工坊.md`(系统更名,用户令),顶层文档表行与系统总表行随名换代并顺延版本注(v0.3);版本历史行内旧名按历史记载保留 | -| v1.23 | 2026-10-11 | 锻造工坊 A 组定案随迁:锻造工坊行版本注换代 v0.4(A 组三裁+攻防所有权切分〔树脊柱砍攻/护两线,树侧 29→21 归天赋树会话交接批〕+钥匙无前置+2c/5a 结案) | -| v1.25 | 2026-10-12 | **锻造工坊 B 组定案随迁(用户逐点裁决)**:锻造工坊行版本注换代 v0.5、描述格随裁换代——两区定名(武器锻造区/护甲锻造区)、三甲型统一命名「魔法护甲」、一次冒险各选一件、**满级特效本期不做留扩展位**;**17 裁点清零**(推翻推荐案四行 2a/3b/6/8a,撤回呈报子问 4a-1),开工门裁点侧已满足、仅剩用户发令;设计文档「裁决结果清单」+「工作间内容清单」两节为实装批需求卡片输入 | -| v1.26 | 2026-10-13 | **Alpha 版本标准立文(用户令「先定里程碑内容」)**:顶层文档表补 `08-Alpha版本标准.md` 行——Alpha 版本包含哪些东西的清单,即里程碑 M3 的完成标准;只列条目不写内容,定义一律指路各权威文档。本文只管「有什么」,系统与内容的定义权仍归各自权威文档,本表不复制其内容 | -| v1.27 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 2 处(关卡节点图生成行「拍板点全落文」→「拍板点全部已写入」;battle.md 行「Complete·随批修订」→「Complete·顺带修订」)+失同步修复 1 处(顶层文档表 08 行「已定稿 v1.0」→「已定稿 v1.4」,对齐 08 篇现行定稿版本) | -| **v1.28** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:奇物行「资源=转换源凭证」→「补给=给系统资源加一笔的转换源」——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/03-内容规模.md b/design/gdd/03-内容规模.md index c329d1b0..31d1f9c7 100644 --- a/design/gdd/03-内容规模.md +++ b/design/gdd/03-内容规模.md @@ -69,22 +69,3 @@ MVP 不加新状态;扩容走 `status_effects.tres` 加行 + [增益状态](sy - 战后自动回复——回复只有道具与恢复点两个来源 - 新敌种、新棋盘档位、更高密度、同深度多敌种混搭 - 秘宝清单之外的新件、状态表之外的新状态 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-09-15 | 顶层六文档成文:关卡 / 敌人 / 棋盘 / 战斗道具 / 辅助道具 / 状态六项体量 | -| v0.2 | 2026-09-15 | 雾格残留清理:棋盘、辅助道具、暂不做三处去掉"雾格已移除 / 不依赖雾格"的迁移期注记,改指[不做清单](05-不做清单.md)。体量数字不变 | -| v0.3 | 2026-09-17 | 数值纪律收口批:全文改指路化体例——种数/行数/幅度不再抄配置,事实源改 data/tables/*.tres 与 registry;同步三批次失同步(两关落地/可选类删除/数值压缩) | -| v0.4 | 2026-09-20 | 层名改名批:第一层「苔藓回廊」→「裂颚洞窟」(用户拍板——苔藓意象与地精巢穴不契合;新名致敬 DND 5e《凡戴尔的失落矿坑》地精部族「裂颚」Cragmaw,洞窟纵深连通幽暗地域)。关卡表 display_name / registry / 00-游戏概念 / 切片首页按钮 / README 随批同步 | -| v0.5 | 2026-09-20 | 层名二改批:「裂颚洞窟」→「地精洞窟」(用户拍板——不绑定 DND 专名部族、规避 IP 指涉,直取地精巢穴意象;v0.4 出典随之作废仅留档)。全仓 8 处消费面随批同步 | -| v0.6 | 2026-09-20 | **第三关内容批(灰矮人矿城——与切片代码 / registry / 难度曲线与Boss / 棋盘生成 / 地形变异 同批)**:层名表加第三层(测试直入口已落地、正式序列推进待收尾——正式三关序列推进仍登记 Alpha 验收条件);棋盘尺寸条款由两档改按关配置(第三关 13×13 / Boss 14×14 随批铺行);棋盘节地形变异句随批补第三关一对(落石/矿尘);暂不做「更多关卡」行更新为已按扩展批流程落地。行值读 `data/tables/level.tres` / `board_gen.tres` / `variation.tres`(registry 为准) | -| v0.7 | 2026-09-20 | **GP+商店房批(与切片代码 / registry / 关卡节点地图 / 冒险结构 / 战斗结算 / 地图战斗资源 / 难度曲线与Boss 同批)**:格面资源池"八型 × 正负两向(十六格)"→"九型 × 正负两向(十八格)"(+gp 金币);新增「商店」小节一行——shop.tres 读表纪律(商品三行 / 掉落参数 / 价格参数,全部 provisional 归曲线调参批);一句话定位句补"一套商店配置" | -| v0.8 | 2026-09-21 | **冒险结构实现批(与切片代码 / registry / 冒险结构 同批)**:层名表 L2/L3 状态行改「正式序列已生效」——首页「开始冒险」三关连探落地(AdventureRunner 编排;测试直入口保留);「更多关卡」行同步;正文零历史叙述纪律下仅状态口径更新,结构框架零改动 | -| v0.9 | 2026-09-21 | **元进度实现批(与切片代码 / registry / 元进度 / 02 / 05 同批)**:「暂不做」节移除「元进度与跨局成长」行——跨局成长首批落地(营地三柜台 / 钥石账本 / 跨局注入,数值 provisional 归元进度设计批标定);新增「一套元进度配置」小节(meta.tres 四行族读表纪律,数值 provisional 归设计批) | -| v1.0 | 2026-10-03 | R3 清账批(gdd_lint 分域随批):五处日期批注括注迁出——体例说明=本表 v0.3 事件;十八格=本表 v0.7 事件;正式序列=本表 v0.8 事件;三处用户拍板事件随行入账:显影尘/地穴全图卷效果定位归 Alpha 且原 06 待办条目移除(2026-09-20 拍板)、单关测试直入口退役且唯一试玩入口=完整冒险(2026-09-23 拍板)、反制道具与全局作用域排 Alpha(2026-09-20 拍板);语义零变更 | -| v1.1 | 2026-10-09 | 文档正确性审查批:扫雷秘宝节过期订正——「registry 登记六件封闭清单(数据表未建)、其余四件定义有效」滞后于秘宝目录重设计(旧目录已全数退役、只作素材库),改写为目录(重设计 v1)15 件代号制+旧行删除归实装批;同调件数据表 treasure_items.tres 在役补记 | -| v1.2 | 2026-10-10 | 元进度配置段柜台名扫改(2026-10-10 天赋树设计会话裁「道具工坊」改名「秘宝匣」):「道具工坊阈值六行」改「秘宝匣阈值六行」。体量数字零改动 | -| v1.3 | 2026-10-11 | 文档一致性修复批(定时检查呈报项):扫雷秘宝节目录计数换代 15 件→12 件(普通 7/优秀 3/稀有 2——回能器删除、换装券撤消、第四只手删除三轮修正在本文件的漏网面,秘宝.md v2.7-v2.9 已载);该段超长拆两段(R1) | -| **v1.4** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:「GP 钱包账本归冒险结构」→「GP 归冒险结构」——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/04-美术音频方向.md b/design/gdd/04-美术音频方向.md index 71fd2f63..1da5fa72 100644 --- a/design/gdd/04-美术音频方向.md +++ b/design/gdd/04-美术音频方向.md @@ -13,10 +13,3 @@ **音频方向未定稿**:MVP 阶段用占位音效即可,正式音乐与音效等核心循环验证后再定。 美术细则(色板、形状语言、图标契约、验收标准)见 `design/art/art-bible.md`(含参考与反参考,见其 §9)。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v1.0 | 2026-09-14 | 初版随 GDD 骨架建立:风格一句话、三条关键词、参考游戏、音频方向占位 | -| v1.1 | 2026-10-03 | gdd_lint 分域批:补版本历史节(R4);本文体系裁散文体,R2 表格占比分域豁免 | diff --git a/design/gdd/05-不做清单.md b/design/gdd/05-不做清单.md index 272e392e..3fab7430 100644 --- a/design/gdd/05-不做清单.md +++ b/design/gdd/05-不做清单.md @@ -23,14 +23,3 @@ - **反雪球机制**:MVP 不做。等 Alpha 拿到真实测试数据,再决定要不要治滚雪球、怎么治。 - **正式音频、教学引导、战斗动画演出、设置与本地化**:MVP 内的打磨项,一律排后。先验证核心循环,再谈好听好看。 - **连刷 / 换图资金跨战斗携带**:现行规则是每场战斗清零,防滚雪球。是否解禁连刷策略,等实测数据说话。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v1.0 | 2026-09-14 | 初版随 GDD 骨架建立:确定不做 / 现阶段不做两节 | -| v1.1 | 2026-09-21 | 元进度实现批:元进度行注首批已落地(营地三柜台 / 钥石账本 / 跨局注入),数值 provisional 归设计批标定 | -| v1.2 | 2026-10-03 | R3 清账批(gdd_lint 分域随批):元进度行日期批注迁出至本表 v1.1 行;语义零变更 | -| v1.3 | 2026-10-03 | 道具替代推理边界锚复核(迭代 11 第①批同调实施批——需求卡片 §十连带):「允许恢复推理原料,不允许道具替代推理」边界锚**原样保留即通过**——同调目录九件逐件对表:真视/预读类=信息给付(探巢摆钟 3×3 窄域护栏承重),六被动=机制修正(禁裸 flat schema 强制),无一替代推理判定本体;复核零改动 | -| v1.4 | 2026-10-07 | 道具三层重设计·地图层身份裁决(案甲,用户裁):第 14 条收窄——「未开格显示奖励身份」改「未开格预读危险格与安全格」,未开格类型微光(读类型不读危险格与安全格)移出禁止面;呈现现行事实源=HUD框架「未开格类型微光」节(定义与色带已定稿),实施归微光批;推理本体保护不变 | -| **v1.5** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:「中间资源折算」→「中间系统资源折算」;「钥石账本」→「钥石」——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/07-体验验证清单.md b/design/gdd/07-体验验证清单.md index 06297264..fca4e440 100644 --- a/design/gdd/07-体验验证清单.md +++ b/design/gdd/07-体验验证清单.md @@ -100,7 +100,7 @@ **局后随手记**(一句话即可,事后对日志):每局大概掉了多少血 / 有没有整轮一点血没掉的轮次 / 通关与否 / 有没有"这局特别顺/特别倒霉"的体感(种子体感核对用)。 -**结果回流**:日志取数 → 真人修正系数 k(真人整关承伤中位 ÷ 模拟完美档中位;**正常预期 k>0.5、预警线 k<0.3**——2026-10-03 用户裁)并入 T19 标定报告(落 design/research/,换代 2026-09-19 判读报告为现行锚);①–⑤ 体感按各条目的回流位分流。 +**结果回流**:日志取数 → 真人修正系数 k(真人整关承伤中位 ÷ 模拟完美档中位;**正常预期 k>0.5、预警线 k<0.3**——2026-10-03 用户裁)并入 T19 标定报告(落 design/qa/,换代 2026-09-19 判读报告为现行锚);①–⑤ 体感按各条目的回流位分流。 **2026-10-01 数值修复批后试玩注记**(master 4b4a011 起的正式标定局):本批已落 hero 血池 20→26 / 直伤雷三行 4/5/5→6/8/8 / L1 系敌 atk 2→1(轨迹与读数见 numfix 报告(已退役,git 历史可查))。试玩时对号新增两点: 1. **踩雷疼痛感**(本批主刀):「踩很多雷还是轻松活」应是过去式——单雷 6-8 直伤、两三连雷应明显肉疼;若仍无痛感=回调信号,记一句话即可; @@ -162,7 +162,7 @@ ### ⑮ 秘宝词族换词全 UI 面目检 + 渲染像素闸补跑(2026-10-05 秘宝代码词族对齐批顺带登记——迭代15③号卡) - **实机目检(「秘宝」字样全 UI 面,约 3 分钟)**:①C 区槽位标题应显示「秘宝」(原「魔法道具」,hero_info_panel_view 槽位组);②空槽悬停提示应显示「秘宝槽(空)」;③战斗总结三选一叙述行应显示「秘宝 / …」或「秘宝 / 随机获得一件」(原「魔法道具」开头);④换关 toast 应显示「上关剩余 N 件秘宝已随关卡结束清空」。**红灯信号**:任何界面残留「魔法道具」字样。〔**✅ 真人目检半已核销(2026-10-14)**:用户实机目检回报完成,未呈报残留(qa 收尾批)〕 -- **渲染像素类闸补跑挂账**:本批屏蔽五件(golden_compare / shot_probe / fx_probe / ui_layout_probe / board_shot——组 A 文案变更使像素断言合法失效,按 goal 令弃断);**补跑时点=迭代 14 全入库后的表现批周期闸一次性补跑**,与本批无独立补跑义务;届时若 golden 基线因文案换代失效,按换代流程重锚而非当缺陷修。**分工注记(2026-10-05 ui-struct-probe 批)**:结构类断言(互压/等宽/出屏)已由 `ui_struct_probe` 入轻闸默认必跑段(tools/probe_gate.sh),与像素五闸互补不替代——五闸补跑义务不变。**核销注记(2026-10-08 迭代 19 卡①自动化验收补齐批——机器补跑半顺带核销)**:五件机器半全部归宿已入库并实测绿——shot_probe(扩屏七屏+shot_checker A-D 断言)/board_shot(L1-L3 取证+golden 逐像素 0.00%×3)/golden_compare 三件入 render_gate(窗口化自动闸),fx_probe 入 probe_gate --full(headless 逻辑层断言),ui_layout_probe 补 1280/1920 两档最小断言(首跑 PASS);五闸归宿见本句上列逐件注记(原对账卡已按「吸收即死」退役,git 历史可考)。**真人目检半(上方「秘宝」字样全 UI 面 3 分钟)仍归用户,不注销**。 +- **渲染像素类闸补跑挂账**:本批屏蔽五件(golden_compare / shot_probe / fx_probe / ui_layout_probe / board_shot——组 A 文案变更使像素断言合法失效,按 goal 令弃断);**补跑时点=迭代 14 全入库后的表现批周期闸一次性补跑**,与本批无独立补跑义务;届时若 golden 基线因文案换代失效,按换代流程重锚而非当缺陷修。**分工注记(2026-10-05 ui-struct-probe 批)**:结构类断言(互压/等宽/出屏)已由 `ui_struct_probe` 入轻闸默认必跑段(tools/probe_gate.sh),与像素五闸互补不替代——五闸补跑义务不变。**核销注记(2026-10-08 迭代 19 卡①自动化验收补齐批——机器补跑半顺带核销)**:五件机器半全部归宿已入库并实测绿——shot_probe(扩屏七屏+shot_checker A-D 断言)/board_shot(L1-L3 取证+golden 逐像素 0.00%×3)/golden_compare 三件入 render_gate(窗口化自动闸),fx_probe 入 probe_gate --full(headless 逻辑层断言),ui_layout_probe 补 1280/1920 两档最小断言(首跑 PASS);五闸归宿对账见需求卡片-自动化验收补齐批 §一。**真人目检半(上方「秘宝」字样全 UI 面 3 分钟)仍归用户,不注销**。 ### ⑯ UI 结构批复验(2026-10-05 ui-struct-probe mini-loop 顺带登记——标题屏双列修复+按钮宽度纪律,约 2 分钟) @@ -261,28 +261,6 @@ **后续内容批义务(2026-10-06 敌人表行集多行批 P3 丙二裁挂单)**:首个混编遭遇行投放(连同 Boss 多行内容,敌种候选与坐标由内容批裁)——投时 MC 取证先报批(数值验证场景二档起)、难度带读数义务随投登记、首遇教学位纪律与 expect_pools 断言面逐项复核(巨蜘蛛首遇位「固定 2 不加骰」等表注释为准)、Boss 多行投放时 Boss 名取首行显示/Boss 遭遇骰逐行区间骰〔每行各掷自己区间——2026-10-07 卡① Q8 逐行骰换代,旧「读首行区间」口径消解〕/半血解锁/独占技/难度带六面读数逐项过。——**已编入 roadmap 迭代 18 卡⑤混编遭遇首批投放批(2026-10-06 用户令;读数义务维持顺带登记,MC 取证跑批顺延 Alpha 收官 M4 数值批统一执行〔未排期,届时另令——数值统一调整殿后〕)。进展:首批已于 2026-10-07 落表((2,5) 双行,目检与读数义务见 ⑱);剩余面 = Boss 多行第二批(六面读数随投逐项过)** -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-10-09 | 补登:文档正确性审查批改动①——⑬节「迷雾联动信号」行魔法提灯观测点加退役注(「魔法提灯 +2——已裁退役 2026-10-09,拆线批入库后本信号面失效」);本文件当时无版本表,本行系卫生批补登 | -| v0.2 | 2026-10-09 | 补登:文档正确性审查批改动②——⑰节「结论回流」行裸「M-4」改「Beta 阶段(未排期)」(强度体感归 Beta 阶段带判读);同上系卫生批补登 | -| v0.3 | 2026-10-09 | 版本历史表补建——本文件此前无版本表(2026-10-09 审查批呈报在案),本卫生批补建本表并补登上两行 | -| v0.4 | 2026-10-09 | **文档正确性审查批·独立复核(worktree docaudit-2026-10-09)**:①三处「链接语法但目标非路径」伪死链去链接改纯文本(numfix 报告/迭代10通关率读数/T19真人试玩读数——三份读数均已退役,git 历史可查口径不变);②「难度修正批」批次名全替「数值批(Beta 阶段,未排期)」——与 06 现行归属称呼对齐(同批=M4 数值批需求卡片,未排期态不变) | -| v0.5 | 2026-10-10 | 生涯页呈现行柜台名扫改(2026-10-10 天赋树设计会话裁「道具工坊」改名「秘宝匣」):「道具工坊已解锁 X/6 件」改「秘宝匣已解锁 X/6 件」;计数语义(旧六件→新目录)随实装批换代,见 06「天赋树结构重构批」改名连带面 | -| v0.6 | 2026-10-12 | 新增 ㉒ 锻造工坊工作间形态与购买交互目检节(迭代 23 锻造工坊实装批随批登记——V13 人闸观测项:门与形态/购买/解锁双通道/选中与锁死/注入抽查) | -| v0.7 | 2026-10-13 | 新增 ㉓ 敌人表内容修批三观测目检节(迭代 24 卡①随批登记:新招可见性/甲型体感/第一关节奏——登记不阻塞按 2026-10-12 真人检测立规) | -| v0.8 | 2026-10-13 | 新增 ㉔ UI 全局主题批全屏巡检目检节(迭代 25 卡①随批登记:引擎默认灰清零巡检/音量滑轨两段可辨/专项观察点二(滑轨柄抢焦点·滚动条槽可见性)/预盖件无实役注记——登记不阻塞;能力验证半=冒烟 V1-V6) | -| v0.9 | 2026-10-14 | 新增 ㉕ UI 交互与观感批逐屏巡检目检节(迭代 26 卡①随批登记:按钮五态反馈/键盘焦点环/全局 Nearest 巡检(含暗角与渐变白名单判据)/布局均衡(商店居中+营地四栏等高)/诊断钮清零——登记不阻塞;能力验证半=冒烟 V1-V6+T4 结构断言) | -| v1.0 | 2026-10-14 | **qa 收尾批·人闸核销(用户 2026-10-14 回报实机目检全部完成)**:⑮真人半、⑳、㉑、㉒、㉓、㉔、㉕ 七节逐节加「✅ 已核销(2026-10-14)」注记——用户目检回报完成、未呈报问题;iter19 acceptance-package 存活八项与 iter20 五件(行为变化速览节)同批核销;迭代 18 清单 18 项同批核销。注:⑯⑰⑱⑲ 等早期人闸节此前已随各批核销或归 07 独立跟踪,本条不涉及 | -| v1.1 | 2026-10-14 | 新增 ㉖ 代码架构技术债修复批全流程走查目检节(迭代 27 卡①随批登记:全流程观感零变化走查/续玩断点恢复/调试浮窗对局中可开不锁棋盘〔:407-408 事故回归〕/刷新余量显示一致/DS_DEBUG 启动浮窗+两屏角标——登记不阻塞;能力验证半=冒烟 V1-V9+parity 三变体逐位一致对拍五跑全同) | -| v1.2 | 2026-10-15 | **冲突标记清理解(迭代 28 随批)**——本文件 v1.0/v1.1 两行处残留 `<<<<<<<`/`=======`/`>>>>>>>` 合并冲突标记(迭代 27 分支 iter27-techdebt-20261014 合并进 master 时漏解,两侧均有效故全留:qa 收尾批人闸核销行 + ㉖ 目检节登记行与正文节);清理后两行内容照旧,仅版本号顺延。同批新增 ㉗ 启动态菜单目检节(迭代 28 卡①随批登记) | -| v1.3 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 35 处(随批→顺带 25、收口→完成/合并进 master 5、台账→状态记录 1、销号→注销 2、报错→返回错误 1、对拍→与基线数据逐项比对 1;均系正文现役文本,版本历史既有行按豁免不动)+失同步修复 0 处 | -| v1.4 | 2026-10-17 | ㉖① 机检承接注记(迭代 29 GDD 反哺点经用户逐条裁决写入):屏壳切换正确性已由 `screen_flow_probe` 机检承接(入轻闸必跑段);该项**保留不注销**——承载机器抓不到的观感半(演出时序/文案/布局逐屏零漂移) | -| v1.5 | 2026-10-17 | 新增 ㉘ 未开格类型徽章批类型微光实机目检节(迭代 30 卡①随批登记:五组一眼可分/微光不遮数字〔环不外溢〕/出圈灭入圈复亮/整屏不脏/群伤暗档 #A61D37 观感〔provisional,读数归样张批复核〕——登记不阻塞;能力验证半=双帧 glow 作用集 2/4/4·outside=0+golden off 帧 0.10–0.14%+探针 case⑰+单测五段 51 检查) | -| v1.6 | 2026-10-20 | 死链清偿:㉑ 节「五闸归宿对账见需求卡片-自动化验收补齐批 §一」指路句删除——该卡早已按 doc-conventions §11「吸收即死」退役,五件归宿由本句上列逐件注记自持。同批十一张失归属卡片退役,roadmap 卡片列改「已退役(git 历史可考)」 | - - ## ㉖ 代码架构技术债修复批——全流程走查(迭代 27 卡①顺带登记;能力验证半=冒烟 V1-V9+parity 三变体逐位一致、与基线数据逐项比对五跑全同) > 场景拆分+会话物化+战斗域重构+账本完成+模态协议内聚后,玩家可见面唯一验收=观感零变化。登记不阻塞(2026-10-12 真人检测立规)。 @@ -315,7 +293,7 @@ ## ㉘ 未开格类型徽章批——类型微光实机目检(迭代 30 卡①顺带登记;能力验证半=双帧 glow 作用集取证 2/4/4·outside=0+golden off 帧 0.10–0.14%+探针 case⑰+单测五段 51 检查) -> 类型微光实装(默认开、组合根布尔可切)后,玩家可见面=棋盘格内五组类型微光。机检只能证明「作用集正确/开帧一致/关帧逐位一致」,真机上「五组分不分得清、看着脏不脏」仍需人眼。**群伤组明度档为 provisional 值**(art-bible 版本历史 v3.15 登记),观感复核归战斗一屏样张批(迭代 30 卡②)——本节第 5 项读数作该复核的输入。登记不阻塞(2026-10-12 真人检测立规)。 +> 类型微光实装(默认开、组合根布尔可切)后,玩家可见面=棋盘格内五组类型微光。机检只能证明「作用集正确/开帧一致/关帧逐位一致」,真机上「五组分不分得清、看着脏不脏」仍需人眼。**群伤组明度档为 provisional 值**(art-bible v3.15 登记,明细见其 git 提交史),观感复核归战斗一屏样张批(迭代 30 卡②)——本节第 5 项读数作该复核的输入。登记不阻塞(2026-10-12 真人检测立规)。 | # | 目检项 | 判据 | |---|---|---| diff --git a/design/gdd/08-Alpha版本标准.md b/design/gdd/08-Alpha版本标准.md index d4e62e29..167186cc 100644 --- a/design/gdd/08-Alpha版本标准.md +++ b/design/gdd/08-Alpha版本标准.md @@ -2,7 +2,7 @@ > **一句话定位**:本文定义这个项目的 **Alpha 版本包含哪些东西**——它是里程碑 M3 的完成标准,也是判断"还差什么"的对照表。 > **本文只列条目,不写内容**:每样东西是什么、规则怎么走,一律归各自的权威文档,本文只给指路链接。想知道某样东西的定义,请点链接,不要在本文里找解释。 -> **状态**:**已定稿(v1.10)**——2026-10-13 用户令定稿(v1.0),同日升版 v1.1(界面美化八条)与 v1.2(敌种池行注摘除);v1.3/v1.4 为迭代 25/26 完成回填;v1.5 简明技术中文用语规范批;v1.6 状态刷新批(锻造工坊在役回填 + 数值统一标定按 2026-10-09 里程碑立规结案归 Beta);v1.7 状态刷新批(立绘方向随 2026-10-14 用户裁结案 + 样张/棋盘观感编入迭代 30 注记 + 贫矿脉屏蔽注记);v1.8 playnote 二轮对照批(状态面板行名随改名批换代 + 瘦身义务入册〔2026-10-16 用户令〕);v1.9 未开格类型微光实装回填(迭代 30 卡①,反哺点回写用户令授权);v1.10 混编遭遇第二批裁挂 Beta(2026-10-18 用户令,未决项六行减五行)。Alpha 的内容范围自此冻结:增删条目一律须经用户裁决,并记入文末版本历史。 +> **状态**:**已定稿(v1.10)**——2026-10-13 用户令定稿,此后十次升版的明细见 git 提交史。Alpha 的内容范围自此冻结:增删条目一律须经用户裁决。 > **成文**:2026-10-13。 ## 本文怎么用 @@ -89,8 +89,8 @@ | 商店配置 | `shop.tres` | 在役 | | 元进度配置 | `meta.tres` | 在役 | | 天赋树节点集 | `meta_tree.tres` | 在役 | -| 锻造工坊路线行族 | `forge.tres` | 在役(定价 provisional 归 M4;表名订正与入库依据见版本历史 v1.6) | -| 混编遭遇行集 | `enemy.tres` | 在役(首批;第二批移挂 Beta,裁决与明细见版本历史 v1.10) | +| 锻造工坊路线行族 | `forge.tres` | 在役(定价 provisional 归 M4;表名订正与入库依据见 git 提交史) | +| 混编遭遇行集 | `enemy.tres` | 在役(首批;第二批移挂 Beta,裁决与明细见 git 提交史) | | 第四关 | —— | 待裁 | --- @@ -101,7 +101,7 @@ |---|---|---| | 主菜单 | —— | 在役 | | 开始覆盖层 | —— | 在役 | -| 营地(天赋树 / 锻造工坊 / 秘宝匣 / 图鉴) | [camp](ux/camp.md) | 在役(锻造柜台占位面板注已解除,见版本历史 v1.6;柜台贴图占位归「五 · 表现」UI 贴图重构批行) | +| 营地(天赋树 / 锻造工坊 / 秘宝匣 / 图鉴) | [camp](ux/camp.md) | 在役(锻造柜台占位面板注已解除;柜台贴图占位归「五 · 表现」UI 贴图重构批行) | | 生涯页 | [生涯](systems/跨局循环/生涯.md) | 在役(期一) | | 关卡地图屏 | [level-map](ux/level-map.md) | 在役 | | 战斗屏 | [battle](ux/battle.md) | 在役 | @@ -142,7 +142,7 @@ |---|---|---| | 像素美术风格与色板 | [美术圣经](../art/art-bible.md) | 在役 | | 棋盘瓦片与格面资源图标 | [美术圣经](../art/art-bible.md) | 在役 | -| 未开格类型微光(五组色相+明度档) | [HUD框架](systems/表现与支撑/HUD框架.md) | 在役(明度档 provisional 值登记见 art-bible 版本历史,复核转正归战斗一屏样张) | +| 未开格类型微光(五组色相+明度档) | [HUD框架](systems/表现与支撑/HUD框架.md) | 在役(明度档 provisional 值登记见 art-bible 的 git 提交史,复核转正归战斗一屏样张) | | 棋盘观感(第二 / 三关亮度与对比度) | [06-待办清单](06-待办清单.md) | 待做(2026-10-16 用户令编入迭代 30,序位③) | | 立绘清晰度回退评估(是否改用高清图) | [角色设计](../art/character-design.md) | 待做(评估已结——2026-10-14 用户裁维持像素风、升级精细手绘像素、不回退高清图,裁决录=[美术审计-cursor会话存档](../research/美术审计-cursor会话存档-2026-10-14.md) §2.2;余=立绘按新口径重产+大小比例子题用户复核) | | 敌人立绘(全敌种) | [角色设计](../art/character-design.md) | 在役 | @@ -209,23 +209,3 @@ | 5 | 素材升档重产进不进 Alpha | 五 · 表现 | --- - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-10-13 | 首版成文:立 Alpha 版本的内容清单(系统 / 内容量 / 界面 / 工程与质量 / 表现五节 + 不含清单 + 未决项十项)。本文只列条目不写内容,定义一律指路各权威文档 | -| v0.2 | 2026-10-13 | **playnote 五条想法的归属裁定随批**(用户逐条裁):①「关卡节点图展示优化」经用户定性为**重构**(可选节点太少)→ 冒险循环表新增「关卡节点图重构(增加可选节点)」行,标**待做(须先做文档设计,不可直接开发)**,同步登记 06 待办;②「第二 / 三关棋盘亮度对比度」→ 表现表新增「棋盘观感」行,标待做(用户确认标准里已覆盖,此行是把它显式化);③「立绘改回高清图」→ 表现表新增「立绘清晰度回退评估」行,标待裁(与现行像素风定档存在方向冲突,入未决项);④「战斗节点地图类型差异化(更多地图主题)」→ 用户裁**排 Beta**,移入「六 · Alpha 不含」节。未决项十项增为十一项 | -| v0.3 | 2026-10-13 | **五条全部登记 06 待办并标注阶段归属(用户令)**:P1 关卡节点图重构标「Alpha 阶段需完成 · 设计讨论先行」;P2 棋盘观感标「Alpha 阶段需完成 · 开工前过素材轴/UI 轴定性人闸」;P3 第一关遭遇表数值异常标「Alpha 阶段需完成 · 修复方式待裁(甲即时修/乙归 M4/丙先排查)」,本表敌种池行随带待修注;P4 立绘清晰度回退评估标「Alpha 阶段需完成 · 方向待裁」,拆出已兑现的大小比例子问题与未决的回退高清子问题;P5 战斗节点地图类型差异化标「Beta 阶段,Alpha 不做」 | -| v1.0 | 2026-10-13 | **定稿(用户令)**:① **与游戏内容无关的三项移出 Alpha**——音频 / 教学引导(含教学引导面)/ 多语言本地化一律排 Beta,自「一 · 表现与支撑」「三 · 界面」「五 · 表现」三表摘除,移入「六 · Alpha 不含」并单列为一组;判据 = 缺了照样能联调、能通关,属打磨层;② 未决项十一项减为**八项**(删音频 / 教学引导 / 本地化三条,余项重编号);③ 文首加状态行 = **已定稿**,Alpha 内容范围自此冻结,增删须经用户裁决并记版本历史 | -| v1.1 | 2026-10-13 | **界面美化三层诊断入 Alpha 标准(用户令)**:用户同日提出界面美化需求并要求先作现状分析,随后下令「把分析出的三层全部作为独立待办事项登记、且一律列为 Alpha 阶段必须完成」。据此新增八行——「三 · 界面」表两行(UI 全局主题资源、UI 按钮状态矩阵),「五 · 表现」表六行(全局纹理过滤、UI 贴图重构批、UI 字体补完、战斗一屏样张、UI 氛围层与九宫格切片观感修、UI 元素细节修)。八行的登记事实源统一为 [06-待办清单](06-待办清单.md) 同批新增的八条专条;其中「UI 贴图重构批」「UI 字体补完」「战斗一屏样张」三条原先只登记在美术侧的资产清单与素材状态清单里,本次转立本清单以免两处各写一份内容。用户同时指定**先动第一层**,即主题资源 / 按钮状态矩阵 / 全局纹理过滤三项(均属纯工程补齐、不依赖美术素材)。本次改动未触碰既有的未决项八项与「六 · Alpha 不含」清单 | -| v1.2 | 2026-10-13 | **敌种池行注摘除(迭代 24 卡①机械面随批)**:「二 · 内容量」敌种池行的「第一关遭遇表数值待修」注摘除——该异常已随迭代 24 N1 修复((1,2) 降档 hp 22/ac 2,06 对应条已销号),本行回归「在役」净态;条目集合零增删,未决项与「六 · Alpha 不含」零触碰 | -| v1.3 | 2026-10-13 | **UI 全局主题批收口回填(迭代 25 卡①机械面随批)**:「三 · 界面」表「UI 全局主题资源(引擎原生控件接管皮肤)」行 待做→在役(主题资源已入库:game/assets/theme/main_theme.tres 挂 project.godot gui/theme/custom,06 对应条销号);「五 · 表现」表「UI 元素细节修」行状态注记①销号(滑轨两段难辨已随主题批重配=已填充段 BG_ROOT 对暖石 ≈5.5:1,余②③④保留)。「五 · 表现」表余零改动——逐行核对六条 06 指向行中仅「UI 元素细节修」事实变化,其余(棋盘观感/站桩帧动画/素材升档重产/全局纹理过滤/UI 氛围层)本批零触碰;条目集合零增删,未决项与「六 · Alpha 不含」零触碰 | -| v1.4 | 2026-10-14 | **UI 交互与观感批收口回填(迭代 26 卡①机械面随批)**:「三 · 界面」表「UI 按钮状态矩阵」行 待做→在役(五态矩阵补齐);「五 · 表现」表三行——「全局纹理过滤设为邻近采样」待做→在役、「UI 氛围层与九宫格切片观感修」待做→部分在役(光柱半已修,九宫格半未结注明)、「UI 元素细节修」待做(余②③④)→在役(②③④全落地);06 对应四条销号或改写+反哺点四条新条登记(待用户裁决另批落文);条目集合零增删,未决项与「六 · Alpha 不含」零触碰 | -| v1.5 | 2026-10-15 | 简明技术中文用语规范(用户令):文头状态行换代 v1.2→v1.4(v1.3/v1.4 两批漏更);「现状」取值枚举三种改四种(补「部分在役」定义,与「五 · 表现」九宫格切片行既有状态对齐)。条目集合零增删,未决项与「六 · Alpha 不含」零触碰 | -| v1.6 | 2026-10-16 | **状态刷新批(用户令)**:① 「一 · 跨局循环」锻造工坊行 待做→在役(实装批 2026-10-12 入库,06 载明;满级特效按裁 6 留扩展位不影响判定);② 「二 · 内容量」锻造路线行族事实源订正 `meta_forge.tres`→`forge.tres` 并转在役;③ 「三 · 界面」营地行锻造柜台注 占位面板→工作间实形态(目检 07 ㉒ 已核销;柜台贴图占位归表现表贴图批行)——以上三行为 v1.0 定稿时失实残留;④ 「四 · 工程与质量」数值统一标定行撤销(待裁→归「六 · Alpha 不含」,依据=2026-10-09 里程碑立规 M4=Beta 且用户 2026-10-16 重申),未决项八项减为七项重编号;⑤ 文头状态行 v1.4→v1.6(v1.5 漏更)。除④外条目集合零增删 | -| v1.7 | 2026-10-16 | **状态刷新批(用户令)**:① 「五 · 表现」立绘清晰度回退评估行 待裁→待做(方向已裁——2026-10-14 用户裁维持像素风、升级精细手绘像素、不回退高清图,裁决录=美术审计-cursor会话存档 §2.2;余下义务=立绘按新口径重产与大小比例人闸复核),「七 · 未决项」七项减为六项重编号;② 「五 · 表现」战斗一屏样张、棋盘观感两行加编入注记(2026-10-16 用户令编入迭代 30 序位②③,状态维持待做);③ 「一 · 排雷循环」「二 · 内容量」地形变异两行加屏蔽注记(2026-10-16 贫矿脉整图型屏蔽删行,variation.tres 回 region 六行;机制代码保留,重建设计加行即恢复)。除未决项销项外条目集合零增删;连带 06 立绘条子问题二与状态行随裁换代(方向已裁+08 指路改注,权威面 art-bible/character-design 反哺另批) | -| v1.8 | 2026-10-16 | **playnote 二轮对照批(用户令立框架:不需要讨论的写进 08 并同步 06、需要讨论的挂 06 待裁)**:① 「三 · 界面」「暂停层」行改名「状态面板(局内)」(随 2026-10-13 暂停层改名批换代——08 行名漏扫)并在役→部分在役(瘦身义务入册:去跨关解锁内容〔秘宝匣解锁态 12 行概览 / 天赋树已购概览〕、只留本局五件〔带的秘宝 / 已获专长 / 当前属性 / 现有 GP / 钥石总量〕——来源=playnote「状态界面不需要有具体的解锁内容」条;同步登记 06「状态面板瘦身」专条);② playnote 余下增量两条不进本表:成长系数节奏语义两读待澄清→06 专条待裁(数值调优义务 v1.6 起不入版本标准);路径长度统计与递增增幅=关卡节点图重构的设计输入→补进 06 既有专条。条目集合零增删(改名不算增删),未决项与「六 · Alpha 不含」零触碰 | -| v1.9 | 2026-10-17 | **未开格类型微光实装回填(迭代 30 卡①,反哺点回写用户令授权)**:「五 · 表现」表新增「未开格类型微光(五组色相+明度档)」行(事实源 = HUD框架 微光节——2026-10-17 实装入库),状态 = 在役(明度档 provisional 值登记见 art-bible 版本历史,复核转正归战斗一屏样张〔迭代 30 序位②〕);文头状态行 v1.8→v1.9。条目集合 +1 行(回写授权=用户裁),未决项与「六 · Alpha 不含」零触碰 | -| v1.10 | 2026-10-18 | **混编遭遇第二批裁挂 Beta(用户令「挂 beta 吧,不需要再进行讨论了」)**:未决项第 4 行「混编遭遇第二批(Boss 多行)进不进 Alpha」删除(六项减为五项、第 5/6 重编号为 4/5),「二 · 内容量」混编遭遇行集现状注改为「首批;第二批 2026-10-18 用户裁挂 Beta、Alpha 不做」;本批零代码零内容变更——机制面(迭代 17 行集多行批)与首批投放(迭代 18 卡⑤)维持在册,Boss 多行投放与 MC 取证/数值统标一系随 Beta 阶段再议;文头状态行 v1.9→v1.10。其余条目与「六 · Alpha 不含」零触碰 | -| **v1.11** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:奇物池行三分类「资源」→「补给」;「中间资源折算」→「中间系统资源折算」——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/systems/冒险循环/关卡节点图生成.md b/design/gdd/systems/冒险循环/关卡节点图生成.md index d1a552fb..ecfaae6c 100644 --- a/design/gdd/systems/冒险循环/关卡节点图生成.md +++ b/design/gdd/systems/冒险循环/关卡节点图生成.md @@ -212,16 +212,3 @@ ## 待办 本系统无未决待办(结构随机生成池已落地);后续新增待办统一登记 06-待办清单,本节不再逐条登记。 - -## 版本历史 - -| 版本 | 日期 | 说明 | -|---|---|---| -| v0.1 | 2026-09-27 | **设计草案成文(立项批,用户拍板立项——06 条目「关卡内结构随机生成」随批改状态)**:概念三件套(图模板/模板池/图模板抽签,N=1 回滚档)、抽签时机(开始关卡内逐关抽、主种子派生 `node_map` 流提案)、三级台阶路线(抽签→属性随机→全程序)、MC 测量对账三条款(分层出数/基线可比/实施门=曲线调参批后)、五拍板点、依赖表与验收草案。实施未开工;术语入 registry 词汇表随定稿批执行 | -| v0.2 | 2026-09-27 | **首轮裁决落文批(用户拍板①④⑤+路线确认)**:①第一关参与抽签、仅首次冒险走固定脚本——新增「首次冒险的固定脚本」节(存档域布尔标志「首次冒险已进行」、收束点置位、边界与测量口径,P0/验收/依赖表同步);④首版池规模=每关 5 张(调参表投值);⑤抽签时点确认;用户并裁「骨架不完全固定、多份随机调取」= 台阶一路线确认(台阶节补白话块+教学位随骨架走注记)。②③补证据面待复裁——新增「拍板点证据面」节:A=随机流/增流白话释义+两选项;B=台阶一详解(玩家看到什么/做三件/不做两件/内容形态 15 骨架/遭遇表按编号共用约束)+实施时点三选项(A 立即全上/B 等调参批/C 机制先行骨架随后,荐 C);测量对账实施门条款同步改"随机量扩池守门、机制可先行"口径 | -| v0.3 | 2026-09-27 | **②③终裁落文批(用户两轮复裁)**:②统一用一个流·全面执行——全游戏 rng 架构批先行(评估书 2026-09-27 交付:核心发现=七流系同一主种子的盐值分栏、字面目标现行已满足;待裁决=甲维持分栏/乙物理并流/丙并流+全事件日志),本特性实施排队其后(P0 补前置行、抽签节流形态改随统一流结论);③特性内机制先行骨架随后(池暂 N=1、骨架内容批扩池);证据面 A 补裁决注记。06 新立「全游戏随机流统一架构批」条目(数据配置节) | -| v0.4 | 2026-09-27 | **实施前置解除批(统一随机流批随批——rng 架构批已按 2026-09-27 裁决落地)**:状态行改实施解锁;抽签节流形态定稿 = 统一流扩签新用途标签 `node_map`(标签不参与派生、只进事件日志——并流后派生隔离概念退役);P0 闭环前置行改解除口径。本批只记架构依赖解除,特性实施仍未开工 | -| v0.5 | 2026-09-28 | **台阶一实施落地批(M-3 迭代 5 T5)**:P0 六项全落地——①关卡表逐关行 templates 池(3 关 × 5,模板 0 = 现行图回滚档;L1 单链排列变体〔图形态 Boss 最大编号 vs 遭遇深度 4 两不可全〕/L2L3 网状变体〔战斗编号恒 ∈ 遭遇表行集、商店必经位承袭〕)②node_map 扩签(标签不参与派生只进事件日志,黄金向量零改动)③首次冒险固定脚本(存档唯一新增布尔位「首次冒险已进行」、老档迁移=true、收束点置位幂等、测量夹具恒抽签)④池内全模板加载校验(validate 抽出 + config_db 跨表校验模板感知)⑤抽签确定性/零 scope 强制/N=1 等价/首冒分支 冒烟断言(558→576)⑥MC 分层出数(RUNSUM level_templates)。内容批生成器 = tools/t5_build_templates.py(生成前自校验)。遗留:台阶二/三后置不变;正式侧生存链/带面影响随读数批 | -| v0.6 | 2026-10-01 | **出度上限拍板批(T17 目检用户裁决「节点出度最大为 2」)**:① 加载校验第七检 `fanout_violation`(出度 >2 加载致命);② 规则连带——层宽上限随出度约束调整为 4(2026-09-29「层宽上限 5」废止,数学不相容);③ L2/L3 十张模板全池重建(tools/t17_fanout2_rebuild.py——出度 ≤2/层宽 ≤4/类型序列保持/可达自校验,五骨架换名宽廊双干〔现行〕等);④ 钉固断言 5 处随新图更新(min/max 路径/入口候选/奖励后候选)。**连带义务:MC 读数基线随图结构变化漂移——全旧 MC 锚作废,重锚归下一测量批**(当前只测不判) | -| v0.7 | 2026-10-09 | **文档正确性审查批(用户令——状态记录与证据对齐)**:①状态行里程碑前缀按 2026-10-09 里程碑口径删「M-3」只留「迭代 5」(worktree 名为历史产物名不动);②调参表模板池大小行「内容批落地前现行 1 张」过期表述替换——2026-09-28 台阶一实施批已落地 3 关 × 5。注:版本表内 v0.6(2026-10-01)行排在 v0.5(2026-09-28)行前的既有乱序不动,另行列呈报。 | -| v0.8 | 2026-10-15 | **简明技术中文用语规范批(用户令):词面修正 10 处**——「收口」→「完成」9 处(三级台阶表前置两处 / 测量对账实施门句 / 实施时点选项 A、B 两处 / 依赖表难度曲线与Boss行 / P1、P2 后置表两处 / 验收标准节题)+「对拍」→「与基线数据逐项比对」1 处(测量对账·基线可比条)。机制与数值零改动;文头「原 06 条目已收口移除」系原条目处置记载(对照性文本)按豁免保留 | diff --git a/design/gdd/systems/冒险循环/关卡节点地图.md b/design/gdd/systems/冒险循环/关卡节点地图.md index af486347..fda8d77e 100644 --- a/design/gdd/systems/冒险循环/关卡节点地图.md +++ b/design/gdd/systems/冒险循环/关卡节点地图.md @@ -175,21 +175,3 @@ Boss 兑付(胜利或英雄死亡)触发关卡收束点,此后不再有选 ## 待办 本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 - -## 版本历史 - -| 版本 | 日期 | 说明 | -|---|---|---| -| v0.1 | 2026-09-15 | 自归档线索整合为范围草案(旧体系未单独成文) | -| v0.2 | 2026-09-15 | 待拍板"多敌数量的消费面"条目同步教学位掷骰口径(随[难度曲线与Boss](难度曲线与Boss.md)同批修订):删除"教学位节点固定不掷" | -| v1.0 | 2026-09-17 | **定稿**(逐问题拍板,全用户裁决):① 形态重开——用户拍板重开[05-不做清单](../../05-不做清单.md)「路径分支地图后置」裁定,定稿为**分支节点图**(分层节点图,杀戮尖塔 / 哥布林弹珠同构;方块地牢美术观感、逻辑为节点图),P0 图定稿 + 单链特例先行;② 节点类型定稿四类封闭枚举不扩类;③ 行进交互定稿全节点确认 + 兑付后确认、零自动推进;④ 遭遇构成收窄为编排面三条(战斗内部初始化全归战斗小循环),寻址定稿节点编号升级(`node_depth` 语义升级为关卡内唯一节点编号,表键与字段名零改动,单链零漂移);⑤ 节点奖励拍板为功能道具的正式渠道(内容归秘宝内容重定批,切片期直通为合法空态);⑥ 「精英与 Boss 编码位」(同层多遭遇由节点编号消解,不设编码位)与「多敌数量的消费面」(关卡层零消费)两悬案收口,同场多敌种面拆归战斗侧;⑦ 切片行进代码对照的接口漂移清单登记 06 | -| v1.0.1 | 2026-09-17 | **P1 分支节点图内容与实现批落地**(用户拍板任务批——切片代码 / 难度曲线与Boss v0.7 / registry / 06 待办同批):首张分支图 = 切片关卡 2「第二层 · 幽暗地域」行集落地(9 节点网状图:入口 0 → 中间三层 2/3/2 → Boss 8,真实岔路 4 处,奖励点 + 恢复点各 1,战斗节点 6 + Boss);行进器图版推进(`choices_presented` 选路态 + `pick_next_node`——零自动推进,战斗胜利不再自动推进、`continue_after_node` 泛化为兑付确认,06 接口漂移清单 ④⑤⑧ 清偿);图合法性校验落地 `LevelTable.validate`(单链与图同一套算法,L1 零迁移过校验,违规加载致命);节点图选路 UI(选路覆盖层整图自绘——房间方块 + 通道连线 + 当前/候选高亮,占位图形质量;顶栏图形态渲染行进序列 + 候选);首页"关卡 2 试玩"直入口(测试模式,≠ 两关序列生效)。本版本号只记实现批状态,图规则口径零改动 | -| v1.1 | 2026-09-20 | **商店房扩类(GP+商店房批,用户拍板——与冒险结构 / 战斗结算 / 地图战斗资源 / 难度曲线与Boss / registry / 切片同批)**:① 节点封闭枚举四类→五类(+商店房);② 编排规则定稿——每关恰 1、关底 Boss 前一位必经位(哈迪斯式"决战前最后一个补给点"定位);必经位由冒烟断言承载、图合法性六检零新增;③ 兑付定稿——打开商店覆盖层、购买即时生效写统一冒险加算区(与关卡大奖励同一笔,归冒险结构)、离开后兑付确认;商店房不携带战斗行;④ 节点兑付表 / 纪律表 / 依赖表 / P0 闭环 / 验收标准 / P2「事件类节点候选」注记同步 | -| v1.2 | 2026-09-23 | **停点前移批(冒险入口流程倒置修复,用户 2026-09-23 拍板;上位裁决 = 棋盘/战斗舞台 Node2D 迁移批(已执行完毕,git 历史可查),代码实装另批并行)**:① 行进循环改停点前移口径——关卡开始即呈现节点图选路停点(关卡画面 = 选路覆盖层常驻化,入口节点不自动进入,第一次选路就是"出发"),选路确认进节点,兑付确认后返回关卡画面再选路(战后回图);兑付后确认、零自动推进两条纪律语义不变,只改承载位;② 呈现侧口径补进度承载条款——关卡画面本体即节点链进度呈现载体(节点态直接读图:已过暗金 / 当前金 / 候选下一跳通道亮金 / Boss 旗朱描边),不另设进度条组件(战斗屏 A 区进度条随批退役);③ P0 闭环两条、依赖表 HUD 框架行、验收标准「行进自主」条同步。**批内代拍板三项已追认(2026-09-24 用户确认)**:① B/C/D 字母保持不重编;② 28px 纵向空间划归 C/D 底行;③ 关卡画面进度呈现由选路覆盖层节点态承载(登记面见 HUD框架 v0.8) | -| v1.3 | 2026-10-01 | **图合法性第七检(T17 目检用户拍板「节点出度最大为 2」)**:`validate` 新增 `fanout_violation`(单节点出边 >2 加载致命);规则连带层宽上限 4(原 5 与出度约束不相容,废止)——生成侧规则与模板池重建归[关卡节点图生成](关卡节点图生成.md) v0.6 同批 | -| v1.4 | 2026-10-03 | **奖励节点道具渠道退役注记(迭代 11 第①批同调实施批——与 node-reward.md v2.2 / registry 同批)**:奖励节点的秘宝件渠道随停点渠道退役拆除(BONUS_IDS 词表除名 aux_item,池五种;三选一刷新件面新增见 node-reward.md v2.2)——奖励节点兑付面=提升三选一(属性/GP/AP 五种)+刷新,零结构改动(节点类型词表/图合法性六检零新增) | -| v1.5 | 2026-10-03 | **商店房兑付换代注记(迭代 11 第②批 GP 商店房重构批——需求卡片 v1.3 全裁;冒险结构 v0.13 / registry / 难度曲线与Boss 同批)**:商店节点类型词表与编排规则零改动(每关恰 1/Boss 前一位必经位/图合法性六检零新增);兑付面换代 = pool 模式进店抽 3(shop_draw 封闭流)+买 1 全重抽+重抽绑购买+空架合法态,货架候选与库存归冒险结构共享池节;覆盖层呈现面=货架三选一同构卡(legacy 固定三件面随对照模式保留注记) | -| v1.7 | 2026-10-09 | **文档正确性审查批(用户令——状态记录与证据对齐)**:①奖励节点兑付口径全节订正——「池六种含秘宝、加权洗牌、全冒险次数上限」改现行令牌池口径(七种、洗牌不放回抽 3、池耗即上限、未选回池);「道具件满位替换子交互」随秘宝件出池不再触发;「池空直通随共享池退役、牌库恒非空」反转订正——TP0 后池耗即枯竭、空库直通为合法态;「终局=秘宝局外同调件的改写义务仍归同调实施批」订正为已落地(迭代 11 第①批);②P0 闭环与验收「切片期直通合法空态 / 取一件入关卡域库存(随同调实施批退役改写)」过期表述替换为提升三选一共享令牌库口径;③P1 后置「分支节点图内容与实现批」已随 v1.0.1 落地——行移除,正文两处「随第二关内容批(见 P1)」改「已落地」;④不负责表与依赖表「节点奖励的道具内容→秘宝(内容重定批)」改指奇物(提升池构成与账本归冒险结构)。注:版本号 v1.6 系正文商店行已有标签(MC-1 独立刷新批 2026-10-04)的表内让号,该批版本行缺失另行列呈报。 | -| —— | 2026-10-09 | 缺号注记:v1.6 未登记(对应批次=MC-1 商店独立刷新批〔2026-10-04,git ac3cee7 明记「关卡节点地图v1.6换代」〕,登记见正文商店行 v1.6 标签与 v1.7 行让号注记),卫生批仅注记不补写 | -| v1.8 | 2026-10-15 | **简明技术中文用语规范批(用户令):词面修正 1 处**——设计目的首句「若干节点」改「由关卡表配置的一组节点」(「若干」→写明数值出处:节点构成与数量读关卡表行集)。机制与数值零改动 | -| **v1.9** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:「跨战斗生命账本」「共享池账本」「库存账本」等去账字;指路「GP 冒险账本节」→「GP」节、「共享池账本节」→「共享池节」——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/systems/冒险循环/冒险结构.md b/design/gdd/systems/冒险循环/冒险结构.md index 777f6045..7dae708f 100644 --- a/design/gdd/systems/冒险循环/冒险结构.md +++ b/design/gdd/systems/冒险循环/冒险结构.md @@ -301,31 +301,3 @@ GP(显示名「GP」)是冒险内的一次性属性提升货币:战斗胜 ## 待办 本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | -| v0.2 | 2026-09-15 | 雾格残留清理:第二关"解锁新元素"条目改引用「已从设计中移除的机制」(见不做清单),并明确第二关层名未定稿、随第二关内容批重定。关卡序列与节点模板不变 | -| v0.3 | 2026-09-17 | 代币→钥石统一拍板(用户裁决):大奖励第三件「代币记账 +10」改「钥石入账 +10」——与元进度钥石同一资源(渠道 = 关卡大奖励入账与 Boss 掉落),「代币」措辞退役;调参表字段名、验收标准、依赖表同步。数值与机制不变 | -| v0.4 | 2026-09-17 | 数值纪律收口批:正文与调参表 knob 现行值改指路存根(事实源 data/tables/*.tres 与 registry),3 处失同步修正(示例轨迹改纯符号〔旧 50/50 生命轴示例作废〕、大奖励 +10/+10 改读 adventure_table 行值并删换算率数字锚、调参表 30/10/10 三格改读 level.tres / adventure_table) | -| v0.5 | 2026-09-20 | **GP+商店房批(用户拍板——与关卡节点地图 v1.1 / 战斗结算 v0.23 / 地图战斗资源 v0.15 / 难度曲线与Boss v0.18 / registry / 切片同批)**:① 新增「GP 冒险账本」节——钱包三收口(战斗完成统一入账 / 商店购买出账 / 冒险收束清零)+ 战斗内缓冲隔离语义(格面兑付入缓冲、战斗完成统一到账、战斗域零钱包状态);② 统一冒险加算区成文——商店购买与关卡大奖励上限提升同一本账(三轴 {攻击, 生命上限, 护甲等级},经覆盖值通道生效;购血 = 上限与当前生命同步 +Δ);③ GP 掉落掷定消费 gp_drop 封闭随机流(主种子派生)登记进主种子节与调参表;④ GP 不入存档、不入冒险摘要;范围表 / 大奖励表 / 依赖表 / 验收标准同步。数值全 provisional-pending-曲线调参批,行值读 shop.tres | -| v0.6 | 2026-09-21 | **冒险结构实现批落地登记(切片 AdventureRunner + LevelRunner 账本外置 + AdventureTable 建表——与切片代码 / registry / 03 / 06 / roadmap 同批)**:本批只记实现批状态,正文规则口径零改动。落地面 = 三关正式序列生效(首页「开始冒险」)、接口契约四件套正式侧承载(开始关卡 start_level_external / 战斗结果上报共享账本直写 / 治疗封顶回报 apply_rest / 关卡结束 level_finished)、生命账本与 GP 冒险账本上交冒险结构层、大奖励非末关恰兑付一次(末关钥石照记)、冒险摘要五件事产出、主种子恰一次注入(registry rng_service new_adventure 调用权同批登记)、结算受理只算一次;06 待办「两关序列未生效」「切片行进代码与定稿的接口漂移」「冒险表未建表」三条随批解决移除。**规划书冲突按代码为准登记两处**:①大奖励 `_pending_next_level` 置位先于 emit(信号同步派发——处理器内立即确认需标记已就位);②放弃受理补 state=running 守卫(契约 7 结算受理只算一次的 abandoned 侧对齐) | -| v0.7 | 2026-09-21 | **放弃入口界面呈现批(用户拍板「放弃接口也要有」——台账 119,推翻本文原「MVP 无界面入口、呈现后置」条款)**:① 放弃入口挂[关卡节点地图](关卡节点地图.md)选路覆盖层(选路停点 = 天然非战斗期;战斗中拒绝转为防御兜底分支——入口在战斗期不可达);② 入口只在冒险模式开放,单关测试直入口没有可放弃的冒险对象;③ 正文改现行口径(放弃节 / 验收标准放弃条),P1 后置表「放弃入口的界面呈现」随落地移除(同表「两关序列生效」系 v0.6 已落地漏收口,顺手同口径移除);④ 验收闸 = ui_probe 三断言(默认隐藏 / 冒险模式可见 / 首战中按下被拒 state 保持 running)+ 冒烟既有放弃两态 API 断言 | -| v0.8 | 2026-09-23 | **单关测试直入口退役(用户拍板——唯一试玩入口 = 完整三关冒险)**:正文改现行口径两处(放弃节「按钮只在冒险模式开放」的理由从「单关直入口无冒险对象」改为「选路覆盖层只在冒险模式出现」;验收标准放弃条同步去单关直入口从句)——放弃语义对象(整局冒险)与拒绝分支零改动。版本历史行(v0.7)按文档纪律不回改 | -| v0.9 | 2026-09-23 | **停点前移批流程口径对齐(用户 2026-09-23 拍板冒险入口流程倒置修复——与 HUD框架 / 关卡节点地图 / battle.md 同批;上位裁决 = 棋盘/战斗舞台 Node2D 迁移批)**:P0 闭环「开始关卡」条改新流程口径——关卡节点地图加载节点图后停在入口选路停点(关卡画面,选路覆盖层常驻形态),行进自玩家首次选路开始;通读复核其余章节——「通关自动进下一关」属关卡序列层语义(进入下一关后仍出图选路,零矛盾)、接口契约四件套、收束点先清库后宣布、放弃入口(选路停点 = 天然非战斗期)等既有裁决零改动。**批内代拍板三项已追认(2026-09-24 用户确认)**(字母不重编 / 28px 归 C/D 底行 / 进度呈现由选路覆盖层节点态承载)不落本文修订面,登记见 HUD框架 v0.8 | -| v0.10 | 2026-09-27 | **统一随机流批口径对齐(2026-09-27 裁决——rng 架构批随批)**:主种子节「可复现域 = 主种子 + 各随机流计数器」改「主种子 + 全局取数计数器」(语义权威指数据配置);本文规则面零改动——主种子恰一次注入、重开即全新一轮、摘要五件事均不变。代码实证与七消费点迁移见数据配置 v0.5 | -| v0.11 | 2026-09-29 | **冒险断点批(迭代 8 卡①③——中断可续玩/退出即结算两口径分离)**:核心规则新增「冒险断点」节(停点粒度/七字段拍板面+附随件/中断退出两口径/续玩语义/测量面静默);依赖表存档序列化行补断点域 owner 登记;验收标准 GP 不留痕条补断点域豁免口径。实现落点 = AdventureRunner 快照/清除/续玩 + SaveManager breakpoint 域 + rng restore_adventure | -| v0.12 | 2026-10-01 | **关卡大奖励重构批(迭代 10——用户 2026-09-30 拍板案丙 + P-A~P-E 全裁毕;冒险表扩列 / meta.tres 重锚 / registry / 行动经济 / 元进度 / 01-核心循环 / 03-内容规模 / 难度曲线与Boss / 关卡节点地图 / 06 同批落文)**:①大奖励「固定三件套」退役改两层兑付——非末关通关 = 部分回血(clear_heal_pct 20 provisional)+ 提升三选一(池六种:攻击/生命上限/护甲/GP 袋/秘宝/行动点件;加权洗牌不放回 E-S weight-key 消费 reward_pick 封闭流;属性件上限各 3、AP 件上限 2,达上限先剔牌库);②统一冒险加算区三轴扩四轴 +行动点(AP 件 = 每场战斗开始首轮基线 +1);③钥石退役出大奖励改 Boss/精英击杀逐杀掉落(boss_keystone 重锚首杀 3/复杀 2,末关照常入账,精英掉 1 预留);④秘宝件受同调位约束(过渡键 transitional_sync_slots=1 provisional,现行事实源 = 同调实施批谓词表;超位替换交互 N+1 选 N、战斗内渠道沉没不入);⑤断点附随件扩奖励选择态 + 件获取次数计数;⑥选择停点零自动推进/可中断。渲染层验证冻结(用户 2026-10-01 提前开工拍板——不合入 master、目检待批),目检清单随批交付 | -| v0.13 | 2026-10-03 | **GP 商店房重构批(迭代 11 第②批——需求卡片 v1.3 全裁 P1 共享池/P1-a/P1-b 双甲/P2 甲/P3 甲/P4 ceil/P5 甲;06「GP 商店房重构」条 2026-10-02 用户裁决取代 09-20 无刷新裁决)**:①GP 冒险账本节商店购买行换代——价格公式 = ceil(基价 × b^(关序−1) × A^(本次进店已购次数))(A/b provisional 1.8/1.1;legacy 旧式随对照模式保留注记);②新增「共享池账本」段——商店货架 = 池∖{GP 袋}∖{秘宝件} 四种,库存=上限即库存全冒险一次性,两渠道同一账本(买一件=奖励面少一件),池空硬闸+空架合法态;③shop_draw 扩签登记;④统一冒险加算区段——pool 模式买上限不回血(池件=奖励件本体)、AP 件累加源并商店;⑤断点附随件扩商店货架态(shop_shelf/shop_visit_buys,P2 甲;确定性重放承载注记);⑥调参表 GP 经济参数行随表换代。实现=AdventureRunner/LevelRunner 池模式(缺省 legacy 对照承载,真实入口投 pool) | -| v0.14 | 2026-10-03 | **令牌池落地批(迭代 12 TP0——node-reward v2.2 追认 b 实施批)**:①提升池改**固定配额令牌池**——普通 70/稀有 25/罕见 3=98 张〔罕见档原列「道具件 2」随 aux_item 池种退役〔迭代 11 第①批 T7,落地晚于追认 b〕收窄,池总量 100→98——台账自决披露项〕;②抽取机制换代——Fisher-Yates 不放回抽 3 同 kind 去重每 kind 至多一枚(取代 E-S 加权洗牌),选中踢池未选回池、池耗即枯竭、**种类次数上限退役**;③恢复件新入池(rare 档 +6 当即回血封顶生效上限)+ 数值对(小GP 20/大GP 50 等);④MC 策略 316-f 落地(autoplay 1 级最稀有/2 级最左);⑤共享池账本段换代——库存=剩余令牌数,货架=令牌级抽签(价格公式 tier-blind 维持批②裁定),消费=AdventureRunner._bonus_deck 单点;⑥断点附随件扩令牌池余库(bonus_deck 逐枚还原;旧断点缺键=满库重建防御口径单版本周期);⑦现行基线锚换代=runsum_m4iter12_tp0_n20_20261003(normal 档配对读数同带 0/5/0) | -| v0.16 | 2026-10-06 | **三选一刷新对齐商店批(用户令——「三选一对齐商店,得有刷新」;机制现行事实源=秘宝.md 三选一刷新双源节同批落文)**:免费双源(刷新件 X/冒险池 Y)用尽后 GP 付费刷新——同 shop_refresh_* 两旋钮(curio_refresh_gp_cost 单点调参)、扣同一 GP 冒险账本(LevelRunner.spend_gp 新单口)、重抽同 reward_pick 共享池抽签;付费刷计数每停点清零;呈现=CurioPickOverlay.set_refresh_display 与商店 set_refresh_display 同构(钮常驻选择态、两源皆穷禁用不隐藏、角标=免费余量、价签行示 GP 价);通关停点刷新重发载荷带 refreshed 标直落选择面(不再重开胜利总结面)。店内凭证专长三选一暂不挂刷新面(维持现状)。单测=tests/unit/core/curio_refresh_paid_test.gd | -| v0.17 | 2026-10-07 | **生命周期轴裁决随批(框架现行事实源=核心循环「生命周期轴」节同批落文)**:GP 冒险账本节补独立资源口径——GP 与钥石=两条平行独立资源不立统一上位概念(钥石归元进度同批落文);各层对 GP 的兑付=一次性转换入账(转换源结算即消尽、钱包长存,类A→类C 转换关系非横跨多层);既有账本语义零改动 | -| v0.18 | 2026-10-09 | **文档正确性审查批(用户令——状态记录与证据对齐)**:①关卡序列节「第二关生效有前提、未落地前单关运行」过期句替换——三关序列 2026-09-21 起均已生效;②共享池账本货架候选订正——pool_shelf 六行 = 池∖{GP 袋, 刷新件}∪{凭证}(凭证与回复随迭代15② 入架),「∖{GP 袋} 四种」过期;③大奖励表提升三选一「加权抽 3、另 2 件丢弃」改令牌池口径(洗牌不放回抽 3、未选回池);④提升池表六种→七种——恢复件配额 稀有 5→3、补刷新件行(稀有 2/+1,迭代15② 入池);⑤秘宝件同调位读数源改谓词表实时求值(transitional_sync_slots 已退役、切换义务清偿,调参表过渡键行同改);⑥断点附随件「秘宝库存」重复短语去重;⑦P2 冒险长度扩展行「MVP 两关」改「现行三关」;⑧调参表关卡行集行「第一关现行、第二关随扩展批」改「三关现行(templates 池 3×5)」、三选一件值(其余)行 bonus_* 旧键改 curio_value_* 列族、三选一权重行整体标退役(E-S 随 TP0 换代)、件次数上限行删「GP/道具件无次数上限」残句;⑨验收三条订正——抽签封闭条「AP 用尽 2 次/属性件达 3 次先剔」改「令牌耗尽快即枯竭」、同调位条「过渡键」改「谓词表实时求值」、加算区同账条购买生命上限改 pool 模式语义(只加上限不回当前生命);⑩不负责表「节点奖励内容与库存语义→地图战斗资源」改「节点奖励件的分类与凭证定义→奇物」(提升池构成与库存归本文——两文档互指矛盾收口)。 | -| —— | 2026-10-09 | 缺号注记:v0.15 未登记(对应批次=MC-1 商店独立刷新机制批〔2026-10-04,git ac3cee7 提交信息明记「冒险结构v0.15回写」、版本行未入表〕,登记见正文「共享池库存」节 v0.15 标签),卫生批仅注记不补写 | -| v0.19 | 2026-10-09 | 文档正确性审查批·独立复核(worktree docaudit-2026-10-09):「秘宝件受同调位约束」段与验收「同调位约束」条补现状注——道具件已随迭代 11 第①批 T7 出池,三渠道零投放、替换交互无现役触发面(与关卡节点地图 v1.7「满位替换子交互随之不再触发」口径对齐),约束保留作渠道恢复契约;段内「(06 在册)」悬空指针改「原 06 条目已随收口移除」 | -| v0.20 | 2026-10-12 | **迭代 20 反哺落文批·关卡大奖励换代(用户裁②——通关兑付=专长三选一按档配比加权抽取+回血,2026-10-11 迭代 20 Q1 已裁形态对齐)**:①章节标题/概览行/三层奖励框架表「提升三选一」→「专长三选一」(通关渠道=专长独占兼唯一直接渠道,未选候选不落袋);②提升池七种×档位表与洗牌抽取段整体退役——池机制事实源移交[奇物]「池结构与抽取」节(案D 四级 104/曝光槽 2+1/令牌语义/概率与 cap 解耦),本节压缩为结构层段(共享池冒险级单例/库存=剩余令牌数/reward_pick 封闭流/MC 策略 316-f/断点余库还原);③本文件「提升三选一」指通关兑付处换代「专长三选一」、指奖励节点选择处换代「奖励节点三选一」(生命周期图/加算区同账段/共享池账本段/关卡序列图/验收步骤 6/结构冻结——版本历史行引述豁免);④不负责表换代(池结构与抽取机制→奇物;共享池库存账本留本文);⑤~~秘宝件~~出池删除线行随提升池表退役(渠道恢复契约口径由「秘宝件受同调位约束」段承载不变);⑥刷新句「提升三选一免费双源」中性化「三选一免费双源」 | -| v0.21 | 2026-10-13 | **Y 断点随存缺陷修批(06「天赋树实装批登记欠账三条」③——用户令单独开修)**:「冒险断点」节附随件清单扩 **Y 刷新池余量**(attune_refresh_y——续玩优先读断点、不自参数面整额重注入,堵「用完 Y 退菜单再续玩满血复活」可利用漏洞;旧断点缺键回退参数面=旧档行为零变化);快照时点不变(停点整体覆写已覆盖 Y 消耗后状态)。断点域登记与版本口径归[存档序列化](../表现与支撑/存档序列化.md) v1.8(v7 域后扩列不升版) | -| v0.22 | 2026-10-15 | **简明技术中文用语规范批(用户令):词面修正 9 处**——「若干」→「三关(关数读关卡表)」1 处(冒险计量单位定义句);「报错」→「返回错误」1 处(加关纪律运行期拦截句);「收口」→「收支口」3 处(GP 冒险账本钱包句、表头、验收 GP 账本封闭条——名词义,对齐本文件生命账本「收支口」既有用词)+→「完成」1 处(同调位约束段「统一收口」);「不得」→「禁止」2 处(共享池账本两渠道句、主种子节生成新种子句);「在飞」→「执行期间」1 处(放弃受理句·战斗域单事务括注)。机制与数值零改动;不负责表 HUD 行「随 spec 命名收口退役」与同调位段「原 06 条目已随收口移除」系更名/条目处置记载(对照性文本)按豁免保留 | -| **v0.23** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:「生命账本/GP 冒险账本」表行与节标题 →「生命/GP」;GP 节标题改「### GP:…」,全库指路同步;生命/GP 两笔的系统资源表述换代(机制零改动)——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/systems/冒险循环/奇物.md b/design/gdd/systems/冒险循环/奇物.md index 996053c4..4719d536 100644 --- a/design/gdd/systems/冒险循环/奇物.md +++ b/design/gdd/systems/冒险循环/奇物.md @@ -118,7 +118,7 @@ ## 资源(重设计·基础框架 v1) -> 本节是补给分类的现行事实源。补给成员 = **转换源**:不是系统资源本身,是「到手即结算成一笔系统数值的凭证」——凭证加完消尽,被写入的系统资源各有自己的寿命档位(五档轴见[核心循环](../../01-核心循环.md)「生命周期轴」节)。判据句与归类方法见 §1.3/§1.4。**新凭证已随迭代 20 专长实装批落表(2026-10-11);2026-10-18 用户裁削两件后,现行成员=新 3+留任 2(同调电池删除、完美保险归专长——见版本历史 v3.18)。** +> 本节是补给分类的现行事实源。补给成员 = **转换源**:不是系统资源本身,是「到手即结算成一笔系统数值的凭证」——凭证加完消尽,被写入的系统资源各有自己的寿命档位(五档轴见[核心循环](../../01-核心循环.md)「生命周期轴」节)。判据句与归类方法见 §1.3/§1.4。**新凭证已随迭代 20 专长实装批落表(2026-10-11);2026-10-18 用户裁削两件后,现行成员=新 3+留任 2(同调电池删除、完美保险归专长——见 git 提交史 v3.18)。** ### 凭证件表(新 3 + 留任 2;代号制命名归用户;稀有度档、配额与面值数值归调参批) @@ -461,43 +461,3 @@ ## 待办 全部待办单点登记于 [06-待办清单](../../06-待办清单.md)(BD 分层条目、命名统一后续条目),本节不复制。 - -## 版本历史 - -| 版本 | 日期 | 变更 | -|---|---|---| -| v1.0 | 2026-10-05 | 以「特性」为名首次为本概念立定义文档。此前它按内部分类被叫成三个名字(规则类称「流派件」、属性类称「数值件」、界面称「本关强化」),现收敛为一个对象下的分类;性质定为「角色自身得到提升」而非「获得物品」。 | -| v1.1 | 2026-10-05 | 分类重构:两类由「规则改写型 / 属性加成型」改为「属性提升 / 专长」。 | -| v1.2 | 2026-10-05 | 专长渠道落定:关底 Boss 击败后兑付,不新增节点类型;罕见旁路明确为"普通奖励里的专长 N 选一"。 | -| **v2.0** | 2026-10-05 | **顶层改名为「奖励」并重构为两根轴**。改名动因:筐里既装"角色自身的变化"也装金币这类一次性兑付物,用"自身提升 vs 持有物"已切不开,边界判据改由生命周期承担——**当局清零的是奖励,跨局带走的是魔法道具**。分类由两类改为**三个枚举**(当时的写法是「机制类 / 属性提升类 / 资源与机会类」,v2.7 才定名为专长 / 属性值提升 / 资源):专长 / 属性值提升(生命·AC·攻击)/ 资源(行动点上限·刷新次数·金币·回复)。新增第 2 节分类 × 渠道交叉开关表,明确两根轴互不决定;金币与回复不再被当作"该移出去的脏东西",而是安置在资源里,同时把它们的即时兑付性质显式登记为类内异质性。 | -| v2.1 | 2026-10-05 | **交叉表收口(用户拍板)**:Boss 渠道**只出专长**,属性值提升与资源在此均不出现——三条渠道的形状定为"一块独占 + 两块并行",专长靠打赢、其余靠抽取与购买。Boss 兑付明确为**终局前**的 Boss,终局 Boss 不给(无后续关卡可消费)。新增 2.4 节**「计价物不自售」规则**:金币不进商店既不拆分类也不开特例,而是写成两轴交叉处的一条约束——商店的计价物是金币,故金币不进商店;按"能不能进商店"反推分类等于用渠道轴去切分类轴,两根轴会缠回去。 | -| v2.2 | 2026-10-05 | **凭证形态 + 约束分层 + 默认原则**。① 用户明确:奖励节点与商店不直接给专长,而是给一个**「专长获取」道具**,拿到后开专长三选一——交叉表专长在两渠道由"不出现"改为"**凭证形式**";凭证归专长(给的是一件以前不会的事,只是把选择推迟),理由是防止用钱定点买构筑。② 用户质疑「计价物不自售」本质是特判——**承认成立**:它确实是在分类白名单之外加的一道过滤,与死特判的区别在于把"枚举例外"变成"**可计算谓词**"(新渠道/新奖励自动判定)。2.4 改写为**三层约束**(分类白名单 / 可计算谓词 / 显式例外清单),并给出判断标准:结构性原因可写成谓词,设计性原因只能进清单且每条须写理由;三个方案(单独分类 / 谓词 / 死特判)的代价并列摆出,不藏折中。③ 用户定**默认原则**:除已登记的特殊规则外,分类内的东西都要在池子里——据此**回复应在商店内**,现行 shop.tres 货架缺它是"现状与表格不对齐",须在实施批补上。 ⟵〔更正注记 2026-10-19:本行①的「凭证归专长」归类记载无用户裁断记录,系写文档时的误记,已在 v3.19 改写为渠道兑付形态表述;机制部分不受影响〕 | -| v2.3 | 2026-10-05 | **凭证机制细化 + 默认原则表述修正**。① 凭证**拿到即开、不可囤积**(用户定)——不进持有集,防止玩家把关键决策无限推迟,也防持有物语义从后门回来。② 凭证的"罕见"**只在概率不在价格**,一局限购一次,并加**计步保底**:连续 5 次三选一展示未出现则第 6 次必出;计数跨奖励节点与商店共享、**刷新后的重新展示计入**(用户明定含刷新),限购用满后保底不再触发。③ **修正 v2.2 的误读**:把"分类在某渠道不出现"当成需要理由的缺格是错的——渠道出哪些分类是渠道轴的定位(Boss 只出专长),不是例外;默认原则只管**分类内部**的成员齐不齐。④ 专长总量与档位阈值的匹配按用户决定**延后**(待第四关内容批后实测复裁),另单独登记 charge 标签仅 3 件、永远达不到档二的数据缺陷。 | -| **v2.4** | 2026-10-05 | **顶层由「奖励」改名为「奇物」(Wondrous Item)**。用户否决了「奖励」「收益」与全部自造词(进益/造化/机缘/遇获),要求回到 DND/西幻既有名词。定名依据:DMG 魔法物品九分类中的 Wondrous Item,官方中文译名即「奇物」,是专装不好归类但有奇效之物的兜底杂类——正好对应本概念下三个互不相干的分类。此前考虑过的 Treasure(宝物)因偏财物、装不下专长而落选;roguelike 品类惯例 Relic 因用户否决遗物落选。**代码词族定为 `curio_*`、`ADVENTURE_CURIO`**(`reward_*` 已被 `reward_pick` / `reward_node` / `reward_preview` 占用,不能对齐)。 | -| **v2.5** | 2026-10-05 | **第三类定名「资源」**(用户拍板,父节点定为「奇物」后解锁)。定名依据:行动点上限 / 刷新次数 / 金币 / 回复都是可以调动、可以花掉的余量。「资源」偏泛(能力资源、财富资源都叫资源),因此在 1.5 写死判据句——**给的是可消耗或可重掷的余量,不是角色基础属性的永久抬升**,这一句是把泛用词收回本类定义的唯一凭据。**回复归属同时定案:留在资源,不独立成第四类**——它与金币同为即时兑付、判据同源,拆出去第四类只剩两项且与本类判据重合。附带修复:1.5 段末与「### 2. 渠道轴」标题粘连(缺换行)。 | ⟵〔更正注记 2026-10-19:本行定名的第三类「资源」已于 v3.20 改名「补给」——原类名与「系统资源」同词(用户 2026-10-19 裁),本类定义以现行 §1.3 为准〕 | -| **v2.6** | 2026-10-05 | **修正核心循环位置图:奇物不是打一场战斗给一份**(用户纠错)。原图把"关内 排雷推理 → 战斗结算 → 通关 → 得到一份奇物"画成一条链,读起来就是每场战斗通关都给一份——**错在把关内普通战斗的通关与关底 Boss 的通关混为一谈**。按 [冒险结构](冒险结构.md) 的定义,**通关一关 = 该关关底 Boss 被击杀**,所以"击败 Boss"与"通过这一关"是同一个时刻、不是一条链上的两步。改法:① 图改为分支结构(普通战斗节点→不给、往下走;关底 Boss 击败→专长三选一+通关回血);② **一关只兑付一次**写成显式口径;③ 2.1 节渠道名由"终局前 Boss 击败后"改为"关底 Boss 击败(即通过这一关)",并写明触发点就是关卡推进本身那一刻;④ 文首引言加"兑付频率"条,交叉表渠道名与 registry 同步;⑤ 连带修掉一处污染——节点类型封闭枚举五种里的"奖励"曾被 v2.4 批量替换误伤成"奇物"(节点类型里没有奇物这一类),已复原。 | -| **v2.7** | 2026-10-05 | **三个子节点正式定名(用户拍板:去「类」字后缀)**。此前三个分类只有带后缀的描述(机制类 / 属性提升类 / 资源类),是文档层临时叫法,既非专名也非玩家可读的词。现定专名:**专长**(Feat)/ **属性值提升**(ASI)/ **资源**。定名依据:前两个是 DND 规则书官方中文,且与用户 v1.1 原话一致(当时原话就是「属性提升(ASI)」与「专长」,v1.1 写入文档时被加了「类」字后缀而退化成描述)。「机制类」这个叫法本身还有硬伤——它的 28 个成员里没有一件是"机制",实际是"在结算挂点上改一条规则",读者看到会误解为游戏机制。 -| **新增 1.6 节「三层结构与命名」**(用户 2026-10-05 拍板做玩家可见的三层):奇物(总称)/三个分类/具体单件。明确**命名是本节规矩、呈现是另一件事**——分类名在卡面不出现(归 battle.md / node-reward.md 裁决),但帮百科、成就名、效果描述的指代三处都要用,所以它必须是玩家读一遍就懂的正式名词。连带:修掉批量替换撞出的五处「专长(专长)」类自撞、v2.0 历史行内的自撞并标注当时的旧称、registry 的「资源(命名待定)」过期标注。 -| **v2.8** | 2026-10-06 | **效果行为数据驱动换代(内容数据驱动扩展批)**:专长的效果声明从「挂点+效果字典」换为「订阅行」——每件声明**订阅哪个事件(on)/ 什么条件(when)/ 什么效果(do)**,由效果引擎统一解释执行;旧挂点枚举消亡(事件名+效果类型取代)。配套事实:效果引擎 `game/core/effect_engine.gd`(事件 16 / 效果类型 24 / 条件事实 9 / 算子封闭词表);专长行 `feats.tres` 27 件全量迁移,秘宝被动六件同批订阅化;行为与迁移前逐位一致(MC 同种子 40 局逐位逐项比对实证)。 -| **v2.9** | 2026-10-07 | **专长体系推倒重设计裁(用户裁——道具三层重设计·奇物层)**:专长分类的**流派标签(archetype)与档位机制(集件质变)框架级作废**——用户判流派式设计「烂到极点」,且流派标签从未被认可为呈现面概念(命名铁律:流派名禁上玩家可见面,06「内部分类禁写入玩家可见面」条升格);现行 27 件全数待重设,重设计主权归用户,灵感原材料归调研批(design/research 两份 2026-10-07 调研);审查「六流派档位兑付位立项」方向随档位作废注销。专长=机制改写件的分类定位、凭证/渠道机制、属性值提升与资源两分类不受影响。新增准入校验(重设计适用):**代价与收益须同账可核算**——「纯代价件」禁止出生(深挖钻头/整备军备教训);头部加冻结遗留态横幅。 | -| **v3.0** | 2026-10-07 | **专长基础框架落地批(用户终审认同——道具三层重设计·奇物层)**:新增「专长(重设计·基础框架 v1)」节=新现行事实源——设计原则五条(触发器句式/事件族组织不上卡面/准入校验同账可核算/信息红线/防兑换环)+基础件表 18 件(开格系6/插旗系3/踩雷系3/节奏系3/战斗系3+契约尖点1;代号制命名归用户)+扩签登记(新事实候选6+停手挂点+清图事件暂缓)+老27件处置(随实装批整体替换、仅作素材库不默认继承);横幅由「推倒重设计中」翻转「基础框架已立」;数值归调参批、实装归重设计实装批。 | -| **v3.1** | 2026-10-07 | **档位名与 rarity 语义约束顺带(现行事实源=[核心循环](../../01-核心循环.md)「档位与获取规则」节 v1.5 同批写入文档)**:稀有度四级采用**普通/优秀/稀有/传说**——本层旧三档名映射=普通→普通、稀有→优秀、罕见→稀有,第四级「传说」=新增头奖位(正文档名扫改归奇物批次);**专长 rarity 语义约束落为文档约束**——Boss 三选一候选按档配比或加权抽取(双脱钩修复:此前 rarity 不影响抽选也不稳代表幅度;配比数值归调参批,MC「最稀有优先」策略的读数偏颇随实装一并校正);「获取概率提升不动保底」护栏同批。 | -| **v3.2** | 2026-10-07 | **资源分类基础框架落地批(五件新凭证用户裁准——道具三层重设计·奇物层)**:新增「资源(重设计·基础框架 v1)」节=新现行事实源——定义句重写为**转换源**(成员=到手即结算成独立资源/系统数值的凭证,加完消尽,账各有寿命档)+凭证件表新 5 留任 2(刷新券/储备金袋RAP/同调电池/时沙/完美保险+小金币袋/应急口粮;代号制命名归用户,稀有度档配额面值归调参批)+上架原则(默认原则全渠道可出);§1.3 判据句与异质性节随迁重写(凭证全部即时消尽,异质性=账的寿命不在凭证上);池子档位形态(各档装什么)待用户裁后顺带 | ⟵〔更正注记 2026-10-19:①本行「五件新凭证用户裁准」系失实记载——当日用户所裁为池结构案D,未作此归类裁定;②本行「资源分类」已于 v3.20 改名「补给分类」〕 | -| **v3.3** | 2026-10-07 | **池结构与抽取写入文档(用户裁案D——归档打底做翼+曝光槽,道具三层重设计·奇物层)**:新增「池结构与抽取(重设计 v1)」节——令牌=出现次数上限明文化(拿消耗/没拿回池/刷新不消耗,「只刷出没拿」不计次,TP0 语义沿用);内容归档=普通档面粉打底、优秀/稀有档功能凭证做翼、传说档惊喜位(按决策影响力归档不按数值);曝光槽=三选一 2 格全池+1 格「优秀档以上」子池(子池空回退全池,池空直通同族);凭证维持独立计数体系不进子池;配额改动须用户重裁(TP0 结构锚非调参);MC 策略读数影响随实装复核 | -| **v3.4** | 2026-10-07 | **概率与上限解耦约束+耦合问题登记(用户指出的令牌模型冲突——道具三层重设计·奇物层)**:池结构节补两条——①**概率与上限解耦**(设计约束,新内容必检:概率位与已拿上限=两个独立字段,拿了才计/刷出不计,互不决定);②已知耦合问题与实现路径候选三案登记(令牌 N 张同时承担概率与上限不可独立设定——抽象权重表+独立计数器/令牌池+提前退役计数器/维持耦合已否;选型归实装批,影响面=MC 对账与断点存档)。用户裁:实现设计不定于现在,只落约束与问题点防后续撞车 | -| **v3.5** | 2026-10-07 | **秘宝域迁出两件迁入登记(用户裁——秘宝层归留裁决同批)**:淬毒刃纹→战斗系克制向(`on attack_commit + advantageous → 追加 +N`);标中殉爆→插旗系(`on flag_hit → 全体存活敌 N 群伤`,插旗系补第 4 件;数值均归调参批);惊巢反制→退役进素材库(归[秘宝](../跨局循环/秘宝.md)速览「目录处置」同批);实装批执行数据迁移 treasure→feats 并补入件表 | -| **v3.6** | 2026-10-09 | **旧条例外科摘除批(用户令——流派方向讨论中暴露的活矛盾)**:①分类表专长行、§1.1、生命周期表、P1 后置四处「流派标签·集件档位质变」残句摘除——v2.9 已框架级作废,残句以正文规则身份存活、持续误导设计(「战斗系占比须治理」伪问题即其衍生);②验收标准第 4 条 B1 铁律(每流派标签 ≥1 件挂排雷侧触发点)作废,替换为条件判据「收益必挂条件、无条件数值归属性值提升」(用户同日讯:纯属性增加不是专长,通过条件获得数值才是专长要做的);③待办两条(档位阈值匹配复裁 / charge 标签缺陷)因对象消亡注销。未动:冻结遗留(老 27 件清单与战斗结算侧现行代码行为描述)仍随重设计实装批整体替换;06-待办清单内三处描述性残留(BD 分层条目现状文 / charge 条 / 档位呈现裁点)归 06 条目自身生命周期,另行列出。 | -| **v3.7** | 2026-10-09 | **去毒批(用户立「文档去毒」为首要任务)**:退役术语魔法道具→秘宝(正文各处,含关联边界表)/档名三档→四级扫改(罕见→稀有)/凭证与刷新入表状态订正(迭代15② 已入库,调参表与 P1 与待办节同步)/资源成员指路凭证件表/验收第 3 条改令牌口径——新老框架分家第一步,老章节冻结段随实装批整体替换不变。 | -| **v3.8** | 2026-10-09 | **文档正确性审查批(用户令——状态记录与证据对齐)**:①§1.6 命名节例子「同标签达到 4 件时质变」摘除(流派标签集件档位 v2.9 已框架级作废,换为不引退役机制的归类指代例);②渠道轴交叉表专长行自撞「专长(专长)」修为「专长」(v2.7 同类自撞漏网);③§2.4 回复节现状句订正——shop.tres pool_shelf 六行已含回复(迭代15② 落地,默认原则对齐),「货架四项、回复缺席须补上」过期表述替换;④§2.5 在册事项订正——凭证形式已随迭代15② 入表实装,渠道分工仅 Boss 渠道直接给专长仍为目标状态;⑤生命周期表选定行老规则「选定即从池中剔除、任何渠道不再见」改令牌口径(拿消耗、刷出不计、耗尽不再出现——对齐验收第 3 条与 TP0 在役语义);⑥依赖与输出表摘除「档位求值结果」(集件档位作废的漏网输出);⑦§1.2 补成员变动在途注(行动点上限归属性值提升轴,在役仍三项、迁动归实装批——对齐 §1.3 表下现行事实源注)。 | -| **v3.9** | 2026-10-09 | **B3/B4 两裁写入文档(用户令)**:①P1 后置「两项合成高阶项」注销——非用户设计意图的脏信息,合成方向若需要按新体系重新生一件;②§3 刷新次数例外句口径换代——一律按最新设计口径:刷新次数由刷新券替代(凭证到手即结算进刷新存量账、加完消尽不进持有集),旧「进同一份持有账本」表述作废、随实装批整节删除 | -| **v3.10** | 2026-10-09 | 文档正确性审查批·独立复核(worktree docaudit-2026-10-09):①§1.3 异质性节「被写入的账」清单对齐凭证件表——旧四项时代「AP 上限」摘除(已归属性值提升轴,§1.2 在途注),补生命账/秘宝充能两账;②依赖与输出表 `relics.tres` 改 `feats.tres`(表文件已随词族对齐批换代,data/tables/ 无 relics.tres——代码实证) | -| **v3.11** | 2026-10-10 | **正文换代批(方案甲,用户裁「旧的删、误标改」——同秘宝.md v2.2 同法)**:①头部冻结横幅摘除——所指「流派/档位/27 件清单」旧章节正文已不存在,名单承载=[道具退役素材库](../../../research/道具退役素材库.md)表二;②专长/资源两节引言去「冻结遗留态/随实装批整体替换」错标,各落一句「新框架实装批落地前,现役代码按同框架运行」;③§1.3 旧资源四项枚举表删除(成员去向一行交代:行动点上限归属性值提升轴/刷新次数由刷新券替代/金币回复留任为小金币袋/应急口粮),回复归属裁定并入「资源为什么单独成一类」段;④§1.2 在途注与 §3 刷新例外去标注改正文(行动点上限归本轴/刷新券口径一律按最新设计);⑤§1.6 单件举例换新框架件(奥术余烬/贯穿射击→双管镐/疼痛记忆);⑥「谓词」用词清除——「可计算谓词」改「可计算条件」(正文与验收,版本历史行引述豁免);⑦验收 4/7/8/9 换代新口径+尾部现役代码运行线;⑧P1/P2 括注清算(已清偿/已注销条目由版本历史承载)+待办节收编为 06 单点指针。真旧内容承载=素材库表二+git 历史 | -| **v3.12** | 2026-10-11 | **自爆流扩容批(用户逐裁——踩雷系从被动补偿转主动输出循环)**:踩雷/受伤系 3→7——新增爆芯(踩雷→本轮攻击 +N,走面板乘区)/连爆(同轮多雷递进加层,与疼痛记忆 combo 涌现)/爆心冲击(踩雷→全体敌 雷伤×倍率 直伤,倍率 >1 结构锚——「角色与怪物互相吃伤害」系用户形态本体:开安全格零代价、引爆有代价故回报须更高)/雷蜜(踩雷→回复 N,比值 <1 结构锚);新增跨族桥引信标定(挖开有旗危险格→+1 层——印记=标定引信、挖=引爆,插旗×踩雷推理闭环);扩签登记 +3(本轮踩雷数计数器/被挖格当时有封印印记/雷罚伤害量);**踩雷转化对账锚**顺带登记(净血账期望须为负,两轮压不住砍血蜜——喂雷流 R5 甲教训同源的 kill-switch);用户裁定:主动/误踩不判定(不预判玩家意图,拿件自选收益最高操作)、爆芯走面板、爆心冲击按倍率非折扣;防御向两件(保险丝/安全帽)保留不动——双刃剑两刃相辅相成;附带修正基础件表战斗系计数 3→2(v3.0 起表头与行数不符),件表总 18→23 | -| **v3.13** | 2026-10-11 | **生存件扩容批(用户令「增加生存类的个数」——四类盘点呈报后逐裁)**:件表 23→27——①石肤(on 受伤:AC +1 本场累计上限 M)入踩雷/受伤系——恒定减伤形态被否(用户裁「太硬霸」),改受击成长型护甲;②背水(when 生命 ≤50%:受伤额外 −N)入踩雷/受伤系——风险联动减伤,低血不再是纯劣势;生命比例条件事实系其实现前置需求,用户批扩签+待办登记 06;③铁旗(on 标中:本轮 AC +N)入插旗系——生存奖励挂正确推理,与旗语回响共享事件;④战地包扎(on 战斗胜利:回复 N)入战斗系——战后通用恢复,补「恢复只服务自爆流」缺口。四类占比换代:减伤 2(安全帽/背水)/护甲 3(保险丝/石肤/铁旗)/恢复 2(雷蜜/战地包扎)对增伤 8 ≈ 1:1;用户口径订正=保险丝护盾归提升护甲类(AC 判定)、减伤专指受击直接扣减伤害 | -| **v3.14** | 2026-10-11 | **实装前置两项裁定写入文档(用户裁)**:①§2.5——Boss 渠道直接给专长(主渠道、唯一直接渠道)**已裁随专长实装批本批落地不再分期**;②§2.5 新增池结构选型澄清——池结构正主=案 D(v3.3 用户定夺在案:归档打底做翼+曝光槽 2+1+令牌=出现次数上限),「概率与上限解耦」实现路径(v3.4 在册三案)系**实装侧自选项非用户裁定项**(原裁定「实现设计不定于现在」=实装批内依代码事实自选不再上问)——成因=会话误将实装侧自选升级为用户裁定项重问已定夺事项,经历史记录(2026-10-07 讨论记忆+TP0 令牌池天然兼顾核实结论)找回定夺后澄清;06 渠道分工条状态行顺带同步 | -| **v3.15** | 2026-10-11 | **专长件第一版命名批(用户裁——对外命名纪律:无「雷」无「插旗」,插旗对外=封印、危险格对外风味=地下城陷阱/怪物巢穴;「扫雷插旗」系内部开发用语、对外=探索/挖掘地下城)**:九件代号换代——插旗系:旗语回响→**封印回响**/猎旗手→**封印匠**/铁旗→**封印桩**;踩雷/受伤系:爆芯→**陷阱本能**/连爆→**连环陷阱**/爆心冲击→**陷阱爆发**/雷蜜→**血蜜**;跨族桥:引信标定→**破封一击**;迁入登记:标中殉爆→**封印爆裂**;示警烟火/疼痛记忆/保险丝/见血开窍/石肤/背水/爆破会计等保留(无雷/旗字);纪律登记=术语表新增「对外命名纪律」节(v1.6);版本历史行引用旧代号系留痕不动;命名纪律试例=件名,后续全部对外命名(显示名/UI 文案)同尺 | -| **v3.16** | 2026-10-12 | **迭代 20 反哺落文批(用户令「先回写 GDD」——追认单①裁决齐,06 追认结果条承载裁决记录)**:①设计原则新增**落行注记**:「每第 N 次/积满触发」预评估落行=N−1(when 先于 do 读计数器现值,例:地质学家 eq 3/封印匠 mod_eq ref 2);②疼痛记忆件表「下场战斗」→「下一次攻击」(2026-10-12 用户定性笔误,无需 battle-gate 面);③弃图兑换落法回写=停手后首次攻击全额附加、用后清零、多攻击不拆分;④血税件表补生效时点(均**下一战起生效**——战末汇入冒险加算区,战界重建契约所致滞后一战)+账列换代双向同账细则;⑤时沙落法回写=下一战首轮 AP 队列兑付(hero_ap_bonus 既有通道),§1.3 判据句与异质性账清单「当前 AP=回合级」随迁「时沙暂记=至下一战首轮兑付」;⑥扩签登记节换代为实装承载记录(10 候选=6 fact+4 计数器改道/dig_stop 落/battle_won+mod_eq+hp_ratio 等随裁补位/新效果类型 7/rewrite_board 除名、清图事件继续暂缓);⑦专长/资源两节引言「新框架实装批落地前」过渡句随批落地 expiry 换代(29 行=基础 27+迁入 2/凭证新 5+留任 2 已落表);⑧流派口径澄清落档=**对外永不显示、对内保留事件族五系划分**(v2.9 作废所指=流派作玩法机制非对内划分本身,2026-10-12 用户重申——设计原则第 2 条原文已符,正文零改动);待办=血税卡面 desc(feats.tres)补「下一战起生效」系代码侧一行改,另行小批 | -| **v3.17** | 2026-10-15 | **简明技术中文用语规范批(用户令):词面修正 7 处**——「不得」→「禁止」3 处(信息红线条、代码词族 reward_* 句、验收第 6 条);「若干」→写具体数值 2 处(核心循环位置图「三关串联」、生命周期表出现行「3 个候选」);「收口」改写 2 处(§1.3 判据句「收口凭据」→「界定凭据」、§2.1 悬案句→「完成裁决」)。机制与数值零改动 | -| **v3.18** | 2026-10-18 | **凭证件裁削批(用户逐裁——①同调电池删除、②完美保险改归专长)**:①凭证件表计数「新 5+留任 2」→「**新 3+留任 2**」——同调电池整行删除(秘宝=局外同调件、冒险中零更换途径,与 2026-10-11 撤换装券/删回能器同一原则,且 UI 层从未接线选件入口);完美保险整行迁出资源类改归专长,理由=它给的是规则豁免而非可调动的余量(§1.4 判据),经文记入迁入登记节。②§1.3 异质性「被写入的账」清单注销「秘宝充能」「完美资格」两账;`attune_charges` 账本本身仍属秘宝基础设施保留(迭代 11),本次只删奇物侧写它的入口。③受影响的计数与指路同步换代:§1.3 引言、凭证件表标题、调参表「资源种类」行。④**一处失实记载订正**:资源节头注原写「2026-10-07 五件新凭证**用户裁准**写入文档」——当日用户所裁为池结构案D,未作此归类裁定,该句删除(「资源成员=转换源」判据句本身本批不动,是否复裁归 06 在册)。⑤本批**代码侧零改动**,归独立批:`CURIO_KINDS` 删两枚、`TIER_QUOTAS` rare 9→7 与总量 104→102(结构锚,用户已裁**净删**)、`feats.tres` 增完美保险行、效果引擎扩签一种效果类型、`grant_segment` 硬编码改订阅式(误标总数减豁免数得有效数,不改写既有计数值)。 | -| **v3.19** | 2026-10-19 | **一处误记载订正(用户定性=写文档时的误记,令改)**:§1.1、§2.2 与 `entities.yaml:629` 三处原写「专长凭证归专长、不归资源」——2026-10-19 考古确认其引入与后续两次改写(`d6c13809`/`b6b43ebc`/`6951632d`)分别只承载机制、子节点定名与术语更名,**无一处含归类裁断记录**,现三处统一改写为「专长在非 Boss 渠道的兑付形态」,不再对此作归类论断。**机制零改动**:非 Boss 渠道仍只给凭证、拿到即开、不可囤积、一局限购与计步保底全部不变,交叉表专长行仍是「凭证形式」。连带两处:完美保险改归专长的依据指针由 §1.1 改指 §1.4(**归属结论不动**);v2.2 历史行不改写字面,行尾追加更正注记指向本行。第 2 项(§1.3 资源判据句)本批不动,心智模型对齐前不裁,仍挂在 06 在册条目内。 | -| **v3.20** | 2026-10-19 | **定名批:「系统资源」立规范名+第三类改名「补给」(用户裁)**:①「系统资源」定为 GP/钥石/行动点当前值与上限/储备行动点/刷新存量持久量与当次临时量/生命/充能/时沙暂记等"战斗数值以外的数值容器"的规范名,唯一定义处=[核心循环](../../01-核心循环.md)「系统资源」节(每笔带寿命档+总线/抽屉两坐标);旧称「账/账本」「独立资源」「系统数值」全库退役,跨文档引用只写规范名加指路。②第三类由「资源」改名「**补给**」——原类名与系统资源同词,会把"给系统资源加一笔的件"误读成"系统资源本身";类定义改为"给某一笔系统资源做一次性加仓的凭证(转换源)",§1.3/§1.4/分类表/交叉表/凭证件表同步换代,§1.5 保留命名沿革备查。**机制与数值零改动**:五件凭证写入的账目、配额、寿命档全部不变。③连带:术语表补「系统资源」「补给」词条+节名改「系统资源与经济」;02-系统清单奇物行换代;entities.yaml categories 按 owner 同步。④v2.5/v3.2 历史行不改字面,行尾追加更正注。⑤**代码零改动**——`CURIO_KINDS` 的 kind 字面是账名(gp/ap/heal/refresh/rap/time_sand)不是分类名,不受本次改名影响。 | diff --git a/design/gdd/systems/冒险循环/难度曲线与Boss.md b/design/gdd/systems/冒险循环/难度曲线与Boss.md index 3482d90f..30ec5bc9 100644 --- a/design/gdd/systems/冒险循环/难度曲线与Boss.md +++ b/design/gdd/systems/冒险循环/难度曲线与Boss.md @@ -335,38 +335,3 @@ Boss 战的棋盘用本关最大板形(板形行值读棋盘参数表),板 ## 待办 本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | -| v0.2 | 2026-09-15 | 教学位掷骰自洽(用户拍板:代码不动、文档对齐):删除"教学位/首遇位固定不掷"豁免口径,教学位地精数量明确为开战掷骰区间 [1,2];D0 行数量列改 [1,2];Boss 血量锚 Σ=153.5 补逐数验算(区间期望口径下闭合) | -| v0.3 | 2026-09-15 | 雾格残留清理:关闭「待拍板」的雾相关供给验算失义条目(原供给与对账验算含雾板分层、雾成本负担比等输入分量);第二关新内容投放缺口条目改为引用「已从设计中移除的机制」(见不做清单)。曲线规则、供给带与对账义务不变 | -| v0.4 | 2026-09-15 | **护甲等级批(与战斗结算 / 敌人系统 / registry 同批登记)**:生存链区间模型补记护甲等级掷点带宽口径——峰值/谷值构成各含最坏/最好掷点带宽;EV 中性引入成文(期望伤害对齐现行表值、现行行值不重调,折扣档位与掷点形式定稿前区间扫描维持全额口径、带宽项随定稿批补扫,"零红档"验收与三档判定式不变);调参联动表新增"护甲等级 ↔ 攻击基线 ↔ 区间带宽"一行 | -| v0.5 | 2026-09-16 | **护甲等级掷点批·定稿落地(与战斗结算 / 敌人系统 / registry / 切片代码同批)**:带宽口径改写为"换装点锚定"——掷点形式与档位定稿(d20 / 缺口 1-3→×0.75 · 4-7→×0.5 · 8+→×0.25 / nat20 暴击 ×2 恒全额),基准 AC10 自带约 −21% 敌方输出期望(AC11 25% / AC12 28.75%),对比退役的 defense_up 满层 −60% 减伤墙为结构性削弱 + 伤害下限使零承伤轮结构性消失,方向性偏移与加难杠杆扫描合并处理、不单独重调行值;带宽补扫义务含暴击档与折扣档(并入加难扫描批);护甲等级行值:主角 10(暂定)、敌方首关 0(暂定,正式行值归怪物设定批);调参联动表"护甲等级"行改定稿口径;调参表主角表行与状态强度行同步(减伤 −30 → 护甲强化 +1 AC ×2 层) | -| v0.6 | 2026-09-16 | **敌人技能池批(与敌人系统 / 战斗结算 / 增益状态 / registry / 切片代码同批)**:曲线纪律两处改写(关间台阶"既有敌种新行为环段" → "既有池新技能";关内坡度"保持行为环读数不变" → "保持技能池 EV 读数不变〔权重即旋钮、EV 重锚随批登记〕");Boss 约定改专属池承载(独占技"硬化" + 权重轮廓,旧"专属四拍环且含蓄力拍"退役);调参表敌人行值表"行为环"列改"技能池(权重)"列并落建议池行值,新增"技能池投值"四行(池权重 / 技能冷却 / 保底 M / 池 EV 锚——含闸长期速率实测登记:地精 1.106〔保底闸抬升〕/ 熊地精 1.000 / 酋长 1.024);重击倍率注记随倍率归技能行删除;区间模型受伤峰值/谷值构成改按含闸长期速率复核口径;行值零改动(EV 中性锚定维持,重锚与权重投值随加难扫描批合并处理) | -| v0.7 | 2026-09-17 | **分支节点图批(L2 幽暗地域内容批——与切片代码 / registry / 关卡节点地图 / 06 待办同批)**:第二关深度轴行值填充收口(原 P1 后置项)——图版编号 D0–D8 九节点,战斗/Boss 七坐标在敌人表与棋盘表各有精确行(跨表校验强制);新敌种巨蜘蛛 giant_spider(群行 [2,3]、首遇位固定、轻甲)与 Boss 蛛化卓尔精灵 drider(重甲、血量 175 = r_boss provisional 锚);既有敌种 bugbear 池新技能突刺(兄弟精池差异化——关间台阶纪律两半均兑现);新技能行撕咬(×1.5 冷却 1)/ 毒爆(×2.5 冷却 4,蛛化卓尔精灵专属池独占);技能池投值表 / 棋盘参数表随批扩列,L2 池 EV 锚登记静态份额(≈1.28/1.11/1.33/1.67,含闸速率待抽样);首遇位绿档冒烟断言落地(基线 0 加成完美档 12 种子首遇战全胜且零踩雷)。全部行值 provisional,L2 整关通关率读数随批实测记录于切片汇报(精调归加难杠杆扫描批)。〔2026-09-18 注:本条为历史批注——血量 175、撕咬 ×1.5 / 毒爆 ×2.5 等读数已随数值压缩批作废,按数值纪律不再留值,现行值读 `enemy.tres` / `skills.tres`〕 | -| v0.8 | 2026-09-17 | **文档降级为模板批(用户拍板,与敌人系统 / 战斗结算同批)**:数值纪律定稿——本文只定规则、取值域与口径,全部具体行值移除、一律读配置表(切片 `data/tables/` 与 registry);调参表敌人行值十二行整表改行模板(敌种语义注记保留),技能池投值 / 主角表 / 棋盘参数 / 关键投值各表删除"现行值"列改口径登记;Boss Σ 逐数验算(153.5 闭合)移除改"调参日志留档"口径;换装点锚定句去 AC 硬读数;伏击上限、保底 M、教学位区间等散落行值改"读表"。背景:切片 `.tres` 数值压缩批后文档行值已滞后,双写失同步被实证 | -| v0.9 | 2026-09-17 | 数值纪律收口批:正文 knob 现行值改指路存根(事实源 data/tables/*.tres 与 registry),8 处失同步修正——曲线结论与换装点句残留读数改读 enemy.tres / settlement.tres;护甲克制 150/100/50 与联动表 d20 ×2 / 主角 10 / 敌 0 改读表(消双写);元进度换算率 +10≈1 轮 / 翻倍≈减半改 registry / 调参日志口径;**normal 模拟档目标带 [30,50]→[10,25] 用户拍板落文,旧读数 60% 删除(压缩批后失效,重测随验收批另批登记)**;通关余量带 p90≤13 / p10≥3 压缩前绝对血量带改相对量口径(含验收标准节同步,清单外顺手修正) | -| v0.10 | 2026-09-18 | **元进度定稿批(与 元进度 v1.0 / registry / 06-待办清单 同批)**:元进度接口预留节改定稿口径——区间平移换算率启用(带平移,判读口径不变),换算率表首版三行与护甲行强条目指路 registry `meta_progression_conversion_table`,数值标定归元进度设计批;P2「区间平移换算率定稿」行同步改剩余面口径。曲线规则与行值零改动 | -| v0.11 | 2026-09-18 | **甲效矩阵用户调参批同步(零代码,事实源 settlement.tres 五格改值——详见[战斗结算](../战斗循环/战斗结算.md) v0.15)**:正文克制矩阵节与调参表联动行「克制/中性/被克三档」措辞改五档(克制 / 弱克制 / 中性 / 弱被克 / 被克,档值读表);联动义务面扩写——矩阵档值变更与敌种护甲变更同列,都必须复算 Boss 与普通战的击杀区间。敌种甲类型行值零改动 | -| v0.12 | 2026-09-18 | **数值语言拍板批·甲效矩阵加法核换装同步(零行值改动——与 01-核心循环 数值语言条款 / 元进度 / registry / 06-待办清单 / 切片代码同批)**:正文克制矩阵节与调参表克制矩阵行两处五档措辞改三档加法(克制 / 中性 / 被克三档加法修正 +1 / 0 / −1 点,量纲由百分比改整数点数);重定价义务面扩写——矩阵加法修正点数随攻击成长的重定价与敌种护甲变更同列,均须复算 Boss 与普通战的击杀区间 | -| v0.13 | 2026-09-19 | **技能池节奏体验验证批(与 06-待办清单 / tools/skill_rhythm_audit.py / smoke/rhythm_batch.gd 同批,零行值改动)**:06 待办「单拍行为环的体验验证(改型:技能池节奏体验验证)」解决移除——判读带用户拍板(过旱 = 战斗整体全敌人零特殊技;过涝 = 连续特殊技无普攻基底);调参表「池 EV 锚」行登记 60 种子正式读数(份额对表 / 保底零越界 / 过涝无信号 / 过旱归短命杂鱼生存时长);**方法论规则成文:节奏/EV 类日志读数须 ≥50 distinct seeds**(4200 系 10 种子×网格重复曾产生地精一伙 0/484 突刺假象,4300 系复跑证伪——与 armor_roll 种子偏置发现同族,见 registry rng_service 关联面) | -| v0.14 | 2026-09-20 | **伏击单轮上限删除批同步(零行值改动——上限行值整体退役)**:关键投值节单轮伏击授予上限改述不设上限;原 advantage_per_round_cap 对账供给面随批作废 | -| v0.15 | 2026-09-20 | **格面资源八型批同步(零行值改动——与敌人系统 / 战斗结算 / 地图战斗资源 / 行动经济 / registry / 切片代码同批)**:① 受伤峰值构成去"伏击附加"项(伏击随八型批退役);② 关键投值节伏击上限措辞改述为群伤负向 = 警觉(敌方护甲等级 +1),原 advantage_per_round_cap 对账供给面维持同日先行作废;③ 警觉与行动点修正两新词的当量对账义务归本系统调参批(随 06 清单「调参批数值点评登记」条执行) | -| v0.16 | 2026-09-20 | **基线通关率带分带批 + MC 重投基线(用户拍板方案 A;台账 105〔登记时撞并行会话 103 号,顺延让号〕)**:① 基线通关率带由单一 [10%, 25%] 改为分带——第 1 关 [35%, 55%] / 第 2 关 [25%, 45%]:旧带锚定随机点击画像,普通画像换装基础定式后失锚;推导链 = 真人体验换算(模拟 47%/34% 对应真人新手约六成/五成)+ 与完美档带 [35,65] 错开一档保留元进度爬升空间;② MC 重投基线(N=300/画像/关 · unique · seed0=7000):完美档 55.7%/39.7% 落 [35,65]、普通档 46.7%/34.3% 落新带——双画像双关全落带,加难紧迫性解除;③ 残留越带唯一项 = L2 完美 Boss 承伤 51.6%(微越 1.6 点,归调参批);④ 报告 production/qa/mc-reinvest-baseline-2026-09-20.md;工具 level_monte_carlo.gd 增 baseline 参数 + F5 脚注随带同步 | -| v0.17 | 2026-09-20 | **第三关内容批(灰矮人矿城——与切片代码 / registry / 03-内容规模 / 棋盘生成 / 地形变异 同批,存量行值零改动)**:调参表新增第三关图版注记——敌种生态(灰矮人 duergar 单体重甲中坚 + 钩爪恐魔 hook_horror 群行复用撕咬 + Boss 灰矮人石君王 duergar_king 专属池独占妨害技大地脉动 = 乏力 sapped 第二妨害词汇首发)、首遇位节点 0/1 固定数量不加骰、克制面重轻错开(重甲首次登台,教学梯度轻→魔→重在 L3 补完)、Boss 血量锚 75 = Σ91 × r_boss≈0.82、棋盘 13×13 / Boss 14×14 密度 0.25 维持、地形落石 3 点 + 矿尘、armor_class 恒 0(正式投值仍归在案条目全表同批);期望值带节补 L3 口径——行值 provisional-pending-growth,零成长基线红档属预期、冒烟首遇绿档按成长代理档(atk+200 / hp+100)口径,正式通关率带与首遇绿档口径随 L3-A 玩家成长批(GP + 商店房)换装,归曲线调参批统一收带 | -| v0.18 | 2026-09-20 | **GP+商店房批(用户拍板"骨架先行、数值整体后置"——与 关卡节点地图 v1.1 / 冒险结构 v0.5 / 战斗结算 v0.23 / 地图战斗资源 v0.15 / registry / 切片同批,行值零改动)**:① 新增「商店与 GP 经济杠杆」节——GP 供给 × 商品定价 = 第三族玩家侧杠杆(掉落均值±方差 / 关级掉落加值 / 关级价格加成 / 首价与步长,全部读 shop.tres provisional-pending-曲线调参批),定价锚定口径 = 正常运气与运气极好可购档数的数学期望(期望账进商店表批注);② 分层验收 defer 成文——shop=off/on 双格 MC、shop=on 带平移、换算率登记全部随曲线调参批执行(与「基线通关率越带」「L2 Boss 承伤微越带」「大奖励数值联动」同窗),执行前 shop=on 只登记不判读;③ L3 首遇绿档成长代理档口径不变;④ 调参联动表 +GP 供给↔商品定价行、调参表 +shop.tres 行、验收标准 +杠杆在案条目 | -| v0.19 | 2026-09-23 | **基线通关率带测量口径退役(用户拍板单关直入口口径退役——与单关试玩入口退役同批)**:原带(第 1 关 [35,55] / 第 2 关 [25,45],v0.16 分带批)锚定直入口单关读数——满血零上下文进关,与真实冒险的条件通关率脱节(实证:直入口 L2 普通 5% 与营地检查点 L2 条件 90% 同期并存,曾误导曲线调参)。逐关读数改冒险条件口径(balance_verifier 冒险段派生:通关数/到达数);新带值重锚归曲线调参批,重锚前只测不判;调参表「基线通关率带」行与验收标准通关率带条同步改口径退役注记。行值零改动 | -| v0.20 | 2026-09-28 | 判读口径落档+回滚阶梯收编+Boss 锚漂移登记 | -| v0.21 | 2026-09-30 | 普通档改带 L1 [35,55]/L2 [10,15]+带表与验收标准回写现行口径 | -| v0.22 | 2026-10-03 | **商店定价公式换代(迭代 11 第②批 GP 商店房重构批——需求卡片 v1.3 P1 共享池/P4 ceil/P5 甲;06 条 2026-10-02 用户裁决)**:商店与 GP 经济杠杆节公式换代 = ceil(基价 × b^(关序−1) × A^(进店已购次数)),A/b provisional 投值 1.8/1.1(原 P5 甲 game-balancer 研究拍板改后置追认——零人工令);杠杆位表换货架基价四行+价格因子 A/b 两行;分层验收 defer 节补 v0.22 注记(shop=off=legacy 对照 off_n60 逐位 / shop=on 首锚 N=60 双策略带平移归调参批/终局池读数只测不判)。行值零结构改动(shop.tres 扩列不退役) | -| v0.23 | 2026-10-05 | **挖掘风险不等式判式换代(迭代14②号卡 T3——与行动经济/战斗结算/registry 同批)**:调参联动表 +6 新增行(旗溢价三件套 δ↔p_perfect↔ap_per_round / η 读数画像联动扩员 / β 带端点↔D_ref↔max_hp↔AC 折算 / 直伤雷三行↔正向同轴行〔同轴镜像比入对账面〕/ clear_blast 区间↔p_perfect / 标中强化池权重〔形态 b 条件生效行〕);P1 后置「挖掘风险不等式与清图支配性对账重跑」行改判读回执(不等式半边收口=判式重立+β 带检算接替,残留 u=3 β=1.17 登记态;清图支配性维持);五条经济契约对账段换代 | -| v0.24 | 2026-10-07 | **混编行集难度归属注记(敌人表行集多行批·组 A——与 敌人系统 v0.15 / registry / 06 清单同批)**:敌人表行值节新增混编行集难度归属注记——同一坐标多行混编后各行值按既有口径独立生效再叠加(数量区间各行各掷、行集实例总数 ≤ 4),不引入新难度轴或乘区;首个混编行连同 Boss 多行投放归后续内容批,投时行值 provisional 归本文调参口径不变+MC 取证先报批+难度带读数义务。本批零内容投放零数值变更 | -| v0.25 | 2026-10-09 | **文档正确性审查批(用户令——状态记录与证据对齐)**:①期望值带表「通关率带」行订正——「现行带:普通档 L1 [35,55] / L2 [10,15]、完美档 [35,65]」与同节「带换代」条及验收标准直接矛盾(2026-10-03 四带甲案已将其正式作废),改四带口径;②里程碑前缀按 2026-10-09 口径删「M-3」四处(判读口径同步条两处、回滚阶梯边界③一处、加难走廊扫描行一处)只留「迭代 5」;③杠杆位表与调参表「pool_shelf 四行」改「六行」(凭证与回复随迭代15② 入架);④P1 加难杠杆扫描行「扫描未执行」订正——域内取样扫描已随迭代 5 执行(与 Boss 设计节加难走廊行对齐),全杠杆落带扫描未收口;⑤第二关图版注记奖励点「(直通空态)」过期标注删除(奖励点兑付=提升三选一);⑥两处「见「待办」」悬空指针改指 06-待办清单。 | -| v0.26 | 2026-10-09 | 文档正确性审查批(定点):三处裸「M-4」标签按 2026-10-09 里程碑口径改「Beta 阶段(未排期)」——期望值带节(M-4 排序)、P1/P2 表全局作用域行(M-4 杠杆表)、调参表资源面偏斜行(M-4 杠杆表);批次登记事实不动 | -| v0.27 | 2026-10-09 | **文档卫生批(A5 过期指向收口——用户批准「按推荐做」)**:①调参表「血量锚比率 r_boss」行锚漂移登记尾句「复算与是否收锚归迭代 5 出口判读」改过期注记——迭代 5 已关闭未执行,r_boss 复算与收锚义务挂起、随数值批重开时核销;②期望值带节「期望承伤占比带复验义务随最近的减伤调整批执行」同款改过期注记——所指批次已关闭未执行,复验义务挂起、随数值批重开时核销。两义务内容不删、仅指向挂起 | -| v0.28 | 2026-10-12 | **迭代 20 反哺落文批·投放读数登记(用户裁③——数值暂不调整只落内容,只测不判)**:期望值带节新增「迭代 20 投放读数」注记——池换代构成四级 70/25/9/0=104 张(凭证四件入稀有档 +6 provisional)+MC shop=off 止步分布 {1:90, 2:10}→{1:93, 2:7}(通关率 0% 持平,新基线 seed 71000,位移归因曝光槽高档候选加速);判读与带重锚随曲线调参批,本批零数值变更零带改动 | -| v0.29 | 2026-10-14 | **迭代 24 反哺落文批·敌人表修批读数登记(用户裁「全部按呈报落文」——只测不判,数值终值归 M4)**:期望值带节新增「迭代 24 敌人表内容修批读数」注记——N2 普通敌技能投放后 perfect L2 通关 8→13/20、L3 全通 6→10/20(方向符合预期、量级低于二档判读带,倍率 provisional 归 M4);N3 敌方 attack_type 轴+克制消费后全局平移(重甲 −1/魔法甲 +1/轻甲 0,V5 实测单发恒 ±1,taken 中位上行系构成效应);N1 (1,2) 降档后 perfect L1 通关 19→20/20。判读与带重锚随 M4 数值批 | -| **v0.30** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:「HP 账本」→ HP(生命);「钱包账本归…GP 冒险账本节」→ GP 归…GP 节;「期望账」→ 期望读数——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/systems/战斗循环/地图战斗资源.md b/design/gdd/systems/战斗循环/地图战斗资源.md index e9379bdb..68cb1d3e 100644 --- a/design/gdd/systems/战斗循环/地图战斗资源.md +++ b/design/gdd/systems/战斗循环/地图战斗资源.md @@ -116,7 +116,7 @@ | 封印且留到轮末判定 | **−类型**:标错,该格资源的负向兑付(惩罚) | **+类型**:标中,该格资源的正向兑付(奖励) | | 封印格直接挖开(封印不可逆批 2026-09-19) | 零兑付(四情况④:零惩罚零奖励——标空不判、正向作废) | **−类型**照常(四情况②:只受挖雷一层惩罚——标中不发) | -矩阵的定义归本文;把矩阵跑起来的路由(结算队列、判定基线、逐行兑付)归[战斗结算](战斗结算.md)的授予段。blast 型负向 = 警觉。矩阵只描述现行规则;被本矩阵取代的旧体系与历次结构变更(撤旗退役、伏击换装等)一律记版本历史,不在正文复述。 +矩阵的定义归本文;把矩阵跑起来的路由(结算队列、判定基线、逐行兑付)归[战斗结算](战斗结算.md)的授予段。blast 型负向 = 警觉。矩阵只描述现行规则;被本矩阵取代的旧体系与历次结构变更(撤旗退役、伏击换装等)只进 git 提交史,不在正文复述。 举证:本节为枚举与路由定义,无计算。 @@ -249,32 +249,3 @@ ## 待办 本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | -| v0.2 | 2026-09-15 | 可选类注入递减基准对齐代码:逐图减半改为按实际获取件数递减;补明注入覆盖即时身份与"发放即获取、未挖到不计数"语义;验收标准首件保证改"必注入"口径 | -| v0.3 | 2026-09-15 | 雾格残留清理:关闭「待拍板」的雾格相关定价约束三条失义条目与随之取消的奖励配置表档位过滤门限 t_fog_min | -| v0.4 | 2026-09-15 | **格面资源批(用户拍板,2026-09-15)**:① 核心抽象改为格面资源(CellResource)——安全格与危险格一视同仁、单一类型池装板期摇定,极性由「动作 × 格型」矩阵决定(开安全格/标中雷 = 正向,开危险格/标错安全格 = 负向),取代踩雷固定伏击、标中固定削弱、标错三选一哈希反噬三套固定兑付;② 五型字典(attack/defense/heal/blast/weaken,正负各一行;weaken 负向 sapped 为新行,heal 负向为不经增益状态的直伤);③ 封锁格(初始展开格)恒无资源;④ 清图奖励改述为整图、可配置可替换的清图奖励对象,图类型差异化插槽保留;⑤ **可选类道具(刀/治疗包)整体删除**——供给控制器、注入概率、按板保底、关卡域库存、道具使用窗口的数据面全部下线,RewardConfigTable 随批废止;功能道具经其他渠道加入的结构位登记 P1;⑥ 行动经济对账锚与难度曲线重推义务随批登记(见 registry 修订记录) | -| v0.5 | 2026-09-16 | 更名批(用户拍板 2026-09-16):系统更名"奖励道具经济"→"地图战斗资源"——定义双向(正负由动作×格型决定)、格面承载、只在战斗结算生效;文件同步重命名;「待拍板」系统更名条目关闭;英文代号 REWARD_ITEM_ECONOMY 暂沿用 | -| v0.6 | 2026-09-16 | **护甲等级掷点批·换装(与战斗结算 / 增益状态 / registry / 切片同批)**:defense 型正向行 defense_up(减伤 −30%,hero_defense 池)换装为 ac_up(护甲强化 +1 护甲等级/层 ×2 层,显示名暂定"护甲强化")——百分比减伤行无双轨退役;cell_type defense / 权重 16 / 档位 2 零改动(v0.6 当下类型频次合计 79;v0.7 数值压缩批后 heal_minor 权重 15→3,合计降至 67——见 v0.7 条);五型字典表与 mvp 行表同步 | -| v0.7 | 2026-09-17 | **数值压缩批·文档同步(与 doc-conventions.md §5 数值纪律·强制收口条款同批)**:整体绝对值轴 ÷3(24/7→8/2 等,见 `data/tables/enemy.tres` 注释);奖励表 heal_minor 权重 ÷4(15→3);reward.tres 三 flat 行同步(spark_aoe power 4→1 · heal_backlash power 4→1 · heal_minor power [2,6]→[1,1] 定值);clear_blast 区间 [25,55]→[8,18](中点 13,期望不漂移)。**双写失同步收口**:① 五型字典表与调参表数值列改指路存根(指向 `data/tables/reward.tres` 与 旧 registry 条目 reward_table mvp_content);② 文档表格只锁字段语义与取值域,不再列具体数;③ 与 `增益状态.md` v0.7 / 旧 registry 条目 同批落地——五步收口(`.tres` 落批 · 切片 smoke 跑通 · GDD 表格指路化 · registry mvp_content 指路化 · 待办清单现状刷新)一并兑现 | -| v0.8 | 2026-09-17 | **候选集合节补强(与代码对齐)**:在「格面资源」节后新增「候选集合:安全格与危险格的资源池」——明确安全格与危险格候选集 = cell 池正向 5 行全集(attack_up · ac_up · spark_aoe · heal_minor · weaken),权重分布相同,类型频次合计 67(v0.7 压缩批后)。清图槽 clear_blast 独立于格面资源、整图作用域。代码事实源:`core/reward_economy.gd#roll_board`(`_rollable_rows` 不分格型)+ `core/minesweeper_rules.gd#_do_dig`(cell_revealed 通道 `resource=true` 对两种格一致)。同步修正 v0.6 历史条目"类型频次合计 79 不变"——v0.7 后改 67 | -| v0.9 | 2026-09-17 | **数值纪律收口批:正文与调参表 knob 现行值改指路存根(事实源 `data/tables/*.tres` 与 registry),3 处失同步值修正**——候选集合节"合计 = 67"字面量改指路 reward.tres cell 池正向行 weight 之和(现行值读表);候选集合表"类型频次合计"列两处 67 改"见 reward.tres";代码事实源清单五型 weight 明细(attack_up 20 · ac_up 16 · spark_aoe 16 · heal_minor 3 · weaken 12)改"5 行正向行 weight 现行值读 reward.tres" | -| v0.10 | 2026-09-18 | **伤害道具批(用户指令,2026-09-18)**:① 五型→七型——增补 pierce(穿刺)/ magic(魔法)两型,各正负一行:正向 = 单目标克制直伤道具(pierce_strike 穿刺弹 / magic_bolt 魔法矢,attack_type 字段载攻击类型轴,查战斗结算克制矩阵、必中全额不掷点、目标 = 固定顺位最前存活敌);负向 = 主角直伤(pierce_snare 穿刺陷阱 / magic_recoil 魔法反噬,复用反噬通道不经增益状态);② 权重再平衡(用户指令"保爆裂粉尘不变、等比下调其余"):spark_aoe 16 不动,attack_up 20→14 · ac_up 16→11 · heal_minor 3→2 · weaken 12→8(等比基准 ×35/51≈0.686,整取微差登记已知偏差),新行各 8——类型频次合计仍 67;③ 结构冻结"五型封闭"按 owner 修订流程改"七型封闭";切片同批落地(reward.tres 四新行 + schema 七型枚举 + attack_type 校验 + 结算兑付分支 + 棋盘徽标 穿/魔 + smoke 295 全绿;断言"主角先手攻击行存在"放宽为"存在或授予段终局"——单弱敌可被挖掘期兑付单独击杀,战斗段整段跳过为合法结局) | -| v0.11 | 2026-09-18 | **战斗数值结构修复批·极性矩阵同步(2026-09-18 盘问会话用户拍板,与战斗结算 v0.14 / 增益状态 v0.9 / registry / 切片代码同批)**:① defense 型负向 off_guard 行失同步修正——原残留"hero_defense 池,承伤加深"改"AC 掷点阈值轴负向、不入池"(off_guard 换装 AC 轴随结构修复批落地,effect_pool_map 删键);② weaken 型正向行补续时定案注记(同名重复授予只刷新剩余次数——2026-09-18,叠层措辞随批退役) | -| v0.12 | 2026-09-19 | **插旗不可逆批·极性矩阵同步(用户拍板全套落地,与战斗结算 v0.18 / 排雷玩法 v0.5 / registry / 切片代码同批)**:矩阵「标旗后当轮撤旗」行删除(撤旗动作退役)、「插旗格直接挖开」行新增——安全格零兑付(四情况④零惩罚零奖励)、危险格负向照常(四情况②只受挖雷一层惩罚、标中不发);路由描述「抵消过滤」随战斗结算改「判定基线」 | -| v0.13 | 2026-09-20 | **伏击单轮上限删除批同步(与战斗结算 v0.19 / 敌人系统 v0.11 等同批)**:负向即时节 blast 负向的伏击上限护栏与溢出行协议措辞删除,改直授无上限 | -| v0.14 | 2026-09-20 | **格面资源八型批(用户拍板——与敌人系统 / 战斗结算 / 行动经济 / registry / 切片代码同批)**:① 七型→八型(+action 行动点——正向 ap_up 下轮行动点 +1、负向 ap_drain 迟滞 −1,经 action_economy 排队、下一轮兑现);② blast 负向 ambush_double 退役换装 enemy_alert 警觉(敌方全体护甲等级 +1/层,`status_effects.tres` alert 行,side-wide);③ 极性矩阵/八型字典/负向即时节/候选集合/调参表/结构冻结/验收标准同步;正向权重合计 67→74(attack 14 / defense 11 / blast 16 / heal 2 / weaken 8 / pierce 8 / magic 8 / 清障炸药 1 / action 6) | -| v0.15 | 2026-09-20 | **格面资源九型批(GP+商店房批,用户拍板——格面 GP 获取途径推翻提案"格面池零修订"推荐:定位"低概率惊喜获取"、量与战斗掉落相当;与战斗结算 v0.23 / 冒险结构 v0.5 / 关卡节点地图 v1.1 / registry / 切片代码同批)**:① 八型→九型(+gp 金币——正向 gp_gain 金币袋 weight 2、负向 gp_loss 破财 weight=0 纯字典,power 语义 = 战斗内 GP 缓冲 ±,兑付编排归战斗结算、钱包账本归冒险结构);② 负向恒即时节补 gp 两向缓冲语义(战斗完成随 gp_dropped 统一到账,无库存语义不变);③ 候选集合/调参表/结构冻结(九型封闭枚举)/验收标准同步——正向权重合计 74→76;字典 16 格→18 格 | -| v0.16 | 2026-10-03 | **偏运硬币权重投影注记(迭代 11 第①批同调实施批——需求卡片 §十连带;池结构与冻结项零触碰)**:同调被动件「偏运硬币」装配时对装板摇号(roll_board 身份批,reward_roll 封闭流)注入池内权重投影——稀有正向 kinds {heal, gp, pierce, magic} 行 weight +N(表值 magnitude,provisional),危险格与安全格仍同池同分布、池成员集合与取号次数零变化(reward_economy._biased_cell_rows,luck_bias=0 时逐位返回原行集=off 态零扰动);摇号权重合计面 76 为九型基准值、投影后合计随 N 浮动(逐行归因不受影响——抽签按调整后池权重消费同一取号) | -| v0.17 | 2026-10-07 | **类型层身份裁决(道具三层重设计·地图层开场题——案甲用户裁,与 05-不做清单 v1.4 同批)**:设计目的节补「类型层身份」段——本层=规划素材层,未开格类型经微光可见(只读类型不读危险格与安全格,呈现归 HUD框架),「读敌拍板、抢类型」为正式设计意图;05 清单第 14 条同批收窄移出禁止面;微光实施归呈现批(06「未开格类型徽章呈现时机」条在案) | -| v0.18 | 2026-10-07 | 地图层内容题①裁案A(用户裁):兑付形态差异化方向转正——九型枚举不动、同型兑付形态将拉开(pierce/magic 同构为首要对象),具体形态设计归用户、实施归后续批次;九型字典节补方向注记 | -| v0.19 | 2026-10-07 | **地图层题四裁(用户裁——四档池结构)**:候选集合节新增「四档概率结构与保底」——档=概率位+保底上限两参数(T1 攻击类/T2 增益类·GP 小袋/T3 回复可保底档/T4 惊喜类永不保底档=上限 0 统一表达);保底按型登记(heal=每板 ≥1),超上限时每板随机选定兑现集合(暂定);补签四纪律(只改类型身份/不消费权重/粒度=板/不泄露元信息);GP 数值锚(小袋≈战斗结束 GP×1/10、大宝箱≈×1);大宝箱枚举新增归实装批(微光归通用增益组,五色相不变);调参表节补四档组织注记+旧「按板保底」失义句消歧;结构冻结条补「补签=装板期校验环节非重摇」;验收标准补四档保底条;袋装摇号备选挂号 06 | -| v0.20 | 2026-10-07 | **档位名映射随批(现行事实源=[核心循环](../../01-核心循环.md)「档位与获取规则」节 v1.5 同批落文)**:四档池节补对外稀有度映射行——T1=普通/T2=优秀/T3=稀有/T4=传说(T4=头奖级,与「极致罕见抽到就是爽」定位互证);同补护栏=任何概率提升不得改变本档保底承诺(保底=承诺非概率) | -| v0.21 | 2026-10-09 | **文档正确性审查批(用户令——状态记录与证据对齐)**:①格面资源节「没挖开的格子在界面上不显示里面是什么」订正——未开格类型身份已随 2026-10-07 类型层身份裁决经微光只读可见(不显示的是危险格与安全格),与 P1 呈现深度行同步(基础档已定);②清图节图类型词表 {dungeon, underdark} 补第三值 deep_underdark(第三关内容批在役,P1 差异化行同步);③负责表与 P1「功能道具渠道、渠道设计未定」订正——功能道具 = 秘宝局外同调件(渠道已随秘宝域与同调实施批落定),本系统结构位不变;④调参表 ap_up 行「weight=6」改域表述(数值纪律:行值读表)。 | -| v0.22 | 2026-10-09 | 文档正确性审查批·独立复核(worktree docaudit-2026-10-09):依赖与输出表秘宝行「秘宝的**背包**与使用归其管」过渡形态残留——同调形态无背包(关卡域库存已退役),改「秘宝件的装配与使用归其管」并补预读接口现行零投放注(与秘宝.md v1.7 依赖表对齐) | -| v0.23 | 2026-10-12 | **玩家向显示名跟随批(锻造工坊裁决会话 8a 连带·D 项执行)**:defense 正向行 `ac_up` 显示名「护甲强化」→「盾牌加护」(`reward.tres:22` / `status_effects.tres:18` 同批改名,`smoke_all.gd:1199` 断言同步;用户裁口径=临时叠层 AC 状态不该叫"护甲",附带约定「加护」=AC 判定层、「护盾」=吸收层不得混用);本文九型字典表与设计意图句跟随改现名;另 art-bible.md §4.6.1/§4.6.2 键名列、07 体验验证清单⑫同批跟随。机制与数值零改动 | -| v0.24 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 2 处——四档概率结构与保底节「任何概率提升不得改变本档保底承诺」改「禁止改变」;验收标准加载护栏条「加载报错中止」改「加载时返回错误并中止」。机制与数值零改动 | diff --git a/design/gdd/systems/战斗循环/增益状态.md b/design/gdd/systems/战斗循环/增益状态.md index 25fc00b3..8c6b8233 100644 --- a/design/gdd/systems/战斗循环/增益状态.md +++ b/design/gdd/systems/战斗循环/增益状态.md @@ -96,7 +96,7 @@ ### 剩余次数怎么倒数:按结算次数衰减 -每个状态实例自带一个倒数计数——剩余结算次数(本文说的"衰减"就是它逐次递减、归零消失)。它不承诺"活几轮",而是数"经历过几次轮末结算":每轮结算先让状态起作用,随后计数减一,减到零状态即被移除。持续 1 的状态就是"一次性":在授予它的那轮结算里生效一次,轮末消失。MVP 时期六行内容均为一次性(削弱后改续时——见版本历史;2026-09-20 起主角增益两行也走续时、duration 表值仍为 1——重复拿等于重新获得一次当轮增益);跨轮持续的状态,寿命由表行初始值表达,给几就活几次结算。 +每个状态实例自带一个倒数计数——剩余结算次数(本文说的"衰减"就是它逐次递减、归零消失)。它不承诺"活几轮",而是数"经历过几次轮末结算":每轮结算先让状态起作用,随后计数减一,减到零状态即被移除。持续 1 的状态就是"一次性":在授予它的那轮结算里生效一次,轮末消失。MVP 时期六行内容均为一次性(削弱后改续时——见 git 提交史;2026-09-20 起主角增益两行也走续时、duration 表值仍为 1——重复拿等于重新获得一次当轮增益);跨轮持续的状态,寿命由表行初始值表达,给几就活几次结算。 ``` 一轮结算:查询生效清单 → 逐行兑付(层数 × 行值)→ 轮末衰减(全部实例剩余次数 −1)→ 归零实例移除 @@ -126,7 +126,7 @@ | 例子 | 容器输出 | 消费侧读法 | |---|---|---| -| 暴走叠两层 | +(2 × enrage 行幅度)(读表;越出单行取值域,原样输出) | 压在天花板 +100% 上:敌方输出乘区封顶 ×2(削弱已改续时——"叠两层压地板 −100% 归零"的读法随 2026-09-18 结构修复批退役,见版本历史) | +| 暴走叠两层 | +(2 × enrage 行幅度)(读表;越出单行取值域,原样输出) | 压在天花板 +100% 上:敌方输出乘区封顶 ×2(削弱已改续时——"叠两层压地板 −100% 归零"的读法随 2026-09-18 结构修复批退役) | | 主角盾牌加护再拿一份 | 层数恒 1、剩余结算次数重置(refresh——2026-09-20 主角增益续时批) | 不经任何池:掷点判定阈值 = 主角基准(读 hero 表)+ 层数(现行 +1——上限 2 层叠读取法退役,局内可达 AC 上限 11) | 容器还有一条快照纪律:实例的幅度、初始次数、量纲在授予那一刻从表行拷贝。战斗中配置表即使被重载,已授予实例不受任何影响,只影响后续授予。 @@ -149,7 +149,7 @@ | 状态 | 效果一句话 | 发给谁 | 幅度(现行值) | 时限 / 合并 | 来源类别 | |---|---|---|---|---|---| | attack_up 增伤 | 主角攻击提升 | 主角 | 见 `data/tables/status_effects.tres` attack_up 行 | 时限/上限读表 / 刷新(2026-09-20 续时批 stack→refresh,层数恒 1) | 安全格 | -| ac_up 盾牌加护 | 主角护甲等级提升(掷点折扣判定阈值——AC 轴,不入池) | 主角 | 见 `status_effects.tres` ac_up 行(2026-09-16 换装,原 defense_up 行已退役,见版本历史) | 时限/上限读表 / 刷新(2026-09-20 续时批 stack→refresh,层数恒 1) | 安全格 | +| ac_up 盾牌加护 | 主角护甲等级提升(掷点折扣判定阈值——AC 轴,不入池) | 主角 | 见 `status_effects.tres` ac_up 行(2026-09-16 换装,原 defense_up 行已退役) | 时限/上限读表 / 刷新(2026-09-20 续时批 stack→refresh,层数恒 1) | 安全格 | | alert 警觉 | 敌方护甲等级 +1/层 | 敌方 | 见 `status_effects.tres` alert 行 | 1 结算 / 叠加读表 | 踩雷 / 标空封印(blast 型负向) | | weaken 削弱 | 敌方攻击被削弱(同名重复标中只刷新剩余次数、层数恒 1) | 敌方 | 见 `status_effects.tres` weaken 行(取值域 [60,85],取负生效) | 时限读表 / 刷新(2026-09-18 续时定案) | 封印标中 | | enrage 暴走 | 敌方攻击提升 | 敌方 | 见 `status_effects.tres` enrage 行 | 时限/上限读表 / 叠加 | 标空封印反噬 / 踩雷(attack 型负向) | @@ -240,24 +240,3 @@ empower 与 fortify 是敌方技能池增益技在容器侧的数据落点(技 ## 待办 本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | -| v0.2 | 2026-09-15 | 状态表四行改六行:补暴走(enrage,敌方 +25%)与失衡(off_guard,主角承伤 +25%)两行,承载[战斗结算](战斗结算.md)标错反噬机制(2026-09-12 批已上线);来源类别四选一改五选一(新增标空旗);连带更新"MVP 四行/四类"表述与调参表 | -| v0.3 | 2026-09-15 | 并存分支补容量语义(实例数上界 = 受理授予数,有界确定、无满层语义);P2 后置登记并存行高频授予(持续伤害类)的容量复核 | -| v0.4 | 2026-09-16 | **护甲等级掷点批·换装(与战斗结算 / 难度曲线与Boss / registry / 切片同批)**:defense_up(减伤 −30% ×2 层)整行退役换装 ac_up(护甲强化 +1 护甲等级 ×2 层)——unit 新增 ac 量纲(护甲等级阈值轴,幅度域 [−20,20] 且非 0,不入任何池),消费面 = 战斗结算护甲等级掷点判定;例子表与调参表同步;"叠满减伤触池底"的免伤墙随换装结构性消失。注:sapped 行与极性路由措辞的文档同步归增益状态既有修订批(本批不扩 scope) | -| v0.5 | 2026-09-16 | **敌人技能池批(与敌人系统 / 战斗结算 / 难度曲线与Boss / registry / 切片同批)**:状态表六行 → 九行——新增 empower(蓄力:敌方 +100% 入 enemy_output 池)与 fortify(硬化:敌方 +100% 入**敌方防御池 enemy_defense** 新池——硬化技载体,主角攻击乘区消费面归战斗结算)两行敌方技能施放增益,来源类别 = 敌方技能施放(技能行 buff_ref 引用、施放时长由技能行 buff_duration 覆盖——技能冷却与增益持续两个计时器);两行 duration 2 = 1 个有效增益拍的容器口径成文;**顺手清偿 v0.4 挂起的 sapped 文档同步**(2026-09-15 格面资源批入表未登记的文档漂移——状态行表与调参表补行);P1"刷新类首批内容行"核销(empower/fortify 即首批) | -| v0.7 | 2026-09-17 | **数值压缩批·文档同步(与 doc-conventions.md §5 数值纪律·强制收口条款同批)**:ambush 幅度 +3 flat → +1 flat(量纲未变、压缩倍数三阶下发,参见 `data/tables/status_effects.tres` 注释)。**双写失同步收口**:① 状态行表与调参表数值列改指路存根(指向 `data/tables/status_effects.tres` 与 旧 registry 条目 status_effect mvp_content);② 调参表删除「现行值」列(敌人系统 v0.6 先例),仅保留 schema 模板与取值域;③ 与 `地图战斗资源.md` v0.7 / 旧 registry 条目 同批落地——五步收口一并兑现 | -| v0.8 | 2026-09-17 | **数值纪律收口批:正文与调参表 knob 现行值改指路存根(事实源 `data/tables/*.tres` 与 registry),8 处失同步值修正**——幅度例"两层 +50% 合计 +100"改"2 × 单行幅度(读表)";削弱例"−130 个百分点"改"−(2 × weaken 行幅度)(读表)";护甲例"AC10 → AC12(期望减免 21.25% → 28.75%)"改"基准 AC(读 hero 表)+ 层数"、派生读数删除;状态行表"时限/合并"列 1 次/×2/×16/×1 字面量改读表措辞;defense_up 退役条目删"−30%"数值;"两行 duration = 2"改"duration 表值(读表)";empower"×2"幅度与调参表"AC10 → 11 → 12"、"2 次 = 1 个有效增益拍"同步指路化 | -| v0.9 | 2026-09-18 | **战斗数值结构修复批(2026-09-18 盘问会话用户拍板,与战斗结算 / registry / 切片代码同批)**:三行语义改写(数值全部 provisional 归状态层重设计批)——① off_guard(失衡)换装 AC 轴:unit percent→ac、退出 hero_defense 池(effect_pool_map 删键,池清空结构保留),状态行表与调参表同步,"标错反噬三池"措辞改"三行";② fortify(硬化)符号纠正:旧正值入池实际 ×2 翻倍与"硬化=减伤"语义相反,改负值后主角攻击折半(正负号语义成文:负值 = 减伤方向);③ weaken(削弱)叠层改续时:stack→refresh、duration 表值 2——同名重复授予只刷新剩余次数、层数恒 1,×2 叠满池触底 ×0 的免伤轮结构性根治;消费侧例子表"削弱叠两层压地板"改"暴走叠两层封顶 ×2"(削弱叠层读法退役);"叠层不续命"对削弱不再适用,行动经济联动句随之失效;调参表一次性/叠层上限两行措辞同步 | -| v0.10 | 2026-09-19 | **技能池新效应词汇批(用户拍板——设计权威 proposal-status-vocabulary.md〔提案已吸收退役 git a6833b6a——现行事实源=敌人系统.md 词汇表/增益状态.md〕 v1.0,与 敌人系统 / 战斗结算 / registry / 切片代码同批)**:off_guard(失衡)新增第二来源类别 = 敌方技能施放(妨害技"蛛网束缚"的容器落点——首实装于 L2 Boss 蛛化卓尔精灵池;duration 由技能行 buff_duration=2 覆盖 = 1 个有效结算,empower/fortify 同款口径);容器语义零改动——同构实例、side 路由照常,妨害技零新状态行(乏力 sapped 留作妨害第二词汇,暂无载体) | -| v0.11 | 2026-09-20 | **格面资源八型批(用户拍板——与敌人系统 / 战斗结算 / registry / 切片代码同批)**:① 状态行表 ambush 行 → alert 警觉行(敌方护甲等级 +1,ac 量纲,side-wide);② 标空旗路由措辞纠正(2026-09-15 极性矩阵后已无三选一反噬,本批顺手收口);③ 敌人系统的伏击量纲定义/上限锚义务面随伏击退役移除 | -| v0.12 | 2026-09-20 | **主角增益只续时不叠层批(用户拍板「主角的其实也一样,都是按照叙事的方式,不要有叠层;只续时不叠层,变相削弱主角性能可接受」;与 status_effects.tres / smoke / registry / 06 清单同批)**:① attack_up(增伤)/ ac_up(护甲强化)两行 stack_policy stack→refresh——重复授予层数恒 1、剩余结算次数重置,对齐削弱 2026-09-18 续时定案;至此主角可重复获取的增益与减益合并语义统一(叠层策略仅剩敌侧 alert / enrage / off_guard / sapped 等行);② duration 表值 1 与 max_stack 2 不动(refresh 下 max_stack 不消费——weaken 先例;dur=1 下续时表现为重复拿重置当轮倒数,跨轮延续随将来 duration 拉长自然显形,数值归状态层重设计批);③ 影响面:增伤不再 +100%(hero_offense 池单层封顶 +50)、护甲强化不再 +2 AC(局内可达 AC 上限 11,AC12 折扣档采样探针随行降为 AC11)、这两行不再可达满层拒绝行;④ 同名状态合并策略表/幅度量纲例子表/调参表两行/联动纪律句/验收"叠层不减钟"条改述;06 清单「叠层不续命的读感」条目解决移除;冒烟三闸全过(ac_up 行断言与 AC 探针改形,无净增断言) | -| v0.13 | 2026-10-09 | **文档正确性审查批(用户令——状态记录与证据对齐)**:①设计目的「失衡是个例外」补乏力——主角侧减益为失衡与乏力两行(与「现行九行」节对齐);②状态行表来源类别列补全极性矩阵负向双分支——alert / enrage / off_guard / sapped 四负向行各补「标空旗 / 踩雷」另一分支(开危险格与标错旗均兑该型负向);③sapped 行与正文「暂无载体」订正——妨害第二词汇载体已落地(L3 Boss 石君王独占妨害技「大地脉动」,skills.tres earth_pulse→sapped)。注:版本号 v0.6 缺号(v0.5→v0.7)系既有断档不动,另行列呈报。 | -| v0.14 | 2026-10-12 | **玩家向显示名跟随批(锻造工坊裁决会话 8a 连带·D 项执行)**:`ac_up` 状态显示名「护甲强化」→「盾牌加护」(`status_effects.tres:18` 同批改名;用户裁口径=临时叠层 AC 状态不该叫"护甲",附带约定「加护」=AC 判定层、「护盾」=吸收层不得混用)——现行九行节、状态行表、同名状态合并策略表、幅度量纲例子表、联动纪律句五处现役描述跟随改现名;机制与数值零改动(版本历史各行的旧名留档不动) | -| v0.0 | 2026-10-11 | 术语统一补扫批(危险格更名收尾,2026-10-11 用户裁无类型划分):标中旗/踩雷两行「巢穴」表述换代——机制文档巢穴清零 | -| —— | 2026-10-09 | 缺号注记:v0.6 未登记(对应批次=未考——v0.5→v0.7 跳号,v0.7 行注引「敌人系统 v0.6 先例」,疑系 2026-09-17 文档降级为模板批未在本文件单独成行,登记见正文),卫生批仅注记不补写 | -| v0.15 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 2 处——验收标准「合成不收口」改「合成不设上下限」(同句「不封顶不保底」语义不变);P1/P2 表并存容量行「随批复核容量读法」改「顺带复核」。机制与数值零改动 | diff --git a/design/gdd/systems/战斗循环/战斗结算.md b/design/gdd/systems/战斗循环/战斗结算.md index 584e2671..50c60414 100644 --- a/design/gdd/systems/战斗循环/战斗结算.md +++ b/design/gdd/systems/战斗循环/战斗结算.md @@ -214,7 +214,7 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 × **护甲等级掷点:必中、非归零,只吃基础攻击分量**(2026-09-16 定稿落地,判定式与全部数值已拍板;判定对象措辞随敌人技能池批改述)。防守方由此多了一条数值轴——护甲等级(数据键 `armor_class`):攻击永远命中,没有 miss、没有零收益白回合;只有吃掷点的分量在掷点低于防守方护甲等级时按减伤档位打折,档位再重也不归零。判定式:攻击结算时掷单骰(骰面读表),掷点 ≥ 防守方护甲等级 + 攻击加成 → 全额;掷点 < 护甲等级按缺口(护甲等级 − 掷点)查减伤档位表打折——边界与档值读 `settlement.tres` 减伤档位表,三档皆非零档。暴击:天然最大面(读表)使该次基础攻击分量 ×暴击倍率(读表),双方同规,且天然最大面恒全额(暴击与折扣互斥;天然最大面〔nat20〕暴击是掷点层概念,与技能重击〔池技能〕严格区分——两层禁止混述)。伤害下限:**任何来源的伤害落地**至少 damage_floor(读表,全局 max(damage_floor, ·)——2026-09-20 用户拍板扩全来源:攻击双方、棋盘直伤与爆裂、地形变异、负向反噬;伤害取值域 [1, +∞),**不设上限**)——"被减伤归零 v=0"零值伤害行语义顺带退役,重档折扣的攻击行在行文本记"被压制"。掷点范围:只有基础攻击分量吃掷点——主角先手攻击的基础分量,敌方技能的基础伤害分量(= 攻击基线 × 技能伤害倍率,普通攻击倍率 1 为特例);无伤害分量的技能(增益/妨害类)不掷不折;棋盘来源一律无视护甲等级——爆裂、清障炸药、奖励即时伤害、技能必中附加分量(rider,2026-09-19)全部必中全额不掷,这是本机制的边界切口,与"奖励/惩罚必中"同构。护甲等级(数值轴,掷点打折)与护甲类型(属性轴,克制修正)严格分离:护甲类型不做护甲等级映射,克制修正点数读表、消费面不变,两概念在文档、表字段与代码键中禁止混用。数值载体:主角与敌方护甲等级行值读 hero / enemy 表的 armor_class 列(正式行值归怪物设定批,登记[待办清单](../../06-待办清单.md)),ac_up(盾牌加护)在其上加算(幅度/层数读 `status_effects.tres`)。攻击加成(`attack_bonus`)为结构位预留字段,切片恒 0,未来归元进度 / 武器附魔投值。掷点时机在结算战斗段内、每次基础攻击伤害计算时判定,消费 `armor_roll` 封闭流(逐次掷逐次取号,可逐位回放)。 -EV 参考数不入正文(派生读数,需要时按判定式与现行表值自行复算);旧 defense_up 的减伤墙已整体退役换装为 AC(无双轨,见版本历史)。微调旋钮 = 档位边界与档位值,不动护甲等级值。换装点锚定:基准 AC(读 hero 表)自带的方向性偏移与[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)已登记的加难杠杆扫描合并处理;其生存链区间模型按掷点带宽口径复核(带宽含暴击档与折扣档),"零红档"验收保留。 +EV 参考数不入正文(派生读数,需要时按判定式与现行表值自行复算);旧 defense_up 的减伤墙已整体退役换装为 AC(无双轨)。微调旋钮 = 档位边界与档位值,不动护甲等级值。换装点锚定:基准 AC(读 hero 表)自带的方向性偏移与[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)已登记的加难杠杆扫描合并处理;其生存链区间模型按掷点带宽口径复核 **结论**:先合成、再取整、全程非负;吃掷点分量必中非归零、低掷按档位折扣、天然最大面暴击恒全额(倍率读表)、落地伤害保底 ≥ damage_floor(读表);溢杀丢弃、治疗封顶、死亡即时判定。 @@ -357,40 +357,3 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值 ## 待办 本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| 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 | 雾格残留清理:关闭「待拍板」的对账输入雾相关分量失义条目(原对账输入含雾成本负担比与雾板分层等分量)。现行对账输入 = 实测可推理率分布低分位值等现行读数,条款③⑤对账协议与判定式不变 | -| v0.5 | 2026-09-15 | 攻击/护甲命名去位置化(全仓统一,跨文档 + registry + 切片代码同批):攻击分量与充能池 {基础, 伤害A, 伤害B} → {普通, 穿刺, 魔法}(数据键 {base, dmg_a, dmg_b} → {normal, pierce, magic}),敌方护甲 {无甲, 护甲A, 护甲B} → {轻甲, 魔法护甲, 重甲}(数据键 {none, a, b} → {light, ward, heavy},映射沿教学梯度 none→light / a→ward / b→heavy);战斗段把甲效表从"三档措辞"改为 3×3 显式矩阵(行 = 攻击类型、列 = 护甲类型,克制 ×150 / 中性 ×100 / 被克 ×50,普通行恒 100)并补语义列;hero_attack 行分量字段 base/dmg_a/dmg_b → normal/pierce/magic;调参表参数名与措辞同步(伤害A→穿刺、伤害B→魔法、"被对位克制"→"被克");registry 与 敌人系统/难度曲线与Boss/03-内容规模/切片 schema·tres·core·presentation·smoke 同批改键(旧名仅在本次修订与各文件批次注记中作为"原名"留存) | -| v0.6 | 2026-09-15 | **攻击类型与奖励抽象分离**(用户裁定"攻击类型的定义和格子奖励要分离开;开格\|标雷 → 奖励;奖励如何定义是可以修改的;不要将两者绑定"):修正 v0.5 遗留的焊死命名——攻击类型是**伤害的属性轴**(只决定查甲效表哪一行,定义里不含任何棋盘来源);充能是**按攻击类型分桶的附加伤害储备**,"谁能充、充哪个桶"归**奖励定义**,开格 / 标中旗 / 踩雷 / 清图一律只作奖励触发源。战斗段:矩阵表去掉来源措辞(语义列改"穿透附魔护甲…"),新增"谁往桶里放东西属奖励定义"一段与"奖励触发源 × 现行奖励内容 × 换算上限"表;授予段:挖格批与旗判定批改为"按奖励定义累加充能计数"并加一句充能归属说明;调参表:穿刺每格 / 魔法每雷两行合并为「充能奖励定义 `charge_grants`」(触发源 → {attack_type, per_unit, cap}),v0.5 落下的 pierce_per_cell / pierce_cap / magic_per_flag 同批作废;新增「待拍板」条目登记充能奖励的正式归属。切片同批:`charge_grants` 承接三字段、`_charge_counts`(只计数)与 `_charge_points()`(按奖励定义投桶)、round_facts 改 `charge_counts` / `charge_points`、冒烟加"奖励定义在位 ×2 + 改投桶行为断言" | -| v0.7 | 2026-09-15 | **格面资源批(用户拍板四点)**:① 段序七段 → 五段——道具使用窗口与道具段随可选类道具整体删除(2026-09-15 用户裁定)下线,段序常量与 registry settlement_table 同步修订;② 授予段改述为"结算队列 + 抵消过滤":开格 / 标旗 / 撤旗入队,标旗后被撤旗的动作不结算(零兑付、行动点不返);③ 兑付统一走极性矩阵(开安全格 / 标中旗 = 正向,开危险格 / 标错旗 = 负向,字典归奖励道具经济),取代踩雷固定伏击、标中固定削弱、标错三选一哈希反噬三套固定兑付;④ 明细行型 15 → 10(删道具行 / 已消耗未生效行 / 使用被拒行 / 窗口打开锚行 / 窗口跳过锚行),两层豁免集合改两类 + 三类;⑤ 战斗道具背包与库存语义下线,关卡收束只清辅助道具背包;⑥ 收益对照表 flat 类措辞去道具;验收标准改五段全序 + 抵消过滤 + 极性路由正确,删窗口类断言。行动经济 F1 对账锚(伏击共享池)与难度曲线重推义务随批登记(见 registry 修订记录),切片侧修改指导随批产出 | -| v0.8 | 2026-09-15 | **护甲等级批(用户拍板登记,只改文档与 registry、不动代码)**:战斗段新增护甲等级掷点规则——必中、非归零,掷点低于防守方护甲等级按减伤档位折扣,没有 miss、没有零收益白回合;只吃基础攻击分量(主角普通分量 / 敌方攻击拍与重击拍基线),穿刺/魔法充能分量不吃;棋盘来源(伏击附加、道具、清障炸药、奖励即时)一律无视;护甲等级(数值轴,数据键 `armor_class`)与护甲类型(克制属性轴)命名区分成文。随机口径修订:结算换算层首次引入回合内随机,可回放契约从"结算路径零随机"改为"封闭随机流可回放"(同种子同输入逐位复现);开战掷骰属初始化随机维持不变。调参表新增护甲等级掷点 / 减伤档位表 / `armor_class` 三行(全部 provisional 未定值);伤害行补掷点读数与折扣档位随行留档(行型 10 类封闭不变);验收标准新增护甲等级掷点与折扣零值归路两条、可回放条改封闭随机流口径;EV 中性引入成文(期望伤害对齐现行表值,"零红档"验收保留);待拍板新增"掷点形式与数值域""掷点的随机流归属"两条 | -| v0.9 | 2026-09-16 | 新增「呈现只读面」节(06 清单「呈现只读面契约登记缺口」闭合):把切片已实现的呈现面函数与信号登记为对外契约——呈现状态快照 `presentation_snapshot`、战斗进行中谓词 `is_battle_live`、奖励身份查询 `query_reward_identity`、结算快照信号 `settlement_snapshot`、战斗结束信号 `battle_finished` 五件成文(载荷字段、消费方、销毁前捕获语义),并登记"呈现层唯一状态读取出口、禁链式穿透"的出口纪律与诊断观测面的非契约定位;依赖与输出表 HUD 框架下游行补指路 | -| v0.10 | 2026-09-16 | **护甲等级掷点批·定稿落地(用户拍板,数字即规范——与敌人系统 / 难度曲线与Boss / registry / 切片代码同批)**:判定式定稿——掷 1d20,掷点 ≥ 防守方护甲等级 + 攻击加成(结构位 `attack_bonus`,切片恒 0)→ 全额,低掷按缺口三档折扣(1-3 → ×0.75 · 4-7 → ×0.5 · 8+ → ×0.25,无零档);nat20 暴击该基础攻击分量 ×2 且恒全额(双方同规);伤害下限全局 max(1, ·)(`damage_floor` = 1)——"被减伤归零 v=0"零值伤害行语义退役,重档折扣行文本记"被压制";百分比减伤增益 defense_up 整体退役换装 ac_up(护甲强化 +1 AC/层 ×2 层,`unit=ac` 新量纲、不入任何池,无双轨),off_guard 与池结构零改动;护甲等级与护甲类型分离成文(数值轴 / 属性轴,不做映射)。数值载体:主角 armor_class 10(暂定)、敌方首关 0(暂定,正式行值归怪物设定批,登记待办清单);掷点流归属定稿 = `armor_roll` 封闭流(逐次掷逐次取号,可逐位回放),调参表掷点/档位/下限/加成五行由未定改拍板值;EV 参考数成文(AC10 21.25% / AC11 25% / AC12 28.75%,按判定式复算),换装点锚定(基准 AC10 自带约 −21% 敌方输出期望)与加难杠杆扫描合并处理;验收标准改写掷点条目 + 新增伤害下限与留档条目;切片同批:settlement.tres 七参数入表、战斗段掷点判定/暴击/下限/行留档(roll/ac/tier/crit 字段)、armor_roll 流接入 rng_service(黄金向量 m=42 scope0 = 4806095330042243845)、零值伤害行分支删除、冒烟护栏与掷点行为断言(nat20 种子 / AC12 档位分布 / 池触底保底 / 棋盘必中)、英雄卡与敌人卡 AC 展示、ac_up 状态槽图标、nat20 金框高亮 | -| v0.11 | 2026-09-16 | **敌人技能池批(用户拍板,设计权威 proposal-skill-pool.md〔提案已吸收退役 git a6833b6a——现行事实源=敌人系统.md 技能池节〕 v1.0——与敌人系统 / 增益状态 / 难度曲线与Boss / 战斗表现 / HUD框架 / registry / 切片代码同批)**:① 随机口径两处 → 三处——技能摇号 `behavior_roll` 封闭流(回合内、开轮时点、步骤流之外,每敌按生成序派生独立子流、单敌轨迹可独立复放)入册,可回放契约扩写为"三处皆封闭流,同种子同输入逐位复现";② 战斗段成文开轮摇号与敌方技能兑现(每轮恰摇一次、轮内刷新不重摇、摇定后兑现前死亡作废)、增益技 = 施放行 + 状态授予(0 伤害不掷不折不兑伏击);③ 三乘法链成文(技能倍率乘在最前:基线 × 倍率 → AC 掷点 → 甲效 → 既有链不动);④ AC 判定对象措辞四处改述("敌方攻击拍与重击拍基线" → "敌方技能基础伤害分量",含正文/公式行/边界表/验收标准);⑤ 敌方防御池入乘区(`enemy_defense` 新池——硬化载体):主角攻击 Σ三分量后 ×(100+enemy_defense)/100,四池对称成文(hero_offense 现行走普通分量直乘的切片现状登记待办);⑥ 行型改型:蓄力行 `charge` → 施放行 `cast`(10 类封闭不变);⑦ 呈现快照敌人数组字段定稿(当前拍/行动环进度 → 摇定动作三字段 + 敌方增益 effects);验收标准新增开轮摇号条目、战斗段次序与可回放条目改写;切片同批:`_roll_round_actions` 开轮编排、技能摇号器独立服务类、单位容器实例池/冷却/执行上报、settlement.tres effect_pool_map 增 empower/fortify、施放行格式化、摇定动画位 | -| v0.12 | 2026-09-17 | **数值纪律收口批:正文与调参表 knob 现行值改指路存根(事实源 `data/tables/*.tres` 与 registry),20 余处失同步值修正**——收益对照表参考敞口 12 / 完美乘数 200 改指路 settlement.tres(equivalence_ref_damage / p_perfect);伏击加层"+2 层"改"+stacks 层(读 reward.tres ambush_double 行)";充能供给表与 charge_grants 行"每格 1 / 上限 8 / 每雷 2"改 per_unit/cap 读表;三乘法链与甲效矩阵 1.5/1.0/0.5、150/100/50 改三档读表;掷点判定 1d20 / nat20 ×2 / 缺口档 ×0.75/×0.5/×0.25 / 边界 [3,7] / 档位 [75,50,25] / damage_floor=1 / AC 10·0 / ac_up +1×2 层全部改指路 settlement.tres·status_effects.tres·hero/enemy 表;EV 参考数(AC10 21.25% 等)与"旧 defense_up 满层 −60%"删除(派生读数 / 退役值,版本历史可查);调参表与验收标准同步 | -| v0.13 | 2026-09-18 | **营地扩展前置批·主角双轴可配置(用户指令,与敌人系统 / registry / 切片代码同批)**:① hero 表新增 armor_type({light, ward, heavy},缺省 light)——主角护甲类型轴可配置可修改,消费面 = 甲效矩阵(现行敌方攻击恒 normal 档 = 数值中性的结构位,轴生效待敌方技能攻击类型批);② hero 表新增 attack_type({normal, pierce, magic},缺省 normal)——**基础攻击量与攻击类型抽象分离**:基础分量类型不再硬编码普通、改读主角表值,营地永久强化"换成魔法/穿刺攻击"= 改字段,atk 量轴与掷点口径零改动;③ 同桶充能照加语义成文(基础分量与充能同型时,充能分量保持不掷不折);正文三分量表述、甲效矩阵"普通"行注记、分量固有属性措辞三处同步 | -| v0.14 | 2026-09-18 | **战斗数值结构修复批(2026-09-18 盘问会话用户拍板,与增益状态 / registry / 切片代码同批)**:① 主角侧乘区接线——hero_offense 池入主角攻击乘区:Σ三分量后 ×(100+hero_offense)/100 ×(100+enemy_defense)/100 两池串乘,增伤/乏力覆盖面 = 普通+穿刺+魔法 合计;attack_up 普通分量直乘旁路退役(正文甲效矩阵"普通"行注记、池乘区公式行、v0.11 切片现状注记三处同步销项);② off_guard(失衡)换装 AC 轴——unit percent→ac(幅度 provisional 归状态层重设计批),effect_pool_map 删 off_guard 键,hero_defense 池清空、结构保留,消费走既有掷点判定读法零改动;③ fortify(硬化)符号纠正——旧 +100 入敌方防御池实际 ×2 翻倍与"硬化=减伤"语义相反,改负值(读表)后主角攻击折半;④ weaken(削弱)叠层改续时——同名重复授予只刷新剩余结算数、层数恒 1,×2 叠满池触底 ×0 的免伤轮结构性根治(消饱和);duration 终值、off_guard 幅度、当量锚复算全部归状态层重设计批。切片同批:battle_orchestrator 池接线与直乘删除、status_effects.tres 三行、settlement.tres 删键、冒烟护栏(削弱续时 / 乘区接线 ×1.5·×0.75 / 硬化折半方向三组新断言,旧"削弱×2 池触底"采样通道随批退役) | -| v0.15 | 2026-09-18 | **甲效矩阵用户调参批(用户逐格给值,事实源 settlement.tres 五格改值、四格不动,零代码)**:普通行 ward 100→120 / heavy 100→50;穿刺行 light 100→80 / ward 150→120 / heavy 50→80;魔法行与普通-轻甲不动——「克制/中性/被克」三档结构与「普通行恒中性」退役,改五档(克制 / 弱克制 / 中性 / 弱被克 / 被克,档值读表)。矩阵消费面成文 = 主角侧(奖励直伤道具 / 主角攻击三分量 / 充能分量),敌方攻击不查矩阵、主角 armor_type 轴仍休眠(v0.13「敌方攻击恒 normal 档故中性」的归因改述——轴休眠是结构性的非数值性的)。语义列两行同步(穿刺「破不开重甲」重压语义弱化为与轻甲同档折损)。切片同批:settlement.tres 批注、冒烟矩阵三行断言改五档读数 + 乘区接线穿刺分量 3→2(3 点 ×80% 取整)随批改形,冒烟 300 项 0 失败 + 四探针 PASS;registry(enemy/hero armor_type 两行注记)与 敌人系统 / 难度曲线与Boss 三档措辞同步 | -| v0.16 | 2026-09-18 | **甲效矩阵加法核换装批(用户拍板数值语言——小整数加法核,与 01-核心循环 数值语言条款 / registry / 切片代码同批)**:量纲 percent→整数点数,三档(克制 +1/中性 0/被克 −1)九格改值〔normal 0/+1/−1、pierce −1/+1/0、magic 0/−1/+1〕,pierce×heavy = 0 中性为用户特别拍板;五档词表与百分比乘区退役(v0.15 的五档表随批短命退役,理由=个位数刻度假粒度);分量算术改述=折算取整后加修正点数;缺项回退 100→0;奖励直伤行 payload 键 effectiveness 保留、值语义改点数;池乘区/AC 折扣档/暴击保留百分比并成文粒度口径(数值语言条款:百分比仅此三处既有粗档+开发侧工具);切片同批:settlement.tres/settlement_table.gd/damage_math/battle_orchestrator/smoke/registry/01-核心循环同步 | -| v0.17 | 2026-09-19 | **技能池新效应词汇批(用户拍板——设计权威 proposal-status-vocabulary.md〔提案已吸收退役 git a6833b6a——现行事实源=敌人系统.md 词汇表/增益状态.md〕 v1.0,与 敌人系统 / 增益状态 / registry / 切片代码同批)**:① 三乘法链尾部 +必中附加分量 rider(伤害技 rider_mult 字段:max(伤害下限, floor(攻击基线 × rider_mult))——后置加法、必中全额、不进乘区不出暴击、价位锚 0.75 = AC 折扣档最轻档;"固定值伤害"改形——固定值不随基线缩放与共享技能表前提冲突);② 增益/妨害技 = 同族施放行(0 伤害不掷不折不兑伏击),妨害状态按状态行 target_side 落主角——零新授予通道;③ 必中家族清单 +rider(掷点边界切口);④ 公式行/吃掷点行/验收标准三处同步 + 新效应词汇验收条目(rider 逐拍精确复算 + rider 键封闭 + 妨害落主角端到端);⑤ 实装面 = 仅 L2 Boss 卓尔(毒爆 +rider、新行蛛网束缚妨害→失衡),其余敌种不动;多段命中经用户拍板退役不入词汇表 | -| v0.18 | 2026-09-19 | **插旗不可逆批(用户拍板全套落地,2026-09-18 提案转正;与排雷玩法 v0.5 / 行动经济 v0.4 / 地图战斗资源 v0.12 / registry / 切片代码同批)**:① 授予段「抵消过滤」改述「判定基线」——撤旗动作退役,旗判定以轮末在场旗为基线,被挖开的旗不入基线;② 新增插旗不可逆四情况兑付表:①标中照常 / ②插旗危险格直挖只吃挖雷惩罚标中不发 / ③标空照常 / ④插旗安全格直挖零惩罚零奖励(正向作废 + reward_ineffective 归因行);③ 挖格批兑付表补四情况分支;④ 标中资格措辞改「旗无移除手段」(拔旗重插通道消失);⑤ P0 闭环第 2/4 步与验收标准同步(「抵消过滤」条改「挖旗格兑付改判」)。切片同批:minesweeper_rules 挖旗格放行 + flag_pull 出目录 + dug_under_flag 事件标记、battle_orchestrator 情况④零奖励抑制、action_economy 表 flag_pull_ap_cost 删除、冒烟 317→327 项 0 失败(四情况探针 `_smoke_flag_irreversible_quadrants`) | -| v0.19 | 2026-09-20 | **伤害下限全来源批(用户拍板「任何伤害取值域 [1,+∞),最小值一定是 1」;与 06 清单「零伤害/无威胁组合的跨字段护栏」收口 / registry / 切片代码同批,台账 100)**:① 下限语义从"任何攻击落地伤害"扩为"任何来源的伤害落地"——攻击双方(原有)+棋盘克制直伤(counter_component 增 landed_floor 参数,空桶不吃修正恒 0 边界不变)+爆裂正向+负向反噬(穿刺陷阱/魔法反噬/heal 反噬)+地形变异 flat_damage,全部收进 damage_floor 闸内;② 取值域成文 [1, +∞) **不设上限**——「零伤害/无威胁组合」条目的跨表上界护栏半边随拍板裁决为不设(上不封顶),敌种攻击基线 0 的退化态经下限自然消解(0 基线攻击落地仍 ≥1,"无威胁敌"结构性不存在);③ 现行表值下零行为变更(棋盘直伤贴底值 2−1=1 本就在闸内),本批=结构保证+调参防误配;④ 判读口径/约束表/调参表/验收四处措辞同步;冒烟 352→355 项 0 失败(+贴底/穿透/空桶三断言)。版本号注记:v0.19 在伏击上限删除批(未合并分支)中已被占用,本条与之合并时以先入库者为准顺延避让 | -| v0.20 | 2026-10-12 | **玩家向显示名跟随批(锻造工坊裁决会话 8a 连带·D 项执行)**:数值载体节 `ac_up`(护甲强化)→ `ac_up`(盾牌加护)——`reward.tres:22` / `status_effects.tres:18` 同批改名(用户裁口径=临时叠层 AC 状态不该叫"护甲";附带约定「加护」=AC 判定层、「护盾」=吸收层不得混用);机制描述与数值零改动,版本历史各行旧名留档不动 | -| v0.20 | 2026-09-20 | **伏击单轮上限删除批(用户拍板——与 敌人系统 / 地图战斗资源 / 难度曲线与Boss / registry / 切片代码同批)**:① 行型协议 10 类→9 类——溢出未生效行下线(唯一发射源 = 伏击上限截流,上限删除后零发射面);② 授予段伏击加层改直授无上限(反灾难护栏退役——一轮踩雷数由行动点预算天然封顶);③ 核验清单伏击守恒条改伏击池共享;④ 切片同批:enemy.tres 12 行字段删除、敌表校验/编排器截流/单位容器 F3 计划函数/日志视图 overflow 格式化删除、冒烟 blast 负向断言改直授累加(330 项 0 失败) | -| v0.21 | 2026-09-20 | **格面资源八型批(用户拍板——与 敌人系统 / 地图战斗资源 / 行动经济 / registry / 切片代码同批)**:① 三乘法链与敌方技能攻击公式删伏击附加项及其"后置加法不进乘区"解释短语(rider 保留);② 授予段兑付表 blast 负向换装警觉加层(enemy_alert → alert 行)+ 新增 action 型行动点修正行(queue_ap_delta 排队、下一轮开始兑现、下限 0、明细记 effect_id=ap_delta);③ EV flat 类枚举伏击→行动点;④ 呈现快照两处伏击层数拆除(警觉并入敌方增益 effects 投影);⑤ 棋盘来源必中枚举去伏击(两处);⑥ 核验清单伏击池共享改警觉共享 | -| v0.22 | 2026-09-19 | **充能退役批(版本号避让注记:原登 v0.16 与甲效矩阵加法核换装批撞号——2026-09-20 R10 版本号唯一性规则上线发现,后入库者顺延;用户拍板,与切片代码 / registry / 07 清单 / README 同批)**:主角攻击三分量模型(普通 + 穿刺/魔法充能)整体退役,回归单分量——量 = 攻击基线、类型 = 主角表 attack_type;挖格批/旗判定批的充能计数条款删除、充能供给表与 charge_grants 调参行删除、乘区公式与粒度口径改"攻击合计";退役理由 = 克制策略归冒险前配置(营地换型/未来冒险前参数面),局内不再有挖掘攒弹药的第二伤害供给;保留面 = 攻击类型属性轴与棋盘奖励触发源的抽象分离、奖励直伤道具(穿刺弹/魔法矢)的克制直伤消费不变。切片同批:battle_orchestrator 攻击段单分量化 + _charge_points/_charge_counts/round_facts 充能键删除、DamageMath.charge_component → counter_component 改名(奖励直伤唯一消费方)、settlement.tres charge_grants 键与 schema 校验删除、冒烟充能断言组退役改形(乘区接线单分量基线 100、标中正向兑付行断言、恢复点探针换种子 42)、冒烟 293 项 0 失败 | -| v0.23 | 2026-09-20 | **GP+商店房批(用户拍板——与 关卡节点地图 v1.1 / 冒险结构 v0.5 / 地图战斗资源 v0.15 / 难度曲线与Boss v0.18 / registry / 切片代码同批;版本号注记:v0.22 已被充能退役批占用,表尾顺延)**:① 呈现只读面表 battle_finished 载荷 +gp_dropped(掉落掷定 + 关级加值 + 战斗内缓冲的合计——字段增删走本文修订条款兑现);② 授予段兑付形态表新增 GP 缓冲行:gp 正/负向(金币袋 / 破财——九型批)兑付 = 战斗内 GP 缓冲 ±power,战斗完成统一上抛入钱包账本(账本归冒险结构),战斗域零钱包状态;③ 随机口径六处→七处:战斗结束掉落掷定消费 `gp_drop` 封闭流(出口随机、步骤流之外);九型字典措辞与验收标准可回放条目同步 | -| v0.24 | 2026-09-24 | **伤害管线单据化批(用户三裁决——与切片代码同批,06 台账 148)**:新增「伤害单据与伤害控制器」一节——伤害对象抽象补全:五族伤害来源收口伤害控制器单点管线、兑付配方封闭五种;三裁决落文——①结账时机双模式(现行 = 段界结账:授予段尾 / 清图批同步点 / 战斗段尾;开单即结保留为回切结构位,切换走代码不走调参)②目标结账时刻照规则解析③死亡事件由单位自行宣布(怪死其未结单据作废、主角死兑付终止);授予段兑付与战斗段两节补结账时点句;验收标准 +伤害单据管线条目。切片同批:`core/damage_controller.gd` 新建(单据构造/开单/结账/死亡事件消费/管线算术收口)、battle_orchestrator 六调用点改开单、掷点/折扣/克制/池乘/攻击行文本助手迁出(`_defender_ac`/`_clamped_pool` 留薄委托)、unit_container 增 `unit_died` 信号;冒烟 557 项 0 失败双模式全绿 + A/B 对拍四配置全确定且真实分岔(行数恒等、纯次序位移);历史基线读数自本批起以段界结账口径为准(重测归曲线调参批) | -| v0.25 | 2026-10-05 | **挖掘风险不等式判式换代(迭代14②号卡 T3/T4——与行动经济/难度曲线与Boss/registry 同批)**:①收益对照表补 gp/ap 当量口径注记(gp=flat power 代理 3/2 假设 A5 口径空白登记、ap=flat 表值 1 机会成本口径仅登记假设 A6,精确口径归商店批复核);②验收标准 +条款3 对账条(聚合健康式+β 带逐 u 检算 / 旗溢价兑付三形态覆盖·标空与挖格不乘·同池零触碰);③T4 机制载体 = settlement.tres 新键 flag_hit_premium=125(percent 域 provisional)——标中旗正向兑付 ×(1+δ),整数四舍五入取整与伤害管线 floor 分域(registry 随批登记);DamageController 零改、危险格与安全格同池冻结不动、直伤雷 6/8/8 与 p_perfect 不动 | -| v0.26 | 2026-10-06 | **地图伤害账殿后批(案C,用户裁——歧义质询触发)**:①五段总览①③行改写——授予段只兑非伤害形态,伤害形态兑付(爆裂/直伤/反噬/地形变异/战旗军规/熔火反噬等)暂存到战斗段末、按「主角先手→逐敌还手→地图账」统一落地;②战斗段节补地图账殿后与死亡守卫(主角死于怪物→暂存单整体不兑,逐单留「未生效(主角已倒下)」行);③结账时机双模式改述:现行=段界结账+地图账殿后,清图批同步读数改「将兑付」回报口径(完美第二份依据开单时点事实),历史基线读数以 2026-10-06 前授予段结账口径封存;④兑付形态表 blast 正向/heal 负向兑付时点改战斗段末;⑤P0 闭环第 5 步补地图账;⑥顺手清充能退役遗留:三分量句改单分量、三处「主角普通分量」改「基础分量」。切片同批:battle_orchestrator 暂存闸 `_defer_board_damage`/`_deferred_board` + `_submit` 案C 分流 + `_outcome_of` + 战斗段末补提交块 + 授予段四处直提改走闸;冒烟 783 项 0 失败(新增案C 段内序断言+行相位分类器换代)+ run_all 17 套全绿 + probe_gate --click 全绿;旧行为 MC 锚全数作废,重锚归数值批 | -| v0.27 | 2026-10-09 | **文档正确性审查批(用户令——状态记录与证据对齐)**:①依赖表冒险结构行「provisional,MVP 冒烟直供」过期注记订正——覆盖值通道与接口四件套已随冒险结构实现批(2026-09-21)正式接线;②P1 后置「冒险侧真实供给接线」已随同批落地——行移除;③两处「对账现状见「待办」」悬空指针改指 06-待办清单。 | -| v0.28 | 2026-10-09 | 文档正确性审查批·独立复核(worktree docaudit-2026-10-09):「秘宝背包」三处(五出口表关卡结束行/轮次生命周期节/验收关卡收束条)补机械惰性承载注——清空对象=关卡域库存 treasure_inventory(代码实证在役:level_runner.gd:520 快照计数、battle_orchestrator.gd:745 consume),投放渠道已随迭代 11 第①批全退役、现行恒空,同调装配件不经此域,拆线归实装批;行为描述与代码一致,仅补现状口径 | -| v0.0 | 2026-10-11 | 术语统一补扫批(危险格更名收尾,2026-10-11):②插旗后挖开行「惊动危险格」表述换代 | -| v0.29 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 7 处——明细流水节「宁可报错」改「宁可返回错误」;伤害控制器节「全部收口控制器单点」改「全部统一到控制器单点」;护甲等级掷点节「两层不得混述」「两概念在文档、表字段与代码键中不得混用」改「禁止」;边界表「每池独立收口 ±100 百分点」改「每池独立封顶」(与池乘区公式行同词);调参表护甲等级行「两概念不得混用」改「禁止混用」;行型封闭条「未登记行型不得落行」改「禁止落行」。机制与数值零改动 | -| **v0.30** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:图「账本扣费」→ 系统资源扣费;「非伤害账/地图伤害账」→ 非伤害单据/地图伤害单据;节标题「四类动作各归各账」→ 各归各系统资源——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/systems/战斗循环/战斗表现.md b/design/gdd/systems/战斗循环/战斗表现.md index 16ac48fd..0fac1db6 100644 --- a/design/gdd/systems/战斗循环/战斗表现.md +++ b/design/gdd/systems/战斗循环/战斗表现.md @@ -159,15 +159,3 @@ MVP 不要求本文的闭环:不做清单把战斗动画演出列为 MVP 打 3. 演出速度档位:逐行兑现的加速与跳过交互(约束:信息载体不可整体跳过)。 4. 来源格可读化的形态二选一:缩略图还是格子高亮(登记时两者并列,未裁决)。 5. 坍塌显形连锁动画与音效的挂点协同,安排在哪个批次合并设计。——已约定:对位批次 = 表现层升级批(P1,随样张锁定的动画方案后;音效侧同口径登记)。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-09-15 | 自归档线索整合为范围草案(旧体系未单独成文) | -| v0.2 | 2026-09-16 | 新增「一屏样张的验收标准」:内容清单、五项按序判定与判定回退成文,四件锁定物(角色剪影/动画方案/战斗空间/敌层插入位置)的过判口径落到已冻结口径上(06 清单「样张验收标准未成文」闭合);依赖与输出表"五区"改"四区"随 UI 收口批同步 | -| v0.3 | 2026-09-16 | **敌人技能池批(与敌人系统 / 战斗结算 / HUD框架 / registry / 切片代码同批)**:上游呈现输入清单「敌种姿态资产定稿」行改型——行为环姿态预告(一态与三态)随行为环退役,改「特殊技技能动画定稿」(普通攻击零表示、特殊技攻/防系两型动画映射,暴击掷点层无前置表示);摇定动画位呈现语义 = 开轮摇定即可见、纯类型级提醒(池与权重不公开),样张验收联动口径不变 | -| v0.4 | 2026-09-20 | **敌人卡形态裁决收口批(与 battle.md / HUD框架 / 06 清单同批,台账 99)**:敌人呈现形态拍板全站桩式(无框立绘+底座,主角同站桩、状态小图标挂血条下,卡片式退役)——「前置美术测试是硬前置」节相邻裁定句改裁决已下;样张内容清单「敌人卡两候选形态对照」项划线解除(正式样张按站桩形态单版出样,owner 修订);判定与回退节第 5 项拆出形态对照半边(已收口);敌人层插入位置裁决义务保留随样张批 | -| v0.5 | 2026-09-30 | **拍板点 3 收口批(GDD 概念覆盖审计——用户裁甲:演出权威定义节落位)**:新增「结算演出与轮间节奏」节(五要素:定义/作用对象与范围/生命周期/关联与边界/状态)——结算演出覆盖层(迭代 6)与轮间结算节奏化(迭代 8 卡⑦:段间 0.3s/段内 0.22s/轮横幅 0.6s+减动效双态)的呈现规则自 06 已收口条目与代码注释收编入现行事实源;段内常量按代码实态 0.22s 登记(06 条目旧记 0.06s 系三轮修改批前值);常量以代码为事实源。孤儿 1(演出 spec 零承载)随本节解除 | -| v0.6 | 2026-10-09 | **文档正确性审查批(用户令——状态记录与证据对齐)**:①输入清单「特殊技攻/防系两型动画」订正——2026-09-19 新效应词汇批已扩三族(攻击系/增益系/妨害系,敌人系统意图呈现节);②P1「溢出行呈现」改「奖励未生效行呈现」(溢出未生效行型已随 2026-09-20 伏击上限删除批下线,与输入清单行措辞对齐)。 | -| v0.7 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 10 处——「死亡不得瞬消」「退场有过程不得瞬消」「不得被遮挡到不可辨」「都不得越过」「不得遮挡数字」「不得在挖掘期抢焦」「不得进入生产」7 处「不得」改「禁止」;「提前收口」「提前裁决收口」2 处改「完成」(样张内容清单/判定与回退节);结算演出节「MC 对拍口径」改「MC 与基线数据逐项比对」口径。机制与数值零改动 | diff --git a/design/gdd/systems/战斗循环/敌人系统.md b/design/gdd/systems/战斗循环/敌人系统.md index 2055024a..f56c403c 100644 --- a/design/gdd/systems/战斗循环/敌人系统.md +++ b/design/gdd/systems/战斗循环/敌人系统.md @@ -282,28 +282,3 @@ Boss 专属身份 = 专属池承载:独占技能 + 权重轮廓(**技能错 ## 待办 本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | -| v0.2 | 2026-09-15 | 教学位掷骰口径自洽(随[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)同批修订):unit_count 字段说明、地精敌种定位与现行行值句中"教学位固定 1 只/固定不掷"改为 ×[1,2] 开战掷定 | -| v0.3 | 2026-09-15 | **护甲等级批(用户拍板登记,与战斗结算 / 难度曲线与Boss / registry 同批,不动代码)**:敌人表与主角表 schema 各增 armor_class(护甲等级)字段(取值域随掷点形式定稿,provisional);三敌种表补护甲等级列(行值未定);护甲等级(数值轴)与护甲类型(克制属性轴)命名区分成文;结构冻结清单"零随机"措辞按新口径修订——本系统自身语义零随机不变,掷点随机在战斗结算换算层按封闭随机流消费、可回放契约 = 同种子同输入逐位复现;待拍板新增"护甲等级行值未定"条目 | -| v0.4 | 2026-09-16 | **护甲等级掷点批·定稿落地(与战斗结算 / 难度曲线与Boss / registry / 切片代码同批)**:armor_class 域定稿 [0, 999](缺省 0 向后兼容);主角行值 10(暂定)、三敌种首关行值 0(暂定)——"行值未定"改"暂定值 + 待办",敌方正式行值归怪物设定批(第一关怪物 AC 相对较低,值待怪物设定投值,登记待办清单);敌种表护甲等级列同步落值;调参表两行改域与现行值 | -| v0.5 | 2026-09-16 | **敌人技能池批(用户拍板,设计权威 proposal-skill-pool.md〔提案已吸收退役 git a6833b6a——现行事实源=敌人系统.md 技能池节〕 v1.0;与战斗结算 / 增益状态 / 难度曲线与Boss / 战斗表现 / HUD框架 / registry / 切片代码同批)**:行为环章节整体退役——固定出招剧本、拍枚举(攻击/蓄力/重击)、环指针、同种锁步、heavy_multiplier 字段全部废除;技能池语义成文(三层对象〔技能行/池模板/实例池〕、技能行词汇表、池构成纪律、两道闸〔全技能各自冷却 + 保底〕、开轮摇号时序、死亡作废、独立子流);蓄力语义改写(纯攻击增益技、与重击无组合语义——纠偏二;施放行继承零兑付伏击);Boss 专属身份改专属池承载;意图呈现改三档可见性(普攻零表示 / 特殊技类型级预告 / 暴击掷点层);敌人表 schema pattern → pool;调参表增技能表与池 EV 锚(含闸长期速率实测登记);验收标准按摇号口径重写 | -| v0.6 | 2026-09-17 | **文档降级为模板批(用户拍板,与难度曲线与Boss / 战斗结算同批)**:数值纪律定稿——本文只锁字段、取值域与规则,全部具体行值(敌种表池权重 / 护甲等级行值 / 两道闸表值 / 伏击每层附加与上限 / 技能行倍率与冷却 / 主角三字段 / 三敌种行值与池 EV 实测读数)自本文移除、一律读配置表(切片 `data/tables/` 与 registry);调参表三表删除"现行值"列改纯 schema 模板;伏击公式与验算改符号化(a = 每层伏击表值);验收标准同步去数值。背景:切片 `.tres` 数值压缩批后文档行值已滞后,双写失同步被实证 | -| v0.7 | 2026-09-17 | **数值纪律收口批:正文与调参表 knob 现行值改指路存根(事实源 `data/tables/*.tres` 与 registry),2 处失同步值修正**——共享技能表示例"熊地精 9×2=18"改符号化"基线 A × 技能倍率 M(行值读 enemy.tres / skills.tres)";蓄力语义"施加'攻击×2'状态""×2 遇 ×2 = ×4"改"施加 empower 状态(幅度读 status_effects.tres)",两层乘法组合语义保留符号表述 | -| v0.8 | 2026-09-18 | **营地扩展前置批 + 护甲类型重配(用户指令,与战斗结算 / registry / 切片代码同批)**:① hero 表新增 armor_type / attack_type 两根可配置轴(缺省 light / normal;主角字段表同步两行)——护甲类型轴入矩阵消费面(敌方技能攻击类型轴未开前数值中性),基础攻击类型轴 = 量与类型抽象分离的营地换型落点;② 敌种护甲类型行值重配(数据面):关卡 1 全部轻甲(食人魔酋长 heavy→light、熊地精两行 ward→light),关卡 2 除 Boss 蛛化卓尔精灵 heavy→ward(魔法甲)外全部轻甲(熊地精四行 ward→light,巨蜘蛛既有 light 不动);现行克制三角读数效果 = L1 克制轴中性化、L2 仅 Boss 战非中性(魔法矢 ×150 / 穿刺弹 ×50 对 Boss) | -| v0.9 | 2026-09-18 | **甲效矩阵用户调参批同步(零代码,事实源 settlement.tres 五格改值——详见[战斗结算](战斗结算.md) v0.15)**:主角字段表 armor_type 行注记归因改述——轴休眠的理由由「敌方攻击恒 normal 档故中性」(依赖普通行恒 100 的旧数值结构)改为「矩阵消费面 = 主角侧、敌方攻击不查克制矩阵」(结构性,与数值无关),轴生效仍待敌方技能攻击类型批。历史注记:v0.8 行「魔法矢 ×150 / 穿刺弹 ×50 对 Boss」与当时矩阵(穿刺×魔法甲=150 / 魔法×魔法甲=50)正反互倒,系当批笔误,按历史不改写留档,正确读数见战斗结算 | -| v0.10 | 2026-09-19 | **技能池新效应词汇批(用户拍板——设计权威 proposal-status-vocabulary.md〔提案已吸收退役 git a6833b6a——现行事实源=敌人系统.md 词汇表/增益状态.md〕 v1.0,与 战斗结算 / 增益状态 / registry / 切片代码同批)**:① 技能类型枚举三→四(+妨害 debuff——对主角施减益的 0 伤害施放动作,字段复用 buff_ref/buff_duration,落点由状态行 target_side 路由〔增益 → 敌方侧 / 妨害 → 主角侧,施放类 side 守卫加载拒绝〕,执行与增益技同族施放行语义——不掷不折不兑付伏击);② 伤害技新字段 rider_mult(必中附加分量——"固定值伤害"改形:固定值不随基线缩放与共享技能表前提冲突,必中小倍率承载"躲不掉的稳定伤害");③ 池构成纪律 +每池妨害 ≤1;④ 意图三档特殊技预告扩三族(攻击系 ⚔ / 增益系 ✦ / 妨害系 ☠);⑤ 三词收敛两词——多段命中经用户拍板退役(无防御磨损体系,无对照机制),P1 字段位「命中段数」保留;⑥ 实装面 = 仅 L2 Boss 蛛化卓尔精灵(venom_burst + rider_mult 0.75;新行 web_snare 蛛网束缚 debuff→off_guard,首发载荷 = 失衡〔用户拍板〕,乏力 sapped 留作第二词汇),其余敌种不动 | -| v0.11 | 2026-09-20 | **伏击单轮上限删除批(用户拍板——与 战斗结算 / 地图战斗资源 / 难度曲线与Boss / registry / 切片代码同批)**:① 伏击节上限段与溢出可见行删除,一轮踩雷数由行动点预算天然封顶成文;② 字段表 advantage_per_round_cap 行删除(原 0 = 免疫伏击语义作废);③ 结构冻结联动纪律去单轮上限 × 攻击基线、数量 × 上限两条;④ 验收标准伏击授予与表校验条同步 | -| v0.12 | 2026-09-20 | **格面资源八型批(用户拍板——与战斗结算 / 地图战斗资源 / 行动经济 / registry / 切片代码同批)**:① 伏击节整体退役改写(复利集中单血条与群伤奖励双重不对称,用户裁决);② 责任表/结构冻结/验收标准的伏击词条目拆除;③ 群伤负向现况 = 警觉(敌方护甲等级 +1),定义与承载移交增益状态 | -| v0.13 | 2026-10-05 | **技能池执行批(迭代14④——D1-D8 全裁零待裁,与 skills.tres/enemy.tres/registry 同批)**:①池构成表 8 敌种全覆盖(补 L2+L3 五敌种行:巨蜘蛛/蛛化卓尔精灵/灰矮人/钩爪恐魔/石君王——池构成轮廓+定位列,权重数值不登)+护甲列改读表口径(失同步欠账清偿);②Boss 句改三代错峰口径;③意图呈现节补半血解锁弹出规格句(**Boss 半血解锁新独占伤害技**:字段 unlock_hp_pct〔1,99] 缺省无=无门槛/单向闩/双面过滤/保底不逼锁定/解锁出一次归因行+一次性技能名 toast——D8 只报名不报数值零演出;三 Boss=震地怒击 ×2.5/CD4·遏毒 ×2.0/CD3·岩崩 ×2.5/CD4 案甲 provisional 归调参);④首拍加权取消〔D2〕杂鱼纹理注销不立文 | -| v0.14 | 2026-10-06 | **事件发射点登记(内容数据驱动扩展批)**:半血解锁判定点升级为通用事件 `enemy_hp_threshold` 发射点(对所有带 unlock_hp_pct 字段的敌人逐个发射——非 Boss 专属,Boss 语义留给订阅者条件判定;本批零订阅者,登记归效果引擎事件词汇 16 发射点之一,后续内容批随批接线)。零行为变化。 -| v0.15 | 2026-10-07 | **行集混编口径批(敌人表行集多行批·组 A 先行——与 难度曲线与Boss / registry / 06 清单 / 切片代码同批)**:①「每个坐标只出一种敌种」规则改写为行集构成纪律三条(行集内 enemy_id 唯一 / 同坐标多行文件内相邻且行序 = 声明序 = 生成序 / 行集实例总数 ≤ 4〔= 各行骰后数量求和,行数不设上限,单行数量域 [1,3] 不变、UNIT_COUNT_MAX 语义改单种数〕)——同坐标多行混编合法(P1 甲 + P4 乙用户裁:Boss 行集同样放开);②开战生成节改「取出整个行集逐行实例化」口径(生成序 = 文件行序即契约)+ 区间掷定改按行各掷一次(单行行集掷定次数与既有逐位一致——零内容期随机流零变化);③「敌方效果对全体生效」前提句去同种假设(效果按存活单位逐一生效);④结构冻结「每坐标恰一敌种」换代、验收标准开战生成与表校验两条同步。知情代价登记:Boss 行集多行后开战叙述取首行 display_name、Boss 节点遭遇骰读首行数量区间(= 全行集骰域)——两读数面随批写出口报告。零内容投放(P3 丙):本批表内容不变,首个混编行归后续内容批 | -| v0.16 | 2026-10-09 | **文档正确性审查批(用户令——状态记录与证据对齐)**:①不负责表「遭遇构成与跨战斗血量保留→关卡节点地图」拆分——跨战斗血量保留归冒险结构生命账本;②敌种表引言「首发敌种共三种」与表内八行不符——补「L2/L3 内容批扩至现行八种」;③P2「精英 / Boss 遭遇编码位」行收口——不设编码位(同层多遭遇由节点编号消解,关卡节点地图 v1.0⑥ 裁决),「随定稿强制核对」前置已解除;④结构冻结节「见待办」悬空指针改指 06-待办清单。注:版本表 v0.15 居首、v0.14/v0.13 在尾的既有乱序不动,另行列呈报。 | -| v0.0 | 2026-10-11 | 术语统一补扫批(危险格更名收尾,2026-10-11):头部「惊动危险格」表述换代 | -| v0.17 | 2026-10-12 | **玩家向显示名跟随批(锻造工坊裁决会话 8a 连带·D 项执行)**:enemy.tres 字段表 armor_class 行「ac_up(护甲强化)」→「ac_up(盾牌加护)」——`reward.tres:22` / `status_effects.tres:18` 同批改名(用户裁口径=临时叠层 AC 状态不该叫"护甲";附带约定「加护」=AC 判定层、「护盾」=吸收层不得混用);字段语义与数值零改动 | -| v0.18 | 2026-10-14 | **迭代 24 反哺落文批(实现报告 §六,用户裁「全部按呈报落文」)**:①调参表敌人表字段集增 `attack_type` 行(枚举 {普通, 穿刺, 魔法}、缺省普通、消费面=敌方技兑付查克制矩阵)+ 主角表 armor_type 行休眠注记换代(矩阵消费面双向在役,现役敌方全 normal 档,三甲型读数差 重甲 −1/魔法甲 +1/轻甲 0);②Boss 专属身份节「三代错峰」口径扩为**技能错峰两轨**(Boss 独占技轨 + 普通敌错峰轨,N2 毒吐/盾击投放实录);③敌种表巨蜘蛛族+毒吐、灰矮人族+盾击两行池构成列随 N2 变动;④敌种表增 hobgoblin 缺口登记注(有数据行 (1,3)、无立绘、不在敌种表——已知缺口归敌种内容批)。机制零改动(N2/N3 实现事实登记) | -| v0.19 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 8 处——设计目的「敌人若干」改「敌人一至四个(数量随遭遇行集骰定,见开战生成节)」;「报错止动」2 处(行集构成纪律/验收标准表校验)改「返回错误并止动」;「不得混用」2 处与「保底不得逼出未解锁技」改「禁止」;P1 单体寻址「随批裁决」改「顺带裁决」;P2 编码位「已收口」改「已完成」。机制与数值零改动 | diff --git a/design/gdd/systems/排雷循环/地形变异.md b/design/gdd/systems/排雷循环/地形变异.md index b0d665e4..4587e54b 100644 --- a/design/gdd/systems/排雷循环/地形变异.md +++ b/design/gdd/systems/排雷循环/地形变异.md @@ -155,18 +155,3 @@ region 型变异是「格子级」的:布置段往候选格域写格子快照 - 布置域:变异格全在初始展开区外(伤害型 closed_only 由设置顺序结构保障)且不吃危险格;每图至多一种类型;连通片 ≤ pack_max。 - 配套义务闭环(**已作废,2026-10-03 终裁**):原「定稿批须含反制兑现条目否则验收不通过」随反制道具配套义务一并作废;counter_items 恒空为合法态。 - 全局作用域型(2026-10-04 首发批):替换制生效——Boss 图恰一行整图变异+零格子级变异标记;普通图 region 路径逐位不变(同种子布置/摇号快照与批前基线逐项比对);off 态零扰动(effect_value=0 资源摇号与无偏斜逐位相同,白名单三行任何状态逐位不动);L1 Boss 零全局变异;Boss 图全局池空回落 region;全局取用零取号(确定性,不消费布置随机流);资源面偏斜正向池合计恒 77。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | -| v0.2 | 2026-09-15 | 雾格残留清理:删除上一版设计遗留的「待拍板」失义条目十条;变异框架本体不变 | -| v0.3 | 2026-09-20 | 首批类型定稿批:四类型两轴×两关(荆棘丛/藤蔓缠绕/岩浆/烬覆)落地;机制枚举化(effect/trigger/placement 三枚举 + 跨字段互锁);布置段改排战斗初始化第 4 步(2026-09-19 用户拍板棋盘设置顺序);biome 系命名退役对齐 board_type 词表;反制兑现与全局作用域改排 Alpha;岩浆/冰冻旧占位名退役(冰冻退役、岩浆落位第二关) | -| v0.4 | 2026-09-20 | **第三关内容批(与切片代码 / registry / 03-内容规模 / 棋盘生成 / 难度曲线与Boss 同批)**:类型清单加第三关两行——落石(伤害型 flat_damage 3)+ 矿尘(信息型 hide_number 数字遮蔽),凑齐两轴 × 三关(unlock_level 3、地形 deep_underdark);布量走既有公式(第三关自动 9%,零新配置);反制道具兑现维持改排 Alpha(counter_items 字段位同批预留);调参表直伤量行随批补落石 3。行值全 provisional 归 难度曲线与Boss | -| v0.5 | 2026-09-21 | **变异布置基数修正批(用户试玩反馈「小图变异格非常多」+基数假设实测证实后拍板)**:数量公式百分比基数由总格数改候选池格数(安全格 − 初始展开区,即实际可挖格)——实测初始展开均值占全板 56–67%,旧基数使有效密度膨胀 4–6 倍(L1 10×10 板配置 5% 实际 30.1%,极端板可挖格 100% 覆盖);percent 语义 = 占可挖格比例,关卡递增由 per_level_bonus 绝对格数承载;表值零变更(provisional 归 难度曲线与Boss 调参批重标,正式重基线同批) | -| v0.6 | 2026-10-03 | **反制道具配套义务作废批(2026-10-03 用户终裁——层级错配失败设计)**:①负责表义务行+§反制道具配套义务节改作废注记并附终裁理由(同调位反制件=冒险周期常驻资源对抗关卡周期局部威胁;变异=受控纯税现状维持);②counter_items 字段保留恒空=合法态,承载形态待迭代 12 双层 BD 调研重定(变异应对若做只挂局内);③依赖表秘宝行/P1P2 后置表 Alpha 行/验收「配套义务闭环」条同步作废;④批位移迭代 12(调研前置后重新立项)。连带 秘宝.md v0.8 同批;范围裁定注记见 roadmap 迭代 11+ 行(原 06 条目已收口移除) | -| v0.7 | 2026-10-04 | **全局作用域变异首发批(迭代 14 ③号卡——需求卡片裁决 P1-P8+Q1-Q4 全按推荐案)**:①类型清单加行贫矿脉(scope=global 首发型=案A 资源面·微贫向偏斜,effect_value=30 provisional);②新增 §全局作用域型 语义节(整图承载/替换制/兜底回落/恒定制/资源面偏斜口径/三层预告);③「每图一型」整图推广=普通图 region、Boss/精英图 global;④候选池门控扩第三维=节点身份(global 行仅 boss/elite 入池,普通节点静默跳过;elite 前向词位零表行);⑤布置段节补全局决议前置于资源格设置(数据依赖——偏斜旋钮先于摇号定型,零取号);⑥P1/P2 表 Alpha 行换代已落地(撤 2026-09-19「留 Alpha 再设计」挂起——P1 裁决);⑦调参表+验收标准+影响面随批;⑧呈现三层承载归 HUD框架.md 同批(横幅+常驻角标+手册行);⑨遗留知情代价:迭代 12 四件地形应对件在 Boss 图无的放矢(替换制无地形格——Q3 知情代价,registry/调参日志登记) | -| v0.8 | 2026-10-04 | **文案常规化修订(用户人闸反馈)**:§全局作用域型 玩家体验句俚语表述(「这层奶薄、枪很肥」)改常规描述——玩家可见三层文案同步(横幅/角标/手册,代码同批);机制与数值零改动 | -| v0.9 | 2026-10-09 | 文档正确性审查批(定点):P1/P2 表全局作用域行「(M-4)」裸标签按 2026-10-09 里程碑口径改「(Beta 阶段,未排期)」;行其余部分不动(批次登记事实保留) | -| v1.0 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 3 处——候选池门控节「不报错、不警告」改「不返回错误、不警告」;零特判原则节「变异不得改写扫雷规则本体」改「变异禁止改写」;验收标准全局作用域型条「快照对拍批前基线」改「快照与批前基线逐项比对」。机制与数值零改动 | diff --git a/design/gdd/systems/排雷循环/排雷玩法.md b/design/gdd/systems/排雷循环/排雷玩法.md index bec4278d..d4500571 100644 --- a/design/gdd/systems/排雷循环/排雷玩法.md +++ b/design/gdd/systems/排雷循环/排雷玩法.md @@ -240,16 +240,3 @@ ## 待办 本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | -| v0.2 | 2026-09-15 | 雾格残留清理:关闭「待拍板」三条雾失义登记(连锁开雾格与雾内旗恒不中、开格事件的变异标记透传、四格态中的两个雾态)——现行连锁与旗判定口径已按"全部安全格"写在正文,开格事件仍携带随格只读的变异标记(通用变异框架保留),格态呈现收窄为已开 / 未开两态。规则本体不变 | -| v0.3 | 2026-09-15 | **格面资源批(用户拍板四点)**:① 初始展开格定名**封锁格**(已开、计入清图进度、恒无格面资源、不再有任何加成),铁律表"无奖励"改"无格面资源";② 挖开格事件"奖励资格"字段改"格面资源资格"——安全格与危险格恒有(危险格不再恒无),封锁格恒无;③ 旗生命周期补结算队列口径:标旗 / 撤旗都是动作,轮末经战斗结算抵消过滤(标旗后被撤旗不兑付、行动点不返;开格不可撤);④ 标错惩罚条目与 P1 后置删除——惩罚已定为该安全格格面资源的负向兑付(极性矩阵,归奖励道具经济 / 战斗结算),本系统只报"标空"事实;⑤ 清图呈现口径注记:剩余安全格计数即"剩余未探索安全区域"。玩家说法"失控反噬"随三选一反噬下线改"控制失败" | -| v0.4 | 2026-09-17 | 数值纪律收口批:正文与调参表 knob 现行值改指路存根(事实源 data/tables/*.tres 与 registry),0 处失同步修正——动作价面值改「按标准动作价计费(价目见 action_economy.tres)」口径,连锁免费、移动免费等结构语义保留 | -| v0.5 | 2026-09-19 | **插旗不可逆批(用户拍板全套落地,2026-09-18 提案转正)**:① 挖旗格放行——挖的合法对象去掉"无旗"前提,旗格直挖被受理、旗随挖掘消失、该旗轮末不再上报判定;② 拔旗动作退役——意图目录删 flag_pull,动作表与拒绝原因清单删对应项(flag_absent);③ 旗生命周期改写:旗无任何移除手段、纠错路径 = 挖开(兑付改判四情况归战斗结算 v0.18);④ 验收标准"挖有旗格被拒"改"挖旗格放行"。冒烟 327 项 0 失败(四情况探针 `_smoke_flag_irreversible_quadrants` 在案) | -| v0.0 | 2026-10-11 | **术语统一批(全库危险格/整图/专长凭证更名,2026-10-11 用户裁)**:首节定义句换代——对内名「雷格」与界面名「惩罚格」统一为「危险格」(怪物巢穴保留为危险格类型名、简称巢穴);机制零改动 | -| v0.6 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 1 处——初始展开铁律表「无格面资源」行「下游不得对它们做任何兑付」改「禁止下游对它们做任何兑付」。机制与数值零改动 | -| **v0.7** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:「账本归行动经济」→ 系统资源归行动经济;「请账本扣费」→ 请行动经济扣费——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/systems/排雷循环/棋盘生成.md b/design/gdd/systems/排雷循环/棋盘生成.md index d9e3c002..819dd426 100644 --- a/design/gdd/systems/排雷循环/棋盘生成.md +++ b/design/gdd/systems/排雷循环/棋盘生成.md @@ -232,14 +232,3 @@ - R₀≤cap 闸(2026-10-05 初始展开收窄批):每张出图自然 R₀ ≤ 该行 r0_max_cap(合法板),或带非法产物标记(accept_worst 诚实降级);闸触发次数入指标集 r0_cap_rejected。 - 剃雷域参数化(同批):剃雷域=出生中心切比雪夫 ≤1+shave_ring_radius 的方域,出图 ring_removed ≤ 域内候选危险格数 (3+2r)²−9;同种子布雷序列与收窄前逐位一致(零 RNG 消费变化)。 - 表实一致:配置表字段定义与 `data/schemas/board_gen_table.gd` 一致。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | -| v0.2 | 2026-09-15 | 雾格残留清理:删除「待拍板」五项旧版失义条目(雾参数两字段与雾域跨字段校验、双判据与 inferability_core、雾相关生成约束、雾致清图预算增量两指标、黄金图向量的 core 整数对);验收标准「表实一致」条去掉指向该节的清理登记。参数表、五阶段管线与三分支出图等现行规则不变 | -| v0.3 | 2026-09-17 | 数值纪律收口批:正文与调参表 knob 现行值改指路存根(事实源 data/tables/*.tres 与 registry),3 处失同步修正(雷密度、可推理率及格线、生成尝试上限——文档面旧 provisional 值与 board_gen.tres 现值不一致,改指路);成本闸 16384 改标注「结构护栏常数,登记于 registry board_gen_table 条目」,其余引用处指路;调参表「现行值」列整列指路化 | -| v0.4 | 2026-09-20 | **第三关内容批(与切片代码 / registry / 03-内容规模 / 难度曲线与Boss / 地形变异 同批,参数行值零改动)**:图类型词表 v1.0 → v1.1,增补第三值 deep_underdark(灰矮人矿道方向);正文词表句与调参表 board_type 行随批同步(L3 = deep_underdark)。[地图战斗资源](../战斗循环/地图战斗资源.md)的图类型差异化插槽句不随批动——clear_deep_underdark 启用仍为预留 | -| v0.5 | 2026-10-05 | **初始展开收窄批(迭代14①号卡 T7——甲乙混合,用户裁 D1-D5+S1 方案A)**:①反退化规则表「先布后删」行换代(剃雷域=出生 3×3∪外扩 r 环参数化,全域 flood 剃雷退役)+新增「R₀≤cap 重掷闸」行;②调参表 +2 行(shave_ring_radius [0,2] 现行 1 / r0_max_cap 护栏 [9,半板] 现行 45/43/51/59——10×10 经 S1 停机呈报用户裁上调 30→45);③验收标准 +2 条(R₀≤cap 闸 / 剃雷域参数化+ring_removed 量级);④改后结构读数入 registry initial_expansion_narrowing 条(R₀ 均值 39.7/37.9/42.8/46.6,收窄自 68.6/83.2;雷密度 19.2-21.6% <25% 相变线;inf 全行达标);玩法侧零改动(排雷玩法「初始展开恰等」验收原样为真);裸数字截断路否决退役(D3)不立文 | -| v0.6 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 4 处——设计目的「终局不得不猜的一格」改「终局只能猜的一格」(清「不得」词面误中,语义不变);反退化规则表「开局白给板拒绝」行「不得覆盖」改「禁止覆盖」;生成重试节「质量分不得掩盖功能残废」改「质量分禁止掩盖」;P1/P2 表划线条目「已收口」改「已完成」。机制与数值零改动 | diff --git a/design/gdd/systems/排雷循环/行动经济.md b/design/gdd/systems/排雷循环/行动经济.md index efc88fb2..79836f41 100644 --- a/design/gdd/systems/排雷循环/行动经济.md +++ b/design/gdd/systems/排雷循环/行动经济.md @@ -258,23 +258,3 @@ ## 待办 本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-09-14 | 自归档 GDD 压缩改写 | -| v0.2 | 2026-09-16 | AP 压速批文档面值同步(用户拍板 8→6,削标旗 rush 单轮兑付吞吐为无伤通关根因的主阀门):ap_per_round 与 rap_refresh_cost 现行值 8→6,随动保持"满预算停手 = 恰好一刷"耦合;数据表与 registry 已同批改,本批补文档面正文两处与调参表两行 | -| v0.3 | 2026-09-17 | 数值纪律收口批:正文与调参表 knob 现行值改指路存根(事实源 data/tables/*.tres 与 registry),0 处失同步修正——价目改「统一价目 / 标准价(见 action_economy.tres)」口径,每轮点数与刷新门槛改表值指路;调参表「现行值」列整列指路化;注记 refresh_cap_per_round 与表字段 refresh_max_per_round 命名不一致(字段名对齐待批)。顺带:P0 闭环「扣 1 点」改「按价扣费」;终扫补两处漏网——巢穴约束例句「每轮花 2 点重插」改「重复计费重插」、P0 闭环「每轮至多 2 次」改刷新上限读表 | -| v0.4 | 2026-09-19 | 插旗不可逆批(用户拍板全套落地):拔旗动作退役——设计目的/统一价目/价目表/布尔入口清单/P0 闭环/调参表六处删"拔旗",flag_pull_ap_cost 字段随 schema 与 data 表同批删除;插旗行补"旗 = 一次性承诺、纠错 = 直接挖开"口径 | -| v0.12 | 2026-10-12 | **迭代 22 反哺落文批(实现报告 §三⑦,用户裁「落文」)**:「停手与储备行动点」节补转存率参数化注记——`finish_round_stop(transfer_pct)` 缺省 100=1:1 逐位同旧;秘宝「储备罐」注入 125=1.25:1(整数除法向下取整,每 4 点剩余 AP 多转 1)。机制结构零改动(参数面已随迭代 22 T3 在役) | -| v0.5 | 2026-09-20 | **格面资源八型批同步(用户拍板——与敌人系统 / 战斗结算 / 地图战斗资源 / registry / 切片代码同批)**:① F1 条款 3 改写——原"敌方伏击暴露不等式"随伏击机制退役作废,惩罚当量对账模型归难度曲线与Boss 调参批重立;② 新增「下轮行动点修正」节——action 型格面资源经 queue_ap_delta 排队、下一轮开始兑现(基线 ap_per_round + 净值、下限 0、兑现后清零),跨轮携带量口径改写(RAP 唯一显式携带资源 + 一次性修正队列);③ 节拍不变式(满停一轮 = 恰好一刷)补扰动注记 | -| v0.6 | 2026-10-01 | **失同步清偿 + 跨冒险行动点加成轴节(迭代 10 奖励重构批——与冒险结构 / registry 同批)**:①失同步项清偿——ap_per_round 真实配置 = **8**(action_economy.tres,Package B 2026-09-22 批 6→8 回调,表内批注在案);v0.2 批 8→6 系最后一次文档面记录,此后配置面单独回调未回写本文,本批补记(rap_refresh_cost 与 ap_per_round 的「满预算停手 = 恰好一刷」节拍耦合以现行 8/8 维持);②新增「跨冒险行动点加成轴」节——统一冒险加算区扩第四轴(行动点),经战斗开始入参覆盖值通道、只在每场战斗开轮首轮兑现一次;价值锚 = 冒险表 bonus_ap_flat / bonus_cap_ap(迭代 10 三选一 AP 件,全冒险 2 次上限),调参表补跨表行 | -| v0.7 | 2026-10-03 | **两 AP 件兑现通道注记(迭代 11 第①批同调实施批——需求卡片 §十连带)**:同调目录两 AP 件兑现通道落位——①工兵晨令(被动·限时)=战斗开始首轮 queue_ap_delta 入队 + 轮始段续队(前 effective_rounds 轮每轮 +1,表值化 P4 甲),复用「跨冒险行动点加成轴」同族排队通道;②掘进蓄能(主动·充能)=grant_ap 当轮加量(同挖掘期 ap_grant 通道),受理闸=战斗域安全开格积点(charge_n 格/点);账本零新机制(queue_ap_delta/grant_ap 两既有原语),充能扣减经共享账本(attune_charges)同引用直改 | -| v0.8 | 2026-10-05 | **挖掘风险不等式判式换代(迭代14②号卡 T3——与战斗结算/难度曲线与Boss/registry 同批)**:F1 条款3 重立——三层口径并行立(条款2 标中旗锚不动/条款3 聚合健康式「(1−ρ̂)E_dig−ρ̂V_mine≥0」只留下限 0/旗边际引理+条件二旗溢价「E[标中兑付]≥(1+δ)·E_dig」δ=0.25 provisional 形态 a 兑付溢价);条件二落文按登记已知破·T4 机制闭合;β 比值带 [1.2,2.5] 判读入文(u=3 登记态微破下限);η 降格读数入文(分母=全部插旗数);推导节变量表换代(E_dig/V_mine/ρ̂/β/δ 五锚);旧界形式与「惩罚当量对账模型归调参批重立」挂账句全部清偿 | -| v0.9 | 2026-10-07 | **生命周期轴裁决随批(框架现行事实源=核心循环「生命周期轴」节同批落文)**:「每轮预算与价目」节首补 AP 两账定义段——AP 上限=冒险级角色属性(开局基值+冒险中秘宝/属性提升抬高,兑现细则归「跨冒险行动点加成轴」节)、当前 AP=回合级池(每轮灌满、归零收轮,本账本只管后者);既有规则面零改动 | -| v0.10 | 2026-10-09 | 文档正确性审查批:巢穴约束表「资格认危险格实例」行重复短语清除(「堵死重复计费重插刷收益的农场」一句两写删一) | -| v0.11 | 2026-10-09 | 文档正确性审查批·独立复核(worktree docaudit-2026-10-09):依赖与输出表排雷玩法行「挖/插/**拔**的调用方」退役动作残留清除——拔旗已随插旗不可逆批(2026-09-19)退役,v0.4 批六处删「拔旗」时本处漏网 | -| v0.0 | 2026-10-11 | 术语统一补扫批(2026-10-11):「巢穴」机制表述两处换代危险格 | -| v0.13 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 3 处——推导节条件二「登记态(落文时点)」改「登记态(写入文档时点)」、「按…纪律落文」改「按…纪律写入文档」;调参表注「任一动作成本不得超过每轮预算」改「禁止超过」。机制与数值零改动 | -| **v0.14** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:定义句「这本账」→ 行动点这一笔系统资源;表行「行动点账本」→「行动点(当前池)」;「AP 分两本账」→ 行动点分两笔;扣费入口/事务/休眠表述统一——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/systems/表现与支撑/HUD框架.md b/design/gdd/systems/表现与支撑/HUD框架.md index e7150e30..2d2cd3af 100644 --- a/design/gdd/systems/表现与支撑/HUD框架.md +++ b/design/gdd/systems/表现与支撑/HUD框架.md @@ -168,7 +168,7 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻 配套拍板(同日):魔法提灯=灯甲形态(光照圈外扩 +2 格,flat 整数档)随迷雾立项;**类型微光不随视野扩大**(类型先读仍只贴身 8 格,微光锚=可挖域);提灯载体归 aux_items 新行(登记原文——2026-10-07 用户令改道为独立卡,2026-10-08 裁案A=秘宝·同调位新行落位,见下方实施状态注记;**2026-10-09 用户裁退役**——新目录 15 件未收提灯,fog_lantern 数据行与卡④接线拆除归退役删行批〔实装批〕,功能由新目录普通档「阔视野带」承接,06 登记条在册),呈现面挂「资产升档重产批」(挂账不动)。 -**实施状态(2026-10-03 迭代 11 第④批已入库)**:迷雾遮蔽+菱形灯光区跟随+暗淡记忆态上线,探针断言顺带扩(ui_input_probe case⑮)。四裁决逐条对账——①案甲视野迷雾立项(纯呈现层):迷雾开关分层验证可用(呈现态布尔,off 态=无迷雾基线),同板同动作序列与 MC 逐项比对逐位一致;②暗淡记忆态:区外已开格灰显+数字可读,明度按 [art-bible](../../../art/art-bible.md) §6.5 写入文档值(记忆板 #3A3A3A/记忆墨 #C4C4C4,provisional);③灯光半径=微光环 8 格同圈:LIGHT_RADIUS=8 参数化(曼哈顿菱形,常量);④提灯 +2、微光不扩:FOG_LANTERN_BONUS=+2(落码常量实名——本条旧记 LIGHT_RADIUS_LANTERN_BONUS 系文档侧拟名,随卡④入库对齐),类型微光仍贴身 8 邻格零改动。**〔2026-10-05 迭代14⑤接线注记〕公共接线面已就位**——`board_view.set_fog_lantern(enabled)`(true=半径 8+2、false=复原 0;写入即 refresh 重算雾态),半径算式消费 `_fog_lantern` 迷雾批已在位;ui_input_probe case⑮ 增接线断言(开=dist 9 格转可见+lantern=2/关=复原)。**〔2026-10-08 迭代 19 卡④入库注记〕载体到位+接线闭环=功能可达**——载体=秘宝·同调位新行 `fog_lantern`「魔法提灯」(treasure_items.tres 表尾追加,desc「灯光区半径+2」,slot_cost 1、营地秘宝匣同调装配获渠,行字段=用户「按推荐」全收);生产路径=runner set_attunement→enc.attunement→begin_battle 注入 orchestrator 装配集→公共只读出口 `attune_has`→组合根呈现桥 `main._sync_fog_lantern` 每战首轮装配链**显式重算含否**(🔴 复原语义=禁战斗结束隐式复原——卸装/未装配写 0,断点续玩/跨关天然正确);未装配=false 写 0=缺省零扰动基线逐位不变。顺带测试:case⑮ 载体级段(装配→lantern=2+dist R+1 转可见+卸装复原)+smoke 行字段/同调目录投影(九件→十件)/装配贯通断言+存档回归 Part 6+单测 fog_lantern_wiring(run_all 17→18 套)。原「提灯载体归 aux_items 新行随 Alpha 信息件重定批」登记去向就此注销(改道留痕=原提灯载体道具批卡(已按「吸收即死」退役,git 历史可考))。验收线(本篇「验收标准」视野迷雾行)逐条转正式验收:区内完整渲染/区外已开格灰显可读/区外未开格不可见/灯光区随移动跟随/两态结算逐位一致;实机目检人闸(迷雾观感/记忆态可读性/移动跟随流畅度)随出口闸。黑暗区域渲染规格承载 = art-bible §6.5(v3.5)。 +**实施状态(2026-10-03 迭代 11 第④批已入库)**:迷雾遮蔽+菱形灯光区跟随+暗淡记忆态上线,探针断言顺带扩(ui_input_probe case⑮)。四裁决逐条对账——①案甲视野迷雾立项(纯呈现层):迷雾开关分层验证可用(呈现态布尔,off 态=无迷雾基线),同板同动作序列与 MC 逐项比对逐位一致;②暗淡记忆态:区外已开格灰显+数字可读,明度按 [art-bible](../../../art/art-bible.md) §6.5 写入文档值(记忆板 #3A3A3A/记忆墨 #C4C4C4,provisional);③灯光半径=微光环 8 格同圈:LIGHT_RADIUS=8 参数化(曼哈顿菱形,常量);④提灯 +2、微光不扩:FOG_LANTERN_BONUS=+2(落码常量实名——本条旧记 LIGHT_RADIUS_LANTERN_BONUS 系文档侧拟名,随卡④入库对齐),类型微光仍贴身 8 邻格零改动。**〔2026-10-05 迭代14⑤接线注记〕公共接线面已就位**——`board_view.set_fog_lantern(enabled)`(true=半径 8+2、false=复原 0;写入即 refresh 重算雾态),半径算式消费 `_fog_lantern` 迷雾批已在位;ui_input_probe case⑮ 增接线断言(开=dist 9 格转可见+lantern=2/关=复原)。**〔2026-10-08 迭代 19 卡④入库注记〕载体到位+接线闭环=功能可达**——载体=秘宝·同调位新行 `fog_lantern`「魔法提灯」(treasure_items.tres 表尾追加,desc「灯光区半径+2」,slot_cost 1、营地秘宝匣同调装配获渠,行字段=用户「按推荐」全收);生产路径=runner set_attunement→enc.attunement→begin_battle 注入 orchestrator 装配集→公共只读出口 `attune_has`→组合根呈现桥 `main._sync_fog_lantern` 每战首轮装配链**显式重算含否**(🔴 复原语义=禁战斗结束隐式复原——卸装/未装配写 0,断点续玩/跨关天然正确);未装配=false 写 0=缺省零扰动基线逐位不变。顺带测试:case⑮ 载体级段(装配→lantern=2+dist R+1 转可见+卸装复原)+smoke 行字段/同调目录投影(九件→十件)/装配贯通断言+存档回归 Part 6+单测 fog_lantern_wiring(run_all 17→18 套)。原「提灯载体归 aux_items 新行随 Alpha 信息件重定批」登记去向就此注销(改道留痕=需求卡片-提灯载体道具批-2026-10-07 §一)。验收线(本篇「验收标准」视野迷雾行)逐条转正式验收:区内完整渲染/区外已开格灰显可读/区外未开格不可见/灯光区随移动跟随/两态结算逐位一致;实机目检人闸(迷雾观感/记忆态可读性/移动跟随流畅度)随出口闸。黑暗区域渲染规格承载 = art-bible §6.5(v3.5)。 ### 营地覆盖层:四柜台并排(程序占位——视觉终稿归营地视觉批) @@ -288,29 +288,3 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻 ## 待办 本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.17 | 2026-10-13 | **迭代 21 反哺⑤落文(用户裁「按呈报落文」)**:核心规则新增「营地覆盖层:四柜台并排(程序占位)」小节——树淬炼/锻造工坊/秘宝匣/图鉴四柜台结构实态登记(迭代 21 落地),视觉与布局终稿归 HUD 营地视觉批(未立项);本篇原无营地柜台登记面,随批补缺。机制零改动 | -| v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | -| v0.2 | 2026-09-15 | 雾格残留清理:关闭「待拍板」五条雾失义登记(雾图例条目、雾首遇一次性提示、四格态中的两个雾态、雾纹带与已开雾格 tint 残留、雾区全开合并域完成信号)。现行口径 = 格态两态一眼可辨(已开 / 未开)、图例面板只载现行格态与变异语义;通用变异框架的纹带形状通道保留为未来变异类型的呈现位 | -| v0.4 | 2026-09-16 | **敌人技能池批(与敌人系统 / 战斗结算 / registry / 切片代码同批)**:敌人卡义务改写——行为环环点拆除(proposal §2.4),意图徽标语义改「本拍摇定结果的动画占位」(普通攻击零表示 / 特殊技类型级提示两型:攻击系 ⚔ / 增益系 ✦),护甲行(护甲类型 + AC)保留常驻;敌方增益显示(蓄力/硬化)入敌卡状态行 + 状态槽图标键增 empower/fortify 两键(状态表九行全映射);呈现快照敌人字段消费面同步(摇定动作三字段 + effects,池与权重不投影);上游敌人系统行与验收条目同步 | -| v0.3 | 2026-09-16 | 格面资源批 UI 欠账收口(可选类道具与其轮末窗口已随 2026-09-15 代码批删除):战斗屏布局五区 → 四区(删 E 道具栏行,D 区加宽至约 1036px 并同步装板校验变量);删道具窗口弹层条款(原位点亮、非模态不入栈)、P0 闭环窗口锚点条目、「道具窗口原位点亮 / 至多选一件 / 禁用件带原因 / 空库存不弹窗」验收行;依赖与输出表的窗口选择提交、道具使用窗口呈现、库存查询义务删除或改述为现行口径(奖励身份投影经 `query_identity` 只读回调,零直读);关卡末清库反馈义务改载秘宝背包,随秘宝 P0 落地。秘宝预留义务行与「待拍板」登记保持 | -| v0.5 | 2026-09-17 | 数值纪律收口批:调参表标注文档自持口径(无表承载常量的唯一事实源声明) | -| v0.6 | 2026-09-20 | **敌人卡形态裁决收口批(与 battle.md / 战斗表现 / 06 清单同批,台账 99)**:全站桩形态拍板——B 区主角与敌人均为无框立绘+底座、状态小图标挂血条正下方,英雄卡/敌人卡退役;B 区行、敌人呈现义务行(载体由卡改立绘,意图占位/共享层数各立绘同值/死亡灰化退场等义务面平移)、下游战斗表现交付行、就地更新示例措辞四处同步;攻击值等规划数据仍归 C 区数据框(C 区不动)。呈现快照数据面零改动(消费字段不变,只换呈现载体) | -| v0.7 | 2026-09-20 | **表现层三批落地 + 义务清单补行(代码同日三批:样式收敛 / 站桩改造 / 结算演出链)**:呈现义务来源清单补「关卡节点地图」行(节点链进度常显 + 选路覆盖层只读呈现——此前漏登记);新增结算演出覆盖层(跨区弹道/光带载体,兑现演出因果可视);减动效承诺落地(UiKit.motion 单点包装全部呈现层 tween 时长,开启时长减半、可挖域呼吸停格;切片期入口 = TunePanel 开关,正式设置层归设置批)。代码侧站桩载体(StandeeView)与卡片退役随 v0.6 裁决执行 | -| v0.8 | 2026-09-23 | **停点前移批(冒险入口流程倒置修复,用户 2026-09-23 拍板;上位裁决 = 棋盘/战斗舞台 Node2D 迁移批(已执行完毕,git 历史可查),代码实装另批并行)**:① 战斗屏布局四区 → 三区——删 A 区关卡进度条行(LevelStripView 退役删除,节点链进度呈现移出战斗屏、只留关卡画面);C/D 区纵向 520 → 548;装板校验变量与实算同步(棋盘区高 504、可用高度 488);② 呈现义务来源清单「关卡节点地图」行改承载口径——节点链进度由关卡画面选路覆盖层节点态承载(暗金已过 / 金当前 / 候选下一跳通道亮金 / Boss 旗朱描边),不另设进度条组件;③ 「四区」措辞全线改「三区」(负责表、节题、结构冻结、验收、下游战斗表现交付行),双舞台常驻语义不动。**批内代拍板三项已追认(2026-09-24 用户确认)**:① B/C/D 字母保持不重编(字母是跨文档/代码注释的承载标识);② A 区 28px 纵向空间划归 C/D 底行(520 → 548;1920 档换算仍归表现层升级批);③ 关卡画面进度呈现由选路覆盖层节点态直接承载、不另设进度条组件 | -| v0.9 | 2026-09-23 | 渲染技术注记(棋盘 Node2D 迁移批 Phase A,代码实装同批):棋盘本体 Node2D 化——BoardView 内部由 GridContainer+逐格控件改为 Control 壳 + SubViewport + Node2D 世界,类名/信号/公共方法契约不变、探针零改造;三区布局与性能预算(同屏 draw calls < 200)不变;程序化占位视觉等价平移,素材终稿按 art-bible §8.2 格面 32×32 暂定档槽位 1:1 换入 | -| v0.10 | 2026-09-26 | 渲染技术注记(战斗舞台 Node2D 迁移批 Phase B,代码实装同批):B 区战斗舞台 Node2D 化——BattleStageView 内部由 PanelContainer+Control 站桩改为 Control 壳 + SubViewportContainer + SubViewport + Node2D 世界(StageWorld/StandeeBody),类名/setter 面/公共方法契约不变、调用点零改造;状态图标行与悬停 tooltip 保留 Control 载体挂壳层(伴随件);C6 字体注入挂点复用(set_world_font);三区布局与性能预算(同屏 draw calls < 200)不变;占位表现等价平移(时序常量逐字对照——等价证明=git 提交 7f24b64,文件已按生命周期条款退役) | -| v0.11 | 2026-09-27 | 关卡画面 UX spec 建档([level-map](../../ux/level-map.md),关卡画面 UX 批——用户拍板立项):义务清单「关卡节点地图」行挂屏级 spec 指针;屏级权威行与不负责表改按屏分治口径(战斗屏 = battle.md / 关卡画面 = level-map.md)。文档面零机制改动 | -| v0.12 | 2026-09-30 | **未开格类型微光概念收口批(用户裁决落位)**:新增「未开格类型微光」节=全项目唯一权威定义(五要素——作用对象=英雄周围 8 格内的未开格〔与可挖域同圈〕/信息内容=只类型不泄危险格与安全格/生命周期=入圈亮出圈灭开格灭/关联边界/实装状态=契约定稿〔样张 v2〕游戏内待实施批);核心规则章六节改七节;呈现义务来源清单「地图战斗资源」行补微光指路;验收标准补微光呈现线。背景:该概念此前只活在 06 登记与 art-bible 复述,「常显/全部未开格」无范围表述酿成理解事故(2026-09-30 用户纠正口径),本批落位权威文档、他文只许指路 | -| v0.13 | 2026-10-04 | **地形变异三层预告义务批(全局作用域变异首发批——迭代 14 ③号卡,代码同批)**:呈现义务来源清单补「地形变异」行(开战横幅一行〔减动效=静态驻留,轮横幅先例同款双态〕+ C 区常驻角标〔空态整节隐藏=奇物段先例,摆位 provisional〕+ 帮助手册一行〔零交互教学〕);验收标准补三层预告线(普通图恒空态零打扰);数据面走呈现快照 board_variants 投影(核心→呈现唯一读取面)。语义现行事实源=地形变异.md §全局作用域型,本文只锁呈现承载 | -| v0.14 | 2026-10-03 | **视野迷雾实施批入库注记(迭代 11 第④批)**:迷雾节补「实施状态」注记(四裁决逐条对账:纯呈现两态逐位一致/暗淡记忆态灰显可读/LIGHT_RADIUS=8 参数化〔提灯 +2 插值位预留未接〕/类型微光仍贴身 8 邻格);实装状态行「待实施批」改「已实装」;验收标准迷雾行去「待实施批落地后验收」括注转正式验收。机制定义零改动(定义一句话/作用范围/生命周期/关联边界/配套拍板全段原样);黑暗区域渲染规格落 art-bible §6.5(v3.5) | -| v0.13 | 2026-09-30 | **视野迷雾概念落位批(用户拍板立项)**:新增「视野迷雾」节=权威定义(菱形灯光区+黑暗边界;区外已开格=暗淡记忆态灰显可读、区外未开格=全黑;灯光半径起步=微光环 8 格同圈;纯呈现层,与已退役雾格无关);验收标准补迷雾线;配套拍板随节登记(魔法提灯灯甲外扩 +2 格、类型微光不随视野扩、初始展开收窄后置 Alpha 差异化批)。实施待主线编卡 | -| v0.15 | 2026-10-09 | **文档正确性审查批·独立复核(worktree docaudit-2026-10-09)**:①视野迷雾配套拍板段补魔法提灯退役注(2026-10-09 用户裁——fog_lantern 数据行与卡④接线拆除归退役删行批,功能由新目录「阔视野带」承接,06 登记条在册);②呈现义务清单秘宝行「库存条常读」改「装配件与充能常读」(同调形态无库存条——与秘宝.md v1.7 依赖表对齐)+补在役旧框架注;③P0 闭环第 6 步与验收「终局」条的关卡末清库载体补机械惰性承载注(关卡域库存恒空、拆线归实装批——与战斗结算 v0.28 同款口径);④P1 相邻域屏行「节点奖励屏随秘宝内容重定批」过期批次名清偿(node-reward.md v2.5 令牌池已在役) | -| v0.16 | 2026-10-10 | 柜台名扫改(2026-10-10 天赋树设计会话裁「道具工坊」改名「秘宝匣」):迭代 19 卡④入库注记内「营地道具工坊同调装配获渠」改「营地秘宝匣同调装配获渠」。机制与接线零改动 | -| v0.18 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 5 处——核心规则导语「收口」→「完成」;装板校验「报错中止」→「显示错误并中止」;迷雾实施状态注记「随批」→「顺带」2 处(探针断言扩、测试引导语);营地覆盖层注记「随批补缺」→「顺带补缺」。机制、数值、结构零改动 | -| v0.19 | 2026-10-17 | **未开格类型微光实装入库注记(迭代 30 卡①,合并 `7ffd1dc0`)**:①微光节实装状态行「游戏内待实施批」→「已实装」(2026-09-30 核证的「无独立实现」状态注销),在役实现(ui_kit TG_GLOW_* 五组、格面微光子件 + 距离场 shader)随行登记;②口径史注记后补「两带分工」注记(卡顶色带 = 条目级静态色带 / 格面微光 = 棋盘格内动态微光,禁互为引用;统一面归 06 两带统一条);③验收标准类型微光行去「待实施批落地后验收」括注转正式验收。微光定义(一句话/作用范围/生命周期/关联边界)零改动;明度档 provisional 值登记归 art-bible 版本历史 | -| v0.20 | 2026-10-20 | 死链清偿:视野迷雾实施状态注记内「改道留痕=需求卡片-提灯载体道具批」指路句改指提交史——该卡早已按 doc-conventions §11「吸收即死」退役,原句为死链;同批十一张失归属卡片退役。机制、数值、结构零改动 | diff --git a/design/gdd/systems/表现与支撑/存档序列化.md b/design/gdd/systems/表现与支撑/存档序列化.md index 6b35e4ba..de4ff699 100644 --- a/design/gdd/systems/表现与支撑/存档序列化.md +++ b/design/gdd/systems/表现与支撑/存档序列化.md @@ -181,20 +181,3 @@ MVP 不要求本系统的闭环([不做清单](../../05-不做清单.md)把单 ## 待办 本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-09-15 | 自归档线索整合为范围草案(旧体系未单独成文) | -| v1.0 | 2026-09-21 | **存档序列化批(SaveManager 落地)**:格式裁决 JSON 单档 `user://save.json`;数据模型逐域成文(元进度四件 + 最近冒险摘要 cap 10);读写时机(启动读盘/冒险收束写盘/营地即时写/测试入口不写)+ tmp+rename 原子写;版本策略(高版本拒读禁写/低版本链式迁移/缺域补齐);损坏兜底(.corrupt.bak 备份 + 默认新档);待设计问题清单六条全部裁决成文(1/2/3/5/6 入核心规则,4 = 单档 MVP 多档留 P2)。自范围草案升定稿 | -| v1.1 | 2026-09-23 | 单关测试直入口(L2/L3)退役(用户拍板——唯一试玩入口 = 完整冒险):不写档条款改口径为「调试两层与 headless 单关测试路径(LevelRunner.start_level,仅 QA 工具)」;写盘面零改动(正式冒险收束唯一写档点不变) | -| v1.2 | 2026-09-29 | **断点域出生(迭代 8 卡①,schema v1→v2)**:`breakpoint` 域登记(停点粒度续玩快照,内容 owner=冒险结构);反面清单收窄到 meta 域+断点域豁免条款;写盘时机+停点快照/三结局清除;生产迁移链 v1→v2 补空;P1 快照预挂号兑现(rng `restore_adventure` 回填面);域界验收口径随改 | -| v1.3 | 2026-10-01 | **版本兼容口径批(迭代 10 追加批 g 裁——用户拍板:版本兼容对齐 semantic version 标准)**:①版本策略成文口径——本域版本号语义 = **向后兼容的次序版本**:升版只允许「旧档在新代码可读可玩可续玩」(缺新键=合法空态、内容零丢失、断点可续),禁「新档在旧代码可读」承诺(向前兼容不做);②v2→v3 迁移体=空迁移(断点附随件扩列〔bonus_taken/bonus_pending/bonus_result/bonus_aux_carry/keystone_drops + bonus.ap 轴〕与摘要 additive 键 keystone_drops 均由读取方 .get 兜底——兼容性由冒烟 v1→v3 与 v2→v3 断点续玩断言承载,2026-10-01 增);③中断节点兼容义务:每升版必须在冒烟断言「旧版断点→新版续玩受理」(现行三档 v1/v2/v3 齐) | -| v1.4 | 2026-10-09 | **文档正确性审查批·独立复核(worktree docaudit-2026-10-09——版本滞后四代换代,全部代码实证 save_manager.gd SAVE_FORMAT_VERSION=6)**:①数据模型 JSON 与域清单表换代 v2→v6——补 v4 同调三域(boss_kill_count/attunement_equipped/attune_refresh_level,迭代 11①)、v5 树域(tree_nodes/fork_sides,迭代 12)、v6 生涯两终身计数域(adventure_total/adventure_cleared,迭代 18 卡④)逐域 owner 行;②版本与迁移节换代——当前=6、迁移链五件(v1→v2…v5→v6,含 v4→v5 三体系迁移指路天赋树);③调参表版本常量 2→6;④缺键补齐纪律句补记(读取方默认补零/空集合,收束自增唯一入账=apply_adventure_summary)。注:v3/v4/v5/v6 四次升版当时均未回写本文,本批一次性清偿 | -| v1.5 | 2026-10-12 | **锻造工坊完备性检查批随迁(用户令:新加内容现在补、不等实装批)**:①**预登记锻造路线域**(计划 v7):域清单表 + 版本沿革补 `forge_routes`(三武器等级+三甲等级+当前选中标记、无特效域、旧档破坏性废弃归锻造工坊实装批;域名以实装批定名为准);②**清偿 forge_levels 残留**——JSON 示例、域清单表删该域(代码侧已随迭代 21 T5 删除:`save_manager.gd:12-14/:399-401` 白名单收窄);迁移链 v4→v5 的「三体系迁移」体改述为已删除(`save_manager.gd:96-98`、`meta_progression.gd:294-295`);③**补登两漏域**(代码实证 `save_manager.gd:119-139`):`tree_struct`(树结构版本标记,迭代 21 T5,缺失=换代前结构加载废弃重置,owner 天赋树)、`first_adventure_done`(首冒险完成标记,新档默认 false、旧档缺省按已完成兜底,`meta_progression.gd:100` 置位,owner 元进度);④消费面纪律句「读写锻造等级」→「读写树等级」(访问器已随行族退役删除)。版本号常量仍 =6(v7 未落地) | -| v1.6 | 2026-10-12 | **迭代 22 反哺落文批(实现报告 §三⑥,用户裁「落文」)**:域清单表补 `vision_used` 行(真视使用终身计数,迭代 22 新增,v6 域后扩列补零不升版本——迭代 21 先例;断点随件 `vision_counter_used` 同批新增、旧随件键 `bonus_aux_carry` 随替换子交互拆除退役);缺键补齐纪律句补 v6 扩列注;零迁移口径复核=SAVE_FORMAT_VERSION 仍 6(`save_manager.gd:49`),无迁移分支新增 | -| v1.7 | 2026-10-12 | **锻造工坊实装批随迁(迭代 23 T5——v7 落地;承 v1.6 的 vision_used 登记)**:①域清单表 `forge_routes` 计划行→实际落地态({levels 六路线等级 + unlocked 直购解锁清单 + weapon/armor 当前选中标记},域内键名以实装批定名);②版本与迁移节——当前 =7、迁移链补 v6→v7(空迁移=缺键补齐模式,解锁态派生不落档三通道);③旧档口径订正——「破坏性废弃」→「缺键补齐 = 初始持有态」(开发阶段禁迁移禁折算纪律不变,契约 4);④域界注记——forge_routes 属 meta 永久进度域(契约 2 反面清单不涉) | -| v1.8 | 2026-10-13 | **Y 断点随存缺陷修批(06「天赋树实装批登记欠账三条」③——用户令单独开修)**:断点域扩列随件键 `attune_refresh_y`(Y 冒险周期池消耗余量——续玩优先读断点、不自参数面整额重注入=堵「用完退菜单再续玩满血复活」可利用漏洞;旧断点缺键回退参数面整额注入=旧档行为零变化);**v7 域后扩列不升版**(v1.6 vision_used 先例同款,SAVE_FORMAT_VERSION 仍 7、无迁移分支新增);断点字段口径 owner=冒险结构(v0.21 随批登记) | -| v1.9 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 5 处——断点域豁免注记「随批」→「顺带」2 处;「白名单收口」→「白名单收窄」2 处(forge_levels 退役行与迁移链 v4→v5 述——「收口」系白名单收紧义,按本篇既有词「收窄」就近改写);钥石判据「不得破坏」→「禁止破坏」。域、版本、迁移语义零改动 | -| **v1.10** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:「局内资源」→ 局内系统资源(不入档/单局清零两处);「生命账本、GP」→ 生命、GP——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/systems/表现与支撑/教学引导.md b/design/gdd/systems/表现与支撑/教学引导.md index bff1fc85..88b81957 100644 --- a/design/gdd/systems/表现与支撑/教学引导.md +++ b/design/gdd/systems/表现与支撑/教学引导.md @@ -108,14 +108,3 @@ HUD 框架定稿时已为教学留好两个承载位,本系统的内容将来 3. 图例面板的条目全集与分组方式。 4. 教学文案的定稿权归属,以及与本地化流程的分工。 5. 是否提供"再教一次"的入口(图例面板是否兼任手册)。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-09-14 | 自归档线索整合为范围草案(旧体系未单独成文) | -| v0.2 | 2026-09-15 | 雾格残留清理:删除「待拍板」的雾类教学条目失义登记(图例条目"迷雾 = 无雷盲区"与雾格首遇三要点提示),"待设计问题清单"第 3 条去掉雾条目删除的限定。教学条目清单与承载设施不变 | -| v0.3 | 2026-09-17 | 数值纪律收口批:呈现常量复述改指路 HUD 框架调参表 | -| v0.4 | 2026-10-04 | **地形变异手册行批(全局作用域变异首发批——迭代 14 ③号卡,代码同批)**:已登记的教学条目表补「Boss 图整图变异说明行」——三层预告中的手册层承载(帮助文案块一行,零交互教学),横幅/角标两层归 HUD 框架;语义现行事实源=地形变异.md §全局作用域型 | -| v0.5 | 2026-10-09 | **文档正确性审查批·独立复核(worktree docaudit-2026-10-09)**:①内容原则与 P1 后置「里程碑定位 Alpha」改排 **Beta 阶段**(2026-10-04 用户拍板教学引导整体改排,06 节头注记在案——本文漏同步);②教学条目「库存关卡末清空」行补机械惰性承载注(清空对象=关卡域库存恒空、拆线归实装批,本条目随拆线失效——与战斗结算 v0.28 同款口径) | -| **v0.6** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:「教血账与恢复」→ 教生命与恢复——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | \ No newline at end of file diff --git a/design/gdd/systems/表现与支撑/数据配置.md b/design/gdd/systems/表现与支撑/数据配置.md index 205b47e6..d9586baa 100644 --- a/design/gdd/systems/表现与支撑/数据配置.md +++ b/design/gdd/systems/表现与支撑/数据配置.md @@ -210,15 +210,3 @@ ## 待办 本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-09-15 | 自归档 GDD 压缩改写 | -| v0.2 | 2026-09-15 | 雾格残留清理:关闭「待拍板」的棋盘生成参数表雾字段清理登记(fog_region_count / fog_target_ratio 两字段、雾占比绝对上限与雾域跨字段校验)——字段与校验随雾格移除同批删除,registry `board_gen_table` 条目同步修订。表清单与校验纪律不变 | -| v0.3 | 2026-09-17 | 代币→钥石统一拍板随批措辞清偿:表清单冒险表行「代币记账」改「钥石入账」;registry adventure_table 同批改键 token_per_level→keystone_per_level。表清单与校验纪律不变 | -| v0.4 | 2026-09-18 | **进度坐标解析口径修订(用户拍板,场景三讨论产物)**:① 取整方向「就近向下」→「**向上取整**」——无精确行取不低于请求坐标的最近行,理由 = 保证偏难(宁高估难度让工具读数保守,不静默降难掩盖断档);② 越域致命补齐——低于合法域(关卡序号 <1、节点深度 <0)走运行期致命:Fatal 级诊断 + 进程退出码 1,与装载期致命纪律并轨;**同日追加拍板**:高于最大已有行不致命,封顶取最大已有行并留警告(用户裁定「可取范围内向上取整,超过了最大值就用最大值」);③ registry enemy_table 条目「进度键 floor」随批改 ceil;切片 config_db._resolve_progress 同批落地(ceil 选择器 + _fatal 通道 + 配置致命探针〔smoke/config_fatal_probe.gd,迭代 19 退役删除,断言并入 `tests/unit/data_config/config_db_fatal_oob_test.gd`〕 + 冒烟 ceil 断言) | -| v0.5 | 2026-09-27 | **统一随机流批(2026-09-27 用户两轮复裁终选「统一用一个流」并拍「全面执行」)**:§「封闭随机流」整节改「统一随机流」口径——唯一主种子+单盐派生+唯一全局取数计数器,七流并一;取号参数降格为**用途标签**(只进事件日志不参与派生,七流名保留为封闭词表);新增**全事件日志**(冒险会话制 user://logs/rng_log_<主种子>.jsonl,逐次取数落 scope/标签/派生种子——号位全序化后单点定位的承载面);快照契约=主种子+全局计数器;扩签通道替代增流通道;表清单/依赖表/P0/验收行随批。代码实证:rng_service.gd 重写+七消费点迁移+armor_roll_stream 字段降格标签+behavior_roll 子流派生向量退役;新黄金向量 8 常量重登记(scope 0-3 与旧 board_gen 向量逐位连续)| -| v0.6 | 2026-10-09 | **文档正确性审查批·独立复核(worktree docaudit-2026-10-09——四处表清单失同步,全部代码实证)**:①变异表行「现行六行」→七行(variation.tres 实测 7 行=region 6+global 贫矿脉,2026-10-04 首发批漏登);②奖励配置表 `RewardConfigTable` 行删除(表已随可选类删除下线——reward_config.tres 与类名全仓零命中);③秘宝表 `AuxItemTable`→`TreasureItemTable`(treasure_items.tres,词族对齐批换代漏登);④MetaTable「四行族」→现行五行族(+attune_refresh_upgrade,同调批扩列漏登);⑤主角表行补 armor_class 字段 | -| v0.7 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 5 处——fail-fast 节与 P0 第 3 步「报错」→「显示错误」3 处(均动词义);MetaTable 行与越域验收行「随批」→「顺带」2 处。另 v0.4 行死链清偿 1 处:smoke/config_fatal_probe.gd 探针迭代 19 退役删除、断言并入 `tests/unit/data_config/config_db_fatal_oob_test.gd`(去向经 roadmap 迭代 19 卡①「探针收编」与本文验收行双证)。表、校验、随机语义零改动 | diff --git a/design/gdd/systems/表现与支撑/设置与本地化.md b/design/gdd/systems/表现与支撑/设置与本地化.md index 32c30190..407dcbc5 100644 --- a/design/gdd/systems/表现与支撑/设置与本地化.md +++ b/design/gdd/systems/表现与支撑/设置与本地化.md @@ -122,10 +122,3 @@ MVP 不要求本系统的闭环:[不做清单](../../05-不做清单.md)把设 4. 文案生产流程:文本键(每条文案在工程里的唯一编号,机器据此找到译文)怎么管理、谁负责校对、翻译在流程的哪一步介入。 5. 设置界面的入口与形态:从哪里打开、什么时刻可以打开——与 HUD 框架协作定。 6. 键位映射表是否转化为改键设置项。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-09-15 | 自归档线索整合为范围草案(旧体系未单独成文) | -| v0.2 | 2026-09-29 | **最小设置面落地(迭代 8 卡④)**:P1 两项(音量入口+减动效开关)随迭代 8 兑现——三件面(音量 master bus 实时生效+即改即存/全屏/减动效转正)+退出游戏入口+调试入口 DS_DEBUG 门控;独立存储落地=`user://settings.cfg`(ConfigFile 三节 audio/display/motion,与存档两分按 2026-09-19 拍板);减动效开关自测试调整板退役(设置面唯一入口,battle.md 呈现承诺不变) | diff --git a/design/gdd/systems/表现与支撑/音频.md b/design/gdd/systems/表现与支撑/音频.md index aaef039d..f1df7227 100644 --- a/design/gdd/systems/表现与支撑/音频.md +++ b/design/gdd/systems/表现与支撑/音频.md @@ -151,12 +151,3 @@ 3. 混音与总线方案:音乐与音效怎么分层、相对音量关系怎么定。 4. 与减动效选项的关系:呈现侧已承诺减动效——音频侧是否配对应的减噪、动态范围收缩,未拍板。 5. 四个基础反馈位之外的基础音效(封印、移动、清图奖励等)尚未见挂点登记——是否补登记、归谁提出,未定。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.1 | 2026-09-15 | 自归档线索整合为范围草案(旧体系未单独成文) | -| v0.2 | 2026-09-16 | 新增「临时音效的覆盖清单」:必覆盖五挂点、选配两候选、明确不覆盖两挂点与切片期验收口径成文(06 清单「临时音效的覆盖清单」闭合),P0 最小闭环改指本节;明细流水行型数 15→10、例举去"道具"行,随战斗结算格面资源批行协议同步(追记 2026-09-30:现行 9 类——2026-09-20 伏击上限删除批下线溢出未生效行) | -| v0.0 | 2026-10-11 | 术语统一补扫批(2026-10-11):音频触发名「惊动巢穴」三处换代「惊动危险格」 | -| v0.3 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 1 处——「切片期验收口径」句内「不得先于事件」→「禁止先于事件」。覆盖清单与验收判据零改动 | diff --git a/design/gdd/systems/跨局循环/元进度.md b/design/gdd/systems/跨局循环/元进度.md index d853fb6f..5a12d47b 100644 --- a/design/gdd/systems/跨局循环/元进度.md +++ b/design/gdd/systems/跨局循环/元进度.md @@ -157,35 +157,3 @@ MVP 不要求本系统的闭环([不做清单](../../05-不做清单.md)整体 ## 待办 本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v1.18 | 2026-10-13 | **迭代 23 反哺落文批(实现报告 §五,用户裁「在这里进行更新」)**:①「跨局注入」节补终态句——入战 AC 三层第一层「甲型基础 AC」= 选中甲路线行 base_ac(forge.tres 轻 10/重 12/魔法护甲 9 provisional),effective_ac 三层已随迭代 23 在役;②属性锻造段落代——「实装待办在册 06、待用户发令」过期态换代为已随迭代 23 实装入库(新表 forge.tres),并登记营地钥石入口族三写口(forge_buy_level/forge_buy_unlock/forge_select_*——buy_forge 退役后的新族,契约 9 写口唯一)。机制与数值零改动 | -| v1.19 | 2026-10-13 | **暂停层改名批随迁(用户令:暂停层/暂停角标→状态面板/状态角标,全标识符+文案换代、行为零变化)**:「解锁界面:双入口框架」节正文名称换代+改名括注(版本历史行内旧名按历史记载保留);pause_overlay.gd→status_panel.gd(StatusPanel)。机制零改动 | -| v1.20 | 2026-10-13 | **迭代 21 反哺②落文(用户裁「按呈报落文」)**:「营地统一」段落地终态换代——属性锻造柜台已随迭代 21 退役、属性升级唯一入口=树脊柱淬炼节点、四柜台并排已实装(原「落地前维持现役」过渡态终结)。机制零改动 | -| v0.1 | 2026-09-15 | 自归档线索整合为范围草案(旧体系未单独成文) | -| v0.2 | 2026-09-17 | 代币→钥石统一拍板随批措辞清偿:资源模型裁决闭合(同一资源,渠道 = 关卡大奖励入账 + Boss 掉落),「代币记账」改名「钥石入账」。机制未动(本文仍为范围草案) | -| v0.3 | 2026-09-17 | 数值纪律收口批:正文 knob 现行值改指路存根(事实源 data/tables/*.tres 与 registry),3 处失同步修正(钥石入账 +10/关 三处改「每关固定值,行值读冒险表 keystone_per_level」) | -| v1.0 | 2026-09-18 | **元进度定稿批(用户拍板六件收口)**:定名「永久强化」(系统族名元进度保留,「天赋树」退役、「营地」为界面壳);营地三柜台(属性锻造三档含护甲等级 / 道具工坊六件首版通关次数渠道 / 奖励格图鉴结构位);Boss 重复获取 = 首杀全量 + 重复杀固定小额;定价几何递增原则;区间平移换算率启用(换算率表首版三行、护甲行强条目、数值读 data/tables);注入 = 冒险开始参数面 + 覆盖值通道(override 集合操作:追加 / 替换);解锁界面双入口框架。本文自范围草案升定稿 | -| v1.1 | 2026-09-18 | **数值语言拍板批(与 01-核心循环 数值语言条款 / 难度曲线与Boss / registry / 06-待办清单 / 切片代码同批)**:营地三柜台节新增投值语言锁定条款——属性投值语言锁定 flat 整数加减,数值投值仍归设计批 | -| v1.2 | 2026-09-20 | GP+商店房批注记(知会性质——与冒险结构 v0.5 同批):钥石节新增与 GP 的分工一行——钥石 = 跨局持久解锁、GP(「金币」)= 冒险内一次性属性提升、局内清零不入存档,双币生命周期切分成文、永不互兑。机制零改动 | -| v1.3 | 2026-09-21 | **元进度实现批(与切片代码 / registry / 02 / 03 / 05 / 06 同批)**:本批 = 本文的实现批——MetaTable 四行族建表(`data/tables/meta.tres`,数值全 provisional 归设计批配读数);MetaProgression 账本服务(余额/几何定价/购买/工坊解锁/Boss 两档入账/注入计算,Core 层零 UI 零信号);注入通道落地(start_adventure params.hero_override → LevelRunner base_override,叠加序 = 表值+永久强化 flat+加算区 flat × 测试面板 pct);呈现面(营地覆盖层三柜台+主菜单入口+A 区顶栏钥石余额+结算屏入账明细,ui_kit 程序占位——视觉终稿归 HUD 协作批)。正文零改动(实现面不回流正文——正文零历史叙述纪律) | -| v1.4 | 2026-09-23 | **换算率标定批(用户指令「现在标定」;与切片代码 / registry / 06-待办清单 / 判定端工具同批)**:换算率节回填现行表值(生命 6 / 攻击 9 / 护甲 1 点每级——OFAT 冒险注入档与白板同种子配对的逐关条件通关率差实测,冒险条件口径;同日单关直入口口径退役使首轮直入口面读数作废重测);护甲行强条目重测履行并暴露修复护甲断链(begin_battle hero_armor_class 参数零消费→_defender_ac 接线);判定端带平移表值驱动接线(带重锚后随换算率平移判);排期表 P1 行销项 | -| v1.5 | 2026-10-01 | **钥石渠道改一批(迭代 10 奖励重构——用户 2026-09-30 拍板;与冒险结构 v0.12 / registry 同批)**:钥石渠道自二改一——「关卡大奖励入账(keystone_per_level)」随大奖励三件套退役,渠道 = Boss/精英怪击杀掉落(逐杀实时入账,行值读 meta.tres boss_keystone 首杀/复杀两档;精英掉 1 预留);首杀大额/复杀小额规则不变。**产出重标义务重开**:现行两关冒险产出结构从「大奖励 10×2 + Boss 首杀 5」改「Boss 掉落 ×N(精英未实装零贡献)」,标定随元进度设计批/调参批重开(06 登记) | -| v1.6 | 2026-10-03 | **同调位账本批(迭代 11 第①批同调实施批——save v4 / meta.tres attune_refresh_upgrade 行族 / registry 同批)**:①道具工坊柜台职责改写——解锁→谓词表形态(unlock_requires 行,首批全解锁=空谓词合法态,底稿 §2.2 用户裁),柜台内新增「同调装配」段(装配/换装/Slots 点亮 + Y 刷新升级行购买——程序占位面,视觉终稿归营地批;满位禁选/写档持久 MetaProgression.toggle_attunement 唯一写口);②Boss 击杀总数计数登记(boss_kill_count 含重复,收束入账=apply_adventure_summary 逐通关关次 +1,attunement_growth 谓词表计数源);③Y 刷新升级行登记(attune_refresh_upgrade 行族 L1→Y1/L2→Y2,钥石直购,provisional);④装配关系入存档持久(attunement_equipped save v4 域,冒险中途不可换装——底稿 §8.5) | -| v1.7 | 2026-10-07 | **生命周期轴裁决随批(框架现行事实源=核心循环「生命周期轴」节同批落文)**:设计目的节补独立资源口径——钥石与 GP=两条平行独立资源不立统一上位概念,钥石=存档级账归本文、GP=冒险级账归冒险结构(同批落文);既有账本语义零改动 | -| v1.8 | 2026-10-09 | **文档正确性审查批(用户令——状态记录与证据对齐)**:①设计目的「渠道有二:关卡大奖励入账、关底 Boss 掉落」与核心规则「渠道自迭代 10 起改一」自相矛盾——订正为 Boss/精英怪击杀掉落单渠道;②道具工坊行订正——工兵令已退役(treasure_items.tres retired 旗),可解锁在役=探巢摆钟/爆破工兵包两件;「本柜台职责随同调实施批改写」的未来式订正为已落地(2026-10-03 v1.6);③定名节补审查注——「本作不存在树形结构」失义(属性锻造随迭代 12 T9 落地为锻造脉节点结构,存档域 tree_nodes/fork_sides),章节归后续修订;④里程碑前缀按 2026-10-09 口径删「M-3」(视觉终稿行)只留「迭代 9」;⑤调参表钥石产出行删「每关入账值 keystone_per_level」(行值已退役)改 boss_keystone 行指路。 | -| v1.9 | 2026-10-09 | 文档正确性审查批(定点):解锁双入口框架节「局内暂停层入口未实装(随 HUD 批 M-4)」过期订正——暂停层只读入口已实装(2026-10-06 迭代 17 卡③,实机目检待用户;06 登记条在册);裸 M-4 标签随订正消除 | -| v1.10 | 2026-10-09 | **B2 裁决落文(用户令「删除旧的、直接写新的」)**:道具工坊行删旧写新——旧「现行六行」登记作废(旧目录已随秘宝 v1.5 全退役),改写=件的目录与效果现行事实源指路秘宝.md「目录(重设计 v1)」+解锁门槛谓词分级(普通 0 门槛/优秀中里程碑/稀有高里程碑,阈值归调参批)+通关次数渠道与钥石直购价归定价批后补 | -| v1.11 | 2026-10-09 | **B1 裁决落文(用户令「元进度让他们都独立去写」——天赋树独立成文)**:①定名节冲突表述换代——「归档线索里的『天赋树』一词就此退役」与 v1.8 审查注(「本作不存在树形结构」失义登记)同步摘除,改写 = 退役的是归档线索旧概念的旧义、树形结构已随迭代 12 以锻造脉形态落地在役(系统现行事实源 = 天赋树.md,本批新建 v0.1);②三柜台节补指路句——属性锻造树形节点结构现行事实源 = 天赋树.md,旧三档柜台与树四线 flat 注入面叠加实态随句登记。机制零改动 | -| v1.12 | 2026-10-09 | 武器锻造成文批随迁(用户令「完成文档编写、代码不实现、记录待办」):三柜台节补指路句——属性锻造攻击/护甲两档的路线化改造设计权威文档 = [武器锻造](锻造工坊.md) v0.1(按 2026-10-07 提案推荐案成文、17 裁点开放在册、实装待办在册 06;改造落地前三档直购维持现役)。机制零改动 | -| v1.14 | 2026-10-11 | 秘宝匣行换代随批(秘宝.md v2.7 目录修正批):13 件三档+解锁混合制口径;旧「正主/谓词分级」表述同步清除(拾取渠道指路同日追加又随终裁废止) | -| v1.13 | 2026-10-10 | **「道具工坊」改名「秘宝匣」(2026-10-10 天赋树设计会话裁——树上解锁节点与营地柜台同名)**:现行正文六处扫改(三柜台行 / 柜台行 / 柜台纪律 / 后续商品行 / 调参表 P1 / 定价表行);版本历史行一律不动;别名「道具工坊」登记 registry 术语条保留检索。机制零改动 | -| v1.14 | 2026-10-11 | **营地统一案甲随迁(2026-10-11 天赋树设计会话终裁)**:三柜台节补「营地统一」段——树=营地本体、属性升级唯一入口=树脊柱淬炼节点、本属性锻造柜台随 06「天赋树实装批」退役吸收进脊柱(落地前维持现役)、锻造柜台与秘宝匣转工作间钥匙模型、图鉴常开;设计权威文档指路 = 天赋树.md v0.2。机制零改动(退役与公式换代随实装批) | -| v1.15 | 2026-10-11 | 锻造工坊更名批随迁(机械扫):三柜台节指路句随系统更名「武器锻造→锻造工坊」换代链接与名称(06 实装批条名同步「锻造工坊实装批」;版本历史行内旧名按历史记载保留)。机制零改动 | -| v1.16 | 2026-10-12 | **完备性检查批随迁(用户令:有缺漏即补齐)**:①「跨局注入」节补开局属性四层叠加公式(角色基础值+树生命/命中 flat+锻造路线加值+局内加算区 flat;入战 AC 三层)——锻造工坊与天赋树两文档共指本节为「通道现行事实源」而公式缺位,本次落实;原「属性锻造三档是数值覆盖」随迭代 21 T5 行族退役换代;②锻造工坊 v0.6 引用版本号 v0.1→v0.5 连带校正(三柜台节)。机制零改动 | -| v1.17 | 2026-10-12 | **迭代 22 反哺落文批(实现报告 §三④,用户裁「落文」)**:秘宝匣行补迭代 22 实装实录(购买钮禁用态/条件进度呈现/分档装配呈现/空目录合法态/treasure_shop_status 投影/旧道具工坊渠道面退役);柜台纪律「首版只挂通关次数渠道」排期态消解注记;P1 秘宝匣定价行换代(provisional 10/25 已投,终值归调参批)。机制零改动 | -| v1.21 | 2026-10-15 | **简明技术中文用语规范批(用户令):词面修正 2 处+死链修复 1 处**——「收口」→删(文头状态行「用户拍板收口」→「用户拍板」,已定稿语义由句首承载);「不得」→「禁止」1 处(验收·换算可审计条护甲行);死链修复:v1.12 行的武器锻造死链指路改指锻造工坊.md(2026-10-11 更名漏改,显示文字与行内其余文字同步换代为现行名,其余不动)。机制与数值零改动 | -| **v1.22** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:「独立资源口径…两条平行独立资源」→「系统资源口径…两条平行独立的系统资源」;钥石表行改「钥石(存档级)」——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/systems/跨局循环/天赋树.md b/design/gdd/systems/跨局循环/天赋树.md index 69e5824c..8fcf9286 100644 --- a/design/gdd/systems/跨局循环/天赋树.md +++ b/design/gdd/systems/跨局循环/天赋树.md @@ -196,20 +196,3 @@ A/B 态只放规则面:节点行持 a/b 双效果键(封闭规则键词表 R ## 待办 本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md)「天赋树实装批」条,本节不再逐条登记。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v0.10 | 2026-10-13 | **R1 机制位批(用户推翻迭代 21 追认单 #1 裁撤案)**:「等级阈值前置」以机制位形态随批重立——schema requires_level 字段(Dictionary{node_id: n},键悬空/阈值 <1/类型错加载即拒)+ tree_can_buy 判定分支 + 行板门槛呈现(未达标 🔒+悬停文案 gate_text)+ 单测 tree_requires_level_test 八断言(run_all 24→25 套);现役 12 行零配置=空转零行为影响(冒烟 938/0+全闸复跑零漂移),配置归表行随需填。六处 R1 表述换代(状态行/范围表/schema 连带/购买校验③/调参表/验收前置行) | -| v0.9 | 2026-10-13 | **迭代 21 反哺落文批(实现报告 §五①③⑥,用户裁「按呈报落文」)**:①实装落地态全文档换代七处——头部状态行 / 系统范围表 / 节点总表前言与三行 / schema 连带句 / 依赖表 / P0 段 / 验收实态注(原「实装未落、现役 33 节点」过渡态终结;迭代 21 = 2026-10-12 入库);③「财富之道」设计避让句按卡片 v1.7 ⑪②裁决改写为折扣定义边界口径(散=只覆盖商品购买价,键 gp_cost_mult,不含两处刷新——定义边界非临时避让);⑥验收实态注(机检读数+命中线契约 6 括注定性);连带:已建未接面节换代(同调位判定源已切树点亮数 / 刷新升级同账路由 / 命中线契约 6 维持——两接一维持)。机制与数值零改动 | -| v0.8 | 2026-10-11 | **Fork 一节点双态换代批(用户裁)**:①开局姿态/危险直觉/财富之道三天赋=三节点——现役 A/B 双行结构(迭代 12 沿袭,「付一次钱得双态开关」裁决未落进节点组织=落文错误已纠正)收编为单行双态,同调脉 9→6(同调位 3+Fork 3)、全树 15→12;②节点语义=购买解锁双态开关(cap1、零重复购买)、解锁默认 A 态、营地零币切换(互斥由单态承载);fork_sides 存档语义不变(组→激活态),tree_buy_fork=购买解锁/tree_toggle_fork=零币切态;schema=Fork 行持 a/b 双效果键、效果按激活态取值、Fork 组词表校验改每组恰一节点;③R1(「等级阈值前置」形态去留)不随本批变化,仍开放待裁(推荐裁撤)。实装归 06「天赋树实装批」(33→12 连带,需求卡片 v1.6 同批) | -| v0.7 | 2026-10-11 | **一线一节点换代批(用户裁)**:①脊柱淬炼一线一节点——生命淬炼/命中淬炼各收编为单节点 4 级(原「一线 4 层×层内 3 购」层=级收编;用户明裁:一个内容一个节点、等级在节点内、不拆多节点),脊柱 8→2、全树 21→15;②行门槛平移——SPINE_ROW_GATE=4 公式不变,门槛主语从「层 N」改「节点第 N 级」(第 2~4 级需全树总投入 ≥4/8/12),row 字段随层行退役;③彩蛋条件随结构换代为「生命/命中两节点 4 级拉满 且 同调位 1/2/3 全部解锁」;④R1(「等级阈值前置」形态去留)不随本批变化,仍开放待裁(推荐裁撤)。实装归 06「天赋树实装批」(33→15 连带,需求卡片 v1.5 同批) | -| v0.6 | 2026-10-11 | **攻防所有权切分落文批(锻造工坊裁决会话 A 组定案,天赋树会话交接落文)**:①脊柱换代 16→8——攻击淬炼×4 层与护甲淬炼×4 层删除,脊柱=生命/命中两线×4 层,全树 29→21 节点(每根数值轴全游戏单一来源:生命/命中→树脊柱、攻击→锻造工坊武器路线、AC→甲路线,树零攻防来源=红线);②锻造工坊钥匙节点前置改「无」(free、直接可点亮,原「攻击淬炼累计 ≥2 且 护甲淬炼累计 ≥2」等级阈值前置随两线砍除作废)——连带开放待裁点 R1:schema「等级阈值前置」新形态现无消费者,裁撤(推荐)/留作机制位待用户裁;③地脉共鸣换代——条件改「生命/命中两线全部买满(8 节点全上限)且 同调位 1/2/3 全部解锁」、效果改生命/命中两线 flat(攻/护分量摘除),上限 3 枚不变;④行门槛 SPINE_ROW_GATE=4 规则保留(层 N 需全树总等级 ≥4×(N−1)),两线换代后总等级供给结构变化=达成节奏重算注记在册、值归数值批;⑤叠加公式换代——开局属性=角色基础值+树生命/命中淬炼 flat+锻造路线加值(只按当前选中生效)+局内加算区 flat(命中在账未注入披露不变);⑥营地呈现措辞对齐四柜台并排(树淬炼柜台=树脊柱界面形态、锻造工坊柜台钥匙点亮前=锁定态,机制语义=树营地本体/钥匙模型/图鉴常开不变,A② 裁);⑦节点总表/一脊三脉/验收标准/调参表/依赖表连带换代。实装归 06「天赋树实装批」(结构目标 33→21 连带换代,需求卡片 v1.4 同批) | -| v0.5 | 2026-10-11 | 锻造工坊更名批随迁(机械扫):五处「武器锻造」链接随系统更名「锻造工坊」换代为 [锻造工坊](锻造工坊.md)(v0.2 历史行内旧名按历史记载保留)。结构零改动 | -| v0.4 | 2026-10-11 | **歧义扫描清零批(/grilling 六裁落文)**:①Q1 术语回归正主——分叉效果废「陷阱/危险标记」自造词,改「踩中危险格伤害减半」「危险格标记错误返还行动点」,玩家文案沿「危险格/安全格」;②Q2 地脉共鸣效果改生命/攻击/护甲三线(命中分量待命中线注入随批加回,不留永久无效分量);③Q3 行门槛总等级口径写明=tree_nodes 全部节点等级之和(免费点亮与分叉激活计入,沿现役实态);④Q4 财富之道范围定界——聚=仅战斗掉落渠道、散=全部 GP 消费面(用户裁);⑤Q5 限次计数生命周期落句(随冒险持久/按关重置/新冒险清零/断点保留);⑥Q6 三处旧裁决换代——已建未接面槽位判定源句换 Q2 裁决(树点亮数+旧条件作废删除)、刷新升级条补 Q1 双入口并存、存档域节「迁移重做」整节换代为「旧档废弃」(Q3 裁决落文,禁迁移红线);顺带清「Y 升级行族」黑话为「刷新升级行族」。结构零改动 | -| v0.3 | 2026-10-11 | **节点台账补全批(用户令:台账指引升格文首+29 节点总表落文)**:文档最前新增「节点台账指引」块(节点结构查本文总表 / 数值查配置文件 `game/data/tables/meta_tree.tres` 双源分工声明);核心规则节补「节点总表(29 节点)」——17 行折叠式全名单(脊柱四线按层折叠),逐节点名称/脉/类型/前置/效果方向,数值不进正文沿配置纪律。结构零改动(纯台账补全) | -| v0.2 | 2026-10-11 | **天赋树设计会话裁决批(结构换代+分叉效果定案+营地统一)**:①结构换代 33→29——锻造枝三属性节点(武器锻造/护身锻造/甲胄锻造,旧柜台镜像重复件)删除换单个免费解锁节点「锻造工坊」(前置=攻击淬炼累计≥2 且护甲淬炼累计≥2,等级阈值前置新形态);克制专精 Fork 对整组砍除(类型表达归武器锻造);②分叉效果定案——开局姿态两侧收每关首轮窗(先手压制=每关首轮 AP+1 / 稳健拓荒=每关首轮内受击减伤)、雷感直觉改名危险直觉(锋=陷阱伤害减半 / 守=误标返 AP·均每关限次;标错机制存在性 T0 实查在册)、经济人格改名财富之道(聚=GP 获取增益 / 散=消费折价,避开两处在册旋钮);现役两键占位态随实装批终结;③营地统一案甲——树=营地本体,属性升级唯一入口=树淬炼节点,旧属性锻造柜台退役吸收进脊柱,工作间钥匙模型(锻造工坊/秘宝匣两钥匙+图鉴常开);④叠加公式换代=基础值+树淬炼+锻造路线加值+局内加算;⑤同调位 1 改无前置根节点、串行保留;地脉共鸣条件改四线全部买满;⑥「道具工坊」改名「秘宝匣」;⑦树上刷新升级节点定性缺陷(购买写 attune_refresh_level 同账修复随批);迁移映射重做(forge_levels→脊柱线)。全部实装归 06「天赋树实装批」(原「已建未接面两件」+「结构重构批」两条合并) | -| v0.1 | 2026-10-09 | **B1 裁决补写批(用户令「元进度让他们都独立去写」)**:系统随迭代 12 双层 BD 实施批实装在役(33 节点 + 存档 v5 树域 + 营地树界面 + A/B 面 MC 两侧差 0.0pp 过 <~3pp 验收线,2026-10-04 落地 = 合并 e780063 系),本文补写其设计文档——机制描述以代码实态(meta_tree.tres / MetaTreeTable schema / MetaProgression 树段 / save_manager v5 域 / 效果引擎规则键消费面)与迭代 12 落地裁决(整合定稿 R1 甲融合案、2026-10-07 树全钥石单币裁甲)为据;设计底稿《双层BD体系-整合定稿-2026-10-03》已按吸收即死退役(删除 = git 8e02dcf,内容经 git 历史取证)。已建未接面三条如实登记(同调位 / 刷新升级 / 命中线),处置权归后续批 | -| v0.11 | 2026-10-15 | **简明技术中文用语规范批(用户令):死链修复 1 处**——v0.5 行更名记载内的武器锻造死链改指锻造工坊.md(2026-10-11 更名漏改指路;显示文字「武器锻造」系更名记载的旧名内容本身,按对照性豁免保留,仅换链接目标)。词面修正 0 处、机制零改动 | -| **v0.12** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:「跨局账/这本账/树域账/钥石账本」→ 系统资源表述;「同账路由」→ 同路由;「命中在账未注入」→ 命中未注入——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/systems/跨局循环/生涯.md b/design/gdd/systems/跨局循环/生涯.md index 1ed97511..c8ba53cc 100644 --- a/design/gdd/systems/跨局循环/生涯.md +++ b/design/gdd/systems/跨局循环/生涯.md @@ -99,11 +99,3 @@ P0-P5 六点已于 2026-10-06 用户全裁(案甲 × 6,备选案与淘汰依 | 丙 | 条带原样永久保留(固定存 10 条,不随 N 动) | 改动最小;淘汰候选:与生涯列表长期双轨,上限语义分裂(营地固定 10 / 生涯 N),N 大于 10 后两处看到的条数对不上 | 裁决方式:随本提纲评审一并定案,期二实装批执行。 - -## 版本历史 - -| 版本 | 日期 | 说明 | -|---|---|---| -| v0.2 | 2026-10-07 | 期一实装随批换代(迭代 18 卡④):状态行升「期一已实装」+主菜单组列生涯钮落位+§四期一行挂实装留痕。设计内容零改版——本文仍是三段内容的范围权威;期二/期三范围与 P6 待裁点维持原状 | -| v0.3 | 2026-10-09 | **文档正确性审查批(用户令——状态记录与证据对齐)**:①跨局汇总表「冒险总局数 / 通关局数」行订正——save v6 两终身计数域已随期一落地(2026-10-07 迭代 18 卡④),「无现成数据源、须新增」改为现成;②两处「终局特性(集) relics」改「终局专长持有集 relics」(特性系奇物旧称已退役;存档键名沿用历史形态不动)。 | -| v0.1 | 2026-10-06 | 设计提纲首版(迭代 17 卡④设计批,纯文档):五节成文;P0-P5 已裁结论落文;新发现待裁点 P6(营地最近冒险条带去留);现状描述全部经代码级复核(F1-F10,见 design/qa/iter17-career-exit-report-2026-10-06.md)。状态 = 范围草案待评审 | diff --git a/design/gdd/systems/跨局循环/秘宝.md b/design/gdd/systems/跨局循环/秘宝.md index 8f14c434..bf01dec8 100644 --- a/design/gdd/systems/跨局循环/秘宝.md +++ b/design/gdd/systems/跨局循环/秘宝.md @@ -9,7 +9,7 @@ **现行形态 = 局外同调件**:开局前在营地装配(营地·秘宝匣柜台「同调装配」段)、占同调位(0 起步、固定 3 格,每件固定占 1 格)、被动件整局生效/主动件每冒险充能(冒险开始重置)。实现面 = `treasure_items.tres` + `game/core/attunement.gd`(同调位数量判定源=天赋树同调位节点点亮数——2026-10-11 Q2 裁甲、迭代 21 T4 槽位收编落地;原 `attunement_growth.tres` 谓词表已顺带退役;解锁条件=数据行内 `unlock_requires` 字段承载——迭代 22 实装落地,2026-10-12)。**新目录 12 件已随迭代 22 实装批全量落地(2026-10-12,T1-T7)**,逐件实录见「目录(重设计 v1)」各表实态列。 -**沿革一句话**:本系统前身为切片期掉落消耗品形态(2026-09-29 迭代 7),2026-10-03 随同调实施批整体替换为现行形态;旧目录九件已全数退役入素材库(2026-10-08/10 用户裁)。历史细节见版本历史与 git 提交史。 +**沿革一句话**:本系统前身为切片期掉落消耗品形态(2026-09-29 迭代 7),2026-10-03 随同调实施批整体替换为现行形态;旧目录九件已全数退役入素材库(2026-10-08/10 用户裁)。历史细节见 git 提交史。 **现行形态速览**: @@ -258,40 +258,3 @@ playtest 预警(预注册,归难度曲线与Boss): ## 待办 本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v3.0 | 2026-10-12 | **迭代 22 反哺落文批(实现报告 §三①②③,用户逐点裁「落文」)**:①目录三表补实态三列(item_id/解锁〔价格或条件,阈值 provisional〕/效果实现 kind)+试炼镐行换代自动兑付语义+全部「实装批落地前」现状句换代(定位形态节/目录引言/负责表/受理框架节/调参表/验收护栏覆盖两行)+旧目录退役指针补代码旧行已删;②代价轴转化获取行换代=试炼镐每开 8 安全格自动兑当轮 AP+1(2026-10-12 用户裁:无玩家发起入口、战斗级重置、兑付时序=揭示先于扣费故 AP 归零恰逢满点轮不结束)——设计留白〔积点计数重置周期〕随裁补记;③解锁混合制节条件表实录(钥石 8 件 10/25+条件 4 件三计数键阈值)+承载换代=行内 unlock_requires 字段 | -| v3.1 | 2026-10-15 | **简明技术中文用语规范批(用户令):词面修正 3 处**——「报错」→「返回错误」2 处(真视窄域护栏句、验收·护栏强制条);「收口」→「收束」1 处(P0 第 5 条「装配与充能账随冒险收口」——冒险生命周期收束为本文件既有用词)。机制与数值零改动;目录表线香/天眼行「战斗级/关卡级充能」系术语表在册秘宝主动件术语,不属退役词命中,原样保留 | -| v0.2 | 2026-09-16 | 更名批(用户拍板 2026-09-16):系统更名"辅助道具"→"秘宝"——定位已非纯数值道具,含信息/妙用向效果;文件同步重命名;英文代号 AUXILIARY_ITEMS 暂沿用 | -| v0.3 | 2026-09-17 | 切片期空内容拍板(用户拍板):道具定义表为空列为合法态——五维度覆盖检查改为仅对非空清单执行;验收标准覆盖检查条目同步;06「维度覆盖检查破缺」「失义道具的掉落投放」两条随批关闭 | -| v0.4 | 2026-09-17 | 数值纪律收口批:正文与调参表 knob 现行值改指路存根(事实源 data/tables/*.tres 与 registry),1 处失同步修正(AP 8→6 漏改)——行名与表结构列保留 | -| v0.5 | 2026-09-29 | **内容批落地修订(迭代 7——用户八拍板)**:道具定义表六行入表(三有效实装:工兵令/探巢摆钟/爆破工兵包;探宝罗盘退役留痕;显影尘/地穴全图卷封存);投放维度覆盖口径+豁免面 {plan, info, counter} 登记;解锁语义定稿;奖励节点=三选一构筑点;掉落投放权重 provisional | -| v0.6a | 2026-09-30 | **拍板点 1 收口批(用户裁决甲:同调=终局方向)**:新增「定位与形态沿革」节——现行=过渡形态、终局=局外同调件,两态关系=形态替换;正文口径回写四处;实施批登记见 06「秘宝同调实施批」条 | -| v0.6b | 2026-10-04 | **迭代 13 D6 实装修订**:爆破工兵包换装启用+「中立移除」实装口径节落文+投放态注记换代〔版本号 2026-10-09 由重复的 v0.6 改注 b 后缀——原两行同号系 10-04 批落行未查前账所致,node-reward v2.2a/b 先例〕 | -| v0.7 | 2026-10-01 | **奖励节点渠道改写注记(迭代 10 追加批)**:「奖励节点三选一构筑点」形态退役——奖励节点改提升三选一共享池;道具件经节点渠道入本关库存;同调实施批的全渠道统一收口义务 | -| v0.8 | 2026-10-03 | **反制契约作废批(用户终裁——层级错配失败设计)**:五维度「反制」行改终裁态;上游地形变异依赖行、P2 后置行同步;地形变异.md v0.6 同批落义务作废注记 | -| v0.9 | 2026-10-05 | **消歧更名批(用户拍板):系统更名「魔法道具」→「秘宝」**——「魔法」已被本作征用为敌方侧伤害/护甲语汇;同调位机制名保留;本批仅改文档称谓,代码标识符 aux_* 沿用(对齐另批) | -| v1.0 | 2026-10-06 | **效果声明换代(内容数据驱动扩展批)**:被动件改订阅行(on/when/do 由效果引擎统一解释)+主动件受理闸数据化——按件 id 硬编码清零;结构冻结零触碰,行为与迁移前逐位一致(MC 同种子 40 局对拍实证) | -| v1.1 | 2026-10-07 | **生命周期轴裁决随批(框架现行事实源=核心循环「生命周期轴」节)**:三选一刷新双源补两账语义(存量账/临时账/消耗顺序);「三选一呈现」=比节点更细的事件 | -| v1.2 | 2026-10-07 | **三层职责分界批(用户裁)**:头部一句话换代为「营地装配的角色机能件」(操作包络加强,不出裸属性值、不改战斗结算机制);机制向三件归留本层重设计批处置 | -| v1.3 | 2026-10-07 | **三件机制向现件归留裁决(用户裁)**:淬毒刃纹→专长池;标中殉爆→专长池插旗系;惊巢反制→退役进素材库;现役目录九→六 | -| v1.4 | 2026-10-07 | **同调位分档(用户裁)**:同调位分三档(普通格/优秀格/稀有格)、槽位可装 ≤ 槽位档位的件、里程碑分档发槽;费用制落选留档 | -| v1.5 | 2026-10-08 | **新目录 15 件落地批(用户终审全落)**:新增「目录(重设计 v1)」节=新现行事实源——三档骨架+15 件表;旧目录全数退役只作素材库;数据迁移与旧行删除归实装批 | -| v1.6 | 2026-10-09 | **去毒批**:速览旧目录九件表加退役标注+魔法提灯归属待裁指路 06/老正文过期声称清扫——新老框架分家 | -| v1.7 | 2026-10-09 | **文档正确性审查批**:头部横幅重写/沿革节两态表述换代/实现面表名失同步修正/老正文深层逐节收口+四节隔离标注/调参表与验收旧语境改写 | -| v1.8 | 2026-10-10 | 营地柜台名扫改(天赋树设计会话裁「道具工坊」改名「秘宝匣」):两处改「营地·秘宝匣柜台」。机制零改动 | -| v1.9 | 2026-10-10 | **第一版秘宝全弃用收官批(用户裁「退役与封存都进素材库」)**:显影尘/地穴全图卷由 deferred 改 retired;正文四处换代;素材库四件迁表一;数据表四行删除归退役删行批 | -| v2.0 | 2026-10-10 | **秘宝解锁与槽位裁定批(grilling 审查轮,用户逐裁)**:①同调位上限=基础 3 格+第四只手突破至 4;②槽位数量与品质归天赋树同调位节点(1=普通格/2=优秀格/3=稀有格递增);秘宝侧同调增长表改造为解锁条件表随实装批;③解锁方式换代=混合制(基础件钥石购买+特定件条件解锁,旧「档位谓词分级」作废);④换装券=自主换装唯一渠道(显式例外);⑤三选一刷新双源正文改「存量账/临时账」称谓(先扣临时后扣存量定案;X/Y 字母对表归实装批 T0);⑥分界尺精确化=属性值指角色战斗属性值、经济与操作参数属操作包络(头部+核心循环分界节同步);⑦中立移除「重生待定」标注摘除(素材库件同规);⑧速览旧目录三段退役清理折叠为指针 | -| v2.9 | 2026-10-11 | **第四只手删除批(用户推导「带了等于没带」成立,主会话上轮净收益分析有算术错误致漏删)**:净账=占一槽换一槽(3=3)且自锁唯一稀有格(稀有格只能装它自己、额外格为优秀格)——严格劣于任何真秘宝,删除;稀有档 3→2、全目录 13→12 件;「跨域」概念撤回(用户澄清:天赋树与秘宝同为角色属性贡献者,不存在所有权排他——「归天赋树管」措辞改中性「由树节点提供」) | -| v2.8 | 2026-10-11 | **拾取渠道废止批(用户裁「秘宝只在冒险开始前配置,不存在任何冒险中更换方式」)**:删「冒险中的秘宝拾取」段;来路口径回单渠道(营地解锁)+绝对规则落文(无例外——拾取与效果均不产生装配变化);验收增「装配不可变」条(冒险全程装配快照逐位不变断言);受影响件扫描=13 件零件失效(唯一依赖换装的换装券已于 v2.7 删除) | -| v2.7 | 2026-10-11 | **目录修正批(用户复核抓出两个设计错误)**:①回能器删除(孤儿件——新目录无冒险级限量件,且关卡级/战斗级件天然周期重置、开局回充结构性冗余;优秀档 5→3,两位空位不构成补件议程);②换装券撤消(**设计错误承认**:换装券系从「中途不可换装」规则反推的错误造物,从来不是秘宝件——真实机制=冒险中拾取未知秘宝、打开选择、携带满则替换);③获取渠道换代=营地解锁+冒险拾取两条(原「不掉落」口径废止);新增「冒险中的秘宝拾取」段(替换=获取事件与不可自主换装不冲突;投放渠道/候选构成/频率归实装批与数值批);④效果轴操作能力/行动资源两格改空位、恢复机制改无现役来源;⑤全部「15 件」计数换代 13 件 | -| v2.6 | 2026-10-11 | **怪物巢穴类型退役批(用户裁)**:巢穴预告件效果文本换代(揭示本板危险格数量——件代号保留,命名归用户);「巢穴计数」账名同步;世界观风味层巢穴隐喻保留(00-游戏概念隐喻轴) | -| v2.5 | 2026-10-11 | **可读性审查批(grilling,用户令「谁看了都知道它在说什么」)**:①术语指路行入头部(全库术语表同批建立);②首用术语白话化/查表化(同调位、操作包络、RAP、GP、微光、巢穴等入术语表;slot_cost→每件固定占 1 格);③黑话清扫=正主/落籍/P1 甲死指针/charges/结构闸/边界锚/批前/在册/单口/旋钮;④承重契约白话化+头注修正(非全部由加载校验强制)+真视前向引用补注;⑤验收分层句白话化;⑥两处过时事实修正=战斗道具窗口(2026-09-15 已下线,实证战斗结算文档)/21 项义务死指针(registry aux_items 实证无 obligations 字段,改写为随实装批消解);⑦版本历史 v2.2-v2.4 行序修复;⑧全库术语统一随批(危险格/整图/专长凭证,见术语表 v1.0) | -| v2.1 | 2026-10-10 | **系统目录归位批(用户发现结构问题)**:本文件自 `systems/排雷循环/` 迁入 `systems/跨局循环/`——生命周期裁定=解锁/装配/存档持久全在跨局侧,排雷循环仅是生效现场;成因=前身「辅助道具」系切片期掉落形态故旧置排雷循环,同调换代只换内容未搬位置。文内向排雷循环四文档的引用改跨目录路径 | -| v2.2 | 2026-10-10 | **正文换代批(方案甲,用户裁「旧的删、误标改」)**:①定位与形态节压缩(沿革一句话;删过渡形态长段/中立移除规格段〔规格迁素材库 blast_kit 行〕/衔接纪律/事故留痕——正文零历史纪律);②五维度框架节去「在役旧实现」错标改写(信息/风险/行动三维列新目录承载件,规划/反制豁免维持;逐件标注随实装批);③使用编排/叠加层/边缘零信息三节去⚠(机制为新目录沿用)+举例换新件;④调参表清理(删旧目录六行句/投放态注记/playtest 预读行;订阅行段去件名举例与错标——效果引擎机制在役沿用);⑤验收护栏与覆盖检查两条换代新目录语境;⑥「旧目录处置」小节删除(素材库表一承载)。真旧内容承载=素材库+git 历史 | -| v2.3 | 2026-10-10 | **设计骨架节落地(用户逐轮裁:三大类方向+代价×效果矩阵+使用代价空间+转化获取三通道)**:新增「## 设计骨架」节替换旧维度框架节——①叙述总纲=玩家体验两面(信息/操作);②效果轴三方向(信息/行动资源/操作能力)+细分格开放清单(奖励预读空位备注微光常显重合;资源容量扩展/奖励预读等空位在案);③代价轴三段=获取代价(钥石/条件解锁)+使用代价(按重置周期分层:冒险级/关卡级/战斗级/转化获取〔行为/资源/时间三通道,后两空位〕/常时;恢复机制独立参数=回能器关级回充只作用于冒险级件)+装配代价(slot_cost/档位格约束);④用法规则五条(新件=效果格×代价格/档位=预置平衡带/覆盖检查只跑三方向且空位不构成议程/信息方向按减赌目的检验/账本独立值 provisional);⑤旧五维度框架概念退役(v0.5 起在册的自查清单由骨架三方向继承;逐件归属随实装批登记);⑥负责表/验收/依赖表相关行同步。骨架定位=可设计方向清单(类比奇物骨架、机能面层次),非既有件分类;本批过程事故在册=先行的行切片脚本损坏提交(deb1a80)已全文重写修复 | -| v2.4 | 2026-10-10 | **棋盘事实不可变裁定批(用户裁)**:①承重契约增条——秘宝效果不得移除/增改危险格位置与邻接数字,效果形态只允许信息呈现与开格动作;原爆破工兵包「中立移除」定性为违规形态、随件退役废止(规格留素材库作反面留档);②设计骨架增预留方向行——无差别开格(3×3 全开、收益不获取惩罚不触发)预留,现不做后续拓展再裁,与天眼有差别开格相区分 | -| **v2.5** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:「存量账+临时账两本账」→ 存量+临时两笔;三处表头「写哪本账」→「写哪笔系统资源」;「各周期账本独立」→ 系统资源独立——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/systems/跨局循环/锻造工坊.md b/design/gdd/systems/跨局循环/锻造工坊.md index 6ee5124f..2cbc3c35 100644 --- a/design/gdd/systems/跨局循环/锻造工坊.md +++ b/design/gdd/systems/跨局循环/锻造工坊.md @@ -1,7 +1,7 @@ # 锻造工坊 > 一句话:营地的武器与护甲成长——武器锻造区三条路线、护甲锻造区三条路线各练各的,钥石消费,一次冒险各选一件,满级特效留位本期不做 -> 状态:**v0.8 迭代 21 反哺④残余写入文档(2026-10-13)**——「树侧钥匙」句换代:钥匙节点 forge_workshop 已随迭代 21 实装在役(free 无前置、点亮展开本柜台、锁定态零购买路径),原「实装归 06」悬置指针终结(详见版本历史 v0.8 行)。承 v0.7 迭代 23 反哺写入(2026-10-13)——正文补 Q1 等级语义衔接(0 = 未练合法态)、效果类型闭集 24→31 订正、实装边界 1 回填实装实态(已随迭代 23 入库)。承 v0.6 完备性检查批(承 v0.5 B 组定案——**17 裁点全数清零**:1 丙 / 1a 一次冒险一件武器+一件甲 / 1b 营地可换·战斗禁换 / 1c 免费 / 2a 伪裁点消解 / 2b 随 3a 消解 / 3a 魔法护甲统一命名 / 3b 敌方攻击缺省普通·克制反向当下生效 / 3c 每型独立路线 / 4a 前缓后陡 / 4b 锻造内自闭环 / 4b-1 并联双通道 / 5b 纯钥石 / 5c 零材料 / 6 满级特效本期不做留扩展位 / 8a 工作间两区定名;2c、5a 已于 v0.4 结案)。**v0.6 变更(2026-10-12 完备性检查批·grilling 用户逐条裁)**:现役事实基线换代(forge_products 行族已随迭代 21 T5 退役、定价参数改历史考古口径);**两根类型轴所有权移交**(默认值归锻造工坊配置常驻持有、hero.tres 静态表两轴删除、选中态写存档+参数面注入);「与秘宝混合制同构」与「激活穿刺系专长」两处无依据表述订正删除。**满级特效本期不做**(只留扩展位);全部数值 provisional,终值归 Alpha 收官 M4 数值批〔未排期〕;实装已随迭代 23 入库(2026-10-12,见版本历史 v0.7 行) +> 状态:**v0.8 迭代 21 反哺④残余写入文档(2026-10-13)**——「树侧钥匙」句换代:钥匙节点 forge_workshop 已随迭代 21 实装在役(free 无前置、点亮展开本柜台、锁定态零购买路径),原「实装归 06」悬置指针终结。承 v0.7 迭代 23 反哺写入(2026-10-13)——正文补 Q1 等级语义衔接(0 = 未练合法态)、效果类型闭集 24→31 订正、实装边界 1 回填实装实态(已随迭代 23 入库)。承 v0.6 完备性检查批(承 v0.5 B 组定案——**17 裁点全数清零**:1 丙 / 1a 一次冒险一件武器+一件甲 / 1b 营地可换·战斗禁换 / 1c 免费 / 2a 伪裁点消解 / 2b 随 3a 消解 / 3a 魔法护甲统一命名 / 3b 敌方攻击缺省普通·克制反向当下生效 / 3c 每型独立路线 / 4a 前缓后陡 / 4b 锻造内自闭环 / 4b-1 并联双通道 / 5b 纯钥石 / 5c 零材料 / 6 满级特效本期不做留扩展位 / 8a 工作间两区定名;2c、5a 已于 v0.4 结案)。**v0.6 变更(2026-10-12 完备性检查批·grilling 用户逐条裁)**:现役事实基线换代(forge_products 行族已随迭代 21 T5 退役、定价参数改历史考古口径);**两根类型轴所有权移交**(默认值归锻造工坊配置常驻持有、hero.tres 静态表两轴删除、选中态写存档+参数面注入);「与秘宝混合制同构」与「激活穿刺系专长」两处无依据表述订正删除。**满级特效本期不做**(只留扩展位);全部数值 provisional,终值归 Alpha 收官 M4 数值批〔未排期〕;实装已随迭代 23 入库(2026-10-12) > 成文底稿:`design/research/提案-武器锻造系统-2026-10-07.md`(提案过程稿——全部备选案与淘汰依据、用户原案逐条对照见彼;本文只收录定案口径;**未启用的满级特效候选池亦留彼 §八**,不进正文) ## 设计目的 @@ -224,20 +224,3 @@ ### 10 · 数值与验证 全部数值 provisional 归 Alpha 收官 M4 数值批;实装批必须带改前 / 改后同随机种子配对读数验证难度影响。 - -## 版本历史 - -| 版本 | 日期 | 变更 | -|---|---|---| -| v0.8 | 2026-10-13 | **迭代 21 反哺④残余落文(用户裁「按呈报落文」)**:「树侧钥匙」句换代——钥匙节点 forge_workshop 已随迭代 21 实装在役(free 无前置、点亮展开本柜台、锁定态零购买路径),原「实装归 06「天赋树实装批」」悬置指针(该 06 条已随 480 清理批销号)终结。机制零改动 | -| v0.7 | 2026-10-13 | **迭代 23 反哺落文批(实现报告 §五,用户裁「在这里进行更新」;追认单九项同日全数追认)**:①正文补 Q1 等级语义衔接——「三件武器」节与「工作间内容清单·4」两处补「0 级 = 未练合法态」(未解锁/未锻造 = 0 加值裸体态,锻出第 1 级 = 首个 +1;原正文「1 到上限」未同步 Q1 续裁);②「满级特效扩展位」节与「现役代码事实」表——效果引擎效果类型闭集 24 种→**31 种**(原记系 2026-10-07 旧快照,迭代 20 T1 +7、迭代 22 T3 +1;冒烟断言钉 31);③实装边界 1 回填实装实态——落表=新表 forge.tres(ForgeTable 默认两轴+六路线行族)、路线 id 六个、字段闭集 12 项、ConfigDB.forge_* 访问器(「归实装批定义」已兑现)。机制与数值零改动(provisional 终值仍归 M4) | -| v0.1 | 2026-10-09 | 首版成文(用户令「完成文档编写、代码不实现、记录待办」)——按提案 v1.1 推荐案收录定案口径:柜台就地改造/三武器三甲独立路线/纯钥石零材料/前缓后陡/复用为主特效框架;17 裁点开放在册待用户逐点裁决;02-系统清单、元进度指路句、06 专条与实装待办随批同步 | -| v0.2 | 2026-10-10 | 天赋树设计会话裁定跨文档同步批:「柜台承载」节补登记树侧解锁门——本柜台以天赋树「锻造工坊」解锁节点为前置(免费节点,前置 = 攻击淬炼/护甲淬炼累计各 ≥2 级,等级阈值前置属新机制;实装归 06「天赋树结构重构批」)。机制设计零改动 | -| v0.3 | 2026-10-11 | **更名批(用户令,锻造工坊裁决会话)**:系统名「武器锻造」→「锻造工坊」——本文档改名 `锻造工坊.md`,与树上钥匙节点同名;全库现行指路链接与 06 实装批条名随批换代,提案过程稿文件名、用户原案引文、迭代 18 qa 清单与各版本历史行内旧名按历史记载保留;「武器锻造区/护甲锻造区」区名随承载裁决收口另改。机制设计零改动 | -| v0.5 | 2026-10-12 | **B 组定案落文(锻造工坊裁决会话续,用户逐点裁决)——17 裁点清零**:①1 丙=当前武器单选+每件独立路线;②1a 扩面=**一次冒险一个武器类型+一个甲型**(原只问武器携带数);③1b/1c=营地免费切换·冒险开始后锁死;④**2a 推翻**——伪裁点消解:伤害结算只有一套、单据自带 attack_type 栏,删"叠加/替代/互斥"三分法,改陈述「同一矩阵·单据自带类型·差异只在单据形态与生命周期」;⑤**2b 随 3a 自动消解**(非独立裁点,条件是"魔法甲≠ward");⑥3a=统一命名**魔法护甲**(ward;「魔法甲」系**笔误**不做简称处理,registry 不登记别名);⑦**3b 推翻**——敌方攻击有类型、未设置=默认普通 ⇒ 甲型差异「基础 AC + 克制修正」两轴当下即生效,原"诚实收窄/克制反向留结构位"整段作废,并如实登记现役落差(敌方单据 attack_type="" 恒不查矩阵、`enemy.tres:527` 轴未开)为**跨系统汇合点**(填值面归敌人系统/战斗结算)+ 连带后果(三型成纯序、魔法护甲双负无优势窗口);⑧3c=每型独立路线;⑨4a=前缓后陡(只锁方向);⑩**4a-1 撤回**——"曲线×定价=又贵又弱"结论无依据,不落方向性判断,只留"两条旋钮同批标定"程序句;⑪4b=锻造内自闭环;⑫4b-1=**并联双通道**(练满前一档 OR 一次性解锁价,互不影响);⑬5b=纯钥石(用户注:后续若要区分再重构,不预先建面);⑭5c=零材料;⑮**6 推翻**——满级特效**本期不做**,只留扩展位(不设计清单/不定值/不实装/不开参数位/存档不设特效域),七条候选池退回过程稿 §八;⑯8a=工作间**两区定名 + 路线行名**(区=武器锻造区/护甲锻造区;行=长剑锻造·长枪锻造·法杖锻造、轻甲锻造·重甲锻造·魔法护甲锻造,第一件武器显示名 剑→**长剑**);**并核结用户指出的事实——局内不存在武器/护甲提升**:商店货架三行"攻击锻升/生命锻升/护甲锻升"实为奇物「属性值提升」三轴的货架前台标签(`shop.tres` pool_shelf kind_id → `adventure.tres` CURIO_KINDS),与锻造无关,是否去"锻"字归实装批呈现面。连带:设计目的节能力台阶收缩为新武器/新甲解锁;实装边界重编号(特效条目改"本期不实装"、新增敌方攻击类型填值条);「待裁决清单」换代为「裁决结果清单(17 裁点全表)」+新增「工作间内容清单(实装批需求卡片输入)」两件交付。**同日五点澄清(不升版本)**:①2a 用户确认无异议——按**统一伤害轴**走(删三分法);②2b 连带确认:只有魔法护甲一型,**「魔法甲」系笔误**而非别名,registry 不登记别名、第四甲型议题彻底消解;③3b 的连带后果**不在本批考虑**——用户裁定其为**后续开发改造的前置信息**(敌方攻击差异化与魔法护甲正当性归后续批,本批只按统一伤害轴落结构与字段);④**8a 的 Y 层**(路线行名)定案="件名 + 锻造",第一件武器显示名 剑 → **长剑**;⑤**用户指出局内不存在武器提升——属实**:货架三行"锻升"是奇物「属性值提升」三轴(`shop.tres` pool_shelf 的 kind_id 指向 `adventure.tres` CURIO_KINDS)的货架前台标签,进冒险加算区、冒险结束清零,不是武器也不是护甲;**⑥同日 C/D 两项改名裁决**——C:货架三行「X锻升」→「**X祝福**」(攻击祝福 / 生命祝福 / 护甲祝福,后缀 = 用户选定,D&D 参照为 Blessing),机制分类名「属性值提升」不动、只改玩家向显示名,执行归独立改名小批(06 在册,本会话按禁动 game/ 纪律不代执行);D:棋盘格 defense 正向行与 `ac_up` 状态的同名次 **护甲强化** → **盾牌加护**(用户提案,理由=它是临时叠层状态而非护甲本体;附带约定「加护 = AC 判定层,护盾 = 保险丝那种吸收层,两者不得混用」),同样归改名小批——**注:D 改名连带 `smoke_all.gd:1199` 一条硬编码断言,必须同步改,否则冒烟红**。开工门(17 裁点清零)已满足 | -| v0.4 | 2026-10-11 | **A 组定案落文(锻造工坊裁决会话,用户逐裁)**:①承载换代——营地四柜台并排(树淬炼/锻造工坊/秘宝匣/奖励格图鉴),攻防独立柜台、工作间内武器/护甲两区并列零顺序门槛、宽度不足滚动条兜底、程序占位视觉终稿归 HUD 营地批(A②A③);②生命档移除——生命强化唯一入口=树脊柱生命线,本工作间纯攻防(A①;实装边界①同步);③**攻防所有权切分**——攻击唯一入口=武器路线、AC 唯一入口=甲路线,树脊柱砍攻击/护甲两线、树零攻防来源(红线;树侧 29→21 落文归天赋树会话交接批);④树侧钥匙改无前置直接可点亮(原等级阈值前置随两线砍除作废);⑤注入衔接落文——锻造路线加值=当前武器攻击加值+当前甲 AC 加值,只按当前选中生效;⑥死条件 magic_vs_magic 复活案作废(D 组核结:魔网织者在素材库表二退役名单;2c 结案);⑦「道具工坊」退役词清除(承载节随 A② 改写一并换代为秘宝匣);⑧存档域改旧档废弃口径(开发阶段无迁移)。B 组 15 裁点挂起待用户发令 | -| v0.6 | 2026-10-12 | **完备性检查批(grilling 全库核查——现役代码事实/关联文档/引用一致性三路,用户逐条裁)**:①**现役事实基线换代**——`meta.tres` forge_products 行族已随迭代 21 T5 攻防所有权切分整体退役(行族/访问器/购买面三处退役登记),「改造现役行(吸收)」语义全线订正为「新建行族」(现役代码事实表/三件武器表/工作间清单/实装边界 1 五处);定价「现役参数沿用」改「历史考古参数(20 钥石/150% 公比,`meta.tres:82-84` 退役批注)、实装投值归 M4 从零标定」;②**两根类型轴所有权移交(用户裁)**——`attack_type`/`armor_type` 默认值归锻造工坊配置常驻持有、hero.tres 静态表两轴删除;选中态写存档域+冒险开始参数面注入(订正原「写 hero.tres 休眠轴」口径——与现役「表运行期只读」纪律 `meta_progression.gd:12-13/119` 及本文存档域条目双重冲突);默认值与柜台解锁状态解耦(未解锁=无交互入口但配置常驻可读,不存在读不到默认值的窗口);③**两处无依据表述订正删除**——「与秘宝解锁的混合制同构」(「同构」非本项目概念;与秘宝仅共享钥石单币+直购/条件解锁成分语义,通道结构不同:件级单通道分派 vs 同路线双通道并联)、「选长枪激活穿刺系专长的价值」(现役专长均为跨攻击类型通用件、不按 attack_type 分系,`feats.tres` 29 行实证,该表述无现役对应物);④货架坐标订正(CURIO_KINDS 实为 `adventure_table.gd:29` schema 常量、feat_ticket 为显式豁免种 5/6 命中)+ 改名小批执行态回写(已合入 master `0c93a71`/`0144f60`);⑤存档域预登记存档序列化.md(用户令:验收文档现在做、不等实装批);⑥联动落文:元进度.md「跨局注入」节补四层叠加公式(v1.4)、术语表.md 新增锻造工坊节、entities.yaml terminology 补词条+新建锻造工坊条目。**不在本批范围(呈报归属,谁的问题谁改)**:registry ac_up 显示名失同步(归改名小批 D 项)、「魔法甲」四处残留(敌人系统/美术三档,归 3a 裁执行面)、registry meta_table 条目 forge_products 滞后(归元进度线)、天赋树.md 状态行滞后、06 提案条标题旧名 | -| —— | 2026-10-12 | **同日续裁写入文档(不升版本)**:①**编入迭代 23**(用户令——roadmap 主线序列 + 06 实装批条状态同步;M4 数值批顺延迭代 24+);②实装边界 6 订正——敌方 attack_type 为敌方定义数据(enemy.tres/skills.tres 行级,与敌种名字/血量同批同时读写、无独立时序),「两批排期协商」句删除(用户 D 裁:时序问题不存在;本批只按 3b 裁落结构面);③存档域「合并评估」语境订正——forge_routes 独立成域已预登记,树批入库后无共域冲突(用户 C 裁:非裁点,06 实装批条同句订正);④A 项(未解锁时默认值读取路径)确认口径=配置表常驻持有、解锁只门控交互不门控读取,v0.6 正文已落此文;⑤**等级语义裁(Q1)**——初始持有路线 0 级起步:未解锁/未锻造=0 加值(裸体态,类型=普通/轻甲);解锁并锻造第一级=「获得装备」=1 级=首个 +1 加值;逐级递进。正文「1 到上限」为量级描述(1-5 级),0=未练合法态;⑥**provisional 值落卡(Q2)**——需求卡片 T1 锚表:cap 5/武器与护甲每级增量统一 +1(累计 1/2/3/4/5;provisional 线性起步,4a 前缓后陡为终值形状方向归 M4)/甲型基础 AC 10/12/9(现役结构值)/价格 20×150%^n(20/30/45/67/101)/解锁价 200(中段三级 213 的九折);provisional 归代拍板沿锚投值、终值 M4 | -| v0.9 | 2026-10-15 | **简明技术中文用语规范批(用户令):词面修正 2 处**——「落文」→「写入」1 处(裁决结果清单表头「落文处」→「写入处」);「收口」→「完成裁决」1 处(4b-1 行备注「原正文"或"字歧义收口」)。另按失同步核对修正文头状态行:版本注 v0.7 → v0.8(v0.8 迭代 21 反哺④残余落文行已入库而状态行未随批更替,本批补齐,事实零变更)。机制与数值零改动 | -| v0.10 | 2026-10-18 | **文档卫生批(用户令):死链清偿**——文头状态行尾句「实装待办在册 06-待办清单「锻造工坊实装批」条——开工门 = 17 裁点清零 + 用户发令,裁点门已满足」过期指路换代:该 06 条已随批次完成销号,状态行尾句改记入库事实(实装已随迭代 23 入库,2026-10-12,见 v0.7 行)。机制与数值零改动 | -| **v0.11** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:「钥石账本与营地柜台结构」→ 钥石与营地柜台结构——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/ux/battle.md b/design/gdd/ux/battle.md index b32095bb..8307ef6f 100644 --- a/design/gdd/ux/battle.md +++ b/design/gdd/ux/battle.md @@ -2,7 +2,7 @@ > **Status**: Complete — /ux-review 修订落稿(2026-09-12,blocking 7 项已修,待复检) > **Author**: user + ux-designer -> **Last Updated**: 2026-10-15(简明技术中文用语规范批:词面修正 30 处——见文末修订记录) +> **Last Updated**: 2026-10-15(简明技术中文用语规范批:词面修正 30 处) > **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` 同步——见 OQ11) > **Template**: UX Spec @@ -427,24 +427,3 @@ | 敌人系统资产下限 | 受击反馈/死亡表现/顺位标记 | §Transitions 受击 + §States 敌人死亡呈现(禁瞬消)+ §Component 顺位徽标;呈现语义在本 spec(同等 blocking),动画密度归战斗表现 | --- - -## 修订记录 - -| 日期 | 改动 | -|---|---| -| 2026-09-15 | 雾格残留清理:格态收窄为已开 / 未开两态(删除雾图变体状态行、四格态 AC 与已开雾格 tint / 雾区全开信号两条 AC);图例面板与 toast 槽去掉雾条目与雾首遇提示;BoardView 纹带、绘制优先级与色弱冗余改按通用变异纹带表述;`ux_hint_shown` 的 hint_id 枚举去掉 fog_first;输入义务与 §13 义务对照表去掉 地形变异×3 一项;目标感知示例与提示文案 OQ 措辞同步。本 spec 不装载被移除机制的呈现义务 | -| 2026-09-16 | 格面资源批 UI 欠账完成(随 2026-09-15 可选类道具删除的代码完成同步文档):① 布局四区化——删 E 区道具面板行、布局决策 2(道具窗口形态=右栏原位激活)整段删除(编号留空防交叉引用失锚)、ASCII 线框图重绘为 A/B/C/D 四区(D 区横向加宽 ~1036px)、A 区节点链示例改文字签槽实际渲染(战/赏/疗/王);② States 删道具窗口态与零库存空态(「道包空空」);③ 结算口径五段化(授予→增益/减益→战斗→衰减→判定)与明细行 10 类封闭协议(删 15 类行、四类行旧口径;「奖励未生效」行保留);④ 交互/动效/事件表删道具窗口行、跳过按钮、`ux_window_choice`、`submit_window_selection`;⑤ 数据源登记删 `query_inventory` 与窗口载荷,奖励身份按现行 `query_identity` 只读回调口径校正;⑥ 验收清单删窗口断言、五区改四区、未生效类行改现行两型(溢出未生效/奖励未生效);⑦ 关卡末清库反馈义务改载秘宝背包(随秘宝 P0 落地,本批不设计具体呈现);⑧ OQ7(道具窗口原位激活)删除、OQ 重编号,「囤刀待机」等旧可选类措辞清理。本 spec 不装载被删除机制的呈现义务 | -| 2026-09-20 | **敌人卡形态裁决完成(2026-09-20 用户看对照样张拍板,06 待办「敌人卡形态」解决移除——状态记录 99)**:全站桩形态定稿——① B 区主角与敌人均为无框立绘+底座(站桩式),**英雄卡/敌人卡组件整体退役,卡片式不再作为候选**;主角血条悬浮头顶、状态效果小图标一排挂血条正下方,敌人血条+顺位徽标悬浮头顶、状态小图标同款挂血条下;攻击值等规划数据仍归 C 区数据框(C 区不动);② 布局表 B 区行、Component Inventory 英雄卡/敌人卡两行随裁决改写(敌方 side 池共享层数各立绘同值、意图动画占位等既有语义平移到站桩载体,不随形态改变);③ ASCII 线框图 B 区重绘(旧"意图:爪击/环点"示意早已随行为环退役,本次一并清掉);④ OQ4 改写为裁决已完成注记,对照样张存档 `production/mockups/`;呈现义务细节重述(受击/退场演出挂点等)随表现层升级批执行 | -| 2026-09-23 | **停点前移批(冒险入口流程倒置修复,用户 2026-09-23 拍板;上位裁决 = 棋盘/战斗舞台 Node2D 迁移批(已执行完毕,git 历史可查),代码实装另批并行)**:① 布局四区 → 三区——删布局表 A 区关卡进度条行与 Component Inventory LevelStripView 行(LevelStripView 退役删除,节点链进度只留关卡画面,战斗屏零进度承载);C/D 底行 520 → 548;ASCII 线框图重绘为 B/C/D 三区;② 新流程口径写入文档——关卡画面(选路覆盖层常驻形态)为关卡内常驻枢纽:Navigation Position 图、到达语境、Entry 表、信息层级第 5 层、Data Requirements 节点图行改「关卡开始即出图选路、战后返回关卡画面再选路」;③ AC 四区措辞改三区。**批内代拍板三项已追认(2026-09-24 用户确认)**:① B/C/D 字母保持不重编;② 28px 纵向空间划归 C/D 底行(520 → 548);③ 关卡画面进度呈现由选路覆盖层节点态承载(暗金已过 / 金当前 / 亮金候选通道 / 旗朱 Boss)、不另设进度条组件 | -| 2026-09-23 | 实现注记(棋盘 Node2D 迁移批 Phase A,代码实装同批):棋盘渲染 Node2D 化(BoardView = Control 壳 + SubViewportContainer + SubViewport + Node2D 世界,信号/click_cell/_cells 契约保持,新增 push_input 端到端输入探针);格尺寸公式锚点不变(set_cell_area = floor((min(宽,高) − 预留 − (N−1)×格间距) / N) 单点可调),布局与交互语义零改动 | -| 2026-09-26 | 实现注记(战斗舞台 Node2D 迁移批 Phase B,代码实装同批):B 区战斗画面 Node2D 化(BattleStageView = Control 壳 + SubViewportContainer + SubViewport + Node2D 世界,站桩本体 StandeeBody 世界精灵;set_enemies/clear_enemies/on_step_row_fx/gray_all_enemies 等 setter 面签名保持,弹道落点锚点=壳层口径 world_to_shell 单点);状态图标行与悬停 tooltip 保留 Control 载体挂壳层;三区布局尺寸零改动(B 区外框 252px 逐位) | -| 2026-09-26 | **封印紫批**(用户拍板):插旗呈现色 旗朱 #C63D22 → 封印紫 #7C3AA8(色相 ≈267°,避开禁入带)——旗字形/已承诺封印框/旗化暴击弹道顺带换色;拒绝边框闪语义归危险红;Boss 节点描边归紫赤本色。修订记录历史行旗朱字样系当时口径留痕不改 | -| 2026-09-26 | **战斗屏信息归属批(用户 2026-09-26 三轮纠偏后拍板;代码实装另批——hero_info_panel_view.gd / hud_presenter.gd 改造 + 探针断言迁移,登记待办)**:立两条信息归属原则并全屏贯行——①循环口径原则(战斗屏只展小循环内被消费、影响当下决策的数据;中/大循环资源禁止入侵)②单一展示面原则(同一信息全屏唯一展示面;单位本体已承载的信息数据框不重复;资源数字贴唯一消费口)。随拍板落地:① B 区站桩 = HP 与状态效果唯一展示面——C 区 HP 条/HP 文字/立绘占位/状态效果槽×4 退役(重复展示;证据链 = hud_presenter.gd 同一 s.hero.hp/s.hero_effects 双投喂 B/C 两区);② RAP 读数(点阵+数字)迁 D 区 AP 条、置弃图刷新按钮旁(RAP 唯一消费口 = 弃图刷新——就近原则);③ C 区状态槽悬停 tooltip 职责并入 B 区站桩状态小图标;④ GP(中循环)/钥石(大循环)迁出战斗屏,去向挂 OQ14;⑤ C 区改「攻击数据框 + 秘宝槽(预留)+ 本关强化列表(预留)」——预留区来自秘宝与关卡内属性提升的既有立项;⑥ 空态/清零反馈/悬停交互/AC/§13 义务表载体同步改写。**批内遗留两项待拍板(OQ13/14)**:护甲 AC 是否补入 C 区数据框;GP/钥石去向 | -| 2026-09-26 | **信息归属二轮拍板(用户 2026-09-26,OQ13/14 完成)**:① 我方护甲 AC 补入 C 区攻击数据框(唯一展示面——布局表/组件清单/线框图同步);② GP/钥石去向定案:GP = 关卡画面常驻总量 + 战斗结算画面总量+增量,钥石 = 结算画面 + 营地(具体呈现归对应 UX spec 批次);③ 敌方 AC 展示面挂起——用户口径「敌方 AC 无任何展示」与现行代码冲突(standee_view.gd 底库名字行渲染「名字·护甲·AC%d」,系敌人技能池批克制对策可读性义务),证据链已呈报待终裁,本 spec 暂不改敌人站桩行 | -| 2026-09-26 | **敌方 AC 展示终裁完成(用户 2026-09-26 终裁)**:敌方 AC 数值全屏退役(任何区不直接展示)、护甲类型改图标方式展示(形状+色相双通道,终稿图标资产归美术批)、敌人站桩底座下名字行退回纯名字+护甲类型图标;旧「克制对策可读性义务」降级承载——类型保留、数值退役。终裁理由(用户口径):HP 信息已足够,攻防数值不直接写上;护甲类型图标保留克制对策可读性。同步改写:信息归属树敌人站桩行、Component Inventory 敌人站桩立绘行、OQ13。**代码实装说明**:`standee_view.gd` 改造(站桩名字行去 AC 数值 + 护甲类型图标化)由并行代码批执行,本批只做文档同步 | -| 2026-09-27 | **UX 文档欠账处置批(用户四项拍板:player-journey 不建 / accessibility 不另立改指 HUD框架 / node-reward 改挂秘宝内容重定批 / level-clear 建档 design/gdd/ux/level-clear.md)**:① 删 §Player Context ⚠️ player-journey 未建注记,OQ1 改完成注记;② §Accessibility 头、§Transitions 减动效行、OQ2 改指 HUD框架「可访问性基线」节 + 设置与本地化待设计清单 #1(tools/doc_link_known.txt 欠账行随之清空);③ 导航残留修正——§Navigation Position 图胜利分支、§Entry/Exit 离开表、§Interaction Map 胜利 overlay 行改按现行代码实态(胜利后返回关卡画面选路;节点覆盖层 = 关卡画面域、落地奖励/恢复节点时开出;胜利/失败 overlay 组件锚 battle_end_overlay.gd)——原「胜利 → 节点奖励/恢复覆盖层」系停点前移批前残留;④ OQ3 过期陈述更正(interaction-patterns.md 2026-09-12 已建成)、OQ8 改完成注记。本批只动文档面,代码零改动 | -| 2026-09-27 | 关卡画面 UX spec 建档联动(关卡画面 UX 批):§Navigation Position 上游屏/下游屏行挂 [level-map.md](level-map.md) 屏级 spec 指针——关卡画面(选路覆盖层常驻形态)的布局/组件/交互/状态规格自此有独立权威文档。零机制改动 | -| 2026-10-06 | **方案二·立绘定档与站桩落底排批(用户拍板;工作流程铁律 2026-10-06 = 讨论期只动文档,代码实装另批走 PRD→迭代)**:① B 区 252→270(演出 ≈1/3 屏)/ C 区 548→530(**棋盘 438×438 原尺寸不缩、格子不变**,压缩全部由面板空档吸收)——布局表 B/C/D 三行随改;② 站桩排式重排:**立绘→血条→状态 落底排**(全场血条对齐一线;血条嵌石板位、台缘线留作地面线、落影保留),原「血条悬浮头顶」退役(高盒下血条-立绘空洞,用户点名否决)——Component Inventory 主角/敌人站桩两行随改;③ 大体档(显示 >150px 级:drider/duergar_king)头部探出盒顶压光柱区,血条仍落底;意图徽标上移头顶上方(探顶档压胸);④ 空态行措辞随改;⑤ ASCII 线框图 B 区重绘。立绘八敌源档定档归 art-bible §8.2(v3.7)与 character-design.md §5.5(体量=生物体型修订) | -| 2026-10-09 | 文档正确性审查批(在役态对齐):①秘宝槽「已实装四槽两步交互/关卡域库存/清库义务载体 = 秘宝背包」过期——过渡形态随迭代 11①退役,现行 = 营地同调装配(四槽壳空槽占位,展示重接归装配面批次);②奇物列表「预留」改已实装(现行标题「特性」,迭代 9⑫+迭代 12 呈现补齐);③明细回看 overlay/入口/交互三处随 P-C7 退役订正(回看归「生涯」);④TunePanel 三处改调试浮窗(迭代 15①退役)+减动效开关 = 设置面(迭代 8④);⑤棋盘尺寸 N∈{10,12} 扩 {10,12,13,14}(第三关内容批);⑥OQ9 TunePanel 退役计划完成 | -| 2026-10-09 | 文档正确性审查批·独立复核(worktree docaudit-2026-10-09):Exit 表关卡结算行「无关卡域清库面」表述精确化——旧关卡域库存 treasure_inventory 经代码实证仍在(level_runner.gd:520 快照计数/battle_orchestrator.gd:745 consume),系投放渠道全退役后恒空的机械惰性承载,拆线归实装批;同调装配件不经此域的结论不变 | -| 2026-10-15 | **简明技术中文用语规范批(用户令,词面层)**:词面修正 30 处——不得×5→禁止(信息层级依据句/信息归属循环口径条/敌人意图映射目录注记〔键名禁作现行 enemy_id 引用〕/敌人死亡呈现行〔敌人系统资产下限〕/AC 效果行);收口×11→完成(C 区奇物列表批注〔含随批→顺带〕/布局表 B 区行/意图映射目录命名双轨注记/线框图头注 2026-09-20/OQ1/OQ2/OQ8/OQ9/OQ13 已终裁收口→已终裁完成/OQ14 已拍板收口→已拍板完成+「随 spec 命名收口退役」→「随 spec 命名完成退役」);buff×1→增益(胜利终局行微文案引句「我的增益哪去了」);台账×10→状态记录(Events 呈现订阅行/Data Requirements 三处/终局数据锚行/架构注记/更新触发注记/场景级测试头/§13 记法注/义务表战斗结算行与地图战斗资源行);随批×2→顺带(下游屏行/可挖域微光注记);Last Updated 同步本批。ambusher(伏击者)历史退役词留痕行一字未动 | diff --git a/design/gdd/ux/camp.md b/design/gdd/ux/camp.md index 3765da5b..03e7c433 100644 --- a/design/gdd/ux/camp.md +++ b/design/gdd/ux/camp.md @@ -1,6 +1,6 @@ # 营地覆盖层 UX spec(camp) -> 状态:v1.5(2026-10-15 简明技术中文用语规范批:文头状态行对齐版本历史——原标 v1.1 滞后,实态=v1.4 状态面板改名批补漏;spec 基线=2026-09-30 审计拍板点 4A 用户裁决落文〔乙案新建 ux spec+元进度配套更改〕;视觉终稿已随迭代 9 9A 段落码,本 spec 成文其呈现规则) +> 状态:v1.5(2026-10-15 简明技术中文用语规范批:文头状态行按实态订正;spec 基线=2026-09-30 审计拍板点 4A 用户裁决落文〔乙案新建 ux spec+元进度配套更改〕;视觉终稿已随迭代 9 9A 段落码,本 spec 成文其呈现规则) > 事实源:`game/presentation/views/camp_overlay_view.gd`(CampOverlay——9A 视觉终稿后实态) > 机制权威:[元进度](../systems/跨局循环/元进度.md)(营地三柜台/钥石/永久强化——营地=界面壳、机制主语=永久强化) > 相邻:[settlement-summary.md](settlement-summary.md)(最近冒险摘要数据同源)/ [level-map.md](level-map.md)(主菜单语境) @@ -21,7 +21,7 @@ ## 口径 - 呈现数据源 = MetaProgression 只读投影经组合根喂入;本层不持有系统资源、不算价。 -- 退役/封存件呈现语义已随旧目录整体退役消解(探宝罗盘/显影尘/地穴全图卷等状态行已删——迭代 22 旧 12 行删除后目录内零 deferred/retired 态,2026-10-12);历史语义见版本历史 v1.1。 +- 退役/封存件呈现语义已随旧目录整体退役消解(探宝罗盘/显影尘/地穴全图卷等状态行已删——迭代 22 旧 12 行删除后目录内零 deferred/retired 态,2026-10-12); - 双入口框架(主菜单入口+局内状态面板只读入口〔2026-10-13 由「暂停层」改名——游戏非实时无暂停语义〕)的需求面归元进度「解锁双入口框架」节;状态面板入口已实装(2026-10-06 迭代 17 卡③〔时名暂停层〕——实机目检待用户,06 登记条在册),其呈现面不归本 spec。 ## 秘宝匣柜台呈现细则(迭代 22 实装态,2026-10-12) @@ -33,15 +33,3 @@ - **空目录合法态**:白板档(12 件全未解锁)柜台零可装行=合法态非缺陷(装配面空目录断言 V18 在役)。 - **状态面板只读概览**:局内状态面板秘宝匣段=12 行只读清单(解锁态+装配态概览,零写入口——装配只在营地)。 - 机制权威=元进度/秘宝.md;本节只锁呈现规则。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v1.4 | 2026-10-13 | **状态面板改名批补漏(用户质询发现——原改名批漏扫本文件:批内 grep 路径误写 design/ux/〔不存在〕致假阴性「零命中」)**:正文两处换代(双入口框架句+秘宝匣段「状态面板只读概览」,均括注改名来历;版本历史行内旧名按历史记载保留)。机制零改动 | -| v1.0 | 2026-09-30 | 首版落文(审计拍板点 4A 裁决:乙案新建+元进度配套更改;9A 视觉终稿实态成文) | -| v1.1 | 2026-10-09 | 文档正确性审查批:①头注「M-3 迭代 9」前缀按里程碑口径删除只留「迭代 9」;②口径节「暂停层入口未实装(随 HUD 批 M-4)」过期订正——暂停层只读入口已实装(迭代 17 卡③,2026-10-06,实机目检待用户) | -| v1.2 | 2026-10-10 | 「道具工坊」改名「秘宝匣」扫改(2026-10-10 天赋树设计会话裁):定位句与三柜台列两处。机制零改动 | -| v1.3 | 2026-10-12 | **迭代 22 反哺落文批(实现报告 §三⑤,用户裁「落文」)**:新增「秘宝匣柜台呈现细则」节(购买钮禁用态/条件进度/名后缀·档位/装配行档位标签/未解锁禁装/悬停 desc/空目录合法态/暂停层 12 行只读概览);三柜台列秘宝匣行换代指路;退役/封存件呈现语义口径随旧目录删除消解(历史语义留版本历史)。机制零改动 | -| v1.5 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 0 处;文头状态行失同步修复——原标 v1.1〔2026-09-30〕滞后于版本历史最新行 v1.4〔2026-10-13 状态面板改名批补漏〕,本行对齐。机制零改动 | -| **v1.6** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:「只读账面」→ 只读读数;「零账本/不持有账本」→ 零系统资源写入/不持有系统资源——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/ux/interaction-patterns.md b/design/gdd/ux/interaction-patterns.md index b304c33b..f8c7e79e 100644 --- a/design/gdd/ux/interaction-patterns.md +++ b/design/gdd/ux/interaction-patterns.md @@ -2,7 +2,7 @@ > **Status**: Complete(核心 8 成文〔2 号已退役留档〕+ 12 目录占位) > **Author**: user + ux-designer -> **Last Updated**: 2026-10-15(简明技术中文用语规范批:词面修正 6 处,见文末修订记录) +> **Last Updated**: 2026-10-15(简明技术中文用语规范批:词面修正 6 处) > **Template**: Interaction Pattern Library > **来源**: `design/gdd/ux/battle.md`(2026-09-12 /ux-review APPROVED)已拍板内容的成文固化——本库不引入新设计决策 @@ -213,13 +213,3 @@ MVP 未使用标准控件(不入库):toggle / dropdown / input field / tab 2. Gamepad 批次引入时,需为 pattern 4/12/15 增补手柄映射节(焦点序已在 battle.md OQ8 留位) --- - -## 修订记录 - -| 日期 | 改动 | -|---|---| -| 2026-09-15 | 雾格残留清理:pattern 1 无改;pattern 4 的悬停预承诺消歧依据改按格态两态表述;目录 #10 一次性非模态提示的已实现说明去掉雾首遇、只留 chord 提示。pattern 库不引入新决策 | -| 2026-09-20 | 退役术语扫描批(用户拍板):pattern 2 原位窗口激活退役留档(唯一消费面轮末道具窗口随 2026-09-15 可选类道具删除下线——编号留空防交叉引用失锚,照 battle.md 布局决策 2 先例);pattern 8 禁用态即理由 Used In/Reference 去道具窗口引用(保留为通用模式);聚合纪律未生效类行枚举收敛为奖励未生效 | -| 2026-10-09 | 文档正确性审查批:pattern 8「Used In 现无消费面、消费面随秘宝 Alpha 重设计回归」过期订正——消费面在役 = 商店购买钮余额不足置灰、三选一/商店 GP 刷新钮余额不足禁用 | -| 2026-10-09 | 文档正确性审查批·独立复核(worktree docaudit-2026-10-09):目录 #19「库存常读列表」状态订正——所记载体 inventory_panel_view.gd 经 git 全史复核**从未入库**(「已实现」系失实登记),库存面已随秘宝过渡形态退役,状态改「占位失效」 | -| 2026-10-15 | **简明技术中文用语规范批(用户令,词面层)**:词面修正 6 处——不得×5→禁止(pattern 1 触发条/pattern 5 更新触发条/pattern 6 内容条/pattern 7 Description/pattern 偏差规则);随批×1→顺带(Open Questions 目录占位补全时点条);Last Updated 同步本批 | diff --git a/design/gdd/ux/level-clear.md b/design/gdd/ux/level-clear.md index f70902a0..b316aba3 100644 --- a/design/gdd/ux/level-clear.md +++ b/design/gdd/ux/level-clear.md @@ -120,15 +120,3 @@ 5. **替换子交互视觉形态——已随渠道退役**:秘宝件出池后本屏无道具件候选,替换子交互不于本屏触发(原功能性判据留档) --- - -## 修订记录 - -| 日期 | 改动 | -|---|---| -| 2026-09-27 | 初稿(UX 文档欠账处置批,用户拍板建档):义务锁定版——大奖励三件套/钥石入账/清库反馈预留成文;现行载体(_inter_overlay 与 BattleEndOverlay 复用)与代码锚如实登记;GP 归属两处登记不一致挂 OQ1,拍板前不新增 GP 呈现义务 | -| 2026-09-27 | GP 归属拍板对齐批(用户口径:战斗胜利→战斗总结结算展示获得资源〔目前 GP〕;战斗失败→冒险总结结算→确认回存档首页):OQ1 完成——GP 总量+增量归战斗胜利总结结算(battle.md OQ14 为准),本屏不承载 GP;OQ3 完成——「结算画面」指认 = 冒险总结结算,大奖励屏钥石进账 + 冒险总结结算明细两处并存维持;信息归属 GP 移入禁入清单;Data Requirements GP 行改零访问;06 归属行同步修正 | -| 2026-09-27 | 关卡画面 UX spec 建档联动:§Navigation Position 下游屏行挂 level-map.md 屏级 spec 指针。零机制改动 | -| 2026-10-01 | **三选一选择交互重写(迭代 10 奖励重构批——用户 2026-09-30 拍板案丙;T2 UX spec 卡)**:①Purpose/载体/导航/进出/层级/状态/交互/数据全节重写——「大奖励三件套快照展示」退役,改「部分回血反馈 + 提升三选一三卡点选 + 确认兑付 + 同调位替换子交互」;②钥石元素全屏退役(增量行迁战斗总结结算,禁入清单机检化);③交互范式 = choice_box 按钮族 + 选路两段式复用,零新增原语;④AC 五条改写 + 断点中断/减动效/禁入机检三条新增;⑤OQ3 改钥石三面化完成、OQ5 改替换子交互视觉归样张批 | -| 2026-10-09 | 文档正确性审查批(在役态对齐):①三选一候选订正——自迭代 15② 渠道分离起通关三选一 = 纯专长(原「六种池加权抽三」与秘宝件直显条款退役);②同调位替换子交互全节退役(秘宝件迭代 11① 出池后本屏无道具件候选);③过渡键 transitional_sync_slots 引用删除(同调位现行事实源 = attunement_growth.tres);④载体组件名订正 = curio_pick_overlay(与奖励节点共用面) | -| 2026-10-09 | 文档正确性审查批·独立复核(worktree docaudit-2026-10-09):Data Requirements 三候选行「加权洗牌掷 3」漏网旧口径清偿——冒险结构 v0.14 令牌池换代后 = 令牌池洗牌不放回抽 3(同 kind 去重),与冒险结构/关卡节点地图/node-reward 同口径 | -| 2026-10-15 | **简明技术中文用语规范批(用户令,词面层)**:词面修正 4 处——随批×2→顺带(Status 行目检清单交付/OQ4 实装后目检清单交付);收口×2→已完成(OQ1 GP 增量展示面归属/OQ3 钥石呈现三面化);文头 Last Updated 滞后对齐(原 2026-10-01 → 本批) | diff --git a/design/gdd/ux/level-map.md b/design/gdd/ux/level-map.md index b315a49c..3f62caec 100644 --- a/design/gdd/ux/level-map.md +++ b/design/gdd/ux/level-map.md @@ -236,15 +236,3 @@ | [art-bible](../../art/art-bible.md) | 方块地牢观感(§3.2 圆角方形世界侧)、色板冻结(§4.1)、半拟物(§7.1)、明度分层(§2,v3.0——状态不走明度、空间光照可走) | 图区组件 + Accessibility 对比条 | --- - -## 修订记录 - -| 日期 | 改动 | -|---|---| -| 2026-09-28 | **视觉终稿冻结批(M-2 迭代 4 T1–T4,闸形 A:样张 v1 机检 11/11 全绿即冻结)**:Status 升格定稿版;Layout 节点图区冻结值成文(画布公式 70+层×122+34 / 52+槽×58+26+8 下限 620×240、通道 2/3/4px、节点图标 ♻ kenney 五键 20px 烘焙+双色墨制、编号右上角);已过态 = GOLD_DONE #68562C 冻结新值(旧 GOLD_DIM 对双色墨 <4.5:1 逼守);Accessibility 增 Boss 深墨环灰度冗余+对比断言承载注记;States 换层进入改「淡入+换层色板渐变挂点(§2.7 切片档)」;组件清单节点图画布实现锚更新;OQ ④ 视觉终稿完成;线框图注记随改。产物:样张 `artwork/mockups/level-map-sheet-v1-2026-09-28.png` + 机检报告 git 提交 9a79927 + 出口闸检查单 `M2 出口检查单(已退役,git 历史可查)` | -| 2026-09-28 | **形态升格独立屏批(M-2 迭代 3 T1,用户裁决:独立存在为最终形态,覆盖层实现定性=测试阶段形态)**:Status/覆盖范围/到达方式/Navigation Position——「模态覆盖层形态(暗幕 0.6 底层透出)」全量改写为「独立屏独占呈现(战斗屏宿主整体隐藏,零透出)」;Layout 屏底=深底+石纹底噪(M-1 框材件);Transitions=独立屏淡入 200ms(alpha 淡入非明度变化——art-bible §2);AC「模态纪律」条改「独立性断言」(激活期战斗屏隐藏/选路提交战斗节点后恢复/兑付覆盖层关闭后本屏恢复);节点/商店覆盖层「本屏域内弹出」语义随形态明确(本屏保持激活,模态栈遮挡恢复语义复用);实现锚改名 level_map_screen.gd(RouteOverlay 退役);battle.md 三处选路覆盖层措辞随改;视觉终稿前置改指 M-2 迭代 4 关卡画面样张 | -| 2026-09-27 | 初稿(关卡画面 UX 批,用户拍板立项):占位升格版——信息层级五层/三分区布局/组件清单/三停点状态/交互与数据锚/AC 成文;停点标题措辞修正(清偿状态记录 143 遗留);GP 常驻徽章落地面(2026-09-26 二轮拍板去向,经 GP 归属拍板对齐批维持);三项提案挂 OQ(HP 常驻读数/图上直接点击选路/放弃二次确认)登记 06 待拍板;视觉终稿以表现层样张为前置。实现锚 = route_overlay.gd 程序化占位现行 | -| 2026-09-27 | **三拍板完成批(用户逐项裁决)**:① 底栏 = 状态展示——生命/属性(攻击·AC 有效值)/本关已选加成三组常读(原提案顶栏 HP 扩为底栏状态栏,布局决策 4);② 图上直接点击选路定稿——候选按钮整列退役、图上点击为唯一提交通道(布局决策 2;press_candidate 探针面随实装批改造注记);③ 放弃冒险二次确认定稿(布局决策 3)。信息层级六层重排/组件清单/States/交互表/Data Requirements(属性与加成读数入口)/AC/线框图随改;06 拍板点条目解决移除(去向 = 本批状态记录 204) | -| 2026-10-09 | 文档正确性审查批:States 减动效行「切片期 TunePanel」过期订正——减动效开关已转正设置面(迭代 8 卡④;TunePanel 随迭代 15 卡①退役) | -| 2026-10-09 | 文档正确性审查批·独立复核(worktree docaudit-2026-10-09):正文四处里程碑前缀按 2026-10-09 口径清偿——「M-2 迭代 4」三处删前缀只留「迭代 4」(Status 行/节点图画布实现锚/线框图注记);「M-1 框材组冻结件」改「迭代 2 框材组冻结件」(git 9abf5ff 实证框材组=M-1 迭代 2) | -| 2026-10-15 | **简明技术中文用语规范批(用户令,词面层)**:词面修正 6 处——收口×4→完成(Status 行三项提案拍板/顶栏语境行 HP 拍板注/Open Questions 两「已收口」头注→「已完成」);台账×2→状态记录(布局决策 1 清偿 143 遗留/AC 三停点标题条);Last Updated 同步本批 | diff --git a/design/gdd/ux/node-reward.md b/design/gdd/ux/node-reward.md index 8997061e..0cf03730 100644 --- a/design/gdd/ux/node-reward.md +++ b/design/gdd/ux/node-reward.md @@ -21,19 +21,3 @@ - **同库同池耗(v2.4)**:池=固定配额令牌库(普通 70/稀有 25/罕见 3=98 张;罕见档原列「道具件 2」随 aux_item 池种退役〔迭代 11 第①批 T7,落地晚于追认 b〕收窄——状态记录自决披露项);洗牌不放回抽 3(**同 kind 去重每 kind 至多一枚**——「三种不同选项」体验延续,kind 出现率∝剩余令牌数)、选中踢池未选回池、池耗即枯竭(余库不足出齐剩余,空库=零候选合法态直通);**种类次数上限退役**(池消耗即上限)。数值对:小GP 20/大GP 50、小增伤 +1/大 +2、小护甲 +1/大 +2、小生命 +5/大 +10、恢复 +6 当即回血(封顶生效上限)、AP +1。**MC 策略 316-f**:1 级优先度=最稀有(rarest>rare>common)、2 级=最左(并列同档取最左)。配额结构锚与档位构成读冒险表(schema validate 硬断言 70/25/3——见 `data/schemas/adventure_table.gd`)。**v2.3 第三渠道并账维持**:商店货架=同库付费渠道(令牌级货架,买一件=奖励面少一件),库存=剩余令牌数,账本语义与切边注记归[冒险结构](../systems/冒险循环/冒险结构.md)共享池账本节。 - ~~道具件入本关库存~~(v2.2 退役——秘宝局内不掉落机制道具,三轴 doctrine 锁死)。 - ~~「池空直通」合法态~~(v2.4 随令牌池换代退役又回归异形:旧口径=GP 无上限保证牌库恒非空;现口径=98 张池真可耗尽,空库=零候选直通合法态——池耗即枯竭既定后果)。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v1.0 | 2026-09-29 | 迭代 7 T5 随批出生(三选一构筑点形态——用户拍板②丙) | -| v2.0 | 2026-10-01 | **共享池改写(迭代 10 追加批——用户拍板「奖励节点与通关三选一相同、共享同一个池子」)**:①定位改提升三选一选择面(六种共享池、同权重同次数上限、同 reward_pick 流);②载体改 BonusPickOverlay 共用面(原 node_overlay 道具三选一面退役);③道具件满位升级为替换子交互两路(原过渡形态=满位不授予);④「池空直通」合法态退役(牌库恒非空);⑤道具件入本关库存(即时可用),区别于通关渠道的跨关携带 | -| v2.1 | 2026-10-01 | **掷定前置(目检反馈批——用户反馈「抽到秘宝不显示详情不直观」,推荐案获批)**:道具件具体道具随候选抽定(reward_pick 流序内挪,消费数不变),卡片直显「秘宝 / 道具名 · 效果摘要」;断点停点快照随载 aux_detail(续玩卡片详情不丢);node_bonus_candidates 返回扩 dict {candidates, aux_detail} | -| v2.2a | 2026-10-03 | **池种退役+刷新件面(迭代 11 第①批同调实施批 T7/T5b——P1 甲)**:①aux_item 池种退役出三选一牌库(BONUS_IDS 除名+权重/件数/掷定前置字段随批退役)——秘宝改走营地同调装配面(三轴 doctrine),v2.1 直显/满位替换两面随渠道退役(机械惰性承载零投放);②三选一刷新件面新增(X/Y 双源:刷新件每碰三选一重给优先消耗不结转+营地刷新升级冒险周期池;重抽消费 reward_pick 既有洗牌流池规则全保留;autoplay 默认不刷) | -| v2.2b | 2026-10-03 | **三档位令牌池(用户全裁——待 M-4 数值批实施,现行 v2.1 平铺池维持到实施)**:池改固定配额令牌池(普通 70/稀有 25/罕见 5=100 张;洗牌不放回抽 3、选中踢池未选回池、池耗即枯竭);档位构成=普通〔小GP 18/小增伤 18/小护甲 17/小生命 17〕+稀有〔大GP/大增伤/大护甲/大生命/恢复 各 5〕+罕见〔AP 3/道具 2〕;数值对 20/50、+1/+2、+1/+2、+5/+10、恢复+6、AP+1、道具 1 件;**种类次数上限退役**(池消耗即上限;同调位上限保留);恢复件=新入池种类;MC 策略改判 1 级最稀有/2 级最左(确定性)——设计全稿与执行口径见 [06 待办「奖励池三档位令牌池重设计」条](../06-待办清单.md);卡片呈现面(本 spec 交互节)零改动 | -| v2.3 | 2026-10-03 | **商店并账注记(迭代 11 第②批 GP 商店房重构批——P1 共享池)**:口径节「同池同上限」扩第三渠道=商店货架(pool 模式付费渠道,买一件=奖励面少一件;库存=上限即库存全冒险一次性);本 spec 交互面零改动(商店货架面归 shop.md 与 ShopOverlay,非三选一覆盖层);GP 袋对商店面切边(负交易)、奖励面照常(牌库恒非空结构保证不变) | -| v2.4 | 2026-10-03 | **令牌池落地(迭代 12 TP0——追认 b 实施批)**:三选一池改固定配额令牌池(普通 70/稀有 25/罕见 3=98 张;罕见档原列「道具件 2」随 aux_item 池种退役收窄——台账自决披露项);洗牌=令牌 Fisher-Yates 不放回抽 3 同 kind 去重每 kind 至多一枚、选中踢池未选回池、池耗即枯竭(空库=零候选直通合法态);种类次数上限退役;恢复件=新入池种类(rare 档 +6 当即回血);kind 词表扩 heal 六种;MC 策略 316-f 落地(1 级最稀有/2 级最左);货架=令牌级抽签(价格公式 tier-blind 维持批②裁定);断点扩键 bonus_deck(余库逐枚还原);现行基线锚=runsum_m4iter12_tp0_n20_20261003(normal 档配对读数同带) | -| v2.5 | 2026-10-09 | 文档正确性审查批(在役态对齐):①定位节「与通关三选一共享同一令牌池」过期——迭代 15② 渠道分离后通关三选一候选 = 纯专长,本面与商店货架同库(六种令牌池);②载体组件名订正 = CurioPickOverlay;③头部文案引文加注「与通关三选一同池」字样滞后于渠道分离(文案换代归内容批,已呈报) | -| v2.6 | 2026-10-09 | 文档正确性审查批·独立复核(worktree docaudit-2026-10-09):①定位节令牌池「六种」→**七种**(adventure_table.gd CURIO_KINDS 实测七类含 refresh——刷新件随迭代15② T6 入池,curio_quota_refresh_rare=2 在役;v2.5 修订漏登);②三选一刷新行补机制现行事实源指路与 X 源承载件换代注(旧目录「三选一刷新件」退役→新目录「刷新练习」——秘宝.md「三选一刷新双源」节) | -| —— | 2026-10-09 | v2.2 双行同号系历史登记,2026-10-09 卫生批加 a/b 后缀区分 | -| v2.7 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 1 处(口径节「同库同池耗」条「台账自决披露项」→「状态记录自决披露项」);头注状态行版本号随本行对齐 | diff --git a/design/gdd/ux/settlement-summary.md b/design/gdd/ux/settlement-summary.md index 1a2a0bd5..f3d298a4 100644 --- a/design/gdd/ux/settlement-summary.md +++ b/design/gdd/ux/settlement-summary.md @@ -34,13 +34,3 @@ - **GP / 钥石呈现分工**(battle.md OQ14 完成口径 + 迭代 10 扩):GP = 本 spec 战斗面(增量+总量)+ 关卡画面常驻总量;钥石 = 本 spec 战斗面(Boss/精英击杀增量行,迭代 10 起)+ 冒险面(收束明细)+ 营地存量。钥石多处并存系「进账时刻 / 收束明细 / 存量可用」不同义,不构成重复展示(level-clear.md OQ3 完成维持)。 - **失败面不呈战利品**:冒险总结结算不呈现 GP 增量(倒下即终语义,失败侧恒不呈现)。 - **禁重复展示**:本面不呈状态效果、不呈结算明细正文(明细回看 overlay 已随 P-C7 退役——冒险中明细回看归「生涯」)——[battle.md](battle.md) 信息归属两原则(循环限定 + 单一展示面)对面级呈现同样适用。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v1.0 | 2026-09-30 | 首版落文(审计拍板点 2 用户裁决:丙案两面分节 + 纯呈现轻量 spec——成文已实装显示规则,无新概念;命名三名并存收口为拍板文本口径) | -| v1.1 | 2026-10-01 | **钥石呈现接线批注记(迭代 10 奖励重构——呈现侧 spec 先行,实装随批)**:战斗面触发扩 Boss 胜利(钥石逐杀掉落增量行上战斗总结结算框——契约「钥石增量一面承载」推荐案)+ 呈现内容补钥石增量行;冒险面钥石明细口径改「本局逐杀 Boss 掉落合计」;GP/钥石分工口径三面化(战斗面增量/冒险面明细/营地存量)。原「Boss 胜利不经本面」退役 | -| v1.2 | 2026-10-09 | 文档正确性审查批:明细回看入口两处订正——已随 2026-10-04 P-C7 退役(冒险中回看归「生涯」;battle_end_overlay review_pressed 已退役在码),战斗面呈现内容与禁重复展示条同步 | -| v1.3 | 2026-10-15 | 简明技术中文用语规范(用户令):词面修正 8 处——台账×4→状态记录(定位节接线登记条/冒险面载体条「06 状态记录旧称」/命名清单③⑤);收口×4→完成(冒险面载体条「随本条完成」/命名清单头「历史变体收口清单」→「历史变体退役清单」/GP钥石分工条 OQ14 完成口径与 OQ3 完成维持);头注状态行版本号随本行对齐 | -| **v1.4** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:「钥石入账明细」→ 钥石写入明细——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/ux/shop.md b/design/gdd/ux/shop.md index 02e6fb9b..c656df57 100644 --- a/design/gdd/ux/shop.md +++ b/design/gdd/ux/shop.md @@ -20,11 +20,3 @@ - GP 余额读数 = runner 钱包投影(GP 归[冒险结构](../systems/冒险循环/冒险结构.md) GP 节);本层不作计算。 - 与关卡画面 GP 常驻徽章的关系:进店语境余额与选路常驻总量不同义(本层带购买语境),不构成重复展示——钥石「写入/存量」拆名逻辑同款。 - 购买确认交互:现行直接购买(无二次确认步);是否需破坏性确认异位(pattern 7)未裁决,本 spec 只登记现状不立新裁。 - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v1.0 | 2026-09-30 | 首版落文(审计拍板点 4B 裁决:甲+乙并行——编排面小节落关卡节点地图、呈现面独立成文) | -| v1.1 | 2026-10-09 | 文档正确性审查批(在役态对齐):商店现行 = pool 模式(令牌级货架与三选一同池六行,含回复与专长凭证;进店抽 3、买一件 = 池少一件货架重抽)+ GP 付费刷新(SR-1/MC-1 已落码)——原「三商品卡全陈列、无刷新」为 legacy 形态(shop=off 对照保留),定位/布局/口径三节订正 | -| **v1.2** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:「同一令牌账」→ 同一令牌库;「账本归冒险结构」→ GP 归冒险结构;「本层不算账」→ 本层不作计算——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/gdd/术语表.md b/design/gdd/术语表.md index 71736b20..7e816b21 100644 --- a/design/gdd/术语表.md +++ b/design/gdd/术语表.md @@ -115,7 +115,7 @@ ### B. 豁免条款(三类文本不改写) -1. **历史文本**:版本历史表已入库的行、git 提交说明、裁决记录中引用用户原话的句子——保留原用词,不按 A 表追改。 +1. **历史文本**:git 提交说明、裁决记录中引用用户原话的句子——保留原用词,不按 A 表追改。 2. **对照性文本**:「退役词对照」表本身、「原 ××」式更名记载、禁令引举句——旧词在这些位置是内容本身,不是残留。 3. **玩家可见专名与机制词**:按「对外命名纪律」节与各系统文档现行用语使用(标中/踩雷等机制词在文档内部照常用)。 @@ -145,23 +145,3 @@ | 危险格的对外风味 | **地下城陷阱 / 怪物巢穴**(巢穴仅限世界观风味层使用——产品名清巢者出处、美术纹样名;机制表述仍用危险格) | | 连锁展开的对外表达 | **坍塌显形**:挖穿薄壳、整片松动地面塌陷露出(00 篇巢穴隐喻轴定名;机制文档内部仍用连锁展开) | | 适用范围 | 全部对外命名:道具件名、显示名、UI 文案、成就与百科措辞(首例=专长 27 件第一版命名,[奇物](systems/冒险循环/奇物.md)基础件表 v3.15);封印/旗族与金币的禁令扩为**全库正文**(2026-10-18 用户裁)——机制文档内部一律用封印,无内部用语豁免 | - -## 版本历史 - -| 版本 | 日期 | 改动 | -|---|---|---| -| v1.0 | 2026-10-11 | 首版建立(用户令「做一个专用术语表,让读者查表阅读」):格与棋盘/资源与经济/秘宝系统/道具体系四节+退役词对照表;同批全库统一更名=危险格(原雷格/惩罚格)/整图(原板级)/专长凭证(原门票) | -| v1.1 | 2026-10-11 | **怪物巢穴类型概念退役批(用户裁「目前没有具体的怪物巢穴类型,全部改成危险格」)**:删怪物巢穴词条、危险格与旗/控制两行换代;世界观风味层的「巢穴」隐喻〔00-游戏概念巢穴隐喻轴,产品名清巢者出处〕与美术纹样名保留,机制文档零巢穴 | -| v1.2 | 2026-10-11 | **机制表述巢穴补扫收尾(用户裁无类型划分)**:行动经济/音频/敌人系统等机制文档「惊动巢穴/巢穴被控制」系表述全量换代危险格(惊动 4/标中 1/被控制 2);对照表补巢穴行 | -| v1.3 | 2026-10-11 | 秘宝目录修正批随批:新增「未知秘宝」词条(冒险拾取替换渠道,2026-10-11 用户裁) | -| v1.4 | 2026-10-11 | **正主/落籍全库扫尾批(用户令收尾)**:正主→现行事实源 130 行+落籍→已入库 79 行全库换代(39 文件 194 行;语境微调=权威文档/权威定义节/拼表制主选/入库注记等);雷格/惩罚格/板级/门票/工作日志五词终验零真残留(存量命中均系对照行/更名记载句/禁令引举等对照性文本);技能 SKILL.md 三件与记忆目录随批同扫 | -| v1.5 | 2026-10-11 | 拾取渠道废止批随批:删「未知秘宝」词条(用户终裁装配只在冒险开始前配置、冒险中零更换途径) | -| v1.6 | 2026-10-11 | **对外命名纪律节新增(用户令「对外命名不要有雷跟插旗相关名词」)**:禁「雷/插旗」字面入对外命名;插旗对外=封印、危险格对外风味=地下城陷阱/怪物巢穴(风味层巢穴除外);适用=件名/显示名/UI 文案/成就百科,机制文档内部用语不受限;首例=专长 27 件第一版命名(奇物.md v3.15 九件换代) | -| v1.7 | 2026-10-11 | **通关术语裁定(用户裁)**:通关=打通整局冒险、通过第 N 关=打通第 N 关卡,两词非同义;存量文档中「通关次数」指每关卡澄清(历史行不动,全库口径统一随术语执行批) | -| v1.8 | 2026-10-11 | 新增「开发流程」节两词条:逐需求点验收清单(req-card 技能 §7 三层结构核心名词)、测试方式两分法(能力验证走调试接口/体验验证用户目检)——需求卡片逻辑验收方法论批随批登记 | -| v1.9 | 2026-10-12 | **迭代 22 反哺落文批随迁**:秘宝系统节补「自动兑付」(2026-10-12 用户裁——手动积点兑换钮形态退役)与「真视使用计数」(vision_used 生涯计数域,信标网络解锁条件)两词条(本行原误编号 v1.2,2026-10-15 重排时更正,原 v1.9/v1.10 顺延为 v1.10/v1.11) | -| v1.10 | 2026-10-13 | **迭代 23 反哺落文批随迁**(实现报告 §五③「若需登记补登」经用户令落文):锻造工坊节新增「路线 id / 存档域键名」词条——六路线 id 与 forge_routes 域四键(levels/unlocked/weapon/armor),实现层词汇非玩家可见;玩家向术语零新增 | -| v1.11 | 2026-10-13 | 「道具」统称登记(用户立内部用语习惯):道具=秘宝/奇物/地图战斗资源三类的内部开发统称,可单说或组合(秘宝道具/奇物道具/专长道具/战斗资源道具),仅限开发内部、玩家可见面用各类正式名称;同批补登「地图战斗资源」词条(原「奖励道具经济」2026-09-16 更名后一直未入表) | -| v1.12 | 2026-10-15 | **用语规范节新立 + 简明技术中文用语规范批(用户令「全部 GDD 做语言规范并融合词表」)**:新立「用语规范」节=词面权威指向 STC 词表+已裁替换表 12 行(STC 词面 5 行〔对标/若干/不得/报错/buff〕+doc-conventions §4 流程动词 7 行)+豁免条款三类(历史文本/对照性文本/玩家可见专名);新词条:装板(装板期)/摇号、机能件/机制件、总线/抽屉(新「结算目标」节)、坍塌显形(对外命名纪律节);版本历史重排修复双 v1.2(详见 v1.9 行注) | -| v1.13 | 2026-10-18 | **设计文档术语刷新批(用户裁)**:金币退役(GP 是唯一正式命名,「金币」系 AI 噪音)、插旗退役(正式动作名=封印,全库统一)、旗概念退役(印记=封印印记)——三词入退役词对照表+机检词表(doc_term_audit.py);封印定性由「插旗的对外表达」更正为正式术语(非比喻);禁用字面从对外命名扩为全库;删「机制文档内部用语不受限」条款;旗/控制词条更名封印/控制;雷格/惩罚格存量正文补扫(2026-10-11 退役批残留) | -| **v1.14** | 2026-10-19 | **系统资源定名传导批(用户裁,承接 42d64ec2/17ef0180)**:节名「资源与经济」→「系统资源与经济」;新增「系统资源」「补给」词条;AP 去「次数资源」;「时沙挂账」→「时沙暂记」——跨文档引用一律「规范名+指路 01-核心循环「系统资源」节」,定义源单点。机制与数值零改动。 | diff --git a/design/research/Alpha未完成事项梳理-2026-10-13.md b/design/research/Alpha未完成事项梳理-2026-10-13.md index d4c6a7b6..a8d067c3 100644 --- a/design/research/Alpha未完成事项梳理-2026-10-13.md +++ b/design/research/Alpha未完成事项梳理-2026-10-13.md @@ -15,7 +15,7 @@ | J1 | 一 · 跨局循环:**锻造工坊 = 待做** | ✅ **已入库**(迭代 23,2026-10-12;实现报告已退役〔git 历史可考〕,合入 `52fdaf6`)。六路线行族在役、两轴所有权已移交、存档 v7 已落、工作间 UI 已实装。**残留 = 人闸**:实机目检工作间形态与购买交互([07](../gdd/07-体验验证清单.md) ㉒) | 08「Alpha 完成判据」里这一行其实已满足,不订正会白做一轮实装 | | J2 | 二 · 内容量:**锻造工坊路线行族 = `meta_forge.tres` = 待做** | 落表为 **`forge.tres`**(`ForgeTable`,六路线 sword/spear/staff/light/heavy/ward 在役);`meta_forge` 系 2026-10-12 立项时的**选型旧名**,从未落盘(`meta.tres` 的 `forge_products` 行族已随迭代 21 退役) | 表名错误会让后续按图索骥的人找不到表 | -> J1/J2 属**文档事实订正**,不是设计决策,不进 §三 的待裁清单——建议随本次讨论结论一并订正 08 版本历史。 +> J1/J2 属**文档事实订正**,不是设计决策,不进 §三 的待裁清单——建议随本次讨论结论一并订正 08 的 git 提交史。 另两条文档面欠账(不属游戏内容,仅登记):`gdd_lint` 表格占比存量 3 件(01/06/07)、`doc_term` 退役术语旗 1 件(06「拔旗回收返 AP」备选条目文字引用)。 @@ -316,7 +316,7 @@ | **F6-文档面** 商店刷新机制文档回写三处 | 直接做(冒险结构共享池账本节 / 关卡节点地图商店行 v1.6 / 06 本条收口核对) | 小 | 纯文档,不依赖 M4 调参 | | **H2** 类型色 `TG_*` 常量化 | 直接做:把内联 `Color8` 提为 `ui_kit` 常量并补第五族 aoe `#E25676`(与格面微光同族不同落点) | 小 | ui_kit + 两处消费点 | | **I14** 在途草稿整理 | **先 dry-run 呈报清单**,经确认再分批执行(按用户惯例) | 中 | 批量文件移动/删除,属个人目录高风险操作,必须 dry-run 先行 | -| **J1/J2** 08 两行订正 | 随本次结论一并改 | 小 | 08 版本历史 | +| **J1/J2** 08 两行订正 | 随本次结论一并改 | 小 | 08 的 git 提交史 | > 以上六条**都不是设计决策**,建议从讨论里摘出来直接排执行批。 diff --git a/design/research/提案-武器锻造系统-2026-10-07.md b/design/research/提案-武器锻造系统-2026-10-07.md index bd56cb6a..54174688 100644 --- a/design/research/提案-武器锻造系统-2026-10-07.md +++ b/design/research/提案-武器锻造系统-2026-10-07.md @@ -210,7 +210,7 @@ AC(护甲等级)单值现役生效(`hero.tres:9`=10;敌方攻击掷点 - **等级上限**:每件武器/每型甲各自封顶(provisional 锚点 = 5 级量级)。量纲理由:满级特效要"值得等",级数太多会稀释解锁节奏(与 F6 冲突)。终值归 M4。 - **定价结构**:沿用现役几何递增——每级价格 = 基础价 × 150%^(已购级数)(现役参数:单次 20 钥石、每级涨 150%,`meta.tres:11-24`;《元进度》定价曲线几何递增是已拍板条款)。甲型解锁 = 一次性解锁价(量纲 ≈ 中段几级锻造的花费,provisional)。全部终值归 M4。 -- **货币裁点(v1.1 重组——现役营地一切消费货币=钥石非金币,事实依据见文末修订记录)**: +- **货币裁点(v1.1 重组——现役营地一切消费货币=钥石非金币,事实依据见本文文末审查回写段)**: - **甲=纯钥石(推荐)**:与现役属性锻造/天赋树(2026-10-07 用户裁甲后树全钥石单币)/同调刷新升级同币同柜——原案语义是"攻击力提升改造",即同一笔钱换个花法,语义保真;零新经济面;Boss 击杀掉落产出与几何递增定价配套现成(`meta.tres:26-38`)。 - **乙=引入局外持久金币余额域**(金币入存档、可付营地消费):**淘汰依据**:须推翻两币分工拍板条款(《元进度》:"GP(金币)= 冒险内一次性属性提升货币——局内清零、不入存档……两币永不互兑",元进度.md:55)+ 新存档域 + 金币出口入账规则一套;与"金币无法带出冒险"(2026-10-07 用户判定)直接相逆。 - **丙=第三货币锻造币**(独立于钥石/金币的专用锻造币):**淘汰依据**:无产出渠道凭空造经济——产出渠道、兑换规则、存档域、呈现位全套新建,实装量三案最大。 @@ -311,7 +311,3 @@ AC(护甲等级)单值现役生效(`hero.tres:9`=10;敌方攻击掷点 每个裁点独立拍板,互不绑死(推荐列只是提案立场,不是打包方案)。裁决结果落 06-待办清单「武器锻造系统」专条与路线图卡③行;裁决通过后实装批另行立项,以本提案+裁决记录为需求卡片输入。 --- - -## 修订记录 - -- **v1.1(2026-10-07 盘问轮 S2 纠偏)——货币前提全案订正**。事实修正依据:现役营地一切消费货币=钥石(buy_forge→spend_keystone `meta_progression.gd:59`;树 tree_buy/tree_buy_fork 与刷新升级 buy_attune_refresh 同走 spend_keystone 钥石消费口);GP(显示名金币)=局内一次性货币,开局清零(`adventure_runner.gd:116`)、不入存档(save schema 无 gp 域),两币永不互兑(《元进度》两币分工拍板条款,元进度.md:55);金币无法支付营地柜台账(用户判定 2026-10-07)。错误根源=meta_tree.tres 脊柱行 gp 声明 + meta.tres 表尾陈旧注释「与 GP 商店同族」误导成文。订正面:〇节原案一注记、F1 事实行、裁点 4b 乙引文、裁点 5a 丙论据、裁点 5b 货币裁点整节重组(甲=纯钥石/乙=局外金币余额域/丙=第三货币锻造币)、裁点 5c 前提换钥石(甲=纯钥石零材料)、第九节定价行、第十节汇总表 5b-1/5c 行。配套实况:天赋树货币甲案同日修复(树全钥石单币落定,T8「GP 余额域缺位」双币骨架披露销账)。 diff --git a/design/research/测试审计-单测与验收门禁标准-2026-10-15.md b/design/research/测试审计-单测与验收门禁标准-2026-10-15.md index 118b839b..e247f126 100644 --- a/design/research/测试审计-单测与验收门禁标准-2026-10-15.md +++ b/design/research/测试审计-单测与验收门禁标准-2026-10-15.md @@ -342,11 +342,3 @@ active.md 只记「render_gate golden 0.00%(登记即结未重制)」—— 这份审计**找方向是准的**(术语倒挂、三处判定缺陷、L2 零承载,三条都是代码级确凿),但**证据硬度不够**——它是"读出来的结论",不是"跑出来的结论"。扭转方案的第一步必须是**先把 C 类结论全部坐实成 A 类**,否则后面所有改动都建立在我自己的推断上。 --- - -## 版本历史 - -- v1.0(2026-10-15):审计会话首版。范围 = 单测覆盖 + 验收门禁标准;未跑测,结论全出静态审计;缺口按 A–E 五级分档,§七为标准建议(待裁),§八列未决项。 -- v1.1(2026-10-15 同日,应「报告有什么可优化」问询):①§〇 加证据等级列,全文 ⚠ 标注 C 类结论;②补 §5.2b CI 注释漂移、§5.2c example_test 占位、§5.4 游离测量脚本台账、§5.5 golden 基线时效、§5.6 扫描域半数未落地;③§六 增 A-5 与 F 级(15/16/17);④新增 §九 自评十条 + 证据等级表。仍未跑测。 -- v1.2(2026-10-15 同日,应「CI 现在有用吗」问询):①§〇 加「CI 实态」行;②新增 §5.0(无远端、CI 从未执行、本地闸五件洞况表);③§一/§5.1 修正「smoke_all 不被执行」的错误表述(它本就在本地轻闸首项);④§九 自评补第 11 条(最大视角错误=未核实 CI 通不通电)。 -- v1.3(2026-10-15 同日,**用户裁「CI 没有用、后面也不用、不留死配置」后**):①`.github/workflows/` 全数删除(分支 `ci-removal-20261015`),全文 CI 表述改注为「已删除的历史状态」;②§5.3「本地重闸 vs CI」对比表作废、改为「本地闸是唯一门禁」;③§六 A-4/A-5 中 CI 项作废(保留 example_test 一件);④§七/§八 中 CI job 改名、Q2 作废;⑤架构事实源纪律:历史决策文档只作沿革引用、不回改;现行事实以 architecture.md 为准。 -- v1.4(2026-10-15 同日,用户裁「决策记录归 git commit log、不另存决策文档」后):七份历史决策文件已删(沿革归 git 历史),全文引用清除——原引用处改指 `design/dev/architecture/architecture.md`「测试与质量域」节;§5.6/Q1/时长预算等表述随清;结论本体零改动。 diff --git a/game/README.md b/game/README.md index b0fc56a9..6791086e 100644 --- a/game/README.md +++ b/game/README.md @@ -58,536 +58,4 @@ Godot_v4.7.2-stable_win64_console.exe --headless --path . --script res://smoke/a - **v2 追加**:LevelTable(线性节点链数据表)· C1-lite 关卡推进器 `level_runner.gd`(原 c1_level_runner,2026-09-11 领域命名批更名)(关卡域生命周期:共享 B4 关内延续 + HP 跨战斗携带 + 奖励/恢复节点兑付 + 关卡末清库)· Boss 遭遇行(Dmax=4)· 节点奖励 API(B4 `grant_node_active`)· **测试用角色数值调整板**(atk%/hp% 覆盖 + 批量模拟,模拟天赋树——正式侧归 C4) - **裁剪不变**:A5 / C1 路径分支选择(用户拍板线性)· C2–C4 / B5 战斗动画 / D3–D6 / A1 黄金向量与 F4 批量工具 / gdUnit · 注:标错惩罚(原 A2 OQ1)已于 2026-09-12 批上线(标空封印三选一确定性反噬:暴走 / 伏击 +2 层 / 失衡,坐标×板序号派生、不走随机流),本批(2026-09-15)已收编进现行文档,不再属裁剪项 -## 2026-09-11 可选类供给控制器(用户拍板批——修改记录) - -**背景**:供给控制器批前实测每关可选类 ≈24.8 件(≈18.5 把刀,刀总伤 ≈180 > Boss 130 HP)——"道具获取期望太高"定量坐实。用户重新定义三尺度指标并拍板实现: - -| 尺度 | 指标 | 实现机制 | -|---|---|---| -| 安全格 | 期望极小(全图摊平 < 0.01/格) | 可选类**退出格子权重池**——格子池只剩即时类四行 | -| 雷图 | ≈0.78/板 | 战斗首件保证 ÷ 每战板数(≈1.28)折算 | -| 战斗 | 期望 ≈1,**首件保证**:获取首件前每张新板必注入 1 件;之后按 **p0×decay^(j-1) 指数递减**(永不绝育) | `RewardSupplyController`(B4 私有组合件,战斗域计数) | - -**拍板四条 → 落点**:① 注入占比 小刀 60% / 精工短刀 30% / **治疗包 10%**(治疗资源宝贵)→ `reward.tres` active_inject 池;② **清图奖励改一次性高额伤害**(clear_knife 入库刀 → clear_blast instant_aoe 40,当场兑付全体存活敌,不入库、不占可选类供给——清图与供给脱钩);③ 注入选格**均匀随机**(雾格不加权);④ **指数递减**(active_p0=0.4 / active_decay=0.5 → 0.4/0.2/0.1/0.05…,RewardConfigTable 新参数,provisional 归 C3 标定)。 - -**实现结构**(对象封装——伪代码审阅后落地): - -- `core/reward_supply_controller.gd`(新):`notify_battle_start()`(计数清零)/ `should_inject(stream)`(j==0 恒真;否则 `randf < p0×decay^(j-1)`,取号经传入封闭流)/ `notify_granted()` / `granted_count()`。行值快照抗热重载;零自有随机数。 -- `B4RewardEconomy`(改造):`_supply` 组合件 · `notify_battle_start()`(B1.begin_battle 转发)· `roll_board` 重写(身份批即时类单遍 → 清图槽 → 注入判定/选格;旧 F5 草稿重 roll 循环删除)· `grant()` 挂钩 `notify_granted()`(**发放即获取**——预分配未挖到不计数;去重幂等天然防双计)· `supply_granted_count()` 观测面。 -- `B1BattleOrchestrator`:begin_battle 门序列增 `b4.notify_battle_start()`(编排唯一性不变)。 -- 表/护栏:RewardTable `POOL_TAGS` + `active_inject`;RewardConfigTable + `active_p0/active_decay`、k_dmg 1→0(F5 休眠);ConfigDB 跨表护栏更新(clear_no_value 含即时类 / no_damage_row 扫描全池活行 / 新增 inject_pool 护栏:非可选类拒绝 + 空池致命)。 - -**实测(N=200 板/深度,工具 reward_expectation.gd)**:注入 1.00 件/板(j=0,多件板 0)· 占比 小刀 59–65% / 精工 25–29% / 治疗包 7–17%(名义 60/30/10)· 格池零可选类泄漏 ✓。**实际获取期望**(level_monte_carlo「可选类/战」列,N=15——工具已退役,数据归档):基线 0.88 → +200% 攻击 0.68 件/战(低于分配保证 1.0 的机理 = 注入格均匀随机,落在残余格/速杀未挖区时该件不获取;战斗末无兜底补发——**是否加"战斗末 j==0 补发 1 件"待用户拍板**)。每关合计 ≈ 4.5–6.5 件(原 24.8)✓ 拍板目标达成。 - -**⚠️ 供给侧副作用(本轮扫描发现,待拍板)**:可选类退出格子池后,其 25% 概率质量被动流向即时类——攻防 buff 每格频率从 44% 升至 59%,基线通关率 55%→80%(N=15)、整关承伤 127→80:**难度不降反升方向反了**。即时类是"每格必有货"锁定设计下无法清空的(除非引入空白格 = 违反锁定事实)。候选杠杆:① 接受更快的 buff 节奏,敌 HP 曲线上调对冲(C3 主杠杆)② 下调 attack_up/defense_up 在即时池内的相对权重(压 buff 频率)③ buff 幅度下调(触碰 B3 表值)。 - -**正式侧义务**:B4 GDD「install 期 roll / F5」章节修订(F5 → 战斗首件保证语义)+ registry reward_table/reward_config 条目改写 + RewardConfigTable knob 登记(active_p0/active_decay)——接口漂移批随实现落位。 - -## 2026-09-12 轮内刷新(方案 A,用户拍板批——修改记录) - -**背景**:用户发现刷新实现(仅 Waiting 结算窗口受理)与设计预期不符——预期为**扫雷阶段遇到推理死路时,有剩余 AP 且 RAP 足够即可当场刷新继续挖**。影响分析(三方案对比 + 16 代码触点 + 8 文档 + 5 数值连锁)后用户拍板方案 A。 - -**拍板语义**:① Active 相位可刷(RAP ≥ 8 且本轮未达上限)→ 当场 retire+install 换新图,**轮次继续**:AP 保留不重置、相位不动、不触发结算(敌方时间税语义变更——GDD 修订义务);② Waiting 相位刷新保持现状(登记意图,exit_distribution 换图);③ **每轮兜底上限 2 次**(Active/Waiting 合计,`ActionEconomyTable.refresh_max_per_round = 2` 表值);④ RAP 来源不变(停手 1:1 转存)。 - -**实现落点**:A3 `request_refresh_active()`(仅扣 RAP,相位/AP 不动)· A2 `install_board/retire_board` 增 `during_round` 显式参数(Active 通道,其余相位守卫不变——fail-fast 保留)· B4 `query_full_snapshot()` · B1 `can_request_refresh()` 查询面 + `player_request_refresh()` 双相位重写 + `_refresh_used_this_round` 计数 + **facts 身份快照隔离**(缓冲期捕获身份快照、授予走快照——防旧图已挖格在轮末错拿新图同坐标身份;`_grant_cell` 增 snap_override)· 呈现层按钮"弃图刷新(RAP -8 · 每轮至多 2 次)"。 - -**核心实现难点(分析批未暴露)**:轮内换图后旧图已挖未结算格与新图**坐标重叠**——轮末授予 `b4.grant(cell)` 会错拿新图身份。解法 = facts 缓冲期用 `query_full_snapshot` 冻结身份,授予段直通快照(绕过现行 mapping/_granted,批次隔离;库存语义不变)。 - -**验证**:冒烟 88/88(+14 轮内刷新断言:当场换图/相位 AP 保留/RAP 扣减/上限拒绝/跨图 facts 完整兑现〔4 格跨三图快照授予〕/回放确定性)· 三探针全 PASS · 期望扫描与刷新前持平(80%/0.88——模拟策略不主动刷图,真人专用出口)。**调试教训**(规范 4.6 补充案例):蛆虫 HP 已调 24 而"18 未掉血"误判——排查数值问题先核对当前表值;GDScript lambda 对局部 int 按值捕获(计数器必须用容器)。 - -**正式侧义务(GDD/registry 修订清单)**:A3 GDD Rule 11(受理相位 Waiting → Active∪Waiting + 相位机表 + 时间税语义注记)· A2 GDD install 四不变式轮内场景 · B1 GDD 编排专章(轮内换图 + facts 快照协议)· B4 GDD E5/E6(query_full_snapshot/grant 快照直通)· game-concept 轮次流程 + "战斗:扫雷图 = 1:M"措辞(一轮跨多图新形态)· registry `action_economy`(refresh_max_per_round)· 数值连锁重跑(清图支配性条款⑤/获取期望——模拟不覆盖真人刷图行为,需 playtest 实测)。 - -**2026-09-15 补记(用户拍板)**:**Waiting(等待结算)相位刷新通道整体移除**——呈现层入口此前已按 OQ12 退役(2026-09-12 战斗屏批),本批拆除核心层残留:账本侧 Waiting 受理入口 `request_refresh()` 删除、编排侧 `can_request_refresh` 不再放行 Waiting、`player_request_refresh` 等待期登记意图分支删除、出口分发删除 `_refresh_used_this_waiting → new_board` 换图分支(非清图轮恒同图)、字段与诊断快照键同步移除。文档侧无需修订——[行动经济](../../design/gdd/systems/排雷循环/行动经济.md)只写挖掘期刷新、[战斗结算](../../design/gdd/systems/战斗循环/战斗结算.md)明文"非清图轮恒同图",拆完代码即双双收敛。冒烟断言改为"等待期刷新请求被拒且状态不变"。 - -**同批其它改动(口径读法)**:明细行协议 **13 类 → 15 类**(新增窗口打开锚行 `window_open`、窗口跳过锚行 `window_skip`,服务"窗口段恒在案"验收;单点定义见[战斗结算](../../design/gdd/systems/战斗循环/战斗结算.md));状态表 **四行 → 六行**(暴走 / 失衡两行随标错反噬批收编);达标判定回归**单一判据**(可推理率 ≥ 及格线);求解器禁读雷位真值。本文正文的 v1/v2 范围登记与各历史批条目保留当时陈述,计数以现行文档与代码为准。 - -## 2026-09-11 关卡扩展批 · 切片级偏差登记(实现期决策,正式化时须回 GDD/架构文档) - -1. **C1 线性推进器 provisional**:节点链来自 LevelTable(结构位 = 未来 C1 的数据承载面);路径分支/奖励点分布定稿权归 C1/C3。节点类型 closed enum {battle, reward, rest, boss};末节点必须 Boss(LevelTable schema 校验)。 -2. **B4 新增 `grant_node_active()`**(接口漂移):关卡奖励点在可选类活行 {damage_item, heal_pack} 中 roll 一件直接入库;消耗 `reward_roll` 恰一 scope(与 board install 批同流异 scope,流集合封闭不变)。正式侧应走 B4 GDD 修订(节点奖励 = clear_reward 插槽族的新来源候选)。 -3. **B2 spawn max_hp 语义修复**(切片 bug):原实现 `max_hp = hero_hp 入参`——跨战斗携带 HP 时 max_hp 被压扁成当前 HP,恢复点/治疗包满血守卫失效。修复为 `max_hp = HeroTable.max_hp`(接口语义澄清,正式侧回 B2 GDD Rule 注记)。 -4. **A4 迷雾纪律遵守**:L1 全程无雾(迷雾 `unlock_level=2` 已锁事实——迷雾自第二层解锁);Boss 板以 12×12 大板区分。 -5. **属性覆盖 = 测试专用**:调整板直接写运行时 HeroTable(atk 域 [1,999] 内 clamp ≥1);关卡结束/回菜单恢复基线。正式天赋树归 C4,禁止生产代码引用本机制。 -6. **UI 复用 b1 引用**:关卡模式下呈现层 `b1 = runner.b1`(与调试模式共用 HUD/棋盘路径);runner 在关卡结束置 `b1 = null`。 -7. **runner 信号时序(playtest 缺陷①修复登记)**:`node_entered` 必须先于 `begin_battle` 发出——后发时首板安装的 `board_changed` 到达呈现层时 `b1` 尚未接手,首战棋盘不渲染。场景级探针 `smoke/ui_probe.tscn` 为该缺陷的回归断言载体。 -8. **A2 封印动作末点 AP 软锁(playtest 缺陷②修复登记——A2 核心 bug,v1 即存在)**:`_do_seal_place/_do_seal_pull` 花完末点 AP 后 A3 相位翻 Waiting 但不发 round_end——B1 的 Waiting 结算点依赖 round_end 到达,事件缺席 = 整局软锁(Boss 图封印多,末点 AP 花在封印上即触发)。修复 = 封印动作检查相位翻转并补发 `_emit_round_end_seals_and_payload()`(与 `_do_dig` 同款)。v1 冒烟盲区根源:自动玩家不用封印。回归断言入 smoke_all(封印动作耗尽 AP 必须进入第 2 轮)+ 行为探针 `smoke/ui_click_probe.tscn`(合成鼠标事件走真实 UI 路径,随机混合封印/撤封印/停手/窗口刷新/无效点击,4 种子全关通扫)。**正式侧义务**:A2 GDD F4 事件序契约须补"封印动作路径的 round_end 发射"措辞(接口漂移)。 -9. **呈现层固定分区(playtest 缺陷③修复登记)**:侧栏全部动态区(RAP/敌人/增益/库存/悬停状态)固定槽高 + `clip_contents`——悬停文案切换与库存增长不再推挤整体布局(此前"第 N 轮"库存行被挤出视口 + 全 UI 抖动)。区域独立,超长裁剪不回流。 -10. **L1 12×12 板生成余量**:D2–D4(及 L2)`max_gen_attempts` 16→24(F2c 24×144=3456 ≤ 16384 合法)——16 次尝试下偶发"重试耗尽接受最优"(best≈0.85–0.87 < target 0.88);24 次后仍偶发(best 0.866),密度×推理率的根本解归 C3。 -11. **道具使用后不消失(playtest 缺陷④修复登记——UI 层契约违例)**:B1 窗口选择契约 = `_window_items` **位置**(义务④"选定序"),UI 选用按钮却传 `item.index`(库存数组句柄)——未消耗过时二者巧合相等;一旦消耗过一件,已耗条目仍占库存数组位,后续窗口条目"句柄 = 位置 + 已耗数"错位 → 选中件不消耗、邻件被误耗(可用次数语义本身存在且正确:`use()` 一次性标记 Used 不可逆)。修复 = UI/行为探针一律传窗口位置;探针加"选用必生效"断言(选用件库存态变 Used,失效即退出码非零)。 -12. **数值调整板被遮挡不可见(playtest 缺陷⑤修复登记 + 专属测试补建)**:调整板覆盖层在场景树中位于**不透明的开始覆盖层之前**,`_show_tune_panel` 只置 visible 不隐藏开始层 → 面板被完全遮住 = "点击无反应"。修复 = 打开隐藏开始层 / 关闭(含"应用并关闭")恢复。**专属测试**:`smoke/ui_tune_probe.tscn`(场景级全链路:打开可见性〔缺陷⑤回归〕/ 滑条→生效预览联动 / 应用写 hero 表 12/75 / 重置回基线 6/50 / 批量模拟 N=10 全链路〔与 headless 扫描同口径〕/ 关闭回开始界面 / 加成跨模式持久)。 -13. **呈现层模块化重构(2026-09-11 用户批——"上帝对象"拆分)**:`main.gd` 随功能追加长成 ~1100 行上帝对象(棋盘渲染/HUD/日志/四种覆盖层/调整板/模拟器/关卡流程全糊在一个类)。拆分为 **9 个单一职责单元**(总行数不变,最大单类 433 行):`views/board_view.gd`(棋盘渲染+输入意图翻译,动作经信号外发)· `views/hud_view.gd`(侧栏纯视图,setter+定长槽)· `hud_presenter.gd`(核心状态→文案装配,MVP 静态装配器)· `views/battle_log_view.gd`(13 类行协议格式化)· `views/item_window_overlay.gd`(窗口,选择=位置语义收口)· `views/node_overlay.gd` · `views/level_strip_view.gd` · `views/tune_panel.gd`(调整板自持加成语义+批量模拟)· `views/ui_kit.gd`(共享小部件)。**组合根纪律**:main.gd(433 行)= 模式流转 + 信号接线,核心写调用(settle_batch/submit_window_selection/runner 推进)只在此处发生;视图零核心写、装配器无状态。**回归验证**:冒烟 74/74 + ui_probe/ui_tune_probe PASS + 行为探针 2 种子(通关 + 选用生效 1/2 失效 0)。 - -## 切片调参登记 v2(2026-09-12 起已由 C3 GDD 转正为 MVP 默认曲线——下方登记保留作溯源) - -**EnemyTable L1 深度轴(D0–D4,Boss=Dmax=4——A1 第三轴登记约定)**,设计意图 = 基线难、天赋拉回可玩带: - -| 节点 | 行 | 敌种×数量 | hp | atk | 环 | -|---|---|---|---|---|---| -| 战1 | (1,0) | 蛆虫×1 | 24 | 4 | [attack] | -| 战2 | (1,1) | 蛆虫群×2 | 24 | 4 | [attack] | -| 战3 | (1,2) | 伏击兽×1 | 36 | 6 | [attack,charge,heavy] | -| 战4 | (1,3) | 伏击兽群×2 | 26 | 4 | [attack,charge,heavy] | -| Boss | (1,4) | 遗迹守卫×1 | 130 | 7 | [attack,attack,charge,heavy] | - -首版(敌 HP 总量 208:18/36/26/40/88)实测**基线通关率 73%**——预警⑥速杀退化在关卡尺度依旧成立,与"基线非常难"意图相反;v2 上调至 290(24/48/36/52/130)+ Boss atk 7。**群战对价**:unit_count=2 行单位 hp/atk 下调(B1 条款③满配语境约束;C3 正式调参须按 clause3_supply 复算——registry 已登记 unit_count>1 行须降密度或降 m_amb)。 - -**BoardGenTable L1 深度行**:D0/D1 = 10×10、D2/D3/D4 = 12×12,全部 d0.25/t0.88。**登记**:d0.28/t0.87 首测**不达标**(best≈0.805–0.817,降级告警"接受最优出图")——密度轴上调与求解器能力一起解,留给 C3。 - -**奖励获取期望实测(问题2 汇报批,工具 `smoke/reward_expectation.gd`,N=200 板/深度,走真实 B4 roll 管线含 F5 保底条件化)**: - -| 深度 | 板面 | 资格格均(min/max) | 可选类/板 均 | 其中刀 | 治疗包 | -|---|---|---|---|---|---| -| D0 | 10×10 | 12.4(1/36) | 3.32 | 2.57 | 0.75 | -| D1 | 10×10 | 11.1(2/32) | 3.00 | 2.40 | 0.60 | -| D2 | 12×12 | 22.8(4/63) | 5.70 | 4.42 | 1.27 | -| D3 | 12×12 | 23.8(5/61) | 5.87 | 4.55 | 1.31 | -| D4 | 12×12 | 24.1(6/64) | 5.87 | 4.54 | 1.33 | - -**公式**:每资格格 P(可选类) = 25/100 = 25%(小刀 15% / 精工短刀 4% / 治疗包 6%);每板期望 ≈ 25%×|资格格| + F5 保底条件化加成(k_dmg=1 整批重 roll 至少 1 刀——12×12 板无刀概率 0.81²³<1%,加成可忽略;10×10 板 ≈+0.2);清图奖励 clear_knife 仅真清图兑付(理性策略不整清 ≈0);完美排雷 ×2 条件苛刻不计基线;**节点奖励恒为 1 件可选类**。 - -**每关合计 ≈ 23.8(板)+ 1(节点奖励)≈ 24.8 件可选类**(≈18.5 把刀 + ≈5.3 治疗包)——刀总伤 ≈180,超过 Boss 单体 130 HP。**用户"道具获取期望太高"的定量坐实**:关内不清库(2026-09-11 裁决③)× 每格必有货(B4 锁定)× 12×12 深板资格格翻倍,三者相乘。**候选杠杆(全部 C3 所有权,等拍板再动)**:① 可选类占比 25%→8–12%(改 knife_t1/knife_adv/heal_pack 权重)② 敌 HP 曲线上调对冲 ③ 刀伤下调 ④ 库存上限(触碰 B4 E 节结构,需修订)。 - -**期望扫描数据(N=20/格,种子 4200+20,工具 level_monte_carlo.gd;理性玩家策略近似)**: - -| atk% / hp% | 通关率 | 整关承伤 均/p90 | 通关剩余HP均(胜) | 进BossHP均 | 平均轮数 | 败北节点分布 | -|---|---|---|---|---|---|---| -| +0 / +0(基线) | **55%** | 126.8 / 190 | 33.1 | 44.6 | 18.4 | 蛆虫群×4 · 伏击兽×2 · 伏击兽群×3 | -| +0 / +100 | 100% | 165.8 / 219 | 61.5 | 88.7 | 26.1 | — | -| +50 / +0 | 70% | 109.8 / 155 | 27.1 | 45.5 | 17.1 | 分散(含 Boss×1) | -| +100 / +0 | **100%** | 96.3 / 121 | 33.5 | 47.4 | 17.4 | — | -| +200 / +0 | 95% | 61.1 / 99 | 36.6 | 49.0 | 12.9 | 伏击兽群×1 | - -读法:**基线=明显吃紧(55%,死亡集中在前中期群战)→ 攻击+100% 即满通关带**;HP 翻倍是独立有效的第二杠杆(战斗拖长 → 承伤期望上涨 165 但预算翻倍)。v1 敌数值(HP 208)时基线通关 73%——预警⑥速杀退化在关卡尺度坐实,v2(HP 290)压到 55%。注意:模拟者 = 理性策略近似(免费链式开格、无避雷推理),真人基线通关率应显著低于 55%——**目标带定在哪儿(30%?10%?)待 playtest 拍板,杠杆 = EnemyTable hp/atk 深度曲线(C3)**。 - -## 已知热点(playtest 观察项) - -- **基线难度体感**:基线(无面板加成)应"明显吃紧、可能打不过";如果基线就能轻松通关 → 敌数值仍偏弱(找 C3 杠杆:EnemyTable hp/atk 曲线);如果 +100% 攻击还打不过 → 奖励供给或恢复点数值偏弱。 -- **奖励点随机主动道具的体感**:roll 池 = 小刀 8 / 精工短刀 16 / 治疗包 12(等权);到手的刀是否改变了 Boss 战规划(囤刀 vs 即用)。 -- **恢复点(30% max_hp)时机**:位于战4 与 Boss 之间——是否制造"要不要省治疗包给 Boss"的决策。 -- **Boss 战节拍**:遗迹守卫环 [attack,attack,charge,heavy]——蓄力拍是否被玩家用作"安全挖掘拍";重击 14 点是否构成规划压力。 -- 节点进度条/奖励恢复覆盖层可读性;v1 遗留观测项(结算逐行归因、完美排雷可达性)继续有效(原"雾池体感"一项随雾格移除作废)。 - -## L2 试玩采集清单(分支节点图批 2026-09-17——关卡 2「幽暗地域」试玩观测项) - -入口:「开始冒险」主入口推进到第二关段(单关测试直入口已退役——2026-09-23 用户拍板,唯一试玩入口 = 完整三关冒险;种子框同用)。 - -- **选路行为**:战斗胜利/兑付确认后弹出选路覆盖层(整图 + 候选按钮)——玩家是否理解"零自动推进、每跳都要选";单候选节点(恢复点→编号 6)是否被读成"卡住"。 -- **岔路使用率**:四处真实岔路的走向分布(入口 0→[1,2];战斗 1→[3,4];奖励 2→[4,5];深层 4→[6,7])——奖励点路线 vs 纯战斗路线的选择比例;整图渲染是否被实际用来规划(对比只点按钮的玩家)。 -- **新敌种可读性**:熊地精(突刺/重击池)的意图可读性;巨蜘蛛群行(2–3 只)的数量压力体感;蛛化卓尔精灵 Boss 的毒爆(×2.5)与重击(×2.0)是否构成规划差异(对照关卡 1 酋长的硬化池)。 -- **顶栏图条**:图形态行进序列(已过暗金 → 当前金 → 候选亮边)是否足以反映位置;编号显示(节点编号 = 关内地址)是否被理解。 -- **数值读数参照**(provisional,N=20 双策略扫描 2026-09-17):基线裸值通关 0%(死因集中 Boss×16);hp+100% 档 35% → atk+150%/hp+100% 档 80%——真人试玩体感与读数的偏差即试玩采集的主要增量。 - -## 2026-09-11 用户拍板(四条,已落地本切片) - -| # | 拍板 | 切片实现落点 | -|---|---|---| -| ① | 基础攻击恒存在:atk 域 [1,999]、0 拒绝加载、MVP=6;战斗段主角先手攻击顺位最前敌,attack_up 唯一吃修正 | `hero.tres` atk=6 · `hero_table.gd` 域校验 · B1 战斗段⓪先手(`hero_attack` 行);attack_up 经 `effect_pool_map → hero_offense` 活行 | -| ② | 奖励两类:即时 75%(当场兑付不进库存)/ 可选 25%(刀/治疗包入库走窗口);heal_pack 稀缺化 w6 p12 | `reward.tres` 行集 w75/25;B1 `_resolve_instant` | -| ③ | 库存关内延续:跨战斗不清,关卡末 level_clear 清空 | B1 `_battle_over` 不清库;v2 起由 C1 runner 在关卡末统一调用 | -| ④ | 道具窗口至多选一件 | B1 `submit_window_selection` 截断 `slice(0, 1)` | - -**文档对齐**:四条拍板的 GDD/registry 回写已由文档会话先行完成(b1/b2/b4 GDD、registry、systems-index、d2、game-concept、b3);本切片程序与文档逐项对齐核查通过(详见 session-state 条目 16)。语义注:本切片为参考实现,与文档冲突以 GDD/registry 为准。 - - -## 2026-09-12 试玩日志器 + 诊断转储(playtest 数据采集基建) - -**新增**:① **`PlaytestLogger`**(呈现层组件)——订阅 B1 新信号 `settlement_snapshot`(每结算末尾全量状态:关卡/深度/轮次/verdict/英雄/敌人/行动经济/板序号统计/buff/库存/本轮 facts)+ battle_finished/node_entered/level_finished,逐行写 **JSONL**:`user://logs/playtest__<时间戳>.jsonl`(每行一个完整状态,直接可喂 pandas);② **诊断转储按钮**(侧栏底部"🩺 诊断转储")——卡死时点击,全量核心状态(B1 相位机/计数器/facts、A2 棋盘、A3、B4、runner)+ 最近 200 结算行/100 操作环形缓冲 → `user://logs/diag_*.json`(行为探针 _dump_state 的产品化)。 - -**顺手修复(日志首秀即抓真 bug)**:_start_full_level 面板加成**双写叠加**——tune_panel.apply() 先写表(6→18),runner.set_hero_override 再以 18 为基线 ×3(→54)。修复 = 关卡模式单一应用路径(runner 写表),日志快照 atk 54→18 证实。**教训(规范 5.x 补充案例)**:同一加成的多应用路径必须单一事实源;JSONL 快照是数值回归的最低成本探测器。 - -**冒烟 103/103**(+7:快照信号/字段齐备/板序号/JSONL 解析/诊断文件)。日志目录:`%APPDATA%/Godot/app_userdata/DungeonSweeperVerticalSlice/logs/`。 - -## 2026-09-12 C3 GDD 落地 + 试玩采集清单 - -**落地**:C3 GDD(`design/gdd/c3-difficulty-curve.md`,solo 出稿未评审)的设计承诺落回切片——① **DifficultyTable 结构位**(schema + 空表 + ConfigDB 挂载 + B2.spawn 套乘钩子:行值快照前施加、越域 clamp 至 [0.1,10];MVP 空表零行为——AC-10 冒烟断言含注入/越域验证);② 切片调参登记(敌深度轴/板参数/供给参数)**转正为 MVP 默认曲线**——切片当前数值 = C3 GDD 背书的设计态,试玩即体验 C3 定稿难度。冒烟 96/96。 - -**试玩数据采集清单(反哺 C3 六个 OQ——试玩时请记录)**: -1. **OQ3 真人修正系数(首要)**:你无面板加成打第一关的通关/败北结果(模拟基线 80% 通关——真人预期显著更低,落差就是修正系数)。 -2. **OQ2 Boss 血量**:Boss 战实际打了多少轮、是否觉得血量压迫合理还是拖沓(模拟值 130HP 占比 0.81 越带)。 -3. **OQ6 轮内刷新**:你实际用了几次"弃图刷新"、是否觉得"挖-刷-挖"太顺滑(免结算=敌人不出手)。 -4. **OQ4 弃图倾向**:有没有"挖一半就想弃图刷 RAP"的冲动(模拟测不到真人策略)。 -5. **难度台阶可感知性**:D2 伏击兽/D4 Boss 相比 D0 蛆虫的变强是否有具体面孔(新敌种=新图像线索)。 -6. **奖励供给体感**:可选类道具(刀/治疗包)获取频率与囤积感受(供给控制器批后每关 ≈4.5–6.5 件)。 - -试玩方式:F5 → 「▶ 开始冒险」基线打一局(一条命三关连探——冒险结构实现批 2026-09-21 起,第一关读数即冒险首关) → 调整板 +100% 攻击再打一局(对照"数值提升→通关期望改善"的元进度体感)。 - - -## 2026-09-12 试玩批次 1 → v3 数值批(F7 流程实践) - -**试玩反馈(v2 数值)**:满血全通关(三策略均通)/ Boss 血量 OK 或可上调 / 刷新零使用 / 零弃图倾向 / 治疗包零使用 / DND 命名指令(地精/熊地精/食人魔酋长)。 - -**v3 数值批**:atk 4/4/6/4/7 → **7/5/9/6/9**(承伤主杠杆);D0 goblin 24 保持(20 会被首轮粉尘秒杀——冒烟封印回归断言抓获)、D1 群 13×2、D2 bugbear 40/9、D3 群 26×2、**Boss ogre_chief 150/9**(用户拍板可上调);L2 锚行同步。**DND 命名**:goblin 地精 → bugbear 熊地精(DND 原型即伏击手)→ ogre_chief 食人魔酋长;enemy_id 同步更名。 - -**v3 扫描对照 F5**:基线 **60%**(带 40–60% 上沿 ✓,v2 80%)· 败北 4/6 集中 Boss(压迫预期兑现)· +50%→87% / +100%→93% / +200%→100%(天赋曲线成立)· 承伤 90(v2 80)。C3 GDD 回写:F3 带 [0.5,1.1](OQ2 裁决)、OQ2/3/4/6 试玩读数、试玩批次记录。 - -**冒烟 103/103**(封印回归断言改用 Boss 行——D0 20HP 级被盲挖粉尘秒杀无法承载场景;DifficultyTable 断言对齐 v3 行值)。**下一批 = v3 真人试玩**(OQ3 定量/OQ2 终裁)。 - -## 2026-09-12 遭遇随机化(Roguelike 局感引入批——Peglin 对比报告落地项) - -**触发**:用户试玩反馈"关卡完全没有 Roguelike 的体现"→ Peglin 对比报告(`design/research/peglin-comparison-2026-09-12.md`)→ 用户拍板先做遭遇随机化(节点分支/多波/遗物协同后置)。 - -**设计**(C3 GDD Core Rule 8):EnemyTable 行 `unit_count` 升级为**区间语义** `[unit_count, unit_count_max]`(新字段可省略=定值,旧行零迁移);B1.begin_battle 实例化期按区间均匀骰,**RngService 新增 `encounter` 封闭流**(registry 接口漂移登记——挖掘决策域之外 P1 合规);**B2 零随机纪律保持**(spawn 收 override 即确定值);同种子全程可回放;新敌种首遇节点固定数量(教学位不加骰)。 - -**L1 区间**:地精 [1,2] · 地精一伙 [2,3](hp 13)· 熊地精固定(教学位)· 熊地精双雄 [2,3](hp 18)· Boss 固定——期望总量 ≈304(+8%),F6 带内。 - -**扫描(N=15)**:基线通关 **47%**(区间期望总量上移 +8% 的叠加效应——F5 带 40-60% 带内 ✓);+50% → 67%;败北分散(Boss×3/战1×4/战3×1)。**注意**:区间骰使难度分布更宽(运气成分进入遭遇层——Roguelike 体的核心),真人体感待批次 2。 - -**冒烟 149/149**(+46:区间双值出现/全域内/同种子可回放/D2 教学位固定)。 - -## 2026-09-12 试玩批次 1 → v3 数值批(F7 流程实践) - -## 2026-09-12 攻击类型 × 护甲克制批(用户拍板——三段伤害 + 标错惩罚落地) - -**触发**:设计会话(本日)定稿"怪物护甲类型(轻甲/魔法护甲/重甲)× 角色伤害三段构成(普通/穿刺/魔法)"的克制对策系统(穿甲弹/高爆弹式三角)+ 标错封印随机惩罚。(本段写于 2026-09-12,原文使用位置名 无甲/护甲A/护甲B 与 基础/伤害A/伤害B——2026-09-15 命名统一批已全仓改为语义名,映射见下方该批小节。)设定表经用户多轮审阅确认"没有问题"后落程序(GDD 正式修订另批进行——本批以表格结论为实现依据)。 - -**拍板结构 → 落点**: - -| 设定 | 实现落点 | -|---|---| -| 敌人护甲类型:轻甲 / 魔法护甲 / 重甲 | EnemyTable 新字段 `armor_type`({light,ward,heavy},缺省 light 向后兼容)· 映射:goblin=light / bugbear=ward / ogre_chief=heavy(教学梯度候选,provisional)· B2.spawn 行值快照入单位字典 | -| 伤害单分量(2026-09-19 充能退役) | ~~B1 三分量~~ 主角攻击 = 单一基础分量:量 = atk(表值)、类型 = hero.attack_type(营地换型 = 改字段);hero_attack 行携带实际攻击类型键 + roll/ac/tier 掷点读数(P2 归因)。**攻击类型是伤害的属性轴,与来源无关**(2026-09-15 抽象分离批纪律保留) | -| ~~充能供给~~(2026-09-19 退役) | SettlementTable 字段 `charge_grants` 已删除——挖掘攒弹药的第二伤害供给取消,克制应对 = 冒险前配型(hero.attack_type)+ 棋盘火力(穿刺弹/魔法矢直伤道具) | -| 克制矩阵:克制 ×150 / 中性 ×100 / 被克 ×50 | SettlementTable 新字段 `armor_effectiveness`({normal,pierce,magic}×{light,ward,heavy} percent,缺项回退 100)——刀/AOE/清图奖励**恒定表值不吃克制**(道具=万能稳定伤害,暂定待拍板) | -| 标错封印 → 随机轻惩罚三选一(时效 1 结算) | `_apply_miss_backlash()`:① `enrage` 暴走(敌 +25% 进 enemy_output 池)② 敌方伏击 +2 层(复用 ambush 行)③ `off_guard` 失衡(我方 +25% 进 hero_defense 池 = 多挨打);新 B3 行 ×2(dur=1 与 weaken/ambush 同款先兑付后衰减);沿用 `_seal_miss_seen` 每危险格实例一次去重 | -| 随机载体 | **零新流确定性派生**:(x×7 + y×13 + 板序号×5) mod 3——同种子可回放、不扰动既有三条封闭流取号序;正式侧候选 = RngService 新增封闭流(待拍板) | -| 呈现 | 敌人卡环点行常驻护甲标签(轻甲/魔法护甲/重甲——克制对策可读前提)· 结算明细主角攻击行拆"(普通 X + 穿刺 Y + 魔法 Z)" · 反噬效果行入明细流 · settlement_snapshot 增 armor/charge 字段(JSONL 数值分析面) | - -**数值全部 provisional 待拍板/调参**(登记于 enemy.tres / settlement.tres 注释):~~charge_grants~~(2026-09-19 退役)· ~~矩阵 150/100/50~~(加法核 +1/0/−1 换装)· enrage/off_guard 25% · 伏击 +2 层 · 护甲映射 goblin/bugbear/ogre——C3 调参时按 F6 供给平衡式复算(三段充能是新增伤害供给,裸装败北/基线通关率两条冒烟路径已复验仍成立)。 - -**正式侧义务(GDD/registry 修订清单,待文档批)**:B2 GDD(EnemyTable armor_type 字段 + schema)、B1 GDD(F3 主角攻击三分量构成 + seal_miss 反噬编排 + 克制矩阵载体)、B3 GDD(六行 MVP 状态表 + source_class seal_miss 授予)、A2 OQ1(标错惩罚候选升级为三选一随机池 + 重复性口径=每危险格实例一次)、registry(enemy/settlement_table/status_effect 条目 + A3 条款②锚与条款③不等式重推导——封印命中收益从纯 weaken 变"weaken+魔法 充能")、C3(数值 provisional 接管)。lore 侧:`design/research/lore-nest-metaphor-2026-09-12.md`(穿刺=地利/魔法=封印暴露、反噬=封印失败——待新会话拍板后写回 game-concept)。 - -**验证**:冒烟 **161/161**(+12:护甲快照三档传播 / 克制矩阵三行表值 / hero_attack 行三分量字段〔全战斗回放 ×2〕/ 标错封印 seal_miss+反噬效果行 / 标中雷充能进主角攻击 / 反噬派生同种子回放)· ui_probe PASS · ui_tune_probe PASS · ui_click_probe(done=true、选用失效=0、问题=0)。 - -## 2026-09-12 战斗屏五区改造批(battle.md 落地——ui-programmer 批) - -**背景**:`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₀ 域外/去饱和 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(缺陷⑤家族)。 - -**遥测**(playtest_logger 增 ux 行族,呈现层观测不改 core):`ux_round_input_ratio`(原始输入:AP 消耗,快照驱动)/ `ux_round_exit{path_tag}`(快照 round_facts.path——呈现层只订 B1 的接线纪律下唯一合法源)/ `ux_refresh_attempt{result, round_refresh_index}` / `ux_window_choice` / `ux_reject{source, sub_reason}` / `ux_hint_shown{hint_id}`。 - -**探针**: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 正式化硬性前置——2026-09-12 定);金蜡封/暮蓝氛围为色块占位级。 - -**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(AGENTS.md 代码规范 + 架构文档对照),裁决 CHANGES REQUIRED(7 项必改)。core/ 12 文件与 smoke 断言面整体健康;病灶集中于 tune_panel 封装破口、main.gd 结构回涨、三处呈现契约错位。 - -**BLOCKING 修复**: - -| # | 缺陷 | 修复 | -|---|---|---| -| 1 | **TunePanel 视图写核心表**(`apply()` 直写 `_db.hero.atk/.max_hp`)+ `run_simulation` 内 `load("res://smoke/...")` 驱动 core——面板模拟按 pct² 口径、模拟后表值残留污染真实对局(runner 把放大值当基线再乘) | tune_panel 重构为纯视图(`apply_requested`/`reset_requested`/`simulate_requested` 信号外发 + setter 注入);加成落表收口组合根唯一路径 `_apply_hero_override`(每次从 `_ready` 捕获基线重算,幂等禁叠加);模拟编排拆 `tune_sim_controller.gd`(先复位基线再移交);报告文案归 `HudPresenter.tune_sim_report` | -| 2 | **意图徽标双翻译**:presenter 先把 beat key 译中文投影、EnemyCardView 再按英文 key 匹配 → 色相/重击"▼"通道永久失效;`BEAT_NAMES` 两处重复 | presenter 直传 B2 原键(attack/charge/heavy);名/色/标记渲染映射唯一定义处 = EnemyCardView(set_intent 契约头注成文) | -| 3 | **C 区 RAP 死分支**:`_refresh_economy` 从不投影 `a3.rap`,"RAP 滚动归零"反馈(A3 D1 义务)不可达;视图靠解析自身 label 文本当状态 | presenter 持续投影 `a3.rap`;`hero_info_panel_view` 改 `_last_rap` 成员存储,删除 `_rap_value()` 文本解析 | -| 4 | **smoke_all 恒真断言**(`check(true, "全部计数在域内")`——越域也 PASS) | 改带分布标签的真实域内断言 | - -**结构/封装修复**: - -- **main.gd 761 → 667 行**(评审记录基线 433 行,400 行审视线):节点构建拆 `ui_assembler.gd`(只 new/add_child/布局,零接线零核心写);模态层级状态机拆 `modal_stack.gd`(缺陷⑤纪律载体);战斗流程叙事文案拆 `battle_narrator.gd`(兑现 main 头注"不拼呈现字符串");模拟编排拆 `tune_sim_controller.gd`。剩余行数 = 组合根规定的接线 + 模式流转 + 核心写调用唯一出口(再压需移动组合根规定职责,登记为 D1 正式化批候审)。 -- **level_runner core↔core 接线 lambda → 方法 Callable ×4**(静态规则 S6——lambda 捕获 self 延长 RefCounted 生命周期/成环)。 -- **B1 新增 `diagnostic_snapshot()` 诊断观测面**:组合根诊断转储与 click_probe 停滞诊断全部改走成文 API,零下划线私有字段直读(此前直读 8 个)。 -- **信号处理体去 lambda 化**:main 三处多行/单行 lambda(inter 层继续/单场入口/库存拒绝)改命名方法 + `bind`(规范 4.1)。 -- 顺带:`can_request_refresh()` 断行格式修复(原单行内嵌 tab 不可读);`_build_inter_overlay` 死参 `parent_root` 删除;`_start_battle` 重复 `_start_overlay.visible = false` 去重;调试两层入口改由 `_start_battle` 统一取加成后满血(原传参在加成前取表值)。 - -**探针同步(缺陷回归断言随契约更新——3.3)**:ui_tune_probe 重写——应用/重置走真实按钮信号路径(`press_apply_for_probe` 接缝——合成输入走真实翻译出口口径);**新增两条回归断言**:⑦模拟后 hero 表保持基线(无残留)⑧应用加成 + 启动完整关卡后 runner 写表值 = 基线 × 单次加成(12/75;旧缺陷表现 24/112 在此被抓获);ui_click_probe 停滞状态与诊断转储改走 `diagnostic_snapshot()`。 - -**验证**:smoke_all **141/141** · ui_probe PASS · ui_tune_probe PASS(含新回归⑦⑧)· ui_click_probe 六种子(7/11/23/99/42/77)全 PASS(done=true、选用失效=0、问题=0)。新增 4 脚本 `.uid` 经 headless 编辑器扫描生成(语言纪律⑤)。 - -**登记待办(非本批范围)**:自动玩家策略四份复制收口(评审 W-3);schema 溯源行补齐(W-9);S1–S8 静态扫描脚本化后 S1 自建 RNG 豁免口径登记(W-1);views 转发层信号契约头注补齐(W-2)。 - -## 2026-09-13 封装收口批(代码架构审查 E1–E5/O1–O5/P3 修复——接口正式化候选项的切片侧预收口) - -**触发**:/architecture-review 改编批——以 architecture.md + code-conventions 为基线做代码组织/封装专项审查(报告:`代码架构评审(已退役,git 历史可查)`,Verdict: CONCERNS),用户拍板 P1+P2+P3 全修(P2 中涉接口漂移两项另出设计稿待审)。 - -**核心封装修复(P1)**: - -| # | 项 | 修复 | -|---|---|---| -| E1 | **B1 协作对象全公开 → 呈现层链式穿透**(`b1.b2.hero`、`b1.a3.phase` 式层层下钻 main×18 / presenter×15 处) | a1/b2/b3/b4 私有化(a2/a3 保留公有 = 架构文档 API Boundaries 的 D1 契约面);新增 `presentation_snapshot()`(载荷 schema 头注成文)/`is_battle_live()`/`stock_count()`/`query_reward_identity()` 四个成文只读出口——diagnostic_snapshot 同款模式 | -| E2 | **A2 状态字典公开且被视图绕过查询面直读**(board_view:278/303 直读 `.revealed`,头注自称"只读查询面"自相矛盾) | `board/revealed/seals` 私有化;新增 `current_board()`/`reveal_record()` 查询面;B1/组合根/探针全部改走命名面 | -| E3 | **B2 裸字典容器公开**(`hero/enemies` 可被任意写;presenter 为死亡残位直读原始数组) | 私有化 + `hero_unit()`/`all_enemies()`(含死亡残位,句柄语义与 query_alive 同构)投影面;presenter 残位渲染需求收进 API | -| E5 | **"只读"字段仅靠纪律**(phase/ap/rap/last_round_end/master_seed 架构文档定只读,实际公开可变) | getter-only 属性 + 下划线后备字段(外部读法 `a3.phase` 不变,写入仅剩方法通道——GDScript 层面机制化) | - -**组织修复(P1/P2/P3)**: - -- **O1/O2 调试模式抽离**:main.gd 调试分支(单场/连续两层/HP 携带/共享 B4)拆 `presentation/debug_session.gd`——调试语义单一实现点(O2 双实现漂移收口);组合根保留接线(battle_created 先于 begin_battle 发出,接线唯一归组合根 + 缺陷①时序义务)与终局 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)。 - -**加固(基线既有噪声根治)**:main.gd `_on_board_action` 的清图演出判定在 settle_batch 同步重入(结算→battle_over→关卡终局置空 b1)后仍摸 `b1.a2` → SCRIPT ERROR(基线 click_probe 每跑必现)——补 `b1 != null` 守卫,探针 stderr 归零。 - -**验证**:冒烟 **141/141**(与基线一致)· ui_probe PASS · ui_tune_probe PASS · ui_click_probe PASS(done=true、选用失效=0、问题=0,**SCRIPT ERROR 0**——优于基线)· 新增脚本 .uid 经 headless 编辑器扫描生成(语言纪律⑤)· presentation 层残留穿透引用 grep 归零(呈现面调用 19 处全部为命名 API)。 - -**登记待办(P2 设计稿待审——见审查报告 §4)**:E4 `db.hero` 表值运行时改写参数化(涉 B2.spawn 契约 = 接口漂移,须 GDD/registry 修订批);O4 自动玩家策略四份复制收口(与既有待办 W-3 合并)。 - -## 2026-09-13 P2 收口批(E4 表值参数化 + O4 自动玩家单一实现——用户拍板两项均做) - -**E4(db.hero 表值运行时改写 → 参数显式传递)**: -- `B2.spawn` 增 `atk_override/max_hp_override` 参数(-1 = 表值兜底;沿用 unit_count_override 先例;EC16 越界守卫改对生效上限判); -- `B1.begin_battle` encounter 增 `hero_atk/hero_max_hp` 字段(缺省表值——冒烟直呼路径零改动),战斗段 `_hero_atk` 快照替代 `db.hero.atk` 读取; -- `LevelRunner`:`start_level` 表写删除、生效值进 encounter、`restore_hero_base` 只清百分比(表值不可变后无基线可恢复)、`_base_*` 字段删除(直接读恒定的表); -- main:`_apply_hero_override/_scaled_override` 表写路径废除 → `_debug_hero_override()` 生效值供给 Callable(面板百分比现算经 encounter 入战斗);`_on_tune_apply/_on_tune_simulate` 去复位步骤;`_db_base_*` 字段删除。 -- **收益**:双写叠加(6→18→54)与双基线同步整类隐患随表写移除;D2「单一事实源」原则机制化(表值运行期不可变)。 -- **登记义务**:registry architecture.yaml 新增 `hero_override_parameter_passing` 条目(接口漂移候选;B2.spawn 签名 +2 / B1 encounter +2 = 接口漂移,正式侧 B1/B2 GDD 修订随正式化批)。 -- **探针语义升级**:ui_tune_probe ⑦「表值残留」→「hero 表运行期不可变」(reintroduce 表写即 FAIL);⑧ 双写叠加回归改为完整关卡路径 + 呈现快照单次生效断言(12/75;旧缺陷形态 24/112 仍被抓获)。ui_probe 的 `_start_single` 语义注记:调试单场恒基线(入口清零滑条——原行为,非缺陷)。 - -**O4(自动玩家策略四份复制 → 单一实现,合并既有待办 W-3)**: -- 新增 `smoke/auto_player.gd`:`choose_dig`(最近可挖格)+ `window_selection`(治疗优先于刀;差异参数化 heal_hp_div 2/3 · round_gate 0/3 · knife_compare best/sum——四调用点原语义逐一保留:smoke_all 3/3/best · monte_carlo 2/0/sum · dump_battle 3/3/sum · level_autoplay 2/3/best); -- 四消费方删除各自的 `_choose_dig`/窗口策略块改走单一实现;click_probe 的 `level_autoplay._choose_dig` 引用同步改指 AutoPlayer; -- **等价性证明**:smoke_all 同种子回放断言(步骤流逐行相同)重构后保持全绿。 - -**验证**:冒烟 **141/141** · ui_probe PASS · ui_tune_probe PASS(含 E4 新断言)· ui_click_probe PASS(done=true、选用失效=0、问题=0)。 - - -## 2026-09-13 零承伤根因分割探针 + playtest-09-12 Bug #1–#3 处置批(报告 Top3 授权任务) - -**触发**:playtest-2026-09-12-designer 报告 Top 3 Priorities(探针分割 → Bug 建档修复 → 多种子复扫基线);数值拍板与设计变更不在授权范围(待拍板清单见文末)。 - -**① 零承伤根因分割(新探针 `smoke/damage_probe.gd`——boss/level 两模式)**: -- **快照盲区发现**:settlement_snapshot 取在衰减段之后,时效 1 的 defense_up 当轮授予当轮衰减——真人局 JSONL `buffs[]` 恒空 ≠ 池为空(报告悬置的直接原因)。探针改从结算行(effect 行 pool_value)重建战斗段时点池值,池归属经 settlement.effect_pool_map 表驱动(零字面量)。 -- **Run A(fresh 池零挖掘裸验)**:Boss 攻击拍 d_tick = atk.total 全额兑现(attack 9/9 ×2 · charge 0 设计语义 · heavy 18/18),6 轮击倒英雄(defeat)——**「Boss/敌攻击链缺陷」否证**;拍名轮转与真人局逐拍一致(attack→attack→charge→heavy→attack)。 -- **Run B(自动挖掘墙行为)**:池 -30 → d_tick 21→14、池 -60 → 残余 ×0.40,墙轮承伤恒 >0;表值判定墙最深 -60 > pool_clamp_lo -100 = **归零不可达(09-13 调参批在当前数据上重证)**。 -- **结论**:真人局 12/12 轮零承伤 = 旧数据 defense_up -50×2 = 池触 clamp 下限 ×0(设计语义)——任何 atk 曲线乘在 ×0 上(原报「v3 主杠杆乘在 ×0 上」坐实)。报告 Bug #2 = 设计问题非 bug。 - -**② Bug #1–#3 建档与处置(BUG-0002/0003/0004,`production/qa/bugs/`,编号自 BUG-0001 顺延)**: -- **BUG-0002(报告 #1 浅深度空遭遇)——Rejected as coded**:seed 42 当前构建全关回放复现同款遥测签名(d0 spawn=1 / d1 spawn=3 + round-1 victory + unit_count 0)但实为**首轮全灭**(英雄爆发 + 爆裂粉尘 instant_aoe 全歼低 HP 敌群;与 20:41 局 d1 双地精各剩 1 HP 逐点吻合);遭遇骰数学下限 ≥1(B1 roll_lo)+ B2.spawn count<1 fail-fast 双闸,100 场扫描零越域。**快照盲区修复**:settlement_snapshot 增 `spawn_count`(实例化总数含死亡残位)——unit_count=0 时「全灭 vs 空场」可判别,同类误读机制化排除。 -- **BUG-0003(报告 #2 Boss 攻击零兑现)——Rejected as coded**:根因见①;候选改法(clamp 收紧 / 乘法衰减 / 重击拍穿防)列待设计批。 -- **BUG-0004(报告 #3 grant_node_active 绕过 _supply.notify_granted)——Fixed**:stock 受理成功后补入账(与 grant() 同一「发放即获取」口径);计数器战斗域清零语义不变 = **零战斗数值影响**,纯计数口径修复(报告 Top3 #3 的上报义务执行)。 -- **回归断言(代码规范 3.3)**:smoke_all +7——快照 spawn_count 字段与等值断言;遭遇全深度 × 12 种子全域内扫描(60 场 spawn ≥1 且 ∈[unit_count, unit_count_max]);`_smoke_attack_chain_fresh_pool`(fresh 池非蓄力拍 d_tick == atk.total 全额兑现——攻击链健康钉死,未来真缺陷在此被抓);`_smoke_supply` ⑦ 节点奖励发放即入账。 - -**③ 多种子关卡复扫(Q1 调参批基线——level_monte_carlo 增 F4 两列「普通承伤/场% · Boss承伤%」:逐战斗承伤切分 = round 回卷分段 + 末段 Boss 判定(须抵达 Boss 节点))**: -- N=30 × 10 档(种子 4200–4229;F7 切片样本量口径)。**结论:全档位越带**——F5 基线通关率 **17%**(带 40–60%)· +100% 档 43%(中天赋 ≥95%)· +200% 档 63%(高天赋 100%);F4 普通场承伤 **35.1–43.1%/场**(带 ≤20%)、Boss 场 **71.3–134.9%**(带 ≤50%)(hp+0 档;hp+100 档普通 13.9–22.6 带内 / Boss 35.8–76.7 仍多数越带)。拆墙(-50→-30 且权重 24→16)与 v3 atk 曲线叠加后,难度由严重不足摆向**严重过剩**。**本批未动任何数值**(敌 hp 曲线与奖励供给禁独立调参——registry 预警⑥联动义务;杠杆方向列待拍板,本基线 = F7 流程的测量输入)。 - -**验证**:冒烟 **148/148**(141 既有 + 7 新回归)· 三探针 PASS(ui_probe / ui_click_probe 6 种子 done=true、选用失效=0、问题=0 / ui_tune_probe)· damage_probe boss 模式 7/7 + level 模式(种子 42/43/44)4/4 全 PASS。 - -**待拍板/待设计批清单(本会话零数值变更、零 GDD 变更)**: -1. **难度杠杆重拍板**(F4/F5 全档位越带)——候选:enemy atk 曲线回撤部分 v3 增量 / defense_up 权重回升 / heal 供给联动——归 C3 按 F7 流程(本基线为测量输入); -2. **墙语义候选改法**(clamp 收紧至 -60/-70 / stack 乘法衰减 / heavy 拍穿防)→ C3 + /propagate-design-change(连带 B1 池 clamp 语义 + B3 GDD "-50" 文字同步); -3. **供给量重拍板**:「每战斗首件保证」的总量语义(候选:关卡域首件)→ C3(BUG-0004 已封计数漏洞,关卡供给账目可完整观测); -4. **浅深度首轮跳战可玩性**(autoplay/真人 d0-d3 round-1 全灭跳过战斗过程)→ C3 结合 F4 复验数据裁决。 - - -## 2026-09-13 拍板落地批(四项拍板——难度杠杆/墙语义/供给量/跳战) - -**拍板结果**(用户四问裁决):①难度主杠杆 = **先真人试玩再拍**(F5 真人修正系数标定优先于数值调整);②墙语义 = **维持现状 + 归零护栏**;③供给量语义 = **先观测再拍**;④跳战 = **并入难度复测再议**。本批零玩法数值变更。 - -**落地变更**: -- smoke_all 新增 `_smoke_wall_zero_guard`(表级不变式:`2×defense_up.magnitude > pool_clamp_lo`)——BUG-0003 事故类(叠满触池底 = ×0 全额免伤)永久免疫:任何未来 magnitude/clamp 调参重新造出 ×0 墙即冒烟红灯,强制显式重审; -- level_monte_carlo 增「**跳战率**」列(普通战斗 round-1 即胜占比——拍板④观测面,此后每次复测自动携带);`_damage_segments` 升级为逐段 {承伤, r1_win} 结构; -- defense_scan 输出标签修正:「墙轮承伤(应为 0)」→「(合法——-30 批墙帽 ×0.40)」(旧 -50 数据时代的期望文案过时清理)。 - -**跳战率基线(N=30,拍板④"再议"数据)**:基线 **8%** · +50% 13% · +100% 24% · +150% 27% · +200% 38%(普通场 round-1 全灭占比)。**seed 42(试玩固定种子)为高跳战轨迹**(autoplay d0–d3 四场全部 round-1 全灭)——真人局 d0–d3 全跳的体验含显著种子成分;基线 talent 下跳战是少数派,拍板④"复测再议"的数据前提成立。其余各列与 Q1 基线逐值一致(collect_rows=true 开启不改变行为——确定性交叉验证)。 - -**验证**:冒烟 **149/149**(+1 护栏)。 - -**下一步(用户侧)**:开一局真人试玩(任意种子;JSONL 自动落 user://logs/)。观测清单(服务拍板①③复议):通关与否 + 败北节点(F5 修正系数 = 真人通关率 ÷ 模拟 17%)· 普通场掉血体感(对照 ≤20% 带)· Boss 战撑过几轮 · d0–d3 是否发生跳战 · 治疗包是否出现缺血时刻与库存残留(拍板③数据)。事后由会话分析 JSONL 出修正系数。 - -## 2026-09-14 完美策略档测量批(OQ7 技能轴上界仪——用户拍板"增加完美策略档测试验证",零玩法数值变更) - -**背景**:用户(扫雷强玩家)指出"完全正确开图/标雷、零踩雷 ⇒ 存活无压力"——现行扫描只有弱策略基线档(不封印/邻格盲挖/朴素选道具),技能轴不可测;registry `calibration_gap`(真人显著强于模拟者)此前只有方向无机制。本批 = 测量工具批。 - -**落地变更**: -- `auto_player.gd` 增完美策略求解器(`perfect_action`/`_deduce`):single + subset 推理不动点(A1 F1 `measure_inferability` 同族规则集,**去 safe_set oracle**——约束未知邻格含危险格,比生成期闸保守);**零盲挖**(只挖已证安全格 = 构造保证零踩雷,扫描末断言兜底违例 quit(1))· **已证危险格全封印**(封印先于挖——轮末 weaken + 魔法 首次充能,雷上封印不阻连锁)· 卡死且资源可 → `b1.player_request_refresh()` 轮内刷新 · 否则停手(残 AP 1:1 入 RAP)。输入只经 A2 查询面(reveal_record/is_revealed/has_seal),**禁读棋盘雷区真值**——测推理上界,非全知作弊。core 层零改动; -- `window_selection` 增 `heal_no_waste` 选项(缺口 < 治疗量不用;完美档启用)+ 完美档轮次门解除(round_gate=0); -- `level_autoplay.gd` 增 `policy` 参数(默认 "normal"——tune_sim_controller/defense_scan/level_debug 既有调用零改动);完美档经 `policy="perfect"` 由 `_decide_act` 分派承载(原专职驱动 `_autoplay_battle_perfect` 已随样板收口并入分派——move/dig/seal 走 A2 settle_batch、refresh 走 B1 编排、连续拒绝 ≥3 停手防死循环);st 增 `mine_hits`/`refreshes` 计数(mine_hit 证据行埋点); -- `level_monte_carlo.gd` 增第 3 CLI 参 `[policy]`(normal/perfect/both,缺省 normal 兼容既有文档命令)+ 策略/踩雷/刷新列;脚注 F5 带文案同步 [30,50] 带锚定稿。 - -**完美档基线(N=30 · 种子 4200–4229 · 耗时 597.6s)**:**0 加成通关率 100%**(弱策略基线档 60%)、通关剩余 HP 均 **47.4/50**、整关承伤均 3.5(p90 18.0)、普通场承伤 0.5%(带 ≤20%)、Boss 场 5.3%(带 ≤50%)、踩雷 0.00/局(断言 ✓)、刷新 0.23/局、跳战率 20%。+50%~+200% 全档位恒 100% 满血通关(+200% 承伤均 0.4)——**技能轴上界完全碾压现行曲线:F5 带与 F6 S/K 区间对完美档零分辨力**(区间模型无策略水平轴的结构性证实;calibration_gap 获得机制解释与定量上界)。 - -**验证**:冒烟 **149/149** 全绿(默认行为零变更——弱策略档既有断言全通过)。 - -**待拍板**:① 0 加成完美档通关率的目标带(现行 [30,50] 按弱策略口径定义——是否改为按完美档口径验收?);② 杠杆选择(已预登记:r_boss 走廊 180–207 / 群战上探 / decay 0.6;本批新增候选:"上限掺运气"系——供给量值随机化(power 区间化)/ 承伤硬地板——均待完美档复测验证效果)。 - -## 2026-09-14 伤害量值区间批(用户拍板②——"上限掺运气"两步全落地 + 完美档无效性实测,宽度 provisional) - -**拍板**:验收口径改完美策略档(0 加成通关 ≤40%);杠杆 = 伤害值区间随机(上阶/下阶,范围内 roll);覆盖面 = 奖励侧五行先行、不足扩敌方侧(分步授权已用尽)。roll 时机 = 身份预分配批(E14 快照口径不变);中点恒等现值(A3 条款①当量锚不漂移);宽度 provisional 归测量迭代。 - -**落地变更**: -- **第一步·奖励侧五行**(reward.tres + reward_table.gd schema + reward_economy.gd):heal_minor [2,6] / knife_t1 [5,11] / heal_pack [6,18] / knife_adv [10,22] / clear_blast [25,55]——power_min/power_max 可选配对字段(缺省定值行向后兼容,armor_type 先例);schema 校验 = 成对/buff 禁止/中点锚;roll 在 roll_board 身份批内**追加取号**(既有取号序零扰动)+ grant_node_active 同路径;快照 power = roll 值,B1/呈现零改动,授予期零随机纪律不变; -- **第二步·敌方攻击侧**(enemy.tres 六行 + enemy_table.gd schema + unit_container.spawn + battle_orchestrator):atk [min,max] = 行值 ±3 provisional(d0 7[4,10] / d1 5[2,8] / d2 9[6,12] / d3 6[3,9] / Boss 9[6,12] / L2 7[4,10]);roll = 遭遇骰同流(encounter 恰一 scope,数量骰先、atk 骰后)spawn 期**整战持久**——每拍抖动否决(数字可读性锚),B2 零随机纪律保持(收 override 即确定值);spawn 签名 +1 参数(接口漂移登记,随正式化批); -- smoke_all 新增 `_smoke_power_interval`(4 断言:五行中点锚/roll 域内含清图槽/定值行零外溢/节点路径域内)。 - -**实测(N=30,种子 4200–4229)**: -- 奖励侧单独:完美档 0 加成 **100%**(承伤 3.5——与区间前逐值一致);基线档 17%(不变); -- 敌方侧叠加:完美档 0 加成仍 **100%**(承伤 3.5→3.9 / p90 18→19——方差真实流动但被血缓冲全吞);剩余 HP 均 47.4 不变; -- **验收结论:≤40% 线用数值区间杠杆族到不了**——完美玩家结构性优势(零踩雷 = 零直伤 + 全封印 = weaken −65% 顶格 + 快杀 = 敌出手次数最少)不受值域方差影响。三选待裁决:①承伤硬地板(每结算不可减免平伤——S_min 压缩,B1/B2 域);②weaken 饱和/递减语义(拆"全封印顶格"基石,B3/B1 域);③极端宽度(数值可用但毁基线档与可读性锚——建议否决)。**本批区间机制保留**(对普通玩家方差体验有效,中点锚不伤当量)。 - -**验证**:冒烟 **154/149+5 全绿**(区间批 5 新断言 + 既有全部回归含遭遇骰分布/回放)。 - -## 2026-09-15 攻击/护甲命名统一批(用户拍板"一并修改,统一称呼"——纯改名,数值零改动) - -**触发**:GDD 评审(战斗结算)问题 1——位置键 `{base, dmg_a, dmg_b}` / `{none, a, b}` 不承载语义(a/b 是纯位置占位符:既说不出来源,也说不出来克制谁),且同一件事在仓内已分裂成四种写法(敌人系统 `{无, 甲, 重甲}` / 03-内容规模 `无甲/甲A/甲B` / registry `{none, a, b}` / 本 README `无甲/护甲A/护甲B`)。 - -**新词汇(全仓唯一现行词)**: - -| 面 | 新 | 旧(作废) | -|---|---|---| -| 攻击类型(结算表矩阵行键 / hero_attack 行分量) | `normal` / `pierce` / `magic` = 普通 / 穿刺 / 魔法 | `base` / `dmg_a` / `dmg_b` = 基础 / 伤害A / 伤害B | -| 护甲类型(`armor_type` / 矩阵列键) | `light` / `ward` / `heavy` = 轻甲 / 魔法护甲 / 重甲 | `none` / `a` / `b` = 无甲 / 护甲A / 护甲B | -| 结算表字段 | `charge_grants`(触发源→{attack_type, per_unit, cap},同日第二批抽象分离后定型) | `damage_a_per_cell` / `damage_a_cap` / `damage_b_per_seal`("类型×来源"焊死命名;同名批曾短暂改 `pierce_per_cell` / `pierce_cap` / `magic_per_seal`,随即作废) | -| 结算快照 round_facts | `charge_counts`(各触发源计数)+ `charge_points`(按攻击类型分桶点数) | `charge_dmg_a` / `charge_dmg_b`(既有 JSONL 留存文件仍用旧键) | - -映射沿教学梯度:goblin `none`→`light`、bugbear `a`→`ward`、ogre_chief `b`→`heavy`;**矩阵数值逐格不动**(pierce→ward 150 / pierce→heavy 50 / magic→heavy 150 / magic→ward 50 / normal 全 100)。 - -**同日第二批 · 攻击类型与奖励抽象分离**(用户裁定"攻击类型的定义和格子奖励要分离开;开格|标雷 → 奖励;奖励如何定义是可以修改的;不要将两者绑定"):攻击类型 = 伤害的属性轴(普通 / 穿刺 / 魔法,只决定查甲效矩阵哪一行,定义里不含任何棋盘来源);充能 = 按攻击类型分桶的附加伤害储备,**谁能充、充哪个桶 = 奖励定义**(`charge_grants`;开格 / 封印命中 / 踩雷 / 清图一律只作奖励触发源)。原 `pierce_per_cell` / `magic_per_seal` 式命名(类型与来源焊在一根名字里)作废。冒烟新增三条断言:奖励定义在位 ×2 + 行为断言(把"封印命中"奖励改投穿刺桶 → 同一战斗魔法分量归零;还原后步骤流逐行相同——证明改道唯一入口是奖励定义)。 - -**落点**:GDD(战斗结算 v0.5 / 敌人系统 / 难度曲线与Boss / 03-内容规模)+ registry(`enemy.armor_type`、`settlement_table.armor_effectiveness` 与三字段 + 批次注记)+ 切片(`enemy_table.gd` `ARMOR_TYPES`、`settlement_table.gd` `ARMOR_KEYS` / `ATTACK_TYPE_KEYS`〔原 `COMPONENT_KEYS`〕、`enemy.tres`、`settlement.tres`、`damage_math.gd`、`unit_container.gd`、`battle_orchestrator.gd`、`enemy_card_view.gd`〔敌卡常驻标签改 轻甲 / 魔法护甲 / 重甲〕、`battle_log_view.gd`〔拆行文案改"(普通 X + 穿刺 Y + 魔法 Z)"〕、`smoke_all.gd` / `damage_probe.gd` / `auto_player.gd`);playtest 观测记录保留当时键名并附现名。 - -**验证(本批实跑)**:冒烟 **201 项检查 0 失败**(含分离批三条新断言:奖励定义在位 ×2 + 行为断言"封印命中奖励改投穿刺桶 → 魔法分量归零、还原后步骤流逐行相同")· `ui_probe` PASS · `ui_tune_probe` PASS · `ui_click_probe`(done=true、选用失效=0、问题=0)· `ui_layout_probe` PASS——四探针 exit=0、FAIL 行 0。命名批纯改名零行为变更;分离批为结构重构,数值链路等价(旧"计数×每单位×克制"与现行"计数→按奖励定义折算点数→×克制"结果相同,冒烟全量回归含回放断言未动)。 - -## 2026-09-15 验收 + 收口批(两批改动闭合核对;零数值零机制改动;不碰 v0.7 文件) - -**背景**:2026-09-15 两批(攻击/护甲命名统一 v0.5 + 攻击类型/奖励抽象分离 v0.6)已完成;本批只读核对"文档口径 ↔ 切片实现"是否闭合,并收口遗留开口。**范围纪律**:`战斗结算.md` / `地图战斗资源.md` 属 v0.7 格面资源批所有者文件、口径仍在移动——本批不改;③ 收口项落在 `registry` + 本 README + `active.md`,GDD 侧只报告、待 v0.7 批整体收口后回填。 - -**核对结论(两批核心语义 9 项全闭合)**:`charge_grants` 键与值(safe_cell→pierce 1/格 cap 8 · seal_hit→magic 2/雷 cap 0)· 甲效矩阵 9 格(normal 全 100 / pierce→ward 150、heavy 50 / magic→heavy 150、ward 50)· `armor_type` 三值(light/ward/heavy)· `hero_attack` 行分量字段(normal/pierce/magic)· round_facts 键(`charge_counts`/`charge_points`)· 敌卡标签文案(轻甲/魔法护甲/重甲)· 明细行拆行文案"(普通 X + 穿刺 Y + 魔法 Z)"· 攻击类型定义不含来源 · 矩阵数值逐格不动——GDD/registry/tres/代码逐项一致。残留旧名扫描仅命中批次注记"原名"与历史观测记录;来源-类型硬绑扫描确认代码只剩两处计数埋点(`_charge_counts["safe_cell"]` / `["seal_hit"]`)+ `charge_grants` 键 + 行 `source_class` 归因。 - -**实跑(本批)**:冒烟 **201 项检查 0 失败**;四场景探针 `ui_probe` / `ui_tune_probe` / `ui_click_probe` / `ui_layout_probe` 全部 **exit=0、无 FAIL 行**。 - -**收口(③,落在非 GDD 文件)**: -- ① **收益对照表充能当量覆盖缺口**:登记于本 README + registry + `active.md`(GDD 收益对照表回填待 v0.7 批收口后)。候选口径 = 充能当量 = Σ各桶点数 × 当轮目标护甲平均甲效倍率 ÷ 100(与直伤同类 1 伤害 = 1 当量,守 行动经济 条款①单一当量);补式 / 登记待拍板二选一待回填批裁定。 -- ② **两处已知落差登记**:a) `charge_grants` 触发源可扩展 vs 切片仅两个触发源计数埋点(新增源须加埋点);b) `safe_cell`/`seal_hit` 来源标识跨命名空间同名(明细行 `source_class` / `charge_grants` 键;RewardTable.pool_tag 已随格面资源批改 `cell`)。 -- ③ playtest 观测记录的快照键"现名"注记由中间名订正为现行名 `charge_counts`/`charge_points`。 - -**注意(口径移动)**:本批运行期间 **v0.7 格面资源批**已在 GDD(战斗结算 v0.7 / 地图战斗资源 v0.4)与 registry 落地——段序七→五、行型 15→10、极性路由取代三套固定兑付、可选类道具删除。切片代码尚未同步(registry 注明"切片代码修改随新会话执行、指导已产出"),故本文以上各历史批次条目保留当时陈述。 - -**两轴分离措辞不变**:攻击类型 = 伤害属性轴(定义不含来源);充能 = 按攻击类型分桶的附加伤害储备,投桶归奖励定义 `charge_grants`;开格/封印命中/踩雷/清图只作奖励触发源。 - -## 2026-09-15 格面资源批 · 批 1(数据面 + 极性路由——设计权威 = 地图战斗资源 v0.4 / 战斗结算 v0.7 / 排雷玩法 v0.3 / registry 2026-09-15 条目) - -**模型一句话**:格子分 安全|雷|封锁格 三型;每个非封锁格(安全格 + 危险格,雷安同池同分布)装板期一次摇定格面资源类型(五型 attack/defense/heal/blast/weaken);极性不在资源内,由「动作 × 格型」矩阵决定——开安全格/标中雷 = 正向(奖励),开危险格/标错安全格 = 负向(惩罚),封印后撤封印零兑付;全部兑付在轮末授予段。可选类道具(刀/治疗包)与库存/供给控制器/道具窗口整体删除。 - -**数据面**: -- `reward.tres` 结构性重写(`reward_table.gd` 同批):删 `category`/`use_timing` 字段与 CATEGORIES/USE_TIMINGS 常量;新增 `cell_type`(五型封闭枚举,清单外加载拒绝)× `polarity`(positive/negative)+ `stacks`(可省,缺省 1);`pool_tag` 收窄 {cell, clear_default}。行集 = 十一行:格面池正向五行 attack_up(w20,t2)/defense_up(w16,t2)/spark_aoe(flat 4,w16,t1)/heal_minor(flat [2,6],w15,t1)/weaken(w12,t1) + 负向五行 enrage(attack,t2)/off_guard(defense,t2)/heal_backlash(heal 直伤 flat 4,t1,无 effect_id)/ambush_double(blast 加层 stacks=2,t1,无 effect_id)/sapped(weaken,t1)——负向行 weight=0 纯兑付字典不参与摇号;clear_blast 保留(flat [25,55],w1,t2,clear_default)。加载校验族重写:五型 × 正负两行齐备(缺任一致命)/ cell 池 ≥1 正向行 weight>0 / percent 行 effect_id 必填(悬空校验在 ConfigDB)/ flat 行 power≥1(**例外 = blast 负向加层行,消费 stacks 不消费 power**——战斗结算 兑付形态表"伏击加层"独立形态的行级兑现)/ 区间配对 + 中点锚不变。 -- **删除三件**:`core/reward_supply_controller.gd`(可选类供给控制器——首件保证/指数递减整体下线)、`data/schemas/reward_config_table.gd`、`data/tables/reward_config.tres`(RewardConfigTable 随可选类删除废止——注入概率/按板保底参数失义)。 -- `status_effects.tres` 六行→七行:新增 **sapped(乏力——weaken 型负向:hero · −25 percent · dur 1 · max_stack 16 · stack**,hero_offense 池,attack_up 镜像;值 provisional 归 难度曲线与Boss)。 -- `settlement.tres`:`segment_order` 七段→五段 [grant, buff_debuff, combat, decay, verdict](schema 冻结常量同步);`effect_pool_map` 增 sapped→hero_offense;`source_label_map` 删 item 键(ConfigDB 必需键清单同步)。`charge_grants` 路径不动(开格→穿刺 1/格 cap8 · 封印命中→魔法 2/雷)。 -- `config_db.gd`:reward_config 出表清单;跨表校验族重写——旧 ②池空/③clear正当量并入 RewardTable.validate,旧 ④⑤⑨(k_dmg 保底/零伤害后闸/注入池护栏)随 reward_config 删除退役,保留 ①effect_id 悬空 / poolmap 悬空 / source_label_map 键集 / level 节点悬空。 - -**路由面(core)**: -- `minesweeper_rules.gd`:cell_revealed 事件字段 `reward_eligible` → **`resource`**——initial 恒 false(封锁格),chain/dig 恒 true **含危险格**(雷安同池——旧"mine 恒 false"作废)。 -- `reward_economy.gd` 重写为纯格面资源身份面:roll_board 对全部非封锁格逐一摇定类型(摇号只用正向行权重 = 类型频次,合计 79)+ 清图批尾摇 clear_blast + 区间行 power 追加取号;query_identity 返回 {reward_id, cell_type, tier},未开格恒可查(危险格同权);grant/grant_clear 幂等保持;新增 `polarity_row(cell_type, polarity)`(类型化字典行查询面,拷贝出口)与静默 `is_mapped`/`phase` 只读出口;**删库存轴整族**(stock/use/query_inventory/in_stock_count/clear_inventory/grant_node_active/supply_granted_count/notify_battle_start);equivalence_supply 投影保留(tier_min_buff = 我侧 percent 正向行最低档 = 2)。 -- `battle_orchestrator.gd` 授予段改**极性路由**:结算队列(开格/封印判定/清图三批)逐格兑付——开安全格→该格 cell_type 正向行(charge_grants 计数埋点不变)、开危险格→负向行、标中→该危险格正向行(_seal_consumed 每雷实例一次去重不变,高光 seal_hit 保持)、标空→封印未中归因行 + 该安全格负向行(_seal_miss_seen 同键去重不变);**删旧三套固定兑付**(`_convert_ambush` 踩雷固定伏击 / `_judge_seal` 标中固定 weaken / `_apply_miss_backlash` 标错三选一哈希派生——整段删除)。负向兑付:percent 走 apply_effect(enrage/off_guard/sapped);heal 负向 = 主角直伤 4(apply_damage,不经增益状态;战斗段增 hero 存活守卫 = 致死短路;同轮后到 heal 正向遇已倒下主角记"奖励未生效"行);blast 负向 = ambush +stacks 层(`_apply_ambush_grant` 逐层经 ambush_grant_plan 对 cap=4 守恒,溢出逐层"溢出未生效"行——协议不变)。正向兑付:percent 挂状态、flat 当场(满层/满血/无敌/主角已倒下记"奖励未生效"行)。抵消过滤既有语义保持(封印判定批以轮末在场封印为基线——发射面过滤,勿改)。区间行快照 power 只在正向路由覆盖表值(负向字典行自带定值 power)。**行型协议 15→10**(删 item/consumed_ineffective/use_rejected/window_open/window_skip),SOURCE_EXEMPT 两层豁免集合同步收窄。 -- `level_runner.gd`/`debug_session.gd`:共享 地图战斗资源 容器与库存延续语义随库存删除收窄——战斗各自持容器(映射随战斗退役,零跨战斗状态),runner 删 window 转发/inventory()/level_clear 清库/submit_window_selection;奖励点节点内容随功能道具渠道(P1 未定)**悬置为直通节点**(零兑付,node_entered 零载荷——内容归 关卡节点地图 定稿批,**待拍板**);battle_finished 载荷删 remaining_items。 - -**呈现面**: -- 删除 `inventory_panel_view.gd`(E 区道具面板/窗口态整件);`ui_assembler` 五区→四区(玩法说明文案改格面资源口径);`hud_presenter` 删 _fill_inventory/_inventory_row/window_rows,refresh 签名收窄;`main.gd` 删窗口接线/窗口状态机/库存引用(ux_window_choice 遥测随之退役);`battle_narrator` 文案去道具(层间延续 = HP only);`battle_log_view` 行格式化收窄 10 类(AGG_TYPES = reward_ineffective/overflow 两类);`board_view` 奖励徽章键 category→cell_type(攻/守/医/爆/弱 占位字形——**类型图标预读/极性视觉归批 2,纯呈现**);`status_slot_row` 补 sapped 图标键与语义(七行全映射);`playtest_logger` battle_end/level_end 载荷去 remaining_items、reward 节点零载荷。 -- "剩余安全格计数"注记:切片呈现层现无该计数器(safe_remaining 无 UI 消费方),无可改文案;呈现口径改动随批 2 一并处理。 - -**smoke/tools**: -- 删 `supply_scan.gd`(可选类供给跨种子扫描——对象已不存在);`_smoke_supply` 整段删除。 -- `smoke_all.gd` 大改(201→211 项):删窗口接线族与窗口锚行段、等待期刷新探针改挂衰减行(结算段内 Waiting 相位刷新必拒);`_smoke_power_interval` 收窄两区间行;`_smoke_damage_types` 标错断言改类型化负向兑付。**新增五段**:`_smoke_reward_identity_unit`(roll 恰一次/query_identity 投影/同格重复 grant 幂等/grant_clear 幂等/退役拒绝)、`_smoke_polarity_routing`(真实流多轮:挖安全格只出正向 + 每格 ≥1 行、挖危险格只出负向、标中正向 origin 指回危险格、标空归因 + 负向同格同批、封印兑付零泄漏)、`_smoke_negative_dictionary`(sapped 数据面在位 + effect_pool_map 收编 + 逐型负向直验:enrage/off_guard/sapped 效果行、heal 直伤 4、blast +2 层与 cap 溢出守恒)、`_smoke_resource_surface`(chain/dig resource 恒 true 含危险格、initial 恒 false、封锁格查询 null、未开危险格可查)、`_smoke_settlement_segments`(segment_order 五段冻结 + 行型封闭零残留 + 逐轮行相位单调 + 衰减/判定恰一段)。 -- `reward_expectation.gd` 重写为类型频次测量(实测收敛权重涌现值 attack 25.3/defense 20.3/blast 20.3/heal 19.0/weaken 15.2%,封锁格泄漏 0);`level_autoplay`/`monte_carlo`/`dump_battle`/`damage_probe`/`level_debug`/`level_monte_carlo`/`ui_probe`/`ui_click_probe`/`ui_layout_probe` 去窗口/库存面。**顺手修**:`monte_carlo.gd` 缺 AutoPlayer preload(HEAD 起即解析失败)已补。 - -**验证(本批实跑)**:冒烟 **211 项检查 0 失败**(回放断言全量保持——同 master_seed 同意图序列结算步骤流逐行相同);四场景探针 ui_probe / ui_tune_probe / ui_click_probe(PROBE_SEED=7 与 91 双种子)/ ui_layout_probe 全 PASS;工具回归 reward_expectation / monte_carlo / dump_battle / damage_probe(boss) / level_debug / level_monte_carlo(N=5) 零脚本错误。 - -**表实一致注记(对 registry reward_table 条目)**:十一行逐字段一致;两处切片级补全登记——① 负向 heal/blast 行 registry 未定 reward_id,切片取语义名 `heal_backlash` / `ambush_double`;② blast 负向加层行 effect_id 恒空(registry flat 行口径)+ power 校验例外(power 不消费——伏击加层为独立兑付形态,见战斗结算 GDD 兑付形态表)。 - -**待拍板(本批登记)**:① 关卡奖励点节点内容(功能道具渠道 P1——归 关卡节点地图 定稿批);② 已开格类型徽章与极性视觉(批 2——纯呈现);③ "剩余未探索安全区域"计数呈现口径(切片现无该计数器,随批 2)。 - ---- - -## 2026-09-16 敌人技能池批(批 1+2+3 合并落地——设计权威 proposal-skill-pool.md〔提案已吸收退役 git a6833b6a——现行事实源=敌人系统.md 技能池节〕 v1.0;文档面 v0.5/v0.11/v0.5/v0.6/v0.3/v0.4 同批) - -**机制**:确定性出招剧本(行为环:拍枚举/环指针/同种锁步/heavy_multiplier)整体退役,改技能池 + 开轮摇号——每轮轮次开始排除冷却中技能、按行序逐敌摇定本拍动作(behavior_roll 封闭流,每敌子流 scope = spawn_index×1000000+摇号序),战斗段按技能行兑现(伤害技 = 三乘法链〔基线×倍率→d20 掷点→甲效→伏击后置→池乘区→max(1,·)〕,增益技 = 施放行 cast + 状态授予〔0 伤害不掷不折不兑伏击〕);两道闸 = 全技能各自冷却(普攻恒 0 锁死)+ 保底 M=4(连续 4 拍执行普攻 → 下拍必出特殊技、不受冷却限制);死亡即不动手改"摇定后兑现前死亡 → 作废不进账";拍结构保留(每结算每存活敌恰行动一次/行序/先作用后推进)。 - -**数据面**:新增 `skills.tres` + `skill_table.gd`(五行:普攻/突刺×1.5 cd2/蓄力 cd3/重击×2 cd3/硬化 cd4;pity_threshold=4;普攻倍率/冷却域校验锁死);`enemy.tres` 六行 pattern/heavy_multiplier → pool(地精 9/1 · 熊地精 6/2/2 · 酋长 6/2/2,全部 provisional);`status_effects.tres` 七→九行(empower 蓄力 +100 enemy_output 池 / fortify 硬化 +100 **enemy_defense 敌方防御池新词汇**——duration 2 = 1 个有效增益拍〔先兑付后衰减含施放当轮〕);`settlement.tres` effect_pool_map 增 empower/fortify 两键。 - -**core 面**:`rng_service.gd` 增 behavior_roll 流(salt 0x85EBCA7758C24E15,黄金向量 m=42 scope0=426657203655691839 见冒烟;open_scope 显式 scope 取号门 + BEHAVIOR_SUBSTREAM_STRIDE);新增 `core/skill_lottery.gd`(独立抽签器——输入可摇条目+子流、输出 skill_id,D9 封装纪律);`unit_container.gd` 重写(实例池快照/冷却递减/待发动作/保底计数;query_beat/query_attack/advance/steps/pattern 退役);`battle_orchestrator.gd` 开轮摇号编排 `_roll_round_actions()`(首轮同样摇、轮内刷新不重摇)+ 战斗段技能行兑现 + 主角攻击增敌方防御池乘区(Σ三分量后 ×(100+clamp(enemy_defense))/100);`status_container.apply_effect` 增 duration_override(技能行 buff_duration 覆盖);`config_db.gd` 挂技能表 + validate_skill_pool_links 跨表校验(悬空致命/每池恰一普攻/增益 ≤1)。 - -**呈现面(批 2)**:`presentation_snapshot` 敌人数组字段定稿(beat/ring_size/ring_index 拆除 → pending_skill/pending_type/pending_name + effects 敌方增益投影;池与权重不公开);`enemy_card_view` 环点拆除(护甲行常驻)、意图徽标 = 摇定动画占位(普攻零表示 —/攻击系 ⚔/增益系 ✦);`battle_log_view` 施放行 ✦ 格式化、伤害行具名技能;`status_slot_row` 图标键补 empower ⇧ / fortify ▣(九行全映射);`settlement_snapshot` 敌方 beat 键 → pending_skill;damage_probe 拍名重建改 pending_skill 口径。 - -**smoke(211→263 项)**:行为环断言全部改型(行相位 cast、fresh 池采样、削弱触底/AC12 采样改多种子扫描);新增 `_smoke_skill_pool` 六项验收(proposal §8):数据面(池模板/普攻锁死/空池不可能)、同种子回放逐位复现 + 单敌轨迹独立复放(D3 多实例逐轮记录 vs 只喂该敌子流的独立重放器逐位对照)、EV 抽样对锚(×5000 拍)、死亡打断作废(D2 特殊技种子 + hero_atk 999 先手击杀零行动行 + 不进账)、加载校验拒绝(悬空/池构成/普攻锁死/倍率域/权重域/空池)。 - -**验证(本批实跑)**:冒烟 **263 项检查 0 失败**;四探针 ui_probe / ui_tune_probe / ui_layout_probe / ui_click_probe(种子 7、23)全 PASS;damage_probe(boss/level 全 PASS 含施放行)、defense_scan、monte_carlo 工具零脚本错误。 - -**EV 抽样读数(×5000 拍,含闸长期速率 vs 静态锚)**:地精 1.1056(静态 1.05——保底闸把突刺率从自然 10% 抬到 ~22%,登记难度曲线重锚)/ 熊地精 0.9998(结构守恒恒 1)/ 酋长 1.0236。 - -**文档/registry 同批(批 3)**:敌人系统 v0.5(技能池章节重写)/ 战斗结算 v0.11(随机口径三处/三乘法链/施放行/敌方防御池/AC 措辞四处)/ 增益状态 v0.5(九行 + 敌方防御池;顺手清偿 v0.4 挂起的 sapped 文档同步)/ 难度曲线与Boss v0.6(曲线纪律/Boss 专属池/技能池投值表 + EV 实测登记)/ 战斗表现 v0.3 / HUD框架 v0.4 / 数据配置(敌人表措辞 + 技能表行)/ 03-内容规模 / 02-系统清单 / 关卡节点地图 / ux battle.md(改型注记)/ architecture.md(单位容器 API 面)/ registry(rng/skill 新条目/enemy/status_effect/settlement/术语七词条/修订记录)/ 06-待办清单(改型"单拍行为环体验验证"、收编关闭"行为环废除与蓄力拍退役"、新增 P1 五项 + P2 技能图鉴)。 - -**实现决策登记(提案未定处的自行拍板,按封装纪律报告)**:① 保底 M 载体 = 技能表全局单字段 pity_threshold(不分敌种,难度曲线单旋钮);② 冷却"施放后连续 N 拍不可摇中"的实现 = 摇号按当前冷却值排除、递减在其后(与提案"递减→排除"的可摇集合逐拍恒等);③ 增益持续与技能冷却两计时器 = apply_effect duration_override 通道;④ 敌方防御池乘区落点 = 主角攻击 Σ三分量后(hero_offense 现行走普通分量直乘的切片现状不动——登记遗留);⑤ 摇号器类名 SkillLottery(core/skill_lottery.gd)。 - -## 2026-09-19 技能池新效应词汇批(用户拍板——设计权威 proposal-status-vocabulary.md〔提案已吸收退役 git a6833b6a——现行事实源=敌人系统.md 词汇表/增益状态.md〕 v1.0) - -**三词收敛两词**:妨害技(debuff 新类型)+ 必中附加分量(rider_mult,"固定值伤害"改形);多段命中经用户拍板退役(无防御磨损体系,无对照机制)。**实装面 = 仅 L2 Boss 蛛化卓尔精灵,其余敌种不动**: -- 毒爆 venom_burst + `rider_mult = 0.75`——必中毒分量 = max(1, floor(atk × 0.75))(atk 开战掷定 2–4 → 毒 1–3 点),后置加法、必中全额、不进乘区不出暴击;伤害行 payload 增 `rider` 键 + 行文本「+附加N(必中)」。 -- 新技能行**蛛网束缚 web_snare**(debuff → off_guard 失衡,duration 2 = 1 有效结算,冷却 4,池权重 2 → 卓尔池 6/2/2/2 全 provisional)——0 伤害施放行,状态按 target_side 落主角(掷点阈值 10 → 8)。 -- 结构面:SkillTable type 枚举 +debuff;池纪律 +每池妨害 ≤1;施放类 side 守卫(buff→enemy / debuff→hero,`validate_skill_pool_links` 增 status_table 显式入参——装载序修正);意图徽标 +妨害系 ☠(紫)。 -- 验证:冒烟 306 项 0 失败(+新探针 `_smoke_debuff_rider`:毒爆行逐拍精确复算 / rider 键封闭 / 蛛网束缚落主角端到端 / 六项加载校验拒绝)+ 四探针 PASS;800 局模拟试玩(两关 × 20 种子 × 双画像)——L2 基线通关 90%→80%、死因全部集中 Boss(设计方向生效),L1 零行为变更回归一致(65%/85%)。 -- 顺手收口:smoke_all `variant_pool(1, ["dungeon"])` → `"dungeon"`(并行 board_type 批签名 Array→String 的漏网同步——此前该断言被 SCRIPT ERROR 静默吞掉);analyze_playtest.py 反事实重算 +rider 识别。 - -## 2026-09-21 冒险结构实现批(三关正式序列生效——AdventureRunner + LevelRunner 账本外置 + AdventureTable 建表) - -**主入口升级**:「▶ 开始冒险(三关连探:地精洞窟 → 幽暗地域 → 灰矮人矿城)」——一条命走完三关的完整 Roguelike 冒险;`▶ 测试直入口 · 第二关/第三关` 保留单关试玩模式,L1 单关直入口随批取消(冒险首关即 L1)。 - -**冒险级语义**(设计权威 = 冒险结构.md v0.6):主种子恰一次注入(冒险内不重播种,同种子同操作序列逐位可复现);生命账本跨关同账(战后回写、恢复点按比例封顶、大奖励回满);GP 钱包跨关延续、冒险收束清零;统一冒险加算区(商店购买与大奖励同账);非末关通关发大奖励(上限提升 +10 读 adventure.tres、血回满、钥石 +10),末关不发上限提升、钥石照记;任意战斗倒下 = 冒险失败;结算屏出冒险摘要五件事(打穿没有/通关几关/止步第几关/钥石合计/主种子)。 - -**验证**:冒烟 437→482 项 0 失败三闸全过(冒险表 +4 / API 闸 +8 / 冒险验收 +33:表覆盖义务、满配通关、种子复现、大奖励恰 2 次与覆盖值传播、败北线两种子扫描、重复宣布拒绝、GP 跨关延续、加算区同账、恢复数学、放弃两态);MC 回归零行为变更(run_level 旧路径同种子逐位一致)。 - -## 2026-09-21 元进度实现批(跨局循环闭合——MetaTable + MetaProgression + 营地 + 跨局注入) - -**跨局成长首批落地**(设计权威 = 元进度.md v1.2):「存档在变厚」成为玩家可感的现实——冒险收束入账(大奖励渠道 + Boss 首杀/重复杀两档,明细在结算屏可归因)、营地消费、余额 HUD 常驻、永久强化在下一局开局注入。 - -**玩法面**:首页新增「营地 · 永久强化」入口(三柜台:属性锻造三档 flat 直购可重复升级、几何递增定价;秘宝匣六件按累计通关次数解锁——局内效果排 Alpha 魔法道具重设计批;奖励格图鉴占位锁定);A 区顶栏钥石余额常驻;冒险结算屏追加钥石入账明细(大奖励 / 逐关 Boss 首杀或重复 / 工坊新解锁)。买强化 → 下一局开局即生效(表值 + 永久强化 flat + 冒险加算区,再乘调整板百分比)。 - -**技术面**:`data/tables/meta.tres` 四行族(forge_products / boss_keystone / workshop_items / conversion)+ `core/meta_progression.gd` 账本服务(Core 层零 UI 零信号);SaveManager.apply_adventure_summary 增第二参 boss_drops(缺省 [] 零行为兼容,摘要元素附副本);AdventureRunner.start_adventure 增 params.hero_override(缺省全零 = 白板)→ LevelRunner base_override。**数值全 provisional 归元进度设计批配读数**(骨架先行先例 = GP+商店房批)。 - -**验证**:冒烟 522→549 项 0 失败三闸全过(表结构 +4 / 定价与购买 +7 / 注入与白板 +8 / 入账工坊摘要 +8);四探针全 PASS(ui_probe 营地开合/禁用态、click_probe 营地购买合成点击全路径——隔离存档换注保确定性,禁碰真实档);白板成立 = 空参数 = 零强化参数 = 纯表值三轴逐位一致。 - -## 2026-09-24 伤害管线单据化批(伤害对象抽象补全——伤害控制器统一入口) - -**架构面**:伤害此前无对象抽象——五族伤害来源(主角先手 / 敌方伤害技 / 棋盘克制直伤 / 群伤 / 反噬地形)在战斗编排器内各自内联组装管线。本批新建 `core/damage_controller.gd`(伤害单据 + 唯一兑付管线):九栏单据、五种兑付配方封闭枚举;battle_orchestrator 六调用点退化为开单点(流程决定何时开单给谁开单,单据怎么算归控制器),掷点 / 折扣 / 暴击 / 克制 / 池乘区 / 下限 / 攻击行文本算术全部迁入控制器(`_defender_ac` / `_clamped_pool` 留薄委托供快照面与冒烟白盒直呼);unit_container 新增 `unit_died` 死亡事件信号(单位自行宣布死亡——怪死其未结单据作废〔死亡即不动手〕、主角死兑付终止,Game Over 仍归判定段读数)。 - -**结账时机双模式(2026-09-24 用户三裁决之二三)**:目标 = 结账时刻照规则看现场解析(最前存活敌 / 主角 / 全体存活敌),开单不冻结对象;现行 = 段界结账(授予段尾 / 清图批同步点 / 战斗段尾统一兑现),开单即结保留为回切结构位(控制器 policy 常量一行切回=逐位还原迁移前行为)。同一输入两模式结果可不同(兑现时机语义差异),历史基线读数自本批以段界结账口径为准(重测归曲线调参批)。 - -**验证**:冒烟 557 项 0 失败双模式全绿三闸过;A/B 对拍探针四配置(L1/L2 × 双种子)两模式各自同种子逐位确定、四配置全部真实分岔(行数两两恒等、纯次序位移——分岔面 = 伤害行攒批位移与治疗满血判定时机,符合段界结账语义);三场景探针全 PASS。设计权威 = 战斗结算.md v0.24「伤害单据与伤害控制器」节。 - -## 2026-10-06 地图伤害账殿后批(案C,用户裁——「主角先手」歧义质询触发;设计权威 = 战斗结算.md v0.26) - -**裁决**:每轮结算内三者顺序定死 = ①授予段兑非伤害账(资源/增益/治疗/行动点/GP/警觉)→ ③战斗段「主角先基础攻击 → 敌人按生成序逐个还手 → 地图伤害账殿后」→ ④衰减 → ⑤判定。授予段不再当场兑付任何伤害——全部伤害形态单据(爆裂/直伤/反噬/地形变异/战封印军规/熔火反噬/惊巢反制/魔能共鸣/清障炸药等)暂存,战斗段怪物还手后按授予段事件序补提交统一结账;主角死于敌方还手 → 暂存单整体不兑,逐单留「未生效(主角已倒下)」行(载荷 forfeit=hero_down)。 - -**切片落点**:`battle_orchestrator.gd` 暂存闸 `_defer_board_damage`/`_deferred_board` + `_submit` 案C 分流(sync 同闸——清图批一致延后)+ `_outcome_of`(暂存单按「将兑付」回报——完美第二份/高光份数依据开单时点事实)+ 授予段四处直提改走闸 + 战斗段末补提交块(死亡守卫+留痕);授予段界 flush 保留(对空队 no-op 防御位);`smoke_all.gd` 行相位分类器换代(damage 恒战斗段/reward_ineffective 按 forfeit 分流)+ 先手断言收紧(「存在或授予段终局」→「必存在」)+ 新增案C 段内序断言(地图账不得先于主角先手或插入敌方还手中间)。 - -**验证**:冒烟 783 项 0 失败三闸过 + run_all 17 套全绿 + probe_gate(ui_input/ui_struct/ui_contrast/--click 行为走查)全绿、残留 0。**旧行为 MC 锚全数作废**(死亡短路语义变化:授予段伤害不再能致死短路先手;读数重采归数值批)。 - -## 2026-10-10 秘宝匣改名(文档面同步——2026-10-10 天赋树设计会话裁) - -营地柜台「道具工坊」正名「秘宝匣」(树上解锁节点与营地柜台同名):本文档现行正文扫改完毕;**代码标识符(workshop_items 等)与界面文案暂未动**——柜台 UI 名/表行语义连带面归 design/gdd/06-待办清单.md「天赋树结构重构批」实装批办理。 - -## 2026-10-11 专长实装批(迭代 20——奇物重设计 T0-T10 全落) - -**换代面**:feats.tres 整表换代(旧 27 件退役→重设计 29 行=基础 27+迁入淬毒刃纹/封印爆裂——订阅行 on/when/do 四级 rarity+cap);效果引擎词表扩签(事件 18/效果类型 30/事实 18/算子 +mod_eq——heal/ac_bonus/damage_reduce/bonus_delta/blast_scaled/preview_area/target_attack_bonus 七新类型+adventure 域计数器跨战账本);池结构案D(四级档位 70/25/9/0=104+曝光槽 2+1+概率上限解耦案②+Boss 按档配比加权抽取);凭证五件入池(刷新券 F-1 修复/储备金袋/同调电池〔choose_battery_target 玩家点选〕/时沙/完美保险);流派标签/档位激活机制退役(战斗路径 FeatsEngine 求值与 rider_tier 注入摘除;HUD 特性段呈现随 2026-10-12 呈现修复批换代——逐流派聚合行退役改逐件行「件名 ×N」、卡面摘族名,原聚合行在新 29 行下的空键兜底僵尸呈现随之消解)。 -**验证**:冒烟 864/0+run_all 21 套+probe_gate 全绿;MC 同种子重放 30 局逐位复现;新基线 normal/off 100 局通关 0%(master 对照同为 0%=零配基线本相,止步分布 90/10→93/7 可归因曝光槽)。设计权威=奇物.md(反哺点清单见 design/qa/iter20-实现报告-2026-10-11.md)。 - -## 2026-10-12 迭代 21 天赋树实装批(U0——需求卡片 v1.7;设计权威 = 天赋树.md v0.8) - -**结构换代 33→12 节点**:脊柱 2(生命/命中淬炼一线一节点 cap4——攻/护淬炼线随攻防所有权切分砍除,攻唯一入口=锻造工坊武器路线、AC 唯一入口=甲路线)+ 锻造脉 2(forge_workshop 钥匙 free 无前置 + easter_ley 彩蛋〔effects 摘攻/护分量〕)+ 钥石脉 2(秘宝匣/刷新升级)+ 同调脉 6(同调位 1/2/3——socket1 改根节点无前置 + Fork 3 单行双态)。schema 换代:FORK_GROUPS 4→3(fg_mastery 退役)/ RULE_KEYS 2→6 / row 字段退役(行门槛主语=节点第 N 级需全树总投入 ≥4×(N−1))/ requires 只留点亮前置(R1 裁撤案执行)。 - -**六键真效果**:开局姿态窗=每关首战首轮(FACTS 扩签 battle_index=关卡域战斗序);危险直觉锋=踩雷减半·守=标错返还 AP(EVENTS 扩签 seal_missed、契约 12 去重闸语义)——两组每关限次(adventure_counters domain=adventure、按关重置);财富之道聚=战斗掉落 GP 入账前×1.5、散=商品购买价×80%(双计价单点,刷新价不折)。数值全 provisional 归 M4。 - -**退役删除**:属性锻造柜台全家(buy_forge/forge_flat/meta_forge_row/forge_products 行族/forge_levels 存档域/营地·暂停层·生涯三投影);migrate_tree 三体系迁移(旧档=tree_struct 标记检测破坏性废弃重置,禁迁移折算);attunement_growth 谓词表(同调位槽位判定源切树点亮数——Q2 裁甲)。 - -**营地统一**:四柜台并排(树淬炼=树脊柱界面形态主界面/锻造工坊柜台钥匙门+零交互占位面板/秘宝匣柜台钥匙门+工坊六行+同调装配段+Y 升级行迁入/图鉴常开);刷新升级双入口同账(树上 ks_refresh 路由 buy_attune_refresh)。 - -**验证**:冒烟 886/0(基线 864/0+存量红修复——fx_reveal 三处空 source_class 补标签,a57489e9 落地件 51 行脚本错误清零)+ run_all 22 套(新增 tree_rules_v11 六键闭集校验)+ probe --click 全绿(树购买/双态切换点击路径换代);V10 行为段=引擎直构+编排授予段直注(守侧五场景/聚散同种子配对/限次生命周期)。存量红修复与帐目细节见 design/qa/iter21-实现报告-2026-10-12.md。 - -## 2026-10-12 迭代 23 锻造工坊实装批(U0——需求卡片 v1.2;设计权威 = 锻造工坊.md v0.6) - -**六路线行族新建**:新表 `forge.tres`(schema `forge_table.gd`/ForgeTable——默认两轴常驻持有 + routes 六行;ConfigDB `forge_*` 访问器:forge_route/forge_routes/forge_default_attack_type/forge_default_armor_type/forge_weapon_route_by_type/forge_armor_route_by_type)。路线 id=sword/spear/staff/light/heavy/ward(甲路线 id=甲型值本身);provisional 沿锚表:cap 5/每级增量统一 +1/基础价 20×150%^n(20/30/45/67/101)/一次性解锁价 200/甲型基础 AC 10-12-9/初始持有 sword+light/并联双通道前置 spear·staff←sword、heavy·ward←light。 - -**两根类型轴所有权移交**:`hero.tres` armor_type/attack_type 两字段删除(schema 同步删)——默认值归 forge.tres 常驻持有(normal/light);选中态写存档域 forge_routes、冒险开始经参数面注入。单位快照读取面=unit_container.spawn 新两参(空串=锻造配置默认值回退,行为逐位连续);冒烟 hero_attack 行类型键主语换代为 forge_default_attack_type()。 - -**写口族与注入链**:MetaProgression 锻造写口(契约 9 唯一)——forge_buy_level(几何价扣钥石即盘)/forge_buy_unlock(一次性解锁价,已解锁含派生=拒绝零收费)/forge_select_weapon·armor(免费切换只受理已解锁)/forge_route_unlocked(派生单点:初始持有∨直购∨练满前一档)。hero_override 公式换代(FORGE_ROUTE_BONUS 预留常量退役):atk=当前选中武器攻击加值+树 flat、armor_class=当前甲 AC 加值+树 flat、max_hp=树 flat;main.build_adventure_params +attack_type/armor_type 两键 → AdventureRunner 参数面快照(契约 8 冒险开始锁死)→ LevelRunner.set_hero_axes → enc → spawn;入战 AC 三层=甲型基础 AC(选中甲路线 base_ac)+甲路线等级加值+局内加算区。 - -**存档 v7**:SAVE_FORMAT_VERSION 6→7 + 新域 forge_routes({levels 六键/unlocked 直购清单/weapon/armor 选中},无特效域)+ _migrate_v6_v7 空迁移(缺键补齐=初始持有态)+ 访问器组;旧档缺键补齐零折算。 - -**营地工作间**:锻造工坊柜台占位面板→两区六路线行板(武器锻造区/护甲锻造区;件名+Lv+解锁态双通道文案+锻造/解锁/选中钮;余额联动禁用;锁定态零行板零购买路径——占位纪律延续);三意图信号 forge_buy/unlock/select_requested 经 camp_shop_presenter 走写口唯一路径。 - -**验证**:冒烟 938/0(基线 898/0+40 锻造断言)+ run_all 24 套(新增 forge_table_test 41 断言+forge_workbench_test 12 断言)+ probe --click/--full 全绿 + render_gate + doc 三闸/熵增对基线零新增 + MC 同种子配对零漂移。实现报告=design/qa/iter23-实现报告-2026-10-12.md。 +> 历次批次的改动明细与决策过程见 git 提交史(`git log -- game/README.md` 及各批提交信息),本文只保留运行说明与范围。 diff --git a/game/core/action_economy.gd b/game/core/action_economy.gd index f94b90b5..90c29b49 100644 --- a/game/core/action_economy.gd +++ b/game/core/action_economy.gd @@ -12,12 +12,12 @@ const PHASE_IDLE := "Idle" const PHASE_ACTIVE := "Active" const PHASE_WAITING := "Waiting" -# 相位轴(P6 状态机——code-review 2026-09-29 P2-2):内部 enum + match,外部 phase getter 保持 -# String 面(presentation_snapshot 与冒烟链的 "Idle"/"Active"/"Waiting" 对照契约零变化)。 +# 相位轴:内部 enum + match,外部 phase getter 保持 +# String 面(presentation_snapshot 与冒烟链的 "Idle"/"Active"/"Waiting" 对照契约)。 enum Phase { IDLE, ACTIVE, WAITING } var db: ConfigDb -# 相位与账本只读出口(E5 封装收口 2026-09-13):外部读取经 getter-only 属性(架构文档 +# 相位与账本只读出口:外部读取经 getter-only 属性(架构文档 # "ap/rap/phase 只读" 的机制化),写入只经 notify_* / request_* 方法通道。 var _phase: int = Phase.IDLE var phase: String: @@ -33,17 +33,16 @@ var last_round_end: Dictionary[Variant, Variant]: get: return _last_round_end var _settlement_consumed := false # AC-14 门:notify_settlement_done 消费后才受理 round_start var _next_round_mode := "" # 调试观测量(同板续轮 / 换新图) -var _pending_ap_delta := 0 # 下轮行动点修正排队(格面资源八型批 2026-09-20——action 型 ±1 排队,轮开始兑现后清零) -# 蓄力流运行态(迭代 12 T5 → 内容数据驱动扩展批 T3 换代:旧 feat_ap_carry/feat_dig_extra 注入封印 -# 退役——转蓄力=round_end grant_ap(mode:transfer) 订阅(finish_round_stop 定夺)、深挖对价=dig_paid -# counter_spend 订阅(request_dig 施加面);charge_layers=蓄力层账本) +var _pending_ap_delta := 0 # 下轮行动点修正排队(action 型 ±1 排队,轮开始兑现后清零) +# 蓄力流运行态:转蓄力=round_end grant_ap(mode:transfer) 订阅(finish_round_stop 定夺)、 +# 深挖对价=dig_paid counter_spend 订阅(request_dig 施加面);charge_layers=蓄力层账本 var _charge_layers := 0 var charge_layers: int: get: return _charge_layers -# 效果引擎(内容数据驱动扩展批 T1——dig_paid/charge_full 发射面;round_end 转存决策面) +# 效果引擎(dig_paid/charge_full 发射面;round_end 转存决策面) var _fx: EffectEngine = null -var _last_stop_ap := 0 # 停手侧剩余 AP 记账(转存决策移至 round_end 发射点——grant_ap(transfer) 订阅定夺) -var _ap_exhausted_last := false # 上轮 AP 耗尽封印(迭代 20 T1——一滴不剩 round_start when 面) +var _last_stop_ap := 0 # 停手侧剩余 AP 记账(转存决策在 round_end 发射点——grant_ap(transfer) 订阅定夺) +var _ap_exhausted_last := false # 上轮 AP 耗尽封印(一滴不剩 round_start when 面) func set_fx(fx: EffectEngine) -> void: @@ -67,7 +66,7 @@ func _cost(kind: String) -> int: var ae = db.action_economy match kind: "dig": - return ae.dig_ap_cost # 基础挖格成本恒表值(钻头对价挂付费开掘侧——2026-10-04 缺陷修复) + return ae.dig_ap_cost # 基础挖格成本恒表值(钻头对价挂付费开掘侧) "seal_place": return ae.seal_place_ap_cost "move": @@ -87,8 +86,7 @@ func try_spend(action_kind: String) -> bool: # 排雷玩法 挖掘专用:chain_size = 连锁附加格数(不含首格);clears_map = 本次动作后全图安全格开完。 -# 深挖钻头付费开掘(内容数据驱动扩展批 T3——dig_paid counter_spend 订阅施加面,2026-10-04 缺陷 -# 修复口径不变):按序消耗族——AP 富余(≥基础+对价)时本动作付全价并积本轮付费计数(效果引擎 +# 深挖钻头付费开掘(dig_paid counter_spend 订阅施加面):按序消耗族——AP 富余(≥基础+对价)时本动作付全价并积本轮付费计数(效果引擎 # 计数器=授予段追加产出配额取数面);AP 不足全价时 fallback 降级只付基础 1 照常开格、不积计数 # ——持有钻头永不锁死普通挖格(散件保底 B-2)。 func request_dig(chain_size: int, clears_map: bool) -> bool: @@ -96,9 +94,9 @@ func request_dig(chain_size: int, clears_map: bool) -> bool: _reject("phase") return false var cost := _cost("dig") - # dig_paid 发射+施加(内容数据驱动扩展批 T3——付费开掘发起、动作经济闸收对价前: + # dig_paid 发射+施加(付费开掘发起、动作经济闸收对价前: # counter_spend 命中=尝试加收对价并积计数;资源不足走 fallback/耗尽即止=只付常规基础对价。 - # 迭代 20 T1——counter_add〔双管镐 付费挖格计数〕/ grant_ap〔每第 2 次返 1 AP——对价减免, + # counter_add〔双管镐 付费挖格计数〕/ grant_ap〔每第 2 次返 1 AP——对价减免, # mod_eq 闸在行 when〕同面施加) var dig_refund := 0 if _fx != null: @@ -153,16 +151,14 @@ func _spend_and_arbitrate(action_kind: String, clears_map: bool) -> bool: # 停手:剩余 AP 1:1 转存 RAP;行动经济 直发 stopped 路径 round_end(双发射源)。 -# 整备军备改写(迭代 12 T5——feat_ap_carry=true 时剩余 AP 转蓄力层〔上限 3〕替代 RAP 转存: -# 「不动也是行动」——cleared 作废口径改写的停手侧承载;cleared 分支 AP 恒清零维持既有作废语义)。 -# 内容数据驱动扩展批 T1:本方法改记账制——剩余 AP 存 _last_stop_ap 后清零,转存决策移至 -# round_end 发射点 finish_round_stop(grant_ap(mode:transfer) 订阅定夺;双轨期旧封印 feat_ap_carry -# 并行生效,行为与迁移前逐位一致)。 +# 转蓄力层〔上限 3〕替代 RAP 转存——「不动也是行动」;cleared 分支 AP 恒清零维持作废语义。 +# 本方法只记账——剩余 AP 存 _last_stop_ap 后清零,转存决策在 round_end 发射点 +# finish_round_stop(grant_ap(mode:transfer) 订阅定夺)。 func request_stop() -> bool: if _phase != Phase.ACTIVE: _reject("phase") return false - # dig_stop 发射+施加(迭代 20 T1——停手挂点〔弃图兑换〕:剩余 AP 随载荷外发,counter_add + # dig_stop 发射+施加(停手挂点〔弃图兑换〕:剩余 AP 随载荷外发,counter_add # value_event="ap_left" 取值面〔值=停手时刻真实余量〕;发射先于记账清零) if _fx != null: for h in _fx.dispatch("dig_stop", {"ap_left": _ap}): @@ -178,14 +174,14 @@ func request_stop() -> bool: return true -# 储备池注入(迭代 20 T4——储备金袋凭证:战首 RAP +N,节点级一次性;任意相位受理=战首注入时 Idle/Active 均合法) +# 储备池注入(储备金袋凭证:战首 RAP +N,节点级一次性;任意相位受理=战首注入时 Idle/Active 均合法) func grant_reserve_ap(n: int) -> void: _rap += maxi(0, n) # 轮末停手转存决策(round_end 发射点调用——编排器授予段尾):transfer=true=剩余 AP 转蓄力层 -# (上限 3,整备军备面);false=按转存率转存 RAP(transfer_pct 百分比口径缺省 100=1:1 与旧逐位一致; -# 迭代 22 秘宝批 T3——储备罐 rap_transfer_mult magnitude 125=1.25:1,整数除法向下取整=每 4 AP 多转 1)。 +# (上限 3,整备军备面);false=按转存率转存 RAP(transfer_pct 百分比口径缺省 100=1:1; +# 储备罐 rap_transfer_mult magnitude 125=1.25:1,整数除法向下取整=每 4 AP 多转 1)。 # 非停手轮(cleared/耗尽)_last_stop_ap=0 两分支均零操作。转蓄后达上限的沿发 charge_full(R6 框架先行——现无订阅者)。 func finish_round_stop(transfer: bool, transfer_pct: int = 100) -> void: if transfer: @@ -198,7 +194,7 @@ func finish_round_stop(transfer: bool, transfer_pct: int = 100) -> void: _last_stop_ap = 0 -# 轮内刷新(2026-09-12 方案 A 用户拍板;等待期通道 2026-09-15 用户拍板整体移除):唯一入口 = +# 轮内刷新:唯一入口 = # Active 相位——仅扣 RAP,相位与 AP 均不动。刷新不打断轮次、不触发结算;换图编排归 战斗结算 # (retire + install 立即执行,玩家同轮继续挖新图)。决策主体 = 玩家(经 HUD框架发起)纪律不变。 func request_refresh() -> bool: @@ -221,9 +217,9 @@ func notify_settlement_done(next_round_mode: String) -> bool: return true -# 下轮行动点修正排队(格面资源八型批 2026-09-20):action 型正负行结算期调用,同轮多次授予累加; +# 下轮行动点修正排队:action 型正负行结算期调用,同轮多次授予累加; # 相位无关(授予发生在结算段,此时本类可能处于 ACTIVE/WAITING 任一相位) -# 第 9 API(registry 行动经济×① 接口漂移预授权——迭代 7 T2 秘宝内容批落位):ap_grant 道具的 +# 第 9 API(registry 行动经济×① 接口漂移预授权):ap_grant 道具的 # 当轮行动点加量(GDD「加行动点效果给当轮」——区别于 queue_ap_delta 的下轮排队语义)。Active 受理、 # 无上限域、零随机;使用道具本身零扣费(成本在获取时已付——捡道具格不出战斗奖励)。 func grant_ap(amount: int) -> bool: @@ -262,7 +258,7 @@ func notify_combat_end() -> bool: _reject("phase") return false _phase = Phase.IDLE - _rap = 0 # RAP 战斗域清零(用户拍板;HUD框架可见反馈义务) + _rap = 0 # RAP 战斗域清零(HUD框架可见反馈义务) _ap = 0 return true @@ -273,11 +269,11 @@ func _finish_round(path_tag: String, continuation_hint: String) -> void: assert(path_tag != "ap_exhausted" or _ap == 0, "耗尽轮剩余行动点恒为 0(实现层断言兜底)") assert(path_tag != "cleared" or _ap == 0, "清图轮剩余行动点当场清零(不进储备池)") _last_round_end = {"path_tag": path_tag, "continuation_hint": continuation_hint} - _ap_exhausted_last = path_tag == "ap_exhausted" # 迭代 20 T1——一滴不剩 when 面(轮始发射读数) + _ap_exhausted_last = path_tag == "ap_exhausted" # 一滴不剩 when 面(轮始发射读数) _phase = Phase.WAITING -# 上轮 AP 是否耗尽(迭代 20 T1——round_start 发射 payload 读数面;轮始兑现后保持到本轮末) +# 上轮 AP 是否耗尽(round_start 发射 payload 读数面;轮始兑现后保持到本轮末) func ap_exhausted_last_round() -> bool: return _ap_exhausted_last diff --git a/game/core/adventure_runner.gd b/game/core/adventure_runner.gd index 870dda28..b7e1462d 100644 --- a/game/core/adventure_runner.gd +++ b/game/core/adventure_runner.gd @@ -7,9 +7,9 @@ class_name AdventureRunner extends RefCounted signal level_started(level_index: int, display_name: String) # 每关开始(含冒险首关)——呈现层重取 runner()、刷新图条与层名行 -signal curio_choice_presented(payload: Dictionary) # 专长三选一停点(非末关通关恰一次;迭代 20 T5 换代正名——旧「提升三选一」退役,通道白名单后候选恒专长+回血在载荷)——{level_index, candidates, heal_gained, hp_before, hp_after, keystone_gained, keystone_total, gp, aux_cleared} +signal curio_choice_presented(payload: Dictionary) # 专长三选一停点(非末关通关恰一次;通道白名单后候选恒专长+回血在载荷)——{level_index, candidates, heal_gained, hp_before, hp_after, keystone_gained, keystone_total, gp, aux_cleared} signal curio_resolved(result: Dictionary) # 三选一兑付完成(pick_curio/替换受理后恰一次)——{picked, value, hp_before, hp_after, level_index} -signal adventure_finished(summary: Dictionary) # 冒险结算(completed/failed/abandoned)——summary 五件事:打穿没有/通关几关/止步第几关/钥石合计/主种子(+additive keystone_drops 迭代 10) +signal adventure_finished(summary: Dictionary) # 冒险结算(completed/failed/abandoned)——summary 五件事:打穿没有/通关几关/止步第几关/钥石合计/主种子(+additive keystone_drops) # ---- 转发族(签名与 LevelRunner 同款——呈现层对接透明;S6 经 _forward_* 方法)---- signal node_entered(node: Dictionary, info: Dictionary) signal choices_presented(candidates: Array) @@ -20,19 +20,19 @@ signal wallet_changed(event: String, gp: int, extra: Dictionary) var db: ConfigDb var rng: RngServiceCore -enum State { IDLE, RUNNING, SETTLING } # 会话状态机(迭代 27 T6——裸字符串 enum 化:内部 enum,外部 String 契约 getter 词表逐位一致) +enum State { IDLE, RUNNING, SETTLING } # 会话状态机(内部 enum,外部 String 契约经 getter 词表) var _state: State = State.IDLE -var state: String: # 外部契约面(只读——外部零写点实证;"idle"/"running"/"settling" 零变化) +var state: String: # 外部契约面(只读——外部零写点实证;词表 "idle"/"running"/"settling") get: return State.keys()[_state].to_lower() var ledger := {"hero_hp": 0, "gp": 0} # 冒险账本(生命 + GP 钱包——经 start_level_external 注入 runner 共享) -var run_ledger := RunLedger.new() # 共享四本账(迭代 27 T3——P1-4 收口:attune_charges/vision_counter/adventure_counters/bonus 单类持账;裁点②甲) +var run_ledger := RunLedger.new() # 共享四本账(attune_charges/vision_counter/adventure_counters/bonus 单类持账) var purchased := {} # product_id → 已购档数(跨关延续、冒险收束清零——递增定价输入) var level_index := 0 # 当前关卡序号(1 起) var levels_total := 0 # 序列总关数(读 level 表行数) var keystone := 0 # 钥石入账累计(摘要第三件事的账面) var master_seed := 0 # 本局主种子(摘要第五件事) -# 两根类型轴冒险开始快照(迭代 23 T4——契约 8:营地选中态经参数面注入、冒险开始后锁死; +# 两根类型轴冒险开始快照(契约 8:营地选中态经参数面注入、冒险开始后锁死; # 公有=参数面快照的可断言面〔契约 9 写口唯一,本字段只读不改〕。空串=未注入→消费面回退锻造配置默认值) var hero_attack_type := "" var hero_armor_type := "" @@ -42,32 +42,32 @@ var _pending_next_level := false # 大奖励已兑付、等 continue_to var _last_level_payload := {} # 最近一次关卡结束载荷(失败结算的败退节点明细来源——数值验证取数面) var _override := [0, 0] # 调试浮窗百分比通道 [atk_pct, hp_pct](每关新 runner 都要应用) var _base_override := {"atk": 0, "max_hp": 0, "armor_class": 0} -var _first_script := false # 首次脚本模式(关卡节点图生成 v0.4——true = 全关零抽签取池内模板 0;测量夹具恒 false) # 永久强化 flat 注入(元进度实现批——冒险开始参数面 params.hero_override 存入,共享给 LevelRunner;全零 = 白板) -var _last_treasure_cleared := 0 # additive(迭代 7 T4——最近一次关卡末清空计数,summary 取数面) -var _treasure_unlocked := {} # aux 解锁门控集(迭代 7 T5——params.treasure_unlocked 接收面) -var _attunement: Array[Variant] = [] # 同调装配集(迭代 11 第①批 T5——params.attunement 接收面,start_level 外下传 LevelRunner) -var _attune_refresh_x := 0 # 刷新件余量(迭代 11 第①批 T5b P1 甲——每碰三选一重置=X 表值;优先消耗、不结转) +var _first_script := false # 首次脚本模式(关卡节点图生成 v0.4——true = 全关零抽签取池内模板 0;测量夹具恒 false) # 永久强化 flat 注入(冒险开始参数面 params.hero_override 存入,共享给 LevelRunner;全零 = 白板) +var _last_treasure_cleared := 0 # additive(最近一次关卡末清空计数,summary 取数面) +var _treasure_unlocked := {} # aux 解锁门控集(params.treasure_unlocked 接收面) +var _attunement: Array[Variant] = [] # 同调装配集(params.attunement 接收面,start_level 外下传 LevelRunner) +var _attune_refresh_x := 0 # 刷新件余量(每碰三选一重置=X 表值;优先消耗、不结转) var _attune_refresh_y := 0 # Y 冒险周期池(开局参数面注入,用完即无——营地升级行表值) -var _curio_paid_refreshes := 0 # 本次停点已付费刷新次数(2026-10-06 用户令对齐商店 MC-1——GP 刷新价曲线输入,随停点创建清零=与商店进店清零同构) -# ---- 凭证件三本新账(迭代 20 T4——奇物.md 凭证件表新 5 件;F-1 刷新写错账修复承载面)---- -var _refresh_stock := 0 # 刷新存量账(冒险级——刷新券加仓;**不经 _attune_refresh_x**:X 每停点重置会吞存量=旧写错账缺陷 F-1) +var _curio_paid_refreshes := 0 # 本次停点已付费刷新次数(对齐商店 MC-1——GP 刷新价曲线输入,随停点创建清零=与商店进店清零同构) +# ---- 凭证件三本账(奇物.md 凭证件表 5 件;F-1 刷新写错账修复承载面)---- +var _refresh_stock := 0 # 刷新存量账(冒险级——刷新券加仓;**不经 _attune_refresh_x**:X 每停点重置会吞存量=写错账缺陷 F-1) var _pending_rap := 0 # 储备金袋待注入(节点级——下一战 RAP +N,战首注入后清零) var _time_sand_queue := 0 # 时沙待注入(回合级——下一战首轮 AP +N,战首入队后清零) -var _save_manager = null # 断点承载注入(迭代 8 卡①——null = 不写断点;模拟/冒烟缺省) +var _save_manager = null # 断点承载注入(null = 不写断点;模拟/冒烟缺省) var _resume_bp := {} # 续玩快照暂存(resume_adventure → _start_current_level 单跳传递) -# ---- 三选一停点态(迭代 10 奖励重构批)---- +# ---- 三选一停点态 ---- var _curio_taken := {} # 件获取次数计数(kind 维度派生账本——断点附随件与摘要读数承载;池库存正主=_curio_deck) -var _curio_deck: Array[Variant] = [] # 令牌池(TP0 v2.2——持久多重集,元素 {"kind","tier"};洗牌抽候选/选中踢池未选回池/池耗即枯竭;商店货架同库共账;迭代 12 T1 起规则改写型特性带=relic 令牌随表追加) -var _feats: Array[String] = [] # 特性持有集(迭代 12 T1——局内随机渠道获得、冒险级跨关携带、收束清零;🔴 层级纪律承载面:不入同调位不入局外树) -var _tree_rules: Array[Variant] = [] # 树 rule 键集(迭代 12 T10——Fork 激活侧 effects 透传;下传 enc.tree_rules 消费面) +var _curio_deck: Array[Variant] = [] # 令牌池(TP0 v2.2——持久多重集,元素 {"kind","tier"};洗牌抽候选/选中踢池未选回池/池耗即枯竭;商店货架同库共账;规则改写型特性带=relic 令牌随表追加) +var _feats: Array[String] = [] # 特性持有集(局内随机渠道获得、冒险级跨关携带、收束清零;🔴 层级纪律承载面:不入同调位不入局外树) +var _tree_rules: Array[Variant] = [] # 树 rule 键集(Fork 激活侧 effects 透传;下传 enc.tree_rules 消费面) var _curio_pending := {} # 停点态:{"candidates": Array, "payload": Dictionary, "chosen"/"incoming": 替换在途}——空 = 无停点 var _curio_result := {} # 已兑付待推进态(curio_resolved 载荷副本——中断续玩不重兑付) var _keystone_drops: Array[Variant] = [] # Boss 逐杀掉落明细(additive 摘要键 keystone_drops——结算明细/复盘归因数据源) -var _node_curio_pending := {} # 奖励节点三选一停点态(迭代 10 追加批——共享池;断点不载:续玩重建到选路停点重走,恢复的计数器保证同候选重抽) +var _node_curio_pending := {} # 奖励节点三选一停点态(共享池;断点不载:续玩重建到选路停点重走,恢复的计数器保证同候选重抽) var _feat_ticket_pity := 0 # 门票保底计数(T5——展示次数:节点开面/货架抽签/刷新重展各计一次;触发清零) var _feat_ticket_sold := 0 # 门票限购计数(T5——选中/买下即 +1;拿到即开不进持有集) var _feat_ticket_appeared := 0 # 门票出现计数(T5——quota 上限面) -var _shop_mode := "legacy" # 商店模式(迭代 11 第②批 T3——"legacy"=固定三件加定价〔off 对照承载,缺省零扰动〕/"pool"=共享池抽 3 买 1 重抽;真实入口 main.gd 显式投 pool) +var _shop_mode := "legacy" # 商店模式("legacy"=固定三件加定价〔off 对照承载,缺省零扰动〕/"pool"=共享池抽 3 买 1 重抽;真实入口 main.gd 显式投 pool) func _init(db_ref: ConfigDb, rng_ref: RngServiceCore) -> void: @@ -93,34 +93,34 @@ func start_adventure(seed_val: int, params: Dictionary = {}) -> bool: keystone = 0 summary = {} _reset_curio_state() - levels_total = db.level_count() # 表访问收口(2026-10-02——行集直扫退役) + levels_total = db.level_count() # 表访问收口(关数读 level 表行数) level_index = 1 _pending_next_level = false _base_override = _normalize_override(params.get("hero_override", {})) - hero_attack_type = String(params.get("attack_type", "")) # 迭代 23 T4——两根类型轴快照(契约 8 锁死:开局后不随存档选中变化) + hero_attack_type = String(params.get("attack_type", "")) # 两根类型轴快照(契约 8 锁死:开局后不随存档选中变化) hero_armor_type = String(params.get("armor_type", "")) _first_script = bool(params.get("first_script", false)) # 缺省 = 非首次(抽签路径;真实侧由呈现层读存档布尔位传入) - _shop_mode = "pool" if String(params.get("shop_mode", "legacy")) == "pool" else "legacy" # 迭代 11 第②批 T3——缺省 legacy(off 对照零扰动) + _shop_mode = "pool" if String(params.get("shop_mode", "legacy")) == "pool" else "legacy" # 缺省 legacy(off 对照零扰动) _treasure_unlocked = params.get("treasure_unlocked", {}) if params.get("treasure_unlocked", {}) is Dictionary else {} - _attunement = params.get("attunement", []) if params.get("attunement", []) is Array else [] # additive(迭代 11 第①批 T5) - _attune_refresh_y = maxi(0, int(params.get("attune_refresh_y", 0))) # additive(迭代 11 第①批 T5b——Y 冒险周期池) - _seed_attune_charges() # 迭代 11 第①批 T6——冒险开始充能账本按装备主动件重置(每冒险充能语义) - run_ledger.vision_counter = {"used": 0} # 迭代 22 秘宝批 T3——真视使用计数冒险开始归零(跨局累计归生涯档) - # 刷新练习开局注入(迭代 22 秘宝批 T3——refresh_stock_grant 装配即得一次性加仓: + _attunement = params.get("attunement", []) if params.get("attunement", []) is Array else [] # additive + _attune_refresh_y = maxi(0, int(params.get("attune_refresh_y", 0))) # additive(Y 冒险周期池) + _seed_attune_charges() # 冒险开始充能账本按装备主动件重置(每冒险充能语义) + run_ledger.vision_counter = {"used": 0} # 真视使用计数冒险开始归零(跨局累计归生涯档) + # 刷新练习开局注入(refresh_stock_grant 装配即得一次性加仓: # 装配集 kind 分发扫描;只入存量账 _refresh_stock、临时账不动=V8 契约;resume 不重注入〔存量随断点已在〕) for iid_v2 in _attunement: var rp_row: Dictionary[Variant, Variant] = db.treasure_item_row(String(iid_v2)) if (rp_row.get("effect_kinds", []) as Array).has("refresh_stock_grant"): _refresh_stock += int(rp_row.get("magnitude", 0)) - # 特性开局注入(迭代 12 T7——MC 成型画像载体:params.relics_seed 非空=开局持有集〔七流派 + # 特性开局注入(MC 成型画像载体:params.relics_seed 非空=开局持有集〔七流派 # 各 2 件档一成型——测量面专用;真实局规则改写型特性只走局内随机渠道,红线②层级纪律不破〕) var feat_seed: Array[Variant] = params.get("relics_seed", []) if params.get("relics_seed", []) is Array else [] - _tree_rules = params.get("tree_rules", []) if params.get("tree_rules", []) is Array else [] # 迭代 12 T10——A/B 面 rule 键集 + _tree_rules = params.get("tree_rules", []) if params.get("tree_rules", []) is Array else [] # A/B 面 rule 键集 if not feat_seed.is_empty(): _feats = [] for r in feat_seed: _feats.append(String(r)) - ledger["hero_hp"] = effective_max_hp() # 生命账本置满(生效上限口径——T17 修复:含调试浮窗 pct,与战斗内同源) + ledger["hero_hp"] = effective_max_hp() # 生命账本置满(生效上限口径:含调试浮窗 pct,与战斗内同源) _state = State.RUNNING return _start_current_level() @@ -133,7 +133,7 @@ func _normalize_override(raw: Dictionary) -> Dictionary: return out -# 断点续玩(迭代 8 卡①——「继续上局」入口;bp = save.breakpoint_snapshot() 快照,params 同 start_adventure +# 断点续玩(「继续上局」入口;bp = save.breakpoint_snapshot() 快照,params 同 start_adventure # 的注入参数面):账面(生命/GP/加算区/已购档/钥石累计)逐字段回填 + rng.restore_adventure 回填 # 「主种子+计数器」→ _start_current_level 续玩路径(模板随快照强制、重建到停点节点,零重抽)。 # 快照缺字段按防御默认(空快照拒绝——调用方先 has_breakpoint)。 @@ -155,7 +155,7 @@ func resume_adventure(bp: Dictionary, params: Dictionary = {}) -> bool: purchased = (bp.get("shop_purchased", {}) as Dictionary).duplicate(true) keystone = int(bp.get("keystone", 0)) summary = {} - levels_total = db.level_count() # 表访问收口(2026-10-02——行集直扫退役) + levels_total = db.level_count() # 表访问收口(关数读 level 表行数) level_index = int(bp.get("level_index", 1)) _pending_next_level = false _reset_curio_state() @@ -163,9 +163,9 @@ func resume_adventure(bp: Dictionary, params: Dictionary = {}) -> bool: for id in _curio_taken.keys(): _curio_taken[id] = maxi(0, int(bp_taken.get(id, 0))) for id in bp_taken.keys(): - _curio_taken[String(id)] = maxi(0, int(bp_taken.get(id, 0))) # 迭代 20 T2——身份维键(relic:)随快照还原 + _curio_taken[String(id)] = maxi(0, int(bp_taken.get(id, 0))) # 身份维键(relic:)随快照还原 # 令牌池余库还原(TP0 v2.2——快照缺键 = 旧版断点,保持满库重建态:旧档只读一版周期的防御口径; - # 迭代 12 T1——relic 令牌 feat_id 随还原) + # relic 令牌 feat_id 随还原) var bp_deck = bp.get("bonus_deck", null) if bp_deck is Array: var restored: Array[Variant] = [] @@ -176,38 +176,38 @@ func resume_adventure(bp: Dictionary, params: Dictionary = {}) -> bool: rtok["feat_id"] = String(tok.get("feat_id", "")) restored.append(rtok) _curio_deck = restored - # 特性持有集还原(迭代 12 T1——缺键 = 旧版断点防御空集) + # 特性持有集还原(缺键 = 旧版断点防御空集) _feats = [] for r in (bp.get("relics", []) as Array): _feats.append(String(r)) _keystone_drops = (bp.get("keystone_drops", []) as Array).duplicate(true) _base_override = _normalize_override(params.get("hero_override", {})) - hero_attack_type = String(params.get("attack_type", "")) # 迭代 23 T4——续玩参数面同 start_adventure(账号层选中态随 resume 重注入) + hero_attack_type = String(params.get("attack_type", "")) # 续玩参数面同 start_adventure(账号层选中态随 resume 重注入) hero_armor_type = String(params.get("armor_type", "")) - # 生命账本越界钳制(T17——spawn 守卫 EC16 免疫):断点可能由旧口径版本写出(如调试上限 - # 调高期带出的账本值 > 新口径生效上限,实例:hero_hp=28 > 基础 26)——恢复后钳到生效上限, + # 生命账本越界钳制(T17——spawn 守卫 EC16 免疫):断点可能带出高于生效上限的账本值 + # (如调试浮窗调高期写出的值,实例:hero_hp=28 > 基础 26)——恢复后钳到生效上限, # 否则首战 spawn「hero_hp 入参越界」拒收 → 「敌人系统 spawn 被拒」fatal。上限 = 表值+永久 # 强化 flat+加算区 flat 后乘调试浮窗 pct(effective_max_hp 同式——此刻加算区尚未恢复, # 钳制用 flat 已含的保守口径即可,加算区恢复后其余战斗照常)。 ledger["hero_hp"] = mini(int(ledger.get("hero_hp", 0)), maxi(1, int(round(float(int(db.hero.max_hp) + int(_base_override.get("max_hp", 0))) * (100.0 + float(_override[1])) / 100.0)))) _first_script = false # 续玩模板已随快照强制(已抽模板零重抽)——脚本模式不重放 - _shop_mode = "pool" if String(params.get("shop_mode", "legacy")) == "pool" else "legacy" # 迭代 11 第②批 T3——续玩参数面同 start_adventure(缺省 legacy) + _shop_mode = "pool" if String(params.get("shop_mode", "legacy")) == "pool" else "legacy" # 续玩参数面同 start_adventure(缺省 legacy) _treasure_unlocked = params.get("treasure_unlocked", {}) if params.get("treasure_unlocked", {}) is Dictionary else {} - _attunement = params.get("attunement", []) if params.get("attunement", []) is Array else [] # additive(迭代 11 第①批 T5) - _attune_refresh_y = maxi(0, int(bp.get("attune_refresh_y", int(params.get("attune_refresh_y", 0))))) # 2026-10-13 缺陷修批——Y 余量优先读断点(花掉不回血=堵「用完退菜单再续玩满血复活」可利用漏洞);缺键=旧版断点,回退参数面整额注入(旧档行为零变化) - _seed_attune_charges() # 迭代 11 第①批 T6——冒险开始充能账本按装备主动件重置(每冒险充能语义) - _tree_rules = params.get("tree_rules", []) if params.get("tree_rules", []) is Array else [] # 迭代 12 T10——A/B 面 rule 键集(尾裁微批b 2026-10-08 卡⓪受理闭环:续玩参数面同 start_adventure :135 同式,消费面 set_tree_rules 下传现成零改) - # 三选一停点续玩分支(迭代 10——选择态/已兑付态不重跑关卡;奖励选择态不重抽、已兑付不重付) + _attunement = params.get("attunement", []) if params.get("attunement", []) is Array else [] # additive + _attune_refresh_y = maxi(0, int(bp.get("attune_refresh_y", int(params.get("attune_refresh_y", 0))))) # Y 余量优先读断点(花掉不回血=堵「用完退菜单再续玩满血复活」可利用漏洞);缺键=旧版断点,回退参数面整额注入(旧档行为零变化) + _seed_attune_charges() # 冒险开始充能账本按装备主动件重置(每冒险充能语义) + _tree_rules = params.get("tree_rules", []) if params.get("tree_rules", []) is Array else [] # A/B 面 rule 键集(续玩参数面同 start_adventure 同式,消费面 set_tree_rules 下传) + # 三选一停点续玩分支(选择态/已兑付态不重跑关卡;奖励选择态不重抽、已兑付不重付) var bp_pending: Dictionary[Variant, Variant] = bp.get("bonus_pending", {}) as Dictionary _feat_ticket_pity = int(bp.get("feat_ticket_pity", 0)) # T5 扩列——旧档缺键缺省 0(存档兼容) _feat_ticket_sold = int(bp.get("feat_ticket_sold", 0)) - # 迭代 20 T6/T7——adventure 域计数器回填(缺键 = 旧版断点防御空集;_reset_curio_state 已清零在先) + # adventure 域计数器回填(缺键 = 旧版断点防御空集;_reset_curio_state 已清零在先) var bp_counters = bp.get("adventure_counters", null) if bp_counters is Dictionary: run_ledger.adventure_counters = (bp_counters as Dictionary).duplicate(true) - _refresh_stock = maxi(0, int(bp.get("refresh_stock", 0))) # 迭代 20 T4/T7——旧档缺键缺省 0 - run_ledger.vision_counter = {"used": maxi(0, int(bp.get("vision_counter_used", 0)))} # 迭代 22 秘宝批 T3——真视计数随断点回填(缺键=旧断点缺省 0) + _refresh_stock = maxi(0, int(bp.get("refresh_stock", 0))) # 旧档缺键缺省 0 + run_ledger.vision_counter = {"used": maxi(0, int(bp.get("vision_counter_used", 0)))} # 真视计数随断点回填(缺键=旧断点缺省 0) var bp_result: Dictionary[Variant, Variant] = bp.get("bonus_result", {}) as Dictionary if not bp_pending.is_empty(): _pending_next_level = true @@ -234,7 +234,7 @@ func resume_adventure(bp: Dictionary, params: Dictionary = {}) -> bool: curio_resolved.emit(_curio_result.duplicate(true)) return true _resume_bp = bp.duplicate(true) - # 迭代 11 第①批 T6——充能账本随断点回局(缺键 = 旧档/无断点,保持 _seed_attune_charges 种子态) + # 充能账本随断点回局(缺键 = 旧档/无断点,保持 _seed_attune_charges 种子态) var bp_charges = bp.get("attunement_charges", null) if bp_charges is Dictionary: run_ledger.attune_charges = (bp_charges as Dictionary).duplicate(true) @@ -243,7 +243,7 @@ func resume_adventure(bp: Dictionary, params: Dictionary = {}) -> bool: # 三选一停点态归零(冒险开始/结算收束共用;令牌池按表配额重建——池消耗即上限,账本随池重生。 -# 迭代 20 T6——adventure 域计数器账本随冒险开始清零;resume 路径调用后由断点附随件回填) +# adventure 域计数器账本随冒险开始清零;resume 路径调用后由断点附随件回填) func _reset_curio_state() -> void: _curio_taken = {"attack": 0, "max_hp": 0, "armor": 0, "gp": 0, "ap": 0, "heal": 0} _curio_deck = _build_curio_deck() @@ -259,10 +259,9 @@ func _reset_curio_state() -> void: # 令牌池构建(TP0 v2.2——按表 kind×tier 配额展开为持久多重集;构建序确定 = CURIO_KINDS×TIERS 逐层, -# 随机性只发生在洗牌消费 reward_pick 封闭流的时刻。迭代 12 T1:规则改写型特性带=relic 活行每件 1 张追加。 -# 迭代 20 T2/T3 四级换代——relic 令牌档 = 行 rarity 直映射(四级词表内直用;旧三档值 transitional -# 回退映射 rarest→rare/其余→excellent,T3 行换代后回退分支自然休眠);relic 入普通档随新档位框架 -# 解禁〔旧「永不入普通档」系 TP0 三档时代约束,四级框架未沿用——奇物.md 池结构节无此限制〕) +# 随机性只发生在洗牌消费 reward_pick 封闭流的时刻。规则改写型特性带=relic 活行每件 1 张追加。 +# relic 令牌档 = 行 rarity 直映射(四级词表内直用;词表外的 transitional 值回退映射 +# rarest→rare/其余→excellent);relic 可入普通档(奇物.md 池结构节无档位限制)。 func _build_curio_deck() -> Array: var deck: Array[Variant] = [] for kind in db.adventure.CURIO_KINDS: @@ -290,16 +289,15 @@ func set_hero_override(atk_pct: int, hp_pct: int) -> void: _runner.set_hero_override(atk_pct, hp_pct) -# 冒险账本侧生效上限(T17 修复——账本置满/回血封顶与战斗内上限同式同源): +# 冒险账本侧生效上限(账本置满/回血封顶与战斗内上限同式同源): # (表值 + 永久强化 flat + 加算区 flat)后乘调试浮窗百分比——叠加次序与 LevelRunner.effective_max_hp -# 逐字一致。旧口径两处只算 flat 不乘 pct:调生命上限 26→104 时开局血仍 26(账本 26 / 战斗内 104)、 -# 通关 20% 回血封顶按 26 算。pct=0(模拟/冒烟默认)时乘法恒等——MC 锚零漂移。 +# 逐字一致。pct=0(模拟/冒烟默认)时乘法恒等——MC 锚零漂移。 func effective_max_hp() -> int: var base: int = int(db.hero.max_hp) + int(_base_override.get("max_hp", 0)) + int(run_ledger.bonus.get("max_hp", 0)) return maxi(1, int(round(float(base) * (100.0 + float(_override[1])) / 100.0))) -# 断点承载注入(迭代 8 卡①——组合根冒险开始时调用;模拟/冒烟不注入 = 断点面整体静默) +# 断点承载注入(组合根冒险开始时调用;模拟/冒烟不注入 = 断点面整体静默) func set_save_manager(sm: SaveManagerCore) -> void: _save_manager = sm @@ -310,7 +308,7 @@ func runner() -> LevelRunner: # 接口③治疗封顶回报执行体(恢复点节点兑付——按比例回血并封顶)。算术宿主 = LevelRunner.rest_heal -#(2026-10-02 修复批——同式双落点字面量退役,与 LevelRunner.rest_heal_amount 同一单点) +#(与 LevelRunner.rest_heal_amount 同一单点) func apply_rest(pct: int, hp: int, max_hp: int) -> int: return LevelRunner.rest_heal(pct, hp, max_hp) @@ -329,7 +327,7 @@ func continue_to_next_level() -> bool: return _start_current_level() -# 停点空候选消化(2026-10-06 用户令——池空=三选一环节整体跳过:候选 0 件时停点视同已处理, +# 停点空候选消化(池空=三选一环节整体跳过:候选 0 件时停点视同已处理, # 呈现层跳开选择面直接走后续推进。仅空候选合法;非空停点拒绝——零自动推进契约不破,正常 # 消化仍只走 pick_curio/apply_node_curio 兑付。触发源=渠道白名单过滤后池空(关卡 Boss 通关 # 渠道只出专长,专长零配置/旧档 deck 无 relic 余库即空集)。) @@ -342,9 +340,9 @@ func skip_empty_curio() -> bool: return true -# ---- 提升三选一(迭代 10 奖励重构批——选择停点零自动推进、重复兑付被拒;兑付恰一件、未选项零生效)---- +# ---- 提升三选一(选择停点零自动推进、重复兑付被拒;兑付恰一件、未选项零生效)---- -# 候选令牌匹配(身份键恒等——属性加成型特性 kind+tier、规则改写型特性 feat_id;迭代 12 T1 规则改写型特性带) +# 候选令牌匹配(身份键恒等——属性加成型特性 kind+tier、规则改写型特性 feat_id) func _find_token(candidates: Array, kind: String, tier: String, feat_id: String = "") -> Dictionary: for t in candidates: var tok: Dictionary[Variant, Variant] = t as Dictionary @@ -358,7 +356,7 @@ func _find_token(candidates: Array, kind: String, tier: String, feat_id: String # 玩家点选兑付(呈现层/冒烟/自动模拟确认入口):令牌 ∈ 停点候选(身份键精确匹配——relic 件 # 另须 feat_id)。属性件写加算区、AP 件写第四轴、GP 件走钱包「奖励入账」入口、恢复件当即回血、 -# relic 件入特性持有集(🔴 层级纪律:只走局内随机渠道)、道具件受同调位约束(随池种退役不可达)。 +# relic 件入特性持有集(🔴 层级纪律:只走局内随机渠道)、道具件受同调位约束。 # 消费=选中令牌踢池(未选回池由「抽签不摘牌、兑付才摘牌」语义承载——TP0 v2.2)。 func pick_curio(kind: String, tier: String = "", feat_id: String = "") -> bool: if state != "running" or _curio_pending.is_empty(): @@ -379,7 +377,7 @@ func pick_curio(kind: String, tier: String = "", feat_id: String = "") -> bool: return true -# 兑付载荷 relic 伴随键(迭代 12 T1——反馈行取数面;非 relic 件零新增键) +# 兑付载荷 relic 伴随键(反馈行取数面;非 relic 件零新增键) func _feat_payload_keys(feat_id: String) -> Dictionary: if feat_id == "": return {} @@ -387,7 +385,7 @@ func _feat_payload_keys(feat_id: String) -> Dictionary: return {"feat_id": feat_id, "feat_name": String(row.get("display_name", "")), "feat_archetype": String(row.get("archetype", ""))} -# 三选一件兑付共享体(2026-10-02 修复批双胞胎收口;TP0 改令牌消费——摘牌单点;迭代 12 T1 relic 分支): +# 三选一件兑付共享体(TP0——令牌消费、摘牌单点,含 relic 分支): # 属性件写加算区 + 件获取计数、AP 件写第四轴、GP 件走钱包、恢复件当即回血(封顶生效上限—— # 与账本置满/通关回血同式 effective_max_hp)、relic 件入持有集(散件单体保底——效果接线面 # 按挂点消费,档位质变由 FeatsEngine 求值)。兑付即从 _curio_deck 摘除该令牌(选中踢池; @@ -400,7 +398,7 @@ func _apply_curio_pick(kind: String, tier: String, value: int, feat_id: String = push_error("[冒险结构] 令牌消费失败——牌库无此令牌: %s|%s|%s" % [kind, tier, feat_id]) return false if kind == "refresh": - _refresh_stock += value # T4 F-1 修复——刷新券入刷新存量账(冒险级;**退役 _attune_refresh_x 写口**:X 每停点 _reset_refresh_x 重置会吞存量=写错账缺陷正主;摘牌先于落账=选中即消尽,旧早退路径零摘牌缺陷同批修正) + _refresh_stock += value # T4 F-1——刷新券入刷新存量账(冒险级;**不写 _attune_refresh_x**:X 每停点 _reset_refresh_x 重置会吞存量;摘牌先于落账=选中即消尽) _curio_taken["refresh"] = int(_curio_taken.get("refresh", 0)) + 1 return true if kind == "rap": @@ -415,9 +413,9 @@ func _apply_curio_pick(kind: String, tier: String, value: int, feat_id: String = if not _feats.has(feat_id): _feats.append(feat_id) _curio_taken["relic"] = int(_curio_taken.get("relic", 0)) + 1 - _curio_taken["relic:" + feat_id] = int(_curio_taken.get("relic:" + feat_id, 0)) + 1 # 迭代 20 T2 案②——身份维已拿计数(cap 消费面) + _curio_taken["relic:" + feat_id] = int(_curio_taken.get("relic:" + feat_id, 0)) + 1 # 身份维已拿计数(cap 消费面) return true - # 加算形态路由(内容数据驱动扩展批 T5——match 收敛进效果类型:属性值提升四类走 + # 加算形态路由(match 收敛进效果类型:属性值提升四类走 # adventure_table.CURIO_APPLY_ROUTES 声明路由(bonus 落点键),加新加算类令牌零代码) var sink := db.adventure.curio_apply_route(kind) if sink != "": @@ -438,7 +436,7 @@ func _apply_curio_pick(kind: String, tier: String, value: int, feat_id: String = return true -# 从牌库摘除一枚令牌(TP0——选中踢池单点;迭代 12 T1 relic 按 feat_id 精确摘;找不到 = false) +# 从牌库摘除一枚令牌(TP0——选中踢池单点;relic 按 feat_id 精确摘;找不到 = false) func _consume_deck_token(kind: String, tier: String, feat_id: String = "") -> bool: for i in _curio_deck.size(): var tok: Dictionary[Variant, Variant] = _curio_deck[i] as Dictionary @@ -456,9 +454,9 @@ func feats_held() -> Array: return _feats.duplicate() -# ---- 商店共享池消费面(迭代 11 第②批 T3——P1 共享池单点账本;TP0 令牌池换代——库存=牌库剩余令牌)---- +# ---- 商店共享池消费面(共享池单点账本;TP0——库存=牌库剩余令牌)---- -# 库存余量(TP0:stock = 牌库内该 kind 剩余令牌数——「池消耗即上限」,种类次数上限退役; +# 库存余量(TP0:stock = 牌库内该 kind 剩余令牌数——「池消耗即上限」,无种类次数上限; # 奖励三选一兑付摘牌 与 商店购买消费 由同一 _curio_deck 承载——两渠道跨关共库,全冒险一次性)。 func pool_stock(kind: String) -> int: var n := 0 @@ -492,7 +490,7 @@ func _pool_stock_snapshot() -> Dictionary: # 兑付收口(恰一次):清停点态 → 记已兑付态 → emit → 停点快照(等继续确认——中断续玩不重兑付)。 -# picked = kind;tier 随载荷(TP0——大小档位读数面);relic 伴随键随载荷(迭代 12 T1——反馈行取数) +# picked = kind;tier 随载荷(TP0——大小档位读数面);relic 伴随键随载荷(反馈行取数) func _finish_curio_pick(picked: String, value: int, hp_before: int, tier: String = "", feat_id: String = "") -> void: _curio_pending = {} _curio_result = { @@ -508,7 +506,7 @@ func _finish_curio_pick(picked: String, value: int, hp_before: int, tier: String _snapshot_breakpoint() -# ---- 奖励节点三选一(迭代 10 追加批——用户拍板:与通关三选一共享同池同权重同次数上限)---- +# ---- 奖励节点三选一(与通关三选一共享同池同权重同次数上限)---- # 候选呈现(节点到达时调用——恰一 reward_pick scope 洗牌 + 道具件掷定 scope;本停点断点不载, # 续玩重建到选路停点后重走重抽,恢复的全局计数器保证同候选逐位复现)。 @@ -518,8 +516,8 @@ func node_curio_candidates() -> Dictionary: func present_node_curio(candidates: Array) -> void: - _reset_refresh_x() # 迭代 11 第①批 T5b——碰三选一重置 X 余量(不结转) - _curio_paid_refreshes = 0 # 付费刷计数随停点清零(对齐商店进店清零——2026-10-06) + _reset_refresh_x() # 碰三选一重置 X 余量(不结转) + _curio_paid_refreshes = 0 # 付费刷计数随停点清零(对齐商店进店清零) _node_curio_pending = {"candidates": candidates.duplicate(true)} @@ -551,12 +549,12 @@ func _seed_attune_charges() -> void: run_ledger.attune_charges[String(iid)] = maxi(0, int(arow.get("charges_per_adventure", 0))) -# ---- 三选一刷新(迭代 11 第①批 T5b——P1 甲 X/Y 双源:X=刷新件每碰三选一重给〔优先消耗、不结转〕、 +# ---- 三选一刷新(X/Y 双源:X=刷新件每碰三选一重给〔优先消耗、不结转〕、 # Y=营地升级行冒险周期池〔用完即无〕;重抽消费 reward_pick 既有洗牌流,池规则全保留——不放回/ # 达上限剔牌/掷定前置直显;停点可中断)---- func _attune_refresh_x_total() -> int: - # 内容数据驱动扩展批 T4——按 id 特判拆除:kind 分发查询(装配集内 effect_kinds 含 bonus_refresh + # kind 分发查询(装配集内 effect_kinds 含 bonus_refresh # 的行 magnitude 合计;刷新件类加件零 id 分支) var total := 0 for iid_v in _attunement: @@ -570,7 +568,7 @@ func _reset_refresh_x() -> void: _attune_refresh_x = _attune_refresh_x_total() -# 当前可刷新次数(X 优先 + Y 池 + 刷新存量账——呈现层余量读数口;T4 F-1 修复扩第三源) +# 当前可刷新次数(X 优先 + Y 池 + 刷新存量账——呈现层余量读数口) func attune_refresh_left() -> int: return _attune_refresh_x + _attune_refresh_y + _refresh_stock @@ -593,7 +591,7 @@ func refresh_curio() -> bool: return _refresh_curio_common(false) -# 三选一 GP 付费刷新(2026-10-06 用户令对齐商店 MC-1——免费位 X/Y 用尽后转付费,同旋钮同曲线同钱包; +# 三选一 GP 付费刷新(对齐商店 MC-1——免费位 X/Y 用尽后转付费,同旋钮同曲线同钱包; # 组合根先经 curio_stop_pending+钱包支出再调,本口只做计数与重抽)。池规则全保留——不放回/达上限剔牌/掷定前置直显。 func refresh_curio_paid() -> bool: return _refresh_curio_common(true) @@ -617,7 +615,7 @@ func _refresh_curio_common(paid: bool) -> bool: _curio_paid_refreshes += 1 else: # 免费位消耗序:X(刷新件每停点重给,优先消耗)→ Y(营地冒险周期池)→ 存量账(刷新券加仓, - # 迭代 20 T4 F-1 修复新账——跨停点持久) + # 跨停点持久) if _attune_refresh_x <= 0 and _attune_refresh_y <= 0 and _refresh_stock <= 0: return false if _attune_refresh_x > 0: @@ -631,7 +629,7 @@ func _refresh_curio_common(paid: bool) -> bool: _curio_pending["candidates"] = cands.duplicate(true) var payload: Dictionary[Variant, Variant] = (_curio_pending.get("payload", {}) as Dictionary).duplicate(true) payload["candidates"] = cands - payload["refreshed"] = true # 重发载荷带标——呈现层直落选择面,不再重开胜利总结面(2026-10-06) + payload["refreshed"] = true # 重发载荷带标——呈现层直落选择面,不再重开胜利总结面 curio_choice_presented.emit(payload) # 同信号重 present(零自动推进契约不破——停点仍在途) _snapshot_breakpoint() return true @@ -660,13 +658,13 @@ func _finish_node_bonus(picked: String, value: int, tier: String = "", feat_id: # kind 出现率∝剩余令牌数〔档位配额即分布——无独立权重 knob〕;抽签不摘牌、兑付才摘牌=未选 # 自动回池;池耗即枯竭——余库不足 N kind 时出齐剩余,空库 = 零候选合法态)。候选 = 令牌字典 # {"kind","tier"}。消费 reward_pick 封闭流——一次停点恰一 scope,同种子同候选。 -# 渠道白名单过滤(迭代 15 卡② T4——渠道轴定位:关底 Boss 击败=通关渠道只出专长(feat 令牌); +# 渠道白名单过滤(渠道轴定位:关底 Boss 击败=通关渠道只出专长(feat 令牌); # 奖励节点/商店只出属性值提升+资源(非 relic 令牌),专长在非 Boss 渠道只以门票形态出现(T5)。 # 过滤式而非物理拆池:deck 物理结构/存档键 bonus_deck 混编余库/消耗语义(选中踢池未选回池)原样, # 白名单在候选视图层生效——配额结构锚 TIER_QUOTAS 70/25/3=98 零改动(专长令牌本系活行追加面,在锚外)。 -# 迭代 20 T2 案D 换代——曝光槽:非 Boss 渠道三选一 = **2 格全池 + 1 格优秀档以上子池** +# 曝光槽:非 Boss 渠道三选一 = **2 格全池 + 1 格优秀档以上子池** # (rank≥excellent;子池空该格回退全池;池空直通同族兜底);凭证(feat_ticket)不进子池 -# 〔独立计数体系〕;已拿上限 cap(案②提前退役):taken≥cap 的身份在候选视图剔除〔牌库本体不动, +# 〔独立计数体系〕;已拿上限 cap:taken≥cap 的身份在候选视图剔除〔牌库本体不动, # 拿了才计、刷出不计——_curio_cap_ok〕。 func _draw_curio_candidates(channel: String = "reward_node") -> Array: var pool := _curio_deck.duplicate() @@ -681,8 +679,8 @@ func _draw_curio_candidates(channel: String = "reward_node") -> Array: return _curio_cap_ok(String(t.get("kind", "")), String(t.get("feat_id", "")))) var rg: RandomNumberGenerator = rng.open_stream("reward_pick") if channel == "level_clear": - # 迭代 20 T5——Boss 渠道按档配比加权抽取(无放回加权抽:逐席按 boss_feat_weight 掷点, - # 身份去重照旧;rarity 语义约束兑付面——奇物.md v3.1,配比数值归调参批) + # Boss 渠道按档配比加权抽取(无放回加权抽:逐席按 boss_feat_weight 掷点, + # 身份去重;rarity 语义约束兑付面——奇物.md v3.1,配比数值归 adventure 表) var out_w: Array[Variant] = [] var seen_w: Array[Variant] = [] var want_w := int(db.adventure.curio_candidate_count) @@ -754,7 +752,7 @@ func _draw_curio_candidates(channel: String = "reward_node") -> Array: return out -# 已拿上限判定(迭代 20 T2 案②——身份维度:kind 走 curio_cap、relic 走 feats 行 cap 字段; +# 已拿上限判定(身份维度:kind 走 curio_cap、relic 走 feats 行 cap 字段; # taken 只在兑付时 +1〔拿了才计〕、刷出不计)。缺省放行=白名单外 kind 兜底。 func _curio_cap_ok(kind: String, feat_id: String = "") -> bool: var cap := 99 @@ -768,7 +766,7 @@ func _curio_cap_ok(kind: String, feat_id: String = "") -> bool: return int(_curio_taken.get(kind, 0)) < cap -# —— 专长获取门票(T5 迭代 15 卡②——非 Boss 渠道的专长入口;四口径契约④:拿到即开不可囤积/ +# —— 专长获取门票(T5——非 Boss 渠道的专长入口;四口径契约④:拿到即开不可囤积/ # 罕见只在概率不在价格/一局限购一次/计步保底连续 5 展示未出第 6 必出——计数=展示次数、刷新 # 重展计入、节点与商店共享、触发清零、限购满不再触发。调用即一次展示判定与记账)—— func _feat_ticket_consider(rg: RandomNumberGenerator) -> bool: @@ -806,7 +804,7 @@ func _redeem_feat_ticket() -> bool: return true -# Boss 钥石逐杀掉落(迭代 10——渠道改 Boss/精英击杀掉落;首杀/复杀两档读 meta.tres boss_keystone; +# Boss 钥石逐杀掉落(掉落渠道 = Boss/精英击杀;首杀/复杀两档读 meta.tres boss_keystone; # 首杀判据 = 存档 boss_first_kill 标记位〔断点未注入 = 恒首杀——模拟/冒烟零扰动;标记仍在收束 # apply_adventure_summary 逐通关关次置位〕;末关 Boss 照常入账;明细随摘要 additive 键供结算面归因) func _boss_keystone_drop(li: int) -> void: @@ -834,7 +832,7 @@ func abandon() -> bool: # ---- 关卡推进(私有——序列编排单一出口)---- -# 树限次计数按关重置(迭代 21 T3——危险直觉锋/守两组「每关限次」账本键:跨战持久由 adventure +# 树限次计数按关重置(危险直觉锋/守两组「每关限次」账本键:跨战持久由 adventure # 域导出/回灌承载,此处随关清零闭合生命周期四态;键集=效果引擎树合成行声明的 counter_id; # 独立成口=V10 断言面直呼) func _reset_tree_limited_counters() -> void: @@ -854,38 +852,38 @@ func _start_current_level() -> bool: _runner.wallet_changed.connect(_forward_wallet_changed) _runner.level_finished.connect(_on_level_finished) _runner.set_hero_override(int(_override[0]), int(_override[1])) - # 断点续玩分支(迭代 8 卡①):模板随快照强制(已抽模板零重抽零 RNG)、resume_state 带 + # 断点续玩分支:模板随快照强制(已抽模板零重抽零 RNG)、resume_state 带 # 停点节点与已到序——重建到停点后经 present_resumed_choice 呈现(信号顺序契约同入口)。 var resume_state: Dictionary[Variant, Variant] = {} - var template_pick: int = 0 if _first_script else -1 # 首次脚本 = 每关固定模板 0 零抽签(v0.4 拍板点①);否则逐关抽签 + var template_pick: int = 0 if _first_script else -1 # 首次脚本 = 每关固定模板 0 零抽签;否则逐关抽签 if not _resume_bp.is_empty(): resume_state = {"node_id": int(_resume_bp.get("node_id", -1)), "visited_ids": _resume_bp.get("visited_ids", []) as Array} template_pick = int(_resume_bp.get("template_pick", -1)) # 接口①开始关卡:生命经共享账本交接(账本当前值即开局生命——冒险开始置满 / 大奖励回满已写好); # _base_override 共享引用随载荷传入(永久强化 flat——LevelRunner.effective_* 叠加序第二项)。 - # 停点前移批 2026-09-23:defer_entry=true 起每关(含首关)——先 emit level_started(呈现层在 + # defer_entry=true 起每关(含首关)——先 emit level_started(呈现层在 # 该回调重取 runner 实例),后入口候选呈现;顺序反了选路口会被呈现层的 runner 空防御静默丢弃。 # 呈现零 RNG 消耗、pick 走同一 _enter_node——测量面逐位零漂移。 - _runner.set_run_ledger(run_ledger) # 迭代 27 T3——共享四账单类下传(原四 setter/参数散传收口;run_ledger=四账类,ledger=关卡账沿用旧名) - _runner.sync_attune_inventory() # 迭代 11 第①批 T6 原语义——能力件骑库存面注入(随账下传同拍) + _runner.set_run_ledger(run_ledger) # 共享四账单类下传(run_ledger=四账类,ledger=关卡账) + _runner.sync_attune_inventory() # 能力件骑库存面注入(随账下传同拍) var ok: bool = _runner.start_level_external(level_index, ledger, purchased, apply_rest, _base_override, true, template_pick, resume_state) if ok: - _runner.set_attunement(_attunement) # 迭代 11 第①批 T5——同调装配下传(enc 携带进战斗结算) - _runner.set_feats(_feats) # 迭代 12 T1——特性持有集下传(begin_battle enc.feats 求值面) - _runner.set_tree_rules(_tree_rules) # 迭代 12 T10——树 rule 键集下传(A/B 面消费) - _runner.set_hero_axes(hero_attack_type, hero_armor_type) # 迭代 23 T4——两根类型轴快照下传(effective_ac 甲型基础 AC 层+enc 携带进 spawn) + _runner.set_attunement(_attunement) # 同调装配下传(enc 携带进战斗结算) + _runner.set_feats(_feats) # 特性持有集下传(begin_battle enc.feats 求值面) + _runner.set_tree_rules(_tree_rules) # 树 rule 键集下传(A/B 面消费) + _runner.set_hero_axes(hero_attack_type, hero_armor_type) # 两根类型轴快照下传(effective_ac 甲型基础 AC 层+enc 携带进 spawn) if _shop_mode == "pool": - # 商店共享池注入(迭代 11 第②批 T3——库存账本引用+消费 handler 双下传;legacy 模式零注入零扰动。 - # 迭代 20 T2——cap 检查回调四参注入) + # 商店共享池注入(库存账本引用+消费 handler 双下传;legacy 模式零注入零扰动。 + # cap 检查回调四参注入) _runner.set_shop_pool(_curio_deck, _consume_pool_purchase, _feat_ticket_consider, _curio_cap_ok) - # 迭代 20 T4——凭证件三账注入(节点级/回合级一次性:注入即清零,未用即过期=寿命档语义) + # 凭证件三账注入(节点级/回合级一次性:注入即清零,未用即过期=寿命档语义) _runner.set_voucher_grants(_pending_rap, _time_sand_queue) _pending_rap = 0 _time_sand_queue = 0 - # 三选一道具件跨关携带注入(迭代 10)——迭代 11 第①批 T7 退役:aux 卡出池后 carry 恒空集, - # 注入面随停点渠道退役拆除(容器字段保留=替换子交互机械惰性承载,零投放零行为) + # 三选一道具件跨关携带注入面不存在(aux 卡不在池种内→ carry 恒空集; + # 容器字段保留=替换子交互惰性承载,零投放零行为) level_started.emit(level_index, String(_runner.level_row.get("display_name", ""))) # 入口停点断点(node_id=-1)与 defer_entry 同态(node_index=-1+单候选)——走入口呈现; # 中途停点(node_id>=0)走停点呈现(restore_treasure_items 先于呈现=C 区库存就位)。 @@ -912,20 +910,20 @@ func _on_level_finished(payload: Dictionary) -> void: if result != "victory": push_error("[冒险结构] 关卡结束结果出域: %s" % result) return - _last_treasure_cleared = int(payload.get("aux_cleared", 0)) # additive(迭代 7 T4——末关 summary 取数面) - # Boss 钥石逐杀掉落(迭代 10——渠道改击杀掉落,末关照常入账;首杀/复杀读 meta.tres boss_keystone) + _last_treasure_cleared = int(payload.get("aux_cleared", 0)) # additive(末关 summary 取数面) + # Boss 钥石逐杀掉落(击杀掉落渠道,末关照常入账;首杀/复杀读 meta.tres boss_keystone) _boss_keystone_drop(level_index) if level_index < levels_total: - # 通关兑付(非末关恰一次;迭代 10 三层奖励框架):部分回血先行 → 加权洗牌掷 3 → 三选一停点 + # 通关兑付(非末关恰一次;三层奖励框架):部分回血先行 → 加权洗牌掷 3 → 三选一停点 #(顺序即契约——回血按当刻账本与上限结算,选择停点零自动推进) var hp_before := int(ledger.get("hero_hp", 0)) - var max_eff := effective_max_hp() # T17 修复:回血封顶口径含调试浮窗 pct(同战斗内上限) + var max_eff := effective_max_hp() # 回血封顶口径含调试浮窗 pct(同战斗内上限) var heal := mini(int(floor(float(max_eff) * float(int(db.adventure.clear_heal_pct)) / 100.0)), max_eff - hp_before) ledger["hero_hp"] = hp_before + heal # 置位先于 emit(信号同步派发——处理器内立即确认时 _pending_next_level 必须已就位) _pending_next_level = true - _reset_refresh_x() # 迭代 11 第①批 T5b——碰三选一重置 X 余量(不结转) - _curio_paid_refreshes = 0 # 付费刷计数随停点清零(对齐商店进店清零——2026-10-06) + _reset_refresh_x() # 碰三选一重置 X 余量(不结转) + _curio_paid_refreshes = 0 # 付费刷计数随停点清零(对齐商店进店清零) var pick_payload: Dictionary[Variant, Variant] = { "level_index": level_index, "candidates": _draw_curio_candidates("level_clear"), # T4 渠道白名单——关底 Boss 击败=通关渠道只出专长 @@ -935,7 +933,7 @@ func _on_level_finished(payload: Dictionary) -> void: "keystone_gained": int(_keystone_drops.back().get("amount", 0)) if not _keystone_drops.is_empty() else 0, "keystone_total": keystone, "gp": int(ledger.get("gp", 0)), - "aux_cleared": int(payload.get("aux_cleared", 0)), # additive 扩签(迭代 7 T4——关卡末清空反馈取数) + "aux_cleared": int(payload.get("aux_cleared", 0)), # additive 扩签(关卡末清空反馈取数) } _curio_pending = {"candidates": (pick_payload["candidates"] as Array).duplicate(true), "payload": pick_payload.duplicate(true)} @@ -955,13 +953,13 @@ func _settle(result: String) -> void: "stopped_at": 0 if result == "completed" else level_index, "keystone_total": keystone, "master_seed": master_seed, - "aux_cleared_last": _last_treasure_cleared, # additive 扩签(迭代 7 T4——末关清空反馈;非末关走 bonus 载荷) - "keystone_drops": _keystone_drops.duplicate(true), # additive 扩签(迭代 10——逐杀掉落明细;settle 入账明细/复盘归因数据源) - "vision_used_delta": int(run_ledger.vision_counter.get("used", 0)), # additive 扩签(迭代 22 秘宝批 T3——真视使用本局计数;settle 聚合入档) - "pool_stock": _pool_stock_snapshot(), # additive 扩签(迭代 11 第②批 T5——终局池读数:清账前快照,商店买走 vs 奖励领走 vs 枯竭的终局面) - "relics": _feats.duplicate(), # additive 扩签(迭代 12 T1——特性终局持有集:清账前快照,成型判读取数面) + "aux_cleared_last": _last_treasure_cleared, # additive 扩签(末关清空反馈;非末关走 bonus 载荷) + "keystone_drops": _keystone_drops.duplicate(true), # additive 扩签(逐杀掉落明细;settle 入账明细/复盘归因数据源) + "vision_used_delta": int(run_ledger.vision_counter.get("used", 0)), # additive 扩签(真视使用本局计数;settle 聚合入档) + "pool_stock": _pool_stock_snapshot(), # additive 扩签(终局池读数:清账前快照,商店买走 vs 奖励领走 vs 枯竭的终局面) + "relics": _feats.duplicate(), # additive 扩签(特性终局持有集:清账前快照,成型判读取数面) } - # 败退明细(数值验证工具取数面 2026-09-22——tools/balance_verifier.py 止步节点分布数据源; + # 败退明细(数值验证工具取数面——tools/balance_verifier.py 止步节点分布数据源; # 仅失败局附加,键缺省 = 未败退,既有五件事消费方零感知) if result == "failed" and not _last_level_payload.is_empty(): summary["defeat"] = { @@ -970,11 +968,11 @@ func _settle(result: String) -> void: "node_type": String(_last_level_payload.get("node_type", "")), } if _runner != null: - summary["gp_final"] = int(_runner.gp) # gp_final 清账前快照(迭代 27 T3——P1-3 GP 影子账收口:终局面板取数源,影子账随批退役) + summary["gp_final"] = int(_runner.gp) # gp_final 清账前快照(终局面板取数源=runner 钱包单点) _runner.close_wallet() # GP 冒险收束清零(三结局都清——经转发发 wallet_changed "clear" 供日志/呈现) _reset_curio_state() # 三选一停点态收束清零(结算受理只算一次语义——重复宣布零变化) if _save_manager != null: - _save_manager.clear_breakpoint() # 三结局清断点(迭代 8 卡①/T3——退出冒险=放弃流程+清除断点) + _save_manager.clear_breakpoint() # 三结局清断点(退出冒险=放弃流程+清除断点) _save_manager.write_to_disk() _state = State.SETTLING adventure_finished.emit(summary) @@ -989,12 +987,12 @@ func _forward_node_entered(node: Dictionary, info: Dictionary) -> void: func _forward_choices_presented(candidates: Array) -> void: choices_presented.emit(candidates) - _snapshot_breakpoint() # 停点快照(迭代 8 卡①——选路停点=唯一可恢复停点形态;战斗中不存) + _snapshot_breakpoint() # 停点快照(选路停点=唯一可恢复停点形态;战斗中不存) -# ---- 断点快照(迭代 8 卡①——七字段拍板面+恢复必需附随件)---- -# 七字段(拍板面):关卡序号/节点位/生命/属性加成区/GP 钱包/商店已购档/已抽模板; -# 附随件(续玩正确性必需,随批注记):主种子+取数计数器(rng 快照契约回填——续接原时间线)、 +# ---- 断点快照(七字段契约面+恢复必需附随件)---- +# 七字段(契约面):关卡序号/节点位/生命/属性加成区/GP 钱包/商店已购档/已抽模板; +# 附随件(续玩正确性必需):主种子+取数计数器(rng 快照契约回填——续接原时间线)、 # 钥石累计(大奖励中途值——终局摘要五件事不失真)、已到节点序(呈现层图条重建)、道具库存 # (奖励节点已选件——防静默丢失)。注入缺省 null = 整面静默(模拟/冒烟零扰动)。 func _snapshot_breakpoint() -> void: @@ -1004,7 +1002,7 @@ func _snapshot_breakpoint() -> void: if _runner != null and _runner.treasure_inventory != null: treasure_snapshot = _runner.treasure_inventory.snapshot_inventory() # 三选一停点续玩分支 _runner 为 null(关卡已收束、下一关未开)——节点域字段按缺省落档, - # 该两态的续玩只消费 bonus_* 附随件(选择停点/已兑付停点快照,迭代 10) + # 该两态的续玩只消费 bonus_* 附随件(选择停点/已兑付停点快照) var bp: Dictionary[Variant, Variant] = { "level_index": level_index, "node_id": _runner.current_node_id() if _runner != null else -1, @@ -1017,9 +1015,9 @@ func _snapshot_breakpoint() -> void: }, "gp": int(ledger.get("gp", 0)), "shop_purchased": purchased.duplicate(true), - "shop_shelf": _runner.shop_bp_shelf() if _runner != null else [], # 迭代 11 第②批 T2——P2 甲货架入断点(离开店/非店停点 = 空架合法态) - "shop_visit_buys": _runner.shop_bp_visit_buys() if _runner != null else 0, # 迭代 11 第②批 T2——本次进店已购次数(A 链定价输入,P2 甲扩列) - "attunement_charges": run_ledger.attune_charges.duplicate(true), # 迭代 11 第①批 T6——同调主动件充能余量随断点(save v4 域) + "shop_shelf": _runner.shop_bp_shelf() if _runner != null else [], # 货架入断点(离开店/非店停点 = 空架合法态) + "shop_visit_buys": _runner.shop_bp_visit_buys() if _runner != null else 0, # 本次进店已购次数(A 链定价输入) + "attunement_charges": run_ledger.attune_charges.duplicate(true), # 同调主动件充能余量随断点(save v4 域) "template_pick": _runner.active_template_index if _runner != null else -1, "master_seed": master_seed, "rng_counter": rng.counter(), @@ -1028,16 +1026,16 @@ func _snapshot_breakpoint() -> void: "aux_items": treasure_snapshot, "bonus_taken": _curio_taken.duplicate(true), # 三选一件获取次数(kind 维度派生账本——断点附随件与读数承载) "bonus_deck": _curio_deck.duplicate(true), # 令牌池余库(TP0 v2.2——池消耗即上限,续玩余库逐枚还原) - "relics": _feats.duplicate(), # 特性持有集(迭代 12 T1——局内随机渠道获得态续玩防丢失) + "relics": _feats.duplicate(), # 特性持有集(局内随机渠道获得态续玩防丢失) "bonus_pending": _curio_pending.duplicate(true), # 三选一停点态(空 = 无停点——选择停点可中断契约) "feat_ticket_pity": _feat_ticket_pity, # T5 门票保底计数(扩列向后兼容——旧档缺键缺省 0) "feat_ticket_sold": _feat_ticket_sold, # T5 门票限购计数(同上) - "adventure_counters": run_ledger.adventure_counters.duplicate(true), # 迭代 20 T6/T7——adventure 域计数器随断点(续玩跨战账不丢) - "vision_counter_used": int(run_ledger.vision_counter.get("used", 0)), # 迭代 22 秘宝批 T3——真视使用计数随断点(续玩跨战账不丢) - "refresh_stock": _refresh_stock, # 迭代 20 T4/T7——刷新存量账随断点(F-1 新账) - "attune_refresh_y": _attune_refresh_y, # 2026-10-13 缺陷修批——Y 冒险周期池余量随断点(续玩不再自参数面整额重注入=堵「用完退菜单再续玩满血复活」可利用漏洞;扩列向后兼容——旧档缺键回退参数面) + "adventure_counters": run_ledger.adventure_counters.duplicate(true), # adventure 域计数器随断点(续玩跨战账不丢) + "vision_counter_used": int(run_ledger.vision_counter.get("used", 0)), # 真视使用计数随断点(续玩跨战账不丢) + "refresh_stock": _refresh_stock, # 刷新存量账随断点 + "attune_refresh_y": _attune_refresh_y, # Y 冒险周期池余量随断点(续玩不再自参数面整额重注入=堵「用完退菜单再续玩满血复活」可利用漏洞;扩列向后兼容——旧档缺键回退参数面) "bonus_result": _curio_result.duplicate(true), # 已兑付待推进态(空 = 无——中断续玩不重兑付) - "keystone_drops": _keystone_drops.duplicate(true), # 逐杀掉落明细(摘要归因续接——迭代 10) + "keystone_drops": _keystone_drops.duplicate(true), # 逐杀掉落明细(摘要归因续接) } _save_manager.set_breakpoint(bp) _save_manager.write_to_disk() diff --git a/game/core/battle_orchestrator.gd b/game/core/battle_orchestrator.gd index 22f4fca0..b2eb54c7 100644 --- a/game/core/battle_orchestrator.gd +++ b/game/core/battle_orchestrator.gd @@ -7,28 +7,26 @@ class_name BattleOrchestrator extends RefCounted signal step_row(row: Dictionary) -signal battle_finished(payload: Dictionary) # {result, hero_hp, gp_dropped}——hero 在 despawn 前捕获(呈现层销毁后读状态的时序防护);gp_dropped = 战斗掉落合计(GP+商店房实施批 2026-09-21) +signal battle_finished(payload: Dictionary) # {result, hero_hp, gp_dropped}——hero 在 despawn 前捕获(呈现层销毁后读状态的时序防护);gp_dropped = 战斗掉落合计 signal round_started(round_index: int) signal board_changed() signal settlement_snapshot(snap: Dictionary) # 每结算末尾的全量状态快照(playtest_logger 消费——JSONL 数值分析) -# 明细流水行型协议(战斗结算 Core Rule;9 类——2026-09-20 伏击单轮上限退役,溢出未生效行 overflow 随之下线; -# 2026-09-15 格面资源批由 15 类收拢,清单改动须同步 battle_log_view 的 _format_row 与本文档头注): +# 明细流水行型协议(战斗结算 Core Rule;9 类; +# 清单改动须同步 battle_log_view 的 _format_row 与本文档头注): # 效果行 effect · 伤害行 damage · 治疗行 heal · -# 奖励未生效行 reward_ineffective · 封印未中行 seal_miss · 施放行 cast(敌人技能池批由蓄力行 charge 改型)· 衰减行 decay · +# 奖励未生效行 reward_ineffective · 封印未中行 seal_miss · 施放行 cast · 衰减行 decay · # 判定行 verdict · 高光行 highlight # 行来源断言豁免集合(行型层)——判定段 / 衰减段本就无棋盘来源,勿一刀切误炸 const SOURCE_EXEMPT_TYPES := ["decay", "verdict"] # 行来源断言豁免集合(来源类别层)——事实来源是单位 / 清图而非棋盘格; -# fx_reveal=专长揭示掷格(落空行无真实格〔迭代 21 存量红修复——a57489e9 落地件三处空来源 -# 触发行来源断言,51 行/冒烟,两轮确定性复现〕); -# fx_grant_gp=专长·GP 入账(钱包面而非棋盘面,行无格子可指——与 fx_reveal 同款的漏网豁免, -# 未豁免时每局触发行来源断言失败 7 次,因脚本错误不改退出码而被闸长期漏过) +# fx_reveal=专长揭示掷格(落空行无真实格); +# fx_grant_gp=专长·GP 入账(钱包面而非棋盘面,行无格子可指) const SOURCE_EXEMPT_CLASSES := ["hero_attack", "enemy_action", "clear_reward", "fx_reveal", "fx_grant_gp"] var db: ConfigDb var rng: RngServiceCore -# E1 封装收口(2026-09-13):协作对象 board_generator/enemy_system/status_effects/reward_economy 私有化——跨层读取一律经 presentation_snapshot()/ +# E1 封装收口:协作对象 board_generator/enemy_system/status_effects/reward_economy 私有化——跨层读取一律经 presentation_snapshot()/ # diagnostic_snapshot() 成文出口(呈现层链式穿透 settlement._enemy_system.hero_unit() 的根因收口)。 # minesweeper/action_economy 保持公有 = 架构文档 API Boundaries 的 HUD框架消费面(意图提交 settle_batch + compute_move_path # 只读;ap/rap/相位读取)——非本文档登记的契约面,勿增新用途。 @@ -38,9 +36,9 @@ var action_economy: ActionEconomy var _enemy_system: UnitContainer var _status_effects: StatusContainer var _reward_economy: RewardEconomy -var treasure_inventory: TreasureItems # 迭代 7 T3——LevelRunner 注入的关卡域库存引用; +var treasure_inventory: TreasureItems # LevelRunner 注入的关卡域库存引用; # 每战新建本类,库存不归本类所有——注入面 -var _damage: DamageController # 伤害控制器(伤害管线单据化批 2026-09-24——单据唯一兑付管线) +var _damage: DamageController # 伤害控制器(单据唯一兑付管线) var encounter: Dictionary[String, Variant] = {} var round_index := 0 @@ -51,38 +49,38 @@ var _facts_reveals: Array[Dictionary] = [] var _facts_seals: Array[Dictionary] = [] var _facts_path := "" var _settling := false -var _defer_board_damage := false # 案C 暂存闸(2026-10-06 用户裁:地图奖励伤害兑付迁战斗段末——怪物还手后) +var _defer_board_damage := false # 案C 暂存闸(地图奖励伤害兑付在战斗段末——怪物还手后) var _deferred_board: Array[Dictionary] = [] # 授予段暂存伤害单据(保授予段事件序;战斗段怪物还手后按序补提交统一结账) -# 结算五段 Segment(迭代 27 T2——P1-1 拆段;段边界=审计五段〔裁点③甲〕,段序骨架冻结于 -# SettlementTable.segment_order 语义:授予→增益/减益→战斗→衰减→判定。本类退为段序编排+ +# 结算五段 Segment(段边界=审计五段,段序骨架冻结于 +# SettlementTable.segment_order 语义:授予→增益/减益→战斗→衰减→判定。本类做段序编排+ # 行发射/开单原语单点——段体逻辑归 game/core/settlement/ 五类) var _grant_seg = null # GrantSegment(①授予段——含封印判与 counter/grant 助手单点) var _aura_seg = null # AuraSegment(②增益/减益段) -var _combat_seg = null # CombatSegment(③战斗段——原 _combat_segment 体) +var _combat_seg = null # CombatSegment(③战斗段) var _decay_seg = null # DecaySegment(④衰减段) var _verdict_seg = null # VerdictSegment(⑤判定段——返回裁定,终局早退语义归本类) var _refresh_used_this_round := 0 # 每轮刷新计数(Active 相位合计,兜底上限 = ActionEconomyTable.refresh_cap_per_round) var _board_seq := 0 # 板序号(本战斗第几张板——快照归因用) var _board_from_midround_refresh := false # 装板 provenance:轮内刷新换来的图 = true(清图奖励守卫——刷新图不发清图奖励) var _seal_consumed := {} # 兑付资格以危险格实例为键(板级;换图重置) -# 同调装配运行态(迭代 11 第①批 T5——begin_battle 经 enc.attunement 注入;off=空集全部效果零扰动) +# 同调装配运行态(begin_battle 经 enc.attunement 注入;off=空集全部效果零扰动) var attunement: Array[Variant] = [] # 装备中同调件 item_id 集 -var _ledger: RunLedger = null # 共享四本账(迭代 27 T3——begin_battle 经 enc["ledger"] 持引用;缺省新账=调试面) -var _attune_safe_seen := 0 # 积点制件 battle 域安全开格计数(迭代 22 T3 通用化——装配集 ap_charge_safe 行扫描;反哺批⑤ 2026-10-12 用户裁:满 charge_n 自动兑付当轮 AP+1,无玩家发起入口) -# ---- 效果引擎扩签运行态(迭代 20 专长实装批 T1——新效果类型施加面;空订阅零扰动)---- +var _ledger: RunLedger = null # 共享四本账(begin_battle 经 enc["ledger"] 持引用;缺省新账=调试面) +var _attune_safe_seen := 0 # 积点制件 battle 域安全开格计数(装配集 ap_charge_safe 行扫描;满 charge_n 自动兑付当轮 AP+1,无玩家发起入口) +# ---- 效果引擎扩签运行态(新效果类型施加面;空订阅零扰动)---- var _fx_hero_ac_base := -1 # 主角 AC 基线快照(enc.hero_armor_class;-1=表值兜底未解析) var _fx_ac_round := 0 # ac_bonus 本轮累积器(封印桩形态——round_start 清零) -var nest_preview_count := -1 # 巢穴预告读数口(迭代 22 秘宝批 T3——board_installed 命中落值;-1=未装配/未发射;呈现桥消费) +var nest_preview_count := -1 # 巢穴预告读数口(board_installed 命中落值;-1=未装配/未发射;呈现桥消费) var _fx_ac_battle := 0 # ac_bonus 本战累积器(石肤形态——cap 封顶,begin_battle 清零) var _fx_bonus_delta := {"atk": 0, "max_hp": 0, "armor_class": 0, "ap": 0} # 本战 bonus_delta 累积(战末经 _ledger.bonus_add_axis 汇入后清零) var _fx_new_resource_types := {} # 本战已见资源类型集(地质学家 fact new_resource_type 判定——battle 域) var _fx_pending_reveals: Array[Dictionary] = [] # 揭示效果待兑队列(见血开窍/斩首学者/地质学家/跳格采掘——授予段末统一兑付,防轮 facts 迭代中追加重入) var _fx_revealing := false # fx 揭示兑付中标记(_on_cell_revealed 缓冲旁路——fx 揭示的奖励由兑付点直接入账,防二次缓冲二次兑付) -# 特性运行态(内容数据驱动扩展批 T3——relic 持有集经 enc.feats 注入:效果行为=数据行 triggers 经 +# 特性运行态(relic 持有集经 enc.feats 注入:效果行为=数据行 triggers 经 # 效果引擎分发;魔矢每战首次计数 battle 域。空集=零扰动) var _feat_first_dig_used := false -# 效果引擎(内容数据驱动扩展批 T1——发布订阅解释器;begin_battle 从持有集/装备集重建订阅。 -# T3 起施加面全量切换:发射点 dispatch 返回命中,发射点按组合规则施加——旧 feat_seals 封印注入消亡) +# 效果引擎(发布订阅解释器;begin_battle 从持有集/装备集重建订阅。 +# 施加面:发射点 dispatch 返回命中,发射点按组合规则施加) var _fx: EffectEngine @@ -95,7 +93,7 @@ func _fx_emit(event: String, payload: Dictionary) -> Array: # round_start 发射+施加(内容数据驱动扩展批 T3——grant_ap mode:queue=当轮入队,行动经济轮切换 # 即兑现;计数器 round_start 重置点在 dispatch 内生效。调用点两处:begin_battle 首轮 / 轮始段续轮。 -# 迭代 20 T1——payload 扩 ap_exhausted_last〔一滴不剩 when 面〕+ac_bonus 本轮累积器清零) +# payload 扩 ap_exhausted_last〔一滴不剩 when 面〕+ac_bonus 本轮累积器清零) func _emit_round_start() -> void: _fx_ac_round = 0 _sync_hero_ac() @@ -113,7 +111,7 @@ func _sync_hero_ac() -> void: _damage.set_hero_ac_override(_fx_hero_ac_base + _fx_ac_round + _fx_ac_battle) -# ac_bonus 施加(迭代 20 T1——mode=round 本轮累积器〔封印桩,round_start 清零〕/ +# ac_bonus 施加(mode=round 本轮累积器〔封印桩,round_start 清零〕/ # mode=battle 本战累积器〔石肤,cap 封顶;缺省 battle〕;cap=0/缺省=无上限) func _apply_ac_bonus(h: Dictionary) -> void: var mode := String(h.get("mode", "battle")) @@ -192,16 +190,15 @@ func _attune_has(item_id: String) -> bool: return attunement.has(item_id) -# 装配集只读出口(迭代 19 卡④立——呈现桥消费面现归 attune_param_sum〔迭代 22 T4 换代〕。 -# _attune_has 契约化出口,save v6 只读访问器先例;private 面内部调用零改动。只读零副作用—— +# 装配集只读出口(_attune_has 契约化出口,save v6 只读访问器先例。只读零副作用—— # 呈现侧判定专用,非结算写入口) func attune_has(item_id: String) -> bool: return _attune_has(item_id) -# 装备件表值读取(charge_n 等——TreasureItemTable 行;未装配不读表。magnitude 读数面随 T4 -# 秘宝订阅迁移退役——行值经 value_from 在 rebuild 定影,零运行期按件取值) -# 装配集参数合计(迭代 22 秘宝批 T3——常时参数面 kind 的装配集 Σmagnitude 读数口; +# 装备件表值读取(charge_n 等——TreasureItemTable 行;未装配不读表。 +# 行值经 value_from 在 rebuild 定影,零运行期按件取值) +# 装配集参数合计(常时参数面 kind 的装配集 Σmagnitude 读数口; # kind 分发查询先例=_attune_refresh_x_total bonus_refresh。零装配=0) func attune_param_sum(kind: String) -> int: var total := 0 @@ -212,8 +209,8 @@ func attune_param_sum(kind: String) -> int: return total -# 装配集内 ap_charge_safe 行读取(迭代 22 秘宝批 T3——掘进蓄能 id 特判通用化取数源; -# 首行语义=装配集内至多一件积点制〔新目录恰试炼镐〕) +# 装配集内 ap_charge_safe 行读取(取数源=装配集行扫描; +# 首行语义=装配集内至多一件积点制〔试炼镐〕) func _attune_charge_safe_row() -> Dictionary: for iid_v in attunement: var arow: Dictionary[Variant, Variant] = db.treasure_item_row(String(iid_v)) @@ -222,7 +219,7 @@ func _attune_charge_safe_row() -> Dictionary: return {} -# 充能重置(迭代 22 秘宝批 T3——按周期回满:账本回 charges_per_adventure+骑库存差额补注入 +# 充能重置(按周期回满:账本回 charges_per_adventure+骑库存差额补注入 # (used handle 不回收=本轮已耗充能作废,补新 handle=「回满」;差额注入防双份=level_runner # set_attune_charges 同构)。reset ∈ {battle, level}——adventure 周期归冒险开始种子面) func _reseed_attune_charges(reset: String) -> void: @@ -246,7 +243,7 @@ func _reseed_attune_charges(reset: String) -> void: treasure_inventory.add_item(iid, "attunement", Vector2i(-1, -1), 0) -# 积点制件进度读数(迭代 22 反哺批⑤——自动兑付无玩家发起入口,读数口=C 区秘宝槽悬停浮窗进度行: +# 积点制件进度读数(自动兑付无玩家发起入口,读数口=C 区秘宝槽悬停浮窗进度行: # assembled=装配在册/points=本战安全格进度(charge_n 取余)/need=charge_n/item_id=装配行 id。 # 未装配=assembled false) func attune_convert_state() -> Dictionary: @@ -258,13 +255,13 @@ func attune_convert_state() -> Dictionary: "display_name": String(row.get("display_name", "")), "item_id": String(row.get("item_id", ""))} -# 特性求值(内容数据驱动扩展批 T3——_feat_seals_for 挂点求值退役:效果行为=数据行 triggers 订阅, -# 效果引擎 dispatch 分发;旧 23 hook 枚举与封印注入消亡。流派档位质变=FeatsEngine 纯函数求值 +# 特性求值(效果行为=数据行 triggers 订阅,效果引擎 dispatch 分发; +# 流派档位质变=FeatsEngine 纯函数求值 # (档位机制本身系引擎基建非内容效果),两运行态注伤害控制器:档一 rider+1 / 档二 rider 可暴击) var _seal_miss_seen := {} # 封印未中行去重(每安全格实例一次) var _perfect_hit_true := 0 # 板级完美排雷计数(install 重置) var _perfect_hit_false := 0 -var _perfect_forgiven := 0 # 完美保险豁免累计(迭代 31 卡②——单向累加自有账;契约 2 禁改写 _perfect_hit_false) +var _perfect_forgiven := 0 # 完美保险豁免累计(单向累加自有账;契约 2 禁改写 _perfect_hit_false) var _hero_atk := 0 # 主角攻击基值快照(encounter.hero_atk;E4 收口——表值运行期不可变) @@ -287,7 +284,7 @@ func _init(db_ref: ConfigDb, rng_ref: RngServiceCore) -> void: minesweeper.seal_judged.connect(_on_seal_judged) minesweeper.round_end_board.connect(_on_round_end) action_economy.round_end_stopped.connect(_on_round_end) - # 结算五段接线(迭代 27 T2——段持宿主引用;信号连接纪律不涉段〔段零信号连接〕) + # 结算五段接线(段持宿主引用;信号连接纪律不涉段〔段零信号连接〕) _grant_seg = GrantSegment.new(self) _aura_seg = AuraSegment.new(self) _combat_seg = CombatSegment.new(self) @@ -302,24 +299,24 @@ func begin_battle(enc: Dictionary) -> bool: push_warning("[战斗结算] begin_battle 重复受理") return false encounter.assign(enc) - escrow = 0 # 战斗域零 GP 持久(GP+商店房实施批——每场战斗缓冲从零起算) - _damage.set_hero_ac_override(int(enc.get("hero_armor_class", -1))) # 主角护甲合流入参(伤害控制器 defender_ac 消费——口径同原 _defender_ac) + escrow = 0 # 战斗域零 GP 持久(每场战斗缓冲从零起算) + _damage.set_hero_ac_override(int(enc.get("hero_armor_class", -1))) # 主角护甲合流入参(伤害控制器 defender_ac 消费) db.set_reload_gate(true) if not _status_effects.notify_battle_start(): _fatal("增益状态 开域被拒(编排违例)") return false - # 遭遇骰(难度曲线与Boss GDD Core Rule 8——2026-09-12 用户拍板):行有 unit_count_max 时按 [unit_count, max] 均匀骰; - # 2026-09-14 敌方攻击区间批扩展:行有 atk_min 时按 [atk_min, atk_max] 骰 spawn 期整战持久值 + # 遭遇骰(难度曲线与Boss GDD Core Rule 8):行有 unit_count_max 时按 [unit_count, max] 均匀骰; + # 行有 atk_min 时按 [atk_min, atk_max] 骰 spawn 期整战持久值 # (每拍抖动否决——数字可读性锚;中点 = 行值)。encounter 封闭流恰一 scope(数量骰先、atk 骰后); # 挖掘决策域之外——P1 合规;敌人系统 零随机纪律保持(收 override 即确定值)。 - # 遭遇骰(难度曲线与Boss GDD Core Rule 8——2026-09-12 用户拍板):行有 unit_count_max 时按 [unit_count, max] 均匀骰; - # 2026-09-14 敌方攻击区间批扩展:行有 atk_min 时按 [atk_min, atk_max] 骰 spawn 期整战持久值 + # 遭遇骰(难度曲线与Boss GDD Core Rule 8):行有 unit_count_max 时按 [unit_count, max] 均匀骰; + # 行有 atk_min 时按 [atk_min, atk_max] 骰 spawn 期整战持久值 # (每拍抖动否决——数字可读性锚;中点 = 行值)。encounter 封闭流恰一 scope(数量骰先、atk 骰后); # 挖掘决策域之外——P1 合规;敌人系统 零随机纪律保持(收 override 即确定值)。 - # 逐行骰换代(2026-10-07 行集多行批 Q8 用户裁 + P1 补充):混编行集**每行各掷自己的区间骰**—— + # 逐行骰:混编行集**每行各掷自己的区间骰**—— # 先按行序逐行数量骰、再按行序逐行 atk 骰(单行行集 = 既有一次数量骰 + 一次 atk 骰,判定条件、 # 开流条件、消费序、消费次数逐位一致——零内容期随机流零变化;区间宽度为零的行不掷 = 「定值不骰」 - # 既有口径;atk 区间逐行同构 = 行值语义完整,代拍板随批留痕:属「每行一骰」预批准语义内的 + # 既有口径;atk 区间逐行同构 = 行值语义完整,属「每行一骰」语义内的 # 行字段区间骰逐行化,非新增随机源形态)。 var erowset_pre: Array[Variant] = db.resolve_enemy_rowset(int(enc.level_index), int(enc.node_depth)) if erowset_pre.is_empty(): @@ -351,21 +348,21 @@ func begin_battle(enc: Dictionary) -> bool: _hero_atk = int(enc.get("hero_atk", int(db.hero.atk))) if not _enemy_system.spawn(int(enc.level_index), int(enc.node_depth), int(enc.hero_hp), count_overrides, _hero_atk, int(enc.get("hero_max_hp", -1)), atk_overrides, - String(enc.get("attack_type", "")), String(enc.get("armor_type", ""))): # 迭代 23 T4——两根类型轴(空串=锻造配置默认值回退,行为连续) + String(enc.get("attack_type", "")), String(enc.get("armor_type", ""))): # 两根类型轴(空串=锻造配置默认值回退,行为连续) _fatal("敌人系统 spawn 被拒") return false if not _install_new_board(): return false _reset_round_facts() # 首板 install 的初始展开事件不入轮 facts(resource 恒 false 的双保险) - # 同调装配运行态注入(迭代 11 第①批 T5——enc.attunement 携带;off=空集零扰动。淬毒 N 注入 + # 同调装配运行态注入(enc.attunement 携带;off=空集零扰动。淬毒 N 注入 # 伤害控制器、偏运 N 注入地图战斗资源——均须先于首板 install) attunement = (enc.get("attunement", []) as Array).duplicate() _attune_safe_seen = 0 - # 淬毒/偏运注入拆除(内容数据驱动扩展批 T4——两件被动改 triggers 订阅行:淬毒=clamp_check - # modify 窗口、偏运=reward_roll bias_rewards;value 行字段 value_from 定影,零 begin_battle 注入) - # 特性运行态(内容数据驱动扩展批 T3——enc.feats 携带持有集:效果行为=数据行 triggers 经效果 + # 淬毒/偏运=triggers 订阅行(淬毒=clamp_check + # modify 窗口、偏运=reward_roll bias_rewards;value 行字段 value_from 定影,begin_battle 不注入) + # 特性运行态(enc.feats 携带持有集:效果行为=数据行 triggers 经效果 # 引擎分发;流派档位=FeatsEngine 纯函数求值两运行态注伤害控制器。魔矢每战首次开格计数同步归零) - # 迭代 20 T1——扩签运行态就位:AC 基线快照、累积器清零、adventure 计数器/加算区共享引用接收 + # 扩签运行态就位:AC 基线快照、累积器清零、adventure 计数器/加算区共享引用接收 _fx_hero_ac_base = int(enc.get("hero_armor_class", -1)) _fx_ac_round = 0 _fx_ac_battle = 0 @@ -377,31 +374,31 @@ func begin_battle(enc: Dictionary) -> bool: _damage.fx_reveal_request = _fx_enqueue_reveal _damage.fx_ac_request = _apply_ac_bonus var feat_ids: Array[Variant] = enc.get("feats", []) as Array - # 迭代 20 T3 换代(V14 旧实现摘除)——流派档位质变随重设计退役(奇物.md v1「不设流派标签、 - # 不设档位机制」):FeatsEngine 求值与 rider_tier 注入拆除,散件单体效果=唯一形态 + # 流派档位质变不设(奇物.md v1「不设流派标签、 + # 不设档位机制」):rider_tier 两注入恒零,散件单体效果=唯一形态 _damage.rider_tier_bonus = 0 _damage.rider_tier_crit = false _feat_first_dig_used = false - # 树 rule 键消费(迭代 12 T10 → 内容数据驱动扩展批 T3 换代:Fork 激活侧效果=效果引擎合成 - # 订阅(rebuild 注入——round_start 首轮 AP+1 / damage_taken 减伤+1),旧直调拆除。其余 rule 键 + # 树 rule 键消费(Fork 激活侧效果=效果引擎合成 + # 订阅(rebuild 注入——round_start 首轮 AP+1 / damage_taken 减伤+1)。其余 rule 键 # =stat 面投影不入战斗(T8 表内容 provisional 口径披露)) var tree_rules: Array[Variant] = enc.get("tree_rules", []) as Array - # 效果引擎订阅重建(内容数据驱动扩展批 T1——每战从持有集/装备集重建,中途获得下一战生效; + # 效果引擎订阅重建(每战从持有集/装备集重建,中途获得下一战生效; # 树规则合成订阅同面装载。装载序=feats 表序→treasure 表序→树规则,写死保种子复放。 - # 迭代 20 T6——adventure 域计数器从共享引用回灌〔跨战持久〕) + # adventure 域计数器从共享引用回灌〔跨战持久〕) _fx.rebuild(feat_ids, attunement, tree_rules) _fx.counters_seed(_ledger.counters_seed_snapshot()) - # 秘宝常时参数注入(迭代 22 秘宝批 T3——装配集 kind 分发:远程镐挖距放宽/信标网络封印可达豁免; - # 缺省 0/false=零装配零扰动。注入先于首板 install 已不成立〔板在早段〕——本批板生成不读两参数, + # 秘宝常时参数注入(装配集 kind 分发:远程镐挖距放宽/信标网络封印可达豁免; + # 缺省 0/false=零装配零扰动。注入在首板 install 之后〔板在早段〕——板生成不读两参数, # 参数只影响挖掘/插棋动作判据,时序安全) minesweeper.dig_range_bonus = attune_param_sum("dig_range_bonus") minesweeper.seal_range_free = attune_param_sum("seal_range_free") > 0 - # 充能重置周期(迭代 22 秘宝批 T3——battle=每战回满/level=每关首战回满〔battle_index==1〕; + # 充能重置周期(battle=每战回满/level=每关首战回满〔battle_index==1〕; # adventure 周期维持冒险开始 _seed_attune_charges 单次) _reseed_attune_charges("battle") if int(enc.get("battle_index", 1)) == 1: _reseed_attune_charges("level") - # board_installed 发射+施加(迭代 22 秘宝批 T3——巢穴预告:装板后一次报本板危险格数量; + # board_installed 发射+施加(巢穴预告:装板后一次报本板危险格数量; # 只报数量不标位置=信息红线,不碰分布=棋盘事实不可变契约 3。命中=读数口落值,呈现归 # 呈现桥消费(无格来源不进结算明细行——行来源纪律);板已就绪〔早段 install〕、订阅行已在 rebuild 装载) nest_preview_count = -1 @@ -409,27 +406,27 @@ func begin_battle(enc: Dictionary) -> bool: for h in bi_hits: if String(h.get("kind", "")) == "mine_count_preview": nest_preview_count = minesweeper.mine_total() - # 迭代 10 奖励重构批——跨冒险行动点加成轴(统一冒险加算区第四轴):经排队修正通道兑现 + # 跨冒险行动点加成轴(统一冒险加算区第四轴):经排队修正通道兑现 # 「每场战斗开始首轮 AP +加成值」(queue_ap_delta = 下轮开轮基线加算、notify_round_start 兑现后 # 清零——首轮即消费,后续轮次不重复兑现;语义锚 = 行动经济 GDD「跨冒险行动点加成轴」节) - var ap_bonus: int = int(enc.get("hero_ap_bonus", 0)) + int(enc.get("voucher_time_sand", 0)) # 迭代 20 T4——时沙同通道(首轮池增量,不改上限) + var ap_bonus: int = int(enc.get("hero_ap_bonus", 0)) + int(enc.get("voucher_time_sand", 0)) # 时沙同通道(首轮池增量,不改上限) if ap_bonus > 0: action_economy.queue_ap_delta(ap_bonus) - # 迭代 20 T4——储备金袋(节点级 RAP 注入)接收(完美保险注入通道随迭代 31 卡② 拆除——改由 feats.tres 订阅承载) + # 储备金袋(节点级 RAP 注入)接收(完美保险注入= feats.tres 订阅承载,不经此通道) var voucher_rap: int = int(enc.get("voucher_rap", 0)) if voucher_rap > 0: action_economy.grant_reserve_ap(voucher_rap) - # 工兵晨令直调拆除(内容数据驱动扩展批 T4——round_start grant_ap(mode:queue) 订阅行承载, - # when round_index ≤ effective_rounds 行字段 value_from 定影;发射位先于轮切换=当轮兑现) - # round_start 发射+施加(内容数据驱动扩展批 T3——发射位先于行动经济轮切换:树规则 grant_ap - # mode:queue 当轮入队、notify_round_start 即兑现(先手压制=首轮 AP+1 语义锚,与迁移前 - # begin_battle 直调 queue_ap_delta 逐位一致);计数器 round_start 重置点同点生效) + # 工兵晨令=round_start grant_ap(mode:queue) 订阅行承载, + # when round_index ≤ effective_rounds 行字段 value_from 定影;发射位先于轮切换=当轮兑现 + # round_start 发射+施加(发射位先于行动经济轮切换:树规则 grant_ap + # mode:queue 当轮入队、notify_round_start 即兑现(先手压制=首轮 AP+1 语义锚); + # 计数器 round_start 重置点同点生效) round_index = 1 _emit_round_start() if not action_economy.notify_round_start(): _fatal("行动经济 首轮 notify_round_start 被拒") return false - _roll_round_actions() # 开轮摇号(敌人技能池批——首轮同样摇;先于 round_started,挖掘期动画位可读) + _roll_round_actions() # 开轮摇号(首轮同样摇;先于 round_started,挖掘期动画位可读) round_started.emit(round_index) return true @@ -439,7 +436,7 @@ func _install_new_board(during_round := false) -> bool: var board: BoardData = _board_generator.generate(int(encounter.level_index), int(encounter.node_depth), stream, db) if board == null: return false - # 全局作用域变异决议(首发批 2026-10-04——装板序内前置于 roll_board:图级偏斜旋钮须在资源 + # 全局作用域变异决议(装板序内前置于 roll_board:图级偏斜旋钮须在资源 # 摇号前定型;全局门控与板无关〔节点身份+unlock+board_types〕,确定性取用零取号)。 # boss/elite 图命中全局型 → 写 board_variants(_place_variants 见非空即跳 region=替换制); # 全局池空 → 板级字段留空(_place_variants 原路走 region=兜底回落合法态)。 @@ -462,7 +459,7 @@ func _install_new_board(during_round := false) -> bool: if not _reward_economy.roll_board(eligible): _fatal("地图战斗资源 roll_board 被拒") return false - # 地形变异 布置段(2026-09-19 用户拍板棋盘设置顺序第 4 步:生成棋盘 → 打开状态初始化 → + # 地形变异 布置段(棋盘设置顺序第 4 步:生成棋盘 → 打开状态初始化 → # 战斗资源格设置 → 变异格设置)——布置在初始展开与资源格之后,变异天然不落已开区 _place_variants(board) _seal_consumed.clear() # 换图新雷 = 新实例,资格自然重置(行动经济 Rule 8) @@ -474,11 +471,11 @@ func _install_new_board(during_round := false) -> bool: _board_seq += 1 board_changed.emit() if treasure_inventory != null: - treasure_inventory.retire_overlays() # 迭代 7 T3——叠加层随图消亡(换图/刷新图装板点;已花道具不返还) + treasure_inventory.retire_overlays() # 叠加层随图消亡(换图/刷新图装板点;已花道具不返还) return true -# ---- 全局作用域变异 决议(首发批 2026-10-04——装板序内 roll_board 之前)---- +# ---- 全局作用域变异 决议(装板序内 roll_board 之前)---- # boss/elite 图命中全局型:写板级 board_variants(恰一行)+ 注入资源面偏斜旋钮(图级投影在 # RewardEconomy.roll_board 消费);不消费 variant_place 流(全局取用确定性——零取号合法态)。 # 全局池空(含 L1 Boss 免疫/unlock 门控未达):字段留空、旋钮归零——_place_variants 原路走 @@ -494,16 +491,16 @@ func _resolve_global_variant(board: BoardData) -> void: _reward_economy.board_skew = int(row.get("effect_value", 0)) -# ---- 地形变异 布置段(首批类型定稿批 2026-09-19——棋盘设置顺序第 4 步)---- +# ---- 地形变异 布置段(棋盘设置顺序第 4 步)---- # 候选池门控(unlock_level ≤ 关卡序号 + board_types 与本地形交集,∅ 通配)经 config_db.variant_pool; # 池空 = 合法态,静默零布置(框架 P0 口径不变)。零特判:本段只写格子变异数据快照,不改扫雷规则本体。 # 候选格域 = 安全格 − 初始展开区(伤害型 placement=closed_only 的结构保障——布置发生在初始展开之后, # 已开格天然排除);危险格不吃变异(挖雷一层惩罚 + 变异伤害双层叠罚污染逐行归因,首版排除——provisional)。 -# 每图至多一种类型(候选池内均匀选一,混型布置归因复杂留待后续批);数量 = round(候选池格数×percent) + -# (关卡序号−1)×per_level_bonus——基数为候选池而非总格数(2026-09-21 用户拍板基数修正批:初始展开 +# 每图至多一种类型(候选池内均匀选一,混型布置归因复杂留待后续);数量 = round(候选池格数×percent) + +# (关卡序号−1)×per_level_bonus——基数为候选池而非总格数(初始展开 # 占全板 56–67%,总格数基数使有效密度膨胀 4–6 倍、L1 小板极端全池覆盖;percent 语义 = 占可挖格比例, # 关卡递增由 per_level_bonus 绝对格数承载);连通片生长(8 邻),单片 ≤ pack_max(2×2 / 1×4 / 1×3+1 等形)。 -# 替换制(全局作用域变异首发批 2026-10-04):板级 board_variants 非空 = 本图已带全局型,跳过 region +# 替换制(全局作用域变异):板级 board_variants 非空 = 本图已带全局型,跳过 region # 布置(每图一型的板级推广:普通图=region,Boss/精英图=global);空 = 原路径(含 Boss 图全局池空回落)。 func _place_variants(board: BoardData) -> void: if not board.board_variants.is_empty(): @@ -572,14 +569,14 @@ func _on_cell_revealed(evt: Dictionary) -> void: # 轮 facts 缓冲不设相位守卫——轮末最后一挖的揭示事件在 request_dig 翻相之后才到(事件序: # cell_revealed 批 → seal_judged 批 → round_end),phase==Active 守卫会丢最后一挖的事实; # initial 通道事件(install 初始展开——封锁格)resource=false,进入授予段被资格检查自然跳过。 - # fx_reveal 通道事件旁路缓冲(迭代 20 T1——专长揭示的奖励由 _flush_pending_reveals 兑付点 + # fx_reveal 通道事件旁路缓冲(专长揭示的奖励由 _flush_pending_reveals 兑付点 # 直接入账,此处缓冲会导致二次兑付)。 if battle_result == "" and not _fx_revealing: - # 积点自动兑付(迭代 11 同调批 T6 → 迭代 22 秘宝批 T3 通用化 → 反哺批⑤ 2026-10-12 用户裁: + # 积点自动兑付: # 满 charge_n 直接当轮 grant_ap,无玩家发起入口、无积点账中转〔账即时清空,battle 域重置 # 自然无感〕。落位=揭示缓冲点——事件序 cell_revealed 批先于本格扣费,AP 归零恰逢积点满时 # 先兑再扣,轮次不因本格结束;授予段已无积点段(本段唯一计数点)。fx_reveal 旁路不计数= - # 沿现役缓冲路径口径〔天眼开格不计积点〕。grant_ap 相位防御在 ACTIVE 挖格链内恒过) + # 缓冲路径口径〔天眼开格不计积点〕。grant_ap 相位防御在 ACTIVE 挖格链内恒过) if String(evt.get("kind", "")) == "safe": var cs_row: Dictionary[Variant, Variant] = _attune_charge_safe_row() if not cs_row.is_empty(): @@ -619,24 +616,24 @@ func _maybe_settle() -> void: func _settle() -> void: _settling = true var ri := round_index - # 段序编排(迭代 27 T2——五段 Segment;段体归 game/core/settlement/,本类退为段序+ - # 行发射/开单原语单点。旧 259 行巨函数体已逐字迁五段类,git 史留痕) + # 段序编排(五段 Segment;段体归 game/core/settlement/,本类只做段序+ + # 行发射/开单原语单点) _grant_seg.run(ri) # ① 授予段(案C 闸随段装载) _aura_seg.run(ri) # ② 增益/减益段(续存实例组合行) _combat_seg.run(ri) # ③ 战斗段(主角先手 → 逐敌还手 → 地图伤害账殿后〔案C〕) _decay_seg.run(ri) # ④ 衰减段(恰一次恒执行含末轮——先兑付后衰减) var verdict: String = _verdict_seg.run(ri) # ⑤ 判定段(防御性优先级 hero 先判) if verdict != "continue": - return # 终局:旧早退语义逐位一致(_settling 不回置——_battle_over 已接管) + return # 终局:_settling 不回置——_battle_over 已接管 _settling = false # ---- 授予段 helpers(极性路由)---- -# 开格产出乘区(内容数据驱动扩展批 T3 参数化——贪婪矿灯/矿脉直觉/赌徒的血签事件收集器注入): +# 开格产出乘区(贪婪矿灯/矿脉直觉/赌徒的血签事件收集器注入): # positive=power ×(1+静态 mult% + 矿脉直觉连击加成 min(cap,combo)×10%);negative=power ×(1+cost%)。 # 全零收集器=原快照原样返回(零扰动)。combo 读数=效果引擎 dig_combo 计数器(safe+1/mine 清零, -# 跨轮累计——与迁移前 _feat_combo 逐位一致)。 +# 跨轮累计)。 func _feat_yield_adjust(snap: Dictionary, positive: bool, pos_m: int, neg_m: int, combo_cap: int) -> Dictionary: var combo_val := _fx.counter("dig_combo") if _fx != null else 0 if positive and pos_m <= 0 and combo_cap <= 0: @@ -687,8 +684,8 @@ func _hits_of(hits: Array, kind: String) -> Array: # 「动作 × 格型」矩阵的执行面:snap = 缓冲期冻结身份快照(cell_type = 该格装板期摇定的类型身份), # polarity 由动作决定(开安全格/封印命中 = positive,开危险格/标错封印 = negative), # 兑付行 = 奖励字典(类型, 极性)行。返回 true = percent 行实际生效(flat 行恒 false——兑付结果由行协议承载)。 -# ---- 秘宝(use_treasure 四步受理编排保留给同调主动件复用——迭代 11 第①批 T7:过渡授予路由 -# _grant_treasure 随掉落/停点渠道退役拆除;能力件注入归 LevelRunner.set_attune_charges 骑库存面)---- +# ---- 秘宝(use_treasure 四步受理编排,调用方=同调主动件;能力件注入归 +# LevelRunner.set_attune_charges 骑库存面)---- # use_treasure 四步受理(registry use_orchestration 规范序——唯一调用权归本类;序即原子: @@ -701,26 +698,26 @@ func use_treasure(handle: int, target: Vector2i) -> Dictionary: return {"ok": false, "reason": "库存未接线"} if action_economy.phase != action_economy.PHASE_ACTIVE: return {"ok": false, "reason": "非挖掘期(使用窗口=Active)"} - var board: MinesweeperRules = minesweeper # 恒等包装退役(2026-10-02 修复批——use_treasure 直引公有成员) - # 板维度读数(迭代 22 T3 修——Rules 无 width 代理〔潜伏缺陷:旧目录期零直呼覆盖掩盖〕,读 BoardData 本体) + var board: MinesweeperRules = minesweeper # 直引公有成员(无包装层) + # 板维度读数(Rules 无 width 代理,读 BoardData 本体) var board_b: BoardData = board.current_board() var v: Dictionary[Variant, Variant] = treasure_inventory.validate_use(handle, target, Vector2(board_b.width, board_b.height), func(c: Vector2i): return not board.is_revealed(c)) if not bool(v.ok): return v # ② 拒绝零消耗 - # treasure_used 发射+施加(内容数据驱动扩展批 T4——使用主动秘宝受理面:counter_spend 订阅=受理闸 - # (掘进蓄能积点账本),消耗成功才受理;积点不足拒绝零消耗。按 item_id 特判随本批拆除) + # treasure_used 发射+施加(使用主动秘宝受理面:counter_spend 订阅=受理闸 + # (掘进蓄能积点账本),消耗成功才受理;积点不足拒绝零消耗。零 item_id 特判) var tu_hits := _fx_emit("treasure_used", {"item_id": String(v.item_id), "target": target}) for h in tu_hits: if String(h.get("kind", "")) == "counter_spend": if not _fx.counter_spend(String(h.get("counter_id", "")), int(h.get("value", 1))): var vrow: Dictionary[Variant, Variant] = db.treasure_item_row(String(v.item_id)) - var cn_info: int = int(vrow.get("charge_n", 0)) # 迭代 22 T3——读受理行自身(旧 dig_charge 硬编码随行退役) + var cn_info: int = int(vrow.get("charge_n", 0)) # 读受理行自身 return {"ok": false, "reason": "%s:安全格积点未达(%d/%d)" % [String(vrow.get("display_name", "")), _attune_safe_seen % cn_info if cn_info > 0 else 0, cn_info]} var kinds: Array[Variant] = v.kinds if kinds.has("mine_reveal") or kinds.has("reveal_tiles"): - # 真视写入(迭代 22 T3——reveal_tiles 新真视 kind 与 mine_reveal 同叠加层通道: + # 真视写入(reveal_tiles 这类真视 kind 与 mine_reveal 同叠加层通道: # 危险格显示=信息呈现零回写,棋盘事实不可变契约 3) treasure_inventory.apply_overlay("mine_reveal", v.resolved) if kinds.has("reward_preview"): @@ -729,7 +726,7 @@ func use_treasure(handle: int, target: Vector2i) -> Dictionary: if not action_economy.grant_ap(int(v.magnitude)): return {"ok": false, "reason": "行动点加量被拒(相位防御)"} if kinds.has("safe_dig"): - # 天眼安全格直开(迭代 22 秘宝批 T3——C5 裁全额兑付:fx_reveal 通道复用=免 AP 零相位、 + # 天眼安全格直开(C5 全额兑付:fx_reveal 通道复用=免 AP 零相位、 # 连锁与格面资源与普通挖格同链;危险格仅真视显示不移除=契约 3;有封印格跳过——封印=玩家承诺不代开) var opened_any := false for c_v in v.resolved: @@ -741,51 +738,51 @@ func use_treasure(handle: int, target: Vector2i) -> Dictionary: if not opened_any: return {"ok": false, "reason": "天眼:窗口内安全格均已开(无可开格)"} if kinds.has("cell_removal"): - # 爆破工兵包兑付(迭代 13 T8/D6——中立移除危险格:未揭示/无封印/是雷过滤归排雷玩法; - # P1 甲邻接数字冻结零重算、清图分母零涉(危险格不入分母);空集拒绝零消耗—— + # 爆破工兵包兑付(中立移除危险格:未揭示/无封印/是雷过滤归排雷玩法; + # 邻接数字冻结零重算、清图分母零涉(危险格不入分母);空集拒绝零消耗—— # consume 之前 return(拒绝面注记扩「③内零消耗分支」),拒绝 reason 可呈现) var blasted: Array[Variant] = board.remove_mines_in(v.resolved) if blasted.is_empty(): return {"ok": false, "reason": "爆破工兵包:3×3 区域内无可移除危险格(须未揭示且未封印)"} var rec: Dictionary[Variant, Variant] = treasure_inventory.consume(handle) - # 同调主动件充能扣减(迭代 11 第①批 T6——共享账本直改:adventure/level/settlement 同一字典引用) + # 同调主动件充能扣减(共享账本直改:adventure/level/settlement 同一字典引用) if not rec.is_empty() and String(rec.get("source_class", "")) == "attunement": _ledger.attune_charge_consume(String(rec.get("item_id", ""))) - # 真视类工具使用计数(迭代 22 秘宝批 T3——信标网络解锁行为条件:受理成功恰计一次; + # 真视类工具使用计数(信标网络解锁行为条件:受理成功恰计一次; # 共享 dict 引用下传〔attune_charges 同款〕,冒险收束聚合入档 save.add_vision_used) if kinds.has("reveal_tiles") or kinds.has("safe_dig") or kinds.has("mine_reveal"): if not _ledger.vision_counter.is_empty(): - _ledger.vision_count_add(1) # 迭代 22 秘宝批 T3——受理成功恰计一次(缺省空账=调试不计) + _ledger.vision_count_add(1) # 受理成功恰计一次(缺省空账=调试不计) return {"ok": true, "item_id": v.item_id, "resolved": v.resolved, "record": rec} -# aux 解锁门控转发(迭代 7 T5——LevelRunner 注入;E1/E3 封装:外部经公有面,禁直读 _reward_economy) +# aux 解锁门控转发(LevelRunner 注入;E1/E3 封装:外部经公有面,禁直读 _reward_economy) func set_treasure_unlocked(ids: Dictionary) -> void: _reward_economy.set_treasure_unlocked(ids) func _grant_routed(snap: Dictionary, polarity: String, source_class: String, cell: Vector2i, ri: int, highlight: String = "", label_suffix: String = "", halve_pct: int = 0) -> bool: - # 迭代 11 第①批 T7——aux 授予分支随掉落/停点渠道退役拆除(reward 词表第十型 treasure_item 保留但零投放: - # 无 aux 行入池、CURIO_KINDS 词表已除名);剩余类型走极性字典路由。 + # treasure_item 型零投放(无 aux 行入池、CURIO_KINDS 词表无此型),本口不处理; + # 剩余类型走极性字典路由。 var row: Dictionary[Variant, Variant] = _reward_economy.polarity_row(String(snap.get("cell_type", "")), polarity) if row.is_empty(): _fatal("极性字典缺行: %s %s" % [String(snap.get("cell_type", "")), polarity]) return false if polarity == "positive": row["power"] = int(snap.get("power", int(row.power))) # 区间行快照 power(身份批 roll 值)覆盖表值——授予期零随机口径(E14) - # 标中兑付溢价(迭代14②判式换代批 T4——条款3 条件二封印溢价形态 a,2026-10-04 用户裁 P3): + # 标中兑付溢价(条款3 条件二封印溢价形态 a): # δ 读 settlement.seal_hit_premium(percent 域 125=×1.25 provisional);100=无溢价直通零扰动。 # 兑付公式一处=本块:只乘封印命中正向(flat power 乘后入单据/治疗/排队;percent 幅度经 # premium_pct 贯穿 _apply_percent_row 应用与呈现同乘)——标空/挖格/清图不乘,雷安同池冻结不动。 - # 取整=四舍五入(与伤害管线 round_direction=floor 分域——registry clause3_inequality 随批登记; + # 取整=四舍五入(与伤害管线 round_direction=floor 分域——registry clause3_inequality 登记; # 1 点量纲行 ac_up/action 取整后不变=整数粒度地板)。 if source_class == "seal_hit" and int(db.settlement.seal_hit_premium) != 100: var prem_pct: int = int(db.settlement.seal_hit_premium) row = row.duplicate() row["power"] = int(round(int(row.power) * prem_pct / 100.0)) row["premium_pct"] = prem_pct - # 惊巢反制(迭代 11 同调批 T5 → 内容数据驱动扩展批 T4:按 id 特判拆除——减半系数=mine_hit - # damage_mult 订阅命中(行 value 50=减 50%,取整 ceil 与迁移前逐位一致);反弹单=mine_hit + # 惊巢反制(减半系数=mine_hit + # damage_mult 订阅命中(行 value 50=减 50%,取整 ceil);反弹单=mine_hit # open_ticket channel reflect 订阅施加(编排器 mine_hit 施加段);duplicate 隔离——减半不回写极性字典) if halve_pct > 0 and polarity == "negative" and source_class == "mine_hit": row = row.duplicate() @@ -804,7 +801,7 @@ func _dispatch_row(row: Dictionary, source_class: String, cell: Vector2i, ri: in return false -# percent 行兑付:GP 型行走战斗内缓冲记账(GP+商店房实施批);其余 apply_effect 入容器; +# percent 行兑付:GP 型行走战斗内缓冲记账;其余 apply_effect 入容器; # 满层拒收 = "奖励未生效"行(零静默) func _apply_percent_row(row: Dictionary, source_class: String, cell: Vector2i, ri: int, highlight: String = "", label_suffix: String = "") -> bool: var eff := String(row.effect_id) @@ -827,7 +824,7 @@ func _apply_percent_row(row: Dictionary, source_class: String, cell: Vector2i, r return false -# GP 型行兑付(GP+商店房实施批 2026-09-21):战斗内缓冲 escrow 记账——不入钱包不入增益容器。 +# GP 型行兑付:战斗内缓冲 escrow 记账——不入钱包不入增益容器。 # 正向(gp_gain)= 挖开GP安全格/封印命中;负向(gp_loss)= 挖危险格/标错封印。兑付行经既有 effect 行 # 通道外发(escrow 随行——归因可读),战斗结束随 gp_dropped 一次上抛后即弃。 func _apply_gp_row(row: Dictionary, source_class: String, cell: Vector2i, ri: int, highlight: String = "", label_suffix: String = "") -> bool: @@ -838,7 +835,7 @@ func _apply_gp_row(row: Dictionary, source_class: String, cell: Vector2i, ri: in return true -# flat 行兑付(负向恒即时,无库存语义):伤害型分支全部改开单据(伤害管线单据化批 2026-09-24—— +# flat 行兑付(负向恒即时,无库存语义):伤害型分支走开单据( # 管线/下限/目标解析归 伤害控制器,本函数只保留非伤害分支与单据装配): # action = 行动点排队(非伤害);blast 正向 = 群伤单据(无类型恒定表值打全体存活敌;负向 = 警觉 percent 行走 _apply_percent_row); # heal 正向 = 主角回复 clamp(满血 → 奖励未生效行);heal 负向 = 主角直伤单据(不经增益状态); @@ -859,7 +856,7 @@ func _apply_flat_row(row: Dictionary, source_class: String, cell: Vector2i, ri: DamageController.TARGET_ALL_ALIVE, ri, cell, "", 0, highlight, {"batch_key": String(row.reward_id)}) return _outcome_of(_submit(t, sync)) if ctype == "pierce" or ctype == "magic": - # 伤害道具批(2026-09-18)语义不变:正向 = 单目标克制直伤(必中全额不掷点——棋盘来源伤害既有口径); + # 正向 = 单目标克制直伤(必中全额不掷点——棋盘来源伤害既有口径); # 负向 = 主角直伤(复用反噬通道)。 if String(row.get("polarity", "positive")) == "negative": return _submit_flat_hero(source_class, display, power, cell, ri, highlight, sync) @@ -927,7 +924,7 @@ func _grant_clear_reward(ri: int) -> void: # 清图奖励 = 板级独立对象(不属于任何一格):兑付形态按其 cell_type 的正向字典形态走, # 行值全部取快照(身份批 roll 值)。返回实际有效兑付。 -# 同步开单(sync)——完美第二份与高光份数的流程依赖需要同步读数(开单权归流程 用户裁决③); +# 同步开单(sync)——完美第二份与高光份数的流程依赖需要同步读数(开单权归流程); # 同步路径内先按序结清段内排队单据(B 模式保序),随后本批无视结账政策当场兑现。 func _grant_clear_identity(snap: Dictionary, ri: int, suffix: String) -> bool: var row := { @@ -945,12 +942,12 @@ func _grant_clear_identity(snap: Dictionary, ri: int, suffix: String) -> bool: return _apply_flat_row(row, "clear_reward", Vector2i(-1, -1), ri, "clear_reward_h2", suffix, true) == "redeemed" -# ---- 开轮摇号(敌人技能池批——共识点 B:技能选择前置到轮次开始,数值计算留结算段)---- +# ---- 开轮摇号(共识点 B:技能选择前置到轮次开始,数值计算留结算段)---- # 每实例:保底判定(连续执行普攻 ≥ M → 必出特殊技、特殊技内按权重、不受冷却限制)→ 排除冷却中技能 # (中签率 = 权重 ÷ 可摇权重合计——份额归一)→ 按行序逐敌从统一流顺序取号摇定本拍动作。 # 随机消费只在换算层(本方法 + SkillLottery);单位容器收确定值(零随机纪律——armor_roll 先例同构)。 -# 并流批(2026-09-27 统一流裁决):behavior_roll 子流派生向量(spawn_index×STRIDE+序)退役—— -# 「单敌轨迹独立复放」前提随之移除(位置交错,单点定位由事件日志承载)。摇定后、兑现前死亡 → 本拍技能作废。 +# 统一流:behavior_roll 无子流派生向量(位置交错,单点定位由事件日志承载)。 +# 摇定后、兑现前死亡 → 本拍技能作废。 func _roll_round_actions() -> void: var pity_m: int = int(db.skill.pity_threshold) for u in _enemy_system.query_alive("enemy"): @@ -970,7 +967,7 @@ func _roll_round_actions() -> void: if String((pe as Dictionary).get("skill_id", "")) == sid and (pe as Dictionary).has("unlock_hp_pct"): pct_v = int((pe as Dictionary).unlock_hp_pct) break - # 迭代 20 T1——target_attack_bonus 施加面(处刑台:敌血量阈值沿挂单位字典标记, + # target_attack_bonus 施加面(处刑台:敌血量阈值沿挂单位字典标记, # 主角攻击面 _resolve_hero_attack 通用消费——fx_atk_bonus 键加算进 base_value) var eht_hits := _fx_emit("enemy_hp_threshold", {"unit": String(u.enemy_id), "pct": pct_v, "is_boss": String(encounter.get("node_type", "")) == "boss"}) @@ -988,15 +985,14 @@ func _roll_round_actions() -> void: # ---- 战斗段 ---- -# 伤害管线单据化批(2026-09-24):本段只开单——主角先手单 + 敌方伤害技单;掷点/折扣/暴击/克制/ -# 池乘区/下限/交付/commit 全部收口 伤害控制器(A 模式提交即结=与迁移前逐位一致;B 模式段尾 flush)。 -# 开单守卫归流程(用户裁决③——流程决定给谁开单):主角存活+目标存在才开先手单;hero hp=0 立即 +# 本段只开单——主角先手单 + 敌方伤害技单;掷点/折扣/暴击/克制/ +# 池乘区/下限/交付/commit 全部收口 伤害控制器(A 模式提交即结;B 模式段尾 flush)。 +# 开单守卫归流程(流程决定给谁开单):主角存活+目标存在才开先手单;hero hp=0 立即 # 停开(B 模式下若 flush 中主角倒下,由控制器死亡事件终止余单——两模式同一结果)。 -# ---- 算术读数(伤害管线单据化批 2026-09-24 迁移注记)---- -# 掷点/折扣/克制点数/池乘区/攻击行文本已全部迁入 伤害控制器(damage_controller.gd 管线单点); -# 本类仅保留一处薄委托——_defender_ac(快照面消费)。_clamped_pool 委托壳已随 2026-10-02 修复批删除 -# (冒烟白盒断言消费面改直引 settlement._damage.clamped_pool——并行卡同批改 smoke_all)。 +# ---- 算术读数 ---- +# 掷点/折扣/克制点数/池乘区/攻击行文本 归 伤害控制器(damage_controller.gd 管线单点); +# 本类只保留一处薄委托——_defender_ac(快照面消费)。 # 防守方护甲等级读数——实现归 伤害控制器 defender_ac(本委托供结算快照/呈现快照) func _defender_ac(unit: Dictionary) -> int: @@ -1052,7 +1048,7 @@ func _emit_settlement_snapshot(verdict: String) -> void: "round": round_index, "verdict": verdict, "unit_count": enemies.size(), - "spawn_count": _enemy_system.all_enemies().size(), # 本战斗实例化总数(含死亡残位)——unit_count=0 时区分「首轮全灭」vs「空场」(playtest-2026-09-12 报告 Bug#1 误读教训) + "spawn_count": _enemy_system.all_enemies().size(), # 本战斗实例化总数(含死亡残位)——unit_count=0 时区分「首轮全灭」vs「空场」 "hero": {"hp": int(_enemy_system.hero_unit().get("hp", 0)), "max_hp": int(_enemy_system.hero_unit().get("max_hp", 0)), "atk": int(_enemy_system.hero_unit().get("atk", 0)), "armor_class": _defender_ac(_enemy_system.hero_unit())}, "economy": {"phase": String(action_economy.phase), "ap": int(action_economy.ap), "rap": int(action_economy.rap), "refresh_used": _refresh_used_this_round}, "board": board_stats, @@ -1095,7 +1091,7 @@ func can_refresh() -> bool: # 玩家经 HUD框架发起、战斗结算 代理调用(禁止 RAP 满自动刷)。 -# 挖掘期唯一通道(2026-09-12 方案 A 拍板 + 2026-09-15 等待期通道整体移除):Active 相位立即换图 +# 挖掘期唯一通道:Active 相位立即换图 # 继续挖(RAP -8;AP 保留、相位不动、不触发结算);非挖掘期请求一律拒绝——非清图轮恒同图。 func player_request_refresh() -> bool: if not can_refresh(): @@ -1110,14 +1106,14 @@ func player_request_refresh() -> bool: func _battle_over(result: String) -> void: battle_result = result - # battle_won 发射+施加(迭代 20 T1——战地包扎 heal 订阅面;败北不发射。heal=英雄单位回血 + # battle_won 发射+施加(战地包扎 heal 订阅面;败北不发射。heal=英雄单位回血 # 〔封顶单位上限〕,战后生命经 hero_hp_left 回写冒险账本——时点在捕获前=回血计入带入下一层) if result == "victory": for h in _fx_emit("battle_won", {"round": round_index}): if String(h.get("kind", "")) == "heal": var hu_w: Dictionary[Variant, Variant] = _enemy_system.hero_unit() hu_w["hp"] = mini(int(hu_w.get("hp", 0)) + int(h.get("value", 0)), maxi(1, int(hu_w.get("max_hp", 1)))) - # bonus_delta 战末汇入(迭代 20 T1——血税双向账:本战累积并入冒险加算区共享引用后清零)+ + # bonus_delta 战末汇入(血税双向账:本战累积并入冒险加算区共享引用后清零)+ # adventure 域计数器导出回写(T6——共享引用覆写,attune_charges 先例) if not _ledger.bonus.is_empty(): for axis in _fx_bonus_delta.keys(): @@ -1127,19 +1123,19 @@ func _battle_over(result: String) -> void: _ledger.counters_merge_export(_fx.counters_export()) # 映射随战斗结束退役(地图战斗资源 义务④——下一场战斗 = 新板新 scope 批,roll_board 相位守卫的前提) var hero_hp_left := int(_enemy_system.hero_unit().get("hp", 0)) # despawn 前捕获(信号载荷供呈现层"HP 带入下一层") - var gp_dropped := _roll_gp_drop() # 战斗掉落(GP+商店房实施批——escrow 随此值上抛即弃) + var gp_dropped := _roll_gp_drop() # 战斗掉落(escrow 随此值上抛即弃) _reward_economy.retire_mapping() _enemy_system.despawn_all() _status_effects.notify_battle_end() if treasure_inventory != null: - treasure_inventory.retire_overlays() # 迭代 7 T3——叠加层随战斗结束清空(库存不动——关卡域跨战斗) - action_economy.notify_combat_end() # → Idle,RAP 清零(2026-10-02 修复批:原被 tab 事故并进上一行行尾注释从不执行——每战新建实例掩盖了症状;P0-3) + treasure_inventory.retire_overlays() # 叠加层随战斗结束清空(库存不动——关卡域跨战斗) + action_economy.notify_combat_end() # → Idle,RAP 清零 db.set_reload_gate(false) _reset_round_facts() battle_finished.emit({"result": result, "hero_hp": hero_hp_left, "gp_dropped": gp_dropped}) -# 战斗掉落掷定(GP+商店房实施批 2026-09-21):tier = Boss 节点 ? "boss" : "normal"(elite 留分支位); +# 战斗掉落掷定:tier = Boss 节点 ? "boss" : "normal"(elite 留分支位); # gp_dropped = gp_drop 封闭流掷定(tier 行的 roll_min..roll_max 均匀整数——每战斗末恰一 scope) # + level_gp_bonus(level_index) + escrow。掷定行缺位 = 数据面缺行(fail 报错按 0 兑付——不哑掉)。 func _roll_gp_drop() -> int: @@ -1152,25 +1148,25 @@ func _roll_gp_drop() -> int: var stream: RandomNumberGenerator = rng.open_stream("gp_drop") roll = stream.randi_range(int(drops.get("roll_min", 0)), int(drops.get("roll_max", 0))) var drop := roll + db.shop_level_gp_bonus(int(encounter.get("level_index", 0))) - # 财富之道·聚(迭代 21 T3——战斗掉落 GP 乘算·入账前:只乘战斗掉落两成分〔掷定+关卡加成〕, - # 店内 escrow 不乘〔范围=仅战斗掉落渠道,卡片§11②裁决〕;本函数返回值=结算框「GP 增量」行 - # 显示源,落在入账前=显示即实得;乘数 provisional 150%,值归 M4 数值批) + # 财富之道·聚(战斗掉落 GP 乘算·入账前:只乘战斗掉落两成分〔掷定+关卡加成〕, + # 店内 escrow 不乘〔范围=仅战斗掉落渠道〕;本函数返回值=结算框「GP 增量」行 + # 显示源,落在入账前=显示即实得;乘数 provisional 150%) if (encounter.get("tree_rules", []) as Array).has("economy_hoard"): drop = int(round(float(drop) * 1.5)) return drop + escrow -# ---- 呈现状态面(E1 封装收口 2026-09-13):呈现层 / headless 自动玩家的唯一读取出口—— +# ---- 呈现状态面(E1 封装收口):呈现层 / headless 自动玩家的唯一读取出口—— # 协作对象(_enemy_system/_status_effects/_reward_economy)私有化后,跨层读取一律经本快照或下列命名面(diagnostic_snapshot 同款模式, # 禁再链式穿透 settlement.enemy_system.hero 一类路径)。载荷 schema 成文(code-conventions 2.1): # round / battle_result / phase / ap / rap / can_refresh / hero{hp,max_hp,atk,alive,armor_class} / # enemies[{order,display_name,hp,max_hp,enemy_id,armor_type,armor_class,pending_skill,pending_type,pending_name,effects[],alive}] / -# (敌人技能池批批 2 定稿:beat/ring_size/ring_index 拆除 → pending_* 三字段 + 敌方增益 effects 投影;池与权重不公开; -# 八型批 2026-09-20:ambush_layers 拆除——伏击退役,警觉并入 effects 投影)hero_effects[](增益状态 query_active 投影) +# (字段面=pending_* 三字段 + 敌方增益 effects 投影;池与权重不公开;警觉走 effects 投影) +# hero_effects[](增益状态 query_active 投影) func presentation_snapshot() -> Dictionary: var enemies: Array[Dictionary] = [] var all: Array[Variant] = _enemy_system.all_enemies() - # 敌方增益投影(side-wide 状态——蓄力/硬化/削弱/暴走 percent 行 + 警觉 ac 行,八型批 2026-09-20) + # 敌方增益投影(side-wide 状态——蓄力/硬化/削弱/暴走 percent 行 + 警觉 ac 行) var enemy_effects: Array[Dictionary] = [] for eff in _status_effects.query_active("enemy"): var erow: Dictionary[Variant, Variant] = db.status_effect_row(eff.effect_id) @@ -1206,11 +1202,11 @@ func presentation_snapshot() -> Dictionary: "phase": String(action_economy.phase), "ap": int(action_economy.ap), "rap": int(action_economy.rap), "can_refresh": can_refresh(), - "refresh_used": _refresh_used_this_round, # 迭代 27 T3——P1-2 刷新双账收口:受理计数入呈现成文面(HUD 余量单源读此处) + "refresh_used": _refresh_used_this_round, # 受理计数入呈现成文面(HUD 余量单源读此处) "hero": hero, "enemies": enemies, - "hero_effects": _status_effects.query_active("hero").duplicate(true), # 值拷贝出户(code-review 2026-09-29 P2-3——快照消费方直改不渗入状态容器) - # 板级变异投影(全局作用域变异首发批 2026-10-04——呈现横幅/常驻角标唯一读取面; + "hero_effects": _status_effects.query_active("hero").duplicate(true), # 值拷贝出户(快照消费方直改不渗入状态容器) + # 板级变异投影(呈现横幅/常驻角标唯一读取面; # 空数组 = 无全局型合法态:普通图与全局池空回落图恒空) "board_variants": (minesweeper.current_board().board_variant_ids().duplicate() if minesweeper.current_board() != null else ([] as Array[String])), @@ -1228,7 +1224,7 @@ func query_reward_identity(cell: Vector2i): # 诊断观测面(组合根诊断转储 / 行为探针消费):私有编排状态的成文只读出口—— -# 消费方禁止再直读本类下划线字段(code-review 2026-09-12 封装收口批) +# 消费方禁止再直读本类下划线字段(封装收口) func diagnostic_snapshot() -> Dictionary: return { "battle_result": battle_result, @@ -1293,7 +1289,7 @@ func _fatal(msg: String) -> void: assert(false, msg) -## 完美排雷谓词(迭代 31 卡② T4——两账相减:有效误标=误标总数−豁免数) +## 完美排雷谓词(两账相减:有效误标=误标总数−豁免数) ## 契约 2:_perfect_hit_false 保持纯净,豁免只累加 _perfect_forgiven,禁回退式改写与拦截式吞事件。 func perfect_sweep_earned() -> bool: return _perfect_hit_false - _perfect_forgiven <= 0 and _perfect_hit_true >= 1 diff --git a/game/core/board_data.gd b/game/core/board_data.gd index 677ced68..872f3e88 100644 --- a/game/core/board_data.gd +++ b/game/core/board_data.gd @@ -4,7 +4,7 @@ class_name BoardData extends RefCounted -# 出生 3×3 区格数(2026-10-02 修复批 T2 魔法数结构化——W×H−9 布雷域基的双落点收口单点: +# 出生 3×3 区格数(W×H−9 布雷域基的双落点收口单点: # 棋盘生成 _attempt/_finalize 与 BoardGenTable 布雷数下限校验共用;与 spawn_cells() 的 3×3 几何同源) const SPAWN_AREA_CELLS := 9 @@ -14,7 +14,7 @@ var spawn_center := Vector2i.ZERO var mines := {} # Vector2i → true var digits := {} # Vector2i → int(安全格恒有值;数字恒真 = 8 邻雷数) var variants := {} # Vector2i → Array[String](生成期快照,抗表重载) -var board_variants: Array[String] = [] # 板级变异 id 集(scope=global 整图作用域——全局作用域变异批 2026-10-04: +var board_variants: Array[String] = [] # 板级变异 id 集(scope=global 整图作用域—— # 战斗编排装板决议写入,随图生灭同 variants;普通图恒空) var board_type := "" # 图类型标签(词表 v1.0:dungeon/underdark;玩家侧显示名「地图类型」) var level_index: int = 1 @@ -28,7 +28,7 @@ func in_bounds(c: Vector2i) -> bool: return c.x >= 0 and c.y >= 0 and c.x < width and c.y < height -# 行主序排序键(2026-10-02 修复批——排雷玩法 封印判定批与 地图战斗资源 资格规范化两处手抄收口单点): +# 行主序排序键(排雷玩法 封印判定批与 地图战斗资源 资格规范化两处手抄收口单点): # y×1000+x 字典序 = 行主序;板宽域 [8,64] 远小于 1000,x 不跨行、键值不碰撞。 static func row_major_key(c: Vector2i) -> int: return c.y * 1000 + c.x @@ -55,7 +55,7 @@ func board_variant_ids() -> Array[String]: return board_variants -# 中和格变异(迭代 12 T6 净化工兵——伤害型地形格变普通格;🔴 R4 甲仅限伤害型的过滤在调用方) +# 中和格变异(伤害型地形格变普通格;🔴 仅限伤害型的过滤在调用方) func neighbors8(c: Vector2i) -> Array: var out: Array[Vector2i] = [] for dy in range(-1, 2): @@ -103,7 +103,7 @@ func compute_r0() -> Array: var queue: Array[Variant] = b3.duplicate() while not queue.is_empty(): var c: Vector2i = queue.pop_front() - if is_safe(c) and digit_of(c) == 0: # 变异死分支退役(2026-09-18 用户拍板删——与 排雷玩法 展开实现口径归一;变异定稿批按正式语义重接) + if is_safe(c) and digit_of(c) == 0: # 与 排雷玩法 展开实现同口径(安全且数字 0 才扩散) for n in neighbors8(c): if is_safe(n) and not r0.has(n): r0[n] = true diff --git a/game/core/board_generator.gd b/game/core/board_generator.gd index 290e9352..a3b5d1ae 100644 --- a/game/core/board_generator.gd +++ b/game/core/board_generator.gd @@ -11,7 +11,7 @@ const METRIC_VERSION := 1 # ==================== 生成入口 ==================== # rng_stream = 一次 open_stream("board_gen") 实例(一张图的全部取数;重试共用——attempt 边界非 scope 事件)。 -# db 参数不标具体类型原因:冒烟工具注入 FakeDB 桩(experiment_density.gd 等)——typed 形参会拒收桩表(2026-10-02 注) +# db 参数不标具体类型原因:冒烟工具注入 FakeDB 桩(experiment_density.gd 等)——typed 形参会拒收桩表 func generate(L: int, D: int, rng_stream: RandomNumberGenerator, db) -> BoardData: # type-hint: ignore(测量面 _BoardRowStub 冒烟夹具鸭子型注入——typed 参拒 stub) var row: Dictionary[Variant, Variant] = db.resolve_board_gen(L, D) if row.is_empty(): @@ -86,7 +86,7 @@ func _attempt(params: Dictionary, rng_stream: RandomNumberGenerator, db) -> Boar b.level_index = params.L b.node_depth = params.D # ② 布雷:N = round(d×(W×H−9)) 先定数;域 = 全格 − 出生 3×3;均匀布雷后"先布后删" - # (−9 = 出生区格数,常量单点 BoardData.SPAWN_AREA_CELLS——2026-10-02 修复批) + # (−9 = 出生区格数,常量单点 BoardData.SPAWN_AREA_CELLS) var spawn := {} for c in b.spawn_cells(): spawn[c] = true diff --git a/game/core/config_db.gd b/game/core/config_db.gd index cf90f617..db0ddc0c 100644 --- a/game/core/config_db.gd +++ b/game/core/config_db.gd @@ -19,13 +19,13 @@ const TABLE_MANIFEST := { "settlement": "settlement.tres", "level": "level.tres", "difficulty": "difficulty.tres", - "shop": "shop.tres", # GP+商店房实施批 2026-09-21(表与 schema 落籍归并行数据面——本批只接线加载与消费) - "meta": "meta.tres", # 元进度实现批 2026-09-21(MetaTable 四行族——schema 与表同批落籍) - "meta_tree": "meta_tree.tres", # 迭代 12 T8 建域、迭代 21 T1 换代 12 节点(MetaTreeTable 定义表 Rule 4 豁免——天赋树.md v0.8 结构事实源) - "treasure_items": "treasure_items.tres", # 迭代 7 T1 秘宝内容批(TreasureItemTable 六行——定义表 Rule 4 豁免;罗盘 retired/失义件 deferred 标记见 schema 头注) - "adventure": "adventure.tres", # 冒险结构实现批 2026-09-21(AdventureTable 建表——大奖励与钥石行值单点) - "feats": "feats.tres", # 迭代 12 T1 双层 BD 规则改写型特性基建(FeatTable 定义表 Rule 4 豁免——TreasureItemTable 先例;空表合法态=主时间线零扰动) - "forge": "forge.tres", # 迭代 23 T1 锻造工坊实装批(ForgeTable——两根类型轴默认值+六路线行族;攻防所有权切分唯一数据面) + "shop": "shop.tres", # ShopTable(表与 schema 落籍归数据面——本处只接线加载与消费) + "meta": "meta.tres", # MetaTable 四行族(schema 与表同源落籍) + "meta_tree": "meta_tree.tres", # MetaTreeTable 12 节点(定义表 Rule 4 豁免——天赋树.md v0.8 结构事实源) + "treasure_items": "treasure_items.tres", # TreasureItemTable 六行(定义表 Rule 4 豁免;罗盘 retired/失义件 deferred 标记见 schema 头注) + "adventure": "adventure.tres", # AdventureTable(大奖励与钥石行值单点) + "feats": "feats.tres", # FeatTable 规则改写型特性(定义表 Rule 4 豁免——TreasureItemTable 先例;空表合法态=主时间线零扰动) + "forge": "forge.tres", # ForgeTable——两根类型轴默认值+六路线行族;攻防所有权切分唯一数据面 } var action_economy: ActionEconomyTable @@ -39,20 +39,20 @@ var reward: RewardTable var settlement: SettlementTable var level: LevelTable var difficulty: DifficultyTable -# GP+商店房实施批(2026-09-21):ShopTable 类型化持用(schema class_name 已落籍——code-review 2026-09-29 P2-4 收口; +# ShopTable 类型化持用(schema class_name 已落籍; # 消费面一律走下方 shop_* 访问器,禁直读行集) var shop: ShopTable = null -# 元进度实现批(2026-09-21):MetaTable 类型化持用(schema 与表同批落籍,无 shop 先例的落籍间隙问题) +# MetaTable 类型化持用(schema 与表同源落籍) var meta: MetaTable -var meta_tree: MetaTreeTable # 迭代 12 T8 类型化持用(消费面走 tree_node 访问器) -var treasure_items: TreasureItemTable # 迭代 7 T1 类型化持用(消费面走 treasure_* 访问器) +var meta_tree: MetaTreeTable # 类型化持用(消费面走 tree_node 访问器) +var treasure_items: TreasureItemTable # 类型化持用(消费面走 treasure_* 访问器) var adventure: AdventureTable -var feats: FeatTable # 迭代 12 T1 类型化持用(消费面走 feat_* 访问器) -var forge: ForgeTable # 迭代 23 T1 锻造工坊配置(默认两轴+六路线行族——消费面走 forge_* 访问器) +var feats: FeatTable # 类型化持用(消费面走 feat_* 访问器) +var forge: ForgeTable # 锻造工坊配置(默认两轴+六路线行族——消费面走 forge_* 访问器) var is_ready := false var _diagnostics: Array[Dictionary] = [] # {severity, category, message} -var _resolver: ConfigDbResolver # R1 难度行解析协作类(2026-10-02 修复批 T5 拆分——门面公有签名零变化) +var _resolver: ConfigDbResolver # R1 难度行解析协作类(门面公有签名不变) var _validator := ConfigDbCrossValidator.new() # 跨表校验协作类(无状态——声明期即建) var _reload_gate := false # 数据配置 EC8——战斗结算 唯一调用方 @@ -70,7 +70,7 @@ func push_diag(severity: String, category: String, message: String) -> void: push_error("[ConfigDB/%s] %s" % [category, message]) -# 运行期数据致命(2026-09-18 用户拍板 fail-fast;迭代 27 T6——退出执行归根:核心层不再自携 +# 运行期数据致命(fail-fast;退出执行归根:核心层不自携 # quit/crash,越域记 Fatal 级日志后置 _fatal_flag,进程退出决策归组合根(main._ready 表加载 # 失败已有同通道 fatal 屏+fail-fast 边界)——查询期消费方按返回值安全面走既有默认值回退) func _fatal(category: String, message: String) -> void: @@ -79,7 +79,7 @@ func _fatal(category: String, message: String) -> void: _fatal_flag = true -var _fatal_flag := false # 运行期致命封印(迭代 27 T6——退出归根承载;组合根/闸读面) +var _fatal_flag := false # 运行期致命封印(退出归根承载;组合根/闸读面) func is_fatal() -> bool: @@ -152,7 +152,7 @@ func load_tables(root: String, collect_only: bool) -> bool: return not has_errors -# ---- relic 访问器(迭代 12 T1——消费面一律走本组,禁直读行集)---- +# ---- relic 访问器(消费面一律走本组,禁直读行集)---- func feat_row(feat_id: String) -> Dictionary: return feats.row_by_id(feat_id) if feats != null else {} @@ -163,7 +163,7 @@ func feat_rows() -> Array: return feats.rows if feats != null else [] -# 天赋树节点行(迭代 12 T8——MetaProgression 树段/营地树 UI 取数口) +# 天赋树节点行(MetaProgression 树段/营地树 UI 取数口) func tree_node(node_id: String) -> Dictionary: return meta_tree.row_by_id(node_id) if meta_tree != null else {} @@ -172,8 +172,8 @@ func tree_rows() -> Array: return meta_tree.rows if meta_tree != null else [] -# 跨表校验(悬空引用 / 池护栏——全部加载期致命)本体自 2026-10-02 修复批迁出: -# ConfigDbCrossValidator(core/config_db_cross_validator.gd)承载,门面公有签名零变化。 +# 跨表校验(悬空引用 / 池护栏——全部加载期致命)本体: +# ConfigDbCrossValidator(core/config_db_cross_validator.gd)承载,门面公有签名不变。 func _cross_validate(loaded: Dictionary) -> void: _validator.cross_validate(loaded, push_diag) @@ -183,15 +183,15 @@ func validate_skill_pool_links(skill_table: SkillTable, enemy_table: EnemyTable, return _validator.validate_skill_pool_links(skill_table, enemy_table, status_table) -# ---- R1 难度行解析(2026-09-18 用户拍板修订:ceil 向上取整保证偏难;域越界与内容缺口 Fatal 退出)---- -# 解析本体自 2026-10-02 修复批迁出:ConfigDbResolver(core/config_db_resolver.gd)承载—— -# 含 _resolve_progress/_ceil_key 与 R1 告警去重注册表;门面同名方法委托,越域 Fatal 语义逐位一致。 +# ---- R1 难度行解析(ceil 向上取整保证偏难;域越界与内容缺口 Fatal 退出)---- +# 解析本体:ConfigDbResolver(core/config_db_resolver.gd)承载—— +# 含 _resolve_progress/_ceil_key 与 R1 告警去重注册表;门面同名方法委托,越域 Fatal 语义一致。 func resolve_board_gen(L: int, D: int) -> Dictionary: return _resolver.resolve_board_gen(L, D) func resolve_enemy_rowset(L: int, D: int) -> Array[Dictionary]: - return _resolver.resolve_enemy_rowset(L, D) # 行集数组形态(2026-10-07 行集多行批——原单行 Dictionary 退役) + return _resolver.resolve_enemy_rowset(L, D) # 行集数组形态(非单行 Dictionary) # 难度曲线与Boss DifficultyTable 消费面(敌人系统.spawn 调用):(L,D) 精确匹配修饰乘数,越域值 clamp(GDD Edge Case——组合事故非配置事故) @@ -199,9 +199,9 @@ func resolve_difficulty_modifiers(L: int, D: int) -> Dictionary: return _resolver.resolve_difficulty_modifiers(L, D) -# ---- 地形变异 variant_pool_gate:候选池门控(∅ board_types = 通配;2026-09-19 用户裁定字段名对齐 -# board_type 词表——biome_tags 系旧观念残留退役)---- -# 门控第三维 = 节点身份(全局作用域变异首发批 2026-10-04):scope=global 行仅 boss/elite 节点入池, +# ---- 地形变异 variant_pool_gate:候选池门控(∅ board_types = 通配;字段名对齐 +# board_type 词表,无 biome_tags)---- +# 门控第三维 = 节点身份(全局作用域变异):scope=global 行仅 boss/elite 节点入池, # 其余节点(battle 等)静默跳过——门控兜底 P0 口径(零报错零警告);elite 系前向词位(首发零表行)。 # node_type 缺省 "" = 旧双参调用口径(global 行跳过)——既有测试/冒烟调用零扰动。 @@ -238,8 +238,8 @@ func status_effect_row(effect_id: String) -> Dictionary: return status_effects.row_by_id(effect_id) -# ---- 关卡行集访问器(2026-10-02 修复批 T5 表访问收口——level_runner/meta_progression/adventure_runner -# 直扫 db.level.rows 退役;消费面一律走本访问器,行集解析单点归 LevelTable)---- +# ---- 关卡行集访问器(表访问收口——level_runner/meta_progression/adventure_runner +# 不直扫 db.level.rows;消费面一律走本访问器,行集解析单点归 LevelTable)---- # 关卡行单点读取(键 = level_index,缺行返回空字典——消费方按既有空行防御路径处理) func level_row(level_index: int) -> Dictionary: @@ -251,27 +251,27 @@ func level_count() -> int: return level.rows.size() if level != null else 0 -# ---- GP+商店房实施批(2026-09-21):ShopTable 消费面(行集解析单点——runner/战斗编排禁自扫表)---- -# ── 秘宝访问器(迭代 7 T1——消费面一律走访问器,禁直读行集)── +# ---- ShopTable 消费面(行集解析单点——runner/战斗编排禁自扫表)---- +# ── 秘宝访问器(消费面一律走访问器,禁直读行集)── # 活行集(非 retired 非 deferred)——投放校验/奖励节点池/呈现可用性的唯一取数口径 func treasure_item_row(item_id: String) -> Dictionary: return treasure_items.row_by_id(item_id) if treasure_items != null else {} # 过渡渠道活行(form 空 = 切片期过渡形态)——掉落投放/停点池/工坊解锁取数口径;同调行(form 非空) -# 永不入过渡渠道(迭代 11 第①批 T1;T7 退役面切换后本口径随渠道消亡) +# 永不入过渡渠道 func treasure_transitional_rows() -> Array: return treasure_items.transitional_rows() if treasure_items != null else [] -# 同调行集(form 非空——装配覆盖层/效果接线的取数口径,迭代 11 第①批 T1/T4) +# 同调行集(form 非空——装配覆盖层/效果接线的取数口径) func treasure_attunement_rows() -> Array: return treasure_items.attunement_rows() if treasure_items != null else [] # 活行词表(掉落投放 effect_id 白名单——过渡渠道口径) -# ── 同调轴访问器已删除(迭代 21 T5——attunement_growth 谓词表随槽位收编退役:槽位数量=树同调位 -# 节点点亮数,判定源=Attunement.slots;boss_kill_count/clear_count 计数域保留——非槽位硬消费在册)── +# ── 同调槽位数=树同调位节点点亮数,判定源=Attunement.slots(无 attunement_growth 谓词表访问器); +# boss_kill_count/clear_count 计数域保留——非槽位硬消费在册 ── # 行族四轴(数据契约,行集归 shop.tres):gp_drops {tier, mean, roll_min, roll_max} · @@ -311,7 +311,7 @@ func shop_product_row(product_id: String) -> Dictionary: return {} -# ── 共享池货架访问器(M-4 迭代 11 第②批 T1——消费面一律走访问器,禁直读行集)── +# ── 共享池货架访问器(M-4——消费面一律走访问器,禁直读行集)── # 货架行族({kind_id, display_name, base_price}——行序即抽签/呈现稳定序) func shop_pool_rows() -> Array: @@ -342,8 +342,8 @@ func _shop_rows(family: String) -> Array: return arr if arr is Array else [] -# ---- 元进度实现批(2026-09-21):MetaTable 消费面(行集解析单点——MetaProgression/呈现层禁自扫表)---- -# 行族四轴(数据契约,行集归 meta.tres,数值全 provisional 归元进度设计批配读数): +# ---- MetaTable 消费面(行集解析单点——MetaProgression/呈现层禁自扫表)---- +# 行族四轴(数据契约,行集归 meta.tres,数值全 provisional): # forge_products {attr, display_name, flat_value, base_price, price_ratio_pct} · # boss_keystone {level_index, first_kill, repeat_kill} · # workshop_items {item_id, display_name, clear_threshold} · @@ -356,8 +356,8 @@ func meta_boss_keystone_row(level_index: int) -> Dictionary: return {} -# meta_workshop_items 访问器已删除(迭代 22 T2——工坊行族退役,解锁混合制挂 treasure_items 行内; -# 秘宝解锁投影面=MetaProgression.treasure_shop_status) +# 秘宝解锁混合制挂 treasure_items 行内(无 meta_workshop_items 访问器); +# 秘宝解锁投影面=MetaProgression.treasure_shop_status func meta_conversion_row(attr: String) -> Dictionary: @@ -367,7 +367,7 @@ func meta_conversion_row(attr: String) -> Dictionary: return {} -# Y 刷新升级行单点读取(迭代 11 第①批 T4——键 = 等级,缺行返回空字典=未购/已满级合法态) +# Y 刷新升级行单点读取(键 = 等级,缺行返回空字典=未购/已满级合法态) func meta_attune_refresh_row(level: int) -> Dictionary: for row in _meta_rows("attune_refresh_upgrade"): if int(row.get("level", -1)) == level: @@ -383,7 +383,7 @@ func _meta_rows(family: String) -> Array: return arr if arr is Array else [] -# ---- 锻造工坊(迭代 23 T1——ForgeTable 消费面:两根类型轴默认值+六路线行族;禁自扫行集)---- +# ---- 锻造工坊(ForgeTable 消费面:两根类型轴默认值+六路线行族;禁自扫行集)---- # 设计权威 design/gdd/systems/跨局循环/锻造工坊.md v0.6:默认值归本表常驻持有(hero.tres 两轴已删—— # 契约 2);路线行族=攻防数值成长唯一数据面(契约 1)。数值全 provisional 归 M4。 diff --git a/game/core/config_db_cross_validator.gd b/game/core/config_db_cross_validator.gd index 891e3dfa..670da120 100644 --- a/game/core/config_db_cross_validator.gd +++ b/game/core/config_db_cross_validator.gd @@ -15,7 +15,7 @@ func cross_validate(loaded: Dictionary, push_diag: Callable) -> void: for row in st.rows: effect_ids[row.get("effect_id", "")] = true # ① RewardTable effect_id 悬空(percent 行引用 StatusEffectTable——悬空加载致命)。 - # GP+商店房实施批(2026-09-21)例外:gp_gain/gp_loss = GP 战斗内缓冲(escrow)通道的路由键 + # 例外:gp_gain/gp_loss = GP 战斗内缓冲(escrow)通道的路由键 # (战斗结算 _apply_gp_row 兑付——不入增益状态容器),词表封闭按字面豁免悬空引用校验。 for row in rt.rows: if String(row.get("cell_type", "")) == RewardTable.TREASURE_ITEM_TYPE: @@ -23,7 +23,7 @@ func cross_validate(loaded: Dictionary, push_diag: Callable) -> void: var eff: String = row.get("effect_id", "") if eff != "" and eff != "gp_gain" and eff != "gp_loss" and not effect_ids.has(eff): push_diag.call("error", "dangling_effect", "RewardTable %s 引用不存在的 effect_id: %s" % [row.get("reward_id"), eff]) - # ①b RewardTable aux 投放行双表校验(迭代 7 T1——reward_dangling_treasure):aux 行 effect_id = item_id, + # ①b RewardTable aux 投放行双表校验(reward_dangling_treasure):aux 行 effect_id = item_id, # 须命中 TreasureItemTable 活行(非 retired 非 deferred——罗盘退役/失义件不投放)。retired 行被引用=退役 # 后仍投放(连带错误),同拦。 var treasure_live := {} @@ -39,17 +39,14 @@ func cross_validate(loaded: Dictionary, push_diag: Callable) -> void: continue if not treasure_live.has(treasure_eff): push_diag.call("error", "reward_dangling_treasure", "RewardTable %s aux 行引用无效道具 %s(retired/deferred/不存在): %s" % [row.get("reward_id"), treasure_eff, "双表校验"]) - # ①c F2 投放维度覆盖(秘宝 GDD——五维度各 ≥1 掉落权重为正的活行):豁免面 {plan, info, counter} - # = 罗盘退役(plan,2026-09-29 拍板①乙)+显影件 Alpha 重定(info/counter 悬置)——豁免随 Alpha 重定批消减 - # ①c F2 投放维度覆盖校验随战斗掉落渠道退役(2026-10-01 用户拍板甲——挖格不掉道具,秘宝 - # 唯一来路=三选一共享池〔节点/通关〕):旧校验=「掉落池五维度各 ≥1 正权重活行」,载体已随 - # reward.tres aux 投放四行删除而消失;共享池为「抽到道具位再动态掷定具体道具」,维度覆盖不可 - # 静态校验。静态覆盖保证的重立(如按维度钉共享池抽签面)归同调实施批/渠道设计批。 + # ①c F2 投放维度覆盖校验不启用:挖格不掉道具,秘宝 + # 唯一来路=三选一共享池〔节点/通关〕;共享池为「抽到道具位再动态掷定具体道具」,维度覆盖不可 + # 静态校验。 # ② SettlementTable.effect_pool_map 悬空 for eff in st_tab.effect_pool_map.keys(): if not effect_ids.has(eff): push_diag.call("error", "poolmap_dangling", "SettlementTable.effect_pool_map 悬空 effect_id: %s" % eff) - # ③ source_label_map 键集封闭性(键 = 增益状态 source_class ∪ {enemy_action, hero_attack, seal_miss}——2026-09-15 格面资源批删 item 键) + # ③ source_label_map 键集封闭性(键 = 增益状态 source_class ∪ {enemy_action, hero_attack, seal_miss}) var required_sources := ["safe_cell", "seal_hit", "mine_hit", "clear_reward", "hero_attack", "enemy_action", "seal_miss"] for s in required_sources: if not st_tab.source_label_map.has(s): @@ -91,7 +88,7 @@ func cross_validate(loaded: Dictionary, push_diag: Callable) -> void: if skt != null and en != null: for e in validate_skill_pool_links(skt, en, loaded.get("status_effects")): push_diag.call("error", e.category, e.message) - # ⑥ 商店货架 × 冒险共享池跨表校验(M-4 迭代 11 第②批 T1——次数上限域): + # ⑥ 商店货架 × 冒险共享池跨表校验(M-4——次数上限域): # pool_shelf kind 须命中 adventure.CURIO_KINDS 且为有限库存种(cap ∈ [1,99]——gp 无上限种/牌库外种 # 入货架 = 库存账本无锚,加载致命;gp 袋负交易切边/规则改写型特性三轴切边由 ShopTable 词表封闭另拦) var adv = loaded.get("adventure") @@ -100,12 +97,12 @@ func cross_validate(loaded: Dictionary, push_diag: Callable) -> void: for row in shp.pool_shelf: var kind: String = String(row.get("kind_id", "")) if kind == "feat_ticket": - continue # T5 门票豁免——货架专属机制种(非 deck 池种,零摘牌拿到即开),不入 CURIO_KINDS + continue # 门票豁免——货架专属机制种(非 deck 池种,零摘牌拿到即开),不入 CURIO_KINDS if not adv.CURIO_KINDS.has(kind): push_diag.call("error", "shelf_dangling_kind", "ShopTable.pool_shelf kind %s 不在 AdventureTable.CURIO_KINDS(共享池牌库外种)" % kind) continue - # TP0 令牌池——货架件须为有限令牌种(配额 >0;种类次数上限退役后库存=剩余令牌数。 - # 迭代 20 T2 四级换代——逐档累计遍历 TIERS 词表,不再点名档位常量) + # TP0 令牌池——货架件须为有限令牌种(配额 >0;种类次数上限已废除,库存=剩余令牌数。 + # 四级词表——逐档累计遍历 TIERS 词表,不点名档位常量) var quota := 0 for tier_v in adv.TIERS: quota += int(adv.curio_quota(kind, String(tier_v))) @@ -123,7 +120,7 @@ func validate_skill_pool_links(skill_table: SkillTable, enemy_table: EnemyTable, var skill_types := {} for row in skill_table.rows: skill_types[String(row.get("skill_id", ""))] = String(row.get("type", "")) - # 施放类 side 守卫(新效应词汇批 2026-09-19):buff → 敌方侧状态 / debuff → 主角侧状态,防反向挂接 + # 施放类 side 守卫:buff → 敌方侧状态 / debuff → 主角侧状态,防反向挂接 for row in skill_table.rows: var st: String = String(row.get("type", "")) if st != "buff" and st != "debuff": diff --git a/game/core/config_db_resolver.gd b/game/core/config_db_resolver.gd index 14ec829b..78a83b29 100644 --- a/game/core/config_db_resolver.gd +++ b/game/core/config_db_resolver.gd @@ -4,11 +4,11 @@ class_name ConfigDbResolver extends RefCounted -var _diag: Callable # 诊断/致命通道(迭代 27 T6——门面类型反持解耦,validator 先例:签名 (level, category, message)) +var _diag: Callable # 诊断/致命通道(门面类型反持解耦,validator 先例:签名 (level, category, message)) var _board_gen_rows_get: Callable # () -> Array——board_gen 行集活读(数据面经 Callable 注入,ConfigDb 类型环断根) var _enemy_rows_get: Callable # () -> Array——enemy 行集活读 var _difficulty_get: Callable # () -> DifficultyTable(可空——表缺省合法态) -var _warn_dedup: Dictionary[String, bool] = {} # R1 四元组去重注册表(自 ConfigDb 迁入) +var _warn_dedup: Dictionary[String, bool] = {} # R1 四元组去重注册表 func _init(diag_cb: Callable, board_gen_rows_cb: Callable, @@ -19,19 +19,19 @@ func _init(diag_cb: Callable, board_gen_rows_cb: Callable, _difficulty_get = difficulty_cb -# 去重注册表清空(门面 load_tables / reset_diagnostics 调用——与拆分前清空时点逐位一致) +# 去重注册表清空(门面 load_tables / reset_diagnostics 调用) func reset_warn_dedup() -> void: _warn_dedup.clear() -# ---- R1 难度行解析(2026-09-18 用户拍板修订:ceil 向上取整保证偏难;域越界与内容缺口 Fatal 退出)---- +# ---- R1 难度行解析(ceil 向上取整保证偏难;域越界与内容缺口 Fatal 退出)---- func resolve_board_gen(L: int, D: int) -> Dictionary: return _resolve_progress(_board_gen_rows_get.call(), L, D, "board_gen") func resolve_enemy_rowset(L: int, D: int) -> Array[Dictionary]: - # 行集数组形态(2026-10-07 敌人表行集多行批——原单行 Dictionary 退役):ceil 命中 (l*,d*) 后 + # 行集数组形态:ceil 命中 (l*,d*) 后 # 返回该坐标全部行、按表文件行序(行序即契约——同坐标多行文件内相邻由 EnemyTable.validate 兜底)。 # 空集表达 = 空数组(生产表下 ceil 命中坐标恒有行,空集仅表空时可达——validate 已拦)。 return _resolve_progress(_enemy_rows_get.call(), L, D, "enemy", true) @@ -67,7 +67,7 @@ func _resolve_progress(rows: Array, L: int, D: int, table_id: String, return_all var l_star := _ceil_key(level_keys, L) var l_clamped := l_star < 0 if l_clamped: - l_star = int(level_keys[-1]) # 超出最大行 → 取最大行封顶(2026-09-18 追加拍板:可取范围内向上取整,超出用最大值) + l_star = int(level_keys[-1]) # 超出最大行 → 取最大行封顶(可取范围内向上取整,超出用最大值) var depth_keys: Array[int] = [] for row in rows: if int(row.get("level_index", 0)) == l_star: diff --git a/game/core/damage_controller.gd b/game/core/damage_controller.gd index b7d7f1c2..59c49907 100644 --- a/game/core/damage_controller.gd +++ b/game/core/damage_controller.gd @@ -7,14 +7,14 @@ class_name DamageController extends RefCounted const POLICY_IMMEDIATE := "immediate" # A:开单即结(现状行为——回切位) -const POLICY_SEGMENT := "segment" # B:攒批到段界 flush 统一结(2026-09-24 用户拍板目标形态) +const POLICY_SEGMENT := "segment" # B:攒批到段界 flush 统一结(目标形态) # 兑付配方(kind → 步序): # hero_attack 战斗段·主角先手:掷点折扣暴击 → 克制点数(attack_type vs 敌护甲类型)→ # hero_offense×enemy_defense 池乘区 → 下限 → 交付;行载荷带 roll/ac/tier/killed。 # enemy_skill 战斗段·敌方伤害技(含普攻):基线 = round(atk×倍率)(开单侧算好入 base_value)→ -# 掷点折扣暴击 → 克制点数(attack_type vs 主角护甲类型——迭代 24 N3 轴开列, -# 前态恒中性 delta 0)→ hero_defense×enemy_output +# 掷点折扣暴击 → 克制点数(attack_type vs 主角护甲类型—— +# 无类型恒中性 delta 0)→ hero_defense×enemy_output # 池乘区 → 下限 → +rider(必中附加)→ 交付 → commit_action;来源敌已死 = 作废。 # board_typed 棋盘·单目标克制直伤(穿刺弹/魔法矢正向):必中全额,克制点数进加法核,下限保底。 # board_blast 棋盘·群伤(爆裂粉尘/清障炸药):无类型恒定表值,全体存活敌逐个交付。 @@ -30,19 +30,19 @@ const TARGET_HERO := "hero" const TARGET_ALL_ALIVE := "all_alive_enemies" var db: ConfigDb -var rng: RngServiceCore # 注入成员类型注(2026-10-02 修复批——单测经真实 RngService 构造,标注安全) +var rng: RngServiceCore # 注入成员类型注(单测经真实 RngService 构造,标注安全) var units: UnitContainer # UnitContainer——目标解析/伤害交付/存活查询(句柄即 Dictionary 引用) var effects: StatusContainer # StatusContainer——池值/AC 型效果读取(增益状态 只读消费面) var emit_row_cb: Callable # 行协议注入口:func(type, source_class, origin_cell, ri, display, value, extra, highlight) -var policy := POLICY_SEGMENT # 结账时机开关(2026-09-24 用户拍板第二步拨 B=攒批段界统一结;回切 A 改回 POLICY_IMMEDIATE 即还原迁移前行为) +var policy := POLICY_SEGMENT # 结账时机开关(B=攒批段界统一结;回切 A 改 POLICY_IMMEDIATE 即开单即结) var _queue: Array[Dictionary] = [] # 未结单据(B 模式攒批;A 模式恒空) var _outcomes := {} # ticket_id → "redeemed"/"zero"/"voided"(结账后可查——清图高光份数消费) var _seq := 0 # 流水号 var _halted := false # 主角倒下终止封印(死亡事件置位——flush 余单作废) var _hero_ac_override := -1 # 主角护甲等级合流入参(begin_battle 显式设定——-1 = 表值兜底,口径同战斗编排器) -# 效果引擎(内容数据驱动扩展批 T1/T3——attack_commit/clamp_check/armor_roll/kill/damage_taken -# 发射+施加面:dispatch 返回命中,本类按组合规则施加——T3 起旧 feat_seals 封印消费点全部拆除) +# 效果引擎(attack_commit/clamp_check/armor_roll/kill/damage_taken +# 发射+施加面:dispatch 返回命中,本类按组合规则施加) var _fx: EffectEngine = null # 战斗段运行态事实(编排器每轮刷新——fact 取数面:attack_commit 载荷 dig_streak / # charge_layers facts〔猎巢人 per/整备 attack_bonus per/厚积薄发 when/铁壁 shield per〕; @@ -80,7 +80,7 @@ func _fx_hits(event: String, payload: Dictionary) -> Array: # 事件发射薄面(免施加观测位——enemy_hp_threshold 等现无订阅者的事件保留零扰动面) # 补充事实面(fact 取值第二优先源——payload 未携带的运行态读数:charge_layers 编排器每轮注入。 -# 迭代 20 T1——hp_ratio 补入〔背水 when 面,敌技 damage_taken 载荷不带血比例时回落〕; +# hp_ratio 补入〔背水 when 面,敌技 damage_taken 载荷不带血比例时回落〕; # fx_reveal_request=揭示效果回调〔斩首学者 kill 订阅面——编排器注入,入队授予段末兑付〕) func _fx_fact(fact: String): match fact: @@ -135,7 +135,7 @@ func submit(t: Dictionary) -> int: # 单据构造(缺省填齐——调用点只写差异栏;context = kind 专用:enemy_skill 带 skill_id/baseline, # board_flat_hero 的键并入行载荷,board_blast/board_typed 带 batch_key 供未生效行归因)。 -# attack_commit 发射点(内容数据驱动扩展批 T3——我方伤害单据开立入口,需求卡片 §3.1 定稿位; +# attack_commit 发射点(我方伤害单据开立入口; # 命中挂单据 context 随行——施加面在 _resolve_hero_attack 管线算术前逐族施加,开单时点=主角攻击 # 单恒为段内首单(结账现场与开单现场一致)。载荷 atk/target/matchup + 挖掘 streak 事实〔连珠矢/ # 执拗订阅面〕+巢穴控制数〔猎巢人〕) @@ -170,7 +170,7 @@ func open_ticket(kind: String, source_class: String, display: String, channel: S return t -# 同步开单(清图批专用——完美第二份与高光份数的流程依赖需要同步读数,开单权归流程 用户裁决③): +# 同步开单(清图批专用——完美第二份与高光份数的流程依赖需要同步读数,开单权归流程): # 先按开单序结清段内排队的单据(保序),再无视结账时机政策当场兑现本单。 func flush_submit(t: Dictionary) -> int: flush() @@ -203,7 +203,7 @@ func outcome(ticket_id: int) -> String: return String(_outcomes.get(ticket_id, "pending")) -# ---- 死亡事件(用户裁决③——单位自行宣布,本类消费)---- +# ---- 死亡事件(单位自行宣布,本类消费)---- func _on_unit_died(u: Dictionary) -> void: if bool(u.get("is_hero", false)): @@ -243,12 +243,12 @@ func _resolve(t: Dictionary) -> void: # 主角先手攻击:掷点 → 折扣/暴击 → 克制点数 → hero_offense×enemy_defense 池乘区 → 下限 → 交付 -# (内容数据驱动扩展批 T3——attack_commit/clamp_check/armor_roll 订阅施加面:命中=开单入口随单 -# context 携带,按迁移前算序逐族施加——命中序=数据表声明序,确定性)。 -# 迭代 27 T2 姊妹病灶拆段(P1-1):原 148 行单体拆四步——命中面(_hero_attack_ctx,目标/护甲/ +# (attack_commit/clamp_check/armor_roll 订阅施加面:命中=开单入口随单 +# context 携带,按固定算序逐族施加——命中序=数据表声明序,确定性)。 +# 四步分段:命中面(_hero_attack_ctx,目标/护甲/ # 掷点/按序改写族四拍/克制点数) → 基值装配(_hero_attack_base_value,加法族/计数器施加/倍乘) → # 掷点兑现(_hero_attack_redeem,rolled/池乘/下限/rider/落地/击杀发射) → 交付(_hero_attack_deliver, -# 状态施加/标签/明细行)。步骤间经 ctx/redemption 字典穿线——算序/取值逐字保留(🔴 逐位一致契约)。 +# 状态施加/标签/明细行)。步骤间经 ctx/redemption 字典穿线——算序/取值固定(🔴 逐位一致契约)。 func _resolve_hero_attack(t: Dictionary) -> void: var ctx := _hero_attack_ctx(t) if ctx.is_empty(): @@ -272,10 +272,10 @@ func _hero_attack_ctx(t: Dictionary) -> Dictionary: var ac_payload: Dictionary[Variant, Variant] = (t.context.get("fx_attack_payload", {}) as Dictionary) var roll_read: Dictionary[Variant, Variant] = _armor_roll() var threshold: int = defender_ac(target) + int(db.settlement.attack_bonus) - # armor_roll 发射点(内容数据驱动扩展批 T1——敌护甲掷骰判定;免掷恒折扣订阅面) + # armor_roll 发射点(敌护甲掷骰判定;免掷恒折扣订阅面) var ar_hits := _fx_hits("armor_roll", {"target_ac": threshold, "roll": int(roll_read.roll)}) # 按序改写族第一拍:矿工重锤命中交换(正负双修原生形态:命中判定减成 trade_hit 点〔更易命中〕 - # 换攻击增伤 trade_atk%——高 AC 负期望/低 AC 正期望;改写位先于掷点折扣读数,与迁移前一致) + # 换攻击增伤 trade_atk%——高 AC 负期望/低 AC 正期望;改写位先于掷点折扣读数) var trade_hit := 0 for h in ac_hits: if String(h.get("kind", "")) == "modify_ticket" and int(h.get("trade_hit", 0)) > 0: @@ -314,9 +314,9 @@ func _hero_attack_ctx(t: Dictionary) -> Dictionary: for h in clamp_hits: if String(h.get("kind", "")) == "modify_ticket" and h.has("delta"): cdelta += int(h.delta) - # 淬毒刃纹(迭代 11 同调批 T5 → 内容数据驱动扩展批 T4:特判拆除——行 triggers clamp_check - # modify(mode:clamp_bonus) 订阅命中已并入上方 delta 合计;mode 路由=主角攻击面专享, - # 棋盘克制直伤窗只消费无模式 delta——棋盘不吃毒面与迁移前一致) + # 淬毒刃纹(行 triggers clamp_check + # modify(mode:clamp_bonus) 订阅命中并入上方 delta 合计;mode 路由=主角攻击面专享, + # 棋盘克制直伤窗只消费无模式 delta——棋盘不吃毒面) return {"target": target, "armor": armor, "atk_type": atk_type, "ac_hits": ac_hits, "ac_payload": ac_payload, "roll_read": roll_read, "threshold": threshold, "crit": crit, "discount": discount, "spike_ready": spike_ready, "cdelta": cdelta} @@ -328,7 +328,7 @@ func _hero_attack_base_value(t: Dictionary, ctx: Dictionary) -> float: var ac_hits: Array[Variant] = ctx["ac_hits"] var ac_payload: Dictionary[Variant, Variant] = ctx["ac_payload"] var base_value := float(t.base_value) - # 单位标记加伤(迭代 20 T1——处刑台 target_attack_bonus 挂单位字典 fx_atk_bonus 键; + # 单位标记加伤(处刑台 target_attack_bonus 挂单位字典 fx_atk_bonus 键; # 阈值沿发射点已写入,本处通用消费——对该敌伤害加算) base_value += float(int((ctx["target"] as Dictionary).get("fx_atk_bonus", 0))) # 按序改写族第五拍:矿工重锤增伤面(交换的正向侧) @@ -336,7 +336,7 @@ func _hero_attack_base_value(t: Dictionary, ctx: Dictionary) -> float: if String(h.get("kind", "")) == "modify_ticket" and int(h.get("trade_atk", 0)) > 0: base_value *= 1.0 + float(int(h.trade_atk)) / 100.0 # 加法族:整备军备「每层下轮首段 +1」(层数×value 加算)——attack_bonus per charge_layers。 - # 迭代 20 T1——value_counter 扩展〔疼痛记忆/弃图兑换/陷阱本能——rider 值=计数器账面, + # value_counter 扩展〔疼痛记忆/弃图兑换/陷阱本能——rider 值=计数器账面, # 值读于施加时点=命中序先行 rider 后清零行〕 for h in ac_hits: if String(h.get("kind", "")) == "attack_bonus": @@ -344,7 +344,7 @@ func _hero_attack_base_value(t: Dictionary, ctx: Dictionary) -> float: if h.has("value_counter") and String(h.get("value_counter", "")) != "": contrib = _fx.counter(String(h.get("value_counter", ""))) base_value += float(contrib) - # 计数器施加(迭代 20 T1——attack_commit 命中行内 counter_add〔用后清零行〕,命中序=声明序) + # 计数器施加(attack_commit 命中行内 counter_add〔用后清零行〕,命中序=声明序) for h in ac_hits: if String(h.get("kind", "")) == "counter_add": var set_v = h.get("set", null) @@ -391,8 +391,8 @@ func _hero_attack_redeem(t: Dictionary, ctx: Dictionary, base_value: float) -> D landed += hero_rider payload["hero_rider"] = hero_rider units.apply_damage(target, landed) - payload["killed"] = not target.alive # 击杀标记在扣血后取(原语义不变) - # kill 发射+施加(内容数据驱动扩展批 T3——敌人死亡确认;贯穿射击溢出弹射订阅面:对下一存活敌 + payload["killed"] = not target.alive # 击杀标记在扣血后取 + # kill 发射+施加(敌人死亡确认;贯穿射击溢出弹射订阅面:对下一存活敌 # 以穿刺类型弹射本体 value%〔无次敌=弹射落空〕。B 模式入队段尾 flush 兑现;A 模式递归 resolve) if bool(payload.get("killed", false)): for h in _fx_hits("kill", {"target": String(target.display_name), "overflow": landed}): @@ -403,7 +403,7 @@ func _hero_attack_redeem(t: Dictionary, ctx: Dictionary, base_value: float) -> D continue var next_target = units.default_target() if next_target != null: - # 迭代 20 T9——source_class 中性名(旧件名 feat_pierce_shot 随贯穿射击退役;overflow 通道保留泛用面) + # source_class 用中性名(fx_overflow 泛用通道,不挂件名) var of_t := open_ticket(DamageController.KIND_BOARD_TYPED, "fx_overflow", "贯穿弹射", "board", maxi(int(db.settlement.damage_floor), int(landed * int(h.get("value", 50)) / 100)), DamageController.TARGET_FRONT_ALIVE, int(t.round_index), t.origin_cell, "pierce") @@ -421,7 +421,7 @@ func _hero_attack_deliver(t: Dictionary, ctx: Dictionary, redemption: Dictionary # 重复授予由状态容器自行守卫) for h in (ctx["ac_hits"] as Array): if String(h.get("kind", "")) == "apply_status": - # 迭代 20 T9——source_class 中性名(旧件名 feat_armor_crack 随碎甲震击退役;apply_status 通道保留泛用面) + # source_class 用中性名(fx_apply_status 泛用通道,不挂件名) effects.apply_effect(String(h.get("status_id", "")), {"source_class": "fx_apply_status"}, -1) payload["cracked"] = true var label := _attack_label(String(t.display), bool(ctx["crit"]), int(ctx["discount"])) @@ -431,8 +431,8 @@ func _hero_attack_deliver(t: Dictionary, ctx: Dictionary, redemption: Dictionary _outcomes[int(t.ticket_id)] = "redeemed" -# 敌方伤害技:掷点 → 折扣/暴击 → 克制点数(attack_type vs 主角护甲类型——迭代 24 N3 轴开列; -# 前态恒中性 delta 0,写法同 hero_attack 的 _counter_delta 消费位)→ hero_defense×enemy_output +# 敌方伤害技:掷点 → 折扣/暴击 → 克制点数(attack_type vs 主角护甲类型—— +# 无类型恒中性 delta 0,写法同 hero_attack 的 _counter_delta 消费位)→ hero_defense×enemy_output # 池乘区 → 下限 → +rider(后置必中附加)→ 交付 → commit_action(作废单不 commit——死亡即不动手) func _resolve_enemy_skill(t: Dictionary) -> void: var hero: Dictionary[Variant, Variant] = units.hero_unit() @@ -444,9 +444,9 @@ func _resolve_enemy_skill(t: Dictionary) -> void: var rolled: int = DamageMath.rolled_component(float(t.base_value), discount, crit, int(db.settlement.crit_multiplier), cdelta) var pooled: int = DamageMath.pool_damage(rolled, clamped_pool("hero_defense"), clamped_pool("enemy_output")) var total: int = maxi(int(db.settlement.damage_floor), pooled) + int(t.rider) # rider 后置于伤害下限——独立必中加项,不进乘区 - # damage_taken 发射+施加(内容数据驱动扩展批 T3——kind=enemy_skill;铁壁整备减伤订阅面: + # damage_taken 发射+施加(kind=enemy_skill;铁壁整备减伤订阅面: # shield 加法族合计 value×per(charge_layers),稳健拓荒树规则同面(rebuild 合成订阅); - # 减后过下限保底。迭代 20 T1——damage_reduce〔背水 hp_ratio when〕/counter_add〔保险丝/ + # 减后过下限保底。damage_reduce〔背水 hp_ratio when〕/counter_add〔保险丝/ # 石肤〕/ac_bonus〔石肤〕同面施加;hp_ratio fact 由 _fx_fact 补充事实面回落提供) var shield := 0 for h in _fx_hits("damage_taken", {"kind": "enemy_skill", "amount": total, @@ -488,7 +488,7 @@ func _resolve_board_typed(t: Dictionary) -> void: return var armor_b: String = String(target.get("armor_type", "light")) var atk_b: String = String(t.attack_type) - # clamp_check 发射+施加(内容数据驱动扩展批 T3——克制判定修正点棋盘面;与 hero_attack 同表同点: + # clamp_check 发射+施加(克制判定修正点棋盘面;与 hero_attack 同表同点: # modify delta 订阅改写合计进克制点数;discount_shift 档位面属主角攻击专享,本面不施加) var cdelta: int = _counter_delta(atk_b, armor_b) if atk_b != "": @@ -510,7 +510,7 @@ func _resolve_board_blast(t: Dictionary) -> void: _ineffective_row(t, "无存活敌人") _outcomes[int(t.ticket_id)] = "zero" return - var blast_dmg: int = maxi(int(db.settlement.damage_floor), int(t.base_value)) # 伤害下限全来源(2026-09-20) + var blast_dmg: int = maxi(int(db.settlement.damage_floor), int(t.base_value)) # 伤害下限全来源 for u in alive: units.apply_damage(u, blast_dmg) # 恒定表值(下限保底),逐个;受击即死——死亡即不动手 emit_row_cb.call("damage", String(t.source_class), t.origin_cell, int(t.round_index), "%s → 全体敌人 ×%d" % [String(t.display), alive.size()], blast_dmg, @@ -520,7 +520,7 @@ func _resolve_board_blast(t: Dictionary) -> void: # 棋盘主角直伤(反噬/治疗包负向/地形变异):无类型必中,下限保底;context 键并入行载荷 func _resolve_board_flat_hero(t: Dictionary) -> void: - var dealt: int = maxi(int(db.settlement.damage_floor), int(t.base_value)) # 伤害下限全来源(2026-09-20) + var dealt: int = maxi(int(db.settlement.damage_floor), int(t.base_value)) # 伤害下限全来源 units.apply_damage(units.hero_unit(), dealt) var extra: Dictionary[Variant, Variant] = {"target": "hero"} for k in t.context.keys(): @@ -567,7 +567,7 @@ func defender_ac(unit: Dictionary) -> int: # 克制修正点数读值(SettlementTable.armor_effectiveness:{攻击类型: {护甲: 点数}}——缺项回退 0 中性; -# attack_type "" = 无类型恒不查(群伤/反噬/地形——敌方技自迭代 24 N3 起随单轴查表)) +# attack_type "" = 无类型恒不查(群伤/反噬/地形——敌方技随单轴查表)) func _counter_delta(attack_type: String, armor: String) -> int: if attack_type == "": return 0 @@ -576,7 +576,7 @@ func _counter_delta(attack_type: String, armor: String) -> int: return int(row.get(armor, 0)) -# 折扣档改善(迭代 12 T4 猎弱本能——折扣表向全额方向移 value 档;查不到当前档 = 不动防御口径) +# 折扣档改善(猎弱本能——折扣表向全额方向移 value 档;查不到当前档 = 不动防御口径) func _discount_shift_up(discount: int, shift: int) -> int: var tbl: Array[Variant] = db.settlement.roll_tier_discounts var idx := tbl.find(discount) @@ -608,7 +608,7 @@ func _attack_label(base: String, crit: bool, discount: int) -> String: # ---- 内部 ---- -# 目标解析(裁决②——结账时刻照规则看现场;句柄即 Dictionary 引用) +# 目标解析(结账时刻照规则看现场;句柄即 Dictionary 引用) func _target_for(rule: String): match rule: TARGET_FRONT_ALIVE: diff --git a/game/core/damage_math.gd b/game/core/damage_math.gd index 532cd86d..af27ddaf 100644 --- a/game/core/damage_math.gd +++ b/game/core/damage_math.gd @@ -11,11 +11,11 @@ static func pool_damage(d_raw: int, p_hero: int, p_enemy: int) -> int: return maxi(0, v) -# 充能分量:充能点数(调用方已按奖励定义换算)+ 克制修正点数(加法核——2026-09-18 换装,原 percent 乘区退役); -# 空桶(点数 ≤ 0)不吃修正恒 0——零充能分量无伤害可修正,不产生负贡献(等价旧量纲 0×任何 percent = 0; -# 空桶不受 landed_floor 影响——没有伤害落地就没有下限可言) -# 类型化点数分量:点数 + 克制修正(加法核)——2026-09-19 充能退役后唯一消费方 = 奖励直伤道具(棋盘火力) -# landed_floor:落地伤害全局下限(读 settlement.damage_floor,调用方传入)——2026-09-20 用户拍板 +# 充能分量:充能点数(调用方已按奖励定义换算)+ 克制修正点数(加法核); +# 空桶(点数 ≤ 0)不吃修正恒 0——零充能分量无伤害可修正,不产生负贡献; +# 空桶不受 landed_floor 影响——没有伤害落地就没有下限可言。 +# 类型化点数分量:点数 + 克制修正(加法核)——唯一消费方 = 奖励直伤道具(棋盘火力) +# landed_floor:落地伤害全局下限(读 settlement.damage_floor,调用方传入)—— # 「任何伤害落地取值域 [1,+∞)」:克制修正后触底也保底 1,调参降档不可能打出 0/负伤害 static func counter_component(points: int, counter_delta: int, landed_floor: int = 0) -> int: if points <= 0: @@ -23,7 +23,7 @@ static func counter_component(points: int, counter_delta: int, landed_floor: int return maxi(landed_floor, points + counter_delta) -# ---- 护甲等级掷点批(2026-09-16 用户拍板——判定式与档位参数全在 settlement.tres,本类只做算术)---- +# ---- 护甲等级掷点(判定式与档位参数全在 settlement.tres,本类只做算术)---- # 掷点折扣查档(纯函数):掷点 ≥ 阈值 → 100 全额;低掷按缺口(阈值 − 掷点)查升序边界落档, # 返回档位值 percent(档数 = 边界数 + 1:缺口 ∈ [1, bounds[0]] → discounts[0],(bounds[i], bounds[i+1]] → diff --git a/game/core/effect_engine.gd b/game/core/effect_engine.gd index 01a2f5f8..59461b6a 100644 --- a/game/core/effect_engine.gd +++ b/game/core/effect_engine.gd @@ -5,11 +5,10 @@ class_name EffectEngine extends RefCounted -## 事件词汇(迭代 20 专长实装批 T1 扩签——16→18:+dig_stop 停手挂点〔弃图兑换〕 -## +battle_won 战斗胜利〔战地包扎〕;迭代 21 天赋树批 T3 扩签 18→19:+seal_missed 标错判定 -## 〔危险直觉·守挂点——_judge_seal 去重闸后发射,契约 12 触发主语=当回合标错动作; -## 命名避让 _emit_row 在册 source_class 名 seal_miss〕;迭代 22 秘宝实装批 T3 扩签 19→20: -## +board_installed 装板完成〔巢穴预告——每板恰一次,战斗板生成/重建发射点〕;原发射点不动) +## 事件词汇(封闭枚举——dig_stop 停手挂点〔弃图兑换〕、battle_won 战斗胜利〔战地包扎〕、 +## seal_missed 标错判定〔危险直觉·守挂点——_judge_seal 去重闸后发射,契约 12 触发主语= +## 当回合标错动作;命名避让 _emit_row 在册 source_class 名 seal_miss〕、board_installed +## 装板完成〔巢穴预告——每板恰一次,战斗板生成/重建发射点〕) const EVENTS := ["dig_reveal", "dig_paid", "seal_hit", "mine_hit", "attack_commit", "clamp_check", "armor_roll", "kill", "damage_taken", "enemy_hp_threshold", "round_start", "seal_settle", "round_end", "reward_roll", "treasure_used", "charge_full", "dig_stop", "battle_won", "seal_missed", @@ -27,7 +26,7 @@ const EFFECT_KINDS := ["add_ticket_rider", "modify_ticket", "damage_mult", "open "grant_ap", "grant_gp", "bias_wallet", "shield", "spike", "apply_status", "counter_add", "counter_spend", "reveal_tiles", "remove_mines", "refresh_pick", "bias_rewards", "preview", - # 迭代 20 专长实装批 T1 扩签六型(奇物.md 基础件表 27 件声明清单——落法映射 commit 留痕): + # 六型效果(奇物.md 基础件表 27 件声明清单): # heal=回复生命〔血蜜/战地包扎〕;ac_bonus=护甲加值累积器〔封印桩本轮/石肤本场 cap〕; # damage_reduce=受伤减免〔背水/安全帽〕;bonus_delta=冒险加算区增量〔血税 双向——battle 末汇入 # runner.bonus〕;blast_scaled=雷罚标定群伤〔陷阱爆发——值=事件伤害×mult〕; @@ -35,17 +34,15 @@ const EFFECT_KINDS := ["add_ticket_rider", "modify_ticket", "damage_mult", "open # target_attack_bonus=单位标记加伤〔处刑台——敌血量阈值挂单位字典,主角攻击面通用消费〕 "heal", "ac_bonus", "damage_reduce", "bonus_delta", "blast_scaled", "preview_area", "target_attack_bonus", - # 迭代 22 秘宝实装批 T3 扩签一型:mine_count_preview=危险格数量预告(巢穴预告——board_installed + # mine_count_preview=危险格数量预告(巢穴预告——board_installed # 订阅 do;只报数量不标位置、不碰危险格分布=棋盘事实不可变契约;参数面常时 kind 不入本词表—— # 它们无订阅行,schema 行内 effect_kinds 校验走 treasure_item_table 自有词表) "mine_count_preview", - # 迭代 31 卡② 凭证件裁削批 T4 扩签一型:forgive_seal_miss=完美保险(本场首次封印落空不计入完美 + # forgive_seal_miss=完美保险(本场首次封印落空不计入完美 # 封印判定——订阅 seal_missed 的豁免效果,消费点在授予段;feats.tres 首例 domain=battle 行) "forgive_seal_miss"] - # 注:rewrite_board 已除名(迭代 20 T9——净化工兵随老 27 件退役,V14 连带清理; - # 编排器消费分支 T1 先行摘除) -## fact 条件词汇(封闭枚举——迭代 20 T1 扩签 9→17:payload 同名键直读面〔fact 取值序 payload +## fact 条件词汇(封闭枚举——payload 同名键直读面〔fact 取值序 payload ## 优先——effect_engine._fact_value 既有机制〕。new_resource_type=首开资源类型〔地质学家〕; ## is_edge_cell=边缘格〔边陲矿工〕;is_blank_zero=空白连锁〔跳格采掘〕;dug_under_seal=被挖格 ## 当时有封印〔破封一击〕;ap_exhausted_last=上轮 AP 耗尽〔一滴不剩〕;hp_ratio=生命比例〔背水 @@ -54,13 +51,13 @@ const FACTS := ["matchup", "is_first_dig_of_battle", "terrain_kind", "target_arm "seals_count", "charge_layers", "nest_count", "round_index", "counter", "new_resource_type", "is_edge_cell", "is_blank_zero", "dug_under_seal", "ap_exhausted_last", "hp_ratio", "amount", "ap_left", "pct", - "battle_index"] # 迭代 21 T3 扩签——关卡域战斗序(1 基,enc 携带;开局姿态组「每关首轮窗」条件面) + "battle_index"] # 关卡域战斗序(1 基,enc 携带;开局姿态组「每关首轮窗」条件面) -## when 算子词汇(封闭——fact 查询面落法随批登记:mod_zero=计数器取模判满〔掘进蓄能〕、 +## when 算子词汇(封闭——fact 查询面落法:mod_zero=计数器取模判满〔掘进蓄能〕、 ## advantageous=克制矩阵正面判定〔淬毒刃纹〕、gte_ref/lt_ref=与另一计数器比较〔深挖钻头配额〕、 ## ends_with=后缀匹配〔对某甲族的泛条件〕、mod_eq=取模余数判定〔双管镐每第 2 次——value=模数 ## ref=余数;dispatch 预评估口径〔when 于命中前读计数器现值〕下「每第 N 次」系用 ref=N-1 表达〕。 -## 均系映射表现状条件装进 fact 的查询面落法,代拍板白名单覆盖,commit 留痕) +## 均系映射表现状条件装进 fact 的查询面落法,白名单覆盖) const OPS := ["eq", "neq", "gt", "gte", "lt", "lte", "ends_with", "has", "mod_zero", "advantageous", "gte_ref", "lt_ref", "mod_eq"] @@ -68,7 +65,7 @@ const OPS := ["eq", "neq", "gt", "gte", "lt", "lte", "ends_with", "has", "mod_ze const WHEN_KEYS := ["fact", "op", "value", "id", "ref", "value_from"] ## do 效果键白名单(trigger 行 do 字典键——零裸 flat 同族护栏:kind 外键全部参数引用面。 -## 迭代 20 T1 扩签四键:value_event=事件载荷取值键名〔爆破会计——counter_add 值=本轮挖格花费 +## value_event=事件载荷取值键名〔爆破会计——counter_add 值=本轮挖格花费 ## payload.ap_cost〕;value_counter=计数器取值键〔疼痛记忆/弃图兑换——attack rider 值=账面层值〕; ## domain=计数器寿命域〔battle=战斗域重建清零〔缺省〕/adventure=跨战持久随 battle 末导出〕; ## axis=bonus_delta 加算区轴向) @@ -78,15 +75,15 @@ const DO_KEYS := ["kind", "value", "value_from", "delta", "delta_from", "mult", "value_event", "value_counter", "domain", "axis"] ## 主动件分发通道(不经事件订阅——刷新/显影/移除是玩家主动动作;use_treasure 按 kind 分发) -## 迭代 22 秘宝实装批 T3 扩签:+safe_dig 安全格直开(天眼——3×3 内安全格按普通挖格规则全额兑付 -## 含连锁展开与格面资源,危险格仅真视显示不移除——棋盘事实不可变契约;免行动点即效果本身,C5 裁) +## safe_dig 安全格直开(天眼——3×3 内安全格按普通挖格规则全额兑付 +## 含连锁展开与格面资源,危险格仅真视显示不移除——棋盘事实不可变契约;免行动点即效果本身) const ACTIVE_KINDS := ["reveal_tiles", "preview", "grant_ap", "remove_mines", "refresh_pick", "safe_dig"] # ---- 订阅集与计数器账本 ---- var _triggers: Array[Variant] = [] # [{source, id, on, when, do}](装载序=声明序,重建时定死) var _counters: Dictionary[Variant, Variant] = {} # counter_id → int(battle 域账本;重建清零;重置点由订阅行声明) var _reset_on_round_start: Array[String] = [] # round_start 重置点计数器名单(装载时收集) -var _adventure_counter_ids: Array[String] = [] # domain=adventure 计数器名单(T6——重建时收集、不清零; +var _adventure_counter_ids: Array[String] = [] # domain=adventure 计数器名单(重建时收集、不清零; # battle 末 export → 冒险账本、begin_battle seed 回灌) var db: ConfigDb # 矩阵/表读取(advantageous 算子消费)——可空(纯计数器用法零依赖) @@ -116,9 +113,9 @@ func rebuild(feat_ids: Array, item_ids: Array, tree_rules: Array = []) -> void: continue for tr in (row.get("triggers", []) as Array): _push_trigger("attune", iid, tr, row) - # 树规则合成订阅(迭代 21 T3 换代——六键按 v0.8 三组双态):posture 两键=「每关首轮窗」语义 - # 〔battle_index==1 且 round_index==1;battle_index=关卡域战斗序由 enc 携带,原「每战首轮」 - # 实态随窗语义换代〕;sense 两组=每关限次〔adventure 域计数器 lt 上限闸 + 命中即 counter_add + # 树规则合成订阅(六键按 v0.8 三组双态):posture 两键=「每关首轮窗」语义 + # 〔battle_index==1 且 round_index==1;battle_index=关卡域战斗序由 enc 携带〕; + # sense 两组=每关限次〔adventure 域计数器 lt 上限闸 + 命中即 counter_add # 记账双行——同事件双行同预评估态见闸同记,序=装载序确定;生命周期四态:跨战持久=domain # adventure 导出/回灌、按关重置=AdventureRunner._start_current_level 清零、新冒险清零=账本 # 归零、断点保留=断点快照随键〕;economy 两组零订阅行——消费点=GP 掉落乘算与商品计价折价的 @@ -156,7 +153,7 @@ func rebuild(feat_ids: Array, item_ids: Array, tree_rules: Array = []) -> void: "when": [{"fact": "counter", "id": "tree_sense_guard_used", "op": "lt", "value": 2}], "do": {"kind": "counter_add", "counter_id": "tree_sense_guard_used", "value": 1, "domain": "adventure"}}, {}) - # 计数器账本重建(T6——battle 域清零照旧;adventure 域由 counters_seed 回灌〔rebuild 后调用〕) + # 计数器账本重建(battle 域清零;adventure 域由 counters_seed 回灌〔rebuild 后调用〕) _counters = {} @@ -186,7 +183,7 @@ func _push_trigger(source: String, id: String, tr: Dictionary, row: Dictionary) var cid := String(do_d.counter_id) if not _reset_on_round_start.has(cid): _reset_on_round_start.append(cid) - # 寿命域收集(T6——domain=adventure 计数器跨战持久:重建不清零、battle 末导出回冒险账本) + # 寿命域收集(domain=adventure 计数器跨战持久:重建不清零、battle 末导出回冒险账本) if do_d.has("counter_id") and String(do_d.get("domain", "")) == "adventure": var aid := String(do_d.counter_id) if not _adventure_counter_ids.has(aid): @@ -245,7 +242,7 @@ func counter_spend(counter_id: String, value: int) -> bool: return true -## adventure 域计数器导出(T6——battle 末调用,快照回冒险账本;仅 domain=adventure 名单内键) +## adventure 域计数器导出(battle 末调用,快照回冒险账本;仅 domain=adventure 名单内键) func counters_export() -> Dictionary: var out := {} for cid in _adventure_counter_ids: @@ -253,7 +250,7 @@ func counters_export() -> Dictionary: return out -## adventure 域计数器回灌(T6——rebuild 后由发射宿主调用:冒险账本值回填名单内键,缺省 0; +## adventure 域计数器回灌(rebuild 后由发射宿主调用:冒险账本值回填名单内键,缺省 0; ## 名单=本次 rebuild 装载行声明 domain=adventure 的 counter_id 集) func counters_seed(seed: Dictionary) -> void: for cid in _adventure_counter_ids: @@ -295,7 +292,7 @@ func _cond_ok(c: Dictionary, payload: Dictionary, facts: Callable) -> bool: return false return String(actual).ends_with(String(val)) "has": - # 在场判定(fact 查询面落法——代拍板白名单,commit 留痕):value 缺省=非空判定 + # 在场判定(fact 查询面落法——白名单覆盖):value 缺省=非空判定 # (terrain_kind fact:伤害型变异集非空=挖开伤害型地形格/邻格有伤害型地形/地形伤种类在场); # value 给定=数组包含判定(保留泛用面)。 if c.has("value"): @@ -304,7 +301,7 @@ func _cond_ok(c: Dictionary, payload: Dictionary, facts: Callable) -> bool: return false if actual is Array: return not (actual as Array).is_empty() - return actual != null and String(actual) != "" # null 安全(迭代 20 T2 修正——敌技伤害载荷无 terrain_kind 时事实面回落 null,判「不在场」而非抛错;候选流变化后 devour 件首次被持有而暴露的潜伏缺陷) + return actual != null and String(actual) != "" # null 安全(敌技伤害载荷无 terrain_kind 时事实面回落 null,判「不在场」而非抛错) "mod_zero": var m := int(val) return m > 0 and int(actual) % m == 0 diff --git a/game/core/level_runner.gd b/game/core/level_runner.gd index c71d68ae..e00129e8 100644 --- a/game/core/level_runner.gd +++ b/game/core/level_runner.gd @@ -7,7 +7,7 @@ class_name LevelRunner extends RefCounted -signal node_entered(node: Dictionary, info: Dictionary) # info 按 type:battle/boss={} · reward={}(内容待拍板) · rest={healed,hp,max_hp} · shop={gp} +signal node_entered(node: Dictionary, info: Dictionary) # info 按 type:battle/boss={} · reward={}(内容待定) · rest={healed,hp,max_hp} · shop={gp} signal choices_presented(candidates: Array) # 选路口(兑付确认后——候选节点引用数组,零自动推进) signal step_row(row: Dictionary) # 转发当前 战斗结算 结算行 signal round_started(round_index: int) @@ -34,34 +34,33 @@ var gp: int: # GP 冒险钱包(局内货币— set(v): _ledger["gp"] = v var base_override := {"atk": 0, "max_hp": 0, "armor_class": 0} # 永久强化 flat 注入(元进度实现批——冒险模式 = AdventureRunner 共享字典经 start_level_external 注入;单关测试模式 = 私有全零) var _shop_purchased := {} # product_id → 已购档数(现价重算输入;冒险开始清零) -# 协作对象私有(E1/E3 封装收口 2026-09-13):settlement 读取经 current_battle() 成文出口 +# 协作对象私有(E1/E3 封装收口):settlement 读取经 current_battle() 成文出口 var _settlement: BattleOrchestrator = null # 当前战斗编排器(关卡结束置 null) -var treasure_inventory: TreasureItems = null # 秘宝 关卡域库存(迭代 7 T3——TreasureItems;跨战斗延续, -var _treasure_unlocked := {} # aux 解锁门控集(迭代 7 T5——拍板③甲;空集=零投放) -var _attunement: Array[Variant] = [] # 同调装配集(迭代 11 第①批 T5——adventure params.attunement 下传,begin_battle enc 携带进战斗结算;空集=off 零扰动) +var treasure_inventory: TreasureItems = null # 秘宝 关卡域库存(TreasureItems;跨战斗延续, +var _treasure_unlocked := {} # aux 解锁门控集(空集=零投放) +var _attunement: Array[Variant] = [] # 同调装配集(adventure params.attunement 下传,begin_battle enc 携带进战斗结算;空集=off 零扰动) # 关卡末清空+快照计数入 level_finished 载荷) -# 两根类型轴(迭代 23 T4——adventure 参数面快照经 set_hero_axes 下传;空串=未注入→锻造配置默认值回退。 +# 两根类型轴(adventure 参数面快照经 set_hero_axes 下传;空串=未注入→锻造配置默认值回退。 # 消费面:effective_ac 甲型基础 AC 层 + begin_battle enc 携带进 unit_container.spawn 英雄快照) var _hero_attack_type := "" var _hero_armor_type := "" -# ---- 商店共享池模式态(迭代 11 第②批 T3——缺省 legacy=固定三件加定价 off 对照承载,零 RNG 零池消费;TP0 令牌池换代)---- +# ---- 商店共享池模式态(缺省 legacy=固定三件加定价 off 对照承载,零 RNG 零池消费;TP0 令牌池)---- var _shop_pool_mode := false # pool 模式封印(set_shop_pool 注入时置位——AdventureRunner 按 params.shop_mode 下传) var _pool_deck: Array[Variant] = [] # 共享池令牌库共享引用(AdventureRunner._curio_deck——库存=剩余令牌数单点) var _pool_consume := Callable() # 池消费 handler(AdventureRunner._consume_pool_purchase——_apply_curio_pick 同口写加算区+账本+摘牌) var _pool_ticket := Callable() # 门票展示判定 handler(T5——AdventureRunner._feat_ticket_consider;节点与商店共享计数) -var _pool_cap_check := Callable() # cap 检查回调(迭代 20 T2——AdventureRunner._curio_cap_ok;案②提前退役) +var _pool_cap_check := Callable() # cap 检查回调(AdventureRunner._curio_cap_ok;cap 满剔出货架候选视图) var _shop_shelf: Array[Variant] = [] # 当前货架(进店抽 3/买后全重抽——令牌字典 {"kind","tier"} 序,同 kind 去重每 kind 至多一卡) var _shop_visit_buys := 0 # 本次进店已购次数(A 链定价输入——离开清零) var _shop_paid_refreshes := 0 # 本次进店已付费刷新次数(MC-1——GP 刷新价曲线输入,离开清零) var hero_atk_pct := 0 # 测试面板覆盖值(切片专用) var hero_hp_pct := 0 -# ---- 关卡相位轴(2026-10-02 修复批——布尔封印收拢:_running/_awaiting_choice 两封印 → 显式 Phase enum; -# 对齐 行动经济 Phase 先例(action_economy.gd:内部 enum + 守卫换算,外部读面契约零变化)—— -# level_result:String 与 awaiting_choice() 被 AdventureRunner/呈现层消费的语义逐字不变)---- +# ---- 关卡相位轴(显式 Phase enum:内部 enum + 守卫换算,对齐 行动经济 Phase 先例; +# level_result:String 与 awaiting_choice() 是 AdventureRunner/呈现层消费的外部契约面)---- enum Phase { IDLE, RUNNING, AWAITING_CHOICE, ENDED } var _phase: int = Phase.IDLE -var level_result := "" # "" / "victory" / "defeat"(外部契约面——语义零变化) +var level_result := "" # "" / "victory" / "defeat"(外部契约面) var _candidates: Array[Dictionary] = [] # 当前选路候选(节点引用数组) var visited: Array[Dictionary] = [] # 已兑付/到达节点序列(呈现层图条数据源;含当前节点) var _graph_mode := false # 图形态缓存(行集任一节点带 next;单链 = false) @@ -72,7 +71,7 @@ func _init(db_ref: ConfigDb, rng_ref: RngServiceCore) -> void: rng = rng_ref -# 进行中谓词(原 _running 语义——RUNNING 或 AWAITING_CHOICE 两相位合计;内部守卫专用) +# 进行中谓词(RUNNING 或 AWAITING_CHOICE 两相位合计;内部守卫专用) func _is_running() -> bool: return _phase == Phase.RUNNING or _phase == Phase.AWAITING_CHOICE @@ -84,8 +83,8 @@ func set_hero_override(atk_pct: int, hp_pct: int) -> void: hero_hp_pct = hp_pct -# 叠加次序(元进度实现批钉死):表值 → 永久强化 flat(base_override)→ 加算区 flat(bonus)先加 -# → 调试浮窗百分比后乘(调试数值工具恒乘最后——代拍板 6,与 GP 批既有次序兼容) +# 叠加次序(钉死):表值 → 永久强化 flat(base_override)→ 加算区 flat(bonus)先加 +# → 调试浮窗百分比后乘(调试数值工具恒乘最后) func effective_atk() -> int: var base: int = int(db.hero.atk) + int(base_override.get("atk", 0)) + int(run_ledger.bonus.get("atk", 0)) return maxi(1, int(round(float(base) * (100.0 + float(hero_atk_pct)) / 100.0))) @@ -96,7 +95,7 @@ func effective_max_hp() -> int: return maxi(1, int(round(float(base) * (100.0 + float(hero_hp_pct)) / 100.0))) -# 护甲等级生效值(入战 AC 三层可加——迭代 23 T4:甲型基础 AC〔forge.tres 选中甲路线 base_ac〕+ +# 护甲等级生效值(入战 AC 三层可加:甲型基础 AC〔forge.tres 选中甲路线 base_ac〕+ # 甲路线等级加值〔base_override.armor_class——hero_override 锻造分量〕+ 加算区 armor_class 轴; # 无调试浮窗百分比通道,纯 flat) func effective_ac() -> int: @@ -113,7 +112,7 @@ func _armor_base_ac() -> int: return int(row.get("base_ac", 0)) -# 行动点加成生效值(迭代 10 奖励重构批——统一冒险加算区第四轴 ap;经战斗开始入参 hero_ap_bonus +# 行动点加成生效值(统一冒险加算区第四轴 ap;经战斗开始入参 hero_ap_bonus # 传入战斗域,兑现 = 每场战斗开始首轮行动点基线 +加成值〔行动经济 GDD 跨冒险行动点加成轴节〕) func effective_ap_bonus() -> int: return maxi(0, int(run_ledger.bonus.get("ap", 0))) @@ -128,10 +127,10 @@ func restore_hero_base() -> void: # ---- 关卡生命周期 ---- func start_level(level_index: int, seed_val: int, base_override_in: Dictionary = {}, template_pick: int = -1) -> bool: - # 单关测试模式(旧路径——既有语义一字不改):私有账本、内置恢复数学、自调 new_adventure(漂移① + # 单关测试模式:私有账本、内置恢复数学、自调 new_adventure(漂移① # 单关=冒险的历史简化在测试模式保留;正式种子域归 AdventureRunner.start_adventure) - # base_override_in = 永久强化 flat 注入尾参(换算率标定批 2026-09-23——缺省 {} 全零白板, - # 与既有调用方逐位一致零行为变更;契约同 AdventureRunner.start_adventure params.hero_override: + # base_override_in = 永久强化 flat 注入尾参(缺省 {} 全零白板, + # 契约同 AdventureRunner.start_adventure params.hero_override: # 三键 {atk, max_hp, armor_class}、缺键/-1 = 0、负值 clamp 0。游戏直入口仍恒白板—— # 注入面只服务数值验证工具,非玩家可达路径) _external = false @@ -147,7 +146,7 @@ func start_level(level_index: int, seed_val: int, base_override_in: Dictionary = _candidates = [] visited = [] _graph_mode = false - gp = 0 # 冒险钱包清零开局(GP+商店房实施批——局内货币生命周期起点) + gp = 0 # 冒险钱包清零开局(局内货币生命周期起点) run_ledger.bonus = {"atk": 0, "max_hp": 0, "armor_class": 0} # 加算区冒险开始全 0(单关入口零元进度——注入面见上) base_override = {"atk": 0, "max_hp": 0, "armor_class": 0} # 永久强化 flat:缺省全零白板(单关入口零元进度——注入面见上) _shop_purchased = {} # 已购档数清零(跨冒险不延续——递增定价按冒险内累计) @@ -172,15 +171,15 @@ func start_level(level_index: int, seed_val: int, base_override_in: Dictionary = # 冒险结构接口①:开始关卡(载荷 = 关卡序号 + 当前生命 + 生效上限——生命经共享账本交接; # 种子域归冒险结构:本路径不重播种;账本归冒险结构:本路径不重置 gp/bonus/_shop_purchased, # 也不重置 hero_hp——账本当前值即开局生命,AdventureRunner 已在 ledger 写好)。 -# base_override = 永久强化 flat 共享引用(元进度实现批——缺省 {} 全零白板,与 B1 空参数路径逐位一致)。 +# base_override = 永久强化 flat 共享引用(缺省 {} 全零白板,与 B1 空参数路径同值)。 # 流程与 start_level 同款(_find_level_row → 状态初始化 → _graph_mode 探测 → _enter_node(entry)), # 差异仅在账本/加算区/已购档/恢复执行体的注入与零重置。 -# 停点前移批 2026-09-23:defer_entry 尾参(缺省 false = 既有调用方零变更)——true 时不自动 +# defer_entry 尾参(缺省 false = 直接进节点)——true 时不自动 # _enter_node(entry),改置选路态(awaiting_choice + 单候选 = 入口节点),由 AdventureRunner 在 # level_started 之后调 present_entry_choice() 呈现、玩家 pick_next_node 显式进首战。拆两步的 # 信号顺序契约:呈现层须先经 level_started 重取 runner 实例,choices_presented 才不会被 # _on_choices_presented 的 runner 空防御静默丢弃。入口呈现零 RNG 消耗、pick 走同一个 -# _enter_node(entry)——与旧自动进入逐位等价(测量面零漂移红线)。 +# _enter_node(entry)——测量面零漂移红线。 func start_level_external(level_index: int, ledger: Dictionary, purchased_ref: Dictionary, rest_handler: Callable, base_override_ref: Dictionary = {}, defer_entry: bool = false, template_pick: int = -1, resume_state: Dictionary = {}) -> bool: @@ -205,7 +204,7 @@ func start_level_external(level_index: int, ledger: Dictionary, _graph_mode = true break _phase = Phase.RUNNING - # 断点续玩路径(迭代 8 卡①——defer_entry 之外的第三种停点入口):直接重建到停点所在节点, + # 断点续玩路径(defer_entry 之外的第三种停点入口):直接重建到停点所在节点, # 零 RNG 消耗(模板已随 template_pick 强制、节点状态纯重建不 _enter_node——当场战斗从头打)。 # resume_state = {"node_id": int(-1 = 入口停点), "visited_ids": Array[int]};空字典 = 既有路径逐位不变。 if not resume_state.is_empty(): @@ -223,7 +222,7 @@ func start_level_external(level_index: int, ledger: Dictionary, return _enter_node(entry) -# 入口停点呈现(停点前移批 2026-09-23——defer_entry=true 的第二步):发出入口候选供呈现层弹 +# 入口停点呈现(defer_entry=true 的第二步):发出入口候选供呈现层弹 # 选路层;非停点态(缺省自动进入路径)拒绝。零 RNG 消耗——呈现与行进取号解耦。 func present_entry_choice() -> bool: if _phase != Phase.AWAITING_CHOICE or _candidates.is_empty() or node_index != -1: @@ -233,7 +232,7 @@ func present_entry_choice() -> bool: return true -# ---- 断点续玩(迭代 8 卡①——停点粒度重建)---- +# ---- 断点续玩(停点粒度重建)---- # 停点重建(start_level_external resume_state 路径的落点):node_id = 停点所在节点编号(-1 = 入口 # 停点),visited_ids = 已到节点编号序(呈现层图条数据源重建)。纯状态重建零 RNG 消耗; @@ -284,7 +283,7 @@ func present_resumed_choice() -> bool: return true -# 断点道具库存回填(迭代 8 卡①——奖励节点已选道具随停点快照回局;幂等,先清后入受理序重排) +# 断点道具库存回填(奖励节点已选道具随停点快照回局;幂等,先清后入受理序重排) func restore_treasure_items(items: Array) -> void: if treasure_inventory == null: treasure_inventory = TreasureItems.new(db) @@ -293,14 +292,14 @@ func restore_treasure_items(items: Array) -> void: func _find_level_row(level_index: int) -> Dictionary: - return db.level_row(level_index) # 表访问收口(2026-10-02——行集直扫归 LevelTable/ConfigDB 访问器) + return db.level_row(level_index) # 表访问收口(行集直扫归 LevelTable/ConfigDB 访问器) -# ---- 模板池解析(关卡节点图生成 v0.4——M-3 迭代 5 T5)---- +# ---- 模板池解析(关卡节点图生成 v0.4——M-3)---- # row.templates 非空 = 池形态:template_pick >= 0 = 强制取该模板(首次脚本模式/冒烟固定图,零 RNG 消费); # -1 = 抽签(node_map 用途标签恰一 scope,均匀取模)。空池 = 旧单图形态原样返回(向后兼容零迁移)。 # 解析产物 = row 副本换 nodes(下游 nodes()/校验/呈现全透明);active_template_name 供 MC 分层出数; -# active_template_index 供断点快照备案(迭代 8 卡①——已抽模板续玩零重抽零 RNG 消耗)。 +# active_template_index 供断点快照备案(已抽模板续玩零重抽零 RNG 消耗)。 var active_template_name := "" var active_template_index := -1 # -1 = 非池形态(旧单图)/未解析 @@ -427,7 +426,7 @@ func _enter_node(node: Dictionary) -> bool: "battle", "boss": return _start_battle(node) "reward": - # 奖励点内容待拍板(格面资源批 2026-09-15:可选类道具删除,功能道具渠道 P1 未定—— + # 奖励点内容未定(可选类道具不在池、功能道具渠道未定—— # 节点保留占位、零兑付直通);推进 = 兑付确认后选路(零自动推进) node_entered.emit(node, {}) return true @@ -436,10 +435,10 @@ func _enter_node(node: Dictionary) -> bool: node_entered.emit(node, {"healed": healed, "hp": hero_hp, "max_hp": effective_max_hp()}) return true "shop": - # 商店房兑付(GP+商店房实施批 2026-09-21):到达即开店(覆盖层归呈现层),购买出账/ + # 商店房兑付:到达即开店(覆盖层归呈现层),购买出账/ # 离开归玩家意图——零自动推进;离开确认经 continue_after_node 回选路口 if _shop_pool_mode: - _shop_open_pool() # 迭代 11 第②批 T3——进店抽 3(恰一 shop_draw scope;买后全重抽同签) + _shop_open_pool() # 进店抽 3(恰一 shop_draw scope;买后全重抽同签) node_entered.emit(node, {"gp": gp, "shelf": true}) return true node_entered.emit(node, {"gp": gp}) # legacy 固定三件(off 对照承载——零 RNG 零池消费) @@ -452,9 +451,9 @@ func _start_battle(node: Dictionary) -> bool: _settlement = BattleOrchestrator.new(db, rng) if treasure_inventory == null: treasure_inventory = TreasureItems.new(db) # 惰性建——关卡域单实例(跨战斗延续) - _settlement.treasure_inventory = treasure_inventory # 迭代 7 T3——库存注入(授予路由+use_treasure 编排消费面) + _settlement.treasure_inventory = treasure_inventory # 库存注入(授予路由+use_treasure 编排消费面) if _settlement != null: - _settlement.set_treasure_unlocked(_treasure_unlocked) # 迭代 7 T5——解锁门控下传(装板摇号前) + _settlement.set_treasure_unlocked(_treasure_unlocked) # 解锁门控下传(装板摇号前) # core↔core 接线只许方法 Callable(静态规则 S6——lambda 捕获 self 会延长 # RefCounted 生命周期乃至成环:settlement 的信号持捕获 runner 的 lambda,runner 又持 settlement) _settlement.step_row.connect(_forward_step_row) @@ -462,14 +461,14 @@ func _start_battle(node: Dictionary) -> bool: _settlement.board_changed.connect(_forward_board_changed) _settlement.battle_finished.connect(_on_battle_finished) # node_entered 先于 begin_battle:呈现层须先拿到 settlement 引用,才能响应 begin 期间发出的 - # board_changed(首板安装)并重建棋盘——后发会导致首战棋盘不渲染(2026-09-11 playtest 缺陷①) + # board_changed(首板安装)并重建棋盘——后发会导致首战棋盘不渲染 node_entered.emit(node, {}) if not _settlement.begin_battle({"level_index": int(level_row.level_index), "node_depth": int(node.get("node_depth", 0)), "hero_hp": hero_hp, "hero_atk": effective_atk(), "hero_max_hp": effective_max_hp(), "hero_armor_class": effective_ac(), "hero_ap_bonus": effective_ap_bonus(), - "attack_type": _hero_attack_type, "armor_type": _hero_armor_type, # 迭代 23 T4——两根类型轴(spawn 英雄快照;空串=锻造配置默认值回退) + "attack_type": _hero_attack_type, "armor_type": _hero_armor_type, # 两根类型轴(spawn 英雄快照;空串=锻造配置默认值回退) "attunement": _attunement, - "ledger": run_ledger, # 迭代 27 T3——共享四账单类下传(原四散 dict 引用键收口;裁点②甲) + "ledger": run_ledger, # 共享四账单类下传(单引用键) "feats": _feats, "tree_rules": _tree_rules, "battle_index": _battle_index(), @@ -478,7 +477,7 @@ func _start_battle(node: Dictionary) -> bool: "node_type": String(node.get("type", ""))}): push_error("[关卡节点地图] 战斗启动失败(depth %s)" % str(node.get("node_depth", -1))) return false - _voucher_rap = 0 # 迭代 20 T4——节点级一次性:注入即消费(战斗未启动则保留至下次注入前不清) + _voucher_rap = 0 # 节点级一次性:注入即消费(战斗未启动则保留至下次注入前不清) _voucher_time_sand = 0 return true @@ -489,7 +488,7 @@ func _forward_step_row(row: Dictionary) -> void: # battle_index=第几场战斗(关卡域 1 基序——visited 已含当前节点〔_enter_node :437 先追加后启动〕; # 按已到节点 type=battle 计数,与图形态 node_depth/单链数组下标两编号空间解耦〔混编碰撞免疫〕; -# 开局姿态组「每关首轮窗」条件面——迭代 21 T3) +# 开局姿态组「每关首轮窗」条件面) func _battle_index() -> int: var n := 0 for v in visited: @@ -524,7 +523,7 @@ func _on_battle_finished(payload: Dictionary) -> void: var treasure_cleared := 0 if treasure_inventory != null: treasure_cleared = treasure_inventory.inventory_count() # 快照计数(清空前——「剩余道具随关卡结束清空」可见反馈取数) - treasure_inventory.reset() # 迭代 7 T3——关卡末库存清空(无论输赢,幂等) + treasure_inventory.reset() # 关卡末库存清空(无论输赢,幂等) level_finished.emit({"result": level_result, "hp": hp_left, "node_index": node_index, "node_id": _node_id(node), "node_type": String(node.get("type", "")), "aux_cleared": treasure_cleared}) # additive 扩签(不参与派生——node_map 扩签先例) @@ -534,8 +533,8 @@ func _on_battle_finished(payload: Dictionary) -> void: _present_choices() -# 恢复数学单一路径(漂移③清偿;2026-10-02 修复批——同式双落点收口:算术宿主 = 本静态方法, -# AdventureRunner.apply_rest 同式委托,字面量双写退役)。floor(上限 × 比例 ÷ 100) 后封顶缺口; +# 恢复数学单一路径(漂移③清偿;算术宿主 = 本静态方法, +# AdventureRunner.apply_rest 同式委托)。floor(上限 × 比例 ÷ 100) 后封顶缺口; # 冒险结构 GDD 公式逐位一致 static func rest_heal(pct: int, hp: int, max_hp: int) -> int: return mini(int(floor(float(max_hp) * float(pct) / 100.0)), max_hp - hp) @@ -585,19 +584,19 @@ func pick_next_node(node_id: int) -> bool: func current_battle(): return _settlement -# aux 解锁门控集注入(迭代 7 T5——AdventureRunner 自 params 传递) +# aux 解锁门控集注入(AdventureRunner 自 params 传递) func set_treasure_unlocked(ids: Dictionary) -> void: _treasure_unlocked = ids if _settlement != null: _settlement.set_treasure_unlocked(ids) -# 同调装配集注入(迭代 11 第①批 T5——冒险开始参数面;AdventureRunner 唯一调用方) +# 同调装配集注入(冒险开始参数面;AdventureRunner 唯一调用方) func set_attunement(ids: Array) -> void: _attunement = ids.duplicate() -# 特性持有集注入(迭代 12 T1——AdventureRunner._start_current_level 唯一调用方;begin_battle +# 特性持有集注入(AdventureRunner._start_current_level 唯一调用方;begin_battle # enc.feats 携带进战斗求值;**共享引用不复制**——关内奖励节点兑付的 relic 须当关后续战斗生效 # (attune_charges 共享账本同款);空集=零扰动) var _feats: Array[Variant] = [] @@ -607,12 +606,12 @@ func set_feats(ids: Array) -> void: _feats = ids -# 特性持有集读面(迭代 12 呈现补齐——HUD C 区特性段数据源) +# 特性持有集读面(HUD C 区特性段数据源) func feats_held() -> Array: return _feats.duplicate() -# 树 rule 键集注入(迭代 12 T10——begin_battle enc.tree_rules 携带;Fork 激活侧 effects) +# 树 rule 键集注入(begin_battle enc.tree_rules 携带;Fork 激活侧 effects) var _tree_rules: Array[Variant] = [] @@ -620,16 +619,16 @@ func set_tree_rules(rules: Array) -> void: _tree_rules = rules.duplicate() -# 两根类型轴注入(迭代 23 T4——adventure 参数面快照;空串=未注入→锻造配置默认值回退。 +# 两根类型轴注入(adventure 参数面快照;空串=未注入→锻造配置默认值回退。 # 消费面:effective_ac 甲型基础 AC 层 + begin_battle enc 携带进 unit_container.spawn 英雄快照) func set_hero_axes(attack_type: String, armor_type: String) -> void: _hero_attack_type = attack_type _hero_armor_type = armor_type -# 共享四本账注入(迭代 27 T3——P1-4 收口:RunLedger 单类下传,替代原 bonus/attune_charges/ -# vision_counter/adventure_counters 四散引用;战斗侧只走账类原语,战末 export/开局 seed -# 时点语义不变〔裁点②甲〕) +# 共享四本账注入(RunLedger 单类下传,含 bonus/attune_charges/ +# vision_counter/adventure_counters 四账;战斗侧只走账类原语,战末 export/开局 seed +# 时点语义不变) var run_ledger: RunLedger = RunLedger.new() @@ -637,7 +636,7 @@ func set_run_ledger(l: RunLedger) -> void: run_ledger = l -# 凭证件三账注入(迭代 20 T4——储备金袋 RAP/时沙 首轮 AP/完美保险 标错豁免;节点级一次性, +# 凭证件三账注入(储备金袋 RAP/时沙 首轮 AP/完美保险 标错豁免;节点级一次性, # battle begin 消费后归零;缺省 0=零扰动) var _voucher_rap := 0 var _voucher_time_sand := 0 @@ -648,10 +647,9 @@ func set_voucher_grants(rap: int, time_sand: int) -> void: _voucher_time_sand = maxi(0, time_sand) -# 同调主动件充能账骑库存面注入(迭代 11 第①批 T6 原语义 + 迭代 27 T3 换代——账本住 -# RunLedger;能力件骑库存面注入保留:差额注入防续玩双份——resume 路径 restore_inventory -# 已含断点内 attune 记录。原 set_attune_charges/set_vision_counter/set_adventure_counters -# 三散 setter 随单类下传承接) +# 同调主动件充能账骑库存面注入(账本住 +# RunLedger;差额注入防续玩双份——resume 路径 restore_inventory +# 已含断点内 attune 记录) func sync_attune_inventory() -> void: var charges: Dictionary[Variant, Variant] = run_ledger.attune_charges if treasure_inventory == null: @@ -664,7 +662,7 @@ func sync_attune_inventory() -> void: for i in range(maxi(0, int(charges[iid]) - existing)): treasure_inventory.add_item(String(iid), "attunement", Vector2i(-1, -1), 0) -# 三选一 GP 袋件入账(迭代 10——钱包收口扩「奖励入账」入口;复用战斗完成同一入账原语, +# 三选一 GP 袋件入账(钱包收口的「奖励入账」入口;复用战斗完成同一入账原语, # wallet_changed 载荷带 source 供呈现归因) func grant_curio_gp(amount: int) -> void: gp = maxi(0, gp + amount) @@ -680,13 +678,13 @@ func continue_after_node() -> bool: if t != "reward" and t != "rest" and t != "shop": return false if t == "shop": - _shop_shelf = [] # 离开店面货架态清零(断点快照 shop_shelf 键随离开落空架合法态——迭代 11 第②批 T2) + _shop_shelf = [] # 离开店面货架态清零(断点快照 shop_shelf 键随离开落空架合法态) _shop_visit_buys = 0 _shop_paid_refreshes = 0 # MC-1 return _present_choices() -# ---- GP 冒险钱包(GP+商店房实施批 2026-09-21:入账/出账/收束清零三收口)---- +# ---- GP 冒险钱包(入账/出账/收束清零三收口)---- # 战斗完成入账(gp_dropped 载荷——clamp ≥0;破财可把战斗域 escrow 打负,钱包不透支) func _gain_wallet(amount: int) -> void: @@ -719,16 +717,15 @@ func shop_products() -> Array: # 现价 = base_price + price_level_bonus(level_index) + price_increment × 该商品已购档数 -# (散折价随批:economy_spend 激活时商品标价 ×80%——见 _spend_discounted) +# (散折价:economy_spend 激活时商品标价 ×80%——见 _spend_discounted) func current_price(prow: Dictionary) -> int: return _spend_discounted(int(prow.get("base_price", 0)) + db.shop_price_level_bonus(int(level_row.level_index)) \ + int(prow.get("price_increment", 0)) * purchased_tier(String(prow.get("product_id", "")))) -# 散折价单点(迭代 21 T3——财富之道·散 economy_spend 激活时商品购买价 ×80% provisional, +# 散折价单点(财富之道·散 economy_spend 激活时商品购买价 ×80% provisional, # floor 取整偏向玩家、下限 1 防 1 元商品折成 0;范围=商品标价定义边界〔legacy 商品面 current_price -# + 池货架面 pool_price 同折〕——商店刷新价 shop_refresh_cost 与三选一付费刷新不折〔卡片§11②裁决〕; -# 折率归 M4 数值批) +# + 池货架面 pool_price 同折〕——商店刷新价 shop_refresh_cost 与三选一付费刷新不折) func _spend_discounted(price: int) -> int: if _tree_rules.has("economy_spend"): return maxi(1, int(floor(float(price) * 0.8))) @@ -753,7 +750,7 @@ func buy_product(product_id: String) -> bool: var price := current_price(prow) if gp < price: push_warning("[关卡节点地图] 购买拒绝——余额不足: %s(需 %d,钱包 %d)" % [product_id, price, gp]) - return false # 余额不足(覆盖层按钮禁用为常态防线——此处兜底拒绝;2026-10-02 补静默留痕) + return false # 余额不足(覆盖层按钮禁用为常态防线——此处兜底拒绝+静默留痕) gp -= price var flat := int(prow.get("flat_value", 0)) run_ledger.bonus[attr] = int(run_ledger.bonus[attr]) + flat @@ -770,11 +767,11 @@ func player_request_refresh() -> bool: return _settlement.player_request_refresh() -# ---- 商店共享池模式(迭代 11 第②批 T3——P1 共享池/P4 ceil;legacy 固定三件路径上方原样保留为 off 对照承载)---- +# ---- 商店共享池模式(legacy 固定三件路径保留为 off 对照承载)---- # 注入(AdventureRunner._start_current_level 唯一调用方——pool 模式专用):令牌库共享引用 + # 池消费 handler。legacy 模式不注入(_shop_pool_mode 恒 false——off 态零 RNG 零池消费零扰动)。 -# 迭代 20 T2——cap 检查回调(案②提前退役:cap 满 kind 剔出货架候选视图)。 +# cap 检查回调(cap 满 kind 剔出货架候选视图)。 func set_shop_pool(deck_ref: Array, consume_handler: Callable, ticket_consider: Callable = Callable(), cap_check: Callable = Callable()) -> void: _pool_deck = deck_ref _pool_consume = consume_handler @@ -801,7 +798,7 @@ func _shop_draw_shelf() -> void: for row in db.shop_pool_rows(): var shelf_kind := String(row.get("kind_id", "")) if _pool_cap_check.is_valid() and not bool(_pool_cap_check.call(shelf_kind, "")): - continue # 迭代 20 T2 案②——cap 满提前退役(货架候选视图剔除;牌库本体不动) + continue # cap 满剔除(货架候选视图剔除;牌库本体不动) for t in _pool_deck: var tok: Dictionary[Variant, Variant] = t as Dictionary if String(tok.get("kind", "")) == shelf_kind: @@ -826,10 +823,9 @@ func _shop_draw_shelf() -> void: # T5 门票注入(非 Boss 渠道唯一专长入口——货架与节点共享保底计数;判定含 pity 记账,替换末位占一席。 # 取数复用本函数 shop_draw scope 的 stream——零新 scope,确定性序列不漂移) if _pool_ticket.is_valid() and not _shop_shelf.is_empty() and bool(_pool_ticket.call(stream)): - _shop_shelf[_shop_shelf.size() - 1] = {"kind": "feat_ticket", "tier": "excellent"} # 迭代 20 T2——档名四级换代(旧 rare 语义=优秀) - # 商店保底退役(迭代 15 卡② T4——渠道轴定位裁决:商店渠道只出属性值提升+资源,专长在非 Boss - # 渠道只以门票形态出现(奇物.md v2.7/A4 断言)。迭代 12 T6「货架零特性挤卡换吞噬流件」简化口径 - # 与渠道白名单直接冲突(devour=规则改写型=专长系),随渠道分离退役;专长商店入口=T5 门票。 + _shop_shelf[_shop_shelf.size() - 1] = {"kind": "feat_ticket", "tier": "excellent"} # 门票占位档名 = excellent + # 商店渠道无专长直接投放(渠道白名单:商店渠道只出属性值提升+资源,专长在非 Boss + # 渠道只以门票形态出现——奇物.md v2.7/A4 断言;专长商店入口=T5 门票)。 # 库存余量(TP0——令牌库内该 kind 剩余枚数单点读;未注入/防御读 = 0) @@ -857,7 +853,7 @@ func pool_price(kind: String) -> int: # 货架只读投影(呈现层数据源——kind/显示名/件值/现价/库存余量齐备,UI 零复算)。 -# 件值=在架令牌本体值(TP0——令牌级货架,kind+tier 定值;价格公式维持批②裁定 tier-blind)。 +# 件值=在架令牌本体值(TP0——令牌级货架,kind+tier 定值;价格公式 tier-blind〔不随档位变〕)。 func shop_shelf() -> Array: var out: Array[Dictionary] = [] for tok in _shop_shelf: @@ -882,16 +878,16 @@ func shop_shelf() -> Array: return out -# 商店独立刷新(MC-1——P-C2 裁 2026-10-04 推翻 v1.5「无独立刷新」):免费次数(天赋增益位,基础 -# knob=0——Q2 裁「基础免费 0 次」)用尽后 GP 付费刷新;刷新=货架整架重抽(shop_draw 恰一新 scope, +# 商店独立刷新(MC-1):免费次数(天赋增益位,基础 +# knob=0=「基础免费 0 次」)用尽后 GP 付费刷新;刷新=货架整架重抽(shop_draw 恰一新 scope, # 与进店/买后重抽同签——重抽同源共享池);池空/非池模式=不可刷新合法态。 func shop_refresh_free_left() -> int: - # 迭代 22 秘宝批 T3——刷新执照 shop_refresh_bonus 装配合计叠加(进店入账语义=读数即本店可用, - # 与基础 knob 同生命周期;未装配=基值逐位同旧) + # 刷新执照 shop_refresh_bonus 装配合计叠加(进店入账语义=读数即本店可用, + # 与基础 knob 同生命周期;未装配=基值) return maxi(0, int(db.adventure.shop_refresh_free) + _attune_shop_refresh_bonus()) -# 刷新执照装配合计(迭代 22 秘宝批 T3——装配集 kind 分发扫描;零装配=0) +# 刷新执照装配合计(装配集 kind 分发扫描;零装配=0) func _attune_shop_refresh_bonus() -> int: var total := 0 for iid_v in _attunement: @@ -919,7 +915,7 @@ func shop_refresh() -> bool: return true -# GP 冒险钱包单口支出(2026-10-06——三选一 GP 付费刷新与商店刷新共用同一钱包;余额不足 false 零副作用) +# GP 冒险钱包单口支出(三选一 GP 付费刷新与商店刷新共用同一钱包;余额不足 false 零副作用) func spend_gp(amount: int) -> bool: if amount <= 0 or gp < amount: return false diff --git a/game/core/meta_progression.gd b/game/core/meta_progression.gd index 4911f4ff..46c4b6b5 100644 --- a/game/core/meta_progression.gd +++ b/game/core/meta_progression.gd @@ -9,7 +9,7 @@ var db: ConfigDb var save: SaveManagerCore -# 迭代 27 T1 裁点①——MetaProgression 升格 autoload(RngService 先例:类名加 Core 后缀、 +# MetaProgression 是 autoload(仿 RngService 先例:类名加 Core 后缀、 # autoload 占净名)。_init 参数可缺省兼容双形态:autoload 实例化走 .new() 零参 + _ready 从 # autoload 链取依赖(工程序 ConfigDB→RngService→SaveManager→MetaProgression,_ready 时序 # 已就绪);单测/工具直呼 .new(db, save) 形态不变(不入树零 _ready)。 @@ -29,11 +29,9 @@ func keystone_balance() -> int: return save.keystone_balance() -# ---- 秘宝解锁服务(迭代 22 T2 换代——解锁混合制,契约 6;旧工坊渠道面随批删除)---- -# 〔属性锻造柜台退役——迭代 21 T4/T5:buy_forge/forge_flat/forge_level/forge_price 与 meta_forge -# 表族随攻防所有权切分删除。〕〔道具工坊解锁渠道面退役——迭代 22 T2:旧「总通关次数达阈值」 -# 行族与 _workshop_progress/workshop_status/refresh_workshop_unlocks 删除,解锁条件单一事实源= -# treasure_items.tres 行内 unlock_keystone_cost/unlock_requires 谓词(C1 逐件分配锁定表)。〕 +# ---- 秘宝解锁服务(解锁混合制,契约 6)---- +# 解锁条件单一事实源=treasure_items.tres 行内 unlock_keystone_cost/unlock_requires 谓词 +# (C1 逐件分配锁定表)。 # 道具解锁读数访问器(组合根/呈现层解锁门控查询面——禁再穿透 meta.save 直读 save_manager) func is_item_unlocked(item_id: String) -> bool: @@ -123,11 +121,11 @@ func treasure_shop_status() -> Array: return out -# ---- 锻造工坊写口族(迭代 23 T3——契约 9:扣币/升级/解锁/选中/写盘只经本组;UI 只发意图信号)---- +# ---- 锻造工坊写口族(契约 9:扣币/升级/解锁/选中/写盘只经本组;UI 只发意图信号)---- # 设计权威 design/gdd/systems/跨局循环/锻造工坊.md v0.6:钥石单币(契约 3——GP 局内一次性货币 # 永不互兑)、并联双通道解锁(4b-1——练满前一档 OR 一次性解锁价,互不影响不设串联)、 # 一次冒险一武器一甲(契约 8——营地免费切换、冒险开始锁死由参数面快照保证)。 -# 等级语义(Q1):未解锁/未锻造=0 加值(裸体态);锻造第一级=「获得装备」=首个 +1;逐级递进。 +# 等级语义:未解锁/未锻造=0 加值(裸体态);锻造第一级=「获得装备」=首个 +1;逐级递进。 # 路线解锁态派生(不落档——初始持有∨直购∨练满前一档;派生单点只此一处) func forge_route_unlocked(route_id: String) -> bool: @@ -231,7 +229,7 @@ func hero_armor_type() -> String: return String(row.get("type_axis", "")) -# ---- 锻造工坊柜台只读投影(迭代 23 T6——呈现层数据源:两区六路线行板;余额联动禁用归视图)---- +# ---- 锻造工坊柜台只读投影(呈现层数据源:两区六路线行板;余额联动禁用归视图)---- # 每行 {route_id, display_name, kind, type_axis, level, cap, unlocked, initial_owned, selected, # next_price(未满级已解锁=下级几何价/否则 0), unlock_price, prereq_route, prereq_name, # prereq_level, prereq_cap, prereq_maxed}——纯结构面,禁嵌余额判断(视图按 balance 禁用,同秘宝匣先例)。 @@ -271,16 +269,16 @@ func forge_shop_status() -> Array: # ---- Boss 两档与收束入账(结算屏文案数据源)---- # 明细 {big_reward, boss_drops, total, new_unlocks};入账与标记经 save.apply_adventure_summary # (keystone_drops 副本随摘要入 recent_summaries)。 -# 迭代 10 奖励重构批:钥石改 Boss 逐杀掉落——掉落金额已在冒险内逐杀入账(summary.keystone_total -# 含全部掉落;首杀/复杀裁决在 AdventureRunner._boss_keystone_drop,首杀标记仍在下方 -# apply_adventure_summary 逐通关关次置位)。本函数不再派生掉落金额,只做标记+入账+归档。 +# 钥石为 Boss 逐杀掉落——掉落金额已在冒险内逐杀入账(summary.keystone_total +# 含全部掉落;首杀/复杀判定在 AdventureRunner._boss_keystone_drop,首杀标记在下方 +# apply_adventure_summary 逐通关关次置位)。本函数只做标记+入账+归档。 func settle_adventure(summary: Dictionary) -> Dictionary: # 首次冒险布尔位置位(关卡节点图生成 v0.4——完成/失败/放弃三结局同经本收束挂点,写入只在收束) save.mark_first_adventure_done() var drops: Array[Variant] = (summary.get("keystone_drops", []) as Array).duplicate(true) save.apply_adventure_summary(summary, drops) - save.add_vision_used(int(summary.get("vision_used_delta", 0))) # 迭代 22 T3——真视使用计数收束聚合入档(信标网络行为条件) - var new_unlocks := refresh_treasure_unlocks() # 迭代 22 T2——条件解锁刷新换代(旧工坊面退役) + save.add_vision_used(int(summary.get("vision_used_delta", 0))) # 真视使用计数收束聚合入档(信标网络行为条件) + var new_unlocks := refresh_treasure_unlocks() # 条件解锁刷新 save.write_to_disk() var total := int(summary.get("keystone_total", 0)) return { @@ -292,13 +290,12 @@ func settle_adventure(summary: Dictionary) -> Dictionary: # ---- 跨局注入(冒险开始参数面)---- -# 迭代 23 T4 注入公式换代(锻造工坊实装批——契约 1 攻防所有权切分落地):基础值 + 树生命/命中淬炼 -# flat(命中线在账未注入——契约 6,消费面归数值批)+ **锻造路线加值**(当前选中武器攻击加值 + 当前甲 +# 注入公式(契约 1 攻防所有权切分):基础值 + 树生命/命中淬炼 +# flat(命中线在账未注入——契约 6)+ **锻造路线加值**(当前选中武器攻击加值 + 当前甲 # AC 加值——读存档 forge_routes 域+路线表)+ 局内加算区(bonus 区域不经本面)。入战 AC 三层可加: # 甲型基础 AC(forge.tres 行 base_ac)+ 甲路线等级加值(本面 armor_class 分量)+ 局内加算区。 -# 旧属性柜台 forge_flat 项退役移除(V7/V12);攻/AC 树来源随所有权切分砍除(契约 9——树零攻防来源, -# 现表零 atk/armor_class 行,tree_stat_flat 二轴恒 0 保留通式)。原 FORGE_ROUTE_BONUS 预留常量随本批 -# 退役(公式不再出现——V7/V12)。 +# 攻/AC 树来源按所有权切分砍除(契约 9——树零攻防来源, +# 现表零 atk/armor_class 行,tree_stat_flat 二轴恒 0 保留通式)。 # 全零 = 白板合法态(无解锁不得改变任何局内规则);override 禁写表(表运行期只读)。 func hero_override() -> Dictionary: @@ -309,7 +306,7 @@ func hero_override() -> Dictionary: } -# ---- 天赋树段(迭代 12 T8——R1 甲融合案;设计权威 整合定稿 §1.4 一树双币三脉一脊)---- +# ---- 天赋树段(设计权威 整合定稿 §1.4 一树双币三脉一脊)---- # 全树已购总等级(row-gating 输入——「投入点数累计解锁新行」) func tree_spent_total() -> int: @@ -333,15 +330,15 @@ func tree_can_buy(node_id: String) -> bool: # 刷新升级节点:cap 主语=Y 账本(单一事实源——树上入口与装配段同 cap 同价,防双账漂移) if node_id == "ks_refresh" and db.meta_attune_refresh_row(save.attune_refresh_level() + 1).is_empty(): return false - # 行门槛(一线一节点:脊柱节点第 N 级需全树总投入 ≥4×(N−1)——迭代 21 主语平移,row 字段退役) + # 行门槛(一线一节点:脊柱节点第 N 级需全树总投入 ≥4×(N−1)) if String(row.get("vein", "")) == "spine" and String(row.get("kind", "")) == "stat": if tree_spent_total() < db.meta_tree.level_gate(lvl + 1): return false for req in (row.get("requires", []) as Array): if save.tree_level(String(req)) < 1: return false - # 等级阈值前置(R1 机制位——requires_level {node_id: n}:前置节点等级 ≥ n 才可购; - # 2026-10-13 用户推翻裁撤案随批重立,现役表零配置=空转零行为影响) + # 等级阈值前置(requires_level {node_id: n}:前置节点等级 ≥ n 才可购; + # 现役表零配置=空转零行为影响) var req_lv: Dictionary[Variant, Variant] = row.get("requires_level", {}) as Dictionary for req_id in req_lv.keys(): if save.tree_level(String(req_id)) < int(req_lv[req_id]): @@ -349,9 +346,9 @@ func tree_can_buy(node_id: String) -> bool: return true -# 节点购买(营地树 UI 唯一写口):树全钥石单币(2026-10-07 用户裁甲)。free=工作间钥匙零币点亮 +# 节点购买(营地树 UI 唯一写口):树全钥石单币。free=工作间钥匙零币点亮 # (price 0,零额消费无副作用);彩蛋不经购买(can_buy 已拒——觉醒唯一入口=_check_easter_egg)。 -# 刷新升级节点走同账路由(Q1 裁乙——树上+秘宝匣装配段双入口写同一 attune_refresh_level 账本, +# 刷新升级节点走同账路由(树上+秘宝匣装配段双入口写同一 attune_refresh_level 账本, # 价格/上限单一事实源=Y 行表值 keystone_cost;V15)。 func tree_buy(node_id: String) -> bool: if node_id == "ks_refresh": @@ -479,7 +476,7 @@ func tree_fork_groups() -> Array: # 彩蛋觉醒检查(特化判定——生命/命中两线拉满 且 同调位 1/2/3 全解锁 → easter_ley 免费点亮; -# 迭代 21 T2 换代:不依赖 requires/requires_level 前置形态,发现率监控呈报面沿袭) +# 不依赖 requires/requires_level 前置形态) func _check_easter_egg() -> void: if save.tree_level("easter_ley") > 0: return @@ -493,15 +490,11 @@ func _check_easter_egg() -> void: save.set_tree_level("easter_ley", 1) -# 三体系迁移函数已删除(迭代 21 T5——旧档破坏性废弃〔Q3 用户裁:开发阶段无迁移〕;换代前结构 -# 由 SaveManager._normalize 的 tree_struct 标记检测废弃重置,禁迁移禁折算)。 - - -# ---- 同调位账本(迭代 11 第①批 T4——装配关系/同调位求值/Y 刷新升级;设计权威 proposal §2 + 需求卡片 P1 甲)---- +# ---- 同调位账本(装配关系/同调位求值/Y 刷新升级;设计权威 proposal §2)---- # 装配切换(营地装配覆盖层唯一写口——冒险开始前配置;冒险中零写口=装配不可变契约 1,本口只服务营地): # 已装 → 卸下恒可(卸下后其余件前移位序——效果面只读装配集不受格位影响);未装 → 非同调行拒绝 + -# 满位禁选 + 档位格校验(迭代 22 T2 契约 2:装入件 append 至末位 k=已装数+1,件档 rank ≤ k—— +# 满位禁选 + 档位格校验(契约 2:装入件 append 至末位 k=已装数+1,件档 rank ≤ k—— # 格 1=普通格/格 2=优秀格/格 3=稀有格递增向下兼容;槽位来源=树同调位节点点亮数,树接口接缝现役)。 # 装配关系写存档持久。 func toggle_attunement(item_id: String) -> bool: diff --git a/game/core/minesweeper_rules.gd b/game/core/minesweeper_rules.gd index 2ccdc074..3da13158 100644 --- a/game/core/minesweeper_rules.gd +++ b/game/core/minesweeper_rules.gd @@ -11,18 +11,18 @@ signal round_end_board(payload: Dictionary) # 双发射源之棋盘路径( var db: ConfigDb var action_economy: ActionEconomy -# 秘宝常时参数注入面(迭代 22 秘宝批 T3——编排器 begin_battle 按装配集 kind 分发注入: +# 秘宝常时参数注入面(编排器 begin_battle 按装配集 kind 分发注入: # dig_range_bonus=挖掘切比雪夫距离放宽〔远程镐 dig_range_bonus magnitude〕/seal_range_free= # 封印不限相邻〔信标网络〕;缺省 0/false=零装配零扰动,棋盘事实不可变契约不受影响—— # 两参数只放宽「动作可达性」判据,禁碰危险格/安全格分布) var dig_range_bonus := 0 var seal_range_free := false -# 棋盘状态私有(E2 封装收口 2026-09-13):对外只暴露 current_board()/reveal_record() 等查询面, -# 禁止跨模块直读/直写原始字典——先例教训 = board_view 绕过查询面直读 revealed。 +# 棋盘状态私有(E2 封装收口):对外只暴露 current_board()/reveal_record() 等查询面, +# 禁止跨模块直读/直写原始字典。 var _board: BoardData = null var _revealed := {} # Vector2i → {"kind": "safe"/"mine", "digit": int} var _seals := {} # Vector2i → true(棋盘单态;跨轮保留随图存续) -var _removed := {} # Vector2i → true(迭代 13 T8/D6——中立移除危险格集;随 install/retire 清空) +var _removed := {} # Vector2i → true(中立移除危险格集;随 install/retire 清空) var _hero := Vector2i.ZERO var _spawn: Dictionary[Vector2i, bool] = {} @@ -72,7 +72,7 @@ func clear_map_cleared() -> bool: return safe_remaining() == 0 -# ---- 中立移除(迭代 13 T8/D6——P1 甲:邻接数字=原始雷数冻结零重算;P2 甲:移除格呈现退色降档; +# ---- 中立移除(P1 甲:邻接数字=原始雷数冻结零重算;P2 甲:移除格呈现退色降档; # 移除集=未揭示、无封印、是雷——封印判定基线零回溯;危险格不入清图分母/连锁/C_dig 模拟,判定逻辑零改动) ---- func remove_mines_in(cells: Array) -> Array: @@ -103,7 +103,7 @@ func has_unrevealed() -> bool: # ---- install(编排边界相位 = 行动经济 Idle/Waiting;Active 拒绝——防轮内换板)---- -# during_round = 轮内刷新编排路径(2026-09-12 方案 A,战斗结算 唯一调用方):Active 相位合法—— +# during_round = 轮内刷新编排路径(战斗结算 唯一调用方):Active 相位合法—— # 玩家挖掘中立即换图,棋盘状态(revealed/seals)随 install 重置,初始展开事件照发(initial 通道) func install_board(b: BoardData, during_round := false) -> Dictionary: if action_economy.phase == action_economy.PHASE_ACTIVE and not during_round: @@ -138,7 +138,7 @@ func seal_count() -> int: return _seals.size() -# during_round = 轮内刷新编排路径(2026-09-12 方案 A):Active 相位合法——换图前退役旧板 +# during_round = 轮内刷新编排路径:Active 相位合法——换图前退役旧板 func retire_board(during_round := false) -> Dictionary: if _board == null: return _outcome(true, "executed", "", "") # 幂等受理 @@ -267,7 +267,7 @@ func _do_dig(c: Vector2i) -> Dictionary: var sub := _board_face_dig(c) if sub != "": return _outcome(false, "rejected", "board_face", sub) - # 挖封印格(封印不可逆批 2026-09-19):本格封印事务内隐式退役——链闭包按「本格无封印、其余封印照挡」 + # 挖封印格(封印不可逆):本格封印事务内隐式退役——链闭包按「本格无封印、其余封印照挡」 # 计算(封印格为 0 时连锁照常外扩);request_dig 被拒则封印原地保留(事务性),受理后该封印轮末不判 # (发射面基线 = 在场封印——标中/标空兑付让位于挖掘本体结局,四情况②④)。 var was_sealed := has_seal(c) @@ -295,7 +295,7 @@ func _do_dig(c: Vector2i) -> Dictionary: continue # 闭包可穿过已开区——已开格零事件(cell_revealed × |O′ ∖ O|) var is_mine := _board.is_mine(rc) var channel := "dig" if rc == c else "chain" - # 格面资源资格(2026-09-15 格面资源批):chain/dig 恒 true——安全格与危险格一视同仁(危险格亦携带, + # 格面资源资格:chain/dig 恒 true——安全格与危险格一视同仁(危险格亦携带, # 负向兑付归 战斗结算 极性路由);initial(封锁格)恒 false。资源本体与极性不在本系统。 # dug_under_seal = 首格带封印直挖标记(战斗结算 情况④兑付改判消费;连锁格恒 false——连锁不越封印) if is_mine: @@ -325,12 +325,12 @@ func _board_face_dig(c: Vector2i) -> String: if is_revealed(c): return "target_revealed" if _removed.has(c): - return "target_removed" # 迭代 13 T8/D6——中立移除格不可交互(拒绝先于消耗,pattern 1 board_face 腿) - # 封印不拦挖掘(封印不可逆批 2026-09-19):有封印格直接挖 = 对承诺的兑现,兑付改判归 战斗结算。 + return "target_removed" # 中立移除格不可交互(拒绝先于消耗,pattern 1 board_face 腿) + # 封印不拦挖掘(封印不可逆):有封印格直接挖 = 对承诺的兑现,兑付改判归 战斗结算。 return "" -# fx_reveal 效果通道揭示(迭代 20 专长实装批 T1——订阅类「揭示 1 格」效果的棋盘面执行口: +# fx_reveal 效果通道揭示(订阅类「揭示 1 格」效果的棋盘面执行口: # 不经行动经济〔零 AP 消耗零相位要求〕、不要求邻接〔任意揭示〕、只受理安全格〔信息红线=只揭真格, # 危险格/已开/出界/移除格=拒绝零副作用〕。连锁与揭示事件与 _do_dig 同构(chain 通道复用),资源兑付归 # 战斗结算 _flush_pending_reveals 直接入账——channel=fx_reveal 供归因) @@ -400,7 +400,7 @@ func _do_seal_place(c: Vector2i) -> Dictionary: elif has_seal(c): sub = "seal_present" elif _removed.has(c): - sub = "target_removed" # 迭代 13 T8/D6——中立移除格不可交互 + sub = "target_removed" # 中立移除格不可交互 if sub != "": return _outcome(false, "rejected", "board_face", sub) if not action_economy.try_spend("seal_place"): @@ -408,7 +408,7 @@ func _do_seal_place(c: Vector2i) -> Dictionary: _seals[c] = true # 封印动作零格子事件外发(发射面封闭;反馈经调用返回值命令式驱动) if action_economy.phase != action_economy.PHASE_ACTIVE: # 封印动作花完末点 AP 同样终结轮次(行动经济 三出口——AP 用完与动作种类无关;缺漏使 round_end - # 永不发出、战斗结算 的 Waiting 结算点永不到达 = 整局软锁。playtest 缺陷②,行为探针复现) + # 永不发出、战斗结算 的 Waiting 结算点永不到达 = 整局软锁) _emit_round_end_seals_and_payload() return _outcome(true, "executed", "", "") @@ -468,8 +468,8 @@ func _do_stop() -> Dictionary: # ---- 轮末封印判定 + 棋盘路径 round_end 外发 ---- func _emit_seals_batch() -> void: - # 判定基线 = 轮次结束事务开始时封印位;行主序枚举(确定性——排序键单点 BoardData.row_major_key, - # 2026-10-02 修复批);被拔的不判;诚实重复上报(去重归 战斗结算) + # 判定基线 = 轮次结束事务开始时封印位;行主序枚举(确定性——排序键单点 BoardData.row_major_key); + # 被拔的不判;诚实重复上报(去重归 战斗结算) var cells: Array[Variant] = _seals.keys() cells.sort_custom(func(a, b): return BoardData.row_major_key(a) < BoardData.row_major_key(b)) for c in cells: @@ -487,14 +487,14 @@ func _adjacent_to_hero(c: Vector2i) -> bool: return maxi(d.x, d.y) == 1 -# 挖掘可达判据(迭代 22 秘宝批 T3——远程镐 dig_range_bonus 放宽:切比雪夫距离 ≤ 1+加值, -# 加值 0=与旧「恰相邻」逐位一致;开格仍走既有格规则=不挖开不相邻事实之外 anything) +# 挖掘可达判据(远程镐 dig_range_bonus 放宽:切比雪夫距离 ≤ 1+加值, +# 加值 0=恰相邻;开格仍走既有格规则=不挖开不相邻事实之外 anything) func _within_dig_range(c: Vector2i) -> bool: var d := Vector2i(absi(c.x - _hero.x), absi(c.y - _hero.y)) return maxi(d.x, d.y) <= 1 + dig_range_bonus -# 本板危险格总数(迭代 22 秘宝批 T3——巢穴预告「装板后揭示本板危险格数量」取数口; +# 本板危险格总数(巢穴预告「装板后揭示本板危险格数量」取数口; # 只读投影 BoardData.mines 规模,零分布泄露——数量非位置) func mine_total() -> int: return _board.mines.size() if _board != null else 0 diff --git a/game/core/reward_economy.gd b/game/core/reward_economy.gd index 259cef0f..2bffccf3 100644 --- a/game/core/reward_economy.gd +++ b/game/core/reward_economy.gd @@ -16,7 +16,7 @@ var _granted := {} # Vector2i → 快照(重复受理幂等返 var _clear_identity := "" var _clear_granted := false var _clear_snapshot := {} -# 效果引擎(内容数据驱动扩展批 T1——reward_roll 发射面;偏运硬币 bias_rewards 订阅面) +# 效果引擎(reward_roll 发射面;偏运硬币 bias_rewards 订阅面) var _fx: EffectEngine = null @@ -40,7 +40,7 @@ func roll_board(eligible: Array) -> bool: if eligible.is_empty(): _fatal("roll_board 空资格清单(E1 兜底 fail-fast——排雷玩法 不变式④前置)") return false - # 行主序规范化 + 去重(排序责任不外推给 战斗结算;排序键单点 BoardData.row_major_key——2026-10-02 修复批) + # 行主序规范化 + 去重(排序责任不外推给 战斗结算;排序键单点 BoardData.row_major_key) var seen := {} var list: Array[Dictionary] = [] for e in eligible: @@ -58,7 +58,7 @@ func roll_board(eligible: Array) -> bool: _clear_granted = false _clear_snapshot = {} var stream: RandomNumberGenerator = rng.open_stream("reward_roll") # 恰一 scope 批(格批 + 清图批尾 + 区间行追加取号) - # reward_roll 发射+施加(内容数据驱动扩展批 T4——格面资源掷定、摇号前权重合成层: + # reward_roll 发射+施加(格面资源掷定、摇号前权重合成层: # bias_rewards 订阅命中合计=偏运权重加算(行 value_from magnitude 定影);零命中=原行集零扰动) var luck_bias := 0 if _fx != null: @@ -124,7 +124,7 @@ func query_full_snapshot(cell: Vector2i): return _snapshot(_row_by_id(rid), int(_power_roll.get(cell, -1))) -# ---- 受理面(战斗结算 编排期调用;E6 收口 2026-09-13:失败统一返回 null)---- +# ---- 受理面(战斗结算 编排期调用;E6 收口:失败统一返回 null)---- func grant(cell: Vector2i): if _phase != "ready": @@ -180,12 +180,11 @@ func polarity_row(cell_type: String, polarity: String) -> Dictionary: # ---- F1 选行算子纯函数 ---- -# 偏运硬币 N(迭代 11 同调批 T5 → 内容数据驱动扩展批 T4:begin_battle 注入拆除—— -# reward_roll bias_rewards 订阅命中合计经 _biased_cell_rows 入参;0 = 未装配零扰动) +# 偏运硬币 N(reward_roll bias_rewards 订阅命中合计经 _biased_cell_rows 入参;0 = 未装配零扰动) # 稀有正向资源 kinds(底稿 §3——权重投影面,池结构零触碰) const LUCK_BIAS_KINDS := ["heal", "gp", "pierce", "magic"] -# 图级偏斜旋钮(全局作用域变异首发批 2026-10-04——battle_orchestrator 装板决议注入,全局型行 +# 图级偏斜旋钮(battle_orchestrator 装板决议注入,全局型行 # effect_value 语义=生存族权重下调百分比;0 = 中性 off 态。每板决议时显式重置/写入) var board_skew: int = 0 @@ -196,7 +195,7 @@ const SKEW_UP_KINDS := ["attack", "blast", "pierce", "magic"] # 偏运硬币权重投影(底稿 §3:只动池内权重、雷安仍同池同分布;luck_bias=0 逐位返回原行集——off 态零扰动) -# 基座换源(首发批 2026-10-04):先经图级偏斜投影再叠件级加法——合成序锚=图级先、件级后 +# 合成序:先经图级偏斜投影再叠件级加法——合成序锚=图级先、件级后 #(环境事实先定型、玩家构筑叠其上;两投影均为池内权重面,雷安同池与取号次数零变化) func _biased_cell_rows(bias: int) -> Array: var base: Array[Variant] = _skewed_cell_rows() @@ -213,7 +212,7 @@ func _biased_cell_rows(bias: int) -> Array: return out -# 图级资源面偏斜投影(首发批 T3——整数最大余数法:生存族按 board_skew% 下调,下调量按进攻族 +# 图级资源面偏斜投影(整数最大余数法:生存族按 board_skew% 下调,下调量按进攻族 # 原权重比例整数重分配,合计恒等于原池合计 77;负向行与白名单三行逐位不动)。 # board_skew<=0 逐位返回原行集 = off 态零扰动第一断言:不进投影域、行集/行序/取号域与基线逐位同。 func _skewed_cell_rows() -> Array: @@ -300,7 +299,7 @@ func weighted_pick(rows: Array, r: int) -> String: return "" -# aux 解锁门控集(迭代 7 T5——拍板③甲「解锁→进投放池」:未解锁 aux 行不入摇号池。 +# aux 解锁门控集(「解锁→进投放池」:未解锁 aux 行不入摇号池。 # 空集默认 = 全部 aux 不投放(白板/夹具态零投放——模拟读数零扰动;真实侧 main 组装工坊解锁集传入) var _treasure_unlocked := {} diff --git a/game/core/rng_service.gd b/game/core/rng_service.gd index a0090a94..bca06417 100644 --- a/game/core/rng_service.gd +++ b/game/core/rng_service.gd @@ -5,8 +5,8 @@ class_name RngServiceCore extends Node -# 用途标签封闭词表(并流前七流名全保留;新增用途走扩签通道 = 改代码 + 评审——清单封闭语义由「流」改「标签」) -const PURPOSE_TAGS := ["board_gen", "reward_roll", "encounter", "armor_roll", "behavior_roll", "variant_place", "gp_drop", "node_map", "reward_pick", "shop_draw", "fx_reveal"] # node_map = 关卡节点图生成 v0.4 扩签(M-3 迭代 5 T5);reward_pick = 提升三选一加权洗牌扩签(M-3 迭代 10 奖励重构批——每关大奖励抽签恰一 scope:E-S weight-key 每候选一取,标签不参与派生只进事件日志,派生/黄金向量零改动);shop_draw = 商店房货架抽签扩签(M-4 迭代 11 第②批 T1——每次抽 3〔进店+每次买后重抽〕恰一 scope,与 reward_pick 分签防取数序互扰;shop=off 零消费零扰动);fx_reveal = 专长订阅类揭示效果掷格(迭代 20 T1——见血开窍/斩首学者等「揭示 1 格」,与 reward_pick 分签防取数序互扰;只揭真格=安全格信息红线承载) +# 用途标签封闭词表(流名清单封闭;新增用途走扩签通道 = 改代码 + 评审) +const PURPOSE_TAGS := ["board_gen", "reward_roll", "encounter", "armor_roll", "behavior_roll", "variant_place", "gp_drop", "node_map", "reward_pick", "shop_draw", "fx_reveal"] # node_map = 关卡节点图生成 v0.4 扩签;reward_pick = 提升三选一加权洗牌扩签(每关大奖励抽签恰一 scope:E-S weight-key 每候选一取,标签不参与派生只进事件日志,派生/黄金向量零改动);shop_draw = 商店房货架抽签扩签(每次抽 3〔进店+每次买后重抽〕恰一 scope,与 reward_pick 分签防取数序互扰;shop=off 零消费零扰动);fx_reveal = 专长订阅类揭示效果掷格(见血开窍/斩首学者等「揭示 1 格」,与 reward_pick 分签防取数序互扰;只揭真格=安全格信息红线承载) # 分段表达式书写(数据配置 R3 实现级规约——禁 ≥2^63 完整字面量) const GOLDEN_RATIO := (0x9E3779B9 << 32) | 0x7F4A7C15 # 0x9E3779B97F4A7C15 @@ -18,7 +18,7 @@ const MIX_MUL_B := (0x94D049BB << 32) | 0x133111EB # 0x94D049BB133111EB const OUT_MASK := 0x7FFFFFFFFFFFFFFF const INT64_MIN := -9223372036854775808 -# master_seed 只读出口(E5 封装收口 2026-09-13):写入只经 set_master_seed(计数器全零断言 +# master_seed 只读出口(E5 封装收口):写入只经 set_master_seed(计数器全零断言 # 不可绕过);外部读 master_seed 供 存档序列化 快照契约观测。 var _master_seed: int = -1 # -1 = 未播种(取数即致命,EC7) var master_seed: int: @@ -30,16 +30,16 @@ var _log_fa: FileAccess = null var _log_warned := false -# 纯函数(测试/预览/日志回放入口,不推计数器)——单盐单参数(并流前 (流, scope) 双参退役) +# 纯函数(测试/预览/日志回放入口,不推计数器)——单盐单参数 func derive_at(scope: int) -> int: assert(scope >= 0, "负 scope 与 scope+2^63 经输出掩码别名(禁止)") var t: int = _master_seed + scope * GOLDEN_RATIO # wrap64 自然回绕——禁 float 中间量/禁 %/禁主动修复 return _mix64(SINGLE_SALT ^ t) -# R3 派生终末混淆(splitmix64 finalizer 变体,2026-09-19 掷点测量修复批 B 案):裸派生种子直接作 +# R3 派生终末混淆(splitmix64 finalizer 变体):裸派生种子直接作 # PCG 初始状态时,「连续小整数 master × 头部 scope 窗口」的面值彩票会被短局复用放大进聚合统计 -# (验收重测批实证:30 连续种子 × 头部窗口 × 40 局复用 → 18 点聚合 +57%);此混淆使任何窄种子窗 +# (30 连续种子 × 头部窗口 × 40 局复用 → 18 点聚合 +57%);此混淆使任何窄种子窗 # 表现如随机抽样。纯函数、逐 scope 复放语义不变;全程 OUT_MASK 63 位掩码——有符号 int64 的 >> # 为算术移位,63 位正值域内与逻辑移位逐位一致,这是与参考实现(Python 无符号模型)对齐的关键。 func _mix64(z: int) -> int: @@ -63,14 +63,14 @@ func set_master_seed(seed_val: int) -> void: # 切片登记:冒险开始重播种入口(正式侧调用权归 冒险结构;切片主菜单 = 冒险起点)—— -# 并流批(2026-09-27 统一流裁决):重播种同时开本次冒险的事件日志会话。 +# 重播种同时开本次冒险的事件日志会话。 func new_adventure(seed_val: int) -> void: _counter = 0 set_master_seed(seed_val) _open_log_session(_master_seed) -# 断点续玩恢复入口(迭代 8 卡①——快照契约「主种子+计数器」的回填面,调用权归 冒险结构): +# 断点续玩恢复入口(快照契约「主种子+计数器」的回填面,调用权归 冒险结构): # 回填后首个 open_stream(scope=counter_val) 的派生种子与中断前逐位一致——续玩从断点号位精确 # 续接原时间线(停点前已消耗的号位不重耗,停点后取数逐位可复现)。仅续玩路径调用;模拟/冒烟 # 零触达(MC 对拍零扰动)。 diff --git a/game/core/run_ledger.gd b/game/core/run_ledger.gd index 8a0a3789..cad9650e 100644 --- a/game/core/run_ledger.gd +++ b/game/core/run_ledger.gd @@ -1,15 +1,15 @@ class_name RunLedger extends RefCounted -# 共享四本账显式承载(迭代 27 T3——审计 P1-4「共享可变字典跨三层:所有权名义单点、实际三处 -# 可写」收口;裁点②甲 = 单类持四账)。 +# 共享四本账显式承载(审计 P1-4「共享可变字典跨三层:所有权名义单点、实际三处 +# 可写」收口 = 单类持四账)。 # 所有权:AdventureRunner 持有(开局构造、冒险全程唯一宿主);LevelRunner 经 set_run_ledger # 下传并装配 encounter;战斗侧(BattleOrchestrator)经 encounter["ledger"] 拿本类引用, # 只走下方 read/append 原语——战末 export/开局 seed 时点语义不变(确定性设计原样保留, # 只把「函数签名上不可见的共享可变引用」换成签名可见的显式类)。 -var attune_charges: Dictionary[Variant, Variant] = {} # 同调主动件充能账(迭代 11 第①批 T6——use_treasure 扣减;断点随局回档) -var vision_counter: Dictionary[Variant, Variant] = {} # 真视类使用计数(迭代 22 秘宝批 T3——冒险开始置 {"used":0}; - # 缺省空 = 调试/单场战斗不计——原 enc 缺键守卫语义) -var adventure_counters: Dictionary[Variant, Variant] = {} # adventure 域效果计数器(迭代 20 T6——rebuild 回灌/战末导出回写目标) +var attune_charges: Dictionary[Variant, Variant] = {} # 同调主动件充能账(use_treasure 扣减;断点随局回档) +var vision_counter: Dictionary[Variant, Variant] = {} # 真视类使用计数(冒险开始置 {"used":0}; + # 缺省空 = 调试/单场战斗不计——enc 缺键守卫语义) +var adventure_counters: Dictionary[Variant, Variant] = {} # adventure 域效果计数器(rebuild 回灌/战末导出回写目标) var bonus: Dictionary[Variant, Variant] = {} # 统一冒险加算区(冒险开始置四轴零账——商店购买/三选一属性件/战末 bonus_delta 汇入) diff --git a/game/core/save_manager.gd b/game/core/save_manager.gd index c7569f3a..f381145e 100644 --- a/game/core/save_manager.gd +++ b/game/core/save_manager.gd @@ -6,10 +6,10 @@ class_name SaveManagerCore extends Node -const SAVE_FORMAT_VERSION := 7 # registry schema_version:v7=锻造工坊域(迭代 23 T5——meta 新域 forge_routes〔六路线等级 levels+直购解锁清单 unlocked+当前武器/甲选中标记 weapon/armor;无特效域——裁 6 满级特效本期不做〕,旧档缺键由 _normalize 按默认补齐=初始持有态〔sword/light 在档余四锁、选中=初始路线〕,v6→v7 空迁移=缺键补齐模式——v3→v4 先例);v6=生涯终身计数域(迭代 18 卡④——meta 两新域 adventure_total〔冒险总局数,开局即计含放弃与失败〕/adventure_cleared〔通关局数,三关全通才计 1——判定字段 summary.cleared〕,旧档缺键由 _normalize 按默认补零,收束自增唯一入账=apply_adventure_summary);v5=天赋树域(迭代 12 T9——meta 三新域 tree_nodes〔node_id→已购等级〕/fork_sides〔fork_group→a|b〕/migration_note〔三体系迁移补偿注记〕——M-4 迭代 12 批次二;需求卡片「v3→v4」系同调批未落时行文,v4 已被同调批占用顺延 v5 披露);v4=同调批扩域(meta 三新域 boss_kill_count/attunement_equipped/attune_refresh_level——M-4 迭代 11 第①批 T2;断点充能余量随 T6 接线,旧档缺键 = 合法空态);v3=断点附随件扩列+摘要 keystone_drops(M-3 迭代 10 奖励重构);v2=断点域出生(M-3 迭代 8 卡①);v1=首版;高版本拒读 owner=存档序列化 +const SAVE_FORMAT_VERSION := 7 # registry schema_version:v7=锻造工坊域(meta 新域 forge_routes〔六路线等级 levels+直购解锁清单 unlocked+当前武器/甲选中标记 weapon/armor;无特效域〕,旧档缺键由 _normalize 按默认补齐=初始持有态〔sword/light 在档余四锁、选中=初始路线〕,v6→v7 空迁移=缺键补齐模式);v6=生涯终身计数域(meta 两新域 adventure_total〔冒险总局数,开局即计含放弃与失败〕/adventure_cleared〔通关局数,三关全通才计 1——判定字段 summary.cleared〕,旧档缺键由 _normalize 按默认补零,收束自增唯一入账=apply_adventure_summary);v5=天赋树域(meta 三新域 tree_nodes〔node_id→已购等级〕/fork_sides〔fork_group→a|b〕/migration_note〔三体系迁移补偿注记〕);v4=同调位域(meta 三新域 boss_kill_count/attunement_equipped/attune_refresh_level——旧档缺键 = 合法空态);v3=断点附随件扩列+摘要 keystone_drops;v2=断点域出生;v1=首版;高版本拒读 owner=存档序列化 const SUMMARY_CAP := 10 # 最近冒险摘要保留条数(最新在前) -const TREE_STRUCT_VERSION := 2 # 树结构版本标记(迭代 21 T5——12 节点 v0.8 结构;加载检测缺失 +const TREE_STRUCT_VERSION := 2 # 树结构版本标记(12 节点 v0.8 结构;加载检测缺失 # 或更低 = 换代前结构 → 树域破坏性废弃重置〔契约 4:禁迁移禁折算〕) var _path: String # 存档文件路径(默认 user://save.json;冒烟注入隔离路径) @@ -30,14 +30,14 @@ func _init(path: String = "user://save.json") -> void: register_migration(6, _migrate_v6_v7) -# autoload 生命周期(迭代 27 T1 裁点①——SaveManager 升格跨场景持有者,RngService 先例: -# 类名加 Core 后缀、autoload 占净名;读盘挂 _ready=autoload 先于主场景就绪,时序与旧 -# main._ready 读盘等价)。独立 .new() 实例(单测/工具)不入树零 _ready,读盘仍由调用方显式触发。 +# autoload 生命周期(SaveManager 为跨场景持有者,仿 RngService 先例: +# 类名加 Core 后缀、autoload 占净名;读盘挂 _ready=autoload 先于主场景就绪)。独立 +# .new() 实例(单测/工具)不入树零 _ready,读盘仍由调用方显式触发。 func _ready() -> void: load_from_disk() -# 原地重置(迭代 27 T1——探针隔离面,沿 RngService.set_master_seed 单例原地重置先例: +# 原地重置(探针隔离面,仿 RngService.set_master_seed 单例原地重置: # 换路径+回默认数据+重读盘;对象引用恒定,MetaProgression 持有的 save 引用零失效) func attach_path(path: String) -> void: _path = path @@ -54,25 +54,25 @@ func _migrate_v1_v2(data: Dictionary) -> Dictionary: return data -# v2→v3:断点附随件扩列(迭代 10 奖励重构批——bonus_taken/bonus_pending/bonus_result/ -# keystone_drops + bonus.ap 轴)与摘要 additive 键 keystone_drops——旧档缺键〔bonus_aux_carry 键随迭代 22 T5 替换子交互拆除退役〕 +# v2→v3:断点附随件扩列(bonus_taken/bonus_pending/bonus_result/ +# keystone_drops + bonus.ap 轴)与摘要 additive 键 keystone_drops——旧档缺键 # = 合法空态(读取方 .get 兜底),无结构迁移体;版本号推进仅为 schema_version 对齐 func _migrate_v2_v3(data: Dictionary) -> Dictionary: data["version"] = SAVE_FORMAT_VERSION return data -# v3→v4:同调批扩域(迭代 11 第①批 T2——meta 三新域 boss_kill_count/attunement_equipped/ +# v3→v4:同调位域(meta 三新域 boss_kill_count/attunement_equipped/ # attune_refresh_level,旧档缺键由 _normalize 按默认补齐,无结构迁移体;版本号推进仅为 -# schema_version 对齐——v2→v3 先例) +# schema_version 对齐) func _migrate_v3_v4(data: Dictionary) -> Dictionary: data["version"] = SAVE_FORMAT_VERSION return data -# v4→v5:天赋树域(迭代 12 T9 建域——meta 三新域 tree_nodes/fork_sides/migration_note,缺键默认 -# 补齐;迭代 21 T5 换代:原「三体系迁移」映射体随 migrate_tree 一并删除——开发阶段破坏性废弃 -# 〔Q3 用户裁〕,换代前结构由 _normalize 的 tree_struct 标记检测废弃重置,本函数只剩缺键补齐)。 +# v4→v5:天赋树域(meta 三新域 tree_nodes/fork_sides/migration_note,缺键默认 +# 补齐;开发阶段破坏性废弃口径:换代前结构由 _normalize 的 tree_struct 标记检测废弃重置, +# 本函数只做缺键补齐)。 func _migrate_v4_v5(data: Dictionary) -> Dictionary: var meta: Dictionary[Variant, Variant] = data.get("meta", {}) as Dictionary if not meta.has("tree_nodes"): @@ -83,17 +83,17 @@ func _migrate_v4_v5(data: Dictionary) -> Dictionary: return data -# v5→v6:生涯终身计数域(迭代 18 卡④——meta 两新域 adventure_total/adventure_cleared,旧档缺键 -# 由 _normalize 按默认补零,无结构迁移体;版本号推进仅为 schema_version 对齐——v3→v4 先例。 +# v5→v6:生涯终身计数域(meta 两新域 adventure_total/adventure_cleared,旧档缺键 +# 由 _normalize 按默认补零,无结构迁移体;版本号推进仅为 schema_version 对齐。 # 幂等性:重复迁移只覆写 version,既有值零改动;加载后 _normalize 补齐缺省——旧档可载可玩) func _migrate_v5_v6(data: Dictionary) -> Dictionary: data["version"] = SAVE_FORMAT_VERSION return data -# v6→v7:锻造工坊域(迭代 23 T5——meta 新域 forge_routes,旧档缺键由 _normalize 按默认补齐= +# v6→v7:锻造工坊域(meta 新域 forge_routes,旧档缺键由 _normalize 按默认补齐= # 初始持有态〔开发阶段无迁移禁折算——契约 4〕,无结构迁移体;版本号推进仅为 schema_version 对齐 -# ——v3→v4 先例。幂等性:重复迁移只覆写 version,既有值零改动;加载后 _normalize 补齐缺省——旧档可载可玩) +# 幂等性:重复迁移只覆写 version,既有值零改动;加载后 _normalize 补齐缺省——旧档可载可玩) func _migrate_v6_v7(data: Dictionary) -> Dictionary: data["version"] = SAVE_FORMAT_VERSION return data @@ -112,27 +112,27 @@ func _default_data() -> Dictionary[String, Variant]: "boss_kill_count": 0, "attunement_equipped": [], "attune_refresh_level": 0, - "tree_nodes": {}, # 天赋树已购等级(node_id→int——迭代 12 T9 建域) - "fork_sides": {}, # Fork 激活态(fork_group→"a"|"b"——一节点双态切换承载,迭代 21 收编语义) - "tree_struct": TREE_STRUCT_VERSION, # 树结构版本标记(迭代 21 T5——缺失=换代前结构,加载废弃重置) + "tree_nodes": {}, # 天赋树已购等级(node_id→int) + "fork_sides": {}, # Fork 激活态(fork_group→"a"|"b"——一节点双态切换承载) + "tree_struct": TREE_STRUCT_VERSION, # 树结构版本标记(缺失=换代前结构,加载废弃重置) "recent_summaries": [], "first_adventure_done": false, - "adventure_total": 0, # 生涯终身计数·冒险总局数(迭代 18 卡④——开局即计含放弃与失败,收束唯一入账) + "adventure_total": 0, # 生涯终身计数·冒险总局数(开局即计含放弃与失败,收束唯一入账) "adventure_cleared": 0, # 生涯终身计数·通关局数(三关全通才计 1——判定字段 summary.cleared) - "vision_used": 0, # 生涯终身计数·真视类工具累计使用次数(迭代 22 T2——信标网络解锁行为条件; - # 受理成功唯一计数点=battle 层经冒险层聚合、收束入账;缺键补零不升版本——迭代 21 先例) - "forge_routes": { # 锻造工坊域(迭代 23 T5——六路线等级+直购解锁清单+当前选中标记;无特效域) + "vision_used": 0, # 生涯终身计数·真视类工具累计使用次数(信标网络解锁行为条件; + # 受理成功唯一计数点=battle 层经冒险层聚合、收束入账;缺键补零不升版本) + "forge_routes": { # 锻造工坊域(六路线等级+直购解锁清单+当前选中标记;无特效域) "levels": {"sword": 0, "spear": 0, "staff": 0, "light": 0, "heavy": 0, "ward": 0}, "unlocked": [], # 直购解锁路线 id 清单(初始持有与练满前一档=派生解锁不落档) "weapon": "sword", # 当前选中武器路线(初始持有=sword) "armor": "light", # 当前选中甲路线(初始持有=light) }, }, - "breakpoint": {}, # 冒险断点快照(空 = 无断点合法态——「继续上局」隐藏;迭代 8 卡①) + "breakpoint": {}, # 冒险断点快照(空 = 无断点合法态——「继续上局」隐藏) } -# ---- 首次冒险布尔位(关卡节点图生成 v0.4——唯一新增存档字段,M-3 迭代 5 T5)---- +# ---- 首次冒险布尔位(关卡节点图生成 v0.4)---- # false = 首次脚本模式(全关零抽签取池内模板 0=现行固定图);置位只在冒险收束挂点(MetaProgression.settle_adventure)。 # 老档迁移:缺字段 = 该档已有游玩史 → true(不重放教学脚本)。 @@ -243,7 +243,7 @@ func boss_first_kill_marked(level_index: int) -> bool: return _data["meta"]["boss_first_kill"].has(str(level_index)) -# ---- 同调位账本域(迭代 11 第①批 T2——里程碑谓词表计数源 + 装配关系 + Y 升级态)---- +# ---- 同调位账本域(里程碑谓词表计数源 + 装配关系 + Y 升级态)---- # Boss 击杀总数(含重复——底稿裁决 4 计数源;收束入账 = apply_adventure_summary 逐通关关次 +1, # Boss 恒唯一终点故 levels_cleared 即本次冒险 Boss 击杀数) @@ -251,7 +251,7 @@ func boss_kill_count() -> int: return int(_data["meta"].get("boss_kill_count", 0)) -# ---- 生涯终身计数域(迭代 18 卡④——跨局汇总页数据源;只读面经访问器, +# ---- 生涯终身计数域(跨局汇总页数据源;只读面经访问器, # 写入唯一经 apply_adventure_summary 收束口,禁第二写入点)---- # 冒险总局数(口径=开局即计:三结局 completed/failed/abandoned 同经收束恰计一次,含放弃与失败) @@ -265,7 +265,7 @@ func adventure_cleared() -> int: return int(_data["meta"].get("adventure_cleared", 0)) -# 真视类工具累计使用次数(迭代 22 T2——信标网络解锁行为条件;写入唯一经 add_vision_used +# 真视类工具累计使用次数(信标网络解锁行为条件;写入唯一经 add_vision_used # 冒险收束聚合入账,受理计数点=battle 层经冒险层聚合) func vision_used() -> int: return int(_data["meta"].get("vision_used", 0)) @@ -275,7 +275,7 @@ func add_vision_used(n: int) -> void: _data["meta"]["vision_used"] = maxi(0, vision_used() + maxi(0, n)) -# ---- 天赋树域(迭代 12 T9——MetaProgression 树段读写面)---- +# ---- 天赋树域(MetaProgression 树段读写面)---- func tree_nodes() -> Dictionary: return (_data["meta"].get("tree_nodes", {}) as Dictionary).duplicate() @@ -305,7 +305,7 @@ func set_fork_side(group: String, side: String) -> void: _data["meta"]["fork_sides"] = fs -# ---- 锻造工坊域 forge_routes(迭代 23 T5——MetaProgression 锻造写口读写面;无特效域)---- +# ---- 锻造工坊域 forge_routes(MetaProgression 锻造写口读写面;无特效域)---- # 解锁态不落档(派生):初始持有=表 initial_owned、练满前一档=levels[prereq]≥cap——判定单点在 # MetaProgression.forge_route_unlocked(读表+读档);本类只承载直购清单 unlocked 与选中标记。 # 域结构:{levels:{六路线 id→等级}, unlocked:[直购路线 id], weapon:当前武器路线 id, armor:当前甲路线 id} @@ -365,7 +365,7 @@ func set_forge_armor(route_id: String) -> void: # 装配关系(同调目录 item_id 有序数组——装配序即呈现序;跨冒险持久,冒险中途不可换装〔底稿 §8.5〕)。 -# 局外进度事实(元进度域同族),非契约 2 反面清单的「局内道具库存」——存档序列化.md 契约 2 随批注记。 +# 局外进度事实(元进度域同族),非契约 2 反面清单的「局内道具库存」——口径见 存档序列化.md 契约 2。 func attunement_equipped() -> Array: return (_data["meta"].get("attunement_equipped", []) as Array).duplicate() @@ -377,7 +377,7 @@ func set_attunement_equipped(item_ids: Array) -> void: _data["meta"]["attunement_equipped"] = out -# Y 刷新升级购买等级(0 = 未购 → 每冒险刷新次数 0;等级行值归营地升级行族——T4 接线) +# Y 刷新升级购买等级(0 = 未购 → 每冒险刷新次数 0;等级行值归营地升级行族) func attune_refresh_level() -> int: return int(_data["meta"].get("attune_refresh_level", 0)) @@ -393,10 +393,10 @@ func recent_summaries() -> Array: # 域更新原语(正式冒险收束唯一入账口——组合根经本函数入账,禁直改内部结构): -# 钥石入账(summary.keystone_total——迭代 10 起逐杀掉落已在冒险内计入,boss_drops 参数降级为 +# 钥石入账(summary.keystone_total——逐杀掉落已在冒险内计入,boss_drops 参数为 # 摘要归档副本不重复入账)+ 逐通关关次 clear_count +1 与 Boss 首杀标记 + Boss 击杀总数累计 -# (迭代 11 第①批 T2——同调位里程碑计数源)+ 摘要头部插入(cap 10,最新在前,元素附 -# keystone_drops 副本——复盘可归因)+ 生涯终身计数自增(迭代 18 卡④——总局数开局即计: +# (同调位里程碑计数源)+ 摘要头部插入(cap 10,最新在前,元素附 +# keystone_drops 副本——复盘可归因)+ 生涯终身计数自增(总局数开局即计: # 三结局同经本口恰计一次;通关局数按 summary.cleared 判定三关全通才计 1。终身计数写入 # 单口=本函数,禁第二写入点)。 func apply_adventure_summary(summary: Dictionary, boss_drops: Array = []) -> void: @@ -409,7 +409,7 @@ func apply_adventure_summary(summary: Dictionary, boss_drops: Array = []) -> voi var key := str(li) _data["meta"]["level_clear_counts"][key] = int(_data["meta"]["level_clear_counts"].get(key, 0)) + 1 _data["meta"]["boss_first_kill"][key] = true - _data["meta"]["boss_kill_count"] = boss_kill_count() + cleared # 迭代 11 T2——Boss 恒唯一终点:levels_cleared 即本次冒险 Boss 击杀数(含重复) + _data["meta"]["boss_kill_count"] = boss_kill_count() + cleared # Boss 恒唯一终点:levels_cleared 即本次冒险 Boss 击杀数(含重复) var entry: Dictionary[Variant, Variant] = summary.duplicate(true) entry["boss_drops"] = boss_drops.duplicate(true) var arr: Array[Variant] = _data["meta"]["recent_summaries"] @@ -418,7 +418,7 @@ func apply_adventure_summary(summary: Dictionary, boss_drops: Array = []) -> voi arr.pop_back() -# ---- 冒险断点域(迭代 8 卡①——停点粒度续玩快照;内容装配归 AdventureRunner,本类照单承载)---- +# ---- 冒险断点域(停点粒度续玩快照;内容装配归 AdventureRunner,本类照单承载)---- # 空字典 = 无断点合法态。值拷贝进出(禁碰内部结构契约同款)——快照写入后调用方再改不渗入存档态。 func set_breakpoint(bp: Dictionary) -> void: @@ -452,7 +452,7 @@ func _corrupt_fallback(reason: String) -> bool: # 迁移后/低版本档字段补齐 + 退役域清退(改版不弃档:缺新域按默认补齐,既有值保留; # 退役域按默认模型键集白名单收口——换代退役键〔forge_levels/migration_note 等树域旧件〕不流入 -# 内存不回写盘,开发阶段破坏性废弃口径〔迭代 21 T5,Q3 用户裁:禁迁移禁折算〕)。 +# 内存不回写盘,开发阶段破坏性废弃口径〔禁迁移禁折算〕)。 # 树结构检查先于缺键补齐:换代前结构(tree_struct 标记缺失或更低)→ 树域废弃重置—— # tree_nodes/fork_sides 清空、钥石余额等他域零触碰(V16 断言面)。 func _normalize(data: Dictionary) -> Dictionary[String, Variant]: diff --git a/game/core/settlement/aura_segment.gd b/game/core/settlement/aura_segment.gd index add4aca7..301457c0 100644 --- a/game/core/settlement/aura_segment.gd +++ b/game/core/settlement/aura_segment.gd @@ -1,6 +1,6 @@ class_name AuraSegment extends RefCounted -# ② 增益/减益段 Segment(迭代 27 T2——P1-1 结算巨函数拆段;段边界=审计五段〔裁点③甲〕)。 +# ② 增益/减益段 Segment(P1-1 结算巨函数拆段;段边界=审计五段〔裁点③甲〕)。 # 职责:续存实例组合行(本结算新授予的已在授予段逐 grant 出行——增益状态 义务⑦)。 # 行发射归宿主编排器(oc)——零算法改动(🔴 零行为变更契约)。 diff --git a/game/core/settlement/combat_segment.gd b/game/core/settlement/combat_segment.gd index ff80ef2d..d43879a1 100644 --- a/game/core/settlement/combat_segment.gd +++ b/game/core/settlement/combat_segment.gd @@ -1,9 +1,9 @@ class_name CombatSegment extends RefCounted -# ③ 战斗段 Segment(迭代 27 T2——P1-1 结算巨函数拆段;段边界=审计五段〔裁点③甲〕)。 +# ③ 战斗段 Segment(P1-1 结算巨函数拆段;段边界=审计五段〔裁点③甲〕)。 # 职责:案C 闸复位 + 本轮扫雷事实推导(执拗 streak/连珠矢段数)+ 蓄力层注入 + 主角先手 # (含连珠矢分段开单)+ 敌方行动兑现 + 地图伤害账殿后(补提交统一结账)。 -# 调用序:主角先手 → 逐敌还手 → 地图伤害账殿后〔案C 2026-10-06 用户裁〕;hero hp=0 短路。 +# 调用序:主角先手 → 逐敌还手 → 地图伤害账殿后〔案C〕;hero hp=0 短路。 # 行发射/开单/兑付原语仍归宿主编排器(oc)——本函数体为原编排器 _combat_segment 逐字搬运 # (🔴 零行为变更契约)。 @@ -16,7 +16,7 @@ func _init(host) -> void: func run(ri: int) -> void: oc._defer_board_damage = false # 案C 闸复位——战斗段起开单即入队(主角/敌方/补提交的地图单按开单序统一结账) - # 本轮扫雷事实推导(迭代 12 T4——执拗 streak/连珠矢段数共用取数面):本轮 safe 事件数= + # 本轮扫雷事实推导(执拗 streak/连珠矢段数共用取数面):本轮 safe 事件数= # streak;踩雷即清零(mine_hit 监听同口——执拗「踩雷清零」承载)。攻击在战斗段=授予段后 # 同一次 _settle 内,facts 已定。 var round_safe := 0 @@ -30,14 +30,14 @@ func run(ri: int) -> void: # 蓄力层注入(内容数据驱动扩展批 T3——整备军备「每层下轮首段 +1」/厚积薄发满层 spike/铁壁整备 # 减伤——三件 fact charge_layers 同读 action_economy;battle 域每轮刷新) oc._damage.charge_layers = oc.action_economy.charge_layers - # ⓪ 主角先手攻击(基础攻击恒存在——2026-09-11 用户裁决;先于敌方行动。案C 后授予段不再产出伤害, + # ⓪ 主角先手攻击(基础攻击恒存在;先于敌方行动。案C:授予段不再产出伤害, # 主角进入战斗段时恒存活——先手必兑,除非场上无敌)。 - # 单分量伤害构成(2026-09-19 充能退役批·用户拍板):主角攻击 = 唯一基础分量(atk,吃掷点含暴击; - # 类型 = 主角 attack_type 表值——2026-09-18 营地扩展前置批:量与类型抽象分离;查甲效矩阵对应行取克制修正)。 + # 单分量伤害构成:主角攻击 = 唯一基础分量(atk,吃掷点含暴击; + # 类型 = 主角 attack_type 表值(量与类型抽象分离);查甲效矩阵对应行取克制修正)。 # 原"基础 + 穿刺/魔法充能三分量"模型随充能系统整体退役——克制策略归冒险前配置(营地换型 / 未来冒险前参数面), # 局内不再有挖掘攒弹药的第二伤害供给。attack_up 增益经 hero_offense 池乘攻击合计(见池乘区注记)。 - # 护甲等级掷点批(2026-09-16):基础分量吃掷点判定(含暴击);棋盘来源伤害不掷不折; - # 任何伤害落地 ≥ damage_floor(全局 max(1,·)——2026-09-20 用户拍板扩全来源,下限在控制器管线单点收口)。 + # 护甲等级掷点:基础分量吃掷点判定(含暴击);棋盘来源伤害不掷不折; + # 任何伤害落地 ≥ damage_floor(全局 max(1,·) 适用所有来源,下限在控制器管线单点收口)。 var hero_alive: bool = int(oc._enemy_system.hero_unit().get("hp", 0)) > 0 var hero_target = oc._enemy_system.default_target() if hero_alive and hero_target != null: @@ -50,7 +50,7 @@ func run(ri: int) -> void: for h in oc._hits_of(ht.context.get("fx_attack_hits", []) as Array, "attack_segments"): var segments := mini(int(h.get("cap", 2)), oc._damage.dig_streak / maxi(1, int(h.get("divisor", 3)))) for s in segments: - # 迭代 20 T9——source_class 中性名(旧件名 feat_chain_arrows 随连珠矢退役;attack_segments 兑付通道保留泛用面) + # source_class 用中性名;attack_segments 兑付通道保留泛用面 var ct := oc._damage.open_ticket(DamageController.KIND_BOARD_TYPED, "fx_streak_segments", "连击分段", "board", int(h.get("value", 0)), DamageController.TARGET_FRONT_ALIVE, ri, oc.minesweeper.hero_pos(), "pierce") @@ -66,8 +66,7 @@ func run(ri: int) -> void: oc._fatal("敌实例待发动作悬空: %s" % skill_id) continue if String(srow.type) == "buff" or String(srow.type) == "debuff": - # 增益/妨害技(新效应词汇批 2026-09-19)= 0 伤害施放行:不掷不折;状态授予即数值兑现,技能冷却与增益持续两计时器分账。 - # (原"本轮喂的伏击逢施放拍不兑现"读怪奖励随伏击退役一并作废——2026-09-20 八型批) + # 增益/妨害技 = 0 伤害施放行:不掷不折;状态授予即数值兑现,技能冷却与增益持续两计时器分账。 # 落点由状态行 target_side 路由(buff → 敌方侧 / debuff → 主角侧——容器零改动,proposal-status-vocabulary §1)。 var dur: int = int(srow.get("buff_duration", 1)) oc._status_effects.apply_effect(String(srow.buff_ref), {"source_class": "enemy_action", "origin_cell": Vector2i(-1, -1), "round_index": ri}, dur) @@ -87,7 +86,7 @@ func run(ri: int) -> void: et["source_unit"] = u et["context"] = {"skill_id": skill_id, "baseline": baseline} oc._damage.submit(et) - # 地图伤害兑付(案C 2026-10-06 用户裁——战斗段末:怪物还手后按授予段事件序补提交统一结账; + # 地图伤害兑付(案C:战斗段末——怪物还手后按授予段事件序补提交统一结账; # 主角死于怪物 → 地图账不兑,逐单留「未生效」行不作废静默——没生效也要留痕口径; # 补提交后若地图直伤反杀主角,控制器 _halted 作废余单——战斗已败,胜负归判定段) if int(oc._enemy_system.hero_unit().get("hp", 0)) <= 0: diff --git a/game/core/settlement/decay_segment.gd b/game/core/settlement/decay_segment.gd index c54e13d2..ce942ea6 100644 --- a/game/core/settlement/decay_segment.gd +++ b/game/core/settlement/decay_segment.gd @@ -1,6 +1,6 @@ class_name DecaySegment extends RefCounted -# ④ 衰减段 Segment(迭代 27 T2——P1-1 结算巨函数拆段;段边界=审计五段〔裁点③甲〕)。 +# ④ 衰减段 Segment(P1-1 结算巨函数拆段;段边界=审计五段〔裁点③甲〕)。 # 职责:状态衰减恰一次恒执行含末轮——先兑付后衰减。行发射归宿主编排器(oc)—— # 零算法改动(🔴 零行为变更契约)。 diff --git a/game/core/settlement/grant_segment.gd b/game/core/settlement/grant_segment.gd index 8339f555..fe6a4d9a 100644 --- a/game/core/settlement/grant_segment.gd +++ b/game/core/settlement/grant_segment.gd @@ -1,6 +1,6 @@ class_name GrantSegment extends RefCounted -# ① 授予段 Segment(迭代 27 T2——P1-1 结算巨函数拆段;段边界=审计五段〔裁点③甲〕)。 +# ① 授予段 Segment(P1-1 结算巨函数拆段;段边界=审计五段〔裁点③甲〕)。 # 职责:结算队列(开格/封印判定/清图)→ 极性路由逐批兑付 + 封印判/军规开单 + round_end 施加 + # 转存收口 + 揭示兑付 + 段界结账。行发射/开单/兑付原语仍归宿主编排器(oc)—— # 本段只搬运时序,零算法改动(🔴 零行为变更契约:同种子完整局输出逐位一致)。 @@ -17,9 +17,9 @@ func _init(host) -> void: func run(ri: int) -> void: # ① 授予段:结算队列(开格/封印判定/清图)→ 极性路由逐批兑付(伤害形态单据暂存——见 _submit 案C 闸)。 - # 判定基线 = 轮末在场封印(发射面已过滤——被挖开的封印已随挖掘擦除零兑付,封印不可逆批 2026-09-19; + # 判定基线 = 轮末在场封印(发射面已过滤——被挖开的封印已随挖掘擦除零兑付; # 开格事实不可撤)。 - oc._defer_board_damage = true # 案C:授予段伤害单据只暂存不结账(2026-10-06 用户裁——兑付时点=战斗段末) + oc._defer_board_damage = true # 案C:授予段伤害单据只暂存不结账(兑付时点=战斗段末) for evt in oc._facts_reveals: if not bool(evt.get("resource", false)): continue # 封锁格(initial 通道)恒无资源——不入账(战斗结算 义务②) @@ -28,13 +28,13 @@ func run(ri: int) -> void: continue if evt.kind == "safe": if bool(evt.get("dug_under_seal", false)): - # 封印不可逆四情况④(2026-09-19 用户拍板):插安全格再挖开 = 零惩罚零奖励——正向兑付 + # 封印不可逆四情况④:插安全格再挖开 = 零惩罚零奖励——正向兑付 # 作废(归因行在案);标空判定已随封印擦除自然缺席(被挖的封印不在轮末在场基线)。 oc._emit_row("reward_ineffective", "safe_cell", evt.cell, ri, "奖励作废(封印格直接挖开——零惩罚零奖励)", 0, {}, "") continue # dig_reveal 发射+施加(内容数据驱动扩展批 T3——桶序固定承载等价: # 乘区收集 → 正向兑付 → 计数器 → 追加产出(深挖)→ 奥术矢。 - # 迭代 20 T1——payload 扩三事实:is_edge_cell〔边陲矿工〕/is_blank_zero〔跳格采掘〕/ + # payload 携三事实:is_edge_cell〔边陲矿工〕/is_blank_zero〔跳格采掘〕/ # new_resource_type〔地质学家——快照 cell_type 首见判定,见后集登记〕) var board_b: BoardData = oc.minesweeper.current_board() var snap_pre = evt.get("reward_snapshot") @@ -64,7 +64,7 @@ func run(ri: int) -> void: for h in dr_hits: if String(h.get("kind", "")) == "counter_add": _apply_counter_hit(h) - # 揭示效果入队(迭代 20 T1——地质学家/跳格采掘 reveal_tiles 订阅面;授予段末 + # 揭示效果入队(地质学家/跳格采掘 reveal_tiles 订阅面;授予段末 # _flush_pending_reveals 统一掷格兑付) if not oc._hits_of(dr_hits, "reveal_tiles").is_empty(): oc._fx_enqueue_reveal() @@ -85,7 +85,7 @@ func run(ri: int) -> void: # 标中不发(封印已随挖掘擦除、不入轮末判定基线)。 # mine_hit 发射+施加(内容数据驱动扩展批 T3——桶序固定承载等价: # 减半收集 → 负向兑付〔带减半系数〕→ 反打开单 → 连击清零计数器。 - # 迭代 20 T1——发射前移+payload 扩 dug_under_seal〔破封一击〕;新增施加面: + # 发射时点前移并扩 payload dug_under_seal〔破封一击〕;施加面: # damage_reduce〔安全帽耗层减伤——value_counter 层值,一次清零〕/ heal〔血蜜〕/ # blast_scaled〔陷阱爆发——雷伤×倍率全体敌〕/ bonus_delta〔血税〕/ reveal_tiles〔见血开窍〕) var mine_power := int((snap as Dictionary).get("power", 0)) @@ -129,7 +129,7 @@ func run(ri: int) -> void: int(h.get("value", 0)), DamageController.TARGET_ALL_ALIVE, ri, evt.cell, "", 0, "", {}) oc._submit(nct, false) # 地形变异 兑付段(授予段尾——触发枚举 on_open:挖开即伤、chain 通道同口径;伤害单据案C 暂存到 - # 战斗段末兑付〔2026-10-06 用户裁〕;信息型 hide_number 不进结算——呈现层读取,见 board_view 数字遮蔽; + # 战斗段末兑付〔案C〕;信息型 hide_number 不进结算——呈现层读取,见 board_view 数字遮蔽; # 危险格恒无变异——布置段排除,双层叠罚不存在;封印格直挖照吃变异伤害——地形后果同 mine_hit 口径, # 非奖励不作废;吞噬流资源兑付〔荆棘编织/地脉补偿〕中伤害形态行同样经案C闸暂存,非伤害形态照常当场) for evt in oc._facts_reveals: @@ -138,8 +138,8 @@ func run(ri: int) -> void: var vrow: Dictionary[Variant, Variant] = oc.db.variation.row_by_id(String(vid)) if String(vrow.get("effect", "")) != "flat_damage": continue # 触发词表按 effect 路由:flat_damage=on_open 兑现;hide_number/on_open 外组合 = 数据行新词表未接线(显式忽略面) - # 地形变异伤害单据(伤害管线单据化批 2026-09-24)——无类型必中,下限保底在控制器管线内 - # 迭代 20 T1——damage_taken 发射前移(单据开立前):damage_reduce〔背水——hp_ratio when + # 地形变异伤害单据——无类型必中,下限保底在控制器管线内 + # damage_taken 发射在单据开立前:damage_reduce〔背水——hp_ratio when # 面〕先收集再按减后值开单;counter_add〔保险丝/石肤〕+ ac_bonus〔石肤〕照常施加; # grant_material〔荆棘/地脉〕移到单据提交后(与迁移前兑付值序一致——收益不因减伤变化) var dt_amount := int(vrow.get("effect_value", 0)) @@ -162,7 +162,7 @@ func run(ri: int) -> void: _apply_material_hit(h, evt.cell, ri) for evt in oc._facts_seals: _judge_seal(evt, ri) - # 战封印军规开单段(迭代 12 T3 封印流——seal_judged 批后统一开单:轮末每面封印命中对最前存活敌 + # 战封印军规开单段(封印流:seal_judged 批后统一开单:轮末每面封印命中对最前存活敌 # 结算 board_typed 必中伤害〔复用零新配方;「封印所在巢穴敌」简化为 default_target 最前存活敌—— # 台账披露待追认〕;完美布防=本轮封印批全中(hit>0 且 miss==0)时封印伤 ×mult——全对推理奖励)。 # 伤害单据案C 暂存战斗段末兑付。 @@ -205,7 +205,7 @@ func run(ri: int) -> void: var mg_layers := oc._fx.counter(String(h.get("per", ""))) var mg_total := int(h.get("value", 0)) * mg_layers if mg_total > 0: - # 迭代 20 T9——source_class 中性名(旧件名 feat_magma_body 随熔火之躯退役;per-counter 反打通道保留泛用面) + # source_class 用中性名;per-counter 反打通道保留泛用面 var mg_t := oc._damage.open_ticket(DamageController.KIND_BOARD_BLAST, "fx_blast_counter", "积层反噬 ×%d" % mg_layers, "board", mg_total, DamageController.TARGET_ALL_ALIVE, ri, oc.minesweeper.hero_pos(), "", 0, "", {}) @@ -213,7 +213,7 @@ func run(ri: int) -> void: for h in re_fx: if String(h.get("kind", "")) == "counter_add": _apply_counter_hit(h) - # 迭代 20 T1——round_end 新施加面:grant_gp〔爆破会计/收盘——escrow 战斗域缓冲,随 gp_dropped 上抛〕/ + # round_end 施加面:grant_gp〔爆破会计/收盘——escrow 战斗域缓冲,随 gp_dropped 上抛〕/ # grant_ap mode:queue〔封印回响——返 1 AP 下轮,queue_ap_delta 通道与轮始加成同面〕 for h in re_fx: if String(h.get("kind", "")) == "grant_gp": @@ -228,11 +228,11 @@ func run(ri: int) -> void: rap_pct if rap_pct > 0 else 100) if oc._facts_path == "cleared": oc._grant_clear_reward(ri) - oc._flush_pending_reveals(ri) # 迭代 20 T1——揭示效果兑付(授予段末统一掷格,防轮 facts 迭代重入) + oc._flush_pending_reveals(ri) # 揭示效果兑付(授予段末统一掷格,防轮 facts 迭代重入) oc._damage.flush() # 授予段界结账(案C 后本段伤害单据全数暂存,此处对空队 no-op——保留作防御性段界) -# 封印判定(迭代 12 T3 封印流本体随段迁入——原编排器 _judge_seal 逐字搬运,仅宿主引用加前缀; +# 封印判定(封印流本体——自编排器 _judge_seal 迁入,宿主引用加前缀; # 唯一调用面=本段 run 的 facts_seals 循环)。 func _judge_seal(evt: Dictionary, ri: int) -> void: var cell: Vector2i = evt.cell @@ -247,14 +247,14 @@ func _judge_seal(evt: Dictionary, ri: int) -> void: "terrain_kind": oc._harmful_adjacent(cell)}) # 标中殉爆(迭代 11 同调批 T5 → 内容数据驱动扩展批 T4:订阅施加——行 triggers open_ticket # channel blast value_from magnitude;每标中一面封印全体存活敌吃 N 群伤,无类型走 blast 通道。 - # 迭代 20 T1——封印爆裂〔迁入专长〕同面消费:行 triggers open_ticket channel blast) + # 封印爆裂〔专长〕同面消费:行 triggers open_ticket channel blast) for h in oc._hits_of(fh_hits, "open_ticket"): if String(h.get("channel", "")) != "blast": continue var fbt := oc._damage.open_ticket(DamageController.KIND_BOARD_BLAST, "feat_seal_burst", "封印爆裂", "board", int(h.get("value", 0)), DamageController.TARGET_ALL_ALIVE, ri, cell, "", 0, "highlight", {}) oc._submit(fbt, false) - # 迭代 20 T1——标中新施加面:counter_add〔血税 标中+1 攻——bonus_delta atk 轴〕/ + # 标中施加面:counter_add〔血税 标中+1 攻——bonus_delta atk 轴〕/ # ac_bonus〔封印桩 本轮 AC+N〕/ preview_area〔示警烟火 3×3 资源类型预告〕/ # remove_mines〔封印匠 每第 3 次该危险格中立移除——mod_eq 闸在行 when〕。 # (净化工兵 rewrite_board 分支随老 27 件退役摘除——效果类型同批除名,T1 落法 commit 留痕) @@ -282,7 +282,7 @@ func _judge_seal(evt: Dictionary, ri: int) -> void: if oc.treasure_inventory != null and not types.is_empty(): oc.treasure_inventory.apply_overlay("reward_preview", board_p.neighbors8(cell)) oc._emit_row("fx_preview_area", "", cell, ri, "示警烟火·周围资源类型", 0, {"types": types}, "") - # 雷区图谱(迭代 12 T3 封印流——标中雷额外获得一份格面资源:封印开始产出对标开格; + # 雷区图谱(封印流——标中雷额外获得一份格面资源:封印开始产出对标开格; # 复用 grant 单点,额外兑付走同一 _grant_routed 正向路由) for h in fh_hits: if String(h.get("kind", "")) == "grant_material": @@ -300,7 +300,7 @@ func _judge_seal(evt: Dictionary, ri: int) -> void: if oc._perfect_hit_false == 1: hl = "perfect_broken" # 本板完美谓词已破的归因锚 oc._emit_row("seal_miss", "seal_miss", cell, ri, "封印未中", 0, {}, hl) - # 危险直觉·守挂点(迭代 21 T3——seal_missed 发射:契约 12 触发主语=「当回合发生的标错 + # 危险直觉·守挂点(seal_missed 发射:契约 12 触发主语=「当回合发生的标错 # 动作」——去重闸=新旧标错判别器〔后续轮重判旧封印被闸挡回零触发〕;双条件②「结算时封印仍在 # 场」由发射面既有过滤承载〔被挖开的封印已随挖掘擦除零兑付〕;grant_ap mode:queue 下一轮 # 开轮兑现——末轮判出无下一轮=合法作废自动成立〔编排器每战新建,队列不跨战〕;限次=合成行 diff --git a/game/core/settlement/verdict_segment.gd b/game/core/settlement/verdict_segment.gd index 5c5bd287..a0dbb532 100644 --- a/game/core/settlement/verdict_segment.gd +++ b/game/core/settlement/verdict_segment.gd @@ -1,6 +1,6 @@ class_name VerdictSegment extends RefCounted -# ⑤ 判定段 Segment(迭代 27 T2——P1-1 结算巨函数拆段;段边界=审计五段〔裁点③甲〕)。 +# ⑤ 判定段 Segment(P1-1 结算巨函数拆段;段边界=审计五段〔裁点③甲〕)。 # 职责:防御性优先级 hero 先判(双死结构不可达的纵深防御)→ 全量状态快照(despawn 前 # 组装——终局含 result)→ 终局行+收束分派 / 下一轮出口分发。 # 返回值 = 裁定("victory"/"defeat"/"continue")——宿主 _settle 据此保持旧早退语义 diff --git a/game/core/treasure_items.gd b/game/core/treasure_items.gd index fc458718..6f39db90 100644 --- a/game/core/treasure_items.gd +++ b/game/core/treasure_items.gd @@ -52,17 +52,17 @@ func inventory_count() -> int: return _items.size() -# 持有数(迭代 10 奖励重构批——同调位上限判定读数:只计未消耗件;Used 不可逆即不再持有) -# 同调位守卫谓词——迭代 11 第①批 T7 退役(读取源 transitional_sync_slots 过渡键已随表退役; +# 持有数(同调位上限判定读数:只计未消耗件;Used 不可逆即不再持有) +# 同调位守卫谓词(读取源 transitional_sync_slots 过渡键已随表退役; # 容量闸正主 = 营地装配面 Attunement.slots 满位禁选。函数体保留空壳防四散引用误删遗漏—— -# T8 冒烟「过渡键读取点归零」断言覆盖) +# 冒烟「过渡键读取点归零」断言覆盖) -# 持有件记录(迭代 10 追加批——奖励节点替换子交互数据源:只列未消耗件,handle 定位丢弃目标) +# 持有件记录(奖励节点替换子交互数据源:只列未消耗件,handle 定位丢弃目标) # 丢弃(同调位替换交互节点渠道——腾位收新;与 Used 消费分轨的一次性移除,快照不再含) # 板级零信息可用性预判(图标置灰/入口禁用判据——GDD「整张图都没东西可看」级): # 真视恒可用(零雷窗口=信息非空);AP 类恒可用(组合判据取 OR——任一效果有信息即可用); -# 纯预读行 = 板上还有未开格才可用。(积点件不入使用面——反哺批⑤自动兑付无玩家入口) +# 纯预读行 = 板上还有未开格才可用。(积点件不入使用面——自动兑付无玩家入口) func _usable_now(item_id: String, board_has_preview_info: Callable) -> bool: var row: Dictionary[Variant, Variant] = _item_row(item_id) if row.is_empty(): @@ -77,7 +77,7 @@ func _item_row(item_id: String) -> Dictionary: if _db == null: return {} if _db.has_method("treasure_item_row"): - return _db.treasure_item_row(item_id) # 表访问收口(2026-10-02——正式面走 ConfigDB 访问器) + return _db.treasure_item_row(item_id) # 表访问收口(正式面走 ConfigDB 访问器) return _db.treasure_items.row_by_id(item_id) # 桩表面(单测 StubDB 无访问器——直读保留,随测试面演进退役) # 不标具体类型原因:单元测试注入 StubDB 桩表(treasure_items_test.gd)——typed 赋值会运行期拒收,保守保持 null 注 @@ -105,12 +105,12 @@ func validate_use(handle: int, target: Vector2i, board_size: Vector2i, cell_unre var kinds: Array[Variant] = row.get("effect_kinds", []) var resolved: Array[Variant] = [] if kinds.has("mine_reveal") or kinds.has("reward_preview") or kinds.has("reveal_tiles") or kinds.has("safe_dig"): - # 空间效果(迭代 22 秘宝批 T3 扩面——真视 reveal_tiles/天眼复合 safe_dig 入空间解析; + # 空间效果(真视 reveal_tiles/天眼复合 safe_dig 入空间解析; # 真视窄域护栏 REVEAL_KINDS 同守): if target.x < 0 or target.y < 0 or target.x >= int(board_size.x) or target.y >= int(board_size.y): return _reject("目标越板") if String(row.get("target", "")) == "cell": - # 单格档(迭代 22 T1——线香真视单格;≤3×3 窄域契约内的点目标) + # 单格档(线香真视单格;≤3×3 窄域契约内的点目标) resolved.append(target) else: # 3×3 窗口 ∩ 板内格(边缘受理——护栏只缩不扩) @@ -172,7 +172,7 @@ func consume(handle: int) -> Dictionary: return rec.duplicate() -# ---- 断点快照(迭代 8 卡①——关卡域库存随停点入档/回局)---- +# ---- 断点快照(关卡域库存随停点入档/回局)---- # 快照面 = {item_id, source_class, origin_cell:[x,y], round_index, used}(JSON 安全形——Vector2i 转 # 数组、键全 String);handle 不入档(受理序句柄,回局时按序重排)。叠加层集不入快照(战斗域 # 随图消亡——停点处无战斗在飞,天然空集)。 @@ -222,7 +222,7 @@ func _reject(reason: String) -> Dictionary: return {"ok": false, "reason": reason, "resolved": [], "item_id": "", "kinds": [], "magnitude": 0} -# 探针出口(T7 收拢——断言面:库存序/叠加层集/拒绝原因) +# 探针出口(断言面:库存序/叠加层集/拒绝原因) func probe() -> Dictionary: return { "count": _items.size(), diff --git a/game/core/unit_container.gd b/game/core/unit_container.gd index 47e41ad7..fadeac2c 100644 --- a/game/core/unit_container.gd +++ b/game/core/unit_container.gd @@ -5,16 +5,16 @@ class_name UnitContainer extends RefCounted -# 死亡事件(伤害管线单据化批 2026-09-24 用户裁决③——单位自行宣布死亡):apply_damage 扣血归零、 +# 死亡事件(单位自行宣布死亡):apply_damage 扣血归零、 # alive 翻 false 的同一时点发出;载荷 = 单位句柄(Dictionary 引用,is_hero 区分主角/敌)。 # 消费方 = 伤害控制器(怪死 → 其未结单据作废〔死亡即不动手〕;主角死 → 兑付终止封印)。 signal unit_died(u: Dictionary) var db: ConfigDb -# 单位容器私有(E3 封装收口 2026-09-13):hero/enemies 原始数组不再外露——读取经 hero_unit()/ +# 单位容器私有(E3 封装收口):hero/enemies 原始数组不外露——读取经 hero_unit()/ # all_enemies() 投影面(死亡残位查询包含在内),写入只经 apply_damage/heal/set_pending_action/commit_action/ # tick_cooldowns/spawn/despawn。 -# 句柄语义不变:投影返回的 Dictionary 引用即单位句柄(同 query_alive 先例)。 +# 句柄语义:投影返回的 Dictionary 引用即单位句柄(同 query_alive)。 var _hero: Dictionary[String, Variant] = {} # {hp, max_hp, atk, is_hero: true} var _enemies: Array[Dictionary] = [] # 行主序生成序;元素 = 单位 Dictionary var _spawned := false @@ -25,12 +25,12 @@ func _init(db_ref: ConfigDb) -> void: db = db_ref -# E4 收口(2026-09-13):加成值经参数显式传入(atk_override/max_hp_override,-1 = 表值兜底)—— -# 此前调用方写 db.hero 表值再由本类读表 = 共享可变单例传参(双写叠加 6→18→54 教训根源)。 -# enemy_atk_override(2026-09-14 敌方攻击区间批):遭遇骰同流的 spawn 期整战持久 roll 结果 +# E4 收口:加成值经参数显式传入(atk_override/max_hp_override,-1 = 表值兜底)—— +# 调用方写 db.hero 表值再由本类读表 = 共享可变单例传参(双写叠加教训根源)。 +# enemy_atk_override:遭遇骰同流的 spawn 期整战持久 roll 结果 # (-1 = 表值定值路径;≥0 = 行值替换后再乘关卡 atk_mult)。敌人系统 零随机纪律保持。 -# 行集受理换代(2026-10-07 行集多行批 P1 甲):unit_count_overrides / enemy_atk_overrides 改**逐行数组** -# (下标=行集行序,长度短于行集时缺省 -1 = 该行行值路径;空数组 = 全行定值——旧调用点零适配)。 +# 行集受理:unit_count_overrides / enemy_atk_overrides 为**逐行数组** +# (下标=行集行序,长度短于行集时缺省 -1 = 该行行值路径;空数组 = 全行定值)。 # 逐行实例化、生成序 = 文件行序(行序即契约,敌人系统 v0.15);行集实例总数(各行传入数量求和) # ≤ ENEMY_ROWSET_INSTANCE_MAX 守卫 fail-fast。 func spawn(level_index: int, node_depth: int, hero_hp: int, unit_count_overrides: Array = [], @@ -39,7 +39,7 @@ func spawn(level_index: int, node_depth: int, hero_hp: int, unit_count_overrides if _spawned: push_warning("[敌人系统] Alive 相位重复 spawn(相位守卫)") return false - # 行集数组口径(2026-10-07 行集多行批——resolver 返回该坐标全部行、文件序) + # 行集数组口径(resolver 返回该坐标全部行、文件序) var rowset: Array[Variant] = db.resolve_enemy_rowset(level_index, node_depth) if rowset.is_empty(): push_error("[敌人系统] 遭遇行解析失败/越域 (%d,%d)" % [level_index, node_depth]) @@ -50,10 +50,10 @@ func spawn(level_index: int, node_depth: int, hero_hp: int, unit_count_overrides if hero_hp > eff_max_hp or hero_hp <= 0: push_warning("[敌人系统] hero_hp 入参越界(EC16): %d" % hero_hp) return false - # max_hp = 生效上限(非入参 hero_hp)——2026-09-11 关卡扩展批修复:跨战斗携带 HP 时上限不得压扁 - # (恢复点/治疗包的满血守卫与治疗上限随之失效——切片登记接口语义澄清) - _hero = {"hp": hero_hp, "max_hp": eff_max_hp, "atk": eff_atk, "is_hero": true, "alive": true, "display_name": "探险者", "enemy_id": "hero", "armor_type": hero_armor_type if hero_armor_type != "" else db.forge_default_armor_type(), "attack_type": hero_attack_type if hero_attack_type != "" else db.forge_default_attack_type()} # 护甲/攻击类型轴快照(迭代 23 T2——hero.tres 两轴删除后改读注入值,空串回退锻造工坊配置默认值 normal/light=行为连续;甲效矩阵消费面) - _enemies.clear() # 难度曲线与Boss DifficultyTable 修饰(2026-09-12 结构位兑现):施加于行值、行值快照之前——MVP 空表 = 恒 1.0 无行为(AC-10);混编行集内全部敌种同乘((L,D) 精确匹配一次取值——F9 同乘不改变异,敌人系统 v0.15) + # max_hp = 生效上限(非入参 hero_hp)——跨战斗携带 HP 时上限不得压扁 + # (恢复点/治疗包的满血守卫与治疗上限随之失效) + _hero = {"hp": hero_hp, "max_hp": eff_max_hp, "atk": eff_atk, "is_hero": true, "alive": true, "display_name": "探险者", "enemy_id": "hero", "armor_type": hero_armor_type if hero_armor_type != "" else db.forge_default_armor_type(), "attack_type": hero_attack_type if hero_attack_type != "" else db.forge_default_attack_type()} # 护甲/攻击类型轴快照(读注入值,空串回退锻造工坊配置默认值 normal/light;甲效矩阵消费面) + _enemies.clear() # 难度曲线与Boss DifficultyTable 修饰:施加于行值、行值快照之前——MVP 空表 = 恒 1.0 无行为(AC-10);混编行集内全部敌种同乘((L,D) 精确匹配一次取值——F9 同乘不改变异,敌人系统 v0.15) var mod: Dictionary[Variant, Variant] = db.resolve_difficulty_modifiers(level_index, node_depth) var hp_mult: float = float(mod.get("hp_mult", 1.0)) var atk_mult: float = float(mod.get("atk_mult", 1.0)) @@ -88,7 +88,7 @@ func spawn(level_index: int, node_depth: int, hero_hp: int, unit_count_overrides "weight": int(entry.get("weight", 0)), "cooldown_left": 0, } - # Boss 半血解锁技(迭代14④ T3——unlock_hp_pct 随池模板快照进实例池;缺省无字段=无门槛; + # Boss 半血解锁技(unlock_hp_pct 随池模板快照进实例池;缺省无字段=无门槛; # unlocked=单向闩标记,初始锁定) if entry.has("unlock_hp_pct"): snap_entry["unlock_hp_pct"] = int(entry.get("unlock_hp_pct", 0)) @@ -103,11 +103,11 @@ func spawn(level_index: int, node_depth: int, hero_hp: int, unit_count_overrides "atk": maxi(0, int(round(float(eff_row_atk) * atk_mult))), "pool": pool_snap, # 实例池(模板快照 + 冷却状态——独立摇号互不干涉) "pending_skill": "", # 本拍摇定动作(开轮摇号写入;兑现前死亡 = 作废不 commit) - "roll_seq": 0, # 单敌摇号拍序(诊断标签——并流后不参与派生,2026-09-27 统一流裁决) + "roll_seq": 0, # 单敌摇号拍序(诊断标签——不参与派生) "basic_streak": 0, # 保底计数:连续执行普攻的拍数(执行上报驱动) - "armor_type": String(row.get("armor_type", "light")), # 护甲类型快照(克制矩阵消费面——战斗结算·战斗段;2026-09-15 命名统一批:light/ward/heavy) - "armor_class": int(row.get("armor_class", 0)), # 护甲等级快照(掷点判定阈值基数——战斗结算·战斗段;2026-09-16 护甲等级掷点批) - "attack_type": String(row.get("attack_type", "normal")), # 攻击类型快照(克制矩阵消费面——敌方伤害单据第 9 参;迭代 24 N3 轴开列,缺省 normal 向后兼容) + "armor_type": String(row.get("armor_type", "light")), # 护甲类型快照(克制矩阵消费面——战斗结算·战斗段:light/ward/heavy) + "armor_class": int(row.get("armor_class", 0)), # 护甲等级快照(掷点判定阈值基数——战斗结算·战斗段) + "attack_type": String(row.get("attack_type", "normal")), # 攻击类型快照(克制矩阵消费面——敌方伤害单据第 9 参;缺省 normal) "alive": true, "is_hero": false, }) @@ -130,9 +130,9 @@ func query_alive(side: String) -> Array: return out -# ---- 实例池状态机(敌人技能池批——全部确定性状态,随机在 战斗结算换算层)---- +# ---- 实例池状态机(全部确定性状态,随机在 战斗结算换算层)---- -# 池条目锁定判定(迭代14④ Boss 半血解锁——带 unlock_hp_pct 且未过闩 = 锁定:双面过滤不进 +# 池条目锁定判定(Boss 半血解锁——带 unlock_hp_pct 且未过闩 = 锁定:双面过滤不进 # 可摇集合与保底特殊技集合;解锁后即可摇,冷却初值 0) func _entry_locked(e: Dictionary) -> bool: return e.has("unlock_hp_pct") and not bool(e.get("unlocked", false)) @@ -154,7 +154,7 @@ func rollable_skills(u: Dictionary) -> Array: # 特殊技集合(保底专用——proposal §2.1:必出特殊技、特殊技内按权重、不受冷却限制):type ≠ 普攻的全部池条目。 -# 锁定条目(半血未解锁)双面过滤——保底不得逼出未解锁技(迭代14④ T3)。 +# 锁定条目(半血未解锁)双面过滤——保底不得逼出未解锁技。 func special_skills(u: Dictionary) -> Array: if u.is_empty() or _despawned or u.get("is_hero", false): _diag("special_skills 失效句柄") @@ -169,7 +169,7 @@ func special_skills(u: Dictionary) -> Array: return out -# 半血解锁闩检查(迭代14④ T3——开轮摇号前逐敌检查;hp ≤ round(max_hp × unlock_hp_pct/100) → +# 半血解锁闩检查(开轮摇号前逐敌检查;hp ≤ round(max_hp × unlock_hp_pct/100) → # 一次过门、单向闩〔实例标记,不解锁回退〕。门=确定性谓词零随机;返回本拍新解锁的 skill_id 列表 # 供编排层出归因行〔每技恰一次——闩已置位不再返回〕) func check_skill_unlocks(u: Dictionary) -> Array: @@ -257,7 +257,7 @@ func apply_damage(u: Dictionary, n: int) -> bool: u.hp = maxi(0, u.hp - n) if u.hp == 0: u.alive = false # Dead 不可逆(死亡判定时机归 战斗结算) - unit_died.emit(u) # 死亡事件——单位自行宣布(伤害管线单据化批 2026-09-24 用户裁决③) + unit_died.emit(u) # 死亡事件——单位自行宣布 return true @@ -281,7 +281,7 @@ func default_target(): # ---- 只读投影面(E3 封装收口:外部读单位经此,禁直读容器数组)---- -# 主角句柄(未 spawn/despawn 后 = {})——句柄即 Dictionary 引用(同 query_alive 先例) +# 主角句柄(未 spawn/despawn 后 = {})——句柄即 Dictionary 引用(同 query_alive) func hero_unit() -> Dictionary: return _hero diff --git a/game/data/schemas/action_economy_table.gd b/game/data/schemas/action_economy_table.gd index 58dfc8cb..9621c45b 100644 --- a/game/data/schemas/action_economy_table.gd +++ b/game/data/schemas/action_economy_table.gd @@ -4,11 +4,11 @@ class_name ActionEconomyTable extends Resource -@export var ap_per_round: int = 6 # [1,32] knob(默认值 = 现行表值基线,2026-09-16 AP 压速批 8→6 随动) +@export var ap_per_round: int = 6 # [1,32] knob(默认值 = 现行表值基线,随 AP 压速调整) @export var dig_ap_cost: int = 1 # [1,8] knob(域下限 1 = 零预算系统失效拒绝) -@export var seal_place_ap_cost: int = 1 # [0,8] knob(seal_pull_ap_cost 随撤封印退役批 2026-09-19 删除) -@export var rap_refresh_cost: int = 6 # [1,64] knob(默认值随 AP 压速批 8→6 随动) -@export var refresh_cap_per_round: int = 2 # [1,8] knob(2026-09-12 轮内刷新批——每轮刷新兜底上限,Active/Waiting 合计) +@export var seal_place_ap_cost: int = 1 # [0,8] knob(无 seal_pull_ap_cost 字段——拔印不占 AP) +@export var rap_refresh_cost: int = 6 # [1,64] knob(默认值随 AP 压速调整) +@export var refresh_cap_per_round: int = 2 # [1,8] knob(每轮刷新兜底上限,Active/Waiting 合计) @export var move_ap_cost: int = 0 # 冻结 0(P4 氛围承载) @export var chain_ap_cost: int = 0 # 冻结 0(v2 定稿) diff --git a/game/data/schemas/adventure_table.gd b/game/data/schemas/adventure_table.gd index c5026a66..68e8f0bd 100644 --- a/game/data/schemas/adventure_table.gd +++ b/game/data/schemas/adventure_table.gd @@ -9,44 +9,44 @@ extends Resource ## 「奇物」(一次冒险内各渠道给予玩家的增益总称)。定义见 design/gdd/systems/冒险循环/奇物.md。 ## 它们是它的分类轴上的枚举(专长 / 属性值提升 / 资源),不是三套系统; ## 本表承载属性值提升与资源的种类配额与件值。 -## (2026-10-05 命名统一 + v2.0 改名:旧称「数值件」→ 属性提升;顶层「特性」→「奖励」→「奇物」。 -## 常量与字段随之前缀 curio_*,**尚未**随顶层改名换到 reward_*——见 06-待办清单。 +## (顶层总称=奇物;属性值提升与资源是本表承载的两类。 +## 常量与字段前缀 curio_*,**尚未**换到 reward_*——见 06-待办清单。 ## 分类轴三个枚举:属性值提升〔生命上限 / AC / 攻击〕;资源〔行动点上限 / ## 刷新次数 / GP / 回复,命名待定〕——本表两类混编;刷新次数与专长获取两项尚未入表。 ## 类内异质性:GP与回复是即时兑付,不进持有集、不持续生效。) ## 三选一提升池 kind 词表(封闭——断点附随件与牌库剔除态依赖它;扩件走本表+registry 修订)。 -## treasure_item 池种退役(迭代 11 第①批 T7——同调批出池);heal 恢复件新入池(v2.2 令牌池追认 b)。 -## 迭代 20 T4 资源凭证入池五件;迭代 31 卡② 凭证件裁削批(用户 2026-10-18 逐裁)两件出池: +## treasure_item 不在池种内(已出池);heal 恢复件在池(v2.2 令牌池口径)。 +## 资源凭证入池五件,两件出池: ## 同调电池整件删除(呈现层零接线、玩家无分配途径——有 API 有账本唯独没有入口); ## 完美保险整件迁出资源类归专长(它给的是规则豁免而非可调动的余量——判据见奇物.md §1.1, ## 落表 feats.tres 第 30 行,效果类型 forgive_seal_miss)。留任 rap 储备金袋/time_sand 时沙。 const CURIO_KINDS: Array[String] = ["attack", "max_hp", "armor", "gp", "ap", "heal", "refresh", - "rap", "time_sand"] # T6 扩第七类(refresh=资源类成员——作为奇物授予的三选一重抽次数,作用对象=三选一界面非角色;见 registry refresh_boundary) -## 令牌档位词表(迭代 20 T2 换代——跨层四级稀有度框架〔01-核心循环 v1.5 档名映射:普通→普通、 + "rap", "time_sand"] # 第七类(refresh=资源类成员——作为奇物授予的三选一重抽次数,作用对象=三选一界面非角色;见 registry refresh_boundary) +## 令牌档位词表(跨层四级稀有度框架〔01-核心循环 v1.5 档名映射:普通→普通、 ## 稀有→优秀、罕见→稀有、传说=新增头奖位〕;1 级最稀有=legendary 优先) const TIERS: Array[String] = ["common", "excellent", "rare", "legendary"] const TIER_COMMON := "common" const TIER_EXCELLENT := "excellent" const TIER_RARE := "rare" const TIER_LEGENDARY := "legendary" -## 档位配额结构锚(迭代 20 换代——T2 四级直映射 70/25/3/0;T4 凭证四件入稀有档投放 +6 -## (rap 2/battery 1/时沙 2/保险 1)→ 稀有 9、总量 104;迭代 31 卡② 净删两件投放(battery 1/保险 1) -## → 稀有 7、总量 102(用户裁「净删」,禁把令牌转给别件保住总量)。已裁换代授权内的 provisional 投放 -## (卡文 T2「四级配额表重构」+Q3 单迭代全量),偏离 GDD 占位记录随代拍板追认单呈报; +## 档位配额结构锚(四级直映射 70/25/3/0; +## 稀有档投放三 kind=ap 3/rap 2/时沙 2 +## → 合计 稀有 7、总量 102(「净删」口径=出池件配额直接归零,禁转给别件保住总量)。provisional 投放 +## (「四级配额表重构」+Q3 单迭代全量),偏离 GDD 占位记录随追认单呈报; ## validate() 硬断言;此后改总量=重裁非调参)。 const TIER_QUOTAS := {"common": 70, "excellent": 25, "rare": 7, "legendary": 0} # —— 通关部分回血(固定型,非末关通关兑付)—— @export var clear_heal_pct: int = 20 # [0,100] knob——回复生效上限的百分比,封顶上限不回满 -# —— 三选一候选数(2026-10-02 修复批 T2 魔法数结构化)—— +# —— 三选一候选数—— @export var curio_candidate_count: int = 3 # [1,6] knob——令牌洗牌不放回抽取张数上界 @export var shop_refresh_free: int = 0 # [0,9] knob(MC-1 provisional——进店免费刷新次数;基础 0=Q2 裁,天赋增益位预留) @export var shop_refresh_cost_base: int = 20 # [1,999] knob(MC-1 provisional——GP 刷新基价) @export var shop_refresh_cost_curve: float = 1.8 # [1.0,4.0] knob(MC-1 provisional——按已付费刷新数幂曲线,A 链同族) -# —— 令牌配额(kind × tier 计数;未列组合 = 0。迭代 20 T2 四级换代:旧 rare→excellent、 -# 旧 rarest→rare 物理承袭〔70/25/3 零偏离〕+凭证四 kind 占位 rare 档配额 0〔T4 落路由同批投放〕)—— +# —— 令牌配额(kind × tier 计数;未列组合 = 0。四级档名 common/excellent/rare/legendary +# 承袭同一物理位序〔70/25/3 零偏离〕;资源凭证 kind 的 rare 档配额见各行现值)—— @export var curio_quota_attack_common: int = 18 # [0,99] @export var curio_quota_attack_excellent: int = 5 # [0,99] @export var curio_quota_max_hp_common: int = 17 # [0,99] @@ -55,13 +55,13 @@ const TIER_QUOTAS := {"common": 70, "excellent": 25, "rare": 7, "legendary": 0} @export var curio_quota_armor_excellent: int = 5 # [0,99] @export var curio_quota_gp_common: int = 18 # [0,99] @export var curio_quota_gp_excellent: int = 5 # [0,99] -@export var curio_quota_heal_excellent: int = 3 # [0,99]——恢复件(原 5;T6 挤占 2 席位予 refresh——用户 2026-10-05 裁方案B,总量 98 锚不变) -@export var curio_quota_refresh_excellent: int = 2 # [0,99]——刷新次数件(T6 新入池资源类成员;provisional 归曲线调参批) -@export var curio_quota_ap_rare: int = 3 # [0,99]——AP 件(稀有档;旧罕见档物理承袭) -@export var curio_quota_rap_rare: int = 2 # [0,99]——储备金袋(T4 投放 provisional 归调参批) -@export var curio_quota_time_sand_rare: int = 2 # [0,99]——时沙(T4 投放 provisional 归调参批) +@export var curio_quota_heal_excellent: int = 3 # [0,99]——恢复件(refresh 挤占 2 席位,总量 98 锚不变) +@export var curio_quota_refresh_excellent: int = 2 # [0,99]——刷新次数件(资源类成员;provisional 归曲线调参) +@export var curio_quota_ap_rare: int = 3 # [0,99]——AP 件(稀有档) +@export var curio_quota_rap_rare: int = 2 # [0,99]——储备金袋(投放 provisional 归调参) +@export var curio_quota_time_sand_rare: int = 2 # [0,99]——时沙(投放 provisional 归调参) -# —— 令牌件值(小/大数值对——v2.2 追认 b 定稿:20/50、+1/+2、+1/+2、+5/+10、恢复+6、AP+1)—— +# —— 令牌件值(小/大数值对——v2.2 令牌池口径定稿:20/50、+1/+2、+1/+2、+5/+10、恢复+6、AP+1)—— @export var curio_value_attack_common: int = 1 # [0,999] knob——小增伤 @export var curio_value_attack_excellent: int = 2 # [0,999] knob——大增伤 @export var curio_value_max_hp_common: int = 5 # [0,999] knob——小生命 @@ -76,9 +76,9 @@ const TIER_QUOTAS := {"common": 70, "excellent": 25, "rare": 7, "legendary": 0} @export var curio_value_rap_rare: int = 3 # [0,99] knob(provisional)——储备金袋 RAP +N @export var curio_value_time_sand_rare: int = 2 # [0,99] knob(provisional)——时沙 下轮 AP +N -# —— 已拿上限 cap(迭代 20 T2 概率与上限解耦〔奇物.md 池结构案D〕——案②令牌池+提前退役: +# —— 已拿上限 cap(概率与上限解耦〔奇物.md 池结构案D〕——案②令牌池+提前退役: # 概率位=档+令牌数〔牌库物理张数〕、上限=本字段〔拿了才计、刷出不计〕;cap 满后该 kind 从候选 -# 视图剔除〔提前退役〕。99=实质无上限占位,实数归调参批;专长 cap 在 feats.tres 行字段〕)—— +# 视图剔除〔提前退役〕。99=实质无上限占位,实数归调参;专长 cap 在 feats.tres 行字段〕)—— @export var curio_cap_attack: int = 99 # [1,99] @export var curio_cap_max_hp: int = 99 # [1,99] @export var curio_cap_armor: int = 99 # [1,99] @@ -89,10 +89,10 @@ const TIER_QUOTAS := {"common": 70, "excellent": 25, "rare": 7, "legendary": 0} @export var curio_cap_rap: int = 99 # [1,99] @export var curio_cap_time_sand: int = 99 # [1,99] -# —— 专长获取门票(迭代 15 卡② T5——非 Boss 渠道的专长入口形态,奇物.md v2.7 渠道轴定位; +# —— 专长获取门票(非 Boss 渠道的专长入口形态,奇物.md v2.7 渠道轴定位; # 四口径契约④:拿到即开不可囤积/罕见只在概率不在价格/一局限购一次/计步保底连续 5 展示未出 # 第 6 必出(计数=展示次数、刷新重展计入、节点与商店共享、触发清零、限购满不再触发)。 -# 四参数全部 provisional 归曲线调参批;limit/pity_step 系口径定死值调参批可复议)—— +# 四参数全部 provisional 归曲线调参;limit/pity_step 系口径定死值,调参可复议)—— @export var feat_ticket_chance: int = 20 # [0,100] knob(provisional)——每次非 Boss 渠道展示门票出现概率 % @export var feat_ticket_quota: int = 2 # [0,9] knob(provisional)——每局门票出现次数上限 @export var feat_ticket_limit: int = 1 # [1,9] knob(口径定死=1)——一局限购(选中/买下)次数 @@ -116,8 +116,8 @@ func curio_apply_route(kind: String) -> String: return String(CURIO_APPLY_ROUTES.get(kind, "")) -## 令牌配额读数(未列 kind×tier 组合 = 0——迭代 20 T2 四级构成:属性四类 common/excellent、 -## heal/refresh excellent、ap rare、凭证四 kind rare 占位 0) +## 令牌配额读数(未列 kind×tier 组合 = 0——四级构成:属性四类 common/excellent、 +## heal/refresh excellent、ap rare、凭证 kind rare 档) func curio_quota(kind: String, tier: String) -> int: match [kind, tier]: ["attack", TIER_COMMON]: return curio_quota_attack_common @@ -155,7 +155,7 @@ func curio_value(kind: String, tier: String = TIER_COMMON) -> int: return 0 -## 已拿上限读数(迭代 20 T2 案②——kind 维度;专长 cap 走 feats.tres 行字段不走本面) +## 已拿上限读数(案②——kind 维度;专长 cap 走 feats.tres 行字段不走本面) func curio_cap(kind: String) -> int: match kind: "attack": return curio_cap_attack @@ -170,8 +170,8 @@ func curio_cap(kind: String) -> int: return 99 -## Boss 专长三选一按档配比加权(迭代 20 T5——奇物.md v3.1 rarity 语义约束「候选按档配比或 -## 加权抽取」兑付面;权重 provisional 归调参批——普通打底/优秀期待/稀有稀缺/传说头奖形态) +## Boss 专长三选一按档配比加权(奇物.md v3.1 rarity 语义约束「候选按档配比或 +## 加权抽取」兑付面;权重 provisional 归调参——普通打底/优秀期待/稀有稀缺/传说头奖形态) func boss_feat_weight(tier: String) -> int: match tier: TIER_COMMON: return 100 diff --git a/game/data/schemas/board_gen_table.gd b/game/data/schemas/board_gen_table.gd index fe9c0d07..664c4ab2 100644 --- a/game/data/schemas/board_gen_table.gd +++ b/game/data/schemas/board_gen_table.gd @@ -8,7 +8,7 @@ extends Resource const SOLVER_RULES := ["single", "single_subset"] const COST_BUDGET := 16384 # F2c provisional 量级护栏(禁墙钟逃生) const TARGET_ABS_FLOOR := 0.85 # 战斗结算 修订——target 域下限(P1 绝对锚) -const BOARD_TYPE_VOCABULARY := ["dungeon", "underdark", "deep_underdark"] # 图类型词表 v1.1(2026-09-20 L3 内容批 +deep_underdark 灰矮人矿道;玩家侧显示名「地图类型」) +const BOARD_TYPE_VOCABULARY := ["dungeon", "underdark", "deep_underdark"] # 图类型词表 v1.1(含 deep_underdark 灰矮人矿道;玩家侧显示名「地图类型」) func validate() -> Array: @@ -49,7 +49,7 @@ 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]}) - # 布雷数下限(R3)——零雷板拒绝(−9 = 出生区格数,常量单点 BoardData.SPAWN_AREA_CELLS——2026-10-02 修复批) + # 布雷数下限(R3)——零雷板拒绝(−9 = 出生区格数,常量单点 BoardData.SPAWN_AREA_CELLS) var n_mines := int(round(d * float(w * h - BoardData.SPAWN_AREA_CELLS))) if n_mines < 1: errs.append({"category": "cross_field", "message": "(%d,%d) 布雷数下限违例 round(d×(W×H−9)) ≥ 1" % [L, D]}) @@ -59,11 +59,11 @@ func validate() -> Array: # F2c 成本可行性 if att * w * h > COST_BUDGET: errs.append({"category": "cross_field", "message": "(%d,%d) cost_feasible 违例 attempts×W×H ≤ %d" % [L, D, COST_BUDGET]}) - # 图类型词表 v1.0(2026-09-19 用户拍板定稿:dungeon=地牢基线 / underdark=幽暗地域;扩词随内容批走修订) + # 图类型词表 v1.0(dungeon=地牢基线 / underdark=幽暗地域;扩词走本表修订) var bt: String = str(row.get("board_type", "")) if not BOARD_TYPE_VOCABULARY.has(bt): errs.append({"category": "cross_field", "message": "(%d,%d) board_type 越词表: %s" % [L, D, bt]}) - # 初始展开收窄批两参数(迭代14① T1——加载期校验违例致命;缺省 shave=1 现行投值 / cap=0 闸关防御口径) + # 初始展开收窄两参数(加载期校验违例致命;缺省 shave=1 现行投值 / cap=0 闸关防御口径) var sr: int = int(row.get("shave_ring_radius", 1)) if sr < 0 or sr > 2: errs.append({"category": "domain", "message": "(%d,%d) shave_ring_radius 越域 [0,2]: %d" % [L, D, sr]}) diff --git a/game/data/schemas/enemy_table.gd b/game/data/schemas/enemy_table.gd index 9284de2b..697ef155 100644 --- a/game/data/schemas/enemy_table.gd +++ b/game/data/schemas/enemy_table.gd @@ -7,23 +7,23 @@ extends Resource @export var rows: Array[Dictionary] = [] # Array[Dictionary] -# 护甲类型封闭枚举(攻击类型 × 护甲克制批——克制矩阵本体在 SettlementTable; -# 2026-09-15 命名统一批:位置键 {none, a, b} → 语义键 {light, ward, heavy} = 轻甲 / 魔法护甲 / 重甲) +# 护甲类型封闭枚举(克制矩阵本体在 SettlementTable; +# 语义键 {light, ward, heavy} = 轻甲 / 魔法护甲 / 重甲) const ARMOR_TYPES := ["light", "ward", "heavy"] -# 攻击类型封闭枚举(迭代 24 N3 2026-10-13——敌方攻击类型轴开列,承接锻造工坊迁移面⑥; +# 攻击类型封闭枚举(敌方攻击类型轴开列,承接锻造工坊迁移面⑥; # 克制矩阵点数制键前缀 = 本枚举:normal → light 0 / ward +1 / heavy −1;pierce/magic 为差异化 # 预留档,差异化填值属新设计另立项。可省略 + 缺省 normal 向后兼容) const ATTACK_TYPES := ["normal", "pierce", "magic"] -# 实例化数量域(2026-10-02 修复批 T2 魔法数结构化——数量域 [1,3] 双落点收口单点: +# 实例化数量域(域 [1,3] 双落点收口单点: # 本表 validate 与 单位容器 spawn 守卫共用;遭遇骰结果与行值 unit_count/unit_count_max 同域。 -# 2026-10-07 行集多行批:MAX 语义 = **单种数**(单行实例数上限),行集实例总数 ≤4 另由 +# MAX 语义 = **单种数**(单行实例数上限),行集实例总数 ≤4 另由 # spawn 期守卫承担——骰后值加载期不可判,双闸分工见 敌人系统 v0.15 行集构成纪律③) const UNIT_COUNT_MIN := 1 const UNIT_COUNT_MAX := 3 -# 行集实例总数上限(2026-10-07 行集多行批 P1 甲——行集构成纪律③:各行开战骰后数量求和 ≤4; +# 行集实例总数上限(行集构成纪律③:各行开战骰后数量求和 ≤4; # 「总数」= 实例数非行数〔Q9 二裁〕,行数不设上限。骰后值加载期不可判——守卫在 单位容器 spawn, # 常量单点在本表与数量域同位收口) const ROWSET_INSTANCE_MAX := 4 @@ -66,7 +66,7 @@ func validate() -> Array: var atk: int = int(row.get("atk", -1)) if atk < 0 or atk > 999: errs.append({"category": "domain", "message": "%s atk 越域 [0,999]" % eid}) - # atk_min/atk_max(可省略配对——2026-09-14 敌方攻击区间批):遭遇骰同流 spawn 期整战持久 roll; + # atk_min/atk_max(可省略配对):遭遇骰同流 spawn 期整战持久 roll; # 中点锚 = 行动经济 条款①同款期望当量纪律(调区间必同步调 atk) var has_amin: bool = row.has("atk_min") var has_amax: bool = row.has("atk_max") @@ -79,7 +79,7 @@ func validate() -> Array: errs.append({"category": "domain", "message": "%s atk 区间越域 [0,999] 且 min≤max: %d..%d" % [eid, amin, amax]}) if atk != int((amin + amax) / 2.0): errs.append({"category": "cross_field", "message": "%s atk(%d) ≠ 区间中点(%d)——中点恒等期望当量锚" % [eid, atk, (amin + amax) / 2]}) - # 池模板(敌人技能池批——单表结构校验;跨表构成纪律在 ConfigDB): + # 池模板(单表结构校验;跨表构成纪律在 ConfigDB): # 非空池 + 条目 {skill_id 非空, weight > 0} + 池内 skill_id 不重复。 # 普攻冷却恒 0(SkillTable schema 锁死)→ 可摇集合恒非空,"空池不可能"由此结构保证。 var pool: Array[Variant] = row.get("pool", []) @@ -100,7 +100,7 @@ func validate() -> Array: var w: int = int(entry.get("weight", 0)) if w <= 0 or w > 9999: errs.append({"category": "domain", "message": "%s pool 权重越域 (0,9999]: %d" % [eid, w]}) - # unlock_hp_pct(可省略——迭代14④ Boss 半血解锁技:缺省无字段=无门槛;域 [1,99] percent。 + # unlock_hp_pct(可省略——Boss 半血解锁技:缺省无字段=无门槛;域 [1,99] percent。 # 投放纪律=仅 Boss 行〔enemy 表无 boss 编码位,硬闸须跨表查节点类型——不做硬闸,文档纪律登记〕) if entry.has("unlock_hp_pct"): var uhp: int = int(entry.get("unlock_hp_pct", 0)) @@ -110,17 +110,17 @@ func validate() -> Array: var at: String = String(row.get("armor_type", "light")) if not ARMOR_TYPES.has(at): errs.append({"category": "enum", "message": "%s armor_type 未知枚举: %s(域 {light, ward, heavy})" % [eid, at]}) - # attack_type(迭代 24 N3——可省略,缺省 normal 向后兼容;写法沿用 armor_type 同款) + # attack_type(可省略,缺省 normal 向后兼容;写法沿用 armor_type 同款) var att: String = String(row.get("attack_type", "normal")) if not ATTACK_TYPES.has(att): errs.append({"category": "enum", "message": "%s attack_type 未知枚举: %s(域 {normal, pierce, magic})" % [eid, att]}) - # armor_class(可省略——缺省 0 向后兼容;2026-09-16 护甲等级掷点批:防守方掷点判定阈值基数) + # armor_class(可省略——缺省 0 向后兼容;防守方掷点判定阈值基数) var ac: int = int(row.get("armor_class", 0)) if ac < 0 or ac > 999: errs.append({"category": "domain", "message": "%s armor_class 越域 [0,999]: %d" % [eid, ac]}) - # 行集构成纪律②(2026-10-07 行集多行批——行序即契约,敌人系统 v0.15):同坐标多行必须 + # 行集构成纪律②(行序即契约,敌人系统 v0.15):同坐标多行必须 # 文件内相邻。迭代中记录上一行坐标;当前坐标曾出现过但 ≠ 上一行坐标 = 同坐标行被隔断,报错。 - # 原纪律「每行集恰一敌种」同批退役——同坐标多敌种混编合法;同坐标同敌种第二行仍由 + # 同坐标多敌种混编合法;同坐标同敌种第二行仍由 # dup_key 拦截(键含 enemy_id)。错误类别沿用 rowset_rule(定位面不变)。 var rk := "%d_%d" % [L, D] if rk != last_rk: @@ -135,6 +135,6 @@ func validate() -> Array: return errs -# 进度键解析单点收口(2026-10-07 行集多行批 P2 甲——原 floor 语义 resolve_rowset 退役,全仓统走 -# ConfigDbResolver.resolve_enemy_rowset ceil 版行集数组:2026-09-18 用户拍板 ceil 保证偏难, -# 双算法并存至本批销号〔状态记录 312 待裁项〕;原冒烟四调用点随批迁移,坐标全精确命中零行为差)。 +# 进度键解析单点收口(全仓统走 +# ConfigDbResolver.resolve_enemy_rowset ceil 版行集数组:ceil 保证偏难, +# 禁双算法并存〔状态记录 312〕;坐标须全精确命中)。 diff --git a/game/data/schemas/forge_table.gd b/game/data/schemas/forge_table.gd index ca378780..a9ffb6ec 100644 --- a/game/data/schemas/forge_table.gd +++ b/game/data/schemas/forge_table.gd @@ -5,7 +5,7 @@ class_name ForgeTable extends Resource -# 路线 id 词表(代拍板立项:甲路线 id=甲型值本身——ward=魔法护甲,3a 裁统一命名) +# 路线 id 词表(甲路线 id=甲型值本身——ward=魔法护甲,统一命名) const WEAPON_IDS := ["sword", "spear", "staff"] const ARMOR_IDS := ["light", "heavy", "ward"] const ROUTE_IDS := ["sword", "spear", "staff", "light", "heavy", "ward"] @@ -104,7 +104,7 @@ func validate() -> Array: errs.append({"category": "cross_field", "message": "%s prereq_route 不得自指" % rid}) elif kind_by_id.has(prereq) and String(kind_by_id[prereq]) != kind: errs.append({"category": "cross_field", "message": "%s 前置 %s 类型不符(武器←武器/甲←甲): %s vs %s" % [rid, prereq, kind, String(kind_by_id[prereq])]}) - # 初始持有恰两行且一武器一甲(长剑/轻甲——语义继承自已退役属性锻造行) + # 初始持有恰两行且一武器一甲(长剑/轻甲) var init_weapons := 0 var init_armors := 0 for k in initial_ids.keys(): diff --git a/game/data/schemas/hero_table.gd b/game/data/schemas/hero_table.gd index c6f2ed3f..11f8176f 100644 --- a/game/data/schemas/hero_table.gd +++ b/game/data/schemas/hero_table.gd @@ -7,7 +7,7 @@ extends Resource @export var max_hp: int = 50 # [1,999] knob(provisional,溯源 = 原型锚) @export var atk: int = 6 # [1,999] knob——基础攻击(溯源 = 概念原型 HERO_BASE_ATK,provisional 归 难度曲线与Boss);消费面 = 战斗结算·战斗段先手攻击 -@export var armor_class: int = 10 # [0,999] knob——防守方护甲等级基准(2026-09-16 护甲等级掷点批,暂定 10 归 难度曲线与Boss);消费面 = 战斗结算掷点判定阈值基数(ac_up 效果加算其上) +@export var armor_class: int = 10 # [0,999] knob——防守方护甲等级基准(暂定 10 归 难度曲线与Boss);消费面 = 战斗结算掷点判定阈值基数(ac_up 效果加算其上) func validate() -> Array: diff --git a/game/data/schemas/level_table.gd b/game/data/schemas/level_table.gd index 2c8568dc..67328b28 100644 --- a/game/data/schemas/level_table.gd +++ b/game/data/schemas/level_table.gd @@ -6,10 +6,10 @@ extends Resource @export var rows: Array[Dictionary] = [] # Array[Dictionary] -const NODE_TYPES := ["battle", "reward", "rest", "boss", "shop"] # 商店房批 2026-09-21 四→五类(关卡节点地图 v1.1) +const NODE_TYPES := ["battle", "reward", "rest", "boss", "shop"] # 五类(关卡节点地图 v1.1) -# 行单点读取(2026-10-02 修复批 T5 表访问收口——LevelRunner._find_level_row 直扫收口;键 = level_index) +# 行单点读取(表访问收口——LevelRunner._find_level_row 禁直扫;键 = level_index) func row_by_level_index(level_index: int) -> Dictionary: for row in rows: if int(row.level_index) == level_index: @@ -35,8 +35,8 @@ func validate() -> Array: var heal: int = int(row.get("rest_heal_pct", -1)) if heal < 0 or heal > 100: errs.append({"category": "domain", "message": "level %d rest_heal_pct 越域 [0,100]" % L}) - # 模板池(关卡节点图生成 v0.4——M-3 迭代 5 T5):row.templates 非空 = 池形态,池内全模板加载期校验 - # (违规致命——不只抽中的那张);空 = 旧单图形态(row.nodes 直读,向后兼容零迁移)。 + # 模板池(关卡节点图生成 v0.4):row.templates 非空 = 池形态,池内全模板加载期校验 + # (违规致命——不只抽中的那张);空 = 单图形态(row.nodes 直读,向后兼容)。 var node_lists: Array[Array] = [] # [ [上下文标签, nodes 数组], ... ] var templates: Array[Variant] = row.get("templates", []) if templates.is_empty(): @@ -88,7 +88,7 @@ func _validate_level_nodes(L: int, ctx: String, nodes: Array) -> Array: # 图合法性(单链与图同一套算法——单链 = 出边恰一的退化形态,违规同样加载致命) for e in _validate_graph(L, nodes, is_graph, tag): errs.append(e) - # U2 目检新规则(迭代 5 返工批 2026-09-29 两条,加载期同检):①单链前三位纯战斗(奖励/休整禁入前三) + # U2 目检规则(两条,加载期同检):①单链前三位纯战斗(奖励/休整禁入前三) if not is_graph and nodes.size() >= 3: for i in 3: if String(nodes[i].get("type", "")) != "battle": @@ -127,9 +127,9 @@ func _validate_graph(L: int, nodes: Array, is_graph: bool, tag: String = "") -> errs.append({"category": "dangling_next", "message": "level %d%s 节点 %d 出边指向不存在编号: %d" % [L, tag, ids[i], tid]}) elif tid <= ids[i]: errs.append({"category": "structural", "message": "level %d%s 连线 %d→%d 违反前进方向(目标编号须严格更大)" % [L, tag, ids[i], tid]}) - # ③b 出度上限(T17 用户拍板 2026-10-01「节点出度最大为 2」):单节点出边 >2 即加载致命。 - # 规则连带:出度 ≤2 + 入口唯一下 BFS 层宽上限 = 4(序列 1,2,4——原「层宽上限 5」与出度约束 - # 不相容,模板池随本检同批按层宽 ≤4 重建)。 + # ③b 出度上限(「节点出度最大为 2」):单节点出边 >2 即加载致命。 + # 规则连带:出度 ≤2 + 入口唯一下 BFS 层宽上限 = 4(序列 1,2,4——层宽上限 5 与出度约束 + # 不相容,模板池按层宽 ≤4 构造)。 for i in nodes.size(): if nexts[i].size() > 2: errs.append({"category": "fanout_violation", "message": "level %d%s 节点 %d 出度 %d > 2(出度上限拍板 2026-10-01)" % [L, tag, ids[i], nexts[i].size()]}) @@ -177,7 +177,7 @@ func _validate_graph(L: int, nodes: Array, is_graph: bool, tag: String = "") -> for i in nodes.size(): if not to_boss.has(i): errs.append({"category": "structural", "message": "level %d 节点 %d 沿连线不可达 Boss" % [L, ids[i]]}) - # ⑧ U2 目检新规则(迭代 5 返工批 2026-09-29):BFS 同深度层节点数上限 5(分支宽度天花板) + # ⑧ U2 目检规则:BFS 同深度层节点数上限 5(分支宽度天花板) var layer_of := {} var bfs: Array[Variant] = [entries[0]] layer_of[entries[0]] = 0 diff --git a/game/data/schemas/meta_table.gd b/game/data/schemas/meta_table.gd index 6f637717..7f68bd4c 100644 --- a/game/data/schemas/meta_table.gd +++ b/game/data/schemas/meta_table.gd @@ -7,9 +7,9 @@ extends Resource @export var boss_keystone: Array[Dictionary] = [] # Array[Dictionary] 键 level_index @export var conversion: Array[Dictionary] = [] # Array[Dictionary] 键 attr -@export var attune_refresh_upgrade: Array[Dictionary] = [] # Array[Dictionary] 键 level——Y 刷新升级行族(迭代 11 第①批 T4) +@export var attune_refresh_upgrade: Array[Dictionary] = [] # Array[Dictionary] 键 level——Y 刷新升级行族 -const FORGE_ATTRS := ["max_hp", "atk", "armor_class"] # 三属性轴词表(conversion 行键域——原 forge 词表名沿用作轴名) +const FORGE_ATTRS := ["max_hp", "atk", "armor_class"] # 三属性轴词表(conversion 行键域=forge 词表名) func validate() -> Array: @@ -36,8 +36,8 @@ func validate() -> Array: if li_at != i + 1: errs.append({"category": "structural", "message": "boss_keystone level_index 不连续(须从 1 连续递增): 位 %d = %d" % [i + 1, li_at]}) break - # workshop_items 行族已退役(迭代 22 T2——解锁混合制换代,条件谓词挂 treasure_items 行内; - # 校验段随批删除——秘宝解锁条件校验单点=TreasureItemTable.validate) + # 无 workshop_items 行族(解锁混合制——条件谓词挂 treasure_items 行内; + # 本表不校验秘宝解锁,单点=TreasureItemTable.validate) # conversion:attr 词表与 forge 一致 + 唯一 + 覆盖恰三 + 平移量域 [0,100] var seen_conv := {} for row in conversion: @@ -54,7 +54,7 @@ func validate() -> Array: for conv_key in FORGE_ATTRS: if not seen_conv.has(conv_key): errs.append({"category": "coverage", "message": "conversion 缺属性行: %s(三行与 forge 词表一致)" % conv_key}) - # attune_refresh_upgrade:level 唯一 + 连续从 1 + charges/cost 域(迭代 11 第①批 T4) + # attune_refresh_upgrade:level 唯一 + 连续从 1 + charges/cost 域 var seen_al := {} for row in attune_refresh_upgrade: var al: int = int(row.get("level", -1)) diff --git a/game/data/schemas/meta_tree_table.gd b/game/data/schemas/meta_tree_table.gd index 1997ad00..8e75a3a5 100644 --- a/game/data/schemas/meta_tree_table.gd +++ b/game/data/schemas/meta_tree_table.gd @@ -9,10 +9,10 @@ extends Resource const VEINS := ["spine", "forge", "keystone", "attune"] const KINDS := ["stat", "rule", "unlock", "socket", "fork", "easter"] -const CURRENCIES := ["keystone", "free"] # 树全钥石单币(2026-10-07 用户裁甲——原 gp 枚举值退役,字段保留为呈现元数据) +const CURRENCIES := ["keystone", "free"] # 树全钥石单币(无 gp 枚举值,字段保留为呈现元数据) const STAT_KEYS := ["atk", "max_hp", "hit", "armor_class"] ## 规则键封闭词表(零裸 flat 同族护栏——effects.rule 键出域=加载致命;六键=三组 Fork 双态真实接线, -## 迭代 21 T1 扩签:posture 两键现役沿袭,sense/economy 四键随危险直觉/财富之道两组建效面新增) +## posture 两键 + sense/economy 四键〔危险直觉/财富之道两组建效面〕) const RULE_KEYS := ["posture_first_strike", "posture_bulwark", "sense_sharp", "sense_guard", "economy_hoard", "economy_spend"] const KEY_WHITELIST := ["node_id", "display_name", "vein", "kind", "currency", "price", "cap", "requires", "requires_level", "effects", "effects_a", "effects_b", "name_a", "name_b", "fork_group", "note"] @@ -20,14 +20,14 @@ const KEY_WHITELIST := ["node_id", "display_name", "vein", "kind", "currency", " const SPINE_ROW_GATE := 4 ## Fork 双态组词表(每组恰一节点——互斥由单态承载;营地零币切换承载面; -## fg_mastery 克制专精整组砍除——2026-10-11 裁,类型表达归锻造工坊) +## 无 fg_mastery 克制专精组——类型表达归锻造工坊) const FORK_GROUPS := ["fg_posture", "fg_sense", "fg_economy"] func validate() -> Array: var errs: Array[Variant] = [] if rows.is_empty(): - return errs # 空表合法态(建表先行——内容随换代批落) + return errs # 空表合法态(建表先行——内容后补) var seen := {} var fork_seen := {} for row in rows: @@ -118,7 +118,7 @@ func row_by_id(node_id: String) -> Dictionary: return {} -## 行门槛(一线一节点:脊柱节点第 N 级可购需全树总等级 ≥ GATE×(N−1);原 row-gating 行号主语 -## 随层行退役平移到节点等级轴) +## 行门槛(一线一节点:脊柱节点第 N 级可购需全树总等级 ≥ GATE×(N−1); +## 门槛主语=节点等级轴) func level_gate(level: int) -> int: return SPINE_ROW_GATE * maxi(0, level - 1) diff --git a/game/data/schemas/reward_table.gd b/game/data/schemas/reward_table.gd index 8e259f90..65ef00f1 100644 --- a/game/data/schemas/reward_table.gd +++ b/game/data/schemas/reward_table.gd @@ -6,7 +6,7 @@ extends Resource @export var rows: Array[Dictionary] = [] # Array[Dictionary] -const CELL_TYPES := ["attack", "defense", "heal", "blast", "weaken", "pierce", "magic", "action", "gp", "treasure_item"] # 十型(迭代 7 T1 秘宝内容批扩值——registry 秘宝词表;aux 行 effect_id = item_id 双表校验键) +const CELL_TYPES := ["attack", "defense", "heal", "blast", "weaken", "pierce", "magic", "action", "gp", "treasure_item"] # 十型(registry 秘宝词表;aux 行 effect_id = item_id 双表校验键) const TREASURE_ITEM_TYPE := "treasure_item" # aux 行标识(掉落投放行:挖开→战斗结算 grant 路由关卡域库存,不入增益容器) const POLARITIES := ["positive", "negative"] const POOL_TAGS := ["cell", "clear_default"] # cell = 格面资源单一池;clear_ 命名空间预留拒绝 @@ -39,11 +39,11 @@ func validate() -> Array: var atk_type: String = String(row.get("attack_type", "")) if atk_type != "" and not ["normal", "pierce", "magic"].has(atk_type): errs.append({"category": "enum", "message": "%s attack_type 出域 {normal, pierce, magic}: %s" % [rid, atk_type]}) - # aux 投放行专属校验(迭代 7 T1):极性恒正/加权入池/effect_id=item_id 非空(悬空在 config_db 跨表层 + # aux 投放行专属校验:极性恒正/加权入池/effect_id=item_id 非空(悬空在 config_db 跨表层 # 对秘宝词表校验——reward_dangling_treasure)/无 power 无区间(数值语义不复用,道具效果读 TreasureItemTable) if ctype == TREASURE_ITEM_TYPE: # 负向行 = 危险格极性字典占位(雷安同池摇号下危险格可摇中 aux 身份——负路由零兑付兜底, - # effect_id 空/power 0/weight 0 不入池;2026-09-29 T1) + # effect_id 空/power 0/weight 0 不入池) if pol == "negative": if String(row.get("effect_id", "")) != "" or int(row.get("power", 0)) != 0 or int(row.get("weight", 0)) != 0: errs.append({"category": "cross_field", "message": "%s aux 负占位行仅允许 空effect_id/0power/0weight" % rid}) diff --git a/game/data/schemas/settlement_table.gd b/game/data/schemas/settlement_table.gd index 22fc984e..96c80217 100644 --- a/game/data/schemas/settlement_table.gd +++ b/game/data/schemas/settlement_table.gd @@ -6,23 +6,23 @@ extends Resource @export var equivalence_ref_damage: int = 12 # [1,999] knob——当量参考敞口 D_ref @export var p_perfect: int = 200 # {100,200} percent——完美排雷第二份兑付触发(载体域) -@export var seal_hit_premium: int = 100 # [100,999] percent knob——封印命中兑付溢价 ×(1+(n−100)/100):125=×1.25(条款3 条件二封印溢价形态 a,2026-10-05 判式换代批 provisional);100=无溢价直通零扰动。只乘封印命中正向兑付(flat power/percent 幅度/gp 缓冲三形态),标空/挖格/清图不乘;雷安同池冻结不动 -@export var segment_order: PackedStringArray = [] # 结构冻结——恒等拍板段序校验违例致命 +@export var seal_hit_premium: int = 100 # [100,999] percent knob——封印命中兑付溢价 ×(1+(n−100)/100):125=×1.25(条款3 条件二封印溢价形态 a,provisional);100=无溢价直通零扰动。只乘封印命中正向兑付(flat power/percent 幅度/gp 缓冲三形态),标空/挖格/清图不乘;雷安同池冻结不动 +@export var segment_order: PackedStringArray = [] # 结构冻结——段序恒等校验违例致命 @export var source_label_map: Dictionary[String, Variant] = {} # 结构冻结——source_class→文案键 @export var effect_pool_map: Dictionary[String, Variant] = {} # 结构冻结——effect_id→pool(悬空加载致命) @export var pool_clamp_lo: int = -100 # 结构冻结 @export var pool_clamp_hi: int = 100 # 结构冻结 @export var round_direction: String = "floor" # 结构冻结——单一取整规则 -# ---- 攻击类型 × 护甲克制批 + 充能奖励定义(2026-09-12 用户拍板结构;2026-09-15 命名统一批 / 抽象分离批;数值 provisional)---- +# ---- 攻击类型 × 护甲克制 + 充能奖励定义(数值 provisional)---- # 主角攻击 = 普通(atk×(1+attack_up),不吃克制)+ 穿刺 + 魔法(后两者由充能供给),三分量各自 floor 后相加。 # 【两条抽象分离,勿焊死】攻击类型 = 伤害的属性轴,只决定查 armor_effectiveness 哪一行,定义里不含任何棋盘来源; # 充能 = 按攻击类型分桶的附加伤害储备,"谁往桶里放东西"属**奖励的定义**(开格/标雷只是奖励触发源,奖励内容可改)。 -# 原 damage_a_per_cell / damage_a_cap / damage_b_per_seal 与 charge_grants 充能奖励定义均退役(2026-09-19 充能退役批——攻击模型回归单分量)。 +# 无 damage_a_per_cell / damage_a_cap / damage_b_per_seal 与 charge_grants 字段(攻击模型=单分量)。 @export var armor_effectiveness: Dictionary[String, Variant] = {} # 克制修正矩阵(加法点数 delta):{攻击类型 {normal|pierce|magic}: {护甲 {light|ward|heavy}: 点数 [-3,+3]}} -# ---- 护甲等级掷点批(2026-09-16 用户拍板,数字即规范——registry settlement_table.ac_roll/ac_discount_tiers 同批定稿)---- +# ---- 护甲等级掷点(数字即规范——registry settlement_table.ac_roll/ac_discount_tiers 定稿)---- # 判定式:掷 1d20,掷点 ≥ 防守方 AC + 攻击加成 → 全额;低掷按缺口(AC−掷点)查档打折,无 miss、无零收益档; # nat 最大面(crit_roll)= 暴击:该次基础攻击分量 ×2 且恒全额;任何伤害落地全局下限 damage_floor(≥1)—— -# 2026-09-20 用户拍板扩全来源(攻击双方/棋盘直伤/地形变异/反噬,取值域 [1,+∞) 无上限)。 +# 全来源(攻击双方/棋盘直伤/地形变异/反噬,取值域 [1,+∞) 无上限)。 # 掷点只吃基础攻击分量(主角普通分量 / 敌方攻击拍与重击拍基线),穿刺/魔法充能与棋盘来源伤害不掷不折。 # 微调旋钮 = 档位边界(roll_tier_bounds)与档位值(roll_tier_discounts),不动 AC 值(armor_class 归单位表)。 @export var roll_faces: int = 20 # [2,1000] knob——掷点骰面(d20) @@ -31,8 +31,8 @@ extends Resource @export var roll_tier_discounts: Array[int] = [] # 档位值 percent 降序(与 bounds 同长;[75,50,25] = ×0.75/×0.5/×0.25) @export var crit_roll: int = 20 # [1,roll_faces] knob——nat 最大面 = 暴击触发掷点(恒全额) @export var crit_multiplier: int = 200 # [100,999] percent knob——暴击倍率(200 = ×2,只乘该次基础攻击分量) -@export var damage_floor: int = 1 # [1,999] knob——任何伤害落地全局下限·全来源("被减伤归零 v=0"行语义随批退役) -@export var armor_roll_stream: String = "armor_roll" # 掷点用途标签(rng_service PURPOSE_TAGS 成员——并流后不参与派生,仅作事件日志用途标记;2026-09-27 统一流裁决) +@export var damage_floor: int = 1 # [1,999] knob——任何伤害落地全局下限·全来源(无"被减伤归零 v=0"语义) +@export var armor_roll_stream: String = "armor_roll" # 掷点用途标签(rng_service PURPOSE_TAGS 成员——不参与派生,仅作事件日志用途标记) const ARMOR_KEYS := ["light", "ward", "heavy"] const ATTACK_TYPE_KEYS := ["normal", "pierce", "magic"] diff --git a/game/data/schemas/shop_table.gd b/game/data/schemas/shop_table.gd index c01ed1ae..ef07d5b1 100644 --- a/game/data/schemas/shop_table.gd +++ b/game/data/schemas/shop_table.gd @@ -9,13 +9,13 @@ extends Resource @export var level_gp_bonus: Array[Dictionary] = [] # Array[Dictionary] 键 level_index @export var products: Array[Dictionary] = [] # Array[Dictionary] 键 product_id @export var price_level_bonus: Array[Dictionary] = [] # Array[Dictionary] 键 level_index -@export var pool_shelf: Array[Dictionary] = [] # Array[Dictionary] 键 kind_id(迭代 11 第②批 T1) +@export var pool_shelf: Array[Dictionary] = [] # Array[Dictionary] 键 kind_id @export var price_a: float = 0.0 # 进店已购次数爬价因子(provisional——0 = 未投值即致命域) @export var price_b: float = 0.0 # 跨关递增因子(provisional) const GP_TIERS := ["normal", "elite", "boss"] const PRODUCT_ATTRS := ["atk", "max_hp", "armor_class"] -const SHELF_KINDS := ["attack", "max_hp", "armor", "ap", "feat_ticket", "heal"] # 货架候选词表(四切边后种 + T5 门票行 + T6 heal 补回复〔默认原则:分类内成员都入该渠道池〕——奇物批迭代15②) +const SHELF_KINDS := ["attack", "max_hp", "armor", "ap", "feat_ticket", "heal"] # 货架候选词表(四切边后种 + 门票行 + heal 补回复〔默认原则:分类内成员都入该渠道池〕) func validate() -> Array: @@ -83,7 +83,7 @@ func validate() -> Array: var inc: int = int(row.get("price_increment", -1)) if inc < 0 or inc > 999: errs.append({"category": "domain", "message": "%s price_increment 越域 [0,999]: %d" % [pid, inc]}) - # pool_shelf:kind_id 词表封闭(四切边后种)+ 唯一 + display_name + base_price 域 [1,999](迭代 11 第②批 T1) + # pool_shelf:kind_id 词表封闭(四切边后种)+ 唯一 + display_name + base_price 域 [1,999] var seen_kind := {} for row in pool_shelf: var kind: String = row.get("kind_id", "") diff --git a/game/data/schemas/skill_table.gd b/game/data/schemas/skill_table.gd index 303ecd7d..f013677c 100644 --- a/game/data/schemas/skill_table.gd +++ b/game/data/schemas/skill_table.gd @@ -10,7 +10,7 @@ extends Resource # (特殊技内按权重、不受冷却限制——proposal §2.1 两道闸之二)。全局单旋钮(不分敌种)。 @export var pity_threshold: int = 4 -const SKILL_TYPES := ["basic", "damage", "buff", "debuff"] # 普通攻击 / 伤害 / 增益 / 妨害(封闭枚举——新效应词汇批 2026-09-19 由三扩四) +const SKILL_TYPES := ["basic", "damage", "buff", "debuff"] # 普通攻击 / 伤害 / 增益 / 妨害(封闭枚举四型) const MULT_DOMAIN_MIN := 1.1 # damage_mult 域 [1.1, 16] provisional(proposal §2.2) const MULT_DOMAIN_MAX := 16.0 const RIDER_MULT_MAX := 1.0 # rider_mult 域 (0, 1](必中附加分量——proposal-status-vocabulary §2;首发 0.75 锚 AC 折扣档最轻档) @@ -78,7 +78,7 @@ func validate() -> Array: var bd: int = int(row.get("buff_duration", 0)) if bd < 1 or bd > 99: errs.append({"category": "domain", "message": "%s buff_duration 越域 [1,99]: %d" % [sid, bd]}) - # 妨害技(新效应词汇批 2026-09-19):0 伤害施放动作,对主角施加负面状态—— + # 妨害技:0 伤害施放动作,对主角施加负面状态—— # 字段复用 buff_ref/buff_duration(落点由状态行 target_side 路由,ConfigDB side 守卫兜底);池纪律妨害 ≤1 在跨表通道 if type == "debuff": if row.has("damage_mult"): diff --git a/game/data/schemas/status_effect_table.gd b/game/data/schemas/status_effect_table.gd index 89891d5a..6811a235 100644 --- a/game/data/schemas/status_effect_table.gd +++ b/game/data/schemas/status_effect_table.gd @@ -7,7 +7,7 @@ extends Resource @export var rows: Array[Dictionary] = [] # Array[Dictionary] const TARGET_SIDES := ["hero", "enemy"] -const UNITS := ["percent", "flat", "ac"] # 2026-09-16 护甲等级掷点批增 ac——AC 阈值轴效果(ac_up),非池百分比非定点值 +const UNITS := ["percent", "flat", "ac"] # ac——AC 阈值轴效果(ac_up),非池百分比非定点值 const STACK_POLICIES := ["stack", "refresh", "independent"] diff --git a/game/data/schemas/treasure_item_table.gd b/game/data/schemas/treasure_item_table.gd index 6b12d03c..7dd35bd3 100644 --- a/game/data/schemas/treasure_item_table.gd +++ b/game/data/schemas/treasure_item_table.gd @@ -8,25 +8,25 @@ extends Resource @export var rows: Array[Variant] = [] # Array[Dictionary] 键 item_id -# 计数键封闭枚举(原 AttunementGrowthTable.COUNTER_KEYS——迭代 21 T5 谓词表退役后就地内联; -# 迭代 22 T1 换代:clear_count(旧工坊按关累计渠道)与 C6 通关口径(通关=打通整局冒险)不符, -# 换名 adventure_cleared(生涯通关局数,save_manager 生涯计数域在役)并扩 vision_used(真视类工具 -# 累计使用——信标网络行为条件计数,本批新增;use_treasure 受理成功处累计、冒险收束导出入档); -# 旧 clear_count 零行消费,换名安全) +# 计数键封闭枚举(就地内联于本表,无独立谓词表; +# 通关口径=C6(通关=打通整局冒险),键名 adventure_cleared +# (生涯通关局数,save_manager 生涯计数域在役);扩 vision_used(真视类工具 +# 累计使用——信标网络行为条件计数;use_treasure 受理成功处累计、冒险收束导出入档); +# 键域以本枚举为准) const UNLOCK_COUNTER_KEYS := ["adventure_cleared", "boss_kill_count", "vision_used"] const DIMENSIONS := ["info", "risk", "action", "plan", "counter"] -# 同调批扩 enum(迭代 11 第①批 T1)——新增九 kind 全部条件触发/机制修正类;mine_reveal/ap_grant 语义不变。 -# cell_removal = 爆破工兵包中立移除格(T7 原位换装时启用——T6 影响评估前置);mine_hit_halve 系固定 +# enum 九 kind 全部条件触发/机制修正类;mine_reveal/ap_grant 语义不变。 +# cell_removal = 爆破工兵包中立移除格;mine_hit_halve 系固定 # 「减半」语义不消费 magnitude(反弹 N 由 reflect_damage 行 magnitude 承载)。 -# 内容数据驱动扩展批 T2 挂账:主动件 kind 词族换代(reveal_tiles/preview/grant_ap/remove_mines/ -# refresh_pick——效果引擎 ACTIVE_KINDS 同名闭集),被动件 effect_kinds 词族随 T4 秘宝迁移退役 -# (passive 行改 triggers 事件订阅形态);旧词保留共存至迁移完成。 +# 主动件 kind 词族(reveal_tiles/preview/grant_ap/remove_mines/ +# refresh_pick——效果引擎 ACTIVE_KINDS 同名闭集);被动件不走 effect_kinds 词族 +# (passive 行走 triggers 事件订阅形态);旧词保留共存至迁移完成。 const EFFECT_KINDS := ["mine_reveal", "reward_preview", "ap_grant", "mine_hit_halve", "reflect_damage", "ap_rounds_front", "ap_charge_safe", "cell_removal", "reward_weight_bias", "bonus_refresh", "reveal_tiles", "preview", "grant_ap", "remove_mines", "refresh_pick", - # 迭代 22 秘宝实装批 T1 扩签八型: + # 以下八型: # 常时参数面六型(无事件订阅——开局/装板参数注入,注入面按装配集 kind 分发读取): # light_radius_bonus=微光半径加值〔阔视野带〕/rap_transfer_mult=停手转存率千分比〔储备罐 125=1.25〕/ # dig_range_bonus=挖掘距离加值〔远程镐〕/seal_range_free=封印不限相邻〔信标网络〕/ @@ -34,34 +34,34 @@ const EFFECT_KINDS := ["mine_reveal", "reward_preview", "ap_grant", # 主动分发两型:safe_dig=安全格直开(天眼——走普通挖格规则全额兑付,C5 裁)/mine_count_preview=危险格数量预告(巢穴预告) "light_radius_bonus", "rap_transfer_mult", "dig_range_bonus", "seal_range_free", "refresh_stock_grant", "shop_refresh_bonus", "safe_dig", "mine_count_preview"] -const TARGETS := ["none", "area_3x3", "board_wide", "cell"] # 迭代 22 T1 扩 cell=单格真视(线香——≤3×3 窄域契约内) +const TARGETS := ["none", "area_3x3", "board_wide", "cell"] # cell=单格真视(线香——≤3×3 窄域契约内) const USE_PHASES := ["active_dig"] const FORMS := ["", "passive", "active_charged"] -# 档位词表(迭代 22 T1——槽位档位约束数据面:槽位可装 ≤ 槽位档位的件;词表沿 feats/adventure TIERS) +# 档位词表(槽位档位约束数据面:槽位可装 ≤ 槽位档位的件;词表沿 feats/adventure TIERS) const TIERS := ["common", "excellent", "rare", "legendary"] -# 档位序(迭代 22 T2——装配档位校验取数源:件档 rank ≤ 装入位序(格 1=普通格/格 2=优秀格/格 3=稀有格 +# 档位序(装配档位校验取数源:件档 rank ≤ 装入位序(格 1=普通格/格 2=优秀格/格 3=稀有格 # 递增,向下兼容=高档格可装低档件);rank 越大档越高) const TIER_RANK := {"common": 1, "excellent": 2, "rare": 3, "legendary": 4} -# 充能重置周期(迭代 22 T1 扩签——现役仅 adventure=每冒险;battle=每战重置〔线香〕/level=每关重置〔天眼〕) +# 充能重置周期(现役仅 adventure=每冒险;battle=每战重置〔线香〕/level=每关重置〔天眼〕) const CHARGE_RESETS := ["adventure", "battle", "level"] # magnitude 消费面(≥1 校验):grant_ap 与同调 N 值 kind;其余 kind 活行 magnitude 恒 0 const MAGNITUDE_KINDS := ["ap_grant", "reflect_damage", "ap_rounds_front", "ap_charge_safe", "reward_weight_bias", "bonus_refresh", "grant_ap", "light_radius_bonus", "rap_transfer_mult", "dig_range_bonus", "seal_range_free", "refresh_stock_grant", "shop_refresh_bonus"] -# 真视类 kind(迭代 22 T1 护栏扩面——活行 target 必须 ∈ {area_3x3, cell}:真视窄域 ≤3×3 契约) +# 真视类 kind(护栏:活行 target 必须 ∈ {area_3x3, cell}:真视窄域 ≤3×3 契约) const REVEAL_KINDS := ["mine_reveal", "reveal_tiles"] # 🔴 零裸 flat 结构护栏:行键白名单封闭(键出域=加载致命)——机制轴禁无条件属性加项的表结构承载 const KEY_WHITELIST := ["item_id", "display_name", "dimension_tags", "effect_kinds", "target", "magnitude", "use_phase", "retired", "deferred", "form", "charges_per_adventure", "slot_cost", "unlock_requires", "effective_rounds", "charge_n", "triggers", "desc", - "tier", "charge_reset", "unlock_keystone_cost"] # 迭代 22 T1 扩三键(档位/充能周期/钥石购买价) + "tier", "charge_reset", "unlock_keystone_cost"] # 三键=档位/充能周期/钥石购买价 func validate() -> Array: var errs: Array[Variant] = [] if rows.is_empty(): - # 空表合法态(2026-09-17 用户拍板——切片期无道具内容;F2 覆盖检查仅对非空清单执行) + # 空表合法态(切片期无道具内容;F2 覆盖检查仅对非空清单执行) return errs var seen := {} for row in rows: @@ -95,8 +95,8 @@ func validate() -> Array: for k in row.keys(): if not KEY_WHITELIST.has(String(k)): errs.append({"category": "zero_flat", "message": "%s 行键出白名单: %s(KEY_WHITELIST 外键禁入)" % [iid, String(k)]}) - # triggers 事件订阅行(内容数据驱动扩展批 T2/T4——被动件换代形态;与 effect_kinds 互斥校验 - # 面=passive 行(换代单形态——效果行为只走订阅);active_charged 行两形合法并存 + # triggers 事件订阅行(被动件形态;与 effect_kinds 互斥校验 + # 面=passive 行(单形态——效果行为只走订阅);active_charged 行两形合法并存 # (effect_kinds=主动分发通道 + triggers=受理闸订阅,掘进蓄能先例)) if row.has("triggers"): if (row.get("effect_kinds", []) as Array).size() > 0 and String(row.get("form", "")) != "active_charged" and not bool(row.get("retired", false)): @@ -120,7 +120,7 @@ func validate() -> Array: errs.append({"category": "dup_key", "message": "%s effect_kind 重复: %s" % [iid, kind]}) kind_seen[kind] = true # 承重护栏①真视窄域:真视类活行 target 必须 area_3x3 或 cell(一次最多 3×3,禁全图看雷; - # 迭代 22 T1 护栏扩面——reveal_tiles 与新 cell 档纳入同护栏,线香单格=cell ⊂ 3×3 契约内) + # reveal_tiles 与 cell 档纳入同护栏,线香单格=cell ⊂ 3×3 契约内) for rv in REVEAL_KINDS: if kind_seen.has(String(rv)) and not (target == "area_3x3" or target == "cell"): errs.append({"category": "load_bearing", "message": "%s 真视窄域护栏:%s 行 target 必须 area_3x3 或 cell,实得 %s(秘宝 GDD 结构冻结)" % [iid, String(rv), target]}) @@ -143,7 +143,7 @@ func validate() -> Array: if form != "": if int(row.get("slot_cost", 1)) != 1: errs.append({"category": "load_bearing", "message": "%s 同调占位统一 1 槽(slot_cost 恒 1——底稿裁决 5,schema 强制)" % iid}) - # 档位必填(迭代 22 T1——槽位档位约束数据面:件档≤格档判定的取数源) + # 档位必填(槽位档位约束数据面:件档≤格档判定的取数源) var tier: String = String(row.get("tier", "")) if not TIERS.has(tier): errs.append({"category": "domain", "message": "%s 同调行 tier 必填且 ∈ %s,实得 %s" % [iid, str(TIERS), tier]}) @@ -153,7 +153,7 @@ func validate() -> Array: if form == "active_charged" and charges < 0: errs.append({"category": "domain", "message": "%s active_charged 行 charges_per_adventure 越域 ≥0,实得 %d" % [iid, charges]}) if form == "active_charged" and charges == 0: - # 充能 0=积点制/滑耗制合法态(迭代 22 T1——试炼镐转化获取,无固定充能上限): + # 充能 0=积点制/滑耗制合法态(试炼镐转化获取,无固定充能上限): # 必须带使用闸——ap_charge_safe 滑耗(安全格积点)或 treasure_used+counter_spend 受理闸,二者缺一即孤儿行 var has_gate := kind_seen.has("ap_charge_safe") if not has_gate and row.has("triggers"): @@ -163,13 +163,13 @@ func validate() -> Array: break if not has_gate: errs.append({"category": "cross_field", "message": "%s active_charged 行 charges=0(积点制)须带 ap_charge_safe 或 counter_spend 受理闸,实得二者皆无" % iid}) - # 充能重置周期(迭代 22 T1 扩签:adventure 缺省/battle 每战/level 每关;仅 active_charged 行可设) + # 充能重置周期(adventure 缺省/battle 每战/level 每关;仅 active_charged 行可设) var creset: String = String(row.get("charge_reset", "adventure")) if not CHARGE_RESETS.has(creset): errs.append({"category": "enum", "message": "%s charge_reset 出域 %s: %s" % [iid, str(CHARGE_RESETS), creset]}) if form != "active_charged" and row.has("charge_reset") and creset != "adventure": errs.append({"category": "cross_field", "message": "%s 非 active_charged 行 charge_reset 仅可缺省(adventure),实得 %s" % [iid, creset]}) - # 解锁混合制字段校验(迭代 22 T1 契约 6:钥石购买价与条件谓词互斥——每件单解锁方式,混合不做) + # 解锁混合制字段校验(契约 6:钥石购买价与条件谓词互斥——每件单解锁方式,混合不做) var price: int = int(row.get("unlock_keystone_cost", 0)) var ureq_count: int = (row.get("unlock_requires", []) as Array).size() if price != 0 and ureq_count > 0: @@ -206,7 +206,7 @@ func validate() -> Array: return errs -# 同调行词表(form 非空)——装配覆盖层/效果接线/同调位上限的唯一取数口径(迭代 11 第①批 T1) +# 同调行词表(form 非空)——装配覆盖层/效果接线/同调位上限的唯一取数口径 func attunement_rows() -> Array: var out: Array[Variant] = [] for row in rows: @@ -216,7 +216,7 @@ func attunement_rows() -> Array: # 过渡行词表(form 空 = 切片期过渡形态活行)——掉落投放/停点池/过渡覆盖面的取数口径; -# 同调行永不入过渡渠道。T7 退役面切换后本口径随渠道消亡。 +# 同调行永不入过渡渠道。 func transitional_rows() -> Array: var out: Array[Variant] = [] for row in rows: diff --git a/game/data/schemas/variation_table.gd b/game/data/schemas/variation_table.gd index 1ab435b0..b88bd5da 100644 --- a/game/data/schemas/variation_table.gd +++ b/game/data/schemas/variation_table.gd @@ -7,14 +7,14 @@ extends Resource @export var rows: Array[Dictionary] = [] # Array[Dictionary] # 布置参数(表头字段;数量公式 = round(候选池格数 × percent_of_cells / 100) + (关卡序号 − 1) × per_level_bonus, -# 连通片生长、单片 ≤ pack_max——2026-09-19 用户拍板:图规模百分比 × 关卡递增,全连通、单片不超 4; -# 2026-09-21 用户拍板基数修正:百分比基数 = 候选池(安全格 − 初始展开区,即实际可挖格)而非总格数) +# 连通片生长、单片 ≤ pack_max——图规模百分比 × 关卡递增,全连通、单片不超 4; +# 百分比基数 = 候选池(安全格 − 初始展开区,即实际可挖格)而非总格数) @export var percent_of_cells: int = 5 @export var per_level_bonus: int = 2 @export var pack_max: int = 4 const SCOPES := ["region", "global"] -# resource_face = 资源面偏斜(全局作用域变异首发批 2026-10-04——整图修摇号分布:生存族按 effect_value% +# resource_face = 资源面偏斜(全局作用域变异——整图修摇号分布:生存族按 effect_value% # 下调、进攻族等比上浮重归一,不动任何格子数据;effect_value 语义随行域切换,不适用 flat_damage [1,9]) const EFFECTS := ["none", "flat_damage", "hide_number", "resource_face"] # 效果词表:直伤 / 数字遮蔽 / 资源面偏斜(可扩充) const TRIGGERS := ["on_open", "on_number_shown", "always"] # 触发词表:被打开即触发 / 打开且显示数字时触发 / 板级恒在无触发时机(可扩充) @@ -46,7 +46,7 @@ func validate() -> Array: errs.append({"category": "enum", "message": "%s trigger 出域: %s" % [vid, row.get("trigger")]}) if not PLACEMENTS.has(row.get("placement", "")): errs.append({"category": "enum", "message": "%s placement 出域: %s" % [vid, row.get("placement")]}) - # 跨字段互锁(加载期致命——枚举语义一致性随首批类型定稿批 2026-09-19 立闸): + # 跨字段互锁(加载期致命——枚举语义一致性立闸): # 伤害型 = 挖开即伤 ⇒ 触发 on_open + 只落未开格(closed_only)+ 伤害量为加法核小整数 if row.get("effect", "") == "flat_damage": if row.get("trigger", "") != "on_open": @@ -61,7 +61,7 @@ func validate() -> Array: errs.append({"category": "cross_field", "message": "%s hide_number ⇒ trigger 必为 on_number_shown" % vid}) # 信息遮蔽型只允许落安全格(遮蔽对象是数字;危险格无数字可遮)——placement=any 时由读取方 # 呈现面按 kind=safe 自然短路,此处不设布置约束 - # 全局作用域型互锁(2026-10-04 首发批——resource_face ⟺ scope=global 三条 + 新值域; + # 全局作用域型互锁(resource_face ⟺ scope=global 三条 + 新值域; # 判定键=effect/scope 词值,既有六 region 行(flat_damage/hide_number)不入本组——零误伤) if row.get("effect", "") == "resource_face": if row.get("scope", "") != "global": diff --git a/game/presentation/battle_narrator.gd b/game/presentation/battle_narrator.gd index c53abb92..aee45931 100644 --- a/game/presentation/battle_narrator.gd +++ b/game/presentation/battle_narrator.gd @@ -19,7 +19,7 @@ static func rest_line(healed: int, hp: int, max_hp: int) -> String: return "[color=#%s]恢复点:回复 %d HP(→ %d/%d)[/color]" % [UiKit.HEX_LOG_HEAL, healed, hp, max_hp] -# 商店房行(GP+商店房实施批——到达即开店;购买/离开归玩家意图) +# 商店房行(到达即开店;购买/离开归玩家意图) static func shop_line(gp: int) -> String: return "[color=#%s]商店房:GP %d——购买即时生效,离开后选下一跳[/color]" % [UiKit.HEX_LOG_GAIN, gp] @@ -57,8 +57,8 @@ static func battle_end_text(result: String, level_end: bool) -> String: static func phase_text(round_index: int, battle_result: String, waiting: bool, boss_active: bool, boss_name: String) -> String: var boss_tag := " · Boss:%s" % boss_name if boss_active else "" if battle_result != "": - # 打磨包 2026-09-29——判定文案两处措辞统一:相位行随结算判定行同词(战斗胜利/战斗失败, - # 与 battle_end_text 同源措辞),「战斗结束」退役 + # 判定文案两处措辞统一:相位行随结算判定行同词(战斗胜利/战斗失败, + # 与 battle_end_text 同源措辞),不用「战斗结束」 return "第 %d 轮 · %s%s" % [round_index, "战斗胜利" if battle_result == "victory" else "战斗失败", boss_tag] if waiting: return "第 %d 轮 · 结算中%s" % [round_index, boss_tag] @@ -66,9 +66,9 @@ static func phase_text(round_index: int, battle_result: String, waiting: bool, b # Boss 名解析(runner Boss 节点 → enemy 表行名;缺省遗迹守卫)。 -# 行集多行后取**首行** display_name(2026-10-07 行集多行批——行序即契约的呈现面后果, +# 行集多行时取**首行** display_name(行序即契约的呈现面后果, # Boss 行集混编护卫时 Boss 名显示可能为护卫名,知情代价登记 敌人系统 v0.15 / 出口报告; -# 零内容期每坐标恰一行,行为零变化) +# 每坐标恰一行时无此歧义) static func boss_name(runner, db) -> String: if runner != null: var node: Dictionary[Variant, Variant] = runner.current_node() @@ -79,7 +79,7 @@ static func boss_name(runner, db) -> String: return "遗迹守卫" -# ---- 提升三选一文案族(迭代 10 奖励重构批——big_reward_text 随三件套退役)---- +# ---- 提升三选一文案族 ---- # 三选一停点头部行(回血反馈 + 选择引导;钥石增量行不上本面——单一展示面归战斗总结结算框, # level-clear.md v2 禁入清单口径) @@ -96,7 +96,7 @@ static func curio_pick_header(payload: Dictionary) -> String: # 三选一选项卡文案(件名 + 档位 + 效果读数;值 = 冒险表行值,组合根喂入;TP0 令牌池——档位词 # 对齐 v2.2 追认 b 口径:小/大前缀(小GP/大GP 族)、恢复/AP 不带档位词;道具件掷定前置时 -# treasure_line = 具体道具「名 · 效果摘要」行——池种退役后恒空走通用分支,机械惰性保留) +# treasure_line = 具体道具「名 · 效果摘要」行——常空走通用分支) static func bonus_card_text(id: String, tier: String, value: int, treasure_line: String = "") -> String: var ts := "" if tier == "common": @@ -133,10 +133,10 @@ static func bonus_result_text(result: Dictionary) -> String: return "已选择:%s\n其余选项已丢弃(不可反悔)" % name -# 特性卡片文案(迭代 12 T1;2026-10-04 呈现补强——第二行=效果摘要,用户反馈「不知道件是 -# 干嘛的」缺口承载。内容数据驱动扩展批 T3 文案表值化:摘要=数据行 desc 字段,零硬编码映射。 -# 2026-10-12 奇物呈现整改批:「件名 · 流派」族名字样摘除(内部分类禁上玩家可见面——新 29 行 -# 无 archetype,原 fallback 实显兜底词「流派」=僵尸文案),卡片=件名+效果摘要两行) +# 特性卡片文案(第二行=效果摘要——须可读「不知道件是 +# 干嘛的」。文案表值化:摘要=数据行 desc 字段,零硬编码映射。 +# 「件名 · 流派」族名字样不上卡片(内部分类禁上玩家可见面——29 行 +# 表无 archetype,fallback 兜底词「流派」会实显僵尸文案),卡片=件名+效果摘要两行) static func feat_card_text(row: Dictionary) -> String: if row.is_empty() or String(row.get("feat_id", "")) == "": return "特性\n???" @@ -151,7 +151,7 @@ static func bonus_keystone_line(payload: Dictionary) -> String: return "钥石 +%d · 累计 %d" % [int(payload.get("keystone_gained", 0)), int(payload.get("keystone_total", 0))] -# 奖励节点三选一头部行(迭代 10 追加批——与通关三选一共享同池;node-reward.md v2) +# 奖励节点三选一头部行(与通关三选一共享同池;node-reward.md v2) static func node_curio_header() -> String: return "关卡奖励点\n从提升池抽三选一(与通关三选一同池同权重同上限):\n选择一件带走:" @@ -168,7 +168,7 @@ static func adventure_summary_text(summary: Dictionary) -> String: int(summary.get("keystone_total", 0)), int(summary.get("master_seed", 0))] -# 钥石入账明细文案(元进度实现批;迭代 10 改口径——钥石全源 = Boss 逐杀掉落,「大奖励」行退役; +# 钥石入账明细文案(钥石全源 = Boss 逐杀掉落,无「大奖励」行; # name_lookup = item_id → 显示名投影,由组合根自 meta 表喂入) static func keystone_settle_text(detail: Dictionary, name_lookup: Dictionary = {}) -> String: var parts: Array[Variant] = [] diff --git a/game/presentation/camp_flow_context.gd b/game/presentation/camp_flow_context.gd index 7d0b6d41..3a986547 100644 --- a/game/presentation/camp_flow_context.gd +++ b/game/presentation/camp_flow_context.gd @@ -1,6 +1,6 @@ class_name CampFlowContext extends RefCounted -# 营地/商店投影的构造上下文(迭代 27 T4——审计 P1-5:控制器构造参数收拢为 context 对象, +# 营地/商店投影的构造上下文(控制器构造参数收拢为 context 对象, # 原 13 参长签名收一处命名面——单测可直接 new() 本 context + 控制器获得独立实例化缝)。 # 字段即原构造参数逐一同名迁移;依赖仅视图句柄 + 查询/编排 Callable(组合根注入)。 diff --git a/game/presentation/camp_shop_presenter.gd b/game/presentation/camp_shop_presenter.gd index bb2001f8..d79155ee 100644 --- a/game/presentation/camp_shop_presenter.gd +++ b/game/presentation/camp_shop_presenter.gd @@ -5,7 +5,7 @@ extends RefCounted var db -var _meta_get: Callable # () → 元进度账本现值(组合根 lambda——探针 isolate_save 换注面,迭代13 T4 实证) +var _meta_get: Callable # () → 元进度账本现值(组合根 lambda——探针 isolate_save 换注面) var _save_get: Callable # () → 存档承载现值(同上——营地 recent 摘要读数面) var camp_overlay: CampOverlay var shop_overlay: ShopOverlay @@ -20,7 +20,7 @@ var _refresh_resume_button: Callable func _init(ctx: CampFlowContext) -> void: - # 迭代 27 T4——构造参数收拢 context 对象(P1-5:13 参长签名收一处命名面;字段逐一同名迁移) + # 构造参数收拢 context 对象(13 参长签名收一处命名面) db = ctx.db _meta_get = ctx.meta_get _save_get = ctx.save_get @@ -42,30 +42,30 @@ func open_camp() -> void: var meta = _meta_get.call() if meta == null: return - meta.refresh_treasure_unlocks() # 迭代 22 T2——条件解锁刷新换代(旧工坊面退役) + meta.refresh_treasure_unlocks() # 条件解锁刷新 start_overlay.visible = false - _open_modal.call(camp_overlay) # 模态栈单口(T3 收口批——登记层开合一律走栈) + _open_modal.call(camp_overlay) # 模态栈单口(登记层开合一律走栈) camp_overlay.open_camp(camp_data()) _refresh_presentations.call() func on_camp_closed() -> void: - _close_modal.call(camp_overlay) # 模态栈单口(T3 收口批) + _close_modal.call(camp_overlay) # 模态栈单口 start_overlay.visible = true - _refresh_resume_button.call() # 迭代 8 卡②——回菜单按断点在档态刷新 + _refresh_resume_button.call() # 回菜单按断点在档态刷新 _refresh_presentations.call() # 关闭后刷新顶栏(工坊解锁可能变了余额侧读数面) # 营地快照投影(纯读——秘宝匣 12 件/同调装配/树面/锻造工坊两区六路线/余额/最近冒险;拼句归 -# CampOverlay,账面归 MetaProgression。属性锻造三行投影已删——迭代 21 T4 柜台退役;工坊六行换代 -# = 迭代 22 T2 秘宝匣;forge 键=迭代 23 T6 锻造工坊路线行板投影) +# CampOverlay,账面归 MetaProgression。锻造三行投影不在本投影内; +# workshop 键=秘宝匣 12 件;forge 键=锻造工坊路线行板投影) func camp_data() -> Dictionary: var meta = _meta_get.call() return { "balance": meta.keystone_balance() if meta != null else 0, "workshop": meta.treasure_shop_status() if meta != null else [], # 键名沿 workshop(视图消费键不变——行内容=秘宝匣 12 件解锁投影) - "forge": meta.forge_shop_status() if meta != null else [], # 迭代 23 T6——锻造工坊两区六路线投影 - "attune": meta.attune_camp_status() if meta != null else {}, # 迭代 11 第①批 T4——同调装配面投影 + "forge": meta.forge_shop_status() if meta != null else [], # 锻造工坊两区六路线投影 + "attune": meta.attune_camp_status() if meta != null else {}, # 同调装配面投影 "tree": meta.tree_camp_rows() if meta != null else [], # 树面投影(含 forge_workshop/ks_workshop 钥匙门判据行) "fork_groups": meta.tree_fork_groups() if meta != null else [], "recent": _save_get.call().recent_summaries() if _save_get.call() != null else [], @@ -76,7 +76,7 @@ func on_camp_buy(attr: String) -> void: var meta = _meta_get.call() if meta == null: return - # 秘宝钥石购买(迭代 22 秘宝批 T4——秘宝匣柜台购买钮意图;写口唯一=buy_treasure_unlock, + # 秘宝钥石购买(秘宝匣柜台购买钮意图;写口唯一=buy_treasure_unlock, # 余额闸/重复购/条件件误购三重拒绝零副作用) if attr != "attune_refresh": if not meta.buy_treasure_unlock(attr): @@ -85,8 +85,8 @@ func on_camp_buy(attr: String) -> void: camp_overlay.refresh_camp(camp_data()) _refresh_presentations.call() return - # Y 刷新升级行购买(迭代 11 第①批 T4——P1 甲;双入口之一 Q1 裁乙——树上 ks_refresh 同账; - # 按钮禁用为常态防线,兜底拒绝可见 pattern 1。属性锻造面已退役——buy_forge 分支随批删除) + # Y 刷新升级行购买(双入口之一——树上 ks_refresh 同账; + # 按钮禁用为常态防线,兜底拒绝可见 pattern 1。本函数无属性锻造分支) if not meta.buy_attune_refresh(): toast.show_toast("购买被拒", "warn") return @@ -94,7 +94,7 @@ func on_camp_buy(attr: String) -> void: _refresh_presentations.call() -# 同调装配切换(迭代 11 第①批 T4——装配关系唯一写口经 MetaProgression.toggle_attunement;满位兜底拒绝可见) +# 同调装配切换(装配关系唯一写口经 MetaProgression.toggle_attunement;满位兜底拒绝可见) func on_camp_attune_toggle(item_id: String) -> void: var meta = _meta_get.call() if meta == null: @@ -105,7 +105,7 @@ func on_camp_attune_toggle(item_id: String) -> void: camp_overlay.refresh_camp(camp_data()) -# 天赋树购买(迭代 12 T9——写口唯一归 MetaProgression.tree_buy/tree_buy_fork;Fork 节点购=激活侧) +# 天赋树购买(写口唯一归 MetaProgression.tree_buy/tree_buy_fork;Fork 节点购=激活侧) func on_camp_tree_buy(node_id: String) -> void: var meta = _meta_get.call() if meta == null: @@ -118,7 +118,7 @@ func on_camp_tree_buy(node_id: String) -> void: _refresh_presentations.call() -# A/B 免费切换(迭代 12 T8——同组换侧零币;未激活组走购买面) +# A/B 免费切换(同组换侧零币;未激活组走购买面) func on_camp_fork_toggle(group: String, side: String) -> void: var meta = _meta_get.call() if meta == null: @@ -130,7 +130,7 @@ func on_camp_fork_toggle(group: String, side: String) -> void: _refresh_presentations.call() -# ---- 锻造工坊三意图(迭代 23 T6——契约 9:写口唯一归 MetaProgression 锻造写口族;UI 只发意图)---- +# ---- 锻造工坊三意图(契约 9:写口唯一归 MetaProgression 锻造写口族;UI 只发意图)---- # 路线购买(几何价;余额不足/未解锁/满级=核心拒绝零副作用,兜底拒绝可见 pattern 1) func on_camp_forge_buy(route_id: String) -> void: var meta = _meta_get.call() diff --git a/game/presentation/curio_flow_context.gd b/game/presentation/curio_flow_context.gd index 8a0dfee0..480fb587 100644 --- a/game/presentation/curio_flow_context.gd +++ b/game/presentation/curio_flow_context.gd @@ -1,6 +1,6 @@ class_name CurioFlowContext extends RefCounted -# 三选一/替换子交互的构造上下文(迭代 27 T4——审计 P1-5:控制器构造参数收拢为 context 对象, +# 三选一/替换子交互的构造上下文(控制器构造参数收拢为 context 对象, # 原 16 参长签名收一处命名面——单测可直接 new() 本 context + 控制器获得独立实例化缝)。 # 字段即原构造参数逐一同名迁移;依赖仅视图句柄 + 查询/编排 Callable(组合根注入)。 diff --git a/game/presentation/curio_interact_controller.gd b/game/presentation/curio_interact_controller.gd index 967a2eb3..f40874d3 100644 --- a/game/presentation/curio_interact_controller.gd +++ b/game/presentation/curio_interact_controller.gd @@ -8,7 +8,7 @@ extends RefCounted const Narrator := preload("res://presentation/battle_narrator.gd") var db -var _meta_get: Callable # () → 元进度账本现值(组合根 lambda——探针 isolate_save 换注面,迭代13 T4 实证) +var _meta_get: Callable # () → 元进度账本现值(组合根 lambda——探针 isolate_save 换注面) var curio_overlay: CurioPickOverlay var end_overlay: BattleEndOverlay var board_view: BoardView @@ -18,18 +18,18 @@ var _adventure_get: Callable # () → 冒险结构现值(组合根 var _runner_get: Callable # () → 关卡推进器现值(组合根 lambda——reward_node 继续推进) var _adventure_mode_get: Callable # () → 冒险模式标记现值(组合根 lambda) var _open_modal: Callable # 模态栈单口(组合根) -var _open_modal_after_playback: Callable # 演播后排窗单口(T17——组合根) +var _open_modal_after_playback: Callable # 演播后排窗单口(组合根) var _close_modal: Callable var _refresh_presentations: Callable var _fatal_screen: Callable var _gp_summary: Callable # () → 战斗总结 GP 行文案(组合根 lambda——_last_gain_amount 取数面在根) -var _pending_curio := {} # 三选一停点载荷暂存(迭代 10——战斗总结结算确认后开三选一面;续玩停点复用) +var _pending_curio := {} # 三选一停点载荷暂存(战斗总结结算确认后开三选一面;续玩停点复用) var _curio_context := "level_clear" # 三选一面上下文(level_clear=通关停点→推进下一关 / reward_node=奖励节点→回图选路) func _init(ctx: CurioFlowContext) -> void: - # 迭代 27 T4——构造参数收拢 context 对象(P1-5:16 参长签名收一处命名面;字段逐一同名迁移) + # 构造参数收拢 context 对象(16 参长签名收一处命名面) db = ctx.db _meta_get = ctx.meta_get curio_overlay = ctx.curio_overlay @@ -49,7 +49,7 @@ func _init(ctx: CurioFlowContext) -> void: # 停点在途判据(组合根 _on_battle_end_continue 分派面——战斗总结确认后开三选一) -# 续玩停点恢复入口(true=已接手呈现,调用方中止后续分派)。空候选降级(2026-10-06 用户令): +# 续玩停点恢复入口(true=已接手呈现,调用方中止后续分派)。空候选降级: # 候选 0 件不开选择面(空面无卡无钮=死面)——消化停点后按上下文直落后续推进(战斗总结面已 # 给过玩家确认拍,三选一环节整体跳过) func resume_if_pending() -> bool: @@ -61,7 +61,7 @@ func resume_if_pending() -> bool: return true -# 停点空候选跳过(2026-10-06 用户令——「选出来 0 个则直接跳过该环节」):分派与 on_continue +# 停点空候选跳过(「选出来 0 个则直接跳过该环节」):分派与 on_continue # 同构(level_clear=推进下一关 / reward_node=兑付确认回图选路 / feat_ticket=只关面回店), # 差异仅零面可收——curio_overlay 未开不 close。core 停点经 skip_empty_curio 消化后推进 #(continue_to_next_level 的「停点未兑付拒推进」守卫因此放行)。 @@ -90,18 +90,18 @@ func on_presented(payload: Dictionary) -> void: _pending_curio = payload.duplicate(true) _curio_context = "feat_ticket" if (_pending_curio.get("candidates", []) as Array).is_empty(): - # 空候选防御(2026-10-06 用户令——零卡不开死面;core _redeem_feat_ticket 守卫外的末道) + # 空候选防御(零卡不开死面;core _redeem_feat_ticket 守卫外的末道) _skip_empty_stop() return _open_modal.call(curio_overlay) curio_overlay.open_pick(Narrator.node_curio_header(), _curio_card_texts(payload.get("candidates", []) as Array)) return if int(payload.get("aux_cleared", 0)) > 0: - toast.show_toast("上关剩余 %d 件秘宝已随关卡结束清空" % int(payload.get("aux_cleared", 0)), "info") # 迭代 7 T4 清空反馈 + toast.show_toast("上关剩余 %d 件秘宝已随关卡结束清空" % int(payload.get("aux_cleared", 0)), "info") # 清空反馈 _pending_curio = payload.duplicate(true) _curio_context = "level_clear" if bool(payload.get("refreshed", false)): - # 刷新重发(2026-10-06):refreshed 标直落选择面——不再重开胜利总结面 + # 刷新重发:refreshed 标直落选择面——不再重开胜利总结面 show_pick() return end_overlay.open_victory(Narrator.battle_end_text("victory", false), "继续", @@ -111,15 +111,15 @@ func on_presented(payload: Dictionary) -> void: _refresh_presentations.call() -# 奖励节点三选一(迭代 10 追加批——与通关三选一共享同池同权重同上限;CurioPickOverlay 共用面)。 -# 原「秘宝投放渠道」三选一(迭代 7 过渡形态)随批退役;替换子交互随迭代 22 T5 拆除。 +# 奖励节点三选一(与通关三选一共享同池同权重同上限;CurioPickOverlay 共用面)。 +# 无替换子交互(同调装配不可变,见类头)。 func present_node_curio() -> void: var adventure = _adventure_get.call() _curio_context = "reward_node" var node_draw: Dictionary[Variant, Variant] = adventure.node_curio_candidates() var node_cands: Array[Variant] = node_draw.get("candidates", []) as Array if node_cands.is_empty(): - # 空池降级(2026-10-06 用户令)——不开面、不挂节点停点(present_node_curio 未调即未挂), + # 空池降级——不开面、不挂节点停点(present_node_curio 未调即未挂), # 兑付确认直落回图选路(auto-sim「node_entered 回调内立即 continue_after_node」先例) toast.show_toast("可用战利品为空——本次三选一跳过", "info") var runner = _runner_get.call() @@ -129,7 +129,7 @@ func present_node_curio() -> void: _open_modal.call(curio_overlay) curio_overlay.open_pick(Narrator.node_curio_header(), _curio_card_texts(node_cands)) adventure.present_node_curio(node_cands) - _feed_refresh_display(adventure) # 迭代 11 第①批 T5b + 2026-10-06 对齐商店——刷新面投喂单点 + _feed_refresh_display(adventure) # 刷新面投喂单点 # 三选一面开出(战斗总结结算确认 / 续玩停点恢复) @@ -139,7 +139,7 @@ func show_pick() -> void: curio_overlay.open_pick(Narrator.curio_pick_header(payload), _curio_card_texts(payload.get("candidates", []) as Array)) var adventure = _adventure_get.call() if adventure != null: - _feed_refresh_display(adventure) # 迭代 11 第①批 T5b + 2026-10-06 对齐商店——刷新面投喂单点 + _feed_refresh_display(adventure) # 刷新面投喂单点 _refresh_presentations.call() @@ -173,10 +173,10 @@ func _curio_card_texts(candidates: Array) -> Array: # 道具件卡片行(掷定前置——具体道具名 + 效果摘要;空 iid = 无预掷回退态显示通用文案)。 -# 内容数据驱动扩展批 T4 文案表值化:效果摘要=数据行 desc 字段直读(零 kind 硬编码映射—— +# 文案表值化:效果摘要=数据行 desc 字段直读(零 kind 硬编码映射—— # 新件写行即有名有姓) -# 三选一刷新(迭代 11 第①批 T5b X/Y 双源 + 2026-10-06 用户令对齐商店 MC-1——免费位用尽转 GP 付费档: +# 三选一刷新(X/Y 双源 + 对齐商店 MC-1——免费位用尽转 GP 付费档: # 同 shop_refresh_cost_base/curve 旋钮、同冒险钱包 runner.gp;通关停点经重发 curio_choice_presented 直落 # 选择面,节点停点在此读在途态重 present——零自动推进契约不破,停点仍在途) func on_refresh() -> void: @@ -246,7 +246,7 @@ func on_continue() -> void: # 秘宝 item_id → 显示名投影(keystone_settle_text/替换子命名文案数据源——拼句归 Narrator); -# 迭代 22 T2 数据源换代:旧工坊行族退役,改读 treasure 装配词表 12 件 +# 数据源=treasure 装配词表 12 件 func item_name_lookup() -> Dictionary: var lookup := {} var meta = _meta_get.call() diff --git a/game/presentation/debug_session.gd b/game/presentation/debug_session.gd index d4deeb0d..d8702bc3 100644 --- a/game/presentation/debug_session.gd +++ b/game/presentation/debug_session.gd @@ -26,7 +26,7 @@ func _init(db_ref, rng_ref, hero_override: Callable, seed_value: Callable) -> vo _seed_value = seed_value -# 单场遭遇原语(2026-09-13 用户裁决:单场用户入口已删——本方法仅 ui_probe 单场段使用; +# 单场遭遇原语(无单场用户入口——本方法仅 ui_probe 单场段使用; # 无延续、standalone 终局语义保留供探针战斗收尾) func start_single(level: int) -> bool: _level_mode = false diff --git a/game/presentation/hud_presenter.gd b/game/presentation/hud_presenter.gd index f6caefcf..0ead2a5b 100644 --- a/game/presentation/hud_presenter.gd +++ b/game/presentation/hud_presenter.gd @@ -7,15 +7,15 @@ extends RefCounted # 每次结算行/轮次/节点变化/动作返回后调用(组合根全量重查装配) -# 2026-09-26 C 区精简批:钱包 GP/钥石投喂退役(中/大循环资源迁出战斗屏——信息归属拍板); -# HP/状态效果单投喂 B 区站桩(原 B/C 双投喂为重复展示——信息归属拍板单一展示面原则) +# 钱包 GP/钥石不在本装配面投喂(中/大循环资源迁出战斗屏——信息归属单一展示面原则); +# HP/状态效果单投喂 B 区站桩(B/C 双投喂属重复展示——单一展示面原则) static func refresh(stage: BattleStageView, info: HeroInfoPanelView, ap_bar: ApBarView, settlement, runner, level_active: bool, db, refresh_remaining: int) -> void: - # 特性列表(v3.5 迭代 9 卡⑫ 2026-09-30——runner 统一加算区投影:商店购买与关卡大奖励 + # 特性列表(runner 统一加算区投影:商店购买与关卡大奖励 # 共账本〔level_runner bonus{atk,max_hp,armor_class}〕;空加算=整节隐藏〔视图内空态纪律〕。 - # 呈现只读投影零核心触碰;行文格式=代拍板白名单项) + # 呈现只读投影零核心触碰;行文格式=白名单项) if runner != null and level_active: - var b: Dictionary[Variant, Variant] = runner.run_ledger.bonus # 迭代 27 T3——加算区住 RunLedger(P1-4 收口) + var b: Dictionary[Variant, Variant] = runner.run_ledger.bonus # 加算区住 RunLedger var lines: Array[String] = [] if int(b.get("atk", 0)) != 0: lines.append("攻击 %+d" % int(b.get("atk", 0))) @@ -26,18 +26,18 @@ static func refresh(stage: BattleStageView, info: HeroInfoPanelView, ap_bar: ApB info.set_level_bonuses(lines) else: info.set_level_bonuses([]) - # 特性持有投影(迭代 12 呈现补齐 2026-10-04——用户反馈「局内奖励选了什么看不到」: - # 逐件行「件名 ×N」〔2026-10-12 整改换代,原逐流派聚合行退役〕;常驻可读+空态隐藏) + # 特性持有投影(「局内奖励选了什么」须可读: + # 逐件行「件名 ×N」;常驻可读+空态隐藏) if runner != null and level_active: info.set_feat_holdings(feat_holdings_lines(db, runner.feats_held())) else: info.set_feat_holdings([]) if settlement == null: - info.set_board_variants([]) # 战斗域角标出战斗即隐(首发批 2026-10-04——空态纪律) + info.set_board_variants([]) # 战斗域角标出战斗即隐(空态纪律) _refresh_out_of_battle(stage, info, ap_bar, runner, level_active, db) return var s: Dictionary[Variant, Variant] = settlement.presentation_snapshot() - # 地形变异常驻角标投影(全局作用域变异首发批 2026-10-04——板级变异快照 → 文案行; + # 地形变异常驻角标投影(板级变异快照 → 文案行; # 空态隐藏=特性段先例;战斗全程常驻防中局遗忘) info.set_board_variants(board_variant_lines(db, s.get("board_variants", []))) var hero: Dictionary[Variant, Variant] = s.hero @@ -66,28 +66,28 @@ static func _refresh_hero(stage: BattleStageView, info: HeroInfoPanelView, s: Di var mod_text := "" if mod_total != 0: mod_text = "(%+d%% %s)" % [mod_total, "·".join(sources)] - # B 区站桩 = HP 与状态效果唯一展示面(2026-09-26 信息归属拍板)——C 区不再重复投喂 + # B 区站桩 = HP 与状态效果唯一展示面(单一展示面原则)——C 区不重复投喂 stage.hero_standee.set_hero(hp, max_hp) stage.hero_standee.set_effects(s.hero_effects) info.set_attack(atk, mod_text) - # 我方 AC 唯一展示面 = C 区(2026-09-26 二轮拍板补入)——快照 armor_class 含战斗内 ac_up 折算 + # 我方 AC 唯一展示面 = C 区——快照 armor_class 含战斗内 ac_up 折算 info.set_armor(int(hero.get("armor_class", 0))) -# ---- 行动经济(AP 点阵 / RAP / 弃图刷新按钮态——RAP 读数 2026-09-26 自 C 区迁入本条) ---- +# ---- 行动经济(AP 点阵 / RAP / 弃图刷新按钮态——RAP 读数在本条) ---- static func _refresh_economy(ap_bar: ApBarView, s: Dictionary, db, refresh_remaining: int) -> void: ap_bar.set_ap(int(s.ap), int(db.action_economy.ap_per_round)) ap_bar.set_rap(int(s.rap)) var digging := String(s.phase) == ActionEconomy.PHASE_ACTIVE ap_bar.set_refresh_state(refresh_remaining, - bool(s.can_refresh) and digging) # Waiting 代理已随 OQ12 退役——UI 仅挖掘期受理 + bool(s.can_refresh) and digging) # 无 Waiting 代理——UI 仅挖掘期受理 ap_bar.set_stop_enabled(bool(s.hero.get("alive", false)) and digging) -# 特性持有文案(迭代 12 呈现补齐——战斗 C 区与关卡选择页两处共用;空持有=空数组。 -# 2026-10-12 奇物呈现整改批:逐流派聚合行退役改逐件行「件名 ×N」——原聚合在新 29 行 -# (无 archetype 字段)下空键兜底实显「流派 ×N · 档一」僵尸文案,且流派档位机制已退役) +# 特性持有文案(战斗 C 区与关卡选择页两处共用;空持有=空数组。 +# 行形态=逐件「件名 ×N」(非逐流派聚合)——表行 +# 无 archetype 字段,聚合形态会空键兜底实显「流派 ×N · 档一」僵尸文案;流派档位非现行机制) static func feat_holdings_lines(db, held: Array) -> Array[String]: var rlines: Array[String] = [] if db == null or db.feats == null or (db.feats.rows as Array).is_empty() or held.is_empty(): @@ -102,9 +102,9 @@ static func feat_holdings_lines(db, held: Array) -> Array[String]: return rlines -# 地形变异常驻角标文案(全局作用域变异首发批 2026-10-04——板级变异 id → 文案行; +# 地形变异常驻角标文案(板级变异 id → 文案行; # 空集 = 空数组=空态隐藏。三行制:变异名+两行效果说明(C 区 240px 宽防裁切)。 -# 文案 2026-10-04 用户人闸反馈常规化修订(原俚语表述退役) +# 文案用常规表述,不用俚语 static func board_variant_lines(db, ids: Array) -> Array[String]: var lines: Array[String] = [] if db == null or db.variation == null: @@ -118,15 +118,15 @@ static func board_variant_lines(db, ids: Array) -> Array[String]: return lines -# ---- 战斗收尾反馈与结算视觉同步(T3 HUD 单通道批 2026-10-02——组合根直改视图收敛入此) ---- +# ---- 战斗收尾反馈与结算视觉同步(组合根直改视图一律收敛入此) ---- # battle_over 收尾反馈:死亡兜底灰化 → 主角态回 idle → RAP 清零脉冲(调试收尾路)→ 状态全清可见反馈。 # 调试/冒险两路共用;reset_rap=false = 冒险收束(RAP 清零由战斗末拍已毕,收束拍不再重放脉冲)。 static func battle_end_feedback(stage: BattleStageView, ap_bar: ApBarView, reset_rap: bool) -> void: stage.gray_all_enemies() # 死亡兜底:站桩灰化残位(禁瞬消语义的战斗收尾面) - stage.settle_hero_idle() # 主角态回 idle(迭代 6 T3 三态收尾) + stage.settle_hero_idle() # 主角态回 idle(三态收尾) if reset_rap: - ap_bar.set_rap(0) # RAP 清零脉冲 + 微文案(载体 2026-09-26 迁 D 区 AP 条) + ap_bar.set_rap(0) # RAP 清零脉冲 + 微文案(载体=D 区 AP 条) stage.hero_standee.set_effects_cleared_feedback() # 状态全清可见反馈(增益状态×4④——载体迁 B 区站桩) @@ -152,7 +152,7 @@ static func _refresh_out_of_battle(stage: BattleStageView, info: HeroInfoPanelVi stage.hero_standee.set_hero(runner.hero_hp, runner.effective_max_hp()) stage.hero_standee.set_effects([]) stage.clear_enemies() # 节点间隙清敌方站桩残位(死亡瞬间的灰化呈现已在结算行驱动完成) - ap_bar.set_rap(0) # battle_over RAP 清零反馈(行动经济 义务——载体 2026-09-26 迁 AP 条) + ap_bar.set_rap(0) # battle_over RAP 清零反馈(行动经济 义务——载体=AP 条) # 三源拒绝可感知(排雷玩法 reject_reason/sub_reason → 玩家文案;pattern 1 双源拒绝反馈) @@ -181,7 +181,7 @@ static func outcome_text(outcome: Dictionary) -> String: return "动作被拒。" -# ---- 调整板批量模拟报告装配(文案归 presenter——视图只 set_text;code-review 2026-09-12 批) ---- +# ---- 批量模拟报告装配(文案归 presenter——视图只 set_text) ---- static func tune_sim_report(n: int, atk_pct: int, hp_pct: int, wins: int, dmg_all: Array, hp_left_win: Array, hp_boss: Array, rounds_all: Array, death_nodes: Dictionary, base_hp: int) -> String: var lines: Array[String] = [] diff --git a/game/presentation/main.gd b/game/presentation/main.gd index 33021374..c8fe9a97 100644 --- a/game/presentation/main.gd +++ b/game/presentation/main.gd @@ -5,7 +5,7 @@ ## 局态全在 run_scope.gd 节点,禁在屏/视图侧持有局态引用;autoload 节点路径常量单点在 AUTOLOAD_PATH_*。 extends Control -# autoload 节点路径单点(迭代 27 T6 P2-2 降格实现:审计处方「编译期全局名」与本仓 --script +# autoload 节点路径单点(降格实现:审计处方「编译期全局名」与本仓 --script # 模式编译器不解析裸 autoload 标识符冲突〔run_all.gd 头注+pacing 实证〕——字符串拼写风险 # 收敛到四常量,类型面由读视图属性承载) const AUTOLOAD_PATH_CFG := "/root/ConfigDB" @@ -18,11 +18,11 @@ const Narrator := preload("res://presentation/battle_narrator.gd") const ModalStack := preload("res://presentation/modal_stack.gd") const TuneSimController := preload("res://presentation/tune_sim_controller.gd") const DebugSessionScript := preload("res://presentation/debug_session.gd") -const RowPacer := preload("res://presentation/row_pacer.gd") # 结算行排播泵(T3 拆件批) -const TreasureInteractController := preload("res://presentation/treasure_interact_controller.gd") # 秘宝两步交互(T3 拆件批) -const CurioInteractController := preload("res://presentation/curio_interact_controller.gd") # 三选一与替换子交互(T4/D4 拆件批) -const CampShopPresenter := preload("res://presentation/camp_shop_presenter.gd") # 营地/商店投影(T4/D4 拆件批) -const MenuScreenScene := preload("res://presentation/scenes/menu_screen.tscn") # 三屏壳场景(迭代 27 T1) +const RowPacer := preload("res://presentation/row_pacer.gd") # 结算行排播泵 +const TreasureInteractController := preload("res://presentation/treasure_interact_controller.gd") # 秘宝两步交互 +const CurioInteractController := preload("res://presentation/curio_interact_controller.gd") # 三选一与替换子交互 +const CampShopPresenter := preload("res://presentation/camp_shop_presenter.gd") # 营地/商店投影 +const MenuScreenScene := preload("res://presentation/scenes/menu_screen.tscn") # 三屏壳场景 const CampScreenScene := preload("res://presentation/scenes/camp_screen.tscn") const AdventureScreenScene := preload("res://presentation/scenes/adventure_screen.tscn") @@ -48,13 +48,13 @@ const LAYER_CONTRACT: Array[Dictionary] = [ {"key": "inter_overlay", "kind": "state", "tags": []}, {"key": "confirm_dialog", "kind": "modal", "tags": []}, {"key": "debug_overlay", "kind": "modal", "tags": [ModalStack.TAG_NON_LOCKING]}, - {"key": "debug_badge", "kind": "float"}, # 2026-10-16 用户令:调试入口全局浮层——末位=最顶绘制序; + {"key": "debug_badge", "kind": "float"}, # 调试入口全局浮层——末位=最顶绘制序; # float 类不注册 ModalStack(open() 遮挡记账只隐藏登记层)→ 任何 UI 打开都不遮它 ] var db -var run_scope = null # 会话状态承载(run_scope.gd——迭代 27 T1 物化;_ready 即建闲时态,永非 null) -# SaveManager/MetaProgression 升格 autoload(迭代 27 T1 裁点①)——成员名保留为「autoload 读视图」 +var run_scope = null # 会话状态承载(run_scope.gd;_ready 即建闲时态,永非 null) +# SaveManager/MetaProgression 升格 autoload——成员名保留为「autoload 读视图」 #(属性 getter 经节点路径解析:--script 模式编译器不解析裸 autoload 标识符〔run_all.gd 头注在案〕, # 节点路径双模式通用;组合根调用点/探针挂载面 main.save_manager 语义零迁移)。 var save_manager: SaveManagerCore: @@ -64,43 +64,43 @@ var meta: MetaProgressionCore: get: return get_node(AUTOLOAD_PATH_META) var logger = null # 试玩日志器(JSONL 持久化 + 卡死诊断转储——呈现层组件) -var _debug_entry := false # 调试会话门控(2026-10-16 用户令写死=true——恒开:启动即开浮窗+两屏角标点亮;_ready 赋值) +var _debug_entry := false # 调试会话门控(写死=true——恒开:启动即开浮窗+两屏角标点亮;_ready 赋值) var _seed_edit: LineEdit -var _resume_btn: Button # 继续上局按钮句柄(迭代 8 卡②——有断点才亮) -var confirm_dialog: ConfirmDialog # 通用确认弹窗(二轮修改批 A——新冒险互斥确认弹窗化) -var curio_overlay: CurioPickOverlay # 提升三选一覆盖层(迭代 10——level-clear.md v2 选择面承载;追加批起奖励节点共用) +var _resume_btn: Button # 继续上局按钮句柄(有断点才亮) +var confirm_dialog: ConfirmDialog # 通用确认弹窗(新冒险互斥确认弹窗化) +var curio_overlay: CurioPickOverlay # 提升三选一覆盖层(level-clear.md v2 选择面承载;奖励节点共用) var _start_overlay: Control var _end_overlay: BattleEndOverlay var _inter_overlay: Control var _inter_label: Label -var level_screen: LevelMapScreen # 关卡画面句柄(指向 adventure_screen.level_screen——迭代 27 T1 场景拆分) -var _battle_root: Control # 战斗屏宿主句柄(指向 adventure_screen.battle_root——同上) +var level_screen: LevelMapScreen # 关卡画面句柄(指向 adventure_screen.level_screen) +var _battle_root: Control # 战斗屏宿主句柄(指向 adventure_screen.battle_root) # 调试模式编排(单场/连续两层——状态机与战斗生命周期归 debug_session.gd,本类只接线与出 UI) var _debug = null -# 视图(views/)——battle.md 三区(A 区关卡进度条顶栏随 停点前移批 2026-09-23 退役——节点链进度 -# 由关卡画面本体选路覆盖层承载;E 区道具面板随可选类删除下线) +# 视图(views/)——battle.md 三区(节点链进度 +# 由关卡画面本体选路覆盖层承载) var stage: BattleStageView # B 区(含 log_view 明细带)——句柄指向 adventure_screen var log_view: BattleLogView -var info_panel: HeroInfoPanelView # C 区(攻击/AC 数据框+两预留区——2026-09-26 信息归属拍板精简) +var info_panel: HeroInfoPanelView # C 区(攻击/AC 数据框+两预留区) var board_zone: BoardZoneView # D 区(含 ap_bar/board_view/toast/fx) var board_view: BoardView # 探针兼容别名(= board_zone.board_view) var ap_bar: ApBarView # 探针兼容别名(= board_zone.ap_bar) var settlement_fx: SettlementFxView # 结算演出覆盖层(跨区弹道/光带——A–D 之上、模态之下) -# 三屏壳实例(迭代 27 T1——屏成员经本类句柄暴露,探针挂载假设 main.X 一级路径零迁移) +# 三屏壳实例(屏成员经本类句柄暴露;探针挂载假设 main.X 一级路径) var _menu_screen = null # MenuScreen(开始菜单屏壳) var _camp_screen = null # CampScreen(营地屏壳) var _adventure_screen = null # AdventureScreen(冒险屏壳——内含关卡地图/战斗两容器) -# T3 拆件批(2026-10-02)——三件迁出后的组合根持有面(职责见各类头注;装配见 _build_ui) +# 拆件后的组合根持有面(职责见各类头注;装配见 _build_ui) var _row_pacer = null # 结算行排播泵(row_pacer.gd——本类只入队/排空/读队列) var _treasure_ui = null # 秘宝两步交互(treasure_interact_controller.gd——本类只接线与转发意图) var _bonus = null # 三选一与替换子交互(curio_interact_controller.gd——本类只接线与回调注入) var _camp_pres = null # 营地/商店投影(camp_shop_presenter.gd——本类只接线、探针缝保缝转发) -# 排播队列只读委托面(探针/测试读 main._row_queue——RowPacer 迁移后保留的同名可读面,共享同一 Array 引用) +# 排播队列只读委托面(探针/测试读 main._row_queue——与 RowPacer 队列共享同一 Array 引用) var _row_queue: Array[Variant]: get: return _row_pacer.pending_rows() @@ -108,21 +108,21 @@ var _row_queue: Array[Variant]: # 模态 overlay(z 序 = 登记序;pattern 6 层级纪律) var legend_overlay: LegendOverlay var node_overlay: NodeOverlay -var shop_overlay: ShopOverlay # 商店覆盖层(GP+商店房实施批——商店房节点兑付呈现) -var camp_overlay: CampOverlay # 营地覆盖层句柄(指向 camp_screen.camp_overlay——迭代 27 T1) -var settings_store # 系统级设置独立存储(迭代 8 卡④——音量/全屏/减动效) -var settings_overlay: SettingsOverlay # 设置覆盖层(迭代 8 卡④——最小设置面) -var status_panel: StatusPanel # 局内状态面板·只读(迭代 17 卡③——钥石余额+营地三柜台进度查看;登记设置层同档) -var career_overlay: CareerOverlay # 生涯页·只读全屏页(迭代 18 卡④——跨局汇总六类九项;登记营地同档〔设置层旁、确认弹窗之前〕) -var debug_overlay: DebugOverlay # 调试浮窗(迭代 14.5 调试整合批——种子/数值调整/批量模拟/两层调试入口收一) -var debug_badge: Button # 调试浮层入口角标(2026-10-16 用户令:UI 最顶层浮层——LAYER_CONTRACT 末位 float 类,任何 UI 不遮挡) +var shop_overlay: ShopOverlay # 商店覆盖层(商店房节点兑付呈现) +var camp_overlay: CampOverlay # 营地覆盖层句柄(指向 camp_screen.camp_overlay) +var settings_store # 系统级设置独立存储(音量/全屏/减动效) +var settings_overlay: SettingsOverlay # 设置覆盖层(最小设置面) +var status_panel: StatusPanel # 局内状态面板·只读(钥石余额+营地三柜台进度查看;登记设置层同档) +var career_overlay: CareerOverlay # 生涯页·只读全屏页(跨局汇总六类九项;登记营地同档〔设置层旁、确认弹窗之前〕) +var debug_overlay: DebugOverlay # 调试浮窗(种子/数值调整/批量模拟/两层调试入口收一) +var debug_badge: Button # 调试浮层入口角标(UI 最顶层浮层——LAYER_CONTRACT 末位 float 类,任何 UI 不遮挡) -var _modal_flow = null # 模态编排纯逻辑类(modal_flow.gd——迭代 27 T4 P1-5/P2-7 抽取;依赖仅 ModalStack+查询 Callable) +var _modal_flow = null # 模态编排纯逻辑类(modal_flow.gd——依赖仅 ModalStack+查询 Callable) var _modals = null # 模态层级状态机(=_modal_flow.stack——探针 _list 登记序断言缝保留) var _tune_sim = null # 调试浮窗批量模拟控制器(tune_sim_controller.gd) # 结算框挂起态属性化(探针/冒烟直读写接缝语义零变化——读=armed,写=arm/disarm;计时器随会话住 -# run_scope.settlement_stop_timer——迭代 27 T1) +# run_scope.settlement_stop_timer) var _settlement_stop_pending: bool: get: return run_scope.settlement_stop_timer.is_armed() if run_scope != null else false @@ -136,22 +136,22 @@ var _settlement_stop_pending: bool: # 锁期点击重放(v3.1):延迟一帧重入唯一动作通道——此刻队列空锁已解,按普通动作受理 #(局面在演播期无变化:逻辑先行、演播只是回放——点击语义保真;_row_queue=RowPacer 委托面, -# 排播泵本体已迁 row_pacer.gd——T3 结构段)。 -var _deferred_modal: Control: # 演播后开窗挂起只读视图(T17——t17_defer_probe 挂起态断言缝;本体归 _modal_flow) +# 排播泵本体在 row_pacer.gd)。 +var _deferred_modal: Control: # 演播后开窗挂起只读视图(t17_defer_probe 挂起态断言缝;本体归 _modal_flow) get: return _modal_flow._deferred if _modal_flow != null else null -# 演播后排窗(T17 用户令「伤害过程演完才切结算窗口」):排播队列在播=挂起,演播完边沿 +# 演播后排窗(伤害过程演完才切结算窗口):排播队列在播=挂起,演播完边沿 # (_on_pump_ended 派发)再开——旧路径 _open_modal 前置 flush 会把击杀轮的伤害/死亡演出 # 同帧倒掉(「直接跳战斗胜利」缺陷本体)。队列空=立即开(行为同旧路径)。 func _open_modal_after_playback(m: Control) -> void: - _modal_flow.open_after_playback(m) # 迭代 27 T4——演播后排窗挂起编排归 ModalFlow(T17 语义逐字随迁) + _modal_flow.open_after_playback(m) # 演播后排窗挂起编排归 ModalFlow # 演播完边沿派发(row_pacer.pump_ended 注入口——先开挂起 modal,后锁期点击重放): func _on_pump_ended() -> void: - _modal_flow.pump_ended() # 迭代 27 T4——派发编排归 ModalFlow(重放经注入 Callable 回本类) + _modal_flow.pump_ended() # 派发编排归 ModalFlow(重放经注入 Callable 回本类) func _replay_locked_click() -> void: @@ -162,7 +162,7 @@ func _replay_locked_click() -> void: _on_board_action(click["cell"], click["kind"]) -# 会话生命周期(迭代 27 T1——P0-2 物化):_ready 建闲时态(永非 null——全组合根零空判责), +# 会话生命周期:_ready 建闲时态(永非 null——全组合根零空判责), # 开局/续玩/调试两层各建新会话,旧会话整节点 queue_free()(帧末回收;新节点先挂树无真空窗)。 func _begin_session(adventure_session: bool) -> void: if run_scope != null: @@ -179,9 +179,9 @@ func _ready() -> void: if not ok: _fatal_screen("数值表加载失败——见输出错误清单(fail-fast)") return - # SaveManager/MetaProgression 升格 autoload(迭代 27 T1 裁点①):读盘已在各自 _ready 完成 - #(autoload 先于主场景就绪——时序与旧 main._ready 读盘等价),此处零动作。 - # 系统级设置(迭代 8 卡④——独立存储不随存档):启动即恢复音量/全屏/减动效引擎态 + # SaveManager/MetaProgression 升格 autoload:读盘已在各自 _ready 完成 + #(autoload 先于主场景就绪——读盘时序等价),此处零动作。 + # 系统级设置(独立存储不随存档):启动即恢复音量/全屏/减动效引擎态 settings_store = SettingsStore.new() settings_store.load_settings() settings_store.apply() @@ -191,19 +191,19 @@ func _ready() -> void: _debug.battle_ready.connect(_on_debug_battle_ready) _build_ui() _begin_session(false) # 闲时会话(gp_ledger 等探针注入面自 _ready 起恒在——ui_probe 合成段时序) - _refresh_resume_button() # 迭代 8 卡②——启动读盘后按断点在档态点亮「继续上局」 + _refresh_resume_button() # 启动读盘后按断点在档态点亮「继续上局」 _start_overlay.visible = true - _debug_entry = true # 2026-10-16 用户令:DS_DEBUG 环境变量门控写死(原 OS.get_environment 读取已退役;发布前清) + _debug_entry = true # 调试入口门控写死=true(不读 DS_DEBUG 环境变量;发布前清) debug_badge.visible = _debug_entry # 浮层角标可见性须门控落定后赋值(构建/连接在 _build_ui) - # 2026-10-16 用户令修正:boot 菜单优先——不自动开浮窗(原「启动即开」把开始屏盖成调试面板, - # 用户实测否决);调试入口=UI 最顶层全局浮层角标(LAYER_CONTRACT 末位 float 类,任何 UI 不遮挡) + # boot 菜单优先——启动不自动开浮窗(开始屏不得被调试面板盖住); + # 调试入口=UI 最顶层全局浮层角标(LAYER_CONTRACT 末位 float 类,任何 UI 不遮挡) # ==================== 视图接线(三屏壳 + 模态层装配;构建归屏壳/UiAssembler,本类只接线) ==================== func _build_ui() -> void: - # 三屏壳实例化(迭代 27 T1 场景拆分):冒险屏先挂、菜单屏后挂(启动态菜单在顶层=玩家可见—— - # 装配序修复:旧序菜单先挂被冒险屏盖死,F5 见战斗界面);最终树序+登记序以 LAYER_CONTRACT + # 三屏壳实例化:冒险屏先挂、菜单屏后挂(启动态菜单在顶层=玩家可见—— + # 装配序纪律:菜单先挂会被冒险屏盖死,F5 见战斗界面);最终树序+登记序以 LAYER_CONTRACT # 为唯一事实源,_apply_layer_contract 在装配尾统一落位。 # 屏内 level_screen 与 battle_root 无同时可见态(屏级互斥+模态栈遮挡),层内先后零视觉差; # 视觉共存对逐对验算:legend/battle(图例战斗中开——legend 在冒险屏壳之后=其上 ✓)、 @@ -223,7 +223,7 @@ func _build_ui() -> void: settlement_fx = _adventure_screen.settlement_fx level_screen = _adventure_screen.level_screen - # 结算行排播泵(T3 拆件批——迁 row_pacer.gd;本类注入视图句柄与呈现刷新回调,零信号连接) + # 结算行排播泵(本体在 row_pacer.gd;本类注入视图句柄与呈现刷新回调,零信号连接) _row_pacer = RowPacer.new() _row_pacer.log_view = log_view _row_pacer.stage = stage @@ -231,16 +231,16 @@ func _build_ui() -> void: _row_pacer.settlement_fx = settlement_fx _row_pacer.board_view = board_view _row_pacer.refresh_request = _refresh_presentations - _row_pacer.pump_ended = _on_pump_ended # T17 v3.1+演播后排窗——边沿统一派发(挂起 modal 优先,其次锁期点击重放) # T17 v3.1——演播完边沿重放锁期点击(合并批接线) + _row_pacer.pump_ended = _on_pump_ended # 演播完边沿统一派发(挂起 modal 优先,其次锁期点击重放) add_child(_row_pacer) - # 秘宝两步交互(T3 拆件批——迁 treasure_interact_controller.gd;settlement/runner 随关卡更替, + # 秘宝两步交互(本体在 treasure_interact_controller.gd;settlement/runner 随关卡更替, # 经现值回调注入——仿 identity_resolver 只读回调先例) _treasure_ui = TreasureInteractController.new(db, meta, info_panel, board_zone.toast, board_view, func() -> Variant: return run_scope.settlement, func() -> Variant: return run_scope.runner) board_zone.action_requested.connect(_on_board_action) - board_zone.status_badge.pressed.connect(_on_status_badge_pressed) # 状态面板入口(迭代 17 卡③——战斗屏 HUD 角标) - info_panel.treasure_slot_clicked.connect(_treasure_ui.on_slot_clicked) # 迭代 7 T4——两步交互第一步 + board_zone.status_badge.pressed.connect(_on_status_badge_pressed) # 状态面板入口(战斗屏 HUD 角标) + info_panel.treasure_slot_clicked.connect(_treasure_ui.on_slot_clicked) # 两步交互第一步 board_zone.stop_pressed.connect(_on_stop_pressed) board_zone.refresh_confirmed.connect(_on_refresh_confirmed) board_zone.legend_toggled.connect(_on_legend_toggled) @@ -251,13 +251,13 @@ func _build_ui() -> void: board_view.set_identity_resolver(_identity_lookup) # 数字遮蔽数据源:地形变异 hide_number 解析只读回调(信息型呈现——board_view 渲染面读取) board_view.set_variant_mask_resolver(_variant_mask_lookup) - board_view.set_variant_mark_resolver(_variant_mark_lookup) # 迭代 6 T6——flat_damage 未开格角标 + board_view.set_variant_mark_resolver(_variant_mark_lookup) # flat_damage 未开格角标 logger = PlaytestLogger.new() logger.ap_per_round = int(db.action_economy.ap_per_round) # 模态覆盖层(登记序 = 树序 = z 遮挡序:图例 < 明细回看 < 节点 < 关卡画面 < 三选一 < 终局 - # < 商店 < 营地 < 设置 < 状态面板(只读) < 生涯页(只读·迭代 18 卡④) < 确认弹窗 < 调试浮窗; + # < 商店 < 营地 < 设置 < 状态面板(只读) < 生涯页(只读) < 确认弹窗 < 调试浮窗; # 关卡画面住冒险屏壳(树序在模态之下)——登记序仍夹在节点层与三选一层之间,遮挡语义零改动) var overlays: Dictionary[Variant, Variant] = UiAssembler.build_overlays(self, db) legend_overlay = overlays.legend_overlay @@ -271,52 +271,52 @@ func _build_ui() -> void: legend_overlay.closed.connect(_on_modal_closed.bind(legend_overlay)) node_overlay.continue_pressed.connect(_on_node_continue) level_screen.route_chosen.connect(_on_route_chosen) - level_screen.status_badge.pressed.connect(_on_status_badge_pressed) # 状态面板入口(迭代 17 卡③——地图屏顶栏角标) - level_screen.abandon_requested.connect(_on_abandon_requested) # 放弃入口(2026-09-21 用户拍板——台账 119) + level_screen.status_badge.pressed.connect(_on_status_badge_pressed) # 状态面板入口(地图屏顶栏角标) + level_screen.abandon_requested.connect(_on_abandon_requested) # 放弃入口 _end_overlay.continue_pressed.connect(_on_battle_end_continue) - settings_overlay = SettingsOverlay.new(settings_store) # 迭代 8 卡④——最小设置面(音量/全屏/减动效) + settings_overlay = SettingsOverlay.new(settings_store) # 最小设置面(音量/全屏/减动效) add_child(settings_overlay) settings_overlay.closed.connect(_on_settings_closed) - # 局内状态面板·只读(迭代 17 卡③——P2 甲:登记设置层同档带 dim 遮罩,确认弹窗之前; - # 数据=组合根开层实时读 MetaProgression 访问器喂入(R4),本层零写通路) + # 局内状态面板·只读(登记设置层同档带 dim 遮罩,确认弹窗之前; + # 数据=组合根开层实时读 MetaProgression 访问器喂入,本层零写通路) status_panel = StatusPanel.new() add_child(status_panel) status_panel.closed.connect(_on_status_closed) - # 生涯页·只读全屏页(迭代 18 卡④——P3 甲:登记序=营地同档,设置层旁、确认弹窗之前; + # 生涯页·只读全屏页(登记序=营地同档,设置层旁、确认弹窗之前; # 树序同步=addChild 同位(登记序=树序=z 序纪律);数据=组合根开层实时读 SaveManager 计数 # 访问器+MetaProgression 访问器喂入,本层零写通路零跳转;入口=开始层「营地与系统」组生涯钮) career_overlay = CareerOverlay.new() add_child(career_overlay) career_overlay.closed.connect(_on_career_closed) - # 提升三选一覆盖层(迭代 10——z 序 = 节点层之上、终局层之下;确认后同拍推进; + # 提升三选一覆盖层(z 序 = 节点层之上、终局层之下;确认后同拍推进; # 插位由 LAYER_CONTRACT curio 槽统一落位——禁散落 move_child) curio_overlay = CurioPickOverlay.new() add_child(curio_overlay) - # 提升三选一与替换子交互(T4/D4 拆件批——迁 curio_interact_controller.gd;本类只接线与回调注入, + # 提升三选一与替换子交互(本体在 curio_interact_controller.gd;本类只接线与回调注入, # 模态栈/演播后排窗/呈现刷新/fatal 经回调注入,adventure/runner 现值回调) _bonus = CurioInteractController.new(CurioFlowContext.new(db, func() -> Variant: return meta, curio_overlay, _end_overlay, board_view, board_zone.toast, func() -> Variant: return save_manager, func() -> Variant: return run_scope.adventure, func() -> Variant: return run_scope.runner, func() -> Variant: return run_scope.is_adventure, _open_modal, _open_modal_after_playback, _close_modal, _refresh_presentations, - _fatal_screen, func() -> String: return _gp_summary_text({"gp_dropped": run_scope.last_gain_amount}))) # 迭代 27 T4——构造参数收拢 context(P1-5) + _fatal_screen, func() -> String: return _gp_summary_text({"gp_dropped": run_scope.last_gain_amount}))) # 构造参数收拢 context curio_overlay.pick_confirmed.connect(_bonus.on_pick_confirmed) curio_overlay.continue_pressed.connect(_bonus.on_continue) curio_overlay.refresh_requested.connect(_bonus.on_refresh) - # 菜单屏接线(原 build_start_overlay 返回值接线段——句柄经屏壳暴露) + # 菜单屏接线(句柄经屏壳暴露) _menu_screen.lvbtn.pressed.connect(_start_adventure_from_menu) - _menu_screen.resumebtn.pressed.connect(_resume_from_menu) # 迭代 8 卡②——续玩入口 + _menu_screen.resumebtn.pressed.connect(_resume_from_menu) # 续玩入口 _resume_btn = _menu_screen.resumebtn - # 调试入口=UI 最顶层全局浮层角标(2026-10-16 用户令:任何 UI 不遮挡——菜单/战斗/地图三枚 - # 屏内角标形态退役,全局浮层全场景承载;连接归组合根,树序/登记面见 LAYER_CONTRACT 末位) + # 调试入口=UI 最顶层全局浮层角标(任何 UI 不遮挡——菜单/战斗/地图三枚 + # 屏内角标由全局浮层承载;连接归组合根,树序/登记面见 LAYER_CONTRACT 末位) debug_badge = UiAssembler.build_debug_badge(self) add_child(debug_badge) debug_badge.pressed.connect(_on_debug_badge_pressed) - # 营地/商店投影(T4/D4 拆件批——迁 camp_shop_presenter.gd;本类只接线、探针缝保缝转发; + # 营地/商店投影(本体在 camp_shop_presenter.gd;本类只接线、探针缝保缝转发; # 购买写调用唯一经 MetaProgression/LevelRunner core 单口——组合根 lambda 现值注入) _camp_pres = CampShopPresenter.new(CampFlowContext.new(db, func() -> Variant: return meta, func() -> Variant: return save_manager, camp_overlay, shop_overlay, board_zone.toast, _start_overlay, logger, func() -> Variant: return run_scope.runner, - _open_modal, _close_modal, _refresh_presentations, _refresh_resume_button)) # 迭代 27 T4——构造参数收拢 context(P1-5) + _open_modal, _close_modal, _refresh_presentations, _refresh_resume_button)) # 构造参数收拢 context shop_overlay.buy_requested.connect(_camp_pres.on_shop_buy) shop_overlay.refresh_requested.connect(_camp_pres.on_shop_refresh) # MC-1 shop_overlay.leave_pressed.connect(_camp_pres.on_shop_leave) @@ -324,47 +324,47 @@ func _build_ui() -> void: camp_overlay.attune_toggled.connect(_camp_pres.on_camp_attune_toggle) camp_overlay.tree_buy_requested.connect(_camp_pres.on_camp_tree_buy) camp_overlay.tree_fork_toggled.connect(_camp_pres.on_camp_fork_toggle) - camp_overlay.forge_buy_requested.connect(_camp_pres.on_camp_forge_buy) # 迭代 23 T6——锻造三意图(写口唯一归 MetaProgression) + camp_overlay.forge_buy_requested.connect(_camp_pres.on_camp_forge_buy) # 锻造三意图(写口唯一归 MetaProgression) camp_overlay.forge_unlock_requested.connect(_camp_pres.on_camp_forge_unlock) camp_overlay.forge_select_requested.connect(_camp_pres.on_camp_forge_select) camp_overlay.closed.connect(_camp_pres.on_camp_closed) _menu_screen.campbtn.pressed.connect(_camp_pres.open_camp) - _menu_screen.careerbtn.pressed.connect(_open_career) # 迭代 18 卡④——生涯页一级入口(营地同组) - _menu_screen.settingsbtn.pressed.connect(_open_settings) # 迭代 8 卡④——最小设置面入口 - _menu_screen.quitbtn.pressed.connect(_quit_game) # 二轮修改批 D1——退出游戏提级一级菜单 + _menu_screen.careerbtn.pressed.connect(_open_career) # 生涯页一级入口(营地同组) + _menu_screen.settingsbtn.pressed.connect(_open_settings) # 最小设置面入口 + _menu_screen.quitbtn.pressed.connect(_quit_game) # 退出游戏提级一级菜单 var inter: Dictionary[Variant, Variant] = UiAssembler.build_inter_overlay(self) _inter_overlay = inter.overlay _inter_label = inter.label inter.next_btn.pressed.connect(_on_inter_next_pressed) - # 确认弹窗(二轮修改批 A——新冒险互斥确认弹窗化):树序落在开始层/过场层之后 = 子级最末 - #(T3 收口批——「登记序 = 树序 = z 序」纪律复位,confirm_dialog.open 的 move_child 运行时自提 - # 创可贴随之删除;弹窗只在开始菜单域弹出,绘制序恒最上。原诊断转储角落钮随迭代 26 T5b 退役, - # 转储入口迁调试浮窗——grilling Q8 裁甲) + # 确认弹窗(新冒险互斥确认弹窗化):树序落在开始层/过场层之后 = 子级最末 + #(纪律「登记序 = 树序 = z 序」——confirm_dialog.open 禁运行时 move_child 自提抬层; + # 弹窗只在开始菜单域弹出,绘制序恒最上; + # 诊断转储入口在调试浮窗) confirm_dialog = ConfirmDialog.new() add_child(confirm_dialog) confirm_dialog.confirmed.connect(_on_confirm_new_adventure) confirm_dialog.cancelled.connect(_on_confirm_cancelled) - # 调试浮窗(迭代 14.5 调试整合批——主菜单三散件收一:随机种子/数值调整/批量模拟/两层调试入口; - # 迭代 18 卡⑦——升级为全局可开浮窗:调试会话恒开=启动即开〔_ready〕+两屏角标再开〔P2 甲〕+当局数据只读区块〔T3〕; - # 迭代 26 T5b——诊断转储入口并入(原主画面左下角常驻钮退役,玩家画面清零))。 + # 调试浮窗(主菜单三散件收一:随机种子/数值调整/批量模拟/两层调试入口; + # 全局可开浮窗:调试会话恒开=启动即开〔_ready〕+两屏角标再开+当局数据只读区块; + # 诊断转储入口在本浮窗,玩家画面零常驻调试件)。 # 树序在开始层与确认弹窗之后 = 浮于菜单之上的 Dialog(不隐藏开始层——与确认弹窗同款形态); # 开窗唯一入口 = _show_debug_overlay(C6 单口——角标/探针/启动路径全收口) debug_overlay = DebugOverlay.new(db, int(db.hero.atk), int(db.hero.max_hp)) add_child(debug_overlay) - _seed_edit = debug_overlay.seed_edit # 种子读取面随浮窗迁入(_seed_value 唯一消费点不变) + _seed_edit = debug_overlay.seed_edit # 种子读取面在浮窗(_seed_value 唯一消费点不变) debug_overlay.closed.connect(_on_modal_closed.bind(debug_overlay)) debug_overlay.apply_requested.connect(_on_tune_apply) debug_overlay.simulate_requested.connect(_on_tune_simulate) debug_overlay.debug_levels_requested.connect(_start_debug_levels) - debug_overlay.diagnose_requested.connect(_on_diagnose_pressed) # 迭代 26 T5b——诊断转储入口随迁(原角落钮连接) + debug_overlay.diagnose_requested.connect(_on_diagnose_pressed) # 诊断转储入口 # 模态登记(缺陷⑤纪律——登记序 = 树序 = z 序):层序唯一事实源=LAYER_CONTRACT, # _apply_layer_contract 统一落位(关卡画面宿住冒险屏壳、营地屏壳夹商店与设置层之间、 # 三选一对位终局层之下等特例均在合同数据内表达,禁散落 move_child) - # 模态编排注入(迭代 27 T4——ModalFlow 纯逻辑类:依赖仅 ModalStack+查询 Callable,P1-5 抽取) + # 模态编排注入(ModalFlow 纯逻辑类:依赖仅 ModalStack+查询 Callable) _modal_flow = ModalFlow.new() _modal_flow.start_visible_get = func() -> bool: return _start_overlay.visible _modal_flow.inter_visible_get = func() -> bool: return _inter_overlay.visible @@ -372,11 +372,11 @@ func _build_ui() -> void: _modal_flow.rows_empty_get = func() -> bool: return _row_pacer.pending_rows().is_empty() _modal_flow.flush_rows = _flush_row_queue _modal_flow.on_open_sync = func() -> void: - _sync_status_entry() # 迭代 17 卡③——状态面板入口角标可见性/置灰随开态同步 - _sync_debug_overlay() # 迭代 18 卡⑦——浮窗当局数据/按钮态随开态同步 + _sync_status_entry() # 状态面板入口角标可见性/置灰随开态同步 + _sync_debug_overlay() # 浮窗当局数据/按钮态随开态同步 _modal_flow.on_close_sync = func() -> void: - _sync_status_entry() # 迭代 17 卡③——关闭恢复角标可点态(无残留——R3 同源口径) - _sync_debug_overlay() # 迭代 18 卡⑦——他层关闭复活浮窗时同步刷新(P1 甲关后自动恢复语义配套) + _sync_status_entry() # 关闭恢复角标可点态(无残留——同源口径) + _sync_debug_overlay() # 他层关闭复活浮窗时同步刷新(关后自动恢复语义配套) _modal_flow.replay_click = _replay_locked_click _modals = _modal_flow.stack # 探针 _list 登记序断言缝(ui_struct 登记序=z 序纪律断言) # 视觉层合同装配(唯一事实源=LAYER_CONTRACT:树序+登记序同源派生——改序只改合同表) @@ -397,7 +397,7 @@ func _register_modal(m: Control, tags: Array = []) -> void: # 统一收口:六个模态同病,探针经信号直发绕过真实点击从未暴露。anchors_and_offsets 而非 anchors # ——后者会把控件重置回最小内容尺寸,ui_assembler 头注同款纪律) m.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) - _modal_flow.register(m, tags) # 排除组随层登记(迭代 27 T4 P2-7——non_locking=调试浮窗/screen_state=关卡地图屏) + _modal_flow.register(m, tags) # 排除组随层登记(non_locking=调试浮窗/screen_state=关卡地图屏) # 合同层寻址(key→节点;纯查表不含层序语义——层序唯一事实源=LAYER_CONTRACT) @@ -456,7 +456,7 @@ func _apply_layer_contract() -> void: func _open_modal(m: Control) -> void: - _modal_flow.open(m) # 迭代 27 T4——挂起兜底/排播排空/遮挡记账/开侧同步编排归 ModalFlow(P1-5 抽取) + _modal_flow.open(m) # 挂起兜底/排播排空/遮挡记账/开侧同步编排归 ModalFlow func _close_modal(m: Control) -> void: _modal_flow.close(m) # 关闭恢复+关侧同步归 ModalFlow(同上) @@ -466,14 +466,14 @@ func _on_modal_closed(m: Control) -> void: func _input_locked() -> bool: - # 模态/非战斗期棋盘输入锁(迭代 27 T4——判据编排归 ModalFlow.locks_input:互斥域随层登记 - # [non_locking=调试浮窗,迭代 18 卡⑦ T2 防线]+ 三例外经查询 Callable 注入;本函数留探针缝) + # 模态/非战斗期棋盘输入锁(判据编排归 ModalFlow.locks_input:互斥域随层登记 + # [non_locking=调试浮窗]+ 三例外经查询 Callable 注入;本函数留探针缝) return _modal_flow.locks_input() -# ==================== 冒险模式入口(唯一试玩入口——单关测试直入口退役 2026-09-23 用户拍板)==================== +# ==================== 冒险模式入口(唯一试玩入口)==================== func _start_adventure_from_menu() -> void: - # 互斥确认弹窗化(二轮修改批 A——用户目检裁决「弹窗提示」):有断点时开新冒险弹实底确认框, + # 互斥确认弹窗化:有断点时开新冒险弹实底确认框, # 「开新冒险」提交(弃旧断点+写盘)/「取消」回菜单 if save_manager.has_breakpoint(): var bp: Dictionary[Variant, Variant] = save_manager.breakpoint_snapshot() @@ -496,14 +496,14 @@ func _on_confirm_cancelled() -> void: confirm_dialog.close() # 回开始菜单(无状态变更) -# 退出游戏(二轮修改批 D1——一级菜单入口;设置即时落盘后退出) +# 退出游戏(一级菜单入口;设置即时落盘后退出) func _quit_game() -> void: if settings_store != null: settings_store.save_settings() get_tree().quit() -# 继续上局按钮可见性 = 断点在档态(迭代 8 卡②——启动读盘后与每次回开始菜单刷新) +# 继续上局按钮可见性 = 断点在档态(启动读盘后与每次回开始菜单刷新) func _refresh_resume_button() -> void: if _resume_btn == null: return @@ -514,22 +514,22 @@ func _refresh_resume_button() -> void: _resume_btn.text = "▶ 继续上局(第 %d 关 · 自最近停点恢复)" % maxi(1, int(bp.get("level_index", 1))) -# 继续上局(迭代 8 卡②——卡① resume_adventure 的消费入口):断点重建至最近停点 +# 继续上局(resume_adventure 的消费入口):断点重建至最近停点 func _resume_from_menu() -> void: if not save_manager.has_breakpoint(): return var bp: Dictionary[Variant, Variant] = save_manager.breakpoint_snapshot() - _close_modal(debug_overlay) # 开冒险路径显式关浮窗(迭代 18 卡⑦ T2 防护——续玩同口径) + _close_modal(debug_overlay) # 开冒险路径显式关浮窗(续玩同口径) _start_overlay.visible = false _begin_session(true) _wire_adventure() run_scope.level_active = true - _sync_status_entry() # 迭代 17 卡③——续玩恢复点亮状态面板入口角标 + _sync_status_entry() # 续玩恢复点亮状态面板入口角标 level_screen.set_abandon_available(true) log_view.clear() logger.start_session(int(bp.get("master_seed", 0))) run_scope.adventure.set_hero_override(debug_overlay.atk_pct(), debug_overlay.hp_pct()) - # 迭代 19 卡⓪①——同调三键随续玩下传(build_adventure_params 统一构造,与开新局同源同口径) + # 同调三键随续玩下传(build_adventure_params 统一构造,与开新局同源同口径) if not run_scope.adventure.resume_adventure(bp, build_adventure_params(save_manager, meta, {"treasure_unlocked": _treasure_ui.unlocked_set()})): _fatal_screen("续玩恢复失败——见输出日志") @@ -545,22 +545,22 @@ func _wire_adventure() -> void: run_scope.adventure.node_entered.connect(_on_runner_node) run_scope.adventure.choices_presented.connect(_on_choices_presented) run_scope.adventure.wallet_changed.connect(_on_wallet_changed) - # 迭代 10 奖励重构批——big_reward_paid 退役,三选一信号族接线 + # 三选一信号族接线 run_scope.adventure.curio_choice_presented.connect(_bonus.on_presented) run_scope.adventure.curio_resolved.connect(_bonus.on_resolved) run_scope.adventure.adventure_finished.connect(_on_adventure_finished) run_scope.adventure.level_started.connect(_on_adventure_level_started) - run_scope.adventure.set_save_manager(save_manager) # 断点承载注入(迭代 8 卡①——停点快照写盘;调试/模拟不经过此路径) + run_scope.adventure.set_save_manager(save_manager) # 断点承载注入(停点快照写盘;调试/模拟不经过此路径) -# 冒险开局参数面构造(主菜单开新/续玩两入口共用——迭代 19 卡⓪①:同调三键随开局下传,真实局此前恒空。 +# 冒险开局参数面构造(主菜单开新/续玩两入口共用:同调三键随开局下传。 # 取值口径与营地投影完全同源:装配集=save.attunement_equipped(save_manager.gd 访问器)、Y 刷新池= # meta.attune_refresh_charges(当前等级行表值)、树 rule 键集=meta.tree_rule_keys(Fork 激活侧 effects); # hero_override 沿用既有 meta 现算口径。static 形态=冒烟直呼单测本函数,免实例化整菜单场景)。 -# 迭代 23 T4:两根类型轴随开局下传(attack_type/armor_type——契约 2 所有权移交+契约 8 冒险开始快照; +# 两根类型轴随开局下传(attack_type/armor_type——契约 2 所有权移交+契约 8 冒险开始快照; # 取值=meta.hero_attack_type/hero_armor_type=存档选中路线类型轴,未解锁/异常选中态回退锻造配置默认值)。 -# 注:runner 侧 resume_adventure 受理面现收 attunement/attune_refresh_y/tree_rules 三键 -# (2026-10-08 尾裁微批b 卡⓪受理闭环——tree_rules 受理补齐,传参/受理两侧对齐,披露句退役)。 +# 注:runner 侧 resume_adventure 受理面收 attunement/attune_refresh_y/tree_rules 三键 +# (传参/受理两侧对齐)。 static func build_adventure_params(save_manager_ref, meta_ref, extra: Dictionary = {}) -> Dictionary: var params: Dictionary[Variant, Variant] = { "hero_override": meta_ref.hero_override() if meta_ref != null else {}, @@ -577,19 +577,19 @@ static func build_adventure_params(save_manager_ref, meta_ref, extra: Dictionary # 冒险模式(三关连探——AdventureRunner 编排;转发信号签名与 runner 一致,接线照原样对接; # 信号连接只在组合根) func _start_adventure() -> void: - _close_modal(debug_overlay) # 开冒险路径显式关浮窗(迭代 18 卡⑦ T2 防护——调试浮窗默认开态下开局不带窗;对局中经角标再开) + _close_modal(debug_overlay) # 开冒险路径显式关浮窗(调试浮窗默认开态下开局不带窗;对局中经角标再开) _begin_session(true) _wire_adventure() run_scope.level_active = true - _sync_status_entry() # 迭代 17 卡③——进对局点亮状态面板入口角标 - level_screen.set_abandon_available(true) # 放弃入口挂选路停点(天然非战斗期——2026-09-21 用户拍板) + _sync_status_entry() # 进对局点亮状态面板入口角标 + level_screen.set_abandon_available(true) # 放弃入口挂选路停点(天然非战斗期) log_view.clear() var seed_val := _seed_value() logger.start_session(seed_val) run_scope.adventure.set_hero_override(debug_overlay.atk_pct(), debug_overlay.hp_pct()) - # 永久强化注入(元进度实现批):冒险开始参数面——meta 现算 override 显式传参(全零 = 白板) + # 永久强化注入:冒险开始参数面——meta 现算 override 显式传参(全零 = 白板) # 首次冒险脚本(关卡节点图生成 v0.4):存档布尔位 false = 全关固定模板 0(教学重放);置位后逐关抽签 - # 迭代 19 卡⓪①——同调三键随开局下传(build_adventure_params 统一构造,与营地投影同源) + # 同调三键随开局下传(build_adventure_params 统一构造,与营地投影同源) var first_script: bool = not save_manager.is_first_adventure_done() if not run_scope.adventure.start_adventure(seed_val, build_adventure_params(save_manager, meta, {"first_script": first_script, "treasure_unlocked": _treasure_ui.unlocked_set(), "shop_mode": "pool"})): @@ -598,12 +598,12 @@ func _start_adventure() -> void: # 每关开始(冒险模式):重取 runner 实例 + 层名行(L1 与单关模式同序——层名行随首战横幅后到达; -# 停点前移批 2026-09-23:本回调返回后才有 choices_presented 到达——入口选路层随即弹出) +# 本回调返回后才有 choices_presented 到达——入口选路层随即弹出) func _on_adventure_level_started(level_index: int, display_name: String) -> void: run_scope.runner = run_scope.adventure.runner() - # 迭代 19 卡⓪②——开场行改传当前生效值(runner.effective_atk/effective_max_hp 与战斗面板同源: + # 开场行传当前生效值(runner.effective_atk/effective_max_hp 与战斗面板同源: # 表值+永久强化 flat+加算区 flat 后乘调试浮窗 pct,本回调时点 runner 已带全部加成);「含面板加成」 - # 后缀判断同步改认局外加成——永久强化 atk/max_hp flat 或调试浮窗 pct 任一存在才带,白板局不带 + # 后缀判断认局外加成——永久强化 atk/max_hp flat 或调试浮窗 pct 任一存在才带,白板局不带 var ov: Dictionary[Variant, Variant] = meta.hero_override() log_view.append_bb(Narrator.level_open_line(display_name, int(run_scope.adventure.master_seed), run_scope.runner.effective_atk(), run_scope.runner.effective_max_hp(), @@ -623,8 +623,8 @@ func _on_runner_node(node: Dictionary, info: Dictionary) -> void: _show_board_fx_for_node(t) log_view.append_bb(Narrator.node_banner(run_scope.runner, node, t)) elif t == "reward": - # 奖励节点三选一(迭代 10 追加批——与通关三选一共享同池同权重同上限;CurioPickOverlay 共用面)。 - # T4/D4 拆件:呈现编排归 curio_interact_controller.present_node_curio(_curio_context 随迁)。 + # 奖励节点三选一(与通关三选一共享同池同权重同上限;CurioPickOverlay 共用面)。 + # 呈现编排归 curio_interact_controller.present_node_curio。 _bonus.present_node_curio() log_view.append_bb(Narrator.reward_line()) elif t == "rest": @@ -633,13 +633,13 @@ func _on_runner_node(node: Dictionary, info: Dictionary) -> void: node_overlay.show_rest(healed, int(info.get("hp", 0)), int(info.get("max_hp", 0))) log_view.append_bb(Narrator.rest_line(healed, int(info.get("hp", 0)), int(info.get("max_hp", 0)))) elif t == "shop": - # 商店房兑付(GP+商店房实施批):到达即开店——商品/货架快照与余额经 runner 只读投影喂入; + # 商店房兑付:到达即开店——商品/货架快照与余额经 runner 只读投影喂入; # 购买/离开归玩家意图(buy_requested/leave_pressed 接线),零自动推进。 - # pool 面 = 共享池货架三选一同构卡(迭代 11 第②批 T4);legacy 面 = 固定三件(off 对照承载) + # pool 面 = 共享池货架三选一同构卡;legacy 面 = 固定三件(off 对照承载) _open_modal(shop_overlay) if run_scope.runner.is_shop_pool(): shop_overlay.open_shelf(run_scope.runner.shop_shelf(), int(run_scope.runner.gp)) - shop_overlay.set_visit_info(int(run_scope.runner.shop_bp_visit_buys()), float(db.shop_price_a())) # T6 爬价规则行 + shop_overlay.set_visit_info(int(run_scope.runner.shop_bp_visit_buys()), float(db.shop_price_a())) # 爬价规则行 shop_overlay.set_refresh_display(run_scope.runner.shop_refresh_free_left(), run_scope.runner.shop_refresh_cost(), int(run_scope.runner.gp) >= run_scope.runner.shop_refresh_cost()) # MC-1 else: shop_overlay.open_shop(run_scope.runner.shop_products(), int(run_scope.runner.gp)) @@ -649,7 +649,7 @@ func _on_runner_node(node: Dictionary, info: Dictionary) -> void: _refresh_presentations() -# ---- 冒险模式终局面(三选一选择面 / 冒险结算屏——迭代 10 奖励重构批)---- +# ---- 冒险模式终局面(三选一选择面 / 冒险结算屏)---- # 冒险结算(completed/failed/abandoned):复用 BattleEndOverlay——摘要五件事 + 钥石入账明细进文案 func _on_adventure_finished(summary: Dictionary) -> void: @@ -657,10 +657,10 @@ func _on_adventure_finished(summary: Dictionary) -> void: var result: String = String(summary.get("result", "")) run_scope.settlement = null _exit_level_screen() # 终局兜底:独立屏在开态(放弃入口)也先回战斗屏呈现摘要——屏级互斥单一出口 - _sync_status_entry() # 迭代 17 卡③——离局熄灭状态面板入口角标(防菜单误现) + _sync_status_entry() # 离局熄灭状态面板入口角标(防菜单误现) _sync_settlement_visuals() # → 全关 - HudPresenter.battle_end_feedback(stage, ap_bar, false) # 灰化/idle 回正/状态全清——HUD 单通道(T3 收口批) - # 存档入账(元进度实现批):settle = Boss 两档入账 + 工坊解锁 + 摘要入档 + 写盘(唯一写档点不变—— + HudPresenter.battle_end_feedback(stage, ap_bar, false) # 灰化/idle 回正/状态全清——HUD 单通道 + # 存档入账:settle = Boss 两档入账 + 工坊解锁 + 摘要入档 + 写盘(唯一写档点不变—— # 调试两层不经过本处理器,天然不写档不污染生涯数据)。 var detail: Dictionary[String, Variant] = {} detail.assign(meta.settle_adventure(summary)) @@ -669,7 +669,7 @@ func _on_adventure_finished(summary: Dictionary) -> void: text += "\n" + Narrator.keystone_settle_text(detail, _bonus.item_name_lookup()) if result == "completed": _end_overlay.open_victory(text, "返回冒险", board_view.get_global_rect(), - "本局 GP 入账 · 合计 %d" % int(summary.get("gp_final", 0))) # 卡⑩ GP 行(迭代 27 T3——取数=summary gp_final 清账前快照,影子账已退役);钥石明细已在 text(keystone_settle_text)——M9 三行账 + "本局 GP 入账 · 合计 %d" % int(summary.get("gp_final", 0))) # GP 行(取数=summary gp_final 清账前快照);钥石明细已在 text(keystone_settle_text)——三行账 else: _end_overlay.open_defeat(text, "返回", board_view.get_global_rect()) logger.log_level_end(summary) # 试玩时间线:冒险终局(摘要随载荷) @@ -680,13 +680,13 @@ func _on_adventure_finished(summary: Dictionary) -> void: func _on_battle_end_continue() -> void: - # 终局出口:返回开始界面(冒险摘要留档试玩日志;钥石已在收束时入存档——存档序列化批) + # 终局出口:返回开始界面(冒险摘要留档试玩日志;钥石在收束时入存档) _close_modal(_end_overlay) _end_overlay.close() - # 迭代 10——三选一停点挂起分支:战斗总结结算(Boss 胜利钥石增量行)确认后进三选一面 - if _bonus.resume_if_pending(): # T4/D4 拆件——三选一停点在途恢复入口(curio_interact_controller) + # 三选一停点挂起分支:战斗总结结算(Boss 胜利钥石增量行)确认后进三选一面 + if _bonus.resume_if_pending(): # 三选一停点在途恢复入口(curio_interact_controller) return - # 卡⑥ 挂起分派:战斗胜利总结结算框的「下一节点」≠ 终局——进选路页(暂存候选恢复呈现) + # 挂起分派:战斗胜利总结结算框的「下一节点」≠ 终局——进选路页(暂存候选恢复呈现) if _settlement_stop_pending: _settlement_stop_pending = false _enter_level_screen() @@ -695,19 +695,19 @@ func _on_battle_end_continue() -> void: run_scope.pending_candidates = [] _refresh_presentations() return - # 会话收束(迭代 27 T1 物化):旧手工置空清单(runner/settlement/adventure/_adventure_mode + - # _reset_run_scope 三项)整节点 queue_free() 消亡——新闲时会话即建,局态封印/账本/模态挂起全复位 + # 会话收束:run_scope 整节点 queue_free()(帧末回收)——新闲时会话即建, + # 局态封印/账本/模态挂起全复位(局态字段清单见 run_scope.gd) _debug.reset() _begin_session(false) debug_overlay.reset_sliders() _start_overlay.visible = true - _refresh_resume_button() # 迭代 8 卡②——回菜单按断点在档态刷新(收束后已清=隐藏) + _refresh_resume_button() # 回菜单按断点在档态刷新(收束后已清=隐藏) _refresh_presentations() func _start_debug_levels() -> void: - # 守卫(迭代 18 卡⑦ T2——浮窗对局中可开后,调试对局与活跃冒险/结算并存不开放:并发会清写 - # settlement/编排态=状态机破坏;随开随收逻辑改向——对局中开窗只读浮窗,不再视为开局前置) + # 守卫:调试对局与活跃冒险/结算并存不开放——并发会清写 + # settlement/编排态=状态机破坏;对局中开窗是只读浮窗,不是开局前置 if run_scope.is_adventure or run_scope.settlement != null: return debug_overlay.reset_sliders() @@ -745,16 +745,16 @@ func _on_inter_next_pressed() -> void: _fatal_screen("战斗启动失败——见输出日志") -# E4:加成生效值供给(debug_session 注入 Callable——每次从浮窗百分比现算,经 encounter 传参零表写; -# 原表写路径 _apply_hero_override/_scaled_override 已废除,双写叠加 6→18→54 整类隐患随之移除; -# 合成式单点在 UiKit.scaled——与调试浮窗生效值预览共用,本类不再持有同式私有实现) +# 加成生效值供给(debug_session 注入 Callable——每次从浮窗百分比现算,经 encounter 传参零表写; +# 禁表写路径(双写叠加隐患源头); +# 合成式单点在 UiKit.scaled——与调试浮窗生效值预览共用,本类不持有同式私有实现) func _debug_hero_override() -> Dictionary: return {"atk": UiKit.scaled(int(db.hero.atk), debug_overlay.atk_pct()), "max_hp": UiKit.scaled(int(db.hero.max_hp), debug_overlay.hp_pct())} # 奖励徽章身份解析(组合根守卫:仅挖掘期 Active 相位内查询——地图战斗资源 Ready 域外零读、零诊断噪音; -# 相位取数经 presentation_snapshot 成文面——禁 settlement.action_economy 链式穿透,T3 收口批) +# 相位取数经 presentation_snapshot 成文面——禁 settlement.action_economy 链式穿透) func _identity_lookup(c: Vector2i): if run_scope.settlement == null or run_scope.settlement.minesweeper.current_board() == null: return null @@ -765,7 +765,7 @@ func _identity_lookup(c: Vector2i): # 地形变异 数字遮蔽解析(信息型 hide_number——格带该效果变异即遮蔽;读取方按格子变异数据行动。 # 变异表直读本根 db——settlement.db 即组合根注入的同一 ConfigDB 实例(AdventureRunner/DebugSession -# 构造传参),免 settlement 内部链式穿透,T3 收口批) +# 构造传参),免 settlement 内部链式穿透) func _variant_mask_lookup(c: Vector2i) -> bool: if run_scope.settlement == null: return false @@ -779,8 +779,8 @@ func _variant_mask_lookup(c: Vector2i) -> bool: return false -# 地形变异 角标解析(迭代 6 T6——伤害型变异未开格视觉标记;读取方按格子变异数据行动,规则本体零特判。 -# 策略纹理非数值墙:标记=玩家绕行/承担的决策输入,难度本体仍住数值包络。变异表直读本根 db——同上款收口) +# 地形变异 角标解析(伤害型变异未开格视觉标记;读取方按格子变异数据行动,规则本体零特判。 +# 策略纹理非数值墙:标记=玩家绕行/承担的决策输入,难度本体仍住数值包络。变异表直读本根 db) func _variant_mark_lookup(c: Vector2i) -> String: if run_scope.settlement == null: return "" @@ -804,7 +804,7 @@ func _on_battle_finished(payload: Dictionary) -> void: # 仅调试模式接线(冒险的关卡结束归 AdventureRunner._on_level_finished——大奖励/冒险终局分派) var result: String = String(payload.get("result", "")) _sync_settlement_visuals() # → 全关(battle_over 反馈面) - HudPresenter.battle_end_feedback(stage, ap_bar, true) # 灰化/idle 回正/RAP 清零/状态全清——HUD 单通道(T3 收口批) + HudPresenter.battle_end_feedback(stage, ap_bar, true) # 灰化/idle 回正/RAP 清零/状态全清——HUD 单通道 var decision: Dictionary[Variant, Variant] = _debug.on_battle_finished(payload) match String(decision.outcome): "next_layer": @@ -831,10 +831,10 @@ func _on_battle_finished(payload: Dictionary) -> void: _refresh_presentations() -# 战利品行装配(battle.md OQ14——胜利总结结算展示 GP 总量+增量;账本语义零改动,纯呈现读数): +# 战利品行装配(battle.md OQ14——胜利总结结算展示 GP 总量+增量;纯呈现读数): # 增量 = battle_finished 载荷 gp_dropped(战斗域上抛);总量 = runner.gp 现值(LevelRunner 入账 # 连接先于组合根 handler——此读数即战后入账完毕的总量)。 -# runner 缺位守卫(2026-10-06 用户实机 main.gd:717 崩值定位——续玩停点恢复分支:adventure_runner +# runner 缺位守卫(续玩停点恢复分支:adventure_runner # resume_adventure 的 bonus_pending 分支在 level_started 之前同步 curio_choice_presented.emit # 〔resume 提前 return〕,本 lambda 求值时 runner 尚未赋值;合计改读断点快照 gp 兜底——恢复源快照 # 此刻必在档,语义=续玩恢复面的合计即存档合计;与 _bonus_summary_text 同款守卫式) @@ -845,11 +845,11 @@ func _gp_summary_text(payload: Dictionary) -> String: return "战利品 GP +%d · 合计 %d" % [int(payload.get("gp_dropped", 0)), int(run_scope.runner.gp)] -# M9 结算三行账·本关加成行装配(呈现只读投影——runner.bonus 统一加算区同源;零加成=行隐藏) +# 结算三行账·本关加成行装配(呈现只读投影——runner.bonus 统一加算区同源;零加成=行隐藏) func _bonus_summary_text() -> String: if run_scope.runner == null: return "" - var b: Dictionary[Variant, Variant] = run_scope.runner.run_ledger.bonus # 迭代 27 T3——加算区住 RunLedger + var b: Dictionary[Variant, Variant] = run_scope.runner.run_ledger.bonus # 加算区住 RunLedger var parts: Array[String] = [] if int(b.get("atk", 0)) != 0: parts.append("攻 %+d" % int(b.get("atk", 0))) @@ -872,11 +872,11 @@ func _wire_battle(settlement_ref: BattleOrchestrator) -> void: # ==================== 结算行排播(泵本体归 row_pacer.gd——本节仅入口与探针/测试委托面)==================== func _on_step_row(row: Dictionary) -> void: - # 清图奖励可感知反馈(2026-10-04 用户反馈「挖完全图无任何奖励感」——clear_blast 兑付对敌伤害 + # 清图奖励可感知反馈(挖完全图须有奖励感——clear_blast 兑付对敌伤害 # 零可见,toast 桥接归组合根呈现层;零兑付(未生效)不弹安静留明细带) if String(row.get("source_class", "")) == "clear_reward" and String(row.get("type", "")) != "reward_ineffective": board_zone.toast.show_toast("清图奖励:%s" % String(row.get("display", "")).replace("(清图奖励)", ""), "info") - # 卡⑦ 排播入口:减动效=延迟归零同帧直落(行呈现不跳过);常态入队按段阶梯播放 + # 排播入口:减动效=延迟归零同帧直落(行呈现不跳过);常态入队按段阶梯播放 if UiKit.motion_scale < 1.0: _row_pacer.consume_now(row) return @@ -894,24 +894,24 @@ func _flush_row_queue() -> void: func _on_round_started(ri: int) -> void: - # 卡⑦:轮首分隔行随排播队列走(落在前轮各行之后——带序正确);轮横幅即轮切换时刻发射 + # 轮首分隔行随排播队列走(落在前轮各行之后——带序正确);轮横幅即轮切换时刻发射 #(view 内判减动效=静态化变体)。减动效快路=分隔行同帧直落(不跳过——consume_now 复用 - # _consume_row 轮首分隔行分支,与原直写逐字等价)。 + # _consume_row 轮首分隔行分支)。 if UiKit.motion_scale < 1.0: _row_pacer.consume_now({"__round_line": ri}) else: _row_pacer.enqueue({"__round_line": ri}) settlement_fx.play_round_banner(ri) - # 秘宝呈现同步(迭代 22 秘宝批 T4 换代——旧提灯桥 _sync_fog_lantern 随行退役;每战首轮装配链 - # 显式重算〔🔴 契约复原语义沿迭代 19 卡④ Q8.1:下一战装配链重算即含「未装配→写 0」复原〕。 - # 挂点时序依据不变:round_started 首轮发射位在 begin_battle 尾(attunement 注入之后)。 + # 秘宝呈现同步:每战首轮装配链 + # 显式重算〔🔴 契约复原语义:下一战装配链重算即含「未装配→写 0」复原〕。 + # 挂点时序依据:round_started 首轮发射位在 begin_battle 尾(attunement 注入之后)。 # settlement 空防御照既有形态。未装配=参数 0→写 0=缺省零扰动基线逐位不变。) if ri == 1: _sync_treasure_glow() - # 巢穴预告呈现(迭代 22 秘宝批 T4——装板报数量读数口消费:≥0=本战装配命中,toast 一次性提示) + # 巢穴预告呈现(装板报数量读数口消费:≥0=本战装配命中,toast 一次性提示) if run_scope.settlement != null and int(run_scope.settlement.nest_preview_count) >= 0: board_zone.toast.show_toast("巢穴预告——本板危险格共 %d 个" % int(run_scope.settlement.nest_preview_count), "info") - # 开战横幅——板级地形变异预告(全局作用域变异首发批 2026-10-04):首轮快照 board_variants + # 开战横幅——板级地形变异预告:首轮快照 board_variants # 非空才发射(Boss 图恒带一型=替换制;普通图空快照零发射);轮横幅下方叠行,view 内判减动效。 if ri == 1 and run_scope.settlement != null: var bvs: Array[Variant] = run_scope.settlement.presentation_snapshot().get("board_variants", []) @@ -933,10 +933,10 @@ func _on_board_changed() -> void: _refresh_presentations() -# 秘宝视野呈现桥(迭代 22 秘宝批 T4 换代——旧提灯桥随 fog_lantern 行退役;阔视野带 light_radius_bonus +# 秘宝视野呈现桥:阔视野带 light_radius_bonus # 装配参数合计显式写给 board_view.set_fog_glow_bonus(装配=半径 8+4 / 未装配=复原 0),写入即 setter # 内 refresh 全板重算雾态。调用点=每战首轮装配链(_on_round_started ri==1)——纯呈现边界 🔴 契约 2: -# 只写呈现态参数,minesweeper 结算零触碰;off 态(未装配)写 0=与既有基线逐位一致。 +# 只写呈现态参数,minesweeper 结算零触碰;off 态(未装配)写 0=缺省基线。 func _sync_treasure_glow() -> void: if run_scope.settlement == null or board_view == null: return @@ -978,16 +978,16 @@ func _show_hint(text: String, hint_id: String) -> void: func _on_node_continue() -> void: _close_modal(node_overlay) if run_scope.runner != null: - # 泛化语义(接口漂移清偿):确认 ≠ 推进——兑付确认后经 choices_presented 弹出选路口 + # 确认 ≠ 推进——兑付确认后经 choices_presented 弹出选路口 run_scope.runner.continue_after_node() func _on_choices_presented(candidates: Array) -> void: - # 零自动推进的停点呈现:整幅节点图 + 图上点击选路(候选按钮退役 2026-09-28——战斗胜利/兑付确认统一到达此处) + # 零自动推进的停点呈现:整幅节点图 + 图上点击选路(战斗胜利/兑付确认统一到达此处) if run_scope.runner == null: return log_view.append_bb(Narrator.route_line(candidates, run_scope.runner)) - # 卡⑥ 战斗胜利总结结算(battle.md OQ14 拍板面接线——欠账清偿):战斗胜利停点先弹 BattleEndOverlay + # 战斗胜利总结结算(battle.md OQ14):战斗胜利停点先弹 BattleEndOverlay # 胜利形态(金蜡封+GP 增量+总量+判定行+「下一节点」+明细回看),确认后进选路页。判据 = 战斗节点 # 的选路停点且战斗已收场(battle 收尾分支 _settlement 置 null 先于本信号;入口/兑付/商店停点 # 的当前节点非 battle 型——三态天然分流)。Boss 胜/失败走 level_finished 另路不经此处。 @@ -1008,7 +1008,7 @@ func _on_choices_presented(candidates: Array) -> void: func _on_route_chosen(node_id: int) -> void: - # 形态升格分支(2026-09-28):视图已按节点类型定去留——战斗/Boss 出屏(visible=false,此处收栈 + # 视图已按节点类型定去留——战斗/Boss 出屏(visible=false,此处收栈 # 记录一致性+回战斗屏);奖励/恢复/商店本屏保持激活(兑付覆盖层由节点事件域内弹出,模态栈 # 打开低层时自动隐藏本屏、关闭自动恢复) if not level_screen.visible: @@ -1018,7 +1018,7 @@ func _on_route_chosen(node_id: int) -> void: push_error("[组合根] 选路被拒(编号 %d 不在候选)" % node_id) -# ---- 独立屏屏级互斥(形态升格批 2026-09-28——单一出口:进屏隐战斗屏 / 出屏显战斗屏)---- +# ---- 独立屏屏级互斥(单一出口:进屏隐战斗屏 / 出屏显战斗屏)---- # 兑付覆盖层(节点/商店)在本屏激活域内弹出期间保持隐藏态不变——模态栈打开低层时隐藏本屏、 # 关闭自动恢复本屏(遮挡语义复用),战斗屏不在此期间回显。 @@ -1026,7 +1026,7 @@ func _enter_level_screen() -> void: run_scope.level_screen_active = true _battle_root.visible = false _open_modal(level_screen) - _sync_status_entry() # 迭代 17 卡③——屏级互斥切换同步(_open_modal 单口不识屏级状态) + _sync_status_entry() # 屏级互斥切换同步(_open_modal 单口不识屏级状态) func _exit_level_screen() -> void: @@ -1034,11 +1034,11 @@ func _exit_level_screen() -> void: _battle_root.visible = true if level_screen.visible: _close_modal(level_screen) - _sync_status_entry() # 迭代 17 卡③——同上 + _sync_status_entry() # 同上 func _on_abandon_requested() -> void: - # 放弃入口(2026-09-21 用户拍板「放弃接口也要有」——推翻 冒险结构.md「MVP 无界面入口」后置条款; + # 放弃入口(冒险结构.md 已放开「MVP 无界面入口」后置条款; # 入口挂选路停点 = 天然非战斗期,拒绝分支仅防御在案):受理 → 冒险放弃结算(同失败型, # 已获大奖励不追回)→ adventure_finished 同步到达 → 终局面收层 if not run_scope.is_adventure or run_scope.adventure == null: @@ -1048,30 +1048,30 @@ func _on_abandon_requested() -> void: board_zone.toast.show_toast("战斗进行中——无法放弃", "warn") -# ---- 营地覆盖层与钥石账本(元进度实现批——写调用唯一归组合根)---- +# ---- 营地覆盖层与钥石账本(写调用唯一归组合根)---- -# ---- 最小设置面(迭代 8 卡④——入口/开合仿营地先例:开始层互斥;生效与持久化归 SettingsStore)---- +# ---- 最小设置面(入口/开合仿营地先例:开始层互斥;生效与持久化归 SettingsStore)---- func _open_settings() -> void: _start_overlay.visible = false - _open_modal(settings_overlay) # 模态栈单口(T3 收口批) + _open_modal(settings_overlay) # 模态栈单口 func _on_settings_closed() -> void: - _close_modal(settings_overlay) # 模态栈单口(T3 收口批) + _close_modal(settings_overlay) # 模态栈单口 _start_overlay.visible = true _refresh_resume_button() -# ---- 局内状态面板·只读(迭代 17 卡③——入口角标在两屏装配段〔组 B〕;开合与数据喂入归组合根)---- +# ---- 局内状态面板·只读(入口角标在两屏装配段;开合与数据喂入归组合根)---- -# 状态面板快照投影(R4 数据只读同源:每次开层实时读 MetaProgression 访问器现值拼装—— +# 状态面板快照投影(数据只读同源:每次开层实时读 MetaProgression 访问器现值拼装—— # 快照仅服务单次开层生命周期(open_status 重建各行),跨开层零持有;零写调用。 -# 属性锻造三行投影已删——迭代 21 柜台退役连带〔状态面板锻造段同步删除〕) +# 状态面板零锻造段) func _status_data() -> Dictionary: return { "balance": meta.keystone_balance(), - "workshop": meta.treasure_shop_status(), # 迭代 22 T2——秘宝匣 12 件解锁投影(旧工坊面退役) + "workshop": meta.treasure_shop_status(), # 秘宝匣 12 件解锁投影 "tree": meta.tree_camp_rows(), "fork_groups": meta.tree_fork_groups(), } @@ -1086,7 +1086,7 @@ func _on_status_closed() -> void: _close_modal(status_panel) # 模态栈单口 -# ---- 生涯页·只读(迭代 18 卡④——入口=开始层生涯钮;开合仿设置面先例:开始层互斥; +# ---- 生涯页·只读(入口=开始层生涯钮;开合仿设置面先例:开始层互斥; # 数据快照随开随建零写通路,页内零跳转)---- func _open_career() -> void: @@ -1103,8 +1103,8 @@ func _on_career_closed() -> void: # 生涯页快照投影(只读同源——每次开层实时读 SaveManager 计数访问器 + MetaProgression 访问器 # 现值拼装(状态面板 _status_data 同构);快照仅服务单次开层生命周期,跨开层零持有;零写调用。 -# 账号成长态三投影已删〔forge_levels_total/workshop/tree——2026-10-12 用户裁:生涯页不统计 -# 天赋树与账号成长态,只统计终身计数〕) +# 生涯页只统计终身计数——不统计天赋树与账号成长态, +# 故 forge_levels_total/workshop/tree 三投影不在本投影内) func _career_data() -> Dictionary: var clears: Array[Dictionary] = [] var boss_first := 0 @@ -1130,7 +1130,7 @@ func _career_data() -> Dictionary: func _on_status_badge_pressed() -> void: var map_on: bool = level_screen != null and level_screen.visible # P1 守卫兜底——其他模态开着即拒开(常态防线=角标置灰,探针 pressed.emit 绕过 disabled 时由此兜住; - # 地图屏自身的登记开态不计;迭代 18 卡⑦ T2——判据排除调试浮窗:对局中浮窗开着时状态角标仍可点) + # 地图屏自身的登记开态不计;判据排除调试浮窗:对局中浮窗开着时状态角标仍可点) if (map_on and _modal_flow.badge_greyed_map()) or (not map_on and _modal_flow.badge_greyed_battle()): return _open_status_panel() @@ -1143,24 +1143,24 @@ func _sync_status_entry() -> void: if status_panel == null or _modals == null or board_zone == null or level_screen == null: return var map_on: bool = level_screen.visible - var battle_live: bool = run_scope.level_active or run_scope.settlement != null # 调试两层无 level_active——settlement 判据补位(迭代 18 卡⑦) + var battle_live: bool = run_scope.level_active or run_scope.settlement != null # 调试两层无 level_active——settlement 判据补位 board_zone.status_badge.visible = run_scope.level_active and not map_on level_screen.status_badge.visible = map_on - # 置灰判据改排除式(迭代 18 卡⑦ T2——调试浮窗开态不计入:对局中浮窗开着时角标仍可点) - board_zone.status_badge.disabled = _modal_flow.badge_greyed_battle() # 迭代 27 T4——互斥域谓词 + # 置灰判据为排除式(调试浮窗开态不计入:对局中浮窗开着时角标仍可点) + board_zone.status_badge.disabled = _modal_flow.badge_greyed_battle() # 互斥域谓词 level_screen.status_badge.disabled = _modal_flow.badge_greyed_map() - # 调试浮窗角标(迭代 18 卡⑦ P2 甲——迁宿主两屏,调试会话门控恒开;17卡③状态角标同形制同守卫): - # 战斗屏=对局内(冒险或调试两层)且地图屏未激活;地图屏=随屏;开始菜单零角标(恒开=启动即开) + # 状态角标判据(同上——重复语句在案): + # 战斗屏=对局内(冒险或调试两层)且地图屏未激活;地图屏=随屏;开始菜单零角标 board_zone.status_badge.visible = run_scope.level_active and not map_on level_screen.status_badge.visible = map_on - board_zone.status_badge.disabled = _modal_flow.badge_greyed_battle() # 迭代 27 T4——互斥域谓词 + board_zone.status_badge.disabled = _modal_flow.badge_greyed_battle() # 互斥域谓词 level_screen.status_badge.disabled = _modal_flow.badge_greyed_map() - # 调试浮层角标(2026-10-16 用户令:全局浮层任何 UI 不遮挡——可见性不随场景变,只抬 offset + # 调试浮层角标(全局浮层任何 UI 不遮挡——可见性不随场景变,只抬 offset # 避让:地图屏底栏 85px 常驻,角标抬至底栏上方 16px;其余场景右下角 16px 贴底) debug_badge.offset_bottom = -101.0 if map_on else -16.0 -# ---- 探针缝保缝(T4/D4 拆件——click/ui_probe 营地段直呼组合根面;实现归 camp_shop_presenter.gd)---- +# ---- 探针缝保缝(click/ui_probe 营地段直呼组合根面;实现归 camp_shop_presenter.gd)---- func _on_camp_closed() -> void: _camp_pres.on_camp_closed() @@ -1174,7 +1174,7 @@ func _on_wallet_changed(event: String, gp: int, extra: Dictionary) -> void: # wallet 行族转发(到账/购买/清零——试玩日志验收取数面)+ 常驻余额与在开商店覆盖层重刷 logger.log_wallet(event, gp, extra) if String(event) == "gain": - run_scope.last_gain_amount = int(extra.get("amount", 0)) # 卡⑥ GP 增量取数(每战恰一笔 gain) + run_scope.last_gain_amount = int(extra.get("amount", 0)) # GP 增量取数(每战恰一笔 gain) if shop_overlay.visible and run_scope.runner != null: if run_scope.runner.is_shop_pool(): shop_overlay.refresh_shelf_state(int(run_scope.runner.gp)) # pool 面余额联动(货架内容仅买后重抽变) @@ -1189,16 +1189,16 @@ func _on_board_action(cell: Vector2i, kind: String) -> void: # 玩家动作 → 核心写调用的唯一通道(模态/无战斗拒绝在此收口) if _input_locked(): return - # 结算演播期棋盘冻结(T17 用户明确令 v3——不可点/不可移/不可挖): + # 结算演播期棋盘冻结(v3 口径——不可点/不可移/不可挖): # 锁面=排播队列活跃(纯队列判据;排播泵尾迹窗口不可作演播中标志——见 row_pacer._process 注)。 # 队列排空即解锁、无状态残留;HUD 按钮不在锁面(停手/明细回看各自通路,开启前 # _flush_row_queue 自行排空)。 - # **点击不丢弃**(v3.1——用户实机「卡死」根因):锁期点击缓存最后一次,演播完边沿 + # **点击不丢弃**(v3.1——「卡死」体感根因):锁期点击缓存最后一次,演播完边沿 # (_process 泵 _was_pumping 分支)自动重放——玩家操作零丢失、体感=「演播一停动作就生效」。 if not _row_queue.is_empty(): run_scope.locked_click = {"cell": cell, "kind": kind} return - # 秘宝选中态劫持(迭代 7 T4——两步交互第二步):点格=使用目标拾取,不落挖格; + # 秘宝选中态劫持(两步交互第二步):点格=使用目标拾取,不落挖格; # 只劫持挖掘点击(move/seal 语义不冲突——选中期玩家仍可移动/封印) var treasure_sel: int = _treasure_ui.active_selection() if treasure_sel != 0 and kind == "dig": @@ -1208,15 +1208,15 @@ func _on_board_action(cell: Vector2i, kind: String) -> void: var accepted: bool = not outcomes.is_empty() and bool(outcomes[0].accepted) logger.log_action(kind, cell, accepted) if run_scope.runner != null and run_scope.runner.treasure_inventory != null: - _treasure_ui.refresh_slots() # 迭代 7 T4——授予发生在 settle_batch 结算段内(同步走完,行尾重查) + _treasure_ui.refresh_slots() # 授予发生在 settle_batch 结算段内(同步走完,行尾重查) _handle_outcome_feedback(outcomes[0] if not outcomes.is_empty() else {}) # settle_batch 内部同步走完 结算→战斗结束→关卡推进(事件同步发射)——关卡终局时 settlement 已被 - # runner 置空,清图演出判定须先判 settlement(基线既有重入隐患,2026-09-13 加固) + # runner 置空,清图演出判定须先判 settlement(重入隐患守卫) if accepted and kind == "dig" and run_scope.settlement != null and run_scope.settlement.minesweeper.current_board() != null and run_scope.settlement.minesweeper.clear_map_cleared(): board_zone.fx.play_clear_burst() if accepted and kind == "dig" and run_scope.settlement != null and run_scope.settlement.minesweeper != null: - # 挖掘演出(棋盘小人贴图批 2026-09-25):挥铲三帧 + 角色弹跳——触发=格子点开那一刻 - #(2026-09-25 用户裁决;settle_batch 同步受理即状态已变,动画纯表现与 refresh 同拍零竞态; + # 挖掘演出:挥铲三帧 + 角色弹跳——触发=格子点开那一刻 + #(settle_batch 同步受理即状态已变,动画纯表现与 refresh 同拍零竞态; # 挖掘不移动英雄,出手方向 = 目标格−英雄格,圆心=英雄持握手位) var hero_cell: Vector2i = run_scope.settlement.minesweeper.hero_pos() board_zone.fx.play_shovel_swing(board_view.hero_hand_point(), cell - hero_cell, board_view.hero_sprite_scale()) @@ -1282,7 +1282,7 @@ func _handle_outcome_feedback(outcome: Dictionary) -> void: # ==================== 全屏 States 状态机(挖掘/结算/窗口/终局)==================== -# 本轮已受理刷新次数只读面(迭代 27 T3——P1-2 刷新双账收口:main 副本已删, +# 本轮已受理刷新次数只读面(刷新双账收口: # 单一事实源=战斗编排器 _refresh_used_this_round,经 presentation_snapshot 成文面读取) func _refresh_used_snapshot() -> int: if run_scope == null or run_scope.settlement == null: @@ -1294,7 +1294,7 @@ func _refresh_presentations() -> void: # 每个核心信号/写调用返回后的全量重查装配(更新触发注记——无推送信号,命令式重查) var refresh_remaining: int = maxi(0, int(db.action_economy.refresh_cap_per_round) - _refresh_used_snapshot()) HudPresenter.refresh(stage, info_panel, ap_bar, run_scope.settlement, run_scope.runner, run_scope.level_active, db, refresh_remaining) - _treasure_ui.refresh_slots() # C 区秘宝槽重查(反哺批⑤——试炼镐积点进度随挖格刷新悬停浮窗) + _treasure_ui.refresh_slots() # C 区秘宝槽重查(试炼镐积点进度随挖格刷新悬停浮窗) _sync_settlement_visuals() @@ -1302,18 +1302,18 @@ func _sync_settlement_visuals() -> void: # 结算阶段(round_end → 下一轮):D 区去饱和+金橙偏移锁输入(明度不变)+ 明细带展开 84px var settling := _is_settling() if settling and not run_scope.was_settling: - settlement_fx.play_round_sweep(board_view.get_global_rect()) # 结算轮光带(演出链批)——时序敏感演出触发,例外留在组合根 + settlement_fx.play_round_sweep(board_view.get_global_rect()) # 结算轮光带——时序敏感演出触发,例外留在组合根 run_scope.was_settling = settling HudPresenter.sync_settlement_visuals(stage, board_view, log_view, settling, _phase_text()) func _is_settling() -> bool: - # T17 修复:结算视觉期跟随排播演播到放完。核心层同步走完(轮末结算后逻辑秒回 Active), - # 旧判定让演播期棋盘提前恢复可挖观感=用户「没意识到在结算演出」感知缺口的根源; + # 结算视觉期跟随排播演播到放完。核心层同步走完(轮末结算后逻辑秒回 Active), + # 判据若只跟逻辑态,演播期棋盘会提前恢复可挖观感=「没意识到在结算演出」感知缺口根源; # 演播期维持去饱和+禁挖光(结算中语义),放完自然回挖掘认知。判据=纯队列(排播泵尾迹 # 窗口不可作演播中标志——row_pacer._process 注)。battle 收尾演播例外: # overlay 开启即 _flush_row_queue 排空,视觉随队列空同步交接结算框。 - # 相位取数经 presentation_snapshot 成文面——禁 settlement.action_economy 链式穿透(T3 收口批)。 + # 相位取数经 presentation_snapshot 成文面——禁 settlement.action_economy 链式穿透)。 if run_scope.settlement == null or not run_scope.settlement.is_battle_live(): return not _row_queue.is_empty() if String(run_scope.settlement.presentation_snapshot().get("phase", "")) == ActionEconomy.PHASE_WAITING: @@ -1323,7 +1323,7 @@ func _is_settling() -> bool: func _phase_text() -> String: # 文案装配归 narrator(settlement 缺位 = 非战斗态——组合根模式状态守卫;相位取数经 - # presentation_snapshot 成文面——禁 settlement.action_economy 链式穿透,T3 收口批) + # presentation_snapshot 成文面——禁 settlement.action_economy 链式穿透) if run_scope.settlement == null: return "第 — 轮 · —" return Narrator.phase_text(int(run_scope.settlement.round_index), String(run_scope.settlement.battle_result), @@ -1343,30 +1343,30 @@ func _on_legend_toggled() -> void: # ==================== 诊断转储(卡死时点击——全量核心状态 + 环形缓冲)==================== func _on_diagnose_pressed() -> void: - # 迭代 18 卡⑦——本局种子现值(原 _seed_value() 重算冒充病灶改向 _current_master_seed 只读单点) + # 本局种子现值走 _current_master_seed 只读单点 var ctx := {"mode": "level" if run_scope.level_active else "debug", "seed": _current_master_seed()} if run_scope.level_active and run_scope.runner != null: ctx["runner"] = {"node_index": run_scope.runner.node_index, "level_result": String(run_scope.runner.level_result), "hero_hp": run_scope.runner.hero_hp, "settlement_is_null": run_scope.runner.current_battle() == null} if run_scope.settlement != null: - ctx["settlement"] = run_scope.settlement.diagnostic_snapshot() # 诊断观测面(私有字段零直读——code-review 2026-09-12) + ctx["settlement"] = run_scope.settlement.diagnostic_snapshot() # 诊断观测面(私有字段零直读) var path: String = logger.dump_diagnosis(ctx) board_zone.toast.show_toast("已转储诊断: " + path, "info") -# ==================== 调试浮窗(迭代 14.5 整合批——原数值调整板节收编;开合/应用/模拟编排组合根承接)==================== +# ==================== 调试浮窗(开合/应用/模拟编排由组合根承接)==================== func _show_debug_overlay() -> void: - # 门禁改向(迭代 18 卡⑦ P2/P3 甲——对局中可开;本函数仍是唯一开窗入口 C6,门禁逻辑收函数内): - # 旧「仅开始菜单可开」门随入口迁宿主退役——棋盘输入锁/状态角标判据已排除浮窗(T2 防护), - # 遮挡语义=P1 甲 ModalStack 登记制(他模态开时暂隐、关后自动恢复),此处零场景限制 + # 门禁:对局中可开;本函数仍是唯一开窗入口,门禁逻辑收函数内: + # 棋盘输入锁/状态角标判据排除浮窗, + # 遮挡语义=ModalStack 登记制(他模态开时暂隐、关后自动恢复),此处零场景限制 if debug_overlay == null: return _open_modal(debug_overlay) _sync_debug_overlay() -# 调试浮窗角标点击(两屏同款处理器——17卡③状态角标同形制守卫;C6:仍收口 _show_debug_overlay 单口) +# 调试浮窗角标点击(两屏同款处理器——与状态角标同形制守卫;仍收口 _show_debug_overlay 单口) func _on_debug_badge_pressed() -> void: var map_on: bool = level_screen != null and level_screen.visible if (map_on and _modal_flow.badge_greyed_map()) or (not map_on and _modal_flow.badge_greyed_battle()): @@ -1374,19 +1374,19 @@ func _on_debug_badge_pressed() -> void: _show_debug_overlay() -# 浮窗上下文同步(迭代 18 卡⑦——当局数据刷新+对局中按钮禁用单点):调用面=开窗口与模态开合 +# 浮窗上下文同步(当局数据刷新+对局中按钮禁用单点):调用面=开窗口与模态开合 # 单口(凡影响开态/对局态的路径必经其一——与 _sync_status_entry 同款纪律) func _sync_debug_overlay() -> void: if debug_overlay == null: return - debug_overlay.set_context_locked(run_scope.settlement != null or run_scope.is_adventure) # 对局中批量模拟/两层调试入口禁用(长程异步模拟与活跃结算并存态不开放——T2) - debug_overlay.update_run_data(_debug_run_data()) # T3 当局数据只读区块喂入(开窗+模态开合信号驱动) + debug_overlay.set_context_locked(run_scope.settlement != null or run_scope.is_adventure) # 对局中批量模拟/两层调试入口禁用(长程异步模拟与活跃结算并存态不开放) + debug_overlay.update_run_data(_debug_run_data()) # 当局数据只读区块喂入(开窗+模态开合信号驱动) -# 当局数据六项只读投影(P4 甲——C4 零直读内部状态、零写通路):种子=adventure.master_seed 现值 -# (非 _seed_value() 重算);调试两层/非对局无冒险对象=RNG 服务 master_seed 现值(E5 只读出口, +# 当局数据六项只读投影(零直读内部状态、零写通路):种子=adventure.master_seed 现值 +# (非 _seed_value() 重算);调试两层/非对局无冒险对象=RNG 服务 master_seed 现值(只读出口, # 未播种 -1 显「—」);关卡/节点/HP/GP=runner 成文出口、钥石=adventure 冒险账本(LevelRunner 无此域); -# 缺位=「—」占位。零动效(纯标签重查——17卡③契约)。 +# 缺位=「—」占位。零动效(纯标签重查)。 func _debug_run_data() -> Dictionary: var r = run_scope.adventure.runner() if run_scope.adventure != null else null var seed_now: int = _current_master_seed() @@ -1398,7 +1398,7 @@ func _debug_run_data() -> Dictionary: # 本局种子现值(只读单点——当局数据区块与诊断转储共用):冒险=adventure.master_seed 访问器现值; -# 调试两层=RNG 服务 master_seed。禁 _seed_value() 重算冒充本局种子(main.gd 旧 :1174 病灶随批改向)。 +# 调试两层=RNG 服务 master_seed。禁 _seed_value() 重算冒充本局种子。 func _current_master_seed() -> int: if run_scope.adventure != null: return int(run_scope.adventure.master_seed) @@ -1410,13 +1410,13 @@ func _close_debug_overlay() -> void: func _on_tune_apply(atk_pct: int, hp_pct: int) -> void: - # E4:加成无持久态可"落"——各战斗开局经 _debug_hero_override/runner 现算生效(应用=关闭浮窗) + # 加成无持久态可"落"——各战斗开局经 _debug_hero_override/runner 现算生效(应用=关闭浮窗) _close_debug_overlay() func _on_tune_simulate(n: int) -> void: # 批量模拟编排 = 控制器承接(tune_sim_controller.gd);E4 后无表态需复位——模拟走 runner 覆盖参数。 - # 对局中禁用兜底(迭代 18 卡⑦ T2——长程异步模拟与活跃结算并存态不开放;探针 emit 绕过 disabled 时由此守住) + # 对局中禁用兜底(长程异步模拟与活跃结算并存态不开放;探针 emit 绕过 disabled 时由此守住) if run_scope.settlement != null: return _tune_sim.run(n) @@ -1425,10 +1425,10 @@ func _on_tune_simulate(n: int) -> void: # ==================== 工具 ==================== func _seed_value() -> int: - # 种子三分判定单点(迭代 18 卡⑦ C1——全工程唯一种子框读取处,禁第二处读框): + # 种子三分判定单点(全工程唯一种子框读取处,禁第二处读框): # ①显式合法整数全场景优先(含首局——测试/调试接口显式指定;第五路 DebugSession Callable - # 经本函数=调试对局与玩家同口径,P6 甲); - # ②首局固定 42(P5 甲——存档现役布尔 is_first_adventure_done:新档显式 false=教学局恒 42〔教学 + # 经本函数=调试对局与玩家同口径); + # ②首局固定 42(存档现役布尔 is_first_adventure_done:新档显式 false=教学局恒 42〔教学 # 重放模板 0 即在此种子下标定〕;置位 true=教学局已收束的非首局走 ③ 随机); # ③非首局空/非法框=引擎全局熵 randi()(Godot 4 启动自播种子,headless 同;不走 rng_service # 封闭流、禁 randomize()/自建 RNG——组合根建种子属引擎熵豁免面,不进玩法 RNG 消费) diff --git a/game/presentation/modal_flow.gd b/game/presentation/modal_flow.gd index c65ade96..16fd35b4 100644 --- a/game/presentation/modal_flow.gd +++ b/game/presentation/modal_flow.gd @@ -1,6 +1,6 @@ class_name ModalFlow extends RefCounted -# 模态编排纯逻辑类(迭代 27 T4——审计 P1-5/P2-7:组合根可测化抽取 + 模态互斥域内聚)。 +# 模态编排纯逻辑类(组合根可测化 + 模态互斥域内聚)。 # 依赖仅 ModalStack + 查询 Callable(审计处方原话)——零节点构建、零信号连接、零核心触碰 #(同构:连接归组合根,本类只收注入)。可直接 new() 单测(V6)。 # 职责三件: @@ -19,7 +19,7 @@ var start_visible_get: Callable # () -> bool——开始层可见(非模态 var inter_visible_get: Callable # () -> bool——过场层可见(例外二) var settlement_get: Callable # () -> Variant——当前战斗编排器(null=战斗缺位例外三) var rows_empty_get: Callable # () -> bool——排播队列空(演播后排窗判据) -var flush_rows: Callable # 开层前排空排播(卡⑦——明细带恒完整) +var flush_rows: Callable # 开层前排空排播(明细带恒完整) var on_open_sync: Callable # 开侧同步钩子(状态角标+浮窗当局数据) var on_close_sync: Callable # 关侧同步钩子 var replay_click: Callable # 演播完边沿无挂起时的锁期点击重放(main._replay_locked_click) @@ -38,7 +38,7 @@ func open(m: Control) -> void: var dm: Control = _deferred _deferred = null open(dm) # 原语义:先结挂起后继续开本层(不 return——两拍都走) - flush_rows.call() # 卡⑦——任何覆盖层开启前排空排播队列(明细带恒完整,回看/停点面不缺行) + flush_rows.call() # 任何覆盖层开启前排空排播队列(明细带恒完整,回看/停点面不缺行) stack.open(m) on_open_sync.call() @@ -48,7 +48,7 @@ func close(m: Control) -> void: on_close_sync.call() -# 演播后排窗(T17 用户令「伤害过程演完才切结算窗口」):排播队列在播=挂起,演播完边沿 +# 演播后排窗(伤害过程演完才切结算窗口):排播队列在播=挂起,演播完边沿 # (pump_ended 派发)再开——旧路径前置 flush 会把击杀轮的伤害/死亡演出同帧倒掉。 # 队列空=立即开(行为同旧路径)。 func open_after_playback(m: Control) -> void: @@ -70,8 +70,8 @@ func pump_ended() -> void: replay_click.call() -# 棋盘输入锁谓词(原 main._input_locked 随迁):模态互斥域(non_locking 层开态不计——迭代 18 -# 卡⑦ T2 防线)+ 三例外(开始层/过场层非模态全屏态 + 战斗缺位棋盘输入无载体)。 +# 棋盘输入锁谓词:模态互斥域(non_locking 层开态不计=调试浮窗防永久锁死的排除组) +# + 三例外(开始层/过场层非模态全屏态 + 战斗缺位棋盘输入无载体)。 func locks_input() -> bool: return stack.has_open_excluding_tags([ModalStackScript.TAG_NON_LOCKING]) \ or bool(start_visible_get.call()) or bool(inter_visible_get.call()) or settlement_get.call() == null diff --git a/game/presentation/modal_stack.gd b/game/presentation/modal_stack.gd index 284ff71b..dd8f0ec4 100644 --- a/game/presentation/modal_stack.gd +++ b/game/presentation/modal_stack.gd @@ -6,10 +6,10 @@ extends RefCounted var _list: Array[Control] = [] # 登记序 = z 遮挡序(低 → 高) var _occluded := {} # modal → 被其隐藏的上方层(关闭恢复) -var _tags := {} # modal → 排除组标签集(迭代 27 T4——互斥域随层登记;P2-7 开态谓词收口) +var _tags := {} # modal → 排除组标签集(互斥域随层登记) # 排除组封闭词表(组合根登记用——新标签=改此处+评审,防调用点拼装回潮) -const TAG_NON_LOCKING := "non_locking" # 开态不计入棋盘输入锁与角标置灰(调试浮窗——迭代 18 卡⑦ T2 防线:调试浮窗默认开×遮挡复活×has_open 组合=棋盘永久锁死) +const TAG_NON_LOCKING := "non_locking" # 开态不计入棋盘输入锁与角标置灰(调试浮窗默认开×遮挡复活×has_open 组合=棋盘永久锁死) const TAG_SCREEN_STATE := "screen_state" # 常驻屏态(关卡地图屏——自身开态不计入本屏角标判据) @@ -38,7 +38,7 @@ func close(m: Control) -> void: _occluded.erase(m) -# 开态查询(T3 模态收口批 2026-10-02——组合根输入锁唯一判据:登记册上是否有任一层处于开态; +# 开态查询(组合根输入锁唯一判据:登记册上是否有任一层处于开态; # 可见性即开态,与 open/close 记账同源——组合根不再手工罗列各层) func has_open() -> bool: for m in _list: @@ -47,9 +47,9 @@ func has_open() -> bool: return false -# 排除组开态查询(迭代 27 T4——P2-7 模态协议内聚:原「调用点排除式拼装」has_open_excluding/ -# has_open_excluding_any 退役,排除语义随层登记(register tags),查询按组名集合表达。 -# 只读查询零副作用——登记序/开合记账语义零改动;空标签集=全计(与旧 has_open 同形)。 +# 排除组开态查询(模态协议内聚:排除语义随层登记(register tags), +# 查询按组名集合表达,禁在调用点拼装 has_open_excluding/has_open_excluding_any。 +# 只读查询零副作用——登记序/开合记账语义不变;空标签集=全计(与 has_open 同形)。 func has_open_excluding_tags(exclude_tags: Array) -> bool: for m in _list: if is_instance_valid(m) and m.visible: diff --git a/game/presentation/playtest_logger.gd b/game/presentation/playtest_logger.gd index 2a3be2d3..1d8dce84 100644 --- a/game/presentation/playtest_logger.gd +++ b/game/presentation/playtest_logger.gd @@ -53,10 +53,10 @@ func _on_battle_finished_log(p: Dictionary) -> void: _append({ "kind": "battle_end", "result": String(p.get("result", "")), "hero_hp": int(p.get("hero_hp", 0)), - "gp_dropped": int(p.get("gp_dropped", 0))}) # 战斗掉落列(GP+商店房实施批 2026-09-21——验收取数面) + "gp_dropped": int(p.get("gp_dropped", 0))}) # 战斗掉落列(验收取数面) -# ---- GP 钱包行(GP+商店房实施批——到账/购买/清零事件;runner wallet_changed 投影经组合根转发)---- +# ---- GP 钱包行(到账/购买/清零事件;runner wallet_changed 投影经组合根转发)---- func log_wallet(event: String, gp: int, extra: Dictionary = {}) -> void: var line := {"kind": "wallet", "event": event, "gp": gp} @@ -76,7 +76,7 @@ func log_ux(ux_kind: String, payload: Dictionary) -> void: func log_action(kind: String, cell: Vector2i, accepted: bool, extra: Dictionary = {}) -> void: _ux_inputs += 1 # 原始输入动作数(含被拒——P4 ≤2 护栏观测口径 = 原始输入) - # 逐操作落盘(2026-09-12 用户要求:操作记录完整持久化——此前仅入环形缓冲、卡死诊断才可见) + # 逐操作落盘(操作记录须完整持久化,禁只入环形缓冲) var line := {"kind": "action", "op": kind, "cell": [cell.x, cell.y], "accepted": accepted} for k in extra.keys(): line[k] = extra[k] @@ -106,8 +106,8 @@ func log_node(node: Dictionary, info: Dictionary, node_index: int) -> void: elif t == "rest": line["healed"] = int(info.get("healed", 0)) elif t == "shop": - line["gp"] = int(info.get("gp", 0)) # 进店时点余额(GP+商店房实施批) - # reward 节点:内容待拍板(格面资源批 2026-09-15 道具删除)——零载荷 + line["gp"] = int(info.get("gp", 0)) # 进店时点余额 + # reward 节点:零载荷(节点内容未在呈现面定义) _append(line) @@ -126,10 +126,10 @@ func log_level_end(payload: Dictionary) -> void: func _on_step_row(row: Dictionary) -> void: _ring(_recent_steps, {"t": row.type, "src": row.source_class, "v": int(row.value), "r": int(row.round_index)}) - # 结算明细行逐行落盘(2026-09-12 用户要求——五段结算完整回放数据面); + # 结算明细行逐行落盘(五段结算完整回放数据面); # 公共七字段之外的全部行字段(payload:roll/ac/tier/crit/normal/pierce/magic/baseline/rider/target/ - # effect_id/pool_value 等)随行平铺落盘(2026-09-17 数值分析工具批——无 payload 的旧日志反事实只能 - # 比例近似,新日志可精确重算)。 + # effect_id/pool_value 等)随行平铺落盘(无 payload 时反事实只能 + # 比例近似,带 payload 可精确重算)。 var line := {"kind": "step", "type": row.type, "source": row.source_class, "cell": row.origin_cell, "round": int(row.round_index), "text": String(row.display_name), "value": int(row.value), diff --git a/game/presentation/row_pacer.gd b/game/presentation/row_pacer.gd index c734b9f9..d5ca6037 100644 --- a/game/presentation/row_pacer.gd +++ b/game/presentation/row_pacer.gd @@ -5,7 +5,7 @@ ## 视图句柄与 refresh_request/pump_ended 回调由组合根注入——本类零信号连接。 extends Node -const PACE_SEGMENT_GAP := 0.3 # 段间阶梯延迟(代拍板:白名单 0.2–0.4s 内取值,追认清单呈报) +const PACE_SEGMENT_GAP := 0.3 # 段间阶梯延迟(取值须落白名单 0.2–0.4s 档位带内) const PACE_ROW_GAP := 0.22 # 段内间隔(三轮 #3 上调 0.06→0.22——逐条演出可感知,配合数字浮现/状态脉冲) var _rows: Array[Variant] = [] # 待排播行(step_row 载荷原样入队;__round_line 标记=轮首分隔行) @@ -54,7 +54,7 @@ func flush() -> void: func _process(delta: float) -> void: - # 排播泵(卡⑦——演出层帧驱动;队列空=零开销直返) + # 排播泵(演出层帧驱动;队列空=零开销直返) if _rows.is_empty(): _pace_wait = 0.0 _prev_segment = "" @@ -79,7 +79,7 @@ func _process(delta: float) -> void: _prev_segment = seg -# 行消费(排播队列的出队步 / 减动效快路共用):明细带入带+演出链+呈现刷新——与卡⑦前排位逐位一致 +# 行消费(排播队列的出队步 / 减动效快路共用):明细带入带+演出链+呈现刷新 func _consume_row(row: Dictionary) -> void: if row.has("__round_line"): log_view.finish_settlement_round() # 上轮摘要行(明细带 pattern 3)随轮首分隔行落带 @@ -94,14 +94,14 @@ func _consume_row(row: Dictionary) -> void: board_zone.fx.play_perfect_sweep() elif String(row.get("highlight", "")) == "seal_hit": board_zone.fx.play_seal_hit_projectile(true) - # Boss 半血解锁技提示(迭代14④ T4——D8 呈现面:skill_unlock 行弹一次性技能名 toast, + # Boss 半血解锁技提示(D8 呈现面:skill_unlock 行弹一次性技能名 toast, # 轻量非演出零动画资产;行文本 =「XX 解锁了 YY」,只报技能名不报数值——规格=敌人系统 意图呈现节) if String(row.get("highlight", "")) == "skill_unlock": board_zone.toast.show_toast(String(row.get("display_name", "")), "info") refresh_request.call() -# 逐条结算标出(三轮 #3——用户裁决按结算顺序演出:先 Buff/Debuff 特效、再基础伤害数字; +# 逐条结算标出(按结算顺序演出:先 Buff/Debuff 特效、再基础伤害数字; # 打中谁标谁、主角被打标主角;道具/奖励行逐条冒出)。目标解析失败兜底棋盘中心。 func _play_settlement_mark(row: Dictionary) -> void: var mark_type := String(row.get("type", "")) @@ -135,7 +135,7 @@ func _play_cross_zone_fx(row: Dictionary) -> void: var target := String(row.get("target", "")) var crit := bool(row.get("crit", false)) if target == "" or target == "hero": - # 主角受击弹道(迭代 6 T5 拆「敌→主角零反馈」早退):⚔ 危险红飞向主角站桩; + # 主角受击弹道(禁「敌→主角零反馈」早退):⚔ 危险红飞向主角站桩; # crit 只加重字号不加金(金=收益/胜利语义位,不用于敌方对主角输出) settlement_fx.play_projectile(from_v, stage.hero_standee_center(), "⚔", UiKit.RED_MINE, crit) diff --git a/game/presentation/run_scope.gd b/game/presentation/run_scope.gd index 3f1855f7..27e916e2 100644 --- a/game/presentation/run_scope.gd +++ b/game/presentation/run_scope.gd @@ -1,6 +1,6 @@ class_name RunScope extends Node -# 一局会话状态承载(迭代 27 T1——P0-2「局生命周期物化」修复波)。 +# 一局会话状态承载(局生命周期单点)。 # 会话 = 一次冒险(开新/续玩)或一次调试两层对局;组合根 _begin_session 创建本节点挂树、 # 会话更替/终局整节点 queue_free()——旧手工复位清单(原 main._reset_run_scope 三项 + # _on_battle_end_continue 置空四件)随节点释放机制消亡,此后新增跨局字段零新增泄漏点 @@ -16,7 +16,7 @@ var level_screen_active := false # 关卡独立屏激活状态(屏级互斥 var boss_active := false # Boss 遭遇变体(阶段指示附 Boss 名) var was_settling := false # 结算相位上升沿检测(结算轮光带触发——演出链批) var hints_shown := {} # 一次性非模态提示去重(每 run 一次:chord/no_adjacent) -var settlement_stop_timer := ArmedTimer.new() # 卡⑥ 结算框挂起计时(T3/D3 P4 乙——窗口 0=挂起到显式回落) +var settlement_stop_timer := ArmedTimer.new() # 结算框挂起计时(窗口 0=挂起到显式回落) var pending_candidates: Array[Variant] = [] # 结算框挂起期的选路候选暂存(choices_presented 载荷) var locked_click := {} # 锁期点击缓存(T17 v3.1——最后一次;演播完边沿重放) -var last_gain_amount := 0 # 最近一笔钱包入账(卡⑥ GP 增量取数面——wallet_changed gain 载荷) +var last_gain_amount := 0 # 最近一笔钱包入账(GP 增量取数面——wallet_changed gain 载荷) diff --git a/game/presentation/scenes/adventure_screen.gd b/game/presentation/scenes/adventure_screen.gd index 1d4e0cc7..5a5882a5 100644 --- a/game/presentation/scenes/adventure_screen.gd +++ b/game/presentation/scenes/adventure_screen.gd @@ -1,6 +1,6 @@ class_name AdventureScreen extends Control -# 冒险屏壳(迭代 27 T1 场景拆分——审计 P0-1 第一步;内含关卡地图屏与战斗屏两容器)。 +# 冒险屏壳(内含关卡地图屏与战斗屏两容器)。 # 两容器视图原样构建(build_battle_ui 归 ui_assembler 纪律不变、LevelMapScreen 类视图继续 # 代码构建、零 .tscn 化改造——契约 2);战斗信号接线归组合根 main.gd(信号连接 # 只在组合根)。树序语义:本屏壳挂 main 首子位(全模态之下)——屏内 level_screen 与 diff --git a/game/presentation/scenes/camp_screen.gd b/game/presentation/scenes/camp_screen.gd index d580c533..47c7bb08 100644 --- a/game/presentation/scenes/camp_screen.gd +++ b/game/presentation/scenes/camp_screen.gd @@ -1,6 +1,6 @@ class_name CampScreen extends Control -# 营地屏壳(迭代 27 T1 场景拆分——审计 P0-1 第一步)。 +# 营地屏壳(营地覆盖层的屏壳容器)。 # 营地覆盖层视图原样构建(CampOverlay 类视图继续代码构建、零 .tscn 化改造——契约 2); # 购买/开合接线归组合根经 CampShopPresenter(信号连接只在组合根)。 # 可独立实例化(F6/headless 挂载)——V2 探针断言载体。 diff --git a/game/presentation/scenes/menu_screen.gd b/game/presentation/scenes/menu_screen.gd index 47d285b8..64859195 100644 --- a/game/presentation/scenes/menu_screen.gd +++ b/game/presentation/scenes/menu_screen.gd @@ -1,6 +1,6 @@ class_name MenuScreen extends Control -# 开始菜单屏壳(迭代 27 T1 场景拆分——审计 P0-1「场景作为组合单元/生命周期单元」第一步)。 +# 开始菜单屏壳(场景=组合单元与生命周期单元)。 # 视图代码原样构建(节点构建归 ui_assembler.gd 纪律不变——本屏壳只持有与暴露句柄); # 按钮接线归组合根 main.gd(信号连接只在组合根)。 # 可独立实例化(F6/headless 挂载)——V2「各新屏场景可独立实例化」探针断言载体。 diff --git a/game/presentation/treasure_interact_controller.gd b/game/presentation/treasure_interact_controller.gd index 06c1ec16..cafc6cc4 100644 --- a/game/presentation/treasure_interact_controller.gd +++ b/game/presentation/treasure_interact_controller.gd @@ -14,7 +14,7 @@ var toast: ToastStack # 反馈面(board_zone.toast 注入) var board_view: BoardView var _settlement_get: Callable # () → 当前战斗结算现值(组合根 lambda) var _runner_get: Callable # () → 当前关卡推进器现值(组合根 lambda) -var _use_selection := 0 # 选中句柄(迭代 7 T4——0=未选中;选中期棋盘点击=使用目标拾取) +var _use_selection := 0 # 选中句柄(0=未选中;选中期棋盘点击=使用目标拾取) func _init(db_ref, meta_ref, info_panel_ref: HeroInfoPanelView, toast_ref: ToastStack, @@ -28,8 +28,8 @@ func _init(db_ref, meta_ref, info_panel_ref: HeroInfoPanelView, toast_ref: Toast _runner_get = runner_get -# aux 解锁门控集组装(迭代 7 T5——拍板③甲:工坊解锁 ∩ 过渡活行词表;罗盘退役/失义件/同调行不入集 -# ——迭代 11 第①批 T1 切 treasure_transitional_rows 口径,同调行永不入过渡渠道) +# aux 解锁门控集组装:工坊解锁 ∩ 过渡活行词表(treasure_transitional_rows 口径); +# 罗盘/失义件/同调行不入集(同调行永不入过渡渠道) func unlocked_set() -> Dictionary: var out := {} if meta == null: @@ -47,7 +47,7 @@ func active_selection() -> int: # 槽点击(第一步):AP 类(target=none)点击即用(无目标);空间类进/出选中态(toggle 取消); -# 自动兑付件展示行(handle<0)无使用动作——点击给说明提示(反哺批⑤)。 +# 自动兑付件展示行(handle<0)无使用动作——点击给说明提示。 func on_slot_clicked(slot_handle: int) -> void: var settlement = _settlement_get.call() var runner = _runner_get.call() @@ -93,7 +93,7 @@ func attempt_use(handle: int, cell: Variant = null) -> void: _use_selection = 0 refresh_slots() refresh_overlays() - board_view.refresh() # 迭代 13 T8/D6——移除格即时落图(无移除态的件 diff 零变化幂等) + board_view.refresh() # 移除格即时落图(无移除态的件 diff 零变化幂等) var arow: Dictionary[Variant, Variant] = db.treasure_item_row(String(v.get("item_id", ""))) toast.show_toast("已使用 %s" % String(arow.get("display_name", "")), "info") @@ -115,7 +115,7 @@ func inventory_projection() -> Array: for rec in runner.treasure_inventory.query_inventory(cb): var arow: Dictionary[Variant, Variant] = db.treasure_item_row(String(rec.get("item_id", ""))) var dn := String(arow.get("display_name", "")) - # 积点进度浮窗行(反哺批⑤——自动兑付件 C 区悬停 tooltip 补 N/M 进度;件 id 锁定=装配行唯一) + # 积点进度浮窗行(自动兑付件 C 区悬停 tooltip 补 N/M 进度;件 id 锁定=装配行唯一) var note := "" if bool(cs.get("assembled", false)) and String(cs.get("item_id", "")) == String(rec.get("item_id", "")): note = "积点 %d/%d" % [int(cs.get("points", 0)), int(cs.get("need", 0))] @@ -129,7 +129,7 @@ func inventory_projection() -> Array: "usable": bool(rec.get("usable", true)), "note": note, }) - # 自动兑付件展示行(反哺批⑤补——charges=0 不入骑库存〔_reseed_attune_charges 跳过注入〕, + # 自动兑付件展示行(charges=0 不入骑库存〔_reseed_attune_charges 跳过注入〕, # C 区四槽末尾补合成行承载悬停进度;handle=-1 非库存句柄:槽点击走说明 toast 分支不进两步交互) if bool(cs.get("assembled", false)) and not auto_seen: var adn := String(cs.get("display_name", "")) diff --git a/game/presentation/tune_sim_controller.gd b/game/presentation/tune_sim_controller.gd index d0c41728..12e52666 100644 --- a/game/presentation/tune_sim_controller.gd +++ b/game/presentation/tune_sim_controller.gd @@ -28,7 +28,7 @@ func _autoplay(): func run(n: int) -> void: - # 共享日志会话(2026-09-12 用户要求:模拟运行与真人试玩同日志合规——操作/轮次/战斗/通关全量 JSONL; + # 共享日志会话(模拟运行与真人试玩同日志合规——操作/轮次/战斗/通关全量 JSONL; # 一文件多局,run 行携带种子切分局次) var logger = PlaytestLogger.new() logger.ap_per_round = int(db.action_economy.ap_per_round) diff --git a/game/presentation/ui_assembler.gd b/game/presentation/ui_assembler.gd index eeb30884..44e3d50a 100644 --- a/game/presentation/ui_assembler.gd +++ b/game/presentation/ui_assembler.gd @@ -5,15 +5,15 @@ extends RefCounted -# 战斗屏三区(B 战斗画面 / C·D 两列——A 区关卡进度条顶栏随 停点前移批 2026-09-23 退役:节点链 -# 进度由关卡画面本体(选路覆盖层整图)承载,28px 纵向空间拨给 C/D 底行 520→548;E 区道具面板 -# 已随可选类删除下线,2026-09-15 格面资源批)。 -# + 结算演出覆盖层(A–D 之上、模态之下——跨区弹道/光带载体,结算演出链批 2026-09-20)。 +# 战斗屏三区(B 战斗画面 / C·D 两列——节点链 +# 进度由关卡画面本体(选路覆盖层整图)承载,28px 纵向空间拨给 C/D 底行 520→548; +# 无顶栏进度条、无道具面板区)。 +# + 结算演出覆盖层(A–D 之上、模态之下——跨区弹道/光带载体)。 # 返回句柄字典:{stage, log_view, info_panel, board_zone, board_view, ap_bar, settlement_fx} -# (gp_label/keystone_label 随 2026-09-26 信息归属拍板退役——GP/钥石迁出战斗屏,句柄不再透出) +# (返回句柄不含 gp_label/keystone_label——GP/钥石不在战斗屏呈现) static func build_battle_ui(root: Control, db) -> Dictionary: # set_anchors_and_offsets_preset(非 set_anchors_preset):后者会把控件重置回最小内容尺寸 - # (实测 927×613——缩顶、棋盘 45px 格 ×10 行超出 D 区 333px 高被裁,2026-09-13 用户报告回归) + # (实测 927×613——缩顶、棋盘 45px 格 ×10 行超出 D 区 333px 高被裁) root.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) root.add_theme_constant_override("separation", 0) @@ -21,7 +21,7 @@ static func build_battle_ui(root: Control, db) -> Dictionary: var stage := BattleStageView.new(db) root.add_child(stage) - # C/D 两列(548px——停点前移批 2026-09-23:原 A 区 28px 顶栏纵向空间并入) + # C/D 两列(548px——含顶栏让出的 28px 纵向空间) var bottom := HBoxContainer.new() bottom.size_flags_vertical = Control.SIZE_EXPAND_FILL bottom.add_theme_constant_override("separation", 4) @@ -38,16 +38,16 @@ static func build_battle_ui(root: Control, db) -> Dictionary: var settlement_fx := SettlementFxView.new() root.add_child(settlement_fx) - # CJK 字体随包(2026-09-27 用户拍板 Fusion Pixel OFL):Control 侧默认主题字体走 project.godot + # CJK 字体随包(Fusion Pixel OFL):Control 侧默认主题字体走 project.godot # gui/theme/custom_font;SubViewport 两世界不继承 Control 主题——显式注入挂点接线(C6 挂点链)。 - # 缺位守卫(load_font 返回 null = 引擎回退字体,与旧 Button 渲染同源,不炸)。 + # 缺位守卫(load_font 返回 null = 引擎回退字体,不炸)。 var ui_font: Font = UiKit.load_font(UiKit.FONT_UI) if ui_font != null: stage.set_world_font(ui_font) board_zone.board_view.set_world_font(ui_font) - # GP/钥石余额位已随 2026-09-26 信息归属拍板退役(中/大循环资源迁出战斗屏—— - # GP 去向 = 关卡画面+战斗结算画面、钥石去向 = 结算画面+营地,呈现归对应 UX spec 批次) + # GP/钥石余额位不在战斗屏(中/大循环资源迁出战斗屏—— + # GP 去向 = 关卡画面+战斗结算画面、钥石去向 = 结算画面+营地,呈现归对应 UX spec) return { "stage": stage, "log_view": stage.log_view, @@ -61,11 +61,11 @@ static func build_battle_ui(root: Control, db) -> Dictionary: # 模态覆盖层组(z 序 = 登记序:图例 < 节点 < 终局 < 商店)。 # 返回 {legend_overlay, node_overlay, end_overlay, shop_overlay};调用方按本序 addChild。 -# (调整板已随迭代 14.5 调试整合批退役——调试浮窗由组合根直构挂树序最末,见 main._build_ui; -# 明细回看 overlay 已随 M9/P-C7 退役 2026-10-04——冒险中回看归「生涯」06 登记; -# 营地覆盖层已随迭代 27 T1 场景拆分迁 camp_screen 屏壳——本组不再构建) +# (本组不含调试浮窗——由组合根直构挂树序最末,见 main._build_ui; +# 本组不含明细回看 overlay——冒险中回看归「生涯」页; +# 本组不含营地覆盖层——在 camp_screen 屏壳构建) static func build_overlays(host: Control, db) -> Dictionary: - var legend_overlay := LegendOverlay.new(int(db.action_economy.rap_refresh_cost)) # 打磨包 2026-09-29——RAP 行表值注入 + var legend_overlay := LegendOverlay.new(int(db.action_economy.rap_refresh_cost)) # RAP 行表值注入 host.add_child(legend_overlay) var node_overlay := NodeOverlay.new() @@ -74,7 +74,7 @@ static func build_overlays(host: Control, db) -> Dictionary: var end_overlay := BattleEndOverlay.new() host.add_child(end_overlay) - # 商店覆盖层(GP+商店房实施批 2026-09-21——商店房节点兑付呈现;按钮接线归组合根,装配器零信号连接) + # 商店覆盖层(商店房节点兑付呈现;按钮接线归组合根,装配器零信号连接) var shop_overlay := ShopOverlay.new() host.add_child(shop_overlay) @@ -87,23 +87,23 @@ static func build_overlays(host: Control, db) -> Dictionary: # 开始覆盖层(返回 {overlay, box, lvbtn, resumebtn, campbtn, careerbtn, settingsbtn, quitbtn}——按钮接线归组合根; -# 迭代 14.5 调试整合批:随机种子/数值调整板/两层调试三散件撤出主按钮组,收进调试浮窗—— -# 2026-10-16 用户令:调试入口=UI 最顶层全局浮层角标(build_debug_badge,本层零调试入口) -# UI 落码批 M2(2026-10-04):单列 VBox→双列(左操作 56% + 右舞台);按钮动词化+悬停解释 -#(解释全迁 tooltip,G5);lvbtn 升主操作钮(烛光黄 CANDLE);右列=立绘看台。**玩法速览牌已退役 -#(2026-10-06 用户令:界面禁玩法文字墙——教学内容归 Beta 帮助手册〔教学引导定稿批 P4 丙〕,历史文案在 git)**; -# tooltip 主题归全局主题单点(迭代 25 2026-10-13——旧 root 挂程序化 tooltip 主题的做法退役)。 -# 返回键集不变,组合根接线零改) +# 随机种子/数值调整板/两层调试三散件不在主按钮组,收进调试浮窗—— +# 调试入口=UI 最顶层全局浮层角标(build_debug_badge,本层零调试入口) +# 布局=双列 VBox(左操作 56% + 右舞台);按钮动词化+悬停解释 +#(解释全迁 tooltip,G5);lvbtn 为主操作钮(烛光黄 CANDLE);右列=立绘看台。**界面禁玩法文字墙 +#(教学内容归 Beta 帮助手册〔教学引导定稿 P4 丙〕)**;本层无玩法速览牌; +# tooltip 主题归全局主题单点(禁在 root 挂程序化 tooltip 主题)。 +# 返回键集如首行所列,接线归组合根) static func build_start_overlay(host: Control, db = null) -> Dictionary: var overlay := overlay_bg(host, UiKit.BG_BRIGHT) - # 石纹弱质感+斜光带+暗角(UI 对齐批 T5 2026-10-06——demo .tilebg 0.14/.beams/.vignette 三层; - # 旧满铺石纹不透退役。缺位不挂即回退平色) + # 石纹弱质感+斜光带+暗角(demo .tilebg 0.14/.beams/.vignette 三层; + # 石纹层用半透明贴图,非满铺不透。缺位不挂即回退平色) var bd := UiKit.backdrop_tile() if bd != null: overlay.add_child(bd) overlay.add_child(UiKit.beams_rect()) overlay.add_child(UiKit.vignette_rect()) - # 双列骨架(M2):左=操作列 56% / 右=舞台+速览 + # 双列骨架:左=操作列 56% / 右=舞台(立绘看台) var cols := HBoxContainer.new() cols.set_anchors_preset(Control.PRESET_FULL_RECT) cols.add_theme_constant_override("separation", 32) @@ -124,14 +124,14 @@ static func build_start_overlay(host: Control, db = null) -> Dictionary: box.add_child(title) box.add_child(HSeparator.new()) - # 组帽·冒险(M2 分组) + # 组帽·冒险 box.add_child(UiKit.label("── 冒 险 ──",UiKit.FS_CAPTION, false, UiKit.WARM_FAINT)) - # 唯一试玩入口 = 正式「开始冒险」(三关序列);单关测试直入口(L2/L3)退役(2026-09-23 用户拍板) - var resumebtn := UiKit.primary_button("▶ 继续上局") # 迭代 8 卡②——有断点才亮(可见性与关数文案归组合根刷新);主操作钮=审计差距⑤对齐 demo + # 唯一试玩入口 = 正式「开始冒险」(三关序列);无单关测试直入口 + var resumebtn := UiKit.primary_button("▶ 继续上局") # 有断点才亮(可见性与关数文案归组合根刷新);主操作钮对齐 demo resumebtn.tooltip_text = "自最近停点恢复" resumebtn.visible = false box.add_child(resumebtn) - # 主操作语义对齐 demo(2026-10-06 审计差距⑤——有档时「继续上局」才是首动作=主黄钮, + # 主操作语义对齐 demo(有档时「继续上局」才是首动作=主黄钮, # 「开始冒险」=常规石钮;tooltip 保留) var lvbtn := UiKit.button("▶ 开始冒险") lvbtn.tooltip_text = "三关连探:地精洞窟 → 幽暗地域 → 灰矮人矿城" @@ -139,30 +139,30 @@ static func build_start_overlay(host: Control, db = null) -> Dictionary: # 组帽·营地与系统 box.add_child(UiKit.label("── 营地与系统 ──",UiKit.FS_CAPTION, false, UiKit.WARM_FAINT)) - var campbtn := UiKit.verb_button("营地", UiKit.TEX_ICON_KEYSTONE, "永久强化:钥石换永久属性——跨局成长账本") # 元进度实现批——主菜单营地入口 + var campbtn := UiKit.verb_button("营地", UiKit.TEX_ICON_KEYSTONE, "永久强化:钥石换永久属性——跨局成长账本") # 主菜单营地入口 box.add_child(campbtn) - # 生涯页一级入口(迭代 18 卡④——与营地平级;页=局外只读跨局汇总,零跳转零购买) + # 生涯页一级入口(与营地平级;页=局外只读跨局汇总,零跳转零购买) var careerbtn := UiKit.button("生涯") careerbtn.tooltip_text = "跨局生涯汇总:总局数 / 通关局数 / Boss 击杀 / 钥石余额 / 三柜台解锁概览(只读)" box.add_child(careerbtn) - var settingsbtn := UiKit.button("设置") # 迭代 8 卡④——最小设置面入口 + var settingsbtn := UiKit.button("设置") # 最小设置面入口 settingsbtn.tooltip_text = "音量 / 全屏 / 减动效" box.add_child(settingsbtn) - # 二轮修改批 D1(2026-09-29 用户目检裁决):退出游戏与设置同层并行——只在一级菜单出现 + # 退出游戏与设置同层并行——只在一级菜单出现 var quitbtn := UiKit.button("退出游戏") box.add_child(quitbtn) - # 迭代 14.5 调试整合批——调试入口收浮层角标;2026-10-16 用户令修正:boot 菜单优先不开 + # 调试入口收浮层角标;boot 菜单优先不开 # 浮窗,调试入口=UI 最顶层全局浮层角标(build_debug_badge——LAYER_CONTRACT 末位、 - # ModalStack 登记外,任何 UI 不遮挡;对局中两屏角标形态随之退役,全局浮层全场景承载) + # ModalStack 登记外,任何 UI 不遮挡;本层不设屏内调试角标,全局浮层全场景承载) - # 右列:立绘看台 + 玩法速览牌(M2——帮助全文保留表值驱动,仅容器化;内容含地形变异段不删) + # 右列:立绘看台(三张立绘 + 标题底座;界面禁玩法文字墙,故无速览牌) var right := VBoxContainer.new() right.name = "start_right" right.size_flags_horizontal = Control.SIZE_EXPAND_FILL right.add_theme_constant_override("separation", 18) right.alignment = BoxContainer.ALIGNMENT_CENTER - cols.add_child(right) # ui-struct-probe 批 T2:右列挂 HBox 第二列(原误挂 pad 与左列同矩形叠放——M2 双列失效根因) + cols.add_child(right) # 右列挂 HBox 第二列(禁挂 pad——与左列同矩形叠放会破双列) var stage := VBoxContainer.new() stage.alignment = BoxContainer.ALIGNMENT_CENTER var foe_row := HBoxContainer.new() @@ -195,9 +195,9 @@ static func build_start_overlay(host: Control, db = null) -> Dictionary: "settingsbtn": settingsbtn, "quitbtn": quitbtn} -# 调试浮层入口角标(2026-10-16 用户令:UI 最顶层浮层,任何 UI 不遮挡)——main 直接子层、 +# 调试浮层入口角标(UI 最顶层浮层,任何 UI 不遮挡)——main 直接子层、 # LAYER_CONTRACT 末位(float 类:只落树序、不注册 ModalStack——open() 遮挡记账只动登记层, -# 故永不被隐藏);右下角 16px(拇指区惯例,与旧三屏角标同域);可见性归组合根(_debug_entry +# 故永不被隐藏);右下角 16px(拇指区惯例);可见性归组合根(_debug_entry # 门控落定后赋值);地图屏底栏 85px 常驻,offset 抬升本函数不处理(组合根 _sync_status_entry)。 static func build_debug_badge(host: Control) -> Button: var badge := UiKit.button("调试", 0.0) # 角落小件豁免宽度基准(0=不设 min/seals——同状态角标) diff --git a/game/presentation/views/ap_bar_view.gd b/game/presentation/views/ap_bar_view.gd index 12b8f2ea..254d88ce 100644 --- a/game/presentation/views/ap_bar_view.gd +++ b/game/presentation/views/ap_bar_view.gd @@ -59,7 +59,7 @@ func _init() -> void: spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL row.add_child(spacer) - # RAP 读数(2026-09-26 信息归属拍板自 C 区迁入):RAP 唯一消费口 = 弃图刷新——资源数字贴消费按钮 + # RAP 读数(自 C 区迁入):RAP 唯一消费口 = 弃图刷新——资源数字贴消费按钮 # (就近原则);扣费文案「RAP−%d」已在刷新按钮副行,此处不重复代价提示(单一展示面原则) _rap_dots = HBoxContainer.new() _rap_dots.add_theme_constant_override("separation", 2) @@ -68,7 +68,7 @@ func _init() -> void: _rap_label = UiKit.label("RAP 0",UiKit.FS_HINT, true, UiKit.INK_LABEL) # 显式传色(UI 设计对齐批 N1-7——T0 实测对 PANEL_DATA 10.4:1 已合规,显式化仅为确定性加固,值不变) _rap_label.size_flags_vertical = Control.SIZE_SHRINK_CENTER row.add_child(_rap_label) - _rap_feedback = UiKit.label("",UiKit.FS_CAPTION, false, UiKit.STONE_DEEP) # 迭代 26 T3 换墨——旧灰石弱化墨对 PANEL_DATA 2.9:1 越带,深石墨 5.6:1 在案 + _rap_feedback = UiKit.label("",UiKit.FS_CAPTION, false, UiKit.STONE_DEEP) # 深石墨 5.6:1(弱化墨对 PANEL_DATA 2.9:1 越带) _rap_feedback.size_flags_vertical = Control.SIZE_SHRINK_CENTER row.add_child(_rap_feedback) diff --git a/game/presentation/views/battle_end_overlay.gd b/game/presentation/views/battle_end_overlay.gd index 9d7405c7..19a28ce0 100644 --- a/game/presentation/views/battle_end_overlay.gd +++ b/game/presentation/views/battle_end_overlay.gd @@ -4,7 +4,7 @@ class_name BattleEndOverlay extends Control -signal continue_pressed # M9:review_pressed 退役(P-C7——冒险中回看归「生涯」,06 登记) +signal continue_pressed # 冒险中无回看入口——回看归「生涯」(06 登记) const COL_GOLD := UiKit.GOLD const COL_DUSK := UiKit.DUSK # 暮蓝(全作唯一暮蓝档) @@ -13,7 +13,7 @@ const COL_WARM := UiKit.WARM var _dim: ColorRect var _seal: Panel var _verdict: Label -var _rows_box: VBoxContainer # M9 三行账(GP/钥石/本关加成——demo ⑧两列对齐 2026-10-06 审计差距④;失败侧整行隐藏=P-C4 维持 OQ14) +var _rows_box: VBoxContainer # 三行账(GP/钥石/本关加成——demo ⑧两列对齐;失败侧整行隐藏) var _gp_row: HBoxContainer var _gp_name: Label var _gp_val: Label @@ -23,16 +23,16 @@ var _ks_val: Label var _bonus_row_l: HBoxContainer var _bonus_name: Label var _bonus_val: Label -var _cele: TextureRect # M9 庆祝立绘(idle 占位浮动——正式帧待资产批) +var _cele: TextureRect # 庆祝立绘(idle 占位浮动) var _btn: Button var _board_rect := Rect2() func _init() -> void: - # 二轮修改批 B(2026-09-29 用户目检裁决):半透明浮层文字不可读 → 实底石板皮面板形态 + # 半透明浮层文字不可读 → 实底石板皮面板形态 #(与营地/设置/图例同族)。半透明氛围 dim 保留(胜利暖纱/失败暮蓝——open_* 就地换色),信息与 - # 按钮全部上板;金蜡封 = 面板头部静态徽记(原全屏坠落演出退役——落点被面板遮挡)。 - # 骨架经 UiKit.modal_shell(T4 收口批);_dim 引用摘出供 open_* 换氛围色。 + # 按钮全部上板;金蜡封 = 面板头部静态徽记(坠落演出落点被面板遮挡)。 + # 骨架经 UiKit.modal_shell;_dim 引用摘出供 open_* 换氛围色。 var shell := UiKit.modal_shell(self, Color(COL_WARM, 0.0), Vector2(520, 0), 12, true, UiKit.panel_skinned(Vector4(16, 14, 16, 14))) _dim = shell.dim @@ -63,7 +63,7 @@ func _init() -> void: _verdict.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER _verdict.size_flags_vertical = Control.SIZE_SHRINK_CENTER header.add_child(_verdict) - # M9 庆祝立绘(demo ⑧——idle 帧浮动占位;正式帧归资产批;减动效=静帧) + # 庆祝立绘(demo ⑧——idle 帧浮动占位;减动效=静帧) _cele = TextureRect.new() var cele_tex := UiKit.load_tex(UiKit.TEX_HERO_IDLE) if cele_tex != null: @@ -81,7 +81,7 @@ func _init() -> void: box.add_child(_rows_box) # 两列对齐账行(审计差距④对齐 demo ⑧——项目名左/数值右,定宽 360) _gp_row = _ledger_row() - _gp_name = _ledger_name(UiKit.FS_SUB, UiKit.GOLD_INK, true) # 尾裁微批a 2026-10-08——GOLD_DEEP 对结算板 2.67:1 越带,换深金墨 5.21:1 + _gp_name = _ledger_name(UiKit.FS_SUB, UiKit.GOLD_INK, true) # GOLD_DEEP 对结算板 2.67:1 越带,换深金墨 5.21:1 _gp_val = _ledger_value(UiKit.FS_SUB, UiKit.GOLD_INK, true) # 同上 _gp_row.add_child(_gp_name) _gp_row.add_child(_gp_val) @@ -101,9 +101,9 @@ func _init() -> void: _bonus_row_l.visible = false _rows_box.add_child(_bonus_row_l) box.add_child(HSeparator.new()) - # M9:明细回看钮退役(P-C7——冒险中回看归「生涯」) + # 无明细回看钮——冒险中回看归「生涯」 _btn = UiKit.primary_button("继续") - _btn.size_flags_horizontal = Control.SIZE_SHRINK_CENTER # 审计差距④——紧凑钮(原全宽) + _btn.size_flags_horizontal = Control.SIZE_SHRINK_CENTER # 紧凑钮 _btn.custom_minimum_size.x = 150 _btn.pressed.connect(_emit_continue_pressed) box.add_child(_btn) @@ -111,11 +111,11 @@ func _init() -> void: # 终局画面数据锚 = 战斗结算 判定行(verdict)——判定行文案由组合根装配传入。 -# gp_summary(OQ14 口径——胜利总结结算展示 GP 总量+增量):组合根装配「战利品 +增量 · 合计总量」 +# gp_summary(胜利总结结算展示 GP 总量+增量):组合根装配「战利品 +增量 · 合计总量」 # 传入(入账次序 = LevelRunner 入账先于组合根 handler,runner.gp 即战后总量);空串 = 不显示(失败侧恒空)。 func open_victory(verdict_line: String, continue_label: String, board_rect: Rect2, gp_summary: String = "", ks_summary: String = "", bonus_summary: String = "", gp_gain := -1, gp_total := -1) -> void: - _dim.color = Color(UiKit.DIM_NIGHT, 0.62) # 审计差距④——全屏压暗对齐 demo(原 0.28 暖纱透底) + _dim.color = Color(UiKit.DIM_NIGHT, 0.62) # 全屏压暗对齐 demo _verdict.text = verdict_line _seal.visible = true # 胜利徽记(面板头部静态) _seal.modulate = Color.WHITE @@ -133,7 +133,7 @@ func open_victory(verdict_line: String, continue_label: String, board_rect: Rect if UiKit.victory_fx_style == "dust": _play_victory_dust() # 尘金粒子(P-C5 两套并存——开关=调试浮窗,会话级) else: - _play_crest_assemble() # 碎砖拼纹章(§2.4——样张 v2 冻结批 T3 终稿;默认) + _play_crest_assemble() # 碎砖拼纹章(§2.4;默认) _play_seal_recall(0) # 胜利不放封印收回 if gp_gain >= 0: _roll_gp(gp_gain, gp_total) @@ -141,14 +141,14 @@ func open_victory(verdict_line: String, continue_label: String, board_rect: Rect func open_defeat(verdict_line: String, continue_label: String, board_rect: Rect2) -> void: # 明度不变的暮蓝色相氛围(全屏唯一暮蓝档——§2.5 最静一拍) - _dim.color = Color(COL_DUSK, 0.6) # 审计差距④同族压暗(原 0.45) + _dim.color = Color(COL_DUSK, 0.6) # 同族压暗 _verdict.text = verdict_line _board_rect = board_rect visible = true _seal.visible = true - _seal.modulate = Color(0.4, 0.4, 0.4) # M9:失败徽记灰化(demo ⑧;旧全隐藏退役) + _seal.modulate = Color(0.4, 0.4, 0.4) # 失败徽记灰化(demo ⑧) _cele.visible = false - _rows_box.visible = false # P-C4 维持 OQ14:失败侧不呈现账行 + _rows_box.visible = false # 失败侧不呈现账行 _play_dust_sadle() # 坐砖掸灰(§2.5——终稿) _play_seal_recall(8) @@ -187,7 +187,7 @@ func _ledger_value(size: int, col: Color, bold: bool) -> Label: # 拆名/值(组合根传入整串):gp_shape=固定名「战利品 GP」值取余串;其余行按「:」或「 · 」切 -#(全角冒号不入值列——T7 实机「:攻击 +1」缩进 Corrections);无分隔符=整串入值列、名空 +#(全角冒号不入值列——实机「:攻击 +1」缩进 Corrections);无分隔符=整串入值列、名空 func _set_ledger_row(name_l: Label, val_l: Label, s: String, gp_shape := false) -> void: if gp_shape and s.begins_with("战利品 GP"): name_l.text = "战利品 GP" @@ -230,7 +230,7 @@ func _play_seal_recall(count: int) -> void: tw.tween_callback(dot.queue_free) -# ---- 演出密度终稿(样张 v2 冻结批 T3——程序化 tween,确定性散布,零新帧资产) ---- +# ---- 演出密度(程序化 tween,确定性散布,零新帧资产) ---- var _crest_bricks: Array[ColorRect] = [] # 纹章碎砖驻留面(close 时回收) var _fx_crest_shards := 0 @@ -277,7 +277,7 @@ func _play_dust_sadle() -> void: mtw.tween_callback(mote.queue_free) -# M9 庆祝立绘浮动(idle 占位——UiKit.motion 守减动效;motion_scale<1 静帧) +# 庆祝立绘浮动(idle 占位——UiKit.motion 守减动效;motion_scale<1 静帧) func _play_celebrate() -> void: if UiKit.motion_scale < 1.0: return @@ -287,7 +287,7 @@ func _play_celebrate() -> void: tw.tween_property(_cele, "position:y", _cele.position.y, UiKit.motion(0.6)).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT) -# M9 尘金粒子(P-C5 备选演出——金屑自面板上带飘落闪灭;确定性散布守 S2) +# 尘金粒子(备选演出——金屑自面板上带飘落闪灭;确定性散布守 S2) func _play_victory_dust() -> void: _fx_dust_motes += 10 var c := _fx_center() @@ -305,7 +305,7 @@ func _play_victory_dust() -> void: tw.tween_callback(mote.queue_free) -# M9 GP 行数字滚动(demo ⑧——0.8s 三次缓出;减动效直出终值) +# GP 行数字滚动(demo ⑧——0.8s 三次缓出;减动效直出终值) func _roll_gp(gp_gain: int, gp_total: int) -> void: if UiKit.motion_scale < 1.0: _gp_val.text = "+%d · 合计 %d" % [gp_gain, gp_total] diff --git a/game/presentation/views/battle_log_view.gd b/game/presentation/views/battle_log_view.gd index 202ff36e..446126d4 100644 --- a/game/presentation/views/battle_log_view.gd +++ b/game/presentation/views/battle_log_view.gd @@ -27,7 +27,7 @@ func _init(db_ref) -> void: add_child(vb) var head := HBoxContainer.new() vb.add_child(head) - # 对比度修复(v3.5 批 B3 2026-09-30——明细条灰字对深灰底实测 2.63:1):暗底双色墨制=暖白族 + # 明细条灰字对深灰底实测 2.63:1 → 暗底双色墨制=暖白族 _summary = UiKit.label("",UiKit.FS_BODY, false, UiKit.WARM) _summary.custom_minimum_size = Vector2(0, BAND_H_DIG - 4) _summary.clip_text = true @@ -101,7 +101,7 @@ func parsed_text() -> String: return _log.get_parsed_text() -# M9(P-C7 裁):带点击回看入口退役——冒险中不给数据回看(归「生涯」06 登记);带保留单行摘要显示 +# 无点击回看入口——冒险中不给数据回看(归「生涯」06 登记);带保留单行摘要显示 # ---- 聚合计数(未生效类行防逐行惩罚轰炸——pattern 3 聚合纪律) ---- @@ -153,7 +153,7 @@ func _format_row(row: Dictionary, agg_count := -1) -> String: var suffix := "(%s)" % src if src != "" else "" match String(row.get("type", "")): "effect": - # GP 型效果行(GP+商店房实施批 2026-09-21):「GP 袋 +3」兑付反馈——value = 本行 ±power, + # GP 型效果行:「GP 袋 +3」兑付反馈——value = 本行 ±power, # escrow = 战斗内缓冲现值(入钱包在战斗末一次上抛——呈现语义与增益池分账) if String(row.get("effect_id", "")) in ["gp_gain", "gp_loss"]: var gp_col := UiKit.HEX_LOG_GAIN if v > 0 else UiKit.HEX_LOG_LOSS @@ -165,9 +165,8 @@ func _format_row(row: Dictionary, agg_count := -1) -> String: var body := "%s 单次%+d(池 %+d)%s" % [name_, v, pool, suffix] return prefix + (_gold_frame(body) if hl != "" else "[color=%s]%s[/color]" % [col, body]) "damage": - # 伤害行无行上拆行文案——基线+伏击与三分量两旧归因拆行已随伏击退役批(2026-09-20) - # 与充能退役批(2026-09-19)出协议,行上归因读数只剩掷点档位随行 - # 护甲等级掷点留档(2026-09-16 掷点批——掷点读数与档位随行可读;吃掷点分量恒带,棋盘来源行不带) + # 伤害行无行上拆行文案——行上归因读数只剩掷点档位随行 + # 护甲等级掷点留档(掷点读数与档位随行可读;吃掷点分量恒带,棋盘来源行不带) var roll_txt := "" if row.get("roll", null) != null: roll_txt = "〔掷 %d vs 护甲 %d" % [int(row.roll), int(row.ac)] @@ -177,8 +176,7 @@ func _format_row(row: Dictionary, agg_count := -1) -> String: roll_txt += " · ×%d%%" % int(row.tier) roll_txt += "〕" var kill := " ⚔击杀!" if row.get("killed", false) else "" - # 二轮修改批 C(2026-09-29 用户目检——「每次结算标出的伤害数字不明显」): - # 伤害值放大加色独立于行文(朱红大一号——数字即信息主角,非同字号色温微差) + # 伤害数字不明显——伤害值放大加色独立于行文(朱红大一号——数字即信息主角,非同字号色温微差) var body := "%s [color=#%s][size=17]-%d[/size][/color]%s%s%s%s" % [name_, UiKit.HEX_LOG_DMG_NUM, v, roll_txt, tail, kill, suffix] var body_col := UiKit.HEX_LOG_DMG_KILL if row.get("killed", false) else (UiKit.HEX_LOG_ROUND if v == 0 else UiKit.HEX_LOG_DMG_BODY) if bool(row.get("crit", false)): @@ -194,7 +192,7 @@ func _format_row(row: Dictionary, agg_count := -1) -> String: var body := "✗ %s%s" % [name_, "(本板完美排雷已破——归因此封印)" if hl == "perfect_broken" else ""] return prefix + (_gold_frame(body) if hl == "perfect_broken" else "[color=#%s]%s[/color]" % [UiKit.HEX_LOG_ROUND, body]) "cast": - # 施放行(敌人技能池批——蓄力行 charge 改型):增益技 0 伤害施放,具名技能 + # 施放行:增益技 0 伤害施放,具名技能 return prefix + "[color=#%s]✦ %s%s[/color]" % [UiKit.HEX_LOG_CAST, name_, suffix] "decay": return prefix + "[color=#%s]状态衰减 ×%d[/color]" % [UiKit.HEX_LOG_DECAY, v] diff --git a/game/presentation/views/battle_stage_view.gd b/game/presentation/views/battle_stage_view.gd index f42a2c08..fb23bc05 100644 --- a/game/presentation/views/battle_stage_view.gd +++ b/game/presentation/views/battle_stage_view.gd @@ -26,9 +26,8 @@ var world: Node2D # StageWorld(preload 脚本实例——Node2D 世 func _init(db_ref) -> void: custom_minimum_size = Vector2(0, 252) - # 面板底(圣经 v3.5 批 B4 2026-09-30——§6.1 舞台正面目标落码:B 区=地窟看台,世界底层暗背景 - # =方向稿 render_battle_screen 取值(值单点收 UiKit.STAGE_BG——T4 裸色收口)——替换原浅石板皮 - # 〔实测 L0.027 旧深底与上半米黄割裂的 opposite 端——v3.5 定暖暗中档〕;描边=PANEL_BORDER 同方向稿) + # 面板底(圣经 v3.5 §6.1 舞台正面目标:B 区=地窟看台,世界底层暗背景 + # =方向稿 render_battle_screen 取值(值单点收 UiKit.STAGE_BG);描边=PANEL_BORDER 同方向稿) var bg := Panel.new() var sb := UiKit.panel_flat(UiKit.STAGE_BG, UiKit.PANEL_BORDER, 0, 1) bg.add_theme_stylebox_override("panel", sb) @@ -114,8 +113,8 @@ func _init(db_ref) -> void: # 主角站桩本体(世界)+ 状态行伴随件(壳层) hero_standee = _STANDEE_BODY.new("hero") var hero_tex := UiKit.load_tex(UiKit.TEX_HERO_PORTRAIT) - hero_standee.set_portrait_texture(hero_tex, true) # B 区立绘 48px 档·normal 态朝右(迭代 6 T3 换装=new-normal 源;素材缺位 null 回退字形「人」) - # 主角三态注册(迭代 6 T3——attack/hit 缺位不注册=该态保持现纹理,缺位回退链延伸) + hero_standee.set_portrait_texture(hero_tex, true) # B 区立绘 48px 档·normal 态朝右(素材缺位 null 回退字形「人」) + # 主角三态注册:attack/hit 缺位不注册=该态保持现纹理,缺位回退链延伸 hero_standee.register_hero_state("idle", hero_tex) hero_standee.register_hero_state("attack", UiKit.load_tex(UiKit.TEX_HERO_ATTACK)) hero_standee.register_hero_state("hit", UiKit.load_tex(UiKit.TEX_HERO_HIT)) @@ -139,7 +138,7 @@ func _draw_light_beams(c: Control) -> void: func _make_slot_companion(parent: Control) -> StatusSlotRow: - # 状态效果唯一展示面(2026-09-26 C 区精简批迁入站桩)——compact 档伴随件,tooltip 全明细 + # 状态效果唯一展示面——compact 档伴随件,tooltip 全明细 var comp := StatusSlotRow.new() comp.compact = true comp.alignment = BoxContainer.ALIGNMENT_CENTER @@ -268,7 +267,7 @@ func set_enemies(cards_data: Array) -> void: world.add_child(body) body.slot_row = _make_slot_companion(enemy_box) body.set_data(d) - # 敌种立绘接线(仅重建拍装载一次;flip=false——八敌像素源核证朝左/正面(迭代 6 T1), + # 敌种立绘接线(仅重建拍装载一次;flip=false——八敌像素源核证朝左/正面, # 呈现即朝主角无误;反向朝向源换代时翻转义务归素材批) body.set_portrait_texture(_enemy_portrait_tex(String(d.get("enemy_id", ""))), false) _cards.append(body) @@ -293,14 +292,14 @@ func set_round_text(text: String) -> void: # 结算行演出分发(占位级):伤害行 → 目标站桩闪白 / 击杀 → 灰化塌陷残位; -# 主角三态切换(迭代 6 T3)——主角攻击行→attack 态(短驻自回)/ 主角受击行→hit 态 +# 主角三态切换:主角攻击行→attack 态(短驻自回)/ 主角受击行→hit 态 func on_step_row_fx(row: Dictionary) -> void: var t := String(row.get("type", "")) if t != "damage": return var target := String(row.get("target", "")) if target == "hero" or target == "": - # 主角受击演出(迭代 6 T5 拆早退——旧「敌→主角零反馈」):弹道到达拍对齐, + # 主角受击演出:弹道到达拍对齐, # 受击态+闪白+打击火花+击杀塌陷与敌方路径同密度(演出对等——计划书 §1.4) hero_standee.set_hero_state("hit") # 受击态(短驻自回 idle) _schedule_arrival_fx(hero_standee, bool(row.get("killed", false))) @@ -358,7 +357,7 @@ func gray_all_enemies() -> void: c.mark_dead() -# 结算收尾:主角态显式回 idle(迭代 6 T3——「结算回 idle」事件;0.35s 短驻自回的兜底) +# 结算收尾:主角态显式回 idle(0.35s 短驻自回的兜底) func settle_hero_idle() -> void: hero_standee.set_hero_state("idle") diff --git a/game/presentation/views/board_cell_unit.gd b/game/presentation/views/board_cell_unit.gd index 8046ffae..a704d60a 100644 --- a/game/presentation/views/board_cell_unit.gd +++ b/game/presentation/views/board_cell_unit.gd @@ -13,14 +13,14 @@ var edge := 46.0: # 格边长(BoardView.set_cell_area 单点 _glow_layer.setup(edge, glow_group) queue_redraw() var bg_sb: StyleBoxFlat = null # 格底 StyleBox(BoardView 每次 paint 重建;呼吸微光就地改边框) -# ── 接触带微光绘制面(2026-09-26 批:可挖域微光自"墙格整框"改"英雄格周界空间侧"——art-bible §3.2 v2.8; +# ── 接触带微光绘制面(可挖域微光画在英雄格周界空间侧——art-bible §3.2 v2.8; # 仅英雄格单元承载,BoardView.refresh 按可挖域写边/角码、_process 逐拍更新呼吸色)── var contact_bands: Array[int] = [] # 正交接触边码 0=N/1=S/2=W/3=E(该侧整条边) var contact_corners: Array[int] = [] # 斜向共享角码 0=NW/1=NE/2=SW/3=SE(角点+两侧各半条边) var contact_col := Color(0, 0, 0, 0) # 当前呼吸色(alpha 0 = 不画) var plate := false # 数字色牌开关(BoardView paint 按已开格 glyph 写入——原则二) -var outline_sides: Array[int] = [] # 墙格地面朝向描边码 0=N/1=S/2=W/3=E(轮廓加强批——程序侧结构件) -# ── 高墙感 D 投影档(2026-09-28 挑档落码——研究件四变体用户裁 D=C+地面投影,ITB 同款高度线索)── +var outline_sides: Array[int] = [] # 墙格地面朝向描边码 0=N/1=S/2=W/3=E(程序侧结构件) +# ── 高墙感 D 投影档(研究件四变体定 D=C+地面投影,ITB 同款高度线索)── # 南立面 = 墙格南缘内侧「口沿高光线 + 双段暗带」(邻地面格才画,墙群内聚);地面投影 = 北邻墙格 # 在本已开格北缘投渐隐暗带。参数按研究件 64px 拼版实测比例换算(立面双段 0.16/0.25 格边、投影带 # 0.22 格边;坐标推导留档 commit)。素材缺位程序化回退同样服役(结构归程序——art-bible §8.5)。 @@ -36,7 +36,7 @@ var glyph := "": # 文字位——数字/雷/封印/人/?( set(v): glyph = v queue_redraw() -var glyph_color := UiKit.INK: # 文字色(墨族/雷朱/封印朱/小人蓝) +var glyph_color := UiKit.INK: # 文字色(墨族/雷朱/封印黑/小人蓝) set(v): glyph_color = v queue_redraw() @@ -46,7 +46,7 @@ var badge_glyph := "": # 奖励徽章文字(右下角金——封 if _glow_layer != null and is_instance_valid(_glow_layer): _glow_layer.set_badge_mask(v != "") queue_redraw() -var dot_visible := false: # BFS 路径预览点迹(中心 6×6 小人蓝——旧 ColorRect 等价) +var dot_visible := false: # BFS 路径预览点迹(中心 6×6 小人蓝) set(v): dot_visible = v queue_redraw() @@ -59,7 +59,7 @@ var hl_color := UiKit.GOLD: # 高亮色(金目标/封印朱/禁入灰 hl_color = v queue_redraw() var font: Font = null # 字体槽位(null = ThemeDB.fallback_font——BoardView.set_world_font 注入) -var bevel := 0.0: # 顶面倒角强度(0=关——立体原型批 2026-09-24;档位 0/0.35/0.6/1.0) +var bevel := 0.0: # 顶面倒角强度(0=关;档位 0/0.35/0.6/1.0) set(v): bevel = v queue_redraw() @@ -72,17 +72,17 @@ const FACADE_FAR_COL := Color(0, 0, 0, 0.82) # 立面远段黑罩(墙 const PROJECTION_NEAR_COL := Color(0, 0, 0, 0.28) # 投影贴墙段(地面 66→46 实测 α≈0.28) const PROJECTION_MID_COL := Color(0, 0, 0, 0.16) # 投影中段(渐隐) const PROJECTION_EDGE_COL := Color(0, 0, 0, 0.06) # 投影远段(渐隐收边) -# ── E 格高墙面(圣经 v3.5 冻结① 2026-09-30——地面格南邻墙→南部 30% 承接墙面:墙顶纹理原亮度 -# 直贴零暗档零阴影〔用户终裁「它们是同样颜色的」〕;墙脚阴线只画地面/墙面交界;(b)-(c) 交界 +# ── E 格高墙面(圣经 v3.5 冻结①——地面格南邻墙→南部 30% 承接墙面:墙顶纹理原亮度 +# 直贴零暗档零阴影;墙脚阴线只画地面/墙面交界;(b)-(c) 交界 # 无边框由 BoardView 侧跳过墙格北向描边承载)── -const E_FACADE_FRAC := 0.30 # 墙面承接高(格边比——用户指令 30%) -# ── 素材槽位(本批全 null = 程序化占位服役;art-bible §8.2 格面 32×32 暂定档)── +const E_FACADE_FRAC := 0.30 # 墙面承接高(格边比 30%) +# ── 素材槽位(现全 null = 程序化占位服役;art-bible §8.2 格面 32×32 暂定档)── var tex_base: Texture2D = null # ① 砖面底 var tex_mutation: Texture2D = null # ② 变异纹带 var tex_glyph: Texture2D = null # ③ 数字 var tex_badge: Texture2D = null # ③' 徽章 -var tex_seal: Texture2D = null: # ④ 封印(T17 修复:槽位可运行时换装〔封印〕——同族 facade/treasure_mark - set(v): # 均 setter 触发重绘;旧普通 var 赋值不重绘=封印插上不显示) +var tex_seal: Texture2D = null: # ④ 封印(槽位可运行时换装〔封印〕——同族 facade/treasure_mark + set(v): # 均 setter 触发重绘(普通 var 赋值不重绘=封印插上不显示)) if tex_seal != v: tex_seal = v queue_redraw() @@ -92,9 +92,9 @@ var facade_strip := false: # E 格开关(BoardView paint 按「已开 facade_strip = v queue_redraw() -# 变异角标(迭代 6 T6——程序化,tex_mutation 纹带槽留给变异纹带六型自产批): +# 变异角标(程序化,tex_mutation 纹带槽暂留): # "flat_damage" = 未开格伤害型变异,左下角危险红三角(开格有代价的策略纹理标记) -# 叠加层标记(迭代 7 T4——秘宝板级叠加层的格面呈现;派生信息层零回写): +# 叠加层标记(秘宝板级叠加层的格面呈现;派生信息层零回写): # "mine_reveal" = 真视格(危险红内缩框——「这格是雷」的确定决策标记,封印照常计费); # "reward_preview" 格不复用本字段——预读徽章走 badge_glyph 注入(board_view refresh 注入 REWARD_BADGE 字形) var treasure_mark := "": @@ -108,20 +108,20 @@ var mutation_mark := "": mutation_mark = v queue_redraw() -# ── 视野迷雾呈现态(迭代 11 第④批 T2/T3——纯呈现零逻辑;规格=art-bible §6.5 v3.5,正主=HUD框架「视野迷雾」节)── +# ── 视野迷雾呈现态(纯呈现零逻辑;规格=art-bible §6.5 v3.5,正主=HUD框架「视野迷雾」节)── # 0=正常(灯光区内)/ 1=全黑(区外未开格——正主「区外未开格=全黑不渲染」不透明档)/ 2=记忆态(区外已开格灰显可读) var fog_state := 0: set(v): if fog_state != v: fog_state = v queue_redraw() -var removed_dim := false: # 中立移除退色层(T8/D6——BoardView paint 按排雷玩法 is_removed 写入) +var removed_dim := false: # 中立移除退色层(BoardView paint 按排雷玩法 is_removed 写入) set(v): removed_dim = v queue_redraw() -# ── 未开格类型微光(迭代 30 卡①·Q1 丙案——英雄 8 向相邻未开格的组粒度类型提示) +# ── 未开格类型微光(英雄 8 向相邻未开格的组粒度类型提示) # 作用集 = 可挖域 ∩ 身份可查格,由 BoardView 侧派生下发;本件只承接绘制与子件生命周期。 -# 静态(Q5 甲案):不呼吸、不入动效预算;相位门控(结算/道具窗口态隐藏)在 BoardView 侧。 +# 静态:不呼吸、不入动效预算;相位门控(结算/道具窗口态隐藏)在 BoardView 侧。 var glow_group := 0: set(v): if glow_group != v: @@ -134,11 +134,11 @@ var _glow_layer: Node2D = null func _draw() -> void: var rect := Rect2(Vector2.ZERO, Vector2(edge, edge)) - # ① 砖面底(占位 = StyleBoxFlat:格底色 + 暗化描边 + 3px 圆角——旧 Button normal 样式等价; + # ① 砖面底(占位 = StyleBoxFlat:格底色 + 暗化描边 + 3px 圆角; # 呼吸微光/主角蓝框由 BoardView 改 bg_sb 后触发重绘) if tex_base != null: draw_texture_rect(tex_base, rect, false) - # 轮廓加强(2026-09-26 用户反馈「轮廓线不明显」):墙格地面朝向边补 2px 深墨线(§8.5 结构归程序—— + # 轮廓加强(轮廓线不明显):墙格地面朝向边补 2px 深墨线(§8.5 结构归程序—— # 素材 1px 墨线在 45/36px 非整数缩放下视觉衰减,程序线保底;墙-墙内界不画,保墙群内聚; # 坐标推导:各边内贴 2px 矩形,相邻边矩形全长相交=周界闭合) if not outline_sides.is_empty(): @@ -155,7 +155,7 @@ func _draw() -> void: _draw_south_facade() _draw_north_projection() _draw_e_facade() - # 瓦片态描边覆盖层(高墙瓦片接线批 2026-09-26):tex_base 在位时 BoardView 传入的 bg_sb + # 瓦片态描边覆盖层:tex_base 在位时 BoardView 传入的 bg_sb # 已降级为「透明底 + 描边」载体——呼吸微光/主角蓝框画在瓦片之上(art-bible §1.2 叠层序 # 不变:底 < 纹带 < 数字 < 封印 < 焦点高亮);素材缺位回退走 elif 程序化原样,零观感变化 if bg_sb != null: @@ -204,7 +204,7 @@ func _draw() -> void: draw_style_box(bg_sb, rect) _draw_south_facade() # 平色回退路径——D 投影档两件同样服役(结构归程序) _draw_north_projection() - # 顶面倒角(立体原型批:光源左上——上/左内沿受光 2px、下/右内沿背光 2px;内缩 2px 让 + # 顶面倒角(光源左上——上/左内沿受光 2px、下/右内沿背光 2px;内缩 2px 让 # 呼吸微光/主角蓝边框保持最外沿可见;强度随档位) if bevel > 0.0: var base: Color = bg_sb.bg_color @@ -215,12 +215,12 @@ func _draw() -> void: draw_rect(Rect2(t, t, t, edge - t * 2.0), lit, true) draw_rect(Rect2(t, edge - t * 2.0, edge - t * 2.0, t), dark, true) draw_rect(Rect2(edge - t * 2.0, t, t, edge - t * 2.0), dark, true) - # ② 变异纹带(占位批次无程序化纹带——槽位先行,终稿换入即用) + # ② 变异纹带(无程序化纹带——槽位先行,贴图落位即用) if tex_mutation != null: draw_texture_rect(tex_mutation, rect, false) - # ②' 变异角标(迭代 6 T6):左下角危险红三角(危险红=「开此格有代价」语义位,与雷族同源; + # ②' 变异角标:左下角危险红三角(危险红=「开此格有代价」语义位,与雷族同源; # 尺寸随格边比例——灰色可辨辅助=红对砖面明度差,禁喧宾) - # ②" 秘宝叠加层(迭代 7 T4):真视格=危险红内缩框(策略纹理——确定决策输入不喧宾) + # ②" 秘宝叠加层:真视格=危险红内缩框(策略纹理——确定决策输入不喧宾) if treasure_mark == "mine_reveal": var inset := edge * 0.14 draw_rect(Rect2(inset, inset, edge - inset * 2.0, edge - inset * 2.0), @@ -231,9 +231,9 @@ func _draw() -> void: draw_colored_polygon(mpts, Color(UiKit.RED_MINE, 0.85)) # ③ 数字/徽章(数字 ≥ 格高 50% 墨族对格底 ≥4.5:1;徽章右下角金,遮蔽态 = "?") if glyph != "": - # 数字色牌后备路径(圣经 v3.5 冻结④ 批 B2 2026-09-30:数字亮墨直画已开格底**退役必垫牌**; - # 牌=后备件——雷/「?」维持牌载保读性(牌上深墨族 12:1),复杂格底〔物件纹样/装饰变体格〕 - # 判定随装饰瓦片自产批扩。牌尺寸 0.60/0.62 格边居中 = 样张 v2 冻结值;封印=未开格不垫牌) + # 数字色牌后备路径(圣经 v3.5 冻结④:数字亮墨直画已开格底须垫牌; + # 牌=后备件——雷/「?」维持牌载保读性(牌上深墨族 12:1); + # 牌尺寸 0.60/0.62 格边居中;封印=未开格不垫牌) if plate: var pw := edge * 0.60 var ph := edge * 0.62 @@ -249,7 +249,7 @@ func _draw() -> void: draw_texture_rect(tex_badge, rect, false) else: _draw_badge(badge_glyph) - # ④ 封印(现行视觉封印文字在 ③ 文字位承载——独立槽位留给终稿封印图) + # ④ 封印(现行视觉封印文字在 ③ 文字位承载——独立槽位留给封印图) if tex_seal != null: draw_texture_rect(tex_seal, rect, false) # ⑤ 路径点迹 + 焦点高亮(悬停态覆盖层,不参与命中) @@ -257,15 +257,15 @@ func _draw() -> void: var ds := 6.0 draw_rect(Rect2(Vector2((edge - ds) * 0.5, (edge - ds) * 0.5), Vector2(ds, ds)), UiKit.HERO_BLUE, true) if hl_visible: - # 悬停高亮减淡(2026-09-26 用户反馈:金框太明显——绘制时 55% alpha,hl_color 属性与探针断言面不动) - draw_rect(Rect2(1, 1, edge - 2.0, edge - 2.0), Color(hl_color, 0.55), false, 2.0) # 2px 内描边(旧 hl Panel 等价) - # ⑥ 视野迷雾层(迭代 11 第④批 T2/T3——最顶遮罩,§6.5 落文): + # 悬停高亮减淡(金框太明显——绘制时 55% alpha,hl_color 属性与探针断言面不动) + draw_rect(Rect2(1, 1, edge - 2.0, edge - 2.0), Color(hl_color, 0.55), false, 2.0) # 2px 内描边 + # ⑥ 视野迷雾层(最顶遮罩,§6.5 落文): # 全黑=不透明纯黑盖全部叠层(含封印印/徽章/高亮——封印印记随格隐没,§6.5 显式推论); # 记忆态=记忆板素色压平(纹理免疫——色牌/封印印/徽章随板隐没)+数字记忆墨重画(数字可读硬指标 ≥4.5:1) if fog_state == 1: draw_rect(Rect2(Vector2.ZERO, Vector2(edge, edge)), Color(0, 0, 0, 1.0), true) elif fog_state == 2: - # 记忆态换装(P10 乙 2026-10-06——demo 口径「地板纹理 + 灰罩 α.66」:原 #3A3A3A 平涂退役; + # 记忆态换装(demo 口径「地板纹理 + 灰罩 α.66」: # 地板纹理原样直画 + FOG_MEMORY_PLATE α.66 灰罩压顶;素材零改动、格边长零改动。 # 记忆墨 FOG_MEMORY_INK 对合成底实测 ≈6.7:1 ≥4.5:1(§7.2 硬指标;floor avg #453020 复算在册)) if tex_base != null: @@ -273,7 +273,7 @@ func _draw() -> void: draw_rect(Rect2(Vector2.ZERO, Vector2(edge, edge)), Color(UiKit.FOG_MEMORY_PLATE, 0.66), true) if glyph != "": _draw_glyph(glyph, UiKit.FOG_MEMORY_INK, maxi(18, int(ceil(edge * 0.5)))) # 字号下限 18(§7.4 冻结公式同源) - # ⑦ 中立移除退色层(迭代 13 T8/D6——P2 甲退色降档:暗幕压顶全层覆盖,暗淡记忆态同族呈现语义; + # ⑦ 中立移除退色层(退色降档:暗幕压顶全层覆盖,暗淡记忆态同族呈现语义; # 顶层于迷雾之上——移除格不再参与迷雾语义。本实现移除集=未揭示危险格(无数字无封印印)) if removed_dim: draw_rect(Rect2(Vector2.ZERO, Vector2(edge, edge)), Color(0.12, 0.10, 0.09, 0.62), true) @@ -290,7 +290,7 @@ func _draw_south_facade() -> void: var y_far := edge - far_h var y_near := y_far - near_h var y_hl := y_near - FACADE_HIGHLIGHT_PX - draw_rect(Rect2(0.0, y_hl, edge, FACADE_HIGHLIGHT_PX), UiKit.STAND_STONE_RIM, true) # 口沿高光(UiKit.STAND_STONE_RIM 并档——同值单点,清扫批 2026-10-02) + draw_rect(Rect2(0.0, y_hl, edge, FACADE_HIGHLIGHT_PX), UiKit.STAND_STONE_RIM, true) # 口沿高光(UiKit.STAND_STONE_RIM 并档——同值单点) draw_rect(Rect2(0.0, y_near, edge, near_h), FACADE_NEAR_COL, true) draw_rect(Rect2(0.0, y_far, edge, far_h), FACADE_FAR_COL, true) @@ -306,10 +306,10 @@ func _draw_north_projection() -> void: draw_rect(Rect2(0.0, seg * 2.0, edge, seg), PROJECTION_EDGE_COL, true) -# E 格高墙面(圣经 v3.5 冻结① 2026-09-30——方向稿 draw_facade 移植):本格已开且南邻为墙 → +# E 格高墙面(圣经 v3.5 冻结①——方向稿 draw_facade 移植):本格已开且南邻为墙 → # 南部 30% 承接墙面。材质 = 墙顶 center 瓦片顶部 30% 区带**原亮度**直贴(零暗档零阴影); # 墙脚阴线只画地面/墙面交界(strip 顶缘 1px);墙面底缘(格界处)不画任何线——直接接南侧墙顶 -# (v3.4 用户裁定:白边导致两截)。仅瓦片态服役(tex_facade 缺位 = 平色回退原语义不动)。 +# (白边导致两截)。仅瓦片态服役(tex_facade 缺位 = 平色回退原语义不动)。 func _draw_e_facade() -> void: if not facade_strip or tex_facade == null: return @@ -321,7 +321,7 @@ func _draw_e_facade() -> void: draw_rect(Rect2(0.0, y0, edge, 1.0), UiKit.E_FACADE_FOOT_COL, true) -# 文字位绘制:水平居中 + 垂直居中(基线 = (格高 − 字高)/2 + 上伸部——旧 Button 居中对齐等价) +# 文字位绘制:水平居中 + 垂直居中(基线 = (格高 − 字高)/2 + 上伸部) func _draw_glyph(g: String, col: Color, fs: int) -> void: var f := font if font != null else ThemeDB.fallback_font if f == null: @@ -332,7 +332,7 @@ func _draw_glyph(g: String, col: Color, fs: int) -> void: HORIZONTAL_ALIGNMENT_CENTER, edge, fs, col) -# 微光子件生命周期(迭代 30 卡①):有组才建、组变即换、无组即撤——作用集 ≤8 格常驻, +# 微光子件生命周期:有组才建、组变即换、无组即撤——作用集 ≤8 格常驻, # 其余格零节点零绘制成本。与父件 _draw() 分离的三条理由见本件头注(命令序列/重绘预算/材质挂点)。 func _sync_glow_layer() -> void: if glow_group == 0: @@ -347,7 +347,7 @@ func _sync_glow_layer() -> void: _glow_layer.set_badge_mask(badge_glyph != "") -# 徽章绘制:右下角金(旧 Label BOTTOM_RIGHT 锚点等价——文字贴角内缩 2–3px) +# 徽章绘制:右下角金(文字贴角内缩 2–3px) func _draw_badge(g: String) -> void: var f := font if font != null else ThemeDB.fallback_font if f == null: diff --git a/game/presentation/views/board_fx_view.gd b/game/presentation/views/board_fx_view.gd index f9ac8644..0013ec8a 100644 --- a/game/presentation/views/board_fx_view.gd +++ b/game/presentation/views/board_fx_view.gd @@ -6,7 +6,7 @@ extends Control const COL_GOLD := UiKit.GOLD const COL_BOSS := UiKit.BOSS_PURPLE # 紫赤 #8F2F6A -const COL_SEAL := UiKit.SEAL_BLACK # 封印黑(封印化暴击弹道——封印朱→封印紫→封印黑 2026-09-28) +const COL_SEAL := UiKit.SEAL_BLACK # 封印黑(封印化暴击弹道) const CONFETTI_COLS := [UiKit.GOLD, UiKit.GOLD_LIT, UiKit.HERO_BLUE, UiKit.WARM] # 装饰彩带不涉封印语义——原紫位改亮金(紫赤系 Boss 独占不入装饰) var _banner: Label @@ -117,7 +117,7 @@ func play_seal_hit_projectile(heavy: bool) -> void: tw.tween_callback(shot.queue_free) -# ---- 挖掘挥铲三帧(棋盘小人贴图批 2026-09-25——计划书 §3.C 解耦方案:铲归 fx 层、角色弹跳归 +# ---- 挖掘挥铲三帧(计划书 §3.C 解耦方案:铲归 fx 层、角色弹跳归 # BoardView.play_hero_dig_bounce,两演出零共享属性) ---- const SHOVEL_FRAME_PX := 32.0 # 铲帧画布边长(缩放比与英雄帧同源) @@ -128,7 +128,7 @@ var _shovel_texs: Array[Texture2D] = [] # 惰性装载缓存(素材缺 # 挖掘挥铲:hand = 英雄持握手位(BoardView.hero_hand_point 出口,fx 与棋盘同层同系)—— -# 以手为圆心、铲长为半径旋转(2026-09-25 用户裁决;三帧系素材侧预烤的旋转相位,握把锚 (18,12) +# 以手为圆心、铲长为半径旋转(三帧系素材侧预烤的旋转相位,握把锚 (18,12) # 三帧同位,锚点钉死手位即成弧);dir = 挖掘方向单位格向量(素材铲头朝左——dir.x>0 翻转); # sprite_scale 与英雄精灵同档(整数 1×——原「共享边中点+12% 偏置」定位与 edge/32 缩放作废)。 func play_shovel_swing(hand: Vector2, dir: Vector2i, sprite_scale: float) -> void: diff --git a/game/presentation/views/board_view.gd b/game/presentation/views/board_view.gd index 303bb742..72835d61 100644 --- a/game/presentation/views/board_view.gd +++ b/game/presentation/views/board_view.gd @@ -14,59 +14,57 @@ const _BOARD_WORLD := preload("res://presentation/views/board_world.gd") const COL_BRICK := UiKit.BRICK # 未开——掩尘完整地砖(色板原语 #C9AF83) const COL_FLOOR := UiKit.FLOOR # 已开——裸土 #B39A78(碎裂裸露地面) const COL_DIGIT := UiKit.INK # 数字——墨族 #33261B(对格底 ≥4.5:1 硬指标) -const COL_HERO := UiKit.HERO_BLUE # 小人边框——小人蓝 #2E6E8E -const COL_SEAL := UiKit.SEAL_BLACK # 封印黑 #000000(封印朱→封印紫→封印黑,2026-09-28 用户拍板) +const COL_HERO := UiKit.HERO_BLUE # 小人边框——小人蓝 +const COL_SEAL := UiKit.SEAL_BLACK # 封印黑 #000000 const COL_GOLD := UiKit.GOLD # 奖励金 #F0A828 -const COL_CONTACT := UiKit.CONTACT_GLOW # 接触带微光基色(蓝族浅一档·近白蓝——§3.2 v2.8;旧绿相退役 2026-09-26) +const COL_CONTACT := UiKit.CONTACT_GLOW # 接触带微光基色(蓝族浅一档·近白蓝——§3.2 v2.8) const COL_HL_TARGET := UiKit.GOLD # 悬停目标格边框(金) -const REWARD_BADGE := { # 已开格格面资源身份 icon(cell_type 九型键;极性视觉归批 2) - "attack": "攻", "defense": "守", "heal": "医", "blast": "爆", "weaken": "弱", "pierce": "穿", "magic": "魔", # 穿/魔 = 伤害道具批 2026-09-18 - "action": "行", # 行 = 行动点型(八型批 2026-09-20——ap_up/ap_drain 两行;徽章键漏网补齐,ui_click_probe 91 断言修复) - "gp": "金", # 金 = GP 型(GP+商店房实施批 2026-09-21——gp_gain/gp_loss 两行;金色系 ~40° 相位,禁入带紫赤 300–345° 外,取色 UiKit.GOLD 徽标色单点) +const REWARD_BADGE := { # 已开格格面资源身份 icon(cell_type 九型键) + "attack": "攻", "defense": "守", "heal": "医", "blast": "爆", "weaken": "弱", "pierce": "穿", "magic": "魔", + "action": "行", # 行 = 行动点型(ap_up/ap_drain 两行) + "gp": "金", # 金 = GP 型(gp_gain/gp_loss 两行;金色系 ~40° 相位,禁入带紫赤 300–345° 外,取色 UiKit.GOLD 徽标色单点) } const BADGE_PLACEHOLDER := "?" # 未知图标键占位纹样(HUD框架:禁静默空图标) const CURSOR_DIG := Input.CURSOR_CROSS # 挖——镐形自绘纹理载体 const CURSOR_SEAL := Input.CURSOR_POINTING_HAND # 封印——封印形自绘纹理载体 const CURSOR_MOVE_SEM := Input.CURSOR_ARROW # 移动——箭头(命名避开 Control.CURSOR_MOVE 原生成员遮蔽) const CHORD_WINDOW_MS := 350 -const SEP := 2 # 格间距(旧 GridContainer v/h_separation 同值——格尺寸公式与命中换算共用) +const SEP := 2 # 格间距(格尺寸公式与命中换算共用) -# 棋盘立体参数(2026-09-24 用户实机三档对比拍板「中档」定稿——原型 F9/按钮入口已退役; -# §1.4 注记待 art-bible 并行批落籍后补写) +# 棋盘立体参数 const DEPTH_PX := 8.0 # 悬崖厚度(像素) const DEPTH_BEVEL := 0.6 # 顶面倒角强度 -# 高墙感 D 投影档(2026-09-28 挑档落码):地面投影带宽 = 格边比(研究件 64px 拼版实测 14/64≈0.22; +# 高墙感 D 投影档:地面投影带宽 = 格边比(研究件 64px 拼版实测 14/64≈0.22; # 立面/投影色参数在 CellUnit 常量——绘制侧单点) const WALL_PROJECTION_FRAC := 0.22 -# 英雄单位演出参数(棋盘小人贴图批 2026-09-25——计划书 §3.B/C 时长档) +# 英雄单位演出参数(计划书 §3.B/C 时长档) const HERO_FRAME_PX := 32.0 # 英雄帧画布边长(素材 32×32 锁定——缩放比分母) -const HERO_SPRITE_SCALE := 1.5 # 1.5× 档(2026-09-26 用户二裁:实机看 1× 偏小放大 1.5 倍——明示 - # 裁决压圣经 §8.2「禁非整数缩放」一般规则,§8.2 豁免注记归 art-bible - # 批另落;头可越格上沿不裁剪) -const HERO_GROUND_FRAC := 0.25 # 脚锚纵向落点 = 格底往上 25%(用户口径「脚踩格子 1/4 处·从下往上数」; - # 头越上格沿造立体感。⚠ 参照系纪律:本值一律自底边起算——上一批用 - # 「自顶 75%」表述同线异名,措辞口径误导用户被纠,本批统一为自底边) +const HERO_SPRITE_SCALE := 1.5 # 1.5× 档(实机 1× 偏小故放大 1.5 倍——本档为圣经 §8.2「禁非整数缩放」 + # 一般规则的显式豁免;头可越格上沿不裁剪) +const HERO_GROUND_FRAC := 0.25 # 脚锚纵向落点 = 格底往上 25%(口径「脚踩格子 1/4 处·从下往上数」; + # 头越上格沿造立体感。⚠ 参照系纪律:本值一律自底边起算,禁改用「自顶 75%」 + # 一类的同线异名表述) const HERO_MOVE_S := 0.14 # 位移时长(~140ms) const HERO_STEP_S := 0.18 # 走路帧周期 = 原地撞墙帧闪时长(~180ms) const HERO_DIG_S := 0.15 # 挖掘弹跳总时长(~150ms,半程压半程回) const HERO_BOUNCE := 0.82 # 弹跳压缩比(scale.y 1→0.82→1 脚底收敛) const HERO_SHADOW_PX := Vector2(32, 12) # 脚下椭圆影屏幕尺寸(Godot 组件合成——径向渐变纹理压扁, - # 贴图零改动,2026-09-26 用户裁决走引擎侧) + # 贴图零改动,走引擎侧) -# ── 高墙/地面瓦片纹理路径单点(棋盘高墙瓦片接线批 2026-09-26)── -# 素材 PNG 不入 git(用户裁定)——一律 UiKit.load_tex(exists 守卫)装载,禁 preload; +# ── 高墙/地面瓦片纹理路径单点 ── +# 素材 PNG 不入 git——一律 UiKit.load_tex(exists 守卫)装载,禁 preload; # 缺位返回 null,整批任一缺位 = 弃用瓦片走程序化平色回退(BRICK/FLOOR,fresh checkout 冒烟不炸)。 -# 路径常量落本文件单点(ui_kit.gd 由并行批占用,需求卡片 §2.5 禁入)。词表 = +# 路径常量落本文件单点。词表 = # design/research/board-tile-vocab-plan-a-2026-09-26.md(16 唯一墙瓦片 + 5 地面变体; # 东/东北/东南/end_e/in_ne/in_se 六镜像件运行时 flip_x 合成,不出文件——词表 §二)。 -# 换色批(T6 2026-09-28):路径按 board_type 后缀参数化——terrain_<件名>_.png; +# 路径按 board_type 后缀参数化——terrain_<件名>_.png; # 词表 §一 16 唯一墙瓦片名单单点在本常量数组。underdark/deep_underdark 两套 = -# tools/recolor_terrain_tiles.py 程序换色产(台账 164 换色遗留清偿);任一套缺位 → 整批回落 +# tools/recolor_terrain_tiles.py 程序换色产;任一套缺位 → 整批回落 # dungeon 套(禁同板混渲染);dungeon 套亦缺位 → 程序化平色回退(fresh checkout 冒烟不炸)。 const TILE_WALL_NAMES := ["wall_center", "wall_center_crack", "wall_center_speckle", "wall_n", "wall_s", "wall_w", "wall_nw", "wall_sw", "wall_hrun", "wall_vrun", "wall_end_n", "wall_end_s", "wall_end_w", "wall_lone", "wall_in_nw", "wall_in_sw"] const TILE_WALL_FMT := "res://assets/art/board/terrain_%s_%s.png" # %s=件名 %s=board_type -const TILE_SEAL_MARK := "res://assets/art/board/seal_mark.png" # 封印印记纹理(迭代 9 卡⑬——独立可选件) +const TILE_SEAL_MARK := "res://assets/art/board/seal_mark.png" # 封印印记纹理(独立可选件) const TILE_FLOOR_FMT := "res://assets/art/board/terrain_floor_%s_%d.png" # %s=board_type 1..%d 变体 const TILE_FLOOR_VARIANTS := 5 # 地面瓦片变体数(词表 §一 floor_1..5) @@ -79,8 +77,8 @@ var _board: BoardData = null var _minesweeper = null # 排雷玩法 只读查询引用(refresh 更新;null = 无战斗) var _identity_cb := Callable() # 地图战斗资源 身份解析回调(组合根注入只读面)——Vector2i → Dictionary/null var _mask_cb := Callable() # 地形变异 数字遮蔽回调(组合根注入只读面)——Vector2i → bool(true = 该格数字不显示) -var _vmark_cb := Callable() # 地形变异 角标回调(迭代 6 T6 只读面)——Vector2i → String("flat_damage"=伤害型变异未开格;""=无) -var _treasure_reveal := {} # 秘宝 真视集(迭代 7 T4——Vector2i → true;组合根 set_treasure_overlays 注入投影) +var _vmark_cb := Callable() # 地形变异 角标回调(只读面)——Vector2i → String("flat_damage"=伤害型变异未开格;""=无) +var _treasure_reveal := {} # 秘宝 真视集(Vector2i → true;组合根 set_treasure_overlays 注入投影) var _treasure_preview := {} # 秘宝 预读集(同上——未开格徽章呈现挂点) var _diggable := {} # 可挖域(8 向相邻未开格)——呼吸微光作用集 var _glow: Dictionary[Vector2i, int] = {} # 未开格类型微光作用集(Vector2i → 组号;=可挖域∩身份可查) @@ -98,7 +96,7 @@ var _desat_mat: ShaderMaterial var _desat_tween: Tween var _cell := 46.0 # 当前格边长(set_cell_area 按容器尺寸重算——battle.md 格尺寸公式) -# ── 英雄单位精灵状态(棋盘小人贴图批 2026-09-25;素材 PNG 不入 git——load_tex 守卫装载,缺位=字形回退)── +# ── 英雄单位精灵状态(素材 PNG 不入 git——load_tex 守卫装载,缺位=字形回退)── var _hero_tex_idle: Texture2D # 站立帧(null = 素材缺位——零精灵,字形「人」原路径) var _hero_tex_walk: Texture2D # 跨步帧 var _hero_last := Vector2i(-99, -99) # 上拍英雄格(refresh diff 基准;哨兵 = 未落位/随 rebuild 复位) @@ -108,31 +106,29 @@ var _hero_move_tw: Tween var _hero_bump_tw: Tween var _hero_dig_tw: Tween -# ── 瓦片状态(高墙瓦片接线批 2026-09-26;素材缺位 = 全 false/空——程序化平色回退)── +# ── 瓦片状态(素材缺位 = 全 false/空——程序化平色回退)── var _tiles := {} # 词表键 → Texture2D(镜像件已预翻转;装载见 _load_board_tiles) var _floor_tiles: Array[Texture2D] = [] # 地面瓦片五变体(下标 0..4 = floor_1..5) var _tiles_ok := false # false = 素材缺位/未装载——bg_sb 程序化平色原路径 var _seal_tex: Texture2D = null # 封印印记纹理(缺盘=null=字形「封印」回退——独立可选件不连瓦片整批) -var _tiles_board_type := "dungeon" # 当前装载瓦片套的 board_type(rebuild 按板切换——T6 换色批) +var _tiles_board_type := "dungeon" # 当前装载瓦片套的 board_type(rebuild 按板切换) var _digit_dark_ink := true # 数字墨族按板自适应(true=深墨三档)。缺盘平色回退态 #B39A78 裸土 # 为中明度底——深墨族 CR 4.96 达标、亮墨族仅 2.2,故缺盘默认深墨;瓦片装载后按实测分位数覆写 var _digit_plate := false # 数字色牌垫底模式(双峰纹理板——直画两族皆不过门槛时落牌, - # 素牌+深墨 12:1 纹理免疫;2026-10-01 渲染帧取证 underdark 系深墨直画隐形后启用) + # 素牌+深墨 12:1 纹理免疫;渲染帧取证 underdark 系深墨直画隐形,故启用色牌) -# ---- 视野迷雾(迭代 11 第④批 T2/T4——纯呈现层;正主=HUD框架「视野迷雾」节 v0.13,渲染规格=art-bible §6.5 v3.5)---- +# ---- 视野迷雾(纯呈现层;正主=HUD框架「视野迷雾」节 v0.13,渲染规格=art-bible §6.5 v3.5)---- const FOG_RADIUS := 8 # 菱形灯光区基准半径(曼哈顿距离 ≤R——与微光环「周围 8 格」同圈起步;半径基准值改动=非白名单须用户) var _fog_enabled := true # 迷雾开关(呈现态布尔——真实游戏恒 on;探针/夹具可 off=无迷雾基线,两态结算逐位一致断言面) var _fog_lantern := 0 # 视野加成现值(缺省 0=无加成基线零扰动;生产写入面=组合根每战装配链显式重算——main._sync_treasure_glow) -# 视野加成接线(迭代 22 秘宝批 T4 换代——旧提灯布尔桥 set_fog_lantern 与 FOG_LANTERN_BONUS 常量 -# 随 fog_lantern 行退役摘除〔V12〕;新主语=阔视野带 light_radius_bonus 装配参数(magnitude 4→半径 -# 8+4=12 格 provisional);类型微光不随视野扩〔微光锚=可挖域贴身 8 邻零改动〕沿迭代 14⑤ 拍板。 -# 组合根 main._sync_treasure_glow 每战首轮装配链显式重算调用;缺省 0=off 态与旧基线逐位一致。 +# 视野加成接线:light_radius_bonus 装配参数(magnitude 4→半径 8+4=12 格 provisional);类型微光 +# 不随视野扩〔微光锚=可挖域贴身 8 邻零改动〕。组合根 main._sync_treasure_glow 每战首轮装配链显式重算。 func set_fog_glow_bonus(bonus: int) -> void: _fog_lantern = maxi(0, bonus) refresh() # 灯光区半径变了——全板重算雾态(refresh/notify_hero_move 既有重绘驱动复用) -var cell_size: float: # 只读属性(棋盘格边长对外契约出口——旧私有名 _cell 的契约化出口) +var cell_size: float: # 只读属性(棋盘格边长对外契约出口) get: return _cell @@ -149,7 +145,7 @@ func _init() -> void: _svp_container.mouse_filter = Control.MOUSE_FILTER_IGNORE # 输入归壳层 _gui_input(板级公式换算),不进 SubViewport _wrap.add_child(_svp_container) _viewport = SubViewport.new() - _viewport.transparent_bg = true # 格间距露出 D 区底色(与旧 Button 网格间隙同观感) + _viewport.transparent_bg = true # 格间距露出 D 区底色 _svp_container.add_child(_viewport) _world = _BOARD_WORLD.new() _viewport.add_child(_world) @@ -158,7 +154,7 @@ func _init() -> void: _desat_mat.set_shader_parameter("strength", 0.0) _hero_tex_idle = UiKit.load_tex(UiKit.TEX_HERO_IDLE) _hero_tex_walk = UiKit.load_tex(UiKit.TEX_HERO_WALK) - _load_board_tiles() # 高墙/地面瓦片整批守卫装载(缺位静默回退——英雄批同款纪律,禁刷屏) + _load_board_tiles() # 高墙/地面瓦片整批守卫装载(缺位静默回退——英雄同款纪律,禁刷屏) func board() -> BoardData: @@ -171,7 +167,7 @@ func _ready() -> void: # 结算期/道具窗口态:D 区去饱和 + 金橙偏移锁输入(明度不变——art-bible §2); -# 材质挂 BoardWorld 世界级单点(CellUnit use_parent_material 链下随世界灰化——语义与旧逐格挂材质一致) +# 材质挂 BoardWorld 世界级单点(CellUnit use_parent_material 链下随世界灰化) func set_desaturated(on: bool) -> void: if _desat_tween != null and _desat_tween.is_valid(): _desat_tween.kill() @@ -182,7 +178,7 @@ func set_desaturated(on: bool) -> void: _world.material = _desat_mat if on else null -# 视野迷雾开关(迭代 11 第④批 T2——呈现态布尔:真实游戏恒 on;探针/夹具 off=无迷雾基线, +# 视野迷雾开关(呈现态布尔:真实游戏恒 on;探针/夹具 off=无迷雾基线, # 迷雾开/关两态结算逐位一致断言面;切换即全板重算 fog_state) func set_fog_enabled(on: bool) -> void: _fog_enabled = on @@ -200,12 +196,12 @@ func set_variant_mask_resolver(cb: Callable) -> void: _mask_cb = cb -# 组合根注入 地形变异 角标只读回调(迭代 6 T6——flat_damage 未开格视觉标记;变异是策略纹理非数值墙: +# 组合根注入 地形变异 角标只读回调(flat_damage 未开格视觉标记;变异是策略纹理非数值墙: # 玩家可据此绕行/承担的决策输入。空 Callable = 全板无标记(缺位回退态) func set_variant_mark_resolver(cb: Callable) -> void: _vmark_cb = cb -# 秘宝叠加层投影注入(迭代 7 T4——组合根在 use 成功/三清后调;refresh 消费) +# 秘宝叠加层投影注入(组合根在 use 成功/三清后调;refresh 消费) func set_treasure_overlays(reveal_cells: Array, preview_cells: Array) -> void: _treasure_reveal.clear() _treasure_preview.clear() @@ -216,8 +212,8 @@ func set_treasure_overlays(reveal_cells: Array, preview_cells: Array) -> void: refresh() -# SubViewport 主题/字体显式注入挂点(Phase B 两舞台复用——SubViewport 不自动继承主场景 Control 主题; -# 本项目无自定义主题,缺省 = 引擎回退字体,与旧 Button 渲染同源) +# SubViewport 主题/字体显式注入挂点(SubViewport 不自动继承主场景 Control 主题; +# 本项目无自定义主题,缺省 = 引擎回退字体) func set_world_font(f: Font) -> void: _world.board_font = f for c in _cells: @@ -226,8 +222,7 @@ func set_world_font(f: Font) -> void: # D 区可用面积(AP 条之外)→ 格边长 = floor((min(宽, 高) − 预留 − (N−1)×格间距) / N)(battle.md 格尺寸公式) -# 2026-09-19 修复:格边长公式补算 (N−1)×2px 网格间距 + 垂直预留 24px——旧公式只算 N×cell, -# L2 12×12 板网格实高溢出可用区 ~6px,下缘被 clip_contents 裁掉约 1/6 格高。 +# 公式须补算 (N−1)×2px 网格间距与垂直预留 24px,否则 12×12 板实高溢出可用区 ~6px,下缘被 clip_contents 裁掉。 func set_cell_area(avail: Vector2) -> void: if _board == null or _board.width == 0: return @@ -265,7 +260,7 @@ func rebuild(board: BoardData, minesweeper: MinesweeperRules) -> void: _minesweeper = minesweeper for child in _world.get_children(): child.queue_free() - _world.hero = null # 英雄精灵随清场退役——下拍 refresh 经 ensure_hero 重建(首建即时落位) + _world.hero = null # 英雄精灵随清场复位——下拍 refresh 经 ensure_hero 重建(首建即时落位) _cells.clear() _glow.clear() _glow_errors.clear() @@ -275,7 +270,7 @@ func rebuild(board: BoardData, minesweeper: MinesweeperRules) -> void: _hover = Vector2i(-9, -9) for c in _board.compute_r0(): _r0[c] = true - # 瓦片套随板图型切换(T6 换色批——board_gen 词表 v1.1 dungeon/underdark/deep_underdark; + # 瓦片套随板图型切换(board_gen 词表 v1.1 dungeon/underdark/deep_underdark; # 同图型重复 rebuild 零重载,_tiles_board_type 守卫) var bt: String = _board.board_type if _board.board_type != "" else "dungeon" if bt != _tiles_board_type: @@ -288,11 +283,11 @@ func rebuild(board: BoardData, minesweeper: MinesweeperRules) -> void: u.cell = c u.edge = _cell u.position = Vector2(c) * stride - u.bevel = DEPTH_BEVEL # 定稿倒角——新建格单元继承 + u.bevel = DEPTH_BEVEL # 新建格单元继承 u.use_parent_material = true # 去饱和材质挂 BoardWorld——单元随世界材质灰化 if _tiles_ok: - # NEAREST 采样(2026-09-26 用户拍板:32×32 源 × 45/36px 格边非整数缩放接受档, - # 与英雄小人 1.5× 豁免同级——圣经 §8.2 豁免注记归 art-bible 批补写);只在瓦片 + # NEAREST 采样(32×32 源 × 45/36px 格边非整数缩放接受档, + # 与英雄小人 1.5× 豁免同级(圣经 §8.2);只在瓦片 # 模式启用——程序化回退路径渲染零扰动(含格面文字采样不回退不变化) u.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST u.font = _world.board_font @@ -318,10 +313,10 @@ func refresh() -> void: _paint_cell(Vector2i(x, y), hero) _refresh_hover_after_paint() _apply_contact_bands() - _update_hero(hero) # 英雄精灵 diff 驱动(棋盘小人贴图批 2026-09-25) + _update_hero(hero) # 英雄精灵 diff 驱动 -# 未开格类型微光作用集(迭代 30 卡①):= 可挖域 ∩ 身份可查格 ∩ 灯光区内。 +# 未开格类型微光作用集:= 可挖域 ∩ 身份可查格 ∩ 灯光区内。 # 组号 = cell_type 经 UiKit.glow_group_for_cell_type 九值封闭判定得出;清单外值 = 数据错, # 登记进 _glow_errors 由断言面显式暴露,禁静默空光(图标键错误处理同款纪律)。 # 纯派生:只读 query_identity 回调,零玩法数据写入(🔴 契约 1)。 @@ -350,8 +345,8 @@ func _recompute_glow(hero: Vector2i) -> void: _glow[n] = g -# 未开格类型微光开关(迭代 30 卡① · Q4 丙案):呈现态布尔,生产写入面 = 组合根单点。 -# 不新增设置项——工程有闸、界面无感;off 态为基线保护面(结算逐位一致断言承接,契约 1/T2)。 +# 未开格类型微光开关:呈现态布尔,生产写入面 = 组合根单点。 +# 不新增设置项——工程有闸、界面无感;off 态为基线保护面(结算逐位一致断言承接)。 func set_type_glow_enabled(on: bool) -> void: if _type_glow == on: return @@ -360,7 +355,7 @@ func set_type_glow_enabled(on: bool) -> void: refresh() -# ---- 入场演出(battle.md Transitions「install 淡入 200ms + 初始 R0 展开涟漪」——2026-09-26 补实装)---- +# ---- 入场演出(battle.md Transitions「install 淡入 200ms + 初始 R0 展开涟漪」)---- # 全板 modulate 淡入 200ms;R0 格按离板心距离逐格延迟显形(涟漪);纯视觉 alpha,零输入影响; # 减动效时长减半(motion);重入(弃图换图 rebuild)先杀旧 tween 防叠加 func _install_entrance_fx() -> void: @@ -385,7 +380,7 @@ func _install_entrance_fx() -> void: _ripple_tws.append(tw) -# ---- 英雄单位精灵(棋盘小人贴图批 2026-09-25——计划书 §3.A/B;格面五 texture 槽零改动) ---- +# ---- 英雄单位精灵(计划书 §3.A/B;格面五 texture 槽零改动) ---- # refresh diff 驱动:位置变化 = 位移演出(140ms Tween + 走路帧);零位移但有受理移动回执 = 只播帧 # 不位移(撞墙语义——排雷玩法「目标=当前格」幂等受理)。素材缺位 = 零精灵,字形「人」回退路径。 @@ -410,7 +405,7 @@ func _update_hero(hero: Vector2i) -> void: # 英雄落位(instant = 即位无演出——首建/格边长变更;否则 140ms 位移 + 走路帧起手、到位回站帧。 -# 帧权威单一化:Sprite2D 换纹理路线(计划书 §3.B 二选一之后者)——换纹理+flip_h 同拍写定即生效, +# 帧权威单一化:Sprite2D 换纹理路线(计划书 §3.B)——换纹理+flip_h 同拍写定即生效, # 无 AnimatedSprite2D 的 play()/advance(0) 错向面) func _place_hero(from: Vector2i, to: Vector2i, instant: bool) -> void: var sp: Sprite2D = _world.hero @@ -478,17 +473,16 @@ func cell_origin(c: Vector2i) -> Vector2: return _svp_container.position + Vector2(c) * (_cell + float(SEP)) -# 英雄脚底锚点——**世界坐标**(精灵在 SubViewport 世界内:格原点 = 格×步距,禁带壳层居中偏移。 -# 2026-09-26 修正:上批误用壳层 cell_origin(含 _svp_container.position 居中偏移)定位世界内精灵, -# 实测整体右偏 ~7 格+偏离格心——实机截图用户报缺陷)。 -# 纵向 = 格底往上 25% 线(脚踩格子 1/4 处——2026-09-26 用户裁决);横向格中线。身体向上延伸, -# 头越上格沿不裁剪(立体感裁决);锚点与精灵缩放解耦(缩放只改身体向上长多少)。 +# 英雄脚底锚点——**世界坐标**(精灵在 SubViewport 世界内:格原点 = 格×步距,禁带壳层居中偏移—— +# cell_origin 含 _svp_container.position,世界内精灵定位误用会整体右偏 ~7 格+偏离格心)。 +# 纵向 = 格底往上 25% 线(脚踩格子 1/4 处);横向格中线。身体向上延伸, +# 头越上格沿不裁剪(造立体感);锚点与精灵缩放解耦(缩放只改身体向上长多少)。 func _hero_feet(c: Vector2i) -> Vector2: return Vector2(c) * (_cell + float(SEP)) + Vector2(_cell * 0.5, _cell * (1.0 - HERO_GROUND_FRAC)) # 英雄持握手位(fx 同层坐标系 = 壳层坐标——fx 在 SubViewport 之外,须含 _svp_container.position -# 居中偏移:世界脚底锚 + 壳层偏移即得)。手 = 盒底往上 1/4 盒高、水平居中(2026-09-25 用户裁决; +# 居中偏移:世界脚底锚 + 壳层偏移即得)。手 = 盒底往上 1/4 盒高、水平居中( # 盒高随 HERO_SPRITE_SCALE——手位钉在身体上不随缩放漂移) func hero_hand_point() -> Vector2: return _svp_container.position + _hero_feet(_hero_last) \ @@ -508,9 +502,8 @@ func click_cell(cell: Vector2i, button: int) -> void: _on_cell_input(cell, ev) -# 板级公式单点(Node2D 迁移批 Decision 3):格坐标 = floor(板内局部坐标 / 格步长) -#(格步长 = 格边长 + 间距;板外/负域返回 (-9,-9)。旧逐格 Button 命中被此函数取代; -# 2px 格间隙落入左/上邻格——旧间隙为零命中死区,等价性偏差已登记迁移方案汇报面) +# 板级公式单点:格坐标 = floor(板内局部坐标 / 格步长) +#(格步长 = 格边长 + 间距;板外/负域返回 (-9,-9);2px 格间隙落入左/上邻格) func _cell_at(shell_pos: Vector2) -> Vector2i: if _board == null or _board.width == 0: return Vector2i(-9, -9) @@ -581,8 +574,8 @@ func _on_cell_input(c: Vector2i, ev: InputEvent) -> void: elif ev.button_index == MOUSE_BUTTON_RIGHT: if not _minesweeper.has_seal(c): action_requested.emit(c, "seal_place") - # 封印 = 一次性承诺(封印不可逆批 2026-09-19):撤封印退役——封印格右键零动作; - # 左键相邻封印格直接挖(四情况②④兑付改判,规则引擎放行)。 + # 封印 = 一次性承诺:右键对封印格零动作(无撤封印); + # 左键相邻封印格直接挖(规则引擎放行)。 # chord 肌肉记忆首遇锚:同格双左击快开尝试(350ms 窗)——每 run 一次提示由组合根去重 @@ -629,11 +622,11 @@ func _apply_hover_visuals(c: Vector2i) -> void: _show_path_preview(c) elif adjacent: u.hl_visible = true - u.hl_color = COL_HL_TARGET # 挖掘目标格边框(相邻封印格同此——左键直接挖,封印不可逆批) + u.hl_color = COL_HL_TARGET # 挖掘目标格边框(相邻封印格同此——左键直接挖) _set_cursor_shape(c, CURSOR_DIG) elif seal: u.hl_visible = true - u.hl_color = COL_SEAL # 已承诺封印标记(封印黑;无交互可供——撤封印已退役) + u.hl_color = COL_SEAL # 已承诺封印标记(封印黑;无交互可供) _set_cursor_shape(c, Input.CURSOR_FORBIDDEN) else: u.hl_visible = true @@ -650,11 +643,11 @@ func _clear_hover_visuals(c: Vector2i) -> void: func _set_cursor_shape(c: Vector2i, shape: int) -> void: - mouse_default_cursor_shape = shape # 壳级光标(悬停格语义决定——单格悬停恒一,等价旧逐格光标) + mouse_default_cursor_shape = shape # 壳级光标(悬停格语义决定——单格悬停恒一) func _show_path_preview(c: Vector2i) -> void: - # D3 合法性指示:悬停已开格 → BFS 路径蓝细线点迹(compute_move_path 只读面) + # 合法性指示:悬停已开格 → BFS 路径蓝细线点迹(compute_move_path 只读面) if _minesweeper == null: return var path: Array[Variant] = _minesweeper.compute_move_path(c) @@ -675,7 +668,7 @@ func _update_badge(c: Vector2i) -> String: return "" if _r0.has(c): return "" # R₀ 初始展开格无奖励身份(地图战斗资源 资格域 = S∖R₀) - var rec: Dictionary[Variant, Variant] = _minesweeper.reveal_record(c) # E2 收口:已开记录经查询面(禁直读 排雷玩法 状态字典) + var rec: Dictionary[Variant, Variant] = _minesweeper.reveal_record(c) # 已开记录经查询面(禁直读 排雷玩法 状态字典) if rec.get("kind", "") != "safe": return "" var ident = _identity_cb.call(c) @@ -684,7 +677,7 @@ func _update_badge(c: Vector2i) -> String: return _badge_glyph(String(ident.get("cell_type", ""))) -# 奖励图标键解析(HUD框架:查不到的键立即断言 + ? 占位纹样 + 诊断;键集 = 格面资源 cell_type 九值枚举——GP+商店房实施批 2026-09-21 八→九) +# 奖励图标键解析(HUD框架:查不到的键立即断言 + ? 占位纹样 + 诊断;键集 = 格面资源 cell_type 九值枚举) func _badge_glyph(category: String) -> String: if REWARD_BADGE.has(category): return REWARD_BADGE[category] @@ -695,7 +688,7 @@ func _badge_glyph(category: String) -> String: # ---- 格态渲染(灰度截图可辨:完整覆尘 / 碎裂裸土 / 已开数字) ---- -# 数字三档色温(按板自适应双族——v3.5 冻结④ 修订 2026-10-01):亮墨族 1-3 冷亮/4-5 暖白/6-8 金亮 +# 数字三档色温(按板自适应双族——v3.5 冻结④):亮墨族 1-3 冷亮/4-5 暖白/6-8 金亮 #(dungeon 瓦片实测达标维持);深墨族 1-3 青墨/4-5 赭墨/6-8 锈墨(色温语义同构——underdark/ # deep_underdark 亮白筋纹瓦片上亮墨对亮斑 CR 1.0–1.9 融字,深墨族 5.7–11.1;选族判据见 _digit_ink_mode) func _digit_ink(d: int) -> Color: @@ -718,20 +711,20 @@ func _paint_cell(c: Vector2i, hero: Vector2i) -> void: return var revealed: bool = _minesweeper.is_revealed(c) var seal: bool = _minesweeper.has_seal(c) - var removed: bool = _minesweeper.is_removed(c) # 迭代 13 T8/D6——中立移除格(P2 甲退色降档) + var removed: bool = _minesweeper.is_removed(c) # 中立移除格(退色降档) var is_hero: bool = c == hero var glyph := "" var bg: Color var digit_col := COL_DIGIT - # 封印槽统一维护(T17 修复):封印格=封印印记纹理;其余格清 null(封印格挖开后残留在 tex_seal + # 封印槽统一维护:封印格=封印印记纹理;其余格清 null(封印格挖开后残留在 tex_seal # 会让 _draw 无条件把封印印画在已开格上——tex_seal 绘制无 revealed 条件)。缺盘走字形回退。 u.tex_seal = _seal_tex if (seal and not revealed and _seal_tex != null) else null if removed: - revealed = false # 移除格固定未开呈现基座(退色暗幕层承载;危险格本无数字——P1 甲周边数字冻结) + revealed = false # 移除格固定未开呈现基座(退色暗幕层承载;危险格本无数字,周边数字冻结) seal = false u.tex_seal = null if revealed: - var rec: Dictionary[Variant, Variant] = _minesweeper.reveal_record(c) # E2 收口:已开记录经查询面 + var rec: Dictionary[Variant, Variant] = _minesweeper.reveal_record(c) # 已开记录经查询面 if rec.get("kind", "") == "mine": bg = COL_FLOOR glyph = "雷" @@ -744,7 +737,7 @@ func _paint_cell(c: Vector2i, hero: Vector2i) -> void: glyph = "?" # 数字遮蔽(地形变异 hide_number——信息型:该格真实数字不显示) else: glyph = str(d) - digit_col = _digit_ink(d) # 数字墨三档色温(样张 v2 冻结批 T4——§4.1) + digit_col = _digit_ink(d) # 数字墨三档色温(§4.1) else: if seal: bg = COL_BRICK @@ -753,10 +746,10 @@ func _paint_cell(c: Vector2i, hero: Vector2i) -> void: digit_col = COL_SEAL else: bg = COL_BRICK - # 瓦片模式(高墙接线批 2026-09-26):tex_base = 查表瓦片(未开=墙瓦片/已开=地面瓦片), + # 瓦片模式:tex_base = 查表瓦片(未开=墙瓦片/已开=地面瓦片), # bg_sb 降级为透明描边载体——只承载呼吸微光/主角蓝框(CellUnit 瓦片态画在瓦片之上), - # 程序化平色退役;瓦片分配=格坐标哈希,初始化落定后逐拍稳定(禁逐轮重掷——圣经原则三) - # draw calls 批优化(2026-10-01):透明载体 sb 视觉贡献=零(透明底+零描边——不可见),但 + # 瓦片分配=格坐标哈希,初始化落定后逐拍稳定(禁逐轮重掷——圣经原则三) + # draw calls 批优化:透明载体 sb 视觉贡献=零(透明底+零描边——不可见),但 # StyleBoxFlat 多边形命令不可合批,每格打断棋盘批——实测 100 格满负荷帧 ~402 DC(A/B 探针 # 阶梯:纹理统一 0 增益/去 glyph −23/去叠层 −23/去隐形 sb −402)。非英雄格 sb 直接置 null #(绘制路径零像素变化),仅英雄格保留蓝框载体。 @@ -780,28 +773,27 @@ func _paint_cell(c: Vector2i, hero: Vector2i) -> void: u.bg_sb = sb u.glyph = glyph u.glyph_color = digit_col - # 色牌后备(v3.5 批 B2——数字直画退牌;雷/「?」维持牌载保读性)+ 2026-10-01 v3.4:双峰纹理板 + # 色牌后备(数字直画退牌;雷/「?」维持牌载保读性)+ v3.4:双峰纹理板 #(_digit_plate——underdark 系亮白筋+近黑斑并存的直画不可救纹理)数字落牌,牌上深墨 12:1 var plate_digit := _digit_plate and glyph != "" and glyph != "雷" and glyph != "?" and glyph != "封" and glyph != "人" if plate_digit: digit_col = COL_DIGIT # 牌上深墨族(素牌 12:1——双峰纹理免疫) u.glyph_color = digit_col u.plate = revealed and (glyph == "雷" or glyph == "?" or plate_digit) - u.outline_sides.assign([]) # typed Array[int](代码审查批 3 类型收紧——assign 保持引用语义) + u.outline_sides.assign([]) # typed Array[int](assign 保持引用语义) u.facade_south = false u.proj_band = 0.0 u.tex_facade = null u.facade_strip = false - # 封印槽不在此重置(2026-10-02 修复批——T13 批的 paint 尾部 `u.tex_seal = null` 与 L683 的条件 - # 赋值构成双写踩踏:执行序 683→此处把封印纹理恒清 null=素材在位时封印不可见;L683 的 else 分支 - # 已是全路径清残留,尾部重置系冗余且有害,删除) + # 封印槽不在此重置:尾部重置会与此上方条件赋值构成双写踩踏(把封印纹理恒清 null=素材在位时封印不可见); + # 上方 else 分支已是全路径清残留,尾部重置系冗余且有害 var south_n: Vector2i = c + Vector2i(0, 1) var north_n: Vector2i = c + Vector2i(0, -1) var south_in: bool = south_n.x >= 0 and south_n.y >= 0 and south_n.x < _board.width and south_n.y < _board.height var north_in: bool = north_n.x >= 0 and north_n.y >= 0 and north_n.x < _board.width and north_n.y < _board.height if not revealed: - # 高墙感 D 投影档(2026-09-28 挑档落码):南邻地面格 → 墙格南缘立「口沿高光+双段暗带」立面 - #(邻地面才画——墙-墙内界保墙群内聚,轮廓加强批同口径);板外=墙不画 + # 高墙感 D 投影档:南邻地面格 → 墙格南缘立「口沿高光+双段暗带」立面 + #(邻地面才画——墙-墙内界保墙群内聚);板外=墙不画 u.facade_south = south_in and _minesweeper.is_revealed(south_n) # 轮廓加强:墙格四邻中已开(地面)格朝向记描边码(板外=墙不描——保墙群外轮廓只在墙/地交界) for d in [Vector2i(0, -1), Vector2i(0, 1), Vector2i(-1, 0), Vector2i(1, 0)]: @@ -811,7 +803,7 @@ func _paint_cell(c: Vector2i, hero: Vector2i) -> void: if code == 1 and u.facade_south: continue # 南缘由立面件承载(高光+双段暗带)——2px 描边让位防三重叠黑 if code == 0 and _tiles_ok: - continue # v3.5 冻结① (b)-(c) 交界无边框:墙面直贴接墙顶(E 格墙面件在邻格承载)——北向描边退役(平色回退态保留描边) + continue # v3.5 冻结① (b)-(c) 交界无边框:墙面直贴接墙顶(E 格墙面件在邻格承载)——北向描边不画(平色回退态保留描边) u.outline_sides.append(code) else: # 地面投影:北邻墙格在本已开格北缘投渐隐暗带(ITB 同款高度线索——带宽按格边比例常量) @@ -822,7 +814,7 @@ func _paint_cell(c: Vector2i, hero: Vector2i) -> void: if south_in and not _minesweeper.is_revealed(south_n) and _tiles_ok: u.facade_strip = true u.tex_facade = _tiles.get("wall_center") - # ②( 秘宝叠加层(迭代 7 T4):真视格=红内缩框;预读格=奖励身份徽章(identity_resolver 既有 + # ②( 秘宝叠加层:真视格=红内缩框;预读格=奖励身份徽章(identity_resolver 既有 # 只读面取字形——零数据复制,badge 位复用);已开格标记自然退位(refresh 逐拍重算) if not revealed: u.treasure_mark = "mine_reveal" if _treasure_reveal.has(c) else "" @@ -832,15 +824,15 @@ func _paint_cell(c: Vector2i, hero: Vector2i) -> void: glyph = String(REWARD_BADGE[String(pid.get("cell_type", ""))]) digit_col = COL_GOLD u.badge_glyph = glyph - # ②' 变异角标(迭代 6 T6):未开格带伤害型变异 → 危险红角标(已开=威胁已兑现标记退位); - # 回调缺位 = 无标记(程序化角标,tex_mutation 纹带槽留给变异纹带自产批) + # ②' 变异角标:未开格带伤害型变异 → 危险红角标(已开=威胁已兑现标记退位); + # 回调缺位 = 无标记(程序化角标,tex_mutation 纹带槽暂留) if not revealed and _vmark_cb.is_valid(): u.mutation_mark = String(_vmark_cb.call(c)) else: u.mutation_mark = "" u.badge_glyph = _update_badge(c) u.glow_group = int(_glow.get(c, UiKit.GLOW_NONE)) - # 视野迷雾呈态(迭代 11 第④批 T2/T3):曼哈顿距离 > 半径 → 区外——未开格全黑(正主 :163 照抄)/ + # 视野迷雾呈态:曼哈顿距离 > 半径 → 区外——未开格全黑(正主照抄)/ # 已开格记忆态(灰显可读);以英雄格为心逐格重算,refresh()/notify_hero_move() 既有重绘驱动=移动实时跟随。 # 纯呈现零逻辑——格态/数字真值/清图判定零触碰(🔴 契约 1);结算期去饱和叠加互斥由 CellUnit 记忆态终态档承载。 if _fog_enabled: @@ -854,7 +846,7 @@ func _paint_cell(c: Vector2i, hero: Vector2i) -> void: # ---- 可挖域接触带呼吸微光(挖掘期唯一在动元素——§3.2 v2.8 画法:光画英雄格周界空间侧, -# 正交邻墙=整条边、斜向=共享角点+两侧各半条边;旧"墙格整框绿相"退役 2026-09-26 批) ---- +# 正交邻墙=整条边、斜向=共享角点+两侧各半条边) ---- func set_dig_glow_enabled(on: bool) -> void: _dig_glow = on @@ -865,7 +857,7 @@ func set_dig_glow_enabled(on: bool) -> void: _sync_glow_to_units() # 相位切换 → 类型微光作用集随之增减(只重绘变动格) -# 类型微光作用集与格件同步(迭代 30 卡①):只重绘「上一拍有组/这一拍有组」的并集格, +# 类型微光作用集与格件同步:只重绘「上一拍有组/这一拍有组」的并集格, # 其余格零触碰;与 refresh() 全板重绘互为补充(refresh 走全板,本函数走增量)。 func _sync_glow_to_units() -> void: if _board == null or _minesweeper == null: @@ -932,15 +924,15 @@ func _reset_breath() -> void: _contact_unit.queue_redraw() -# ---- 高墙/地面瓦片接线(2026-09-26 批;词表 = design/research/board-tile-vocab-plan-a-2026-09-26.md) ---- +# ---- 高墙/地面瓦片接线(词表 = design/research/board-tile-vocab-plan-a-2026-09-26.md) ---- # 瓦片整批守卫装载(_init 单次调用):21 枚全成才启用——任一缺位按整批缺位处理(禁同板混渲染; # fresh checkout 无素材目录 → 静默全回退)。缺位不 push_error——可选素材缺位是预期路径非故障 -# (英雄批 load_tex 纪律同款,防冒烟刷屏)。镜像件运行时 flip_x 合成,不出文件。 +# (英雄 load_tex 纪律同款,防冒烟刷屏)。镜像件运行时 flip_x 合成,不出文件。 func _load_board_tiles(board_type: String = "dungeon") -> void: if board_type == "": board_type = "dungeon" - # 16 墙瓦片装载循环节(词表 TILE_WALL_NAMES 单点——T4 杂并:手写 16 条字典项重复退役; + # 16 墙瓦片装载循环节(词表 TILE_WALL_NAMES 单点; # 词表本身被 terrain_tile_sets_test 直读,保留) var t := {} for wall_name in TILE_WALL_NAMES: @@ -956,8 +948,8 @@ func _load_board_tiles(board_type: String = "dungeon") -> void: if tex == null: _request_dungeon_fallback(board_type) return - # 地板归一(圣经 v3.5 冻结①/§1.4 样张 v3 记录——已开格底归一世界底层档 L≈0.10,带 0.08–0.14): - # 方向稿 _v3_darken_floors 同式移植;现行瓦片 L≈0.036 低于带下沿故实为提亮;素材重产归资产批, + # 地板归一(圣经 v3.5 冻结①/§1.4——已开格底归一世界底层档 L≈0.10,带 0.08–0.14): + # 方向稿 _v3_darken_floors 同式移植;现行瓦片 L≈0.036 低于带下沿故实为提亮; # 本归一为程序代役(逐批装载时对 freshly-loaded 原图测光,幂等)。归一后逐像素明度顺路采集, # 驱动数字墨族按板自适应(_digit_ink_mode——均值分位同源同像素,禁二次解码) var lumas: Array[Variant] = [] @@ -979,11 +971,11 @@ func _load_board_tiles(board_type: String = "dungeon") -> void: _floor_tiles = floors _tiles_board_type = board_type _tiles_ok = true - # 封印印记纹理(迭代 9 卡⑬——独立可选件:缺盘=字形回退,不触发瓦片整批回落语义) + # 封印印记纹理(独立可选件:缺盘=字形回退,不触发瓦片整批回落语义) _seal_tex = UiKit.load_tex(TILE_SEAL_MARK) -# 整批回落(T6 换色批):请求套缺位 → 回落 dungeon 套(禁同板混渲染);dungeon 本身缺位 = +# 整批回落:请求套缺位 → 回落 dungeon 套(禁同板混渲染);dungeon 本身缺位 = # 维持程序化平色回退原语义(_tiles_ok 恒 false,缺位不刷屏纪律不变) func _request_dungeon_fallback(requested: String) -> void: if requested != "dungeon": @@ -1000,7 +992,7 @@ static func _flip_tex(tex: Texture2D) -> Texture2D: return ImageTexture.create_from_image(img) -# 地板瓦片明度归一(v3.5 批 B1——方向稿 _v3_darken_floors 同式移植):8×8 双线性重采样均值测光 +# 地板瓦片明度归一(方向稿 _v3_darken_floors 同式移植):8×8 双线性重采样均值测光 # (sRGB→线性域,Rec.709 系数),增益 k=(目标/实测)^(1/2.2) 钳 [0.6,1.8],逐通道 sRGB 域线性拉伸。 # 输入恒为 freshly-loaded 原图(load_tex 每次盘读)——幂等可重入;32×32 五变体开销可忽略 static func _normalize_floor_luma(tex: Texture2D, target_l: float = 0.10, lumas_out = null) -> Texture2D: @@ -1033,17 +1025,17 @@ static func _srgb_lin(c: float) -> float: return c / 12.92 if c <= 0.04045 else pow((c + 0.055) / 1.055, 2.4) -# ---- 数字墨族按板自适应(L2/L3 亮瓦融字缺陷修复 2026-10-01——甲案:墨色按关自适应+三关对比断言)---- +# ---- 数字墨族按板自适应(墨色按关自适应+三关对比断言)---- const DIGIT_INK_CR_P90 := 4.5 # 墨族对地板 p90 亮斑对比度门槛(失效模式=亮白筋纹冲字,WCAG 数字体同源) const DIGIT_INK_CR_MEAN_BRIGHT := 2.5 # 亮族对地板均值门槛(中调防吃字) -const DIGIT_INK_CR_MEAN_DARK := 3.0 # 深族对地板均值门槛(大字 AA 级——2.4 的实测观感=隐形,v3.4 收紧) +const DIGIT_INK_CR_MEAN_DARK := 3.0 # 深族对地板均值门槛(大字 AA 级——2.4 的实测观感=隐形) # 归一后地板逐像素明度 → 选数字呈现模式。三态:亮族直画(暗纹理板)/深族直画(中暗板)/ -# 色牌垫底(双峰纹理板——近黑斑与近白筋并存时任何墨族直画必融一峰,2026-10-01 渲染帧取证 +# 色牌垫底(双峰纹理板——近黑斑与近白筋并存时任何墨族直画必融一峰,渲染帧取证 # 实证 underdark 系深墨隐形,牌上深墨 12:1 纹理免疫)。家族最弱成员(亮族=金亮/深族=锈墨) # 对 p90 与均值双门槛;亮族过选亮族,否则深族(均值门 3.0),两族皆不过落牌。 -# 实测(2026-10-01):dungeon p90=0.121 亮族 4.79/5.80 ✓ 直画;underdark p90=0.406 亮族 ✗、 +# 实测:dungeon p90=0.121 亮族 4.79/5.80 ✓ 直画;underdark p90=0.406 亮族 ✗、 # 深族 5.34/**2.41**(均值 <3.0 ✗)→ 落牌;deep_underdark 同→落牌 static func _digit_ink_mode(lumas: Array) -> Dictionary: var sorted := lumas.duplicate() @@ -1092,7 +1084,7 @@ static func _cell_hash(c: Vector2i) -> int: return h ^ (h >> 16) -# 四正交邻墙判定(词表 §三.1:板外视为墙;未开格=墙、已开格=地板——用户世界观口径「未开=墙、 +# 四正交邻墙判定(词表 §三.1:板外视为墙;未开格=墙、已开格=地板——世界观口径「未开=墙、 # 已开=挖出的空间」)。唯一调用面 _paint_cell(refresh 对 _minesweeper 非空守卫在先) func _is_wall(c: Vector2i) -> bool: if c.x < 0 or c.y < 0 or c.x >= _board.width or c.y >= _board.height: @@ -1140,7 +1132,7 @@ func _wall_tile_for(c: Vector2i) -> Texture2D: # 四邻皆墙格:对角凹角优先 nw > ne > sw > se(词表 §三.2——双凹角不做专件,多对角地板回落 -# 首中单凹角件,残留 1px 缝为已裁决可接受限);无对角地板 → 中心三变体按格坐标哈希 60/20/20 +# 首中单凹角件,残留 1px 缝为可接受限);无对角地板 → 中心三变体按格坐标哈希 60/20/20 func _wall_center_tile(c: Vector2i) -> Texture2D: if not _is_wall(c + Vector2i(-1, -1)): return _tiles["wall_in_nw"] # 西北对角是地板 @@ -1182,7 +1174,7 @@ func _make_cursor_texture(glyph: String) -> ImageTexture: return ImageTexture.create_from_image(img) -# ---- 探针只读出口(D2 改造 2026-10-04——_cells/_diggable 私有容器直入退役;形态仿 fx_probe 先例:只读快照) ---- +# ---- 探针只读出口(形态仿 fx_probe 先例:只读快照) ---- # 格件映射只读快照(Vector2i → CellUnit;键面同构——断言语义零变化;破私有面的只是容器字典, # 格件字段本为公有呈现面,快照值即原格件引用) @@ -1195,22 +1187,22 @@ func diggable_probe() -> Dictionary: return _diggable.duplicate() -# 悬停格只读出口(case① 悬停到达断言消费面——_hover 私有域直入退役,D2 清单外同类项随批收口) +# 悬停格只读出口(case① 悬停到达断言消费面) func hover_probe() -> Vector2i: return _hover -# 迷雾参数只读快照(case⑮ 参数漂移断言消费面——_fog_lantern/_fog_enabled 私有域直入退役,D2 清单外同类项随批收口) +# 迷雾参数只读快照(case⑮ 参数漂移断言消费面) func fog_params_probe() -> Dictionary: return {"lantern": _fog_lantern, "enabled": _fog_enabled} -# 类型微光只读快照(迭代 30 卡① 断言消费面——开关态/作用集与组号/清单外 cell_type 登记) +# 类型微光只读快照(断言消费面——开关态/作用集与组号/清单外 cell_type 登记) func type_glow_probe() -> Dictionary: return {"enabled": _type_glow, "cells": _glow.duplicate(), "errors": _glow_errors.duplicate()} -# 格件全局矩形只读出口(迭代 30 卡① 像素侧取样坐标源——禁测试侧硬编码像素;私有 _cells 直入退役) +# 格件全局矩形只读出口(像素侧取样坐标源——禁测试侧硬编码像素) # 坐标系:格件居于 SubViewport 内(_world 于原点),global_position 是**子视口画布**坐标; # 取证帧截的是窗口画面 ⇒ 必须经 SubViewportContainer 的全局矩形换算回窗口坐标 # (stretch 恒 1:1,仍按 host/vp 比例换算保稳健——容器中心化由 CenterContainer 驱动)。 diff --git a/game/presentation/views/board_world.gd b/game/presentation/views/board_world.gd index b5ebc7e3..d3eaa73f 100644 --- a/game/presentation/views/board_world.gd +++ b/game/presentation/views/board_world.gd @@ -3,8 +3,8 @@ ## 无 class_name——使用方经 preload 引用。 extends Node2D -var board_font: Font = null # 字体注入槽位(null = ThemeDB.fallback_font——与旧 Button 缺省主题字体同源) -var hero: Sprite2D = null # 英雄单位精灵(棋盘小人贴图批 2026-09-25——移动实体独立于 CellUnit 格面 +var board_font: Font = null # 字体注入槽位(null = ThemeDB.fallback_font) +var hero: Sprite2D = null # 英雄单位精灵(移动实体独立于 CellUnit 格面 # 语义,计划书 §3.A;null = 未创建/随 rebuild 清场,BoardView.refresh 经 # ensure_hero 重建。texture 缺位时 BoardView 不调本方法=字形「人」回退路径) @@ -12,8 +12,8 @@ var hero: Sprite2D = null # 英雄单位精灵(棋盘小人贴图批 2026- # 英雄精灵惰性创建(幂等):脚底锚(offset 上移半高——scale.y 弹跳向脚底收敛不悬空)+ z_index=1 # 压格面之上(挥铲特效在 SubViewport 之外恒更上层,满足「格面之上、特效之下」叠序);NEAREST = # SubViewport 缩放下像素清晰(默认 Linear 会糊);use_parent_material = 随世界去饱和材质灰化 -#(结算期与 CellUnit 同口径——基批漏挂,本批补齐)。返回值便于 BoardView 即时落位。 -# 脚下椭圆影(2026-09-26 用户裁决走 Godot 组件合成、贴图零改动):径向渐变纹理 ×黑色半透明 +#(结算期与 CellUnit 同口径)。返回值便于 BoardView 即时落位。 +# 脚下椭圆影(走 Godot 组件合成、贴图零改动):径向渐变纹理 ×黑色半透明 # modulate 压扁,挂英雄子件(z_index=-1 相对回落格面之上、英雄之下——位移/翻转/弹跳随父件 # 同步免费拿;尺寸换算归 BoardView.HERO_SHADOW_PX 常量)。纹理 filter 用 LINEAR 保渐变平滑 #(NEAREST 会把渐变打回条带)。 @@ -35,16 +35,15 @@ func ensure_hero(tex: Texture2D, shadow_px: Vector2, scale: float) -> Sprite2D: shadow.modulate = Color(0, 0, 0, 0.35) shadow.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR shadow.scale = shadow_px / (64.0 * scale) # 子件缩放叠父件 scale——目标屏幕尺寸 ÷ (纹理边 × 父档) - shadow.position = Vector2.ZERO # 椭圆中心 = 脚锚点(贴脚——上批 (0,2) 下坠让影子与脚脱开,用户报缺陷) + shadow.position = Vector2.ZERO # 椭圆中心 = 脚锚点(贴脚) shadow.z_index = -1 # 相对父件回落:格面(z=0 树序在先)之上、英雄本体之下 shadow.use_parent_material = true # 随英雄链世界去饱和材质 hero = Sprite2D.new() hero.texture = tex hero.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST hero.centered = true - # 脚浮修正(2026-09-26,样张预筛发现+用户实机确认的登记缺陷——台账 169/175 移交):素材底部 7 行全透明 - #(内容底 = 源 row 24,自中心 16-7.5=8.5px),旧 offset -16 按纹理底=内容底假设成立时脚悬空 8.5×1.5≈12.75px; - # 修正 offset.y = -8.5 → 内容底恰落 position(脚锚=格底往上 25% 线,台账 162 口径——头仍越上格沿) + # 脚底对齐:素材底部 7 行全透明(内容底 = 源 row 24,自中心 16−7.5=8.5px),故 offset.y = −8.5 + # → 内容底恰落 position(脚锚=格底往上 25% 线——头仍越上格沿) hero.offset = Vector2(0.0, -8.5) # 纹理中心上移 8.5 源 px——position = 视觉脚底中点 hero.z_index = 1 hero.use_parent_material = true @@ -52,7 +51,7 @@ func ensure_hero(tex: Texture2D, shadow_px: Vector2, scale: float) -> Sprite2D: hero.add_child(shadow) return hero -# ── 立体悬崖(BoardView.set_cell_area / _update_world_size 单点驱动;厚度定稿 8px=中档 2026-09-24)── +# ── 立体悬崖(BoardView.set_cell_area / _update_world_size 单点驱动;厚度 8px=中档)── var depth_px := 0.0: # 悬崖厚度(像素;0 = 平面) set(v): depth_px = v @@ -69,7 +68,7 @@ var cols := 0: # 列数(正面悬崖竖缝数 = cols−1) set(v): cols = v queue_redraw() -var mat: Color = UiKit.BRICK # 材质锚色(掩尘 #C9AF83 与 UiKit.BRICK 同值——T4 裸色收口改引单点;侧面由此派生明暗,BoardView 传入可覆写) +var mat: Color = UiKit.BRICK # 材质锚色(掩尘 #C9AF83 与 UiKit.BRICK 同值;侧面由此派生明暗,BoardView 传入可覆写) func _draw() -> void: diff --git a/game/presentation/views/board_zone_view.gd b/game/presentation/views/board_zone_view.gd index f07774b9..4c2d6861 100644 --- a/game/presentation/views/board_zone_view.gd +++ b/game/presentation/views/board_zone_view.gd @@ -8,7 +8,7 @@ var board_view: BoardView var toast: ToastStack var fx: BoardFxView var status_badge: Button # 状态面板入口角标(迭代 17 卡③ P1 丁;连接归组合根) -var _board_area: Control # resized 命名转发用(原 lambda 局部捕获——P1-3 转命名 2026-09-29) +var _board_area: Control # resized 命名转发用(勿回退为 lambda 局部捕获) signal action_requested(cell: Vector2i, kind: String) signal stop_pressed @@ -38,7 +38,7 @@ func _init() -> void: board_area.add_child(fx) toast = ToastStack.new() board_area.add_child(toast) - # 状态角标(迭代 17 卡③ P1 丁——右下角常驻;2026-10-16 调试角标迁全局浮层后本屏只留状态): + # 状态角标(右下角常驻;调试角标已迁全局浮层,本屏只留状态): # 17卡③同形制:紧凑钮豁免宽度基准+字号降档。可见性/置灰归组合根 _sync_status_entry #(其他模态开着=置灰不可点——排除式开态查询);信号连接归组合根。 # 全局调试浮层角标常驻右下角 16px(main 直接子层、ModalStack 登记外——任何 UI 不遮挡), diff --git a/game/presentation/views/camp_overlay_view.gd b/game/presentation/views/camp_overlay_view.gd index 41798e45..e039b033 100644 --- a/game/presentation/views/camp_overlay_view.gd +++ b/game/presentation/views/camp_overlay_view.gd @@ -7,14 +7,14 @@ extends Control signal buy_requested(attr: String) signal closed -signal attune_toggled(item_id: String) # 同调装配切换意图(迭代 11 第①批 T4——写口唯一归 MetaProgression.toggle_attunement) -signal tree_buy_requested(node_id: String) # 天赋树购买意图(迭代 12 T9——写口唯一归 MetaProgression.tree_buy) +signal attune_toggled(item_id: String) # 同调装配切换意图(写口唯一归 MetaProgression.toggle_attunement) +signal tree_buy_requested(node_id: String) # 天赋树购买意图(写口唯一归 MetaProgression.tree_buy) signal tree_fork_toggled(group: String, side: String) # 双态切换意图(一节点双态——零币切态) -signal forge_buy_requested(route_id: String) # 锻造路线购买意图(迭代 23 T6——写口唯一归 MetaProgression.forge_buy_level) -signal forge_unlock_requested(route_id: String) # 锻造路线解锁意图(迭代 23 T6——写口唯一归 MetaProgression.forge_buy_unlock) -signal forge_select_requested(route_id: String) # 锻造路线选中意图(迭代 23 T6——写口唯一归 MetaProgression.forge_select_weapon/armor) +signal forge_buy_requested(route_id: String) # 锻造路线购买意图(写口唯一归 MetaProgression.forge_buy_level) +signal forge_unlock_requested(route_id: String) # 锻造路线解锁意图(写口唯一归 MetaProgression.forge_buy_unlock) +signal forge_select_requested(route_id: String) # 锻造路线选中意图(写口唯一归 MetaProgression.forge_select_weapon/armor) -# 方向稿取色(柜台头带深棕/行板暖米;双色墨=亮板配深墨)——值单点收 UiKit(T4 裸色收口批) +# 方向稿取色(柜台头带深棕/行板暖米;双色墨=亮板配深墨)——值单点收 UiKit const HEADER_BAND_COL := UiKit.CAMP_HEADER_BAND const ROW_PLATE_COL := UiKit.CAMP_ROW_PLATE @@ -23,28 +23,27 @@ var _tree_holder: VBoxContainer # 树淬炼柜台内容(主界面—— var _tree_buy_btns: Array[Dictionary] = [] # [{node_id, btn}]——树购买/解锁钮登记面(open/refresh 重建时刷新;探针消费) var _tree_fork_btns: Array[Dictionary] = [] # [{group, side, btn}]——Fork 双态切换钮登记面(探针消费) var _forge_lock_l: Label # 锻造工坊柜台锁定态行(钥匙未点亮) -var _forge_workbench: VBoxContainer # 锻造工坊工作间(钥匙点亮后展开——两区六路线行板,迭代 23 T6 实装) +var _forge_workbench: VBoxContainer # 锻造工坊工作间(钥匙点亮后展开——两区六路线行板) var _forge_zone_weapon: VBoxContainer # 武器锻造区行板容器(三路线) var _forge_zone_armor: VBoxContainer # 护甲锻造区行板容器(三路线) var _forge_rows: Array[Dictionary] = [] # [{route_id, name_l, lvl_l, status_l, buy_btn, unlock_btn, select_btn, next_price, unlock_price}](open/refresh 重建;探针消费) var _ws_scroll: ScrollContainer # 秘宝匣柜台内容容器(钥匙点亮后可见) var _ws_lock_l: Label # 秘宝匣柜台锁定态行 -var _workshop_holder: VBoxContainer # 秘宝匣柜台行板(六行+同调装配段+Y 升级行——迭代 11 第①批 T4 结构随迁) +var _workshop_holder: VBoxContainer # 秘宝匣柜台行板(六行+同调装配段+Y 升级行) var _workshop_rows: Array[Dictionary] = [] # [{item_id, progress_l, status_l}] var _attune_header_l: Label # 同调装配段(Slots 点亮呈现) var _attune_btns: Array[Dictionary] = [] # [{item_id, btn}]——装配/卸下切换钮(满位禁选随刷) var _attune_nodes: Array[Control] = [] # 段内节点册(open_camp 重建时定向清理,不扰工坊六行) -var _refresh_l: Label # Y 刷新升级行(双入口之一——树上 ks_refresh 同账 Q1 裁乙) +var _refresh_l: Label # Y 刷新升级行(双入口之一——树上 ks_refresh 同账) var _refresh_btn: Button var _recent_list: Label # 最近冒险(逐行拼接 label——只读账面,随 open_camp 重建) func _init() -> void: - # 底=不透明暖亮档(2026-10-06 用户实测缺陷修——原形制=0.45 半透 dim+满铺石纹遮底,T5 石纹降 0.14 - # 后底下屏幕透出〔用户实机:对局中开营地见棋盘/战斗提示条〕;demo #v-camp=bg-bright 实底, + # 底=不透明暖亮档(半透 dim 会透出底下棋盘/战斗提示条,故须实底;demo #v-camp=bg-bright 实底, # 遮蔽语义由组合根输入锁兜底) var dim := UiKit.modal_dim(self, UiKit.BG_BRIGHT) - # 石纹弱质感+暗角(UI 对齐批 T5 2026-10-06——demo .tilebg 0.14/.vignette;缺位不挂即回退平色) + # 石纹弱质感+暗角(demo .tilebg 0.14/.vignette;缺位不挂即回退平色) var bd := UiKit.backdrop_tile() if bd != null: dim.add_child(bd) @@ -73,17 +72,17 @@ func _init() -> void: plaque.add_child(plaque_col) var title := UiKit.label("营地 · 天赋树",UiKit.FS_TITLE, true, UiKit.INK_TITLE) plaque_col.add_child(title) - var sub := UiKit.label("营地本身即树——钥石逐节点点亮,属性/规则/工作间都在树上",UiKit.FS_HINT, false, UiKit.STONE_DEEP) # 尾裁微批a 2026-10-08——STONE 对铭牌板 3.59:1 越带,换灰石深化 5.98:1 + var sub := UiKit.label("营地本身即树——钥石逐节点点亮,属性/规则/工作间都在树上",UiKit.FS_HINT, false, UiKit.STONE_DEEP) # STONE 对铭牌板 3.59:1 越带,换灰石深化 5.98:1 plaque_col.add_child(sub) var spacer := Control.new() spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL top.add_child(spacer) - # M3(UI 落码批):钥石徽章烛光黄底+深墨字(demo ②)。Q10 甲(2026-10-06):UiKit.keystone_badge 工厂单点 + # 钥石徽章烛光黄底+深墨字(demo ②)。UiKit.keystone_badge 工厂单点 var badge := UiKit.keystone_badge("钥石 0") top.add_child(badge) _balance_label = badge.value_label - # ── 四柜台并排(A② 裁——迭代 21 T6 程序占位重排,视觉终稿归 HUD 营地视觉批)── + # ── 四柜台并排(程序占位重排)── # 宽度不足横向滚动(四柜 300 min 宽 > 窄窗可用宽时横滚兜底;纵向撑满余高) var camp_scroll := ScrollContainer.new() camp_scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL @@ -105,22 +104,22 @@ func _init() -> void: tree_scroll.add_child(_tree_holder) var tree_panel := _counter_panel("天赋树 · 淬炼", "", tree_scroll, 300) tree_panel.size_flags_horizontal = Control.SIZE_EXPAND_FILL - tree_panel.size_flags_vertical = Control.SIZE_FILL # 迭代 26 T5③ 四栏等高:任一栏长高时四栏同步拉伸 + tree_panel.size_flags_vertical = Control.SIZE_FILL # 四栏等高:任一栏长高时四栏同步拉伸 mid.add_child(tree_panel) - # 柜二·锻造工坊(钥匙门——forge_workshop 点亮前锁定态;点亮=工作间两区六路线行板,迭代 23 T6 实装) + # 柜二·锻造工坊(钥匙门——forge_workshop 点亮前锁定态;点亮=工作间两区六路线行板) _forge_lock_l = UiKit.label("🔒 锻造工坊未开放\n\n点亮树上「锻造工坊」钥匙节点后展开工作间。\n(钥匙免费、无前置——树上直接点亮)",UiKit.FS_HINT, false, UiKit.STONE_DEEP) - _forge_lock_l.size_flags_vertical = Control.SIZE_SHRINK_CENTER # 迭代 26 T5③ 锁文在等高栏内垂直居中 + _forge_lock_l.size_flags_vertical = Control.SIZE_SHRINK_CENTER # 锁文在等高栏内垂直居中 _forge_lock_l.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART _forge_lock_l.custom_minimum_size = Vector2(280, 0) _forge_workbench = VBoxContainer.new() _forge_workbench.add_theme_constant_override("separation", 6) - _forge_workbench.visible = false # 默认锁定态(钥匙门未判前零行板——门开才建,迭代 23 T6 占位纪律延续) + _forge_workbench.visible = false # 默认锁定态(钥匙门未判前零行板——门开才建) _forge_zone_weapon = VBoxContainer.new() _forge_zone_weapon.add_theme_constant_override("separation", 4) _forge_zone_armor = VBoxContainer.new() _forge_zone_armor.add_theme_constant_override("separation", 4) - var wb_wh := UiKit.label("── 武器锻造区 ──",UiKit.FS_HINT, true, UiKit.GOLD_INK) # 尾裁微批a 同款深金墨(对柜台板 5.21:1) + var wb_wh := UiKit.label("── 武器锻造区 ──",UiKit.FS_HINT, true, UiKit.GOLD_INK) # 同款深金墨(对柜台板 5.21:1) _forge_workbench.add_child(wb_wh) _forge_workbench.add_child(_forge_zone_weapon) var wb_ah := UiKit.label("── 护甲锻造区 ──",UiKit.FS_HINT, true, UiKit.GOLD_INK) @@ -128,17 +127,17 @@ func _init() -> void: _forge_workbench.add_child(_forge_zone_armor) var forge_holder := VBoxContainer.new() forge_holder.add_theme_constant_override("separation", 6) - forge_holder.custom_minimum_size = Vector2(0, 336) # 迭代 26 T5③ 四栏等高(与树/秘宝匣 scroll 336 min 对齐——锁定态仅锁文也撑住栏高) + forge_holder.custom_minimum_size = Vector2(0, 336) # 四栏等高(与树/秘宝匣 scroll 336 min 对齐——锁定态仅锁文也撑住栏高) forge_holder.add_child(_forge_lock_l) forge_holder.add_child(_forge_workbench) var forge_panel := _counter_panel("锻造工坊", UiKit.TEX_ICON_FORGE, forge_holder, 300) forge_panel.size_flags_horizontal = Control.SIZE_EXPAND_FILL - forge_panel.size_flags_vertical = Control.SIZE_FILL # T5③ 四栏等高:任一栏长高时四栏同步拉伸 + forge_panel.size_flags_vertical = Control.SIZE_FILL # 四栏等高:任一栏长高时四栏同步拉伸 mid.add_child(forge_panel) # 柜三·秘宝匣(钥匙门——ks_workshop 点亮前锁定态;点亮=现工坊内容整体迁入:六行+同调装配段+Y 升级行) _ws_lock_l = UiKit.label("🔒 秘宝匣未开放\n\n点亮树上「秘宝匣」钥匙节点后展开。\n(前置=脊柱生命第 1 级)",UiKit.FS_HINT, false, UiKit.STONE_DEEP) - _ws_lock_l.size_flags_vertical = Control.SIZE_SHRINK_CENTER # 迭代 26 T5③ 锁文在等高栏内垂直居中 + _ws_lock_l.size_flags_vertical = Control.SIZE_SHRINK_CENTER # 锁文在等高栏内垂直居中 _ws_lock_l.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART _ws_lock_l.custom_minimum_size = Vector2(280, 0) _ws_scroll = ScrollContainer.new() @@ -150,23 +149,23 @@ func _init() -> void: _ws_scroll.add_child(_workshop_holder) var ws_holder := VBoxContainer.new() ws_holder.add_theme_constant_override("separation", 6) - ws_holder.custom_minimum_size = Vector2(0, 336) # 迭代 26 T5③ 四栏等高(锁定态 scroll 隐、仅锁文也撑住栏高) + ws_holder.custom_minimum_size = Vector2(0, 336) # 四栏等高(锁定态 scroll 隐、仅锁文也撑住栏高) ws_holder.add_child(_ws_lock_l) ws_holder.add_child(_ws_scroll) var ws_panel := _counter_panel("秘宝匣", UiKit.TEX_ICON_WORKSHOP, ws_holder, 300) ws_panel.size_flags_horizontal = Control.SIZE_EXPAND_FILL - ws_panel.size_flags_vertical = Control.SIZE_FILL # T5③ 四栏等高:任一栏长高时四栏同步拉伸 + ws_panel.size_flags_vertical = Control.SIZE_FILL # 四栏等高:任一栏长高时四栏同步拉伸 mid.add_child(ws_panel) # 柜四·奖励格图鉴(常开独立位——结构位预留,内容排 Alpha) var atlas_holder := VBoxContainer.new() - atlas_holder.custom_minimum_size = Vector2(0, 336) # 迭代 26 T5③ 四栏等高(图鉴仅锁文也撑住栏高) + atlas_holder.custom_minimum_size = Vector2(0, 336) # 四栏等高(图鉴仅锁文也撑住栏高) var atlas_panel := _counter_panel("奖励格图鉴", UiKit.TEX_ICON_ATLAS, atlas_holder, 300) atlas_panel.size_flags_horizontal = Control.SIZE_EXPAND_FILL - atlas_panel.size_flags_vertical = Control.SIZE_FILL # T5③ 四栏等高:任一栏长高时四栏同步拉伸 + atlas_panel.size_flags_vertical = Control.SIZE_FILL # 四栏等高:任一栏长高时四栏同步拉伸 mid.add_child(atlas_panel) var lock_l := UiKit.label(" —— 柜台结构位预留:内容排 Alpha(地图战斗资源差异化批)",UiKit.FS_HINT, false, UiKit.STONE) - lock_l.size_flags_vertical = Control.SIZE_SHRINK_CENTER # 迭代 26 T5③ 锁文在等高栏内垂直居中 + lock_l.size_flags_vertical = Control.SIZE_SHRINK_CENTER # 锁文在等高栏内垂直居中 lock_l.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART lock_l.custom_minimum_size = Vector2(280, 0) atlas_holder.add_child(lock_l) @@ -206,7 +205,7 @@ func _counter_panel(title_text: String, icon_path: String, holder: Control, min_ head.add_theme_constant_override("separation", 6) band.add_child(head) if icon_path != "": - var ic := UiKit.icon_rect(icon_path, 32) # P6 甲②(2026-10-06):柜台头带 64 源 0.5×;缺位 null → 纯文本回退 + var ic := UiKit.icon_rect(icon_path, 32) # 柜台头带 64 源 0.5×;缺位 null → 纯文本回退 if ic != null: head.add_child(ic) var l := UiKit.label(title_text,UiKit.FS_BODY, true, UiKit.WARM) @@ -217,7 +216,7 @@ func _counter_panel(title_text: String, icon_path: String, holder: Control, min_ # ---- 柜台行构建(open_camp 重建;行结构仿 ShopOverlay 商品卡——亮板双色墨制)---- -# 天赋树段重建(迭代 21 T6——树淬炼柜台主界面:脉分组行板:节点名/等级/价/购买钮 + Fork 双态切换钮; +# 天赋树段重建(树淬炼柜台主界面:脉分组行板:节点名/等级/价/购买钮 + Fork 双态切换钮; # 树数据 = 组合根 _camp_data().tree 投影 [{node_id, display_name, vein, kind, level, price, can_buy, # currency}...] + fork_groups [{group, node_id, active_side, owned, can_buy, price, sides:[{side, display_name, effects}]}]) func _rebuild_tree(data: Dictionary) -> void: @@ -233,7 +232,7 @@ func _rebuild_tree(data: Dictionary) -> void: var vein := String(row.get("vein", "")) if vein != last_vein: last_vein = vein - var vh := UiKit.label(String(vein_names.get(vein, vein)),UiKit.FS_HINT, true, UiKit.GOLD_INK) # 尾裁微批a 2026-10-08——GOLD_DEEP 对柜台板 2.67:1 越带,换深金墨 5.21:1 + var vh := UiKit.label(String(vein_names.get(vein, vein)),UiKit.FS_HINT, true, UiKit.GOLD_INK) # GOLD_DEEP 对柜台板 2.67:1 越带,换深金墨 5.21:1 _tree_holder.add_child(vh) var hb := HBoxContainer.new() hb.add_theme_constant_override("separation", 6) @@ -249,7 +248,7 @@ func _rebuild_tree(data: Dictionary) -> void: hb.add_child(name_l) if String(row.get("kind", "")) == "fork": continue # Fork 行去行板化——由 fork_groups 段承载双态切换钮 - var btn := UiKit.button("购买 %d 钥石" % int(row.get("price", 0)), 0.0) # 柜台行板紧凑钮豁免宽度基准(树全钥石单币 2026-10-07 裁甲) + var btn := UiKit.button("购买 %d 钥石" % int(row.get("price", 0)), 0.0) # 柜台行板紧凑钮豁免宽度基准 btn.pressed.connect(func(): tree_buy_requested.emit(String(row.get("node_id", "")))) btn.disabled = not bool(row.get("can_buy", false)) hb.add_child(btn) @@ -282,7 +281,7 @@ func _rebuild_tree(data: Dictionary) -> void: _tree_holder.add_child(fb) -# 工作间钥匙门(迭代 21 T6——锻造工坊/秘宝匣柜台锁定态切换:节点点亮=展开、未点亮=锁定行; +# 工作间钥匙门(锻造工坊/秘宝匣柜台锁定态切换:节点点亮=展开、未点亮=锁定行; # 图鉴常开无门槛。判据读树投影行 level——零核心访问,纯视图) func _refresh_key_gates(data: Dictionary) -> void: var lvl_by_id := {} @@ -296,7 +295,7 @@ func _refresh_key_gates(data: Dictionary) -> void: _ws_scroll.visible = ws_open -# 锻造工坊行板重建(迭代 23 T6——两区六路线;open_camp/refresh_camp 调用。行结构仿秘宝匣行板: +# 锻造工坊行板重建(两区六路线;open_camp/refresh_camp 调用。行结构仿秘宝匣行板: # 件名+等级+解锁态+购买/解锁/选中钮。UI 只发意图信号〔契约 9——零核心写调用、零 MetaProgression # 持有〕;钮禁用=常态防线(余额/未解锁/满级/已选中),兜底拒绝可见归 presenter pattern 1) func _rebuild_forge(data: Dictionary) -> void: @@ -305,7 +304,7 @@ func _rebuild_forge(data: Dictionary) -> void: c.queue_free() _forge_rows.clear() if not _forge_workbench.visible: - return # 锁定态(钥匙未点亮):零行板零购买路径——占位纪律延续(2026-10-11 用户令) + return # 锁定态(钥匙未点亮):零行板零购买路径——占位纪律延续 var bal := int(data.get("balance", 0)) for row in data.get("forge", []): var rid := String(row.get("route_id", "")) @@ -376,7 +375,7 @@ func _rebuild_forge(data: Dictionary) -> void: # 数据 = 组合根 _camp_data() 投影) func open_camp(data: Dictionary) -> void: _rebuild_workshop(data) # 段尾链 _rebuild_attune(同调装配段+Y 升级行随秘宝匣柜台内容) - _rebuild_forge(data) # 迭代 23 T6——锻造工坊两区六路线行板 + _rebuild_forge(data) # 锻造工坊两区六路线行板 _rebuild_recent(data) refresh_camp(data) visible = true @@ -389,7 +388,7 @@ func refresh_camp(data: Dictionary) -> void: _balance_label.text = "钥石 %d" % balance _rebuild_tree(data) _refresh_key_gates(data) - _rebuild_forge(data) # 迭代 23 T6——行板随刷重建(购买/解锁/选中后等级/价/禁用态同步) + _rebuild_forge(data) # 行板随刷重建(购买/解锁/选中后等级/价/禁用态同步) var ws_by_id := {} for row in data.get("workshop", []): ws_by_id[String(row.get("item_id", ""))] = row @@ -398,8 +397,7 @@ func refresh_camp(data: Dictionary) -> void: if row.is_empty(): continue var unlocked := bool(row.get("unlocked", false)) - # 秘宝匣进度列(迭代 22 T2——解锁混合制三形态:钥石购买价/条件进度拼接/已入手; - # 旧「累计通关 N/M 次」单一渠道文案随工坊行族退役) + # 秘宝匣进度列(解锁混合制三形态:钥石购买价/条件进度拼接/已入手) var prog_text := "" var mode := String(row.get("mode", "")) if unlocked: @@ -414,19 +412,19 @@ func refresh_camp(data: Dictionary) -> void: parts.append("%s %d/%d" % [lbl, int(req.get("progress", 0)), int(req.get("threshold", 0))]) prog_text = "、".join(parts) card.progress_l.text = prog_text - # 状态色随卡⑭ 亮板双色墨制(深墨族替代暖白族——亮板上暖白不可读);失义/退役行随新目录退役 + # 状态色用亮板双色墨制(深墨族替代暖白族——亮板上暖白不可读) var st_text := "未解锁" var st_col: Color = UiKit.STONE if unlocked: st_text = "已解锁" - st_col = UiKit.GOLD_INK # 尾裁微批a 2026-10-08——GOLD_DEEP 对行板 3.00:1 越带,换深金墨 5.84:1 + st_col = UiKit.GOLD_INK # GOLD_DEEP 对行板 3.00:1 越带,换深金墨 5.84:1 card.status_l.text = st_text card.status_l.add_theme_color_override("font_color", st_col) card.status_l.tooltip_text = st_text # 截断兜底(状态列 EXPAND_FILL 吸余宽——悬停看全文) - # 购买钮余额联动(迭代 22 秘宝批 T4——禁用态=余额不足,常态防线;pattern 1 兜底拒绝可见归 presenter) + # 购买钮余额联动(禁用态=余额不足,常态防线;pattern 1 兜底拒绝可见归 presenter) if card.get("buy_btn") != null: card.buy_btn.disabled = balance < int(card.get("price", 0)) - # 同调装配段状态就地刷(迭代 11 第①批 T4——Slots 点亮/满位禁选/Y 升级行余额联动) + # 同调装配段状态就地刷(Slots 点亮/满位禁选/Y 升级行余额联动) var att: Dictionary[Variant, Variant] = data.get("attune", {}) if _attune_header_l != null: var slots_n := int(att.get("slots", 0)) @@ -438,7 +436,7 @@ func refresh_camp(data: Dictionary) -> void: for card2 in _attune_btns: var on: bool = eq_set.has(String(card2.item_id)) card2.btn.text = "卸下" if on else "装配" - # 满位禁选+未解锁禁装(迭代 22 T4——已装件恒可卸下;unlocked 快照随 rebuild 刷新) + # 满位禁选+未解锁禁装(已装件恒可卸下;unlocked 快照随 rebuild 刷新) card2.btn.disabled = (not on and eq.size() >= slots_n) or (not on and not bool(card2.get("unlocked", false))) if _refresh_l != null: var rf: Dictionary[Variant, Variant] = att.get("refresh", {}) @@ -469,18 +467,18 @@ func _rebuild_workshop(data: Dictionary) -> void: name_l.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS name_l.tooltip_text = String(row.get("desc", "")) # 件效果摘要悬停可见(分档呈现契约——槽位档位=名后缀) line.add_child(name_l) - var progress_l := UiKit.label("",UiKit.FS_HINT, false, UiKit.STONE_DEEP) # 尾裁微批a 2026-10-08——同行价格墨同案 + var progress_l := UiKit.label("",UiKit.FS_HINT, false, UiKit.STONE_DEEP) # 同行价格墨同案 progress_l.custom_minimum_size = Vector2(150, 0) progress_l.clip_text = true # 营地溢出修——文字全宽不撑柜 progress_l.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS line.add_child(progress_l) - # 状态色随卡⑭ 亮板双色墨制(深墨族替代暖白族)——色随刷新态条件赋值,非机械两行式(T4 收口保留) + # 状态色用亮板双色墨制(深墨族替代暖白族)——色随刷新态条件赋值,非机械两行式 var status_l := UiKit.label("",UiKit.FS_HINT, true, UiKit.STONE) status_l.clip_text = true # 同上——「已解锁 · 能力封存中」不撑柜(余宽吸收者) status_l.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS status_l.size_flags_horizontal = Control.SIZE_EXPAND_FILL line.add_child(status_l) - # 钥石购买钮(迭代 22 秘宝批 T4——购买件且未解锁时在列;写口唯一=buy_treasure_unlock, + # 钥石购买钮(购买件且未解锁时在列;写口唯一=buy_treasure_unlock, # 经 buy_requested(item_id) 信号走 presenter 分支;禁用态=余额不足) var buy_btn: Button = null if not bool(row.get("unlocked", false)) and String(row.get("mode", "")) == "keystone": @@ -492,7 +490,7 @@ func _rebuild_workshop(data: Dictionary) -> void: _rebuild_attune(data) -# 同调装配段重建(迭代 11 第①批 T4——秘宝匣柜台尾部段〔迭代 21 T6 随柜台迁入〕;Slots 点亮+ +# 同调装配段重建(秘宝匣柜台尾部段;Slots 点亮+ # 九件行板+Y 升级行,程序占位面) func _rebuild_attune(data: Dictionary) -> void: var att: Dictionary[Variant, Variant] = data.get("attune", {}) @@ -511,7 +509,7 @@ func _rebuild_attune(data: Dictionary) -> void: var form_l := UiKit.label("被动" if String(row.get("form", "")) == "passive" else "主动·充能",UiKit.FS_CAPTION, false, UiKit.STONE) form_l.custom_minimum_size = Vector2(58, 0) line.add_child(form_l) - # 档位标签(迭代 22 秘宝批 T4——槽位档位显示:件档=普通/优秀/稀有,装入须件档≤格档契约 2 的呈现半边) + # 档位标签(槽位档位显示:件档=普通/优秀/稀有,装入须件档≤格档契约 2 的呈现半边) var tier_l := UiKit.label(String(UiKit.TREASURE_TIER_LABELS.get(String(row.get("tier", "")), "—")),UiKit.FS_CAPTION, false, UiKit.STONE) tier_l.custom_minimum_size = Vector2(36, 0) line.add_child(tier_l) diff --git a/game/presentation/views/career_overlay.gd b/game/presentation/views/career_overlay.gd index 16ec0211..3b169e8e 100644 --- a/game/presentation/views/career_overlay.gd +++ b/game/presentation/views/career_overlay.gd @@ -44,7 +44,7 @@ func _init() -> void: _boss_first_label = _row(box, "Boss 首杀") _boss_kills_label = _row(box, "Boss 总击杀") - # 组二·资源(钥石余额——终身计数域同段只读投影;账号成长态概览三投影已删——2026-10-12 用户裁) + # 组二·资源(钥石余额——终身计数域同段只读投影;账号成长态概览三投影已退役) _section_head(box, "资源") var bal_row := HBoxContainer.new() bal_row.add_theme_constant_override("separation", 8) diff --git a/game/presentation/views/confirm_dialog.gd b/game/presentation/views/confirm_dialog.gd index a45435ae..a841c4fe 100644 --- a/game/presentation/views/confirm_dialog.gd +++ b/game/presentation/views/confirm_dialog.gd @@ -37,10 +37,9 @@ func open(text: String, confirm_label: String, cancel_label: String = "取消") _text.text = text _confirm_btn.text = confirm_label _cancel_btn.text = cancel_label - # z 序纪律(T3 收口批 2026-10-02):树序由组合根构建序保证——本弹窗在 main._build_ui 尾部 - # add_child(开始层/过场层之后 = 子级最末,登记序 = 树序 = 绘制序恒最上;原诊断转储角落钮随 - # 迭代 26 T5b 退役迁调试浮窗,此处不再经其之后), - # 「每次打开 move_child 运行时自提」创可贴随之删除。 + # z 序纪律:树序由组合根构建序保证——本弹窗在 main._build_ui 尾部 + # add_child(开始层/过场层之后 = 子级最末,登记序 = 树序 = 绘制序恒最上) + visible = true diff --git a/game/presentation/views/curio_pick_overlay.gd b/game/presentation/views/curio_pick_overlay.gd index 526853d3..6e3cd430 100644 --- a/game/presentation/views/curio_pick_overlay.gd +++ b/game/presentation/views/curio_pick_overlay.gd @@ -25,7 +25,7 @@ var _bcards: Array[Variant] = [] # M7 bcard 引用列(sele func _init() -> void: - # T7(UI 设计对齐批 2026-10-06):全屏页形态(demo ⑥ #v-bonus——与商店 T6 同壳 page_shell, + # 全屏页形态(demo ⑥ #v-bonus——与商店 T6 同壳 page_shell, # 根底暗档)——56px 通栏顶条(标题+刷新图标钮/角标)+ 居中入账信息行(GP 汇总行承载)+ # bcard 三竖卡(D1 232×352)+ 底部确认主钮与免费选择注记。差异白名单=免费选择/✓章/无价签。 # 状态机不变:pick→result。M7 同构裁决遗产保留。 @@ -94,7 +94,7 @@ func open_pick(header: String, cards: Array) -> void: var title := lines[0] var desc := "\n".join(lines.slice(1)) if lines.size() > 1 else "" var idl := cid.to_lower() - var band := UiKit.tg_band(idl) # 类型色带单点(N4c 2026-10-06——TG_* 五族同源判定;aoe/blast 归 TG_AOE) + var band := UiKit.tg_band(idl) # 类型色带单点(TG_* 五族同源判定;aoe/blast 归 TG_AOE) # 类型脚注(T7 判官 checkpoint:demo .bcard .src 底部类型行——实机缺=卡下半空底;词=demo 同款) var card := UiKit.bcard(title, desc, band, _icon_for_id(idl), "", _type_label(idl)) card.gui_input.connect(func(ev: InputEvent) -> void: @@ -112,7 +112,7 @@ func open_pick(header: String, cards: Array) -> void: visible = true -# 三选一刷新呈现投喂(2026-10-06 用户令对齐商店 MC-1 同构——free_left=X/Y 免费位余量〔基础 0〕, +# 三选一刷新呈现投喂(对齐商店 MC-1 同构——free_left=X/Y 免费位余量〔基础 0〕, # 免费位用尽转 GP 付费档:gp_cost=本次 GP 刷新价、can_afford=冒险钱包可付;钮常驻选择态,两源皆穷=禁用不隐藏) func set_refresh_display(free_left: int, gp_cost: int, can_afford: bool) -> void: _refresh_allowance = maxi(0, int(free_left)) diff --git a/game/presentation/views/debug_overlay.gd b/game/presentation/views/debug_overlay.gd index d0a54334..cf46d111 100644 --- a/game/presentation/views/debug_overlay.gd +++ b/game/presentation/views/debug_overlay.gd @@ -7,10 +7,10 @@ extends Control signal apply_requested(atk_pct: int, hp_pct: int) # 应用并关闭——加成落表归组合根单一应用路径 signal simulate_requested(count: int) # 批量模拟编排归组合根(表基线复位 + 单路径施加) signal debug_levels_requested # 两层调试对局入口(编排归 debug_session.gd) -signal diagnose_requested # 诊断转储入口(迭代 26 T5b——原主画面角落钮迁入;卡死取证编排归组合根) +signal diagnose_requested # 诊断转储入口(卡死取证编排归组合根) signal closed -var seed_edit: LineEdit # 组合根 _seed_value 唯一读取面(原开始覆盖层种子行迁入) +var seed_edit: LineEdit # 组合根 _seed_value 唯一读取面 var _db var _base_atk := 0 @@ -22,11 +22,11 @@ var _hp_val: Label var _eff: Label var _sim_count: SpinBox var _sim_btn: Button -var _dbg_btn: Button # 两层调试入口钮(迭代 18 卡⑦——对局中禁用承载面) +var _dbg_btn: Button # 两层调试入口钮(对局中禁用承载面) var _sim_out: RichTextLabel var _sim_running := false # 批量模拟进行中(is_running 判据——与对局中禁用态分离防互扰) var _ctx_locked := false # 对局中上下文锁定(组合根 _sync_debug_overlay 喂入——批量模拟/两层调试入口禁用) -var _run_labels := {} # 当局数据六项标签(P4 甲——只读投影,组合根 update_run_data 喂入) +var _run_labels := {} # 当局数据六项标签(只读投影,组合根 update_run_data 喂入) var _run_data := {} # 最近一次投喂快照(探针值对面 run_data_probe) @@ -69,7 +69,7 @@ func set_sim_count(n: int) -> void: func is_running() -> bool: - return _sim_running # 批量模拟进行中(迭代 18 卡⑦——与对局中禁用态分离,置灰 ≠ 在跑) + return _sim_running # 批量模拟进行中(与对局中禁用态分离,置灰 ≠ 在跑) func set_sim_running(running: bool) -> void: @@ -77,7 +77,7 @@ func set_sim_running(running: bool) -> void: _sync_sim_button() -# 对局中上下文锁定(迭代 18 卡⑦ T2——组合根 _sync_debug_overlay 喂入):批量模拟与两层调试入口 +# 对局中上下文锁定(组合根 _sync_debug_overlay 喂入):批量模拟与两层调试入口 # 在活跃对局并存态不开放(长程异步模拟/并发对局编排与活跃结算并存态破坏状态机) func set_context_locked(locked: bool) -> void: _ctx_locked = locked @@ -85,7 +85,7 @@ func set_context_locked(locked: bool) -> void: _sync_sim_button() -# 当局数据只读投影喂入(T3 P4 甲六项——组合根 _debug_run_data 构造;纯标签重查零动效) +# 当局数据只读投影喂入(六项——组合根 _debug_run_data 构造;纯标签重查零动效) func update_run_data(data: Dictionary) -> void: _run_data = data.duplicate() for key in _run_labels: @@ -170,9 +170,9 @@ func _build() -> void: list.add_theme_constant_override("separation", 8) scroll.add_child(list) - # 区块·当局数据(迭代 18 卡⑦ T3 P4 甲——六项只读投影:种子=本局种子唯一查看位〔adventure + # 区块·当局数据(六项只读投影:种子=本局种子唯一查看位〔adventure # .master_seed 现值,非 _seed_value() 重算〕/关卡/节点/HP/GP/钥石;数据由组合根开窗与模态开合 - # 时 update_run_data 喂入;纯标签零信号连接零动效——17卡③只读契约) + # 时 update_run_data 喂入;纯标签零信号连接零动效) var run_head := UiKit.label("当局数据(只读)",UiKit.FS_HINT, true, UiKit.WARM) list.add_child(run_head) var run_grid := GridContainer.new() @@ -189,18 +189,18 @@ func _build() -> void: run_grid.add_child(val) list.add_child(HSeparator.new()) - # 区块⓪胜利演出风格(P-C5 两套并存——纹章拼合[默认]/尘金粒子;会话级不落盘) + # 区块⓪胜利演出风格(两套并存——纹章拼合[默认]/尘金粒子;会话级不落盘) var fx_row := HBoxContainer.new() fx_row.add_theme_constant_override("separation", 10) list.add_child(fx_row) fx_row.add_child(UiKit.label("胜利演出",UiKit.FS_HINT, false, UiKit.WARM)) var fx_btn := UiKit.button("纹章拼合" if UiKit.victory_fx_style == "crest" else "尘金粒子") fx_btn.tooltip_text = "两套演出并存——点击切换(会话级,不落盘)" - fx_btn.pressed.connect(_on_fx_toggle.bind(fx_btn)) # 迭代 18 卡⑦——lambda 转命名方法(只读巡检白名单方法名精确可判) + fx_btn.pressed.connect(_on_fx_toggle.bind(fx_btn)) # lambda 转命名方法(只读巡检白名单方法名精确可判) fx_row.add_child(fx_btn) - # 区块①随机种子(原开始覆盖层种子行迁入——种子三分判定归组合根 _seed_value 单点): - # 默认空框(迭代 18 卡⑦ C1——空=随全局规则:首局恒 42/非首局随机;显式填入全场景优先) + # 区块①随机种子(种子三分判定归组合根 _seed_value 单点): + # 默认空框(空=随全局规则:首局恒 42/非首局随机;显式填入全场景优先) var seed_row := HBoxContainer.new() list.add_child(seed_row) seed_row.add_child(UiKit.label("随机种子",UiKit.FS_BODY, false)) @@ -211,7 +211,7 @@ func _build() -> void: seed_row.add_child(seed_edit) list.add_child(HSeparator.new()) - # 区块②角色数值调整板(原 TunePanel 内容原样吸收) + # 区块②角色数值调整板 var atk_row := _slider_row(list, "攻击加成") _atk = atk_row.slider _atk_val = atk_row.value_label @@ -252,14 +252,13 @@ func _build() -> void: list.add_child(_sim_out) list.add_child(HSeparator.new()) - # 区块④两层调试对局入口(原开始覆盖层调试按钮迁入——HP 关内延续;迭代 18 卡⑦——对局中禁用) + # 区块④两层调试对局入口(HP 关内延续;对局中禁用) _dbg_btn = UiKit.button("调试 · 连续关卡两层(HP 关内延续)") _dbg_btn.pressed.connect(_emit_debug_levels) list.add_child(_dbg_btn) - # 区块⑤诊断转储(迭代 26 T5b——原主画面左下角「诊断转储」常驻钮退役迁入:grilling Q8 裁甲, - # 承迭代 18 卡⑦「主菜单三散件收一」纪律;dump_diagnosis 卡死取证功能保留〔删除案否〕, - # 门控隐藏案否——本浮窗本就可全局可开,双轨无意义。纯视图边界:转储编排经信号外发归组合根) + # 区块⑤诊断转储:dump_diagnosis 卡死取证功能保留;不设门控隐藏——本浮窗本就可全局可开,双轨无意义。 + # 纯视图边界:转储编排经信号外发归组合根。 var diag_row := HBoxContainer.new() diag_row.add_theme_constant_override("separation", 10) list.add_child(diag_row) @@ -282,7 +281,7 @@ func _slider_row(box: VBoxContainer, title: String) -> Dictionary: s.min_value = 0 s.max_value = 300 s.step = 5 - s.custom_minimum_size = Vector2(320, 24) # 皮肤走全局主题(迭代 25:与设置屏音量滑轨同一构建方式,消双轨) + s.custom_minimum_size = Vector2(320, 24) # 皮肤走全局主题(与设置屏音量滑轨同一构建方式,消双轨) row.add_child(s) var v := UiKit.label("+0%",UiKit.FS_BODY, true) v.custom_minimum_size = Vector2(70, 0) @@ -318,7 +317,7 @@ func _on_slider_value_changed(_value: float) -> void: _sync_labels() -# 胜利演出切换(原 _build 内 lambda——迭代 18 卡⑦ 转命名方法,只读巡检白名单承载) +# 胜利演出切换(命名方法,只读巡检白名单承载) func _on_fx_toggle(btn: Button) -> void: UiKit.victory_fx_style = "dust" if UiKit.victory_fx_style == "crest" else "crest" btn.text = "纹章拼合" if UiKit.victory_fx_style == "crest" else "尘金粒子" diff --git a/game/presentation/views/hero_info_panel_view.gd b/game/presentation/views/hero_info_panel_view.gd index 8d3c4bad..d94c7139 100644 --- a/game/presentation/views/hero_info_panel_view.gd +++ b/game/presentation/views/hero_info_panel_view.gd @@ -8,27 +8,27 @@ const COL_INK := UiKit.INK var _atk_label: Label var _armor_label: Label -signal treasure_slot_clicked(handle: int) # 迭代 7 T4——槽点击(组合根消费:AP 类即用/空间类进选中态) -var item_slots: HBoxContainer # 秘宝槽(迭代 7 T4 接线——库存条常读+两步交互第一步) +signal treasure_slot_clicked(handle: int) # 槽点击(组合根消费:AP 类即用/空间类进选中态) +var item_slots: HBoxContainer # 秘宝槽(库存条常读+两步交互第一步) var _slot_panels: Array[Variant] = [] # 槽 PanelContainer 引用(选中高亮/置灰重刷) var _selected_handle := 0 # 选中态(0=无;组合根回写维持单源) var _slot_handles: Array[Variant] = [] # 槽位→handle 映射(set_treasure_inventory 刷新) -var _curio_section: VBoxContainer # 特性(预留——空态隐藏,接线归大奖励/锻造呈现批) +var _curio_section: VBoxContainer # 特性(预留——空态隐藏) var _curio_list: VBoxContainer -var _feat_section: VBoxContainer # 特性持有段(迭代 12 呈现补齐——空态隐藏) +var _feat_section: VBoxContainer # 特性持有段(空态隐藏) var _feat_list: VBoxContainer -var _board_variant_section: VBoxContainer # 地形变异常驻角标(全局作用域变异首发批——空态隐藏) +var _board_variant_section: VBoxContainer # 地形变异常驻角标(空态隐藏) var _board_variant_list: VBoxContainer func _init() -> void: custom_minimum_size = Vector2(240, 0) clip_contents = true - # 主面板穿石板戏服(样张 v2 冻结批 T2——纹理本色;数据框仍素面 §7.1;缺位回退 flat) + # 主面板穿石板戏服(纹理本色;数据框仍素面 §7.1;缺位回退 flat) var sb := UiKit.panel_skinned(Vector4(8, 6, 8, 6)) add_theme_stylebox_override("panel", sb) var col := VBoxContainer.new() - col.add_theme_constant_override("separation", 14) # 布局充实(2026-09-26 反馈③:区段间距放大) + col.add_theme_constant_override("separation", 14) # 布局充实(区段间距放大) add_child(col) col.add_child(UiKit.label("探险者",UiKit.FS_SUB, true)) @@ -46,7 +46,7 @@ func _init() -> void: data_col.add_child(_armor_label) # 秘宝槽(预留):随身战斗用道具的唯一展示面——空槽占位承诺格子在此, - # 不预设交互(挖掘期指向交互归 E 区既有裁决);终稿样式/槽位数归秘宝批 + # 不预设交互(挖掘期指向交互归 E 区既有裁决) col.add_child(UiKit.label("秘宝",UiKit.FS_BODY, true)) item_slots = HBoxContainer.new() item_slots.add_theme_constant_override("separation", 10) @@ -64,10 +64,8 @@ func _init() -> void: item_slots.add_child(slot) _slot_panels.append(slot) - # 特性持有段(迭代 12 呈现补齐 2026-10-04——三选一特性兑付后常驻可读:逐件行「件名 ×N」 - # 〔2026-10-12 整改换代,原逐流派聚合行退役〕;空态整节隐藏。用户试玩反馈「局内奖励选了 - # 什么看不到」缺口承载;2026-10-04 二次反馈上移—— - # 构筑核心信息优先级高于临时强化,且防 C 区下部裁切不可见) + # 特性持有段(三选一特性兑付后常驻可读:逐件行「件名 ×N」;空态整节隐藏。 + # 上移承载——构筑核心信息优先级高于临时强化,且防 C 区下部裁切不可见) _feat_section = VBoxContainer.new() _feat_section.add_theme_constant_override("separation", 4) _feat_section.visible = false @@ -76,8 +74,8 @@ func _init() -> void: _feat_list = VBoxContainer.new() _feat_list.add_theme_constant_override("separation", 2) _feat_section.add_child(_feat_list) - # 地形变异常驻角标(全局作用域变异首发批 2026-10-04——Boss 图整图型战斗全程可见防中局遗忘; - # 空态整节隐藏=特性段先例;摆位/文案 provisional 归 HUD 框架批与本地化批) + # 地形变异常驻角标(Boss 图整图型战斗全程可见防中局遗忘; + # 空态整节隐藏=特性段先例;摆位/文案 provisional) _board_variant_section = VBoxContainer.new() _board_variant_section.add_theme_constant_override("separation", 4) _board_variant_section.visible = false @@ -104,11 +102,11 @@ func set_attack(atk: int, mod_text: String) -> void: func set_armor(ac: int) -> void: - # 护甲 AC(2026-09-26 二轮拍板补入)——我方 AC 唯一展示面;掷点判定轴受击侧可读性 + # 护甲 AC——我方 AC 唯一展示面;掷点判定轴受击侧可读性 _armor_label.text = "护甲 AC %d" % ac -# 特性持有段(迭代 12 呈现补齐):lines = 逐件文案行(「疼痛记忆 ×2」式——2026-10-12 整改换代)——空数组 = 整节隐藏 +# 特性持有段:lines = 逐件文案行(「疼痛记忆 ×2」式)——空数组 = 整节隐藏 func set_feat_holdings(lines: Array) -> void: for c2 in _feat_list.get_children(): _feat_list.remove_child(c2) @@ -119,7 +117,7 @@ func set_feat_holdings(lines: Array) -> void: _feat_section.visible = not lines.is_empty() -# 地形变异常驻角标(首发批 2026-10-04):lines = 文案行(板级变异 display_name+体感短语)——空数组 = 整节隐藏 +# 地形变异常驻角标:lines = 文案行(板级变异 display_name+体感短语)——空数组 = 整节隐藏 func set_board_variants(lines: Array) -> void: for c3 in _board_variant_list.get_children(): _board_variant_list.remove_child(c3) @@ -136,7 +134,7 @@ func set_level_bonuses(lines: Array) -> void: _curio_list.remove_child(c) c.queue_free() for line in lines: - var l := UiKit.label(String(line),UiKit.FS_BODY, false, COL_INK) # 字号下限(v3.5 批 B3——正文 ≥16) + var l := UiKit.label(String(line),UiKit.FS_BODY, false, COL_INK) # 字号下限(正文 ≥16) _curio_list.add_child(l) _curio_section.visible = not lines.is_empty() @@ -150,14 +148,14 @@ func armor_text() -> String: func _data_line() -> Label: - # 对比度修复(v3.5 批 B3 2026-09-30——非粗体 label 默认浅灰对米色数据框仅 1.31:1, - # 实测=ui-redesign 对比报告 §一):显式主墨(对 PANEL_DATA ≈10:1) + # 非粗体 label 默认浅灰对米色数据框仅 1.31:1(实测=ui-redesign 对比报告 §一): + # 显式主墨(对 PANEL_DATA ≈10:1) var l := UiKit.label("",UiKit.FS_BODY, false, UiKit.INK) l.clip_text = true l.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS return l -# ---- 秘宝库存条(迭代 7 T4——C 区四槽常读+两步交互第一步)---- +# ---- 秘宝库存条(C 区四槽常读+两步交互第一步)---- # 投影行 = {handle, glyph, name, used, usable}(组合根组装:字形=道具名首字;数据源 runner 级库存只读面)。 # 空槽=虚位;used=暗态「已用」保留占位(Used 不可逆——受理序展示语义);不可用=置灰(板级零信息); # selected=金框高亮(两步交互第一步的可见态)。tooltip=全名+维度语义。 @@ -179,7 +177,7 @@ func set_treasure_inventory(items: Array, selected_handle: int) -> void: var used := bool(rec.get("used", false)) var usable := bool(rec.get("usable", true)) var selected := selected_handle != 0 and int(rec.get("handle", 0)) == selected_handle - # M8(UI 落码批):槽内容=手绘像素图标(demo ⑦;glyph 字符→图标键映射,未映射/used/不可用回退字形+条件墨色——T4 分支保留) + # 槽内容=手绘像素图标(demo ⑦;glyph 字符→图标键映射,未映射/used/不可用回退字形+条件墨色) var glyph_ch := String(rec.get("glyph", "?")) var icon_map := {"爆": UiKit.TEX_ICON_BLAST, "医": UiKit.TEX_ICON_MEDKIT, "铲": UiKit.TEX_ICON_SHOVEL, "袋": UiKit.TEX_ICON_COINBAG, "钥": UiKit.TEX_ICON_KEYSHARD, @@ -204,17 +202,17 @@ func set_treasure_inventory(items: Array, selected_handle: int) -> void: glyph.set_anchors_preset(Control.PRESET_FULL_RECT) glyph.mouse_filter = Control.MOUSE_FILTER_IGNORE if used: - # 「已用」占位墨=灰石深化(UI 设计对齐批 N1-5 2026-10-06——旧 STONE_FAINT 对 PANEL_DATA 槽牌 2.7:1; - # STONE_DEEP = 5.6:1;语义分档保持双墨,Q6 乙不新增通道) + # 「已用」占位墨=灰石深化(STONE_FAINT 对 PANEL_DATA 槽牌 2.7:1; + # STONE_DEEP = 5.6:1;语义分档保持双墨) glyph.add_theme_color_override("font_color", UiKit.STONE_DEEP) elif not usable: - # 「不可用」置灰墨=标签深墨(N1-6——旧 STONE 对槽牌 3.4:1;INK_LABEL = 10.4:1,虚位/失效更强置灰语义) + # 「不可用」置灰墨=标签深墨(STONE 对槽牌 3.4:1;INK_LABEL = 10.4:1,虚位/失效更强置灰语义) glyph.add_theme_color_override("font_color", UiKit.INK_LABEL) slot.add_child(glyph) var border_col: Color = UiKit.GOLD if selected else UiKit.PANEL_BORDER slot.add_theme_stylebox_override("panel", UiKit.panel_flat(UiKit.PANEL_DATA, border_col, 0, 1 if not selected else 2, Vector4(4, 4, 4, 4))) - # note=积点进度行(反哺批⑤——自动兑付件悬停浮窗补「积点 N/M」,进度随挖格经组合根重查刷新) + # note=积点进度行(自动兑付件悬停浮窗补「积点 N/M」,进度随挖格经组合根重查刷新) var note := String(rec.get("note", "")) slot.tooltip_text = "%s%s%s" % [String(rec.get("name", "")), "(%s)" % note if note != "" else "", diff --git a/game/presentation/views/legend_overlay.gd b/game/presentation/views/legend_overlay.gd index b0618da9..45f979e0 100644 --- a/game/presentation/views/legend_overlay.gd +++ b/game/presentation/views/legend_overlay.gd @@ -11,14 +11,14 @@ const ENTRIES := [ ["#000000", "封印", "封印印记(呈现名·不能拔)——轮末自动判定标中;插错可左键直接挖开(安全格零奖励、危险格吃挖雷惩罚)"], ["#2e86de", "小人", "探险者——8 向相邻未开格常驻微光 = 可挖域"], ["#F0A828", "金徽章", "已开格奖励身份 icon(封印之下、数值之上,不进数字区)"], - ["#F0A828", "九徽章解码", "攻=攻击 · 守=护甲 · 爆=爆裂 · 医=回复 · 弱=削弱 · 穿=穿刺 · 魔=魔法 · 行=行动点 · 金=GP(打磨包 2026-09-29 入列)"], + ["#F0A828", "九徽章解码", "攻=攻击 · 守=护甲 · 爆=爆裂 · 医=回复 · 弱=削弱 · 穿=穿刺 · 魔=魔法 · 行=行动点 · 金=GP"], ["#33261B", "状态槽空态", "无状态效果时槽位隐藏,数据框上移补位——非异常"], ] var _panel: PanelContainer -var _rap_cost := -1 # <0 = 不渲染 RAP 行(打磨包 2026-09-29——构造参数注表值,禁字面量) +var _rap_cost := -1 # <0 = 不渲染 RAP 行(构造参数注表值,禁字面量) func _init(rap_cost: int = -1) -> void: @@ -44,7 +44,7 @@ func _init(rap_cost: int = -1) -> void: row.add_child(lab) box.add_child(row) box.add_child(HSeparator.new()) - # RAP 行(打磨包 2026-09-29——表值驱动,禁字面量:刷新代价读行动经济表) + # RAP 行(表值驱动,禁字面量:刷新代价读行动经济表) if _rap_cost >= 0: var rap_row := HBoxContainer.new() rap_row.add_theme_constant_override("separation", 8) diff --git a/game/presentation/views/level_map_screen.gd b/game/presentation/views/level_map_screen.gd index f6f0952e..bfe556d1 100644 --- a/game/presentation/views/level_map_screen.gd +++ b/game/presentation/views/level_map_screen.gd @@ -7,29 +7,29 @@ extends Control signal route_chosen(node_id: int) signal abandon_requested -const COL_ROOM_DONE := UiKit.GOLD_DONE # 已到——暗金(样张 v1 冻结新值 #68562C——旧 GOLD_DIM 对双色墨均 <4.5:1,对比硬指标逼守;UiKit.GOLD_DIM 他用不动) +const COL_ROOM_DONE := UiKit.GOLD_DONE # 已到——暗金 #68562C(GOLD_DIM 对双色墨均 <4.5:1,对比硬指标逼守此值;UiKit.GOLD_DIM 他用不动) const COL_ROOM_CURRENT := UiKit.GOLD # 当前——奖励金 const COL_ROOM_FUTURE := UiKit.DARK_UPCOMING # 未达——暗 const COL_PASSAGE := UiKit.STONE # 通道——石灰 -const COL_PASSAGE_LIT := UiKit.CANDLE # 候选通道/候选描边——烛光黄(M5:金色定岗只留当前位,G4;旧 GOLD_LIT 退役出本屏) -const COL_BOSS_BORDER := UiKit.BOSS_PURPLE # Boss 边框——紫赤(色相独占本色;封印朱退役 2026-09-26) +const COL_PASSAGE_LIT := UiKit.CANDLE # 候选通道/候选描边——烛光黄(金色定岗只留当前位) +const COL_BOSS_BORDER := UiKit.BOSS_PURPLE # Boss 边框——紫赤(色相独占本色) const COL_ABANDON := UiKit.RED_MINE # 破坏性动作红(危险红族) -const NODE_LABELS := {"battle": "战", "reward": "赏", "rest": "疗", "boss": "王", "shop": "商"} # 商 = GP+商店房实施批 2026-09-21(贴图缺位字形回退用——贴图在位=字形退役惯例) -const NODE_TYPE_NAMES := {"battle": "战斗", "reward": "奖励", "rest": "休息", "boss": "Boss", "shop": "商店"} # M5 节点下方类型字(demo ④——三通道可读性;当前位显示「当前位置」) +const NODE_LABELS := {"battle": "战", "reward": "赏", "rest": "疗", "boss": "王", "shop": "商"} # 贴图缺位字形回退用——贴图在位=字形退役惯例 +const NODE_TYPE_NAMES := {"battle": "战斗", "reward": "奖励", "rest": "休息", "boss": "Boss", "shop": "商店"} # 节点下方类型字(demo ④——三通道可读性;当前位显示「当前位置」) const TEX_NODE_ICONS := {"battle": UiKit.TEX_NODE_BATTLE, "reward": UiKit.TEX_NODE_REWARD, "rest": UiKit.TEX_NODE_REST, "boss": UiKit.TEX_NODE_BOSS, "shop": UiKit.TEX_NODE_SHOP} -const NODE_ICON_PX := 20.0 # 节点图标边长(样张 v1 冻结——20px 烘焙 1:1 消费零缩放) -const TITLE_ENTRY := "出发——选择首个节点" # 入口停点(布局决策 1——台账 143 遗留清偿) +const NODE_ICON_PX := 20.0 # 节点图标边长(20px 烘焙 1:1 消费零缩放) +const TITLE_ENTRY := "出发——选择首个节点" # 入口停点(布局决策 1) const TITLE_SINGLE := "继续前进" # 单链停点 const TITLE_FORK := "选择下一节点" # 岔路停点 -const NODE_HALF := Vector2(36.5, 25) # 节点方块半宽高(73×50 = 52×36 的 1.4×——UI 落码批 M5「黑底吃掉」;层距/布局公式零改) -const LAYER_BASE_X := 70 # 首层节点原点 x(画布拟合与布局公式共用——T4 杂并:双写退役) +const NODE_HALF := Vector2(36.5, 25) # 节点方块半宽高(73×50 = 52×36 的 1.4×;层距/布局公式零改) +const LAYER_BASE_X := 70 # 首层节点原点 x(画布拟合与布局公式共用) const LAYER_STEP_X := 122 # 层间横向步距(同上) const SLOT_BASE_Y := 52 # 槽位原点 y(同上) const SLOT_STEP_Y := 58 # 同层槽位纵向步距(同上) const HIT_PAD := 6.0 # 图上命中外扩(指宽容差) const CONFIRM_WINDOW_S := 3.0 # 放弃确认态窗口(秒——超时回落) -const COL_HP_BAR_BACK := UiKit.HP_BAR_BACK # 迷你血条深底(样张 v1 冻结——对暗面板可辨;值单点收 UiKit) +const COL_HP_BAR_BACK := UiKit.HP_BAR_BACK # 迷你血条深底(对暗面板可辨;值单点收 UiKit) var _runner = null var _title: Label @@ -41,13 +41,13 @@ var _hp_bar: Control var _attr_value: Label var _bonus_row: HBoxContainer var _bonus_value: Label -var _feat_value: Label # 特性持有行(迭代 12 呈现补齐——组合根投喂逐件文案〔2026-10-12 换代〕) +var _feat_value: Label # 特性持有行(组合根投喂逐件文案) var _cand_ids: Array[int] = [] # 本停点候选 id 集(图上命中合法集) var _content_size := Vector2(620, 240) # 图内容包络(open_choices 按图拟合——画布 min 尺寸随它) var _hover_id := -1 # 悬停预承诺候选(-1 = 无) var abandon_btn: Button # 放弃入口(可见性归组合根 set_abandon_available——只在冒险模式开) -var status_badge: Button # 状态面板入口角标(迭代 17 卡③ P1 丁——顶栏 GP 徽右侧;连接归组合根) -var _abandon_timer := ArmedTimer.new() # 放弃确认窗(T3/D3 P4 乙——_process 帧驱动倒计时机制收口;窗口=CONFIRM_WINDOW_S) +var status_badge: Button # 状态面板入口角标(顶栏 GP 徽右侧;连接归组合根) +var _abandon_timer := ArmedTimer.new() # 放弃确认窗(_process 帧驱动倒计时机制收口;窗口=CONFIRM_WINDOW_S) var _node_icons := {} # 节点图标贴图(load_tex 守卫——缺位 null → 字形回退,冒烟/无素材检出安全) var _noise_rect: TextureRect # 屏底石纹(换层色板渐变承载面——null = 纯色回退无挂点) var _tint_level := 0 # 当前已应用 tint 的层号(0 = 未应用) @@ -55,11 +55,11 @@ var _tint_level := 0 # 当前已应用 tint 的层号(0 = 未 func _init() -> void: _abandon_timer.expired.connect(_reset_abandon_confirm) - # 节点图标贴图装载(样张 v1 冻结形制——load_tex 守卫,缺位回退现行字形) + # 节点图标贴图装载(load_tex 守卫,缺位回退现行字形) for t in TEX_NODE_ICONS: _node_icons[t] = UiKit.load_tex(TEX_NODE_ICONS[t]) - # 独立屏底(形态升格 2026-09-28——spec Layout;UI 对齐批 T5 2026-10-06:demo #v-map 暖棕竖向 - # 渐变(#4A3B2A 0%→#3A2E22 40%)+石纹弱质感 0.14+暗角聚焦;旧满铺石纹不透退役;底纹缺位回退纯色) + # 独立屏底(spec Layout——demo #v-map 暖棕竖向 + # 渐变(#4A3B2A 0%→#3A2E22 40%)+石纹弱质感 0.14+暗角聚焦;底纹缺位回退纯色) var base := UiKit.gradient_base(UiKit.BG_MAP_TOP, UiKit.BG_ROOT) add_child(base) var tex := UiKit.backdrop_tile() @@ -74,8 +74,8 @@ func _init() -> void: box.add_theme_constant_override("separation", 10) center.add_child(box) # 顶栏语境(spec Layout:左关卡名 / 右 GP 常驻徽章——直角细线数据框; - # T5 判官 checkpoint 对齐 demo ④:关卡名入框板(裸文本退役)+GP 徽章=烛光胶囊(同商店GP框)+ - # 左右两极排布(原居中悬置)) + # 对齐 demo ④:关卡名入框板+GP 徽章=烛光胶囊(同商店GP框)+ + # 左右两极排布) var top := HBoxContainer.new() top.add_theme_constant_override("separation", 12) top.size_flags_horizontal = Control.SIZE_EXPAND_FILL @@ -98,7 +98,7 @@ func _init() -> void: gp_box.add_child(gp_row) _gp_value = UiKit.label("",UiKit.FS_BODY, true, UiKit.INK_ON_GOLD) gp_row.add_child(_gp_value) - # 状态面板入口角标(迭代 17 卡③ P1 丁——顶栏常驻;2026-10-16 调试角标迁全局浮层后本屏只留状态。 + # 状态面板入口角标(顶栏常驻;本屏只留状态——调试角标归全局浮层。 # 置灰守卫归组合根 _sync_status_entry(其他模态开着=不可点;本屏自身的登记开态不计——has_open_excluding); # 信号连接归组合根(视图零连接)) status_badge = UiKit.button("状态", 0.0) @@ -116,11 +116,11 @@ func _init() -> void: _canvas.draw.connect(_draw_graph.bind(_canvas)) _canvas.gui_input.connect(_on_canvas_input) box.add_child(_canvas) - # 底部状态栏(M5 合并单条:亮米面板一站读齐=头像+生命+属性+本关加成/流派件——demo ④; - # 道具槽不摆=道具读数无关卡画面成文出口(读快照私域越权),随 runner 出口批补——台账 352 注记; + # 底部状态栏(合并单条:亮米面板一站读齐=头像+生命+属性+本关加成/流派件——demo ④; + # 道具槽不摆=道具读数无关卡画面成文出口(读快照私域越权); # _hp_value/_attr_value/_bonus_value/_feat_value 投喂键全部保留) - # 底栏定高纪律(2026-10-06 审计差距①对齐 demo——单条 ~85px 紧凑亮条;任何子件不再能把栏撑爆: - # 特性持有行限宽截断+tooltip 全文,旧「autowrap 无限宽→最小高度逐字竖排爆栏」形态根除) + # 底栏定高纪律(对齐 demo——单条 ~85px 紧凑亮条;任何子件不再能把栏撑爆: + # 特性持有行限宽截断+tooltip 全文) var bottom := PanelContainer.new() bottom.custom_minimum_size = Vector2(0, 85) bottom.size_flags_vertical = Control.SIZE_SHRINK_END @@ -132,7 +132,7 @@ func _init() -> void: bottom.add_child(strip) var face := TextureRect.new() var face_tex := UiKit.load_tex(UiKit.TEX_HERO_PORTRAIT) - # P6 甲⑤(2026-10-06):定高 48px=1×、宽随源图比自适应(源 46×48 → 46×48;纵横异倍消除) + # 定高 48px=1×、宽随源图比自适应(源 46×48 → 46×48;纵横异倍消除) var face_h := 48.0 var face_w := face_h if face_tex != null: @@ -160,20 +160,20 @@ func _init() -> void: _attr_value = UiKit.label("",UiKit.FS_BODY, true, UiKit.INK_TITLE) attr_box.add_child(_attr_value) strip.add_child(_vdiv()) - # 本关加成框(零加成隐藏——spec 布局决策 4)+ 流派件持有行(迭代 12 呈现补齐——组合根投喂) + # 本关加成框(零加成隐藏——spec 布局决策 4)+ 流派件持有行(组合根投喂) _bonus_row = HBoxContainer.new() strip.add_child(_bonus_row) var bonus_box := VBoxContainer.new() _bonus_row.add_child(bonus_box) var bonus_inner := VBoxContainer.new() bonus_box.add_child(bonus_inner) - var bonus_cap := UiKit.label("特性",UiKit.FS_CAPTION, false, UiKit.INK_HINT) # 淡墨→深墨(亮板可读,审计差距①) + var bonus_cap := UiKit.label("特性",UiKit.FS_CAPTION, false, UiKit.INK_HINT) # 深墨(亮板可读) bonus_inner.add_child(bonus_cap) _bonus_value = UiKit.label("",UiKit.FS_BODY, true, UiKit.INK_TITLE) # 淡墨→深墨(同上) bonus_inner.add_child(_bonus_value) - # 特性持有行(迭代 12 呈现补齐 2026-10-04——用户反馈关卡选择页看不到局内奖励;组合根投喂) - # 审计差距①修(2026-10-06):限宽单行截断+tooltip 全文(旧 autowrap 无限宽=爆栏元凶); - # 墨色 WARM_SOFT→INK_HINT(暖白系对亮板 ≈1:1 不可读——§7.2 违例修复) + # 特性持有行(组合根投喂) + # 限宽单行截断+tooltip 全文; + # 墨色 INK_HINT(暖白系对亮板 ≈1:1 不可读——§7.2) _feat_value = UiKit.label("",UiKit.FS_HINT, false, UiKit.INK_HINT) _feat_value.custom_minimum_size = Vector2(240, 0) _feat_value.clip_text = true @@ -182,14 +182,14 @@ func _init() -> void: var spacer := Control.new() spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL strip.add_child(spacer) - abandon_btn = UiKit.danger_button("放弃", "", 90.0) # 审计差距①对齐 demo:小号危险钮 ~90×38(原 216 宽砖);打磨包 2026-09-29 文案 + M5 危险钮皮 + abandon_btn = UiKit.danger_button("放弃", "", 90.0) # 小号危险钮 ~90×38 abandon_btn.pressed.connect(_on_abandon_pressed) abandon_btn.visible = false strip.add_child(abandon_btn) visible = false -# 竖分隔线(M5 底栏分组线——亮面板上低对比细线) +# 竖分隔线(底栏分组线——亮面板上低对比细线) static func _vdiv() -> ColorRect: var v := ColorRect.new() v.color = UiKit.MAP_VDIV @@ -197,12 +197,9 @@ static func _vdiv() -> ColorRect: return v -# _status_box 已退役(M5 底栏合并单条——demo ④;本函数随旧三暗框退役删除,投喂键保留于新底栏) - - func _draw_hp_bar(bar: Control) -> void: - # 迷你血条(深底 UiKit.HP_BAR_BACK #28221C + 小人蓝填充——M5 改蓝:与战斗站桩血条同语言, - # 「蓝只说己方」§4.2;旧金填充退役=金只说收益定岗 G4)。比例 = hero_hp / effective_max_hp + # 迷你血条(深底 UiKit.HP_BAR_BACK #28221C + 小人蓝填充——与战斗站桩血条同语言, + # 「蓝只说己方」§4.2)。比例 = hero_hp / effective_max_hp if _runner == null: return var max_hp := maxi(1, _runner.effective_max_hp()) @@ -214,7 +211,7 @@ func _draw_hp_bar(bar: Control) -> void: # 放弃入口可见性(组合根在冒险启动时开、默认关——语义对象 = 整局冒险) -# 特性持有投影(迭代 12 呈现补齐——组合根投喂逐件文案〔2026-10-12 换代〕;空文案=行隐藏) +# 特性持有投影(组合根投喂逐件文案;空文案=行隐藏) func set_feat_holdings(text: String) -> void: _feat_value.text = text _feat_value.tooltip_text = text # 截断全量兜底(限宽单行省略——悬停看全文) @@ -240,7 +237,7 @@ func _on_abandon_pressed() -> void: func _reset_abandon_confirm() -> void: _abandon_timer.disarm() abandon_btn.modulate = Color(1, 1, 1, 1) - abandon_btn.text = "放弃" # 打磨包 2026-09-29——文案收敛 level-map 4 字上限(确认态转义面见 _on_abandon_pressed) + abandon_btn.text = "放弃" # 文案收敛 level-map 4 字上限(确认态转义面见 _on_abandon_pressed) func _process(delta: float) -> void: @@ -269,7 +266,7 @@ func open_choices(cands: Array, runner: LevelRunner) -> void: if cands.size() > 1: _title.text = TITLE_FORK elif visited.is_empty(): - _title.text = TITLE_ENTRY # 入口停点(尚未走出第一步——台账 143 措辞矛盾清偿) + _title.text = TITLE_ENTRY # 入口停点(尚未走出第一步) else: _title.text = TITLE_SINGLE _cand_ids = [] @@ -287,7 +284,7 @@ func open_choices(cands: Array, runner: LevelRunner) -> void: # 画布随图自适应(level-map.md Layout:画布宽随层数、高随同层最大节点数——公式与 _layout 同源; -# 2026-09-28 真鼠标点击 bug 根修:固定 620×240 画布下深层节点(L1 Boss 内容 x=802)落在 gui_input +# 固定 620×240 画布下深层节点(Boss 内容 x=802)落在 gui_input # 命中区外——绘制无裁剪看得见、命中收不到事件。单链关卡层深=节点序,必须先拟合再命中。 func _fit_canvas(nodes: Array) -> void: if nodes.is_empty(): @@ -302,15 +299,15 @@ func _fit_canvas(nodes: Array) -> void: for k in slot.keys(): maxslot = maxi(maxslot, int(slot[k])) _content_size = Vector2(LAYER_BASE_X + maxl * LAYER_STEP_X + NODE_HALF.x + 8.0, - SLOT_BASE_Y + maxslot * SLOT_STEP_Y + NODE_HALF.y + 24.0) # +24 = 类型文字标签行(M5) - _content_size = _content_size.max(Vector2(620, 256)) # 下限(M5 抬高容纳标签行) + SLOT_BASE_Y + maxslot * SLOT_STEP_Y + NODE_HALF.y + 24.0) # +24 = 类型文字标签行 + _content_size = _content_size.max(Vector2(620, 256)) # 下限(抬高容纳标签行) _canvas.custom_minimum_size = _content_size # 换层色板渐变挂点(art-bible §2.7 下探过渡切片档——关卡结算确认→下一关→独立屏淡入链路上的 # 色相层进预告:屏底世界侧随层进换挡,信息层恒定;tint 明度带归一≈1 只动色相/饱和)。 # tint 候选方向 = art-bible §6.3 三关图类型色板方向(1 dungeon 暖石基准/2 underdark 冷蓝灰/3 deep 灰黑金属), -# 终值归色板样张批——本批只落挂点(level-map.md States 换层进入行承载)。 +# 只落挂点(level-map.md States 换层进入行承载)。 const BOARD_TINTS := {1: Color(1, 1, 1), 2: Color(0.84, 0.99, 1.28), 3: Color(0.97, 0.99, 1.09)} @@ -321,7 +318,7 @@ func _apply_level_tint(level_index: int) -> void: var target: Color = BOARD_TINTS.get(level_index, Color(1, 1, 1)) var tw := create_tween() tw.tween_property(_noise_rect, "modulate", - Color(target.r, target.g, target.b, UiKit.BACKDROP_TILE_ALPHA), UiKit.motion(0.45)) # 0.14 弱质感档随 tint 保持(T5) + Color(target.r, target.g, target.b, UiKit.BACKDROP_TILE_ALPHA), UiKit.motion(0.45)) # 0.14 弱质感档随 tint 保持 # 状态栏刷新(命令式纪律——组合根打开本屏/兑付确认回执后重查;零推送信号订阅) @@ -333,7 +330,7 @@ func _refresh_status() -> void: var max_hp: int = _runner.effective_max_hp() _hp_value.text = "HP %d/%d" % [int(_runner.hero_hp), int(max_hp)] _hp_bar.queue_redraw() - var atk_bonus := int(_runner.run_ledger.bonus.get("atk", 0)) # 迭代 27 T3——加算区住 RunLedger + var atk_bonus := int(_runner.run_ledger.bonus.get("atk", 0)) # 加算区住 RunLedger var ac_bonus := int(_runner.run_ledger.bonus.get("armor_class", 0)) var atk_txt := "%d" % _runner.effective_atk() if atk_bonus > 0: @@ -390,7 +387,7 @@ func _candidate_at(local_pos: Vector2) -> int: func _submit_choice(nid: int) -> void: - # 形态升格分支(2026-09-28 独立屏):战斗/Boss 节点 = 出屏切回战斗屏;奖励/恢复/商店节点 = + # 独立屏分支:战斗/Boss 节点 = 出屏切回战斗屏;奖励/恢复/商店节点 = # 本屏保持激活——兑付覆盖层由节点事件在本屏域内弹出(模态栈遮挡恢复语义复用),兑付确认后回图刷新 var node := _node_by_id(nid, _runner.nodes()) var t := String(node.get("type", "")) @@ -430,7 +427,7 @@ func _draw_graph(canvas: Control) -> void: var visited: Array[Variant] = _runner.visited_ids() var cand_ids: Array[Variant] = _runner.next_candidate_ids() # 连线(通道)先行画(方块覆盖其上);悬停预承诺 = 所属通道再增亮(加粗) - # T17 修复:选路停点(候选非空)非候选通道降透明——金岔路从结构网分离(干线共线重叠缺陷的 + # 选路停点(候选非空)非候选通道降透明——金岔路从结构网分离(干线共线重叠缺陷的 # 视觉主因:不同源通道共用同一垂直干线,金边与石色边焊接成「整列可走」假象) var dim_passages: bool = not cand_ids.is_empty() for node in nodes: @@ -443,7 +440,7 @@ func _draw_graph(canvas: Control) -> void: var lit: bool = _id_of(node) == current_id and cand_ids.has(tid) var hovered: bool = lit and _hover_id == tid var col := COL_PASSAGE_LIT if lit else (Color(COL_PASSAGE, 0.35) if dim_passages else COL_PASSAGE) - var width := 4.0 if hovered else (3.0 if lit else 2.0) # 样张 v1 冻结:2/3/4(原 1.5 取整) + var width := 4.0 if hovered else (3.0 if lit else 2.0) # 2/3/4 三档 _draw_passage(canvas, from, to, col, width) # 房间方块 for node in nodes: @@ -458,14 +455,14 @@ func _draw_graph(canvas: Control) -> void: var rect := Rect2(p - NODE_HALF, NODE_HALF * 2.0) canvas.draw_rect(rect, col) if t == "boss": - # Boss 描边 = 紫赤 2px(§4.2 色相独占)+ 外缘 1px 深墨环(灰度冗余通道——样张 v1 L2 逼守: + # Boss 描边 = 紫赤 2px(§4.2 色相独占)+ 外缘 1px 深墨环(灰度冗余通道强制: # 紫赤灰度 72 对石纹噪底 65 灰度不可辨;灰度/色弱下 Boss 环经深墨环可辨) canvas.draw_rect(Rect2(rect.position - Vector2(3, 3), rect.size + Vector2(6, 6)), UiKit.INK_ROUTE, false, 1.0) canvas.draw_rect(rect, COL_BOSS_BORDER, false, 2.0) elif cand_ids.has(nid): # 悬停预承诺 = 亮金描边加粗(4px),常态候选 = 亮金描边 2px(spec States 悬停预承诺行) canvas.draw_rect(rect, COL_PASSAGE_LIT, false, 4.0 if _hover_id == nid else 2.0) - # 节点图标(样张 v1 冻结形制:20px 烘焙 1:1 消费;双色墨制=乘法调制——当前金底深墨,暗底系 WARM 原色; + # 节点图标(20px 烘焙 1:1 消费;双色墨制=乘法调制——当前金底深墨,暗底系 WARM 原色; # 贴图缺位 → 字形回退=贴图在位字形退役惯例) var icon: Texture2D = _node_icons.get(t) if icon != null: @@ -476,11 +473,11 @@ func _draw_graph(canvas: Control) -> void: var font := get_theme_default_font() var label := String(NODE_LABELS.get(t, "?")) canvas.draw_string(font, p + Vector2(-6, 2), label, HORIZONTAL_ALIGNMENT_LEFT, -1, 16, UiKit.INK_ROUTE) - # 编号(右上角——与图标占位区零重叠,样张 v1 L7;双色墨随态) + # 编号(右上角——与图标占位区零重叠;双色墨随态) var num_ink := UiKit.INK_ROUTE if col == COL_ROOM_CURRENT else UiKit.WARM canvas.draw_string(get_theme_default_font(), Vector2(rect.end.x - 16.0, rect.position.y + 8.0), str(nid), HORIZONTAL_ALIGNMENT_RIGHT, 14, 10, num_ink) - # 类型文字标签(M5——demo ④:节点下方 11px;当前位=「当前位置」金、候选=类型名+「 · 可选」烛光黄、 + # 类型文字标签(demo ④:节点下方 11px;当前位=「当前位置」金、候选=类型名+「 · 可选」烛光黄、 # 其余=类型名暖米弱化;文字+图标+形状三通道) var type_text := String(NODE_TYPE_NAMES.get(t, t)) if nid == current_id: @@ -504,7 +501,7 @@ func _layout(nodes: Array, canvas: Control) -> Dictionary: return pos -# ---- 探针只读出口(D2 改造 2026-10-04——_layout/_canvas 私有域直入退役;形态仿 fx_probe 先例:只读快照) ---- +# ---- 探针只读出口(形态仿 fx_probe 先例:只读快照) ---- # 选路布局只读快照(node → 局部位置;画布固定取现行 _canvas,调用侧零私有域触达) func layout_probe(nodes: Array) -> Dictionary: @@ -573,9 +570,9 @@ func _draw_passage(canvas: Control, from: Vector2, to: Vector2, col: Color, widt var b := to - Vector2(NODE_HALF.x, 0) if b.x < a.x: return - # T17 修复:垂直干线 x 按源节点 y 偏移——不同源的边不再共线重叠(旧 mid_x=中点使相邻层 - # 全部通道焊成一条干系,「金岔路+整列可走」误读的直接几何根源)。同源双边仍共线(同出发 - # 点语义正确),跨源分离度 = 源行距 × 0.2(L2 行距 ~58px → 偏移 ~12px 可辨)。 + # 垂直干线 x 按源节点 y 偏移——不同源的边不再共线重叠(共线会把相邻层通道焊成一条干系, + # 「金岔路+整列可走」误读的直接几何根源)。同源双边仍共线(同出发 + # 点语义正确),跨源分离度 = 源行距 × 0.2(行距 ~58px → 偏移 ~12px 可辨)。 var mid_x := (a.x + b.x) / 2.0 + (a.y - b.y) * 0.2 var pts := PackedVector2Array([a, Vector2(mid_x, a.y), Vector2(mid_x, b.y), b]) canvas.draw_polyline(pts, col, width) diff --git a/game/presentation/views/settings_overlay.gd b/game/presentation/views/settings_overlay.gd index 20bf369b..adfe0d12 100644 --- a/game/presentation/views/settings_overlay.gd +++ b/game/presentation/views/settings_overlay.gd @@ -9,10 +9,10 @@ signal closed var _store var _volume: HSlider var _volume_val: Label -var _fs_btn: Button # M4 换 SwitchToggle 拨杆(仍 Button 子类——探针接缝保持) -var _motion_btn: Button # M4 同上 -var _fs_st: Label # M4 状态字随行(开/关) -var _motion_st: Label # M4 状态字(完整/快速) +var _fs_btn: Button # SwitchToggle 拨杆(仍 Button 子类——探针接缝保持) +var _motion_btn: Button # 同上 +var _fs_st: Label # 状态字随行(开/关) +var _motion_st: Label # 状态字(完整/快速) func _init(store) -> void: @@ -29,11 +29,11 @@ func retarget(store: SettingsStore) -> void: func _build() -> void: - # M4(UI 落码批):石板面板化(demo ③)+行牌化(标签+拨杆+状态字+后果说明行); - # 设置项零增减(P-C6:只有主音量——demo 音效音量行系原型发明已撤); - # 减动效与结算演出动画=同一设置(语义命名批合并),一行承载。 - # T8(UI 设计对齐批 2026-10-06):两列对齐(label 列定宽 140——demo .setrow label/控制两列)+ - # 后果说明内联随行(demo .why 同排)+返回钮紧凑化(demo .btn9 紧凑——原 216 宽砖)。 + # 石板面板化(demo ③)+行牌化(标签+拨杆+状态字+后果说明行); + # 设置项零增减(只有主音量); + # 减动效与结算演出动画=同一设置,一行承载。 + # 两列对齐(label 列定宽 140——demo .setrow label/控制两列)+ + # 后果说明内联随行(demo .why 同排)+返回钮紧凑化(demo .btn9 紧凑)。 var shell: Dictionary[Variant, Variant] = UiKit.modal_shell(self, UiKit.BG_BRIGHT, Vector2(560, 0), 8, true, UiKit.panel_skinned(Vector4(20, 16, 20, 16))) var box: VBoxContainer = shell.box @@ -51,13 +51,13 @@ func _build() -> void: vol_row.add_theme_constant_override("separation", 14) box.add_child(vol_row) var vol_lab := UiKit.label("主音量",UiKit.FS_BODY, false, UiKit.INK_LABEL) - vol_lab.custom_minimum_size = Vector2(140, 0) # T8 label 列定宽(两列对齐) + vol_lab.custom_minimum_size = Vector2(140, 0) # label 列定宽(两列对齐) vol_row.add_child(vol_lab) _volume = HSlider.new() _volume.min_value = 0.0 _volume.max_value = 100.0 _volume.value = 100.0 - _volume.custom_minimum_size = Vector2(200, 24) # 几何/量程内联(迭代 25:样式滑杆工厂退役,皮肤走全局主题) + _volume.custom_minimum_size = Vector2(200, 24) # 几何/量程内联(皮肤走全局主题) _volume.step = 1 _volume.size_flags_horizontal = Control.SIZE_EXPAND_FILL _volume.value_changed.connect(_on_volume_changed) @@ -66,12 +66,12 @@ func _build() -> void: _volume_val.custom_minimum_size = Vector2(60, 0) vol_row.add_child(_volume_val) - # 全屏(拨杆形——M10 SwitchToggle;状态字随行) + # 全屏(拨杆形——SwitchToggle;状态字随行) var fs_row := HBoxContainer.new() fs_row.add_theme_constant_override("separation", 14) box.add_child(fs_row) var fs_lab := UiKit.label("全屏",UiKit.FS_BODY, false, UiKit.INK_LABEL) - fs_lab.custom_minimum_size = Vector2(140, 0) # T8 同上 + fs_lab.custom_minimum_size = Vector2(140, 0) # 同上 fs_row.add_child(fs_lab) _fs_btn = UiKit.switch_toggle(false) _fs_btn.toggled.connect(_on_fullscreen_toggled) @@ -79,14 +79,14 @@ func _build() -> void: _fs_st = UiKit.label("关",UiKit.FS_HINT, true, UiKit.INK_LABEL) fs_row.add_child(_fs_st) - # 结算演出动画(=减动效实称——语义命名批 T17;拨杆 on=完整,off=快速时长减半。 - # T8 核证:reduced_motion 单设置同驱 UiKit.motion_scale 与结算演播——demo「减动效」行与 - # 本行系同一设置,不另立行(拆两行=一设置双行重复,违语义命名批裁决) + # 结算演出动画(=减动效实称;拨杆 on=完整,off=快速时长减半。 + # reduced_motion 单设置同驱 UiKit.motion_scale 与结算演播——demo「减动效」行与 + # 本行系同一设置,不另立行(拆两行=一设置双行重复) var motion_row := HBoxContainer.new() motion_row.add_theme_constant_override("separation", 14) box.add_child(motion_row) var motion_lab := UiKit.label("结算演出动画",UiKit.FS_BODY, false, UiKit.INK_LABEL) - motion_lab.custom_minimum_size = Vector2(140, 0) # T8 同上 + motion_lab.custom_minimum_size = Vector2(140, 0) # 同上 motion_row.add_child(motion_lab) _motion_btn = UiKit.switch_toggle(true) _motion_btn.toggled.connect(_on_motion_toggled) @@ -94,14 +94,14 @@ func _build() -> void: _motion_st = UiKit.label("完整",UiKit.FS_HINT, true, UiKit.INK_LABEL) motion_row.add_child(_motion_st) var why := UiKit.label("快速 = 时长减半(运动敏感 / 演示用)",UiKit.FS_CAPTION, false, UiKit.INK_HINT) - motion_row.add_child(why) # T8 内联随行(demo .why 同排;原独立行换排) + motion_row.add_child(why) # 内联随行(demo .why 同排) box.add_child(HSeparator.new()) - # 退出游戏已提级开始菜单(D1——设置面不再承载,用户裁决「退出只在一级菜单出现」) + # 退出游戏归开始菜单——设置面不再承载(退出只在一级菜单出现) var close_row := HBoxContainer.new() close_row.alignment = BoxContainer.ALIGNMENT_CENTER box.add_child(close_row) - var close_btn := UiKit.button("返回", 90.0) # T8 紧凑返回钮(demo 紧凑形;原 216 宽砖) + var close_btn := UiKit.button("返回", 90.0) # 紧凑返回钮(demo 紧凑形) close_btn.pressed.connect(_emit_closed) close_row.add_child(close_btn) @@ -115,7 +115,7 @@ func _sync() -> void: _sync_motion_text() -# T17 修复:文案随状态即时刷新(旧 bug=切换后文案恒「开」,玩家无法得知当前态)+语义命名 +# 文案随状态即时刷新(否则切换后文案恒「开」,玩家无法得知当前态)+语义命名 # (「减动效」玩家读不懂——实称「结算演出动画」速度档)+操作提示内联(所见即所得)。 func _sync_motion_text() -> void: _motion_st.text = "快速" if _store.reduced_motion else "完整" @@ -135,10 +135,10 @@ func _on_fullscreen_toggled(on: bool) -> void: func _on_motion_toggled(on: bool) -> void: - _store.reduced_motion = not on # M4 拨杆语义翻转:on=完整(off=快速) + _store.reduced_motion = not on # 拨杆语义翻转:on=完整(off=快速) _store.apply() _store.save_settings() - _sync_motion_text() # T17 修复:切换即时刷新文案(旧版漏刷新=状态文字恒「开」) + _sync_motion_text() # 切换即时刷新文案(漏刷新会让状态文字恒「开」) func _emit_closed() -> void: diff --git a/game/presentation/views/settlement_fx_view.gd b/game/presentation/views/settlement_fx_view.gd index 31a6fef8..5881d2ba 100644 --- a/game/presentation/views/settlement_fx_view.gd +++ b/game/presentation/views/settlement_fx_view.gd @@ -143,7 +143,7 @@ func play_round_banner(ri: int) -> void: tw.tween_callback(banner.queue_free) -# 开战横幅——板级地形变异预告(全局作用域变异首发批 2026-10-04):board_variants 非空时开战 +# 开战横幅——板级地形变异预告:board_variants 非空时开战 # 显示一行(文本=「地形变异 · 贫矿脉」式);减动效=静态驻留后即隐(轮横幅先例——行呈现不跳过)。 # 文案/驻留参数 provisional 归本地化批;普通图恒不发射(组合根按快照 board_variants 空判)。 func play_board_variant_banner(text: String) -> void: diff --git a/game/presentation/views/shop_overlay_view.gd b/game/presentation/views/shop_overlay_view.gd index 25ce0941..234d858f 100644 --- a/game/presentation/views/shop_overlay_view.gd +++ b/game/presentation/views/shop_overlay_view.gd @@ -21,7 +21,7 @@ var _shelf_rows: Array[Dictionary] = [] # [{kind_id, btn}]——pool 面卡片 func _init() -> void: - # T6(UI 设计对齐批 2026-10-06):全屏页形态(demo ⑤ #v-shop——06 在册 D2 商店全屏化/D1 竖卡 + # 全屏页形态(demo ⑤ #v-shop——06 在册 D2 商店全屏化/D1 竖卡 # 232×352 落地)——暖亮底+石纹弱质感+暗角(UiKit.page_shell)+56px 通栏顶条(标题+刷新图标钮/ # 角标+GP 框)+ 爬价规则行 + bcard 三竖卡居中 + 底部离开钮与池源注记。 # M6 遗产:库存余量退役(关卡节点地图 v1.5-a 用户裁);刷新钮呈现位照摆(机制=MC-1 投喂)。 @@ -56,7 +56,7 @@ func _init() -> void: box.add_child(_visit_label) _cards_box = VBoxContainer.new() _cards_box.size_flags_vertical = Control.SIZE_EXPAND_FILL - _cards_box.alignment = BoxContainer.ALIGNMENT_CENTER # 迭代 26 T5③ 卡片区垂直居中(旧默认顶对齐=卡片堆上半、下半空) + _cards_box.alignment = BoxContainer.ALIGNMENT_CENTER # 卡片区垂直居中 _cards_box.add_theme_constant_override("separation", 8) box.add_child(_cards_box) var foot := HBoxContainer.new() @@ -118,7 +118,7 @@ func _build_card(p: Dictionary) -> Dictionary: var row := HBoxContainer.new() row.add_theme_constant_override("separation", 14) card.add_child(row) - var name_l := UiKit.label(_card_title(p),UiKit.FS_BODY, true, UiKit.WARM_SOFT) # 尾裁微批a 2026-10-08——显式传墨:bold 缺省 INK_LABEL 压暗底行卡 1.12:1 越带,换暖白次级 9.53:1 + var name_l := UiKit.label(_card_title(p),UiKit.FS_BODY, true, UiKit.WARM_SOFT) # 显式传墨:bold 缺省 INK_LABEL 压暗底行卡 1.12:1 越带,换暖白次级 9.53:1 name_l.custom_minimum_size = Vector2(190, 0) row.add_child(name_l) var price_l := UiKit.label("",UiKit.FS_HINT, false, UiKit.WARM_SOFT) @@ -193,7 +193,7 @@ func set_refresh_display(free_left: int, gp_cost: int, can_afford: bool) -> void # 货架卡(bcard 竖卡:类型色带+图标+名+件值描述+价签+购买钮——M6 同构卡;demo ⑤) -# 库存余量退役=关卡节点地图 v1.5-a 用户裁(2026-10-04)——数据层 stock_left 仍投喂断点,仅呈现不摆 +# 库存余量不再呈现(关卡节点地图 v1.5-a)——数据层 stock_left 仍投喂断点 func _build_shelf_card(holder: Control, c: Dictionary) -> Dictionary: var kind := String(c.get("kind_id", "")) var icon_key := UiKit.TEX_ICON_SWORD diff --git a/game/presentation/views/stage_world.gd b/game/presentation/views/stage_world.gd index 4ba4cb5e..7b93896a 100644 --- a/game/presentation/views/stage_world.gd +++ b/game/presentation/views/stage_world.gd @@ -5,5 +5,5 @@ extends Node2D var world_font: Font = null # 字体注入槽位(null = ThemeDB.fallback_font——BattleStageView.set_world_font 注入) -# C6 headless 可验判据(2026-09-12 场景结构裁决):注入字体非空 + 中文字形 has_char + 采样文本宽度 > 0。 +# C6 headless 可验判据:注入字体非空 + 中文字形 has_char + 采样文本宽度 > 0。 # 实际光栅观感归批末目检清单。 \ No newline at end of file diff --git a/game/presentation/views/standee_body.gd b/game/presentation/views/standee_body.gd index fff7b407..046f44ce 100644 --- a/game/presentation/views/standee_body.gd +++ b/game/presentation/views/standee_body.gd @@ -6,13 +6,13 @@ extends Node2D const CHARGE_SKILL_IDS := ["heavy"] # 护甲类型图标占位——形状+色相双通道(art-bible):轻甲=◇ 灰石中性 / 魔法护甲=◆ 小人蓝 / -# 重甲=▣ 深金(避开 Boss 专属紫赤与妨害紫)。(自旧 StandeeView 平移) +# 重甲=▣ 深金(避开 Boss 专属紫赤与妨害紫)。 const ARMOR_ICONS := {"light": "◇", "ward": "◆", "heavy": "▣"} -# 名行/底座纵向预算余量(UI 设计对齐批 N2 2026-10-06——旧名行基线 = 盒底−1px「声明值刚好=容器值」 -# 同型高危写法返修;≥8px 硬余量 + 字形下探预算 ⇒ 12;取值不属色板,不进 ui_kit) +# 名行/底座纵向预算余量(盒底−1px「声明值刚好=容器值」系高危写法; +# ≥8px 硬余量 + 字形下探预算 ⇒ 12;取值不属色板,不进 ui_kit) const STANDEE_FOOT_MARGIN := 12.0 -var box := Vector2(150, 176) # 站桩盒尺寸(旧 Control custom_minimum_size;实际高随壳层 row 布局注入) +var box := Vector2(150, 176) # 站桩盒尺寸(实际高随壳层 row 布局注入) var font: Font = null # 世界字体槽位(null = ThemeDB.fallback_font——world.world_font 注入) var slot_row: StatusSlotRow # 状态效果唯一展示面 = 壳层伴随件(挂 BattleStageView 壳层,本体进世界) @@ -20,10 +20,10 @@ var _kind := "enemy" var _portrait_sprite: Sprite2D = null # 资产挂点(null = 未落位,字形在位) var _portrait_tex: Texture2D = null # 落位纹理引用(set_portrait_texture 装载;字形回退判据) var _portrait_flip := false -# 主角三态切换(迭代 6 T3):state 名 → 纹理(battle_stage_view 组合点注册);缺态=保持现纹理 +# 主角三态切换:state 名 → 纹理(battle_stage_view 组合点注册);缺态=保持现纹理 # (缺位回退链延伸——三态素材缺任一不炸不空)。敌站桩不注册不消费。 var _hero_tex := {} -enum HeroState { IDLE, RESET, ATTACK, HIT } # 主角三态+复位哨兵(迭代 27 T6——裸字符串 enum 化;外部 String 契约=register/set 形参零变化) +enum HeroState { IDLE, RESET, ATTACK, HIT } # 主角三态+复位哨兵(外部 String 契约=register/set 形参零变化) const _HS_NAME := {HeroState.IDLE: "idle", HeroState.RESET: "reset", HeroState.ATTACK: "attack", HeroState.HIT: "hit"} const _HS_VALUE := {"idle": HeroState.IDLE, "reset": HeroState.RESET, "attack": HeroState.ATTACK, "hit": HeroState.HIT} var _hero_state: int = HeroState.IDLE @@ -32,11 +32,11 @@ var _order := 1 var _intent_glyph := "" var _intent_col := Color.WHITE var _intent_visible := false -var _intent_scale := 1.0: # 意图弹入动画参数(旧 tween scale 等价) +var _intent_scale := 1.0: # 意图弹入动画参数 set(v): _intent_scale = v queue_redraw() -var _glyph_rot := 0.0: # 立绘前倾角(旧只转字形 Label——贴图态无此动画,等价平移) +var _glyph_rot := 0.0: # 立绘前倾角(贴图态无此动画) set(v): _glyph_rot = v queue_redraw() @@ -45,7 +45,7 @@ var _enemy_id := "" var _armor := "light" var _dead := false var _hp_max := 1.0 -var _hp_cur := 0 # 血量数字显示面(HUD框架 验收「血量数字可读」——2026-09-26 用户点名补数) +var _hp_cur := 0 # 血量数字显示面(HUD框架 验收「血量数字可读」) var hp_value := 1.0: # 血条值 0..1(直角递减——tween_property 目标,逐行刷新重启不累积) set(v): hp_value = clampf(v, 0.0, 1.0) @@ -66,21 +66,21 @@ func display_name() -> String: return _display_name -# 血条存在性探针出口(T5 断言等价改写——旧 _hp_bar ProgressBar 退役,世界直角血条常在) +# 血条存在性探针出口(世界直角血条常在) var has_world_hp_bar := true -# 意图徽标探针出口(T5——旧 _intent_badge.visible/text 改判) +# 意图徽标探针出口 func intent_probe() -> Dictionary: return {"visible": _intent_visible, "text": _intent_glyph} -# 名字行探针出口(T5——旧 _name_label/_armor_icon.text 改判) +# 名字行探针出口 func name_line_probe() -> Dictionary: return {"name": _display_name, "armor_icon": String(ARMOR_ICONS.get(_armor, "◇"))} -# ---- setter 面(投影契约与旧 StandeeView 一致——presenter/组合根零改排) ---- +# ---- setter 面(presenter/组合根零改排) ---- # data = 战斗结算 presentation_snapshot enemies[] 投影:{order, display_name, hp, max_hp, enemy_id, # pending_skill/pending_type/pending_name, effects[](敌方 side 增益——各立绘同值呈现)} @@ -106,7 +106,7 @@ func set_hero(hp: int, max_hp: int) -> void: _revive() # 新战斗开场 HP 回正——主角死亡残位随之复活(敌侧 set_data 同款语义) -# 血条短 tween 递减(直角递减占位——密度/缓动终稿归战斗表现批);逐行刷新时重启 tween 不累积 +# 血条短 tween 递减(直角递减占位);逐行刷新时重启 tween 不累积 func _set_hp(hp: int) -> void: _hp_cur = clampi(hp, 0, int(_hp_max)) var target := float(_hp_cur) / _hp_max @@ -161,22 +161,22 @@ func set_pending(ptype: String, pid: String) -> void: queue_redraw() return var glyph := "⚔" # 攻击系(damage) - var col: Color = UiKit.RED_MINE # 攻击预告红(危险红族——封印朱退役 2026-09-26,预告语义归封印色独占〔现行封印黑〕) + var col: Color = UiKit.RED_MINE # 攻击预告红(危险红族——预告语义归封印色独占〔现行封印黑〕) if ptype == "buff": glyph = "✦" # 增益系 - col = UiKit.HERO_BLUE_DEEP # 深档墨(N1-4——浅垫牌上 ≥4.5:1;原 HERO_BLUE 亮档对垫牌 2.5:1) + col = UiKit.HERO_BLUE_DEEP # 深档墨(浅垫牌上 ≥4.5:1) elif ptype == "debuff": - glyph = "☠" # 妨害系(新效应词汇批 2026-09-19) + glyph = "☠" # 妨害系 col = UiKit.DEBUFF_PURPLE if pid in CHARGE_SKILL_IDS: - col = UiKit.GOLD_INK # 重击类蓄力档(深金墨 N1——浅垫牌上 ≥4.5:1;原 GOLD_DEEP 2.5:1) + col = UiKit.GOLD_INK # 重击类蓄力档(深金墨——浅垫牌上 ≥4.5:1) _intent_glyph = glyph _intent_col = col _intent_visible = true _play_intent_motion() -# 意图三档动作动画终稿(样张 v2 冻结批 T3——§4.6.4 三档:①普通攻击=零表示〔set_pending 早退〕 +# 意图三档动作动画(§4.6.4 三档:①普通攻击=零表示〔set_pending 早退〕 # ②特殊准备=徽标弹入+二次弹跳(高举语义,运动手段 §2)③重击/硬化=缓推蓄力+定格微顿+回落; # 三档运动签名互异,灰度/剪影层可辨)。摇定时一次性短动画,随后静帧保持。 func _play_intent_motion() -> void: @@ -194,7 +194,7 @@ func _play_intent_motion() -> void: tw.tween_property(self, "_intent_scale", 1.0, UiKit.motion(0.13)) -# 资产挂点(战斗表现样张批):tex 落位后字形隐退、纹理立绘顶位——零代码换装契约;tex=null 回退字形。 +# 资产挂点:tex 落位后字形隐退、纹理立绘顶位——零代码换装契约;tex=null 回退字形。 # flip = 立绘朝向翻转(素材基准朝左时传 true 呈现朝右)。盒高 96px = 48px 立绘源整数 2× # (圣经 §8.2 禁非整数缩放)——源换代时随源重算。 func set_portrait_texture(tex: Texture2D, flip: bool = false) -> void: @@ -208,7 +208,7 @@ func set_portrait_texture(tex: Texture2D, flip: bool = false) -> void: if _portrait_sprite == null: _portrait_sprite = Sprite2D.new() _portrait_sprite.centered = false - _portrait_sprite.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST # 像素帧放大防糊(棋盘小人贴图批 2026-09-25) + _portrait_sprite.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST # 像素帧放大防糊 add_child(_portrait_sprite) _portrait_sprite.texture = tex _portrait_sprite.flip_h = flip @@ -217,7 +217,7 @@ func set_portrait_texture(tex: Texture2D, flip: bool = false) -> void: func _place_portrait() -> void: - # 立绘盒 = (0,44)-(box.x, box.y-36)(旧 FULL_RECT offsets 等价);48 源 ×2 整数档居中 + # 立绘盒 = (0,44)-(box.x, box.y-36);48 源 ×2 整数档居中 if _portrait_sprite == null or _portrait_tex == null: return var box_h := box.y - 44.0 - 36.0 @@ -238,16 +238,16 @@ func mark_dead() -> void: tw.tween_property(self, "rotation_degrees", 0.0, UiKit.motion(0.08)) _spawn_death_shards() # 碎裂退场(§4.6.4 语义硬规则:灰化+碎裂禁瞬间消失;§8.4 v2 冻结 5 块 0.45s) _refresh_portrait_glyph() - _intent_visible = false # 死亡残位意图退位(旧同款) + _intent_visible = false # 死亡残位意图退位 _set_hp(0) if slot_row != null: - slot_row.visible = false # 状态行随 mark_dead 同拍隐藏(批内代拍板②待追认) + slot_row.visible = false # 状态行随 mark_dead 同拍隐藏 -# ---- 演出密度终稿(样张 v2 冻结批 T3——程序化 tween,零新帧资产) ---- +# ---- 演出密度(程序化 tween,零新帧资产) ---- const DEATH_SHARD_N := 5 # 碎块数(§8.4 冻结值) -const HIT_SPARK_N := 6 # 命中火花数(迭代 6 T4 终稿——打击瞬间可读性一拍) +const HIT_SPARK_N := 6 # 命中火花数(打击瞬间可读性一拍) var _death_shards := 0 # 探针出口计数(碎块节点回收后仍保留读数) var _hit_sparks := 0 # 探针出口计数(命中火花累计) var _flash_count := 0 # 探针出口计数(受击闪白触发次数——主角路由断言面) @@ -279,7 +279,7 @@ func fx_probe() -> Dictionary: return {"death_shards": _death_shards, "hit_sparks": _hit_sparks, "flash_count": _flash_count} -# 命中瞬间打击特效(迭代 6 T4 终稿):立绘盒中心六枚短火花放射(程序化色块,确定性方向 +# 命中瞬间打击特效:立绘盒中心六枚短火花放射(程序化色块,确定性方向 # i*60°——禁全局随机;亮金/暖白交替=物理打击语义,不占 危险红=雷 与 奖励金=收益 的语义位)。 # 弹道到达拍由 battle_stage_view 调度(on_step_row_fx 延迟 0.33s≈弹道飞行)。 func play_hit_impact() -> void: @@ -304,7 +304,7 @@ func is_dead() -> bool: return _dead -# 受击闪白(结算演出占位——§2.2 受击反馈;强度时长复核迭代 6 T4=维持现行) +# 受击闪白(结算演出占位——§2.2 受击反馈;强度时长维持现行) func flash_hit() -> void: _flash_count += 1 if _hp_flash_tw != null and _hp_flash_tw.is_valid(): @@ -332,8 +332,8 @@ func _refresh_portrait_glyph() -> void: func _portrait_glyph() -> String: - # 字形回退已退役为纯缺位兜底(迭代 6 T2——八敌真图落位;旧三档体量字形 ▂/▆/█ 随退役, - # 相对体量语义由 48px 档统一比例承载)。缺位态:主角「人」/死亡「✕」/其余「敌」。 + # 字形回退仅作缺位兜底(八敌真图落位;相对体量语义由 48px 档统一比例承载)。 + # 缺位态:主角「人」/死亡「✕」/其余「敌」。 if _kind == "hero": return "人" if _dead: @@ -341,12 +341,12 @@ func _portrait_glyph() -> String: return "敌" -# 立绘落位探针出口(迭代 6 T2——站桩纹理非空断言面;缺位回退链保持的对照面) +# 立绘落位探针出口(站桩纹理非空断言面;缺位回退链保持的对照面) func portrait_probe() -> Dictionary: return {"has_tex": _portrait_sprite != null and _portrait_sprite.texture != null} -# ---- 主角三态切换(迭代 6 T3——攻击演出→attack/受击→hit/结算回 idle;§8.4 帧数档挂点) ---- +# ---- 主角三态切换(攻击演出→attack/受击→hit/结算回 idle;§8.4 帧数档挂点) ---- # 组合点注册(battle_stage_view _init——UiKit 常量 load_tex,缺位 null 不注册=该态保持现纹理) func register_hero_state(state: String, tex: Texture2D) -> void: @@ -399,14 +399,14 @@ func _pedestal_rect() -> Rect2: # 绘制内容矩形(世界局部;ui_struct_probe ⑥standee「不出框+下余量≥8px」断言读数面—— -# 最低绘制元素 = 底座下缘;N2 纵向余量纪律 2026-10-06) +# 最低绘制元素 = 底座下缘) func content_rect() -> Rect2: return Rect2(0.0, 0.0, box.x, _pedestal_rect().end.y) func _draw() -> void: var f := _efont() - # 椭圆落影(圣经 v3.5 批 B4 2026-09-30——§6.1 地台落影压脚:方向稿椭圆 (0,0,0,70),压在地台 + # 椭圆落影(圣经 §6.1 地台落影压脚:方向稿椭圆 (0,0,0,70),压在地台 # 上缘周围;24 段多边形近似椭圆,中心=台面上方 6px、横半径=台宽一半) var sh_center := Vector2(box.x * 0.5, box.y - 24.0) var sh_rx := (box.x - 36.0) * 0.5 @@ -417,13 +417,13 @@ func _draw() -> void: pts.append(sh_center + Vector2(cos(ang) * sh_rx, sin(ang) * sh_ry)) draw_colored_polygon(pts, Color(0, 0, 0, 0.27)) # 石板地台(v3.5——方向稿取色:板身/描边/顶缘受光线 2px——取色单点收 UiKit.STAND_STONE 族 - # (T4 裸色收口);几何沿用现行底座位〔margin 26/高 10→方向稿 18/12——按方向稿对齐〕) + # ;几何沿用现行底座位〔margin 18/高 12——按方向稿对齐〕) var ped := _pedestal_rect() draw_rect(ped, UiKit.STAND_STONE, true) draw_rect(ped, UiKit.STAND_STONE_EDGE, false, 1.0) draw_rect(Rect2(ped.position.x, ped.position.y, ped.size.x, 2.0), UiKit.STAND_STONE_RIM, true) - # 血条(直角递减):敌附顺位徽标(GOLD_BRIGHT ①②③——迭代 26 T3 换墨,旧 GOLD_DEEP 对舞台底 3.3:1 越带)——旧 top VBox 几何等价(左 8 / 右 -8) + # 血条(直角递减):敌附顺位徽标(GOLD_BRIGHT ①②③);血条几何左 8 / 右 -8 var bar_x := 8.0 if _kind == "enemy": var order_txt := String("①②③"[clampi(_order - 1, 0, 2)]) @@ -439,7 +439,7 @@ func _draw() -> void: # 数字=目标值即时刷新,条 tween 只管填充宽度;死残位 0/max 照常可读) var hp_txt := "%d/%d" % [_hp_cur, int(_hp_max)] var hts: Vector2 = f.get_string_size(hp_txt, HORIZONTAL_ALIGNMENT_LEFT, -1, 11) - # 对比度垫牌(UI 设计对齐批 N1-1/N1-2 2026-10-06——白 α.95 直压蓝条 2.67:1 违 §7.2; + # 对比度垫牌(白 α.95 直压蓝条 2.67:1 违 §7.2; # 中央垫 HP_BAR_BACK 深素牌 = 14.3:1;牌宽=字宽+8〔白名单取 8〕,高=条带全高;§4.1 数字色牌原则) draw_rect(Rect2(bar_x + (bar_w - hts.x) * 0.5 - 4.0, 2.0, hts.x + 8.0, 10.0), UiKit.HP_BAR_BACK, true) var hbase := Vector2(bar_x + (bar_w - hts.x) * 0.5, 2.0 + 5.0 + 4.0) @@ -451,9 +451,9 @@ func _draw() -> void: var prect := _portrait_rect() var glyph := _portrait_glyph() var center := prect.get_center() - # 坐标系注记(2026-09-26 错位修复):draw_set_transform 原点已置于 center——draw_string 的 + # 坐标系注记:draw_set_transform 原点已置于 center——draw_string 的 # pos 是**变换后的局部坐标**,须传相对 center 的偏移(-w/2 水平居中、+0.35h 基线下移); - # 旧实现传 center-… = 双重偏移,字形画到盒外(实机敌人立绘区空白的真因,截图取证) + # 传绝对 center 会成双重偏移、把字形画到盒外。 draw_set_transform(center, deg_to_rad(_glyph_rot), Vector2.ONE) var ts := f.get_string_size(glyph, HORIZONTAL_ALIGNMENT_LEFT, -1, 42) f.draw_string(get_canvas_item(), Vector2(-ts.x * 0.5, ts.y * 0.35), glyph, @@ -465,7 +465,7 @@ func _draw() -> void: var icenter := Vector2(box.x * 0.5, 86.0) draw_set_transform(icenter, 0.0, Vector2(_intent_scale, _intent_scale)) var its := f.get_string_size(_intent_glyph, HORIZONTAL_ALIGNMENT_LEFT, -1, 15) - # 对比度垫牌(UI 设计对齐批 N1-3/N1-4 2026-10-06——四色墨直压立绘纹理/暗舞台底 1.5-3.3:1 违 §7.2 + # 对比度垫牌(四色墨直压立绘纹理/暗舞台底 1.5-3.3:1 违 §7.2 # 「文字禁直压纹理底」;垫 PANEL_DATA 素牌后 atk 5.3/buf 4.8/debuff 4.7/charge 4.9 全 ≥4.5:1; # atk/debuff 零换墨、buf 换 HERO_BLUE_DEEP、charge 换 GOLD_INK;随弹入 transform 同步缩放) draw_rect(Rect2(-its.x * 0.5 - 4.0, -its.y * 0.75, its.x + 8.0, its.y * 1.1), UiKit.PANEL_DATA, true) @@ -473,19 +473,19 @@ func _draw() -> void: HORIZONTAL_ALIGNMENT_LEFT, -1, 15, _intent_col) # 局部坐标(同上注记——双重偏移修复) draw_set_transform(Vector2.ZERO, 0.0, Vector2.ONE) - # 底座下 护甲类型图标+名字 常驻行(敌 only——2026-09-26 用户终裁:AC 数值不展示,类型图标化) + # 底座下 护甲类型图标+名字 常驻行(敌 only——AC 数值不展示,类型图标化) if _kind == "enemy": var armor_txt := String(ARMOR_ICONS.get(_armor, "◇")) - var col: Color = UiKit.WARM_FAINT # 轻甲 = 暖白弱化(v3.5 暗底双色墨制——原灰石对暗底不可读) + var col: Color = UiKit.WARM_FAINT # 轻甲 = 暖白弱化(v3.5 暗底双色墨制) match _armor: "ward": - col = UiKit.HERO_BLUE_BRIGHT # 魔法护甲 = 小人蓝亮档(迭代 26 T3 换墨,旧 HERO_BLUE 对舞台底 3.2:1 越带) + col = UiKit.HERO_BLUE_BRIGHT # 魔法护甲 = 小人蓝亮档 "heavy": - col = UiKit.GOLD_BRIGHT # 重甲 = 金族亮档(迭代 26 T3 换墨,旧 GOLD_DEEP 对舞台底 3.3:1 越带) + col = UiKit.GOLD_BRIGHT # 重甲 = 金族亮档 var name_w := f.get_string_size(_display_name, HORIZONTAL_ALIGNMENT_LEFT, -1, 12).x var armor_w := f.get_string_size(armor_txt, HORIZONTAL_ALIGNMENT_LEFT, -1, 12).x var total_w := armor_w + 3.0 + name_w - var baseline := Vector2((box.x - total_w) * 0.5, box.y - 1.0 - STANDEE_FOOT_MARGIN) # N2 余量纪律(2026-10-06——旧值 box.y-1.0 离盒底 1px) + var baseline := Vector2((box.x - total_w) * 0.5, box.y - 1.0 - STANDEE_FOOT_MARGIN) # 纵向余量纪律 f.draw_string(get_canvas_item(), baseline, armor_txt, HORIZONTAL_ALIGNMENT_LEFT, -1, 12, col) f.draw_string(get_canvas_item(), baseline + Vector2(armor_w + 3.0, 0), _display_name, - HORIZONTAL_ALIGNMENT_LEFT, -1, 12, UiKit.WARM) # v3.5 暗底双色墨制(原 INK_TITLE 深墨对暗底不可读) + HORIZONTAL_ALIGNMENT_LEFT, -1, 12, UiKit.WARM) # v3.5 暗底双色墨制 diff --git a/game/presentation/views/status_panel.gd b/game/presentation/views/status_panel.gd index c1f1885f..5976d3ae 100644 --- a/game/presentation/views/status_panel.gd +++ b/game/presentation/views/status_panel.gd @@ -73,7 +73,7 @@ func open_status(data: Dictionary) -> void: # 道具工坊六行(解锁态文案与营地柜台同口径——退役/封存/已解锁/未解锁;进度=解锁判定量读数) -# 秘宝匣 12 行只读概览(迭代 22 T2 换代——旧工坊六行退役;数据源=treasure_shop_status 投影, +# 秘宝匣 12 行只读概览(数据源=treasure_shop_status 投影, # 解锁态文案与营地柜台同口径;进度列=解锁混合制三形态:钥石价/条件进度拼接/已入手) func _rebuild_workshop(data: Dictionary) -> void: for c in _workshop_holder.get_children(): diff --git a/game/presentation/views/status_slot_row.gd b/game/presentation/views/status_slot_row.gd index 51a39400..073aba28 100644 --- a/game/presentation/views/status_slot_row.gd +++ b/game/presentation/views/status_slot_row.gd @@ -5,12 +5,10 @@ class_name StatusSlotRow extends HBoxContainer const MAX_SLOTS := 4 -# 纹理映射(2026-09-24 状态图标接入批):effect_id→定稿纹理,全局恒定禁换图(图标键契约 §4.6 的 +# 纹理映射:effect_id→定稿纹理,全局恒定禁换图(图标键契约 §4.6 的 # 文件侧延伸——文件键 = status_.png,命名规范圣经 §8.3「对象键 = 数据表主键」)。 # 状态表九行全映射(attack_up/ac_up/weaken/alert/enrage/off_guard/sapped/empower/fortify) # ——HUD框架 图标键契约"一键一枚专属纹样,查不到的键立即断言 + 占位 + 诊断" -# (2026-09-15 格面资源批补 sapped;2026-09-16 护甲等级掷点批 defense_up → ac_up 换装; -# 同日 敌人技能池批补 empower/fortify 敌方增益两键——敌方增益显示 = 敌卡状态行文本 + 本图标键词汇)。 const EFFECT_ICON := { "attack_up": "res://assets/ui/icons/status_attack_up.png", "ac_up": "res://assets/ui/icons/status_ac_up.png", @@ -47,7 +45,7 @@ var _tip: PanelContainer var _tip_label: Label var _slots: Array[PanelContainer] = [] # 槽引用数组持有——tooltip _tip 悬停后入子节点表,按位序 get_child 会误取(BUG-0001) var _cleared_feedback := false -var compact := false # B 区站桩迷你档(2026-09-26 C 区精简批):16px 图标+层数角标、无 meta 行——tooltip 义务随组件迁入站桩 +var compact := false # B 区站桩迷你档:16px 图标+层数角标、无 meta 行——tooltip 义务随组件迁入站桩 func _init() -> void: @@ -73,8 +71,8 @@ func set_effects(effects: Array) -> void: _slots[i].visible = true -# battle_over 反馈(增益状态×4④):逐槽化光收回 + 微灰化(下次 set_effects 恢复常态; -# 2026-09-24 状态图标接入批:原字形 "✕ " 前缀随占位字形退役,灰化即清场反馈) +# battle_over 反馈:逐槽化光收回 + 微灰化(下次 set_effects 恢复常态; +# 灰化即清场反馈) func set_cleared_feedback() -> void: _cleared_feedback = true for slot in _slots: @@ -98,7 +96,7 @@ func _sync_slots(n: int) -> void: func _make_slot() -> PanelContainer: var slot := PanelContainer.new() if compact: - # 槽底不透明(2026-09-26 用户反馈:图标显示不清晰——半透明底叠 B 区米色面板吃掉白图标对比度; + # 槽底不透明(图标显示不清晰——半透明底叠 B 区米色面板吃掉白图标对比度; # 改深墨棕实底 = 白色纹样图标对比承载,槽界同时可辨) slot.add_theme_stylebox_override("panel", UiKit.panel_flat(UiKit.SLOT_BACKDROP, UiKit.PANEL_BORDER,UiKit.RADIUS_OBJECT, 1, Vector4(2, 1, 2, 1))) @@ -112,7 +110,7 @@ func _make_slot() -> PanelContainer: if compact: col.add_theme_constant_override("separation", 0) slot.add_child(col) - # 定稿纹理图标(P6 甲③ 2026-10-06:32px 源 → 常规档 32px=1×;mini(站桩)档 16px=0.5× + # 定稿纹理图标(32px 源 → 常规档 32px=1×;mini(站桩)档 16px=0.5× # 共用 §8.2 例外登记——线性过滤匹配抗锯齿矢量风源图) var icon := TextureRect.new() icon.custom_minimum_size = Vector2(32, 32) if not compact else Vector2(16, 16) @@ -184,7 +182,7 @@ func _on_slot_hover(slot: Control) -> void: # 图标键解析(HUD框架:查不到的键按错误处理——立即断言 + 占位 + 诊断,禁止静默显示空图标) -# 装载走 UiKit.load_tex 守卫(呈现层素材 preload 红线=0,UI 设计对齐批 N3 2026-10-06—— +# 装载走 UiKit.load_tex 守卫(呈现层素材 preload 红线=0—— # 素材缺位树上 preload 直接断言炸脚本;路径串表 + exists 守卫,缺位 null 走占位回退) func _icon_tex(effect_id: String) -> Texture2D: if EFFECT_ICON.has(effect_id): diff --git a/game/presentation/views/toast_stack.gd b/game/presentation/views/toast_stack.gd index 4328ed73..cc1daf92 100644 --- a/game/presentation/views/toast_stack.gd +++ b/game/presentation/views/toast_stack.gd @@ -7,7 +7,7 @@ extends Control const LIFE_SEC := 2.5 const MAX_SLOTS := 3 const COL_INFO := UiKit.INK -const COL_WARN := UiKit.RED_MINE # 危险红族——拒绝/作废(封印朱退役 2026-09-26) +const COL_WARN := UiKit.RED_MINE # 危险红族——拒绝/作废 const COL_GOLD := UiKit.GOLD_DEEP # 奖励金族——提示/达成(深金档) var _slot_box: VBoxContainer diff --git a/game/presentation/views/ui_kit.gd b/game/presentation/views/ui_kit.gd index cc10f5a4..4e483058 100644 --- a/game/presentation/views/ui_kit.gd +++ b/game/presentation/views/ui_kit.gd @@ -3,14 +3,14 @@ class_name UiKit extends RefCounted -# ── 色板(语义族;值 = 2026-09-20 收敛时现值) ── +# ── 色板(语义族) ── const INK := Color8(51, 38, 27) # 墨族——正文/数字(对格底 ≥4.5:1) -const INK_COLD := Color8(19, 46, 54) # 青墨 1-3 #132E36(数字墨三档·冷=稀疏——样张 v2 定稿 2026-09-28;亮瓦自适应深墨族档兼色牌后备路径) +const INK_COLD := Color8(19, 46, 54) # 青墨 1-3 #132E36(数字墨三档·冷=稀疏;亮瓦自适应深墨族档兼色牌后备路径) const INK_OCHRE := Color8(60, 37, 12) # 赭墨 4-5 #3C250C(数字墨三档·中;亮瓦自适应深墨族档兼色牌后备路径) const INK_RUST := Color8(74, 30, 20) # 锈墨 6-8 #4A1E14(数字墨三档·暖=密集;亮瓦自适应深墨族档兼色牌后备路径) -# ── 亮墨三档(圣经 v3.5 冻结④ 2026-09-30——数字直画已开格底:色温承袭密度语义,冷亮/暖白/金亮; +# ── 亮墨三档(圣经 v3.5 冻结④——数字直画已开格底:色温承袭密度语义,冷亮/暖白/金亮; # 实测对比 6.0–6.3:1(A3a);金亮低饱和避奖励金语义;色牌后备组用深墨族上牌〔12:1〕。 -# 2026-10-01 修订:亮墨族限暗纹理板(dungeon),亮筋纹板按 _digit_ink_mode 自适应切深墨三档)── +# 亮墨族限暗纹理板(dungeon),亮筋纹板按 _digit_ink_mode 自适应切深墨三档)── const INK_L_COLD := Color8(216, 236, 240) # 冷亮 1-3 #D8ECF0 const INK_L_WARM := Color8(240, 226, 200) # 暖白 4-5 #F0E2C8(关卡屏 WARM 同族) const INK_L_GOLD := Color8(248, 227, 168) # 金亮 6-8 #F8E3A8 @@ -19,41 +19,39 @@ const INK_TITLE := Color8(30, 26, 22) # 亮底标题墨 const INK_ROUTE := Color8(24, 20, 16) # 节点图最深墨 const INK_ON_GOLD := Color8(60, 44, 20) # 金底上的深墨 -const PANEL_DATA := Color8(233, 217, 184) # 面板底·数据框(AP 条/状态槽)#E9D9B8(P7 乙 2026-10-06——demo 唯一来源对齐,Δ≤6/255) -const PANEL_BORDER := Color8(120, 110, 88) # 面板细线框;兼熄灭点阵(DOT_OFF 别名)#786E58(P7 乙同上) +const PANEL_DATA := Color8(233, 217, 184) # 面板底·数据框(AP 条/状态槽)#E9D9B8(demo 唯一来源对齐,Δ≤6/255) +const PANEL_BORDER := Color8(120, 110, 88) # 面板细线框;兼熄灭点阵(DOT_OFF 别名)#786E58(demo 唯一来源对齐,Δ≤6/255) const GOLD := Color8(240, 168, 40) # 奖励金 const GOLD_DEEP := Color8(176, 122, 20) # 深金(金框描边/达意金) -const GOLD_INK := Color8(116, 80, 11) # 深金墨(意图蓄力徽标墨——PANEL_DATA 垫牌上 4.9:1,UI 设计对齐批 N1 2026-10-06) -const GOLD_BRIGHT := Color8(224, 184, 96) # 金族亮档(迭代 26 T3——敌顺位徽标①②③/重甲徽标对暗舞台底 6.5:1;值=收益金 e0b860 同门;GOLD_DEEP 语义岗〔standee:199 意图判据/board_view:35/level_map:237〕在役不动) +const GOLD_INK := Color8(116, 80, 11) # 深金墨(意图蓄力徽标墨——PANEL_DATA 垫牌上 4.9:1) +const GOLD_BRIGHT := Color8(224, 184, 96) # 金族亮档(敌顺位徽标①②③/重甲徽标对暗舞台底 6.5:1;值=收益金 e0b860 同门;GOLD_DEEP 语义岗〔standee:199 意图判据/board_view:35/level_map:237〕在役不动) const GOLD_LIT := Color8(230, 190, 90) # 亮金(候选高亮) const GOLD_DIM := Color8(140, 116, 60) # 暗金(已过节点) -const GOLD_DONE := Color8(104, 86, 44) # 已过节点暗金·关卡画面呈现态(关卡画面样张 v1 冻结新值 #68562C——旧 GOLD_DIM #8C743C 对双色墨均 <4.5:1 对比硬指标逼守;GOLD_DIM 他用不动) +const GOLD_DONE := Color8(104, 86, 44) # 已过节点暗金·关卡画面呈现态 #68562C(GOLD_DIM #8C743C 对双色墨均 <4.5:1,对比硬指标逼守此值;GOLD_DIM 他用不动) -const SEAL_BLACK := Color8(0, 0, 0) # 封印黑 #000000——封印(封印)宣告色(2026-09-28 - # 用户拍板封印朱→封印紫→封印黑:紫色与微光蓝族色相冲突,黑色无色相天然避开禁入带 - # 妨害紫 281° 各留 12-14° 间距;候选值样张批冻结;封印朱 #C63D22 退役) +const SEAL_BLACK := Color8(0, 0, 0) # 封印黑 #000000——封印宣告色(紫色与微光蓝族色相冲突故弃; + # 黑色无色相,天然避开禁入带——与妨害紫 281° 各留 12-14° 间距) const RED_DEEP := Color8(150, 60, 48) # 深朱(敌卡框/敌像) const RED_MINE := Color8(150, 44, 36) # 引爆雷字朱(已开危险格"雷"字) const RED_FORBID := Color8(120, 60, 50) # 禁止框朱 const RED_ALERT := Color8(200, 60, 48) # 报错朱 -const HERO_BLUE := Color8(46, 134, 222) # 小人蓝 #2E86DE(样张 v2 定稿 2026-09-28——圣经 §4.1 候选值冻结;旧 #2E6E8E 收敛期快照退役) -const HERO_BLUE_DEEP := Color8(30, 90, 150) # 小人蓝同族深档(意图增益徽标墨——PANEL_DATA 垫牌上 4.8:1;命名同 CONTACT_GLOW_DEEP 规则,UI 设计对齐批 N1 2026-10-06) -const HERO_BLUE_BRIGHT := Color8(126, 186, 240) # 小人蓝同族亮档(迭代 26 T3——魔法护甲徽标对暗舞台底 5.9:1;HERO_BLUE 语义岗〔board_view:35 小人边框/level_map:237〕在役不动) +const HERO_BLUE := Color8(46, 134, 222) # 小人蓝 #2E86DE(圣经 §4.1 冻结值) +const HERO_BLUE_DEEP := Color8(30, 90, 150) # 小人蓝同族深档(意图增益徽标墨——PANEL_DATA 垫牌上 4.8:1;命名同 CONTACT_GLOW_DEEP 规则) +const HERO_BLUE_BRIGHT := Color8(126, 186, 240) # 小人蓝同族亮档(魔法护甲徽标对暗舞台底 5.9:1;HERO_BLUE 语义岗〔board_view:35 小人边框/level_map:237〕在役不动) const BOSS_PURPLE := Color8(143, 47, 106) # 紫赤(Boss 专属) const DEBUFF_PURPLE := Color8(122, 66, 148) # 妨害紫(意图 ☠) -# ── 类型色五族(UI 设计对齐批 N4c 2026-10-06——值 = demo --tg-* 冻结抄录〔需求卡片 §2.2 抄录表〕; -# 前四族 = 实机现值搬运、第五族群伤 demo 值补族——实机原完全缺位,消费面 = tg_band() 同源判定)── +# ── 类型色五族(值 = demo --tg-* 冻结抄录〔需求卡片 §2.2 抄录表〕;消费面 = tg_band() 同源判定)── const TG_BUFF := Color8(194, 178, 100) # 通用增益/默认带 const TG_HEAL := Color8(102, 164, 87) # 回复 const TG_MAGIC := Color8(138, 114, 196) # 魔法 const TG_PIERCE := Color8(87, 160, 160) # 穿甲 const TG_AOE := Color8(226, 86, 118) # 群伤/AOE #E25676(demo --tg-aoe) -# 类型色带分族判定(N4c/Q4 甲——三选一与商店货架同源同判:id/kind 小写子串匹配,默认=通用增益带。 -# E5 回滚 2026-10-06:审计实证 demo「工兵爆破」卡=紫带(magic 族)——blast 归回 TG_MAGIC, +# 类型色带分族判定(三选一与商店货架同源同判:id/kind 小写子串匹配,默认=通用增益带。 +# demo「工兵爆破」卡=紫带(magic 族)——blast 归 TG_MAGIC, # TG_AOE 只接 aoe 键(spark_aoe 消费面保留);max_hp 含 hp 归回复族) static func tg_band(id_lower: String) -> Color: if id_lower.contains("heal") or id_lower.contains("hp"): @@ -66,24 +64,24 @@ static func tg_band(id_lower: String) -> Color: return TG_PIERCE return TG_BUFF -# ── 未开格类型微光五组(迭代 30 卡①——HUD框架「未开格类型微光」节实装面;Q3 甲案「不并入」卡顶带 +# ── 未开格类型微光五组(HUD框架「未开格类型微光」节实装面;「不并入」卡顶带 # TG_* 两套色带两套归组并存,禁互为引用)── -# 色相 = art-bible §4.2 样张 v2 冻结五组(既裁项:本批无重裁资格,只允许按明度档做亮度缩放)。 -# 🔴 冻结面稽核(2026-10-17 契约 5 停机呈报后用户裁定):逐组 HSV 对照冻结值——BUFF/HEAL/PIERCE/ -# MAGIC 四组 ΔH ≤0.13°(8bit 量化噪声)、ΔS ≤0.002,属纯 V 缩放;群伤组初版 #FF1A31 曾 ΔH 5.40° -# (朝纯红移动、侵蚀冻结绯对危险红的刻意错峰),用户裁「退回色相保持域」→ 改 #A61D37(冻结 -# #FF2D55 的 V=0.65 缩放,H=348.57°/S=0.824 逐位不动)。五组现均满足「只动明度、不动色相」。 -# 明度档 = 本批 Q2 甲案 provisional 值——补齐 §4.2 从未定义的「各组一档明度互辨」数值 -# (色弱灰度互辨通道;复核转正归战斗一屏样张批)。 -# 🔴 生成口径(2026-10-17 原型帧实测订正):阶梯必须在**渲染合成空间**(sRGB/伽马空间)里排—— +# 色相 = art-bible §4.2 冻结五组(色相既裁不可重裁,只允许按明度档做亮度缩放)。 +# 🔴 冻结面稽核:逐组 HSV 对照冻结值——BUFF/HEAL/PIERCE/ +# MAGIC 四组 ΔH ≤0.13°(8bit 量化噪声)、ΔS ≤0.002,属纯 V 缩放;群伤组 #A61D37(冻结 +# #FF2D55 的 V=0.65 缩放,H=348.57°/S=0.824 逐位不动,保持绯色相避开危险红)。 +# 五组均满足「只动明度、不动色相」。 +# 明度档 = provisional 值——补齐 §4.2 从未定义的「各组一档明度互辨」数值 +# (色弱灰度互辨通道)。 +# 🔴 生成口径:阶梯必须在**渲染合成空间**(sRGB/伽马空间)里排—— # 引擎 canvas 混合按帧缓冲编码(伽马)做线性插值,色弱玩家屏幕上看到的是合成值而非色值本身。 -# 首版按 CIE L*(线性)排档曾把群伤/魔法排反(绯红线性亮于紫罗兰,但伽马空间绯红 G+B 通道低, -# 合成后反而更暗——实测最弱对 CR 仅 1.05)。本版五档按合成空间单调阶梯重排:以「带内均值 ≈ +# 按 CIE L*(线性)排档会把群伤/魔法排反(绯红线性亮于紫罗兰,但伽马空间绯红 G+B 通道低, +# 合成后反而更暗——实测最弱对 CR 仅 1.05)。五档按合成空间单调阶梯排列:以「带内均值 ≈ # 0.49×色值 + 0.51×瓦片」合成模型反解,相邻组模型 CR = 1.245/1.234/1.239/1.270(判据线 # 1.20;模型域与实测的差 = shader 距离场权重非扁平混合,故互辨判据的终审在渲染取证探针实测, # L1 棋盘探针逐对读数见 reports/iter30-实现报告读数表)。 -# 明度档只许在 provisional 域内自调(L3 预授权③一轮),翻动色相 = 触 art-bible §4.2 既裁冻结面 -# = L3 停机呈报(2026-10-17 群伤组一案即此路径:停机呈报 → 用户裁 → 批内执行)。 +# 明度档只许在 provisional 域内自调(L3 预授权③一轮),翻动色相 = 触 art-bible §4.2 冻结面 +# = L3 停机呈报。 const TG_GLOW_BUFF := Color8(247, 223, 67) # 通用增益·芥末黄(attack/defense/weaken/action/gp) const TG_GLOW_HEAL := Color8(104, 208, 66) # 治疗·黄绿(heal) const TG_GLOW_PIERCE := Color8(48, 166, 166) # 穿刺·青(pierce) @@ -135,7 +133,7 @@ static func glow_color_for_group(g: int) -> Color: return Color(0, 0, 0, 0) -# ── 呈现散件裸色搬运(UI 设计对齐批 N4a 2026-10-06——原值搬运零观感;本节立后 ui_kit 之外 +# ── 呈现散件裸色搬运(本节立后 ui_kit 之外 # 呈现层裸 Color8 = 0,守卫 = ui_contrast_probe 静态段)── const INK_HINT := Color8(110, 69, 52) # 提示/警示暖棕墨(设置警示文/地图底栏组标) const INK_ON_DEEP := Color8(246, 238, 218) # 深底标题亮墨(主菜单标题/营地柜台等级章字) @@ -146,61 +144,60 @@ const HINT_STRIP_EDGE := Color8(74, 62, 48) # 棋盘底提示条描边(半 const RAP_DOT_CORE_WARM := Color8(248, 226, 168) # AP 点阵亮心(烛光黄族) const RAP_DOT_LIT_BLUE := Color8(105, 161, 232) # RAP 点阵亮面(小人蓝族) const RAP_DOT_CORE_BLUE := Color8(156, 194, 240) # RAP 点阵亮心(小人蓝族) -const E_FACADE_FOOT_COL := Color8(52, 42, 32) # 墙脚阴线(方向稿同色——原 board_cell_unit 局部) -const FOG_MEMORY_PLATE := Color8(58, 58, 58) # 记忆板 #3A3A3A(§6.5——原 board_cell_unit 局部) -const FOG_MEMORY_INK := Color8(196, 196, 196) # 记忆墨 #C4C4C4(对记忆板 ≈6.3:1——原局部) -const FOG_OUTLINE := Color8(30, 24, 18) # 雾面轮廓墨(原 board_cell_unit _draw 局部 oc) -const ICON_TINT_ON_GOLD := Color(24.0 / 240.0, 20.0 / 226.0, 16.0 / 200.0) # 当前金底图标墨 = WARM 分量乘法调制(双色墨制——原 level_map_screen 局部) +const E_FACADE_FOOT_COL := Color8(52, 42, 32) # 墙脚阴线(方向稿同色) +const FOG_MEMORY_PLATE := Color8(58, 58, 58) # 记忆板 #3A3A3A(§6.5) +const FOG_MEMORY_INK := Color8(196, 196, 196) # 记忆墨 #C4C4C4(对记忆板 ≈6.3:1) +const FOG_OUTLINE := Color8(30, 24, 18) # 雾面轮廓墨 +const ICON_TINT_ON_GOLD := Color(24.0 / 240.0, 20.0 / 226.0, 16.0 / 200.0) # 当前金底图标墨 = WARM 分量乘法调制(双色墨制) const DUSK := Color8(90, 108, 140) # 暮蓝(全作唯一暮蓝档——失败终局) const DIM_NIGHT := Color8(24, 18, 12) # 终局压暗底 #18120C(demo 结算仪式暗纱——胜利侧 dim 基色) const WARM := Color8(240, 226, 200) # 暖白(暗底正文) -const WARM_SOFT := Color8(232, 213, 168) # 暖白次级(说明文)#E8D5A8(M0 换代——灰米 #C8BCA6 退役,配色总纲「米色去灰」) -const WARM_FAINT := Color8(205, 184, 140) # 暖白弱化(帮助文)#CDB88C(M0 换代,同上) +const WARM_SOFT := Color8(232, 213, 168) # 暖白次级(说明文)#E8D5A8(配色总纲「米色去灰」) +const WARM_FAINT := Color8(205, 184, 140) # 暖白弱化(帮助文)#CDB88C(配色总纲「米色去灰」) const STONE := Color8(120, 110, 98) # 灰石(通道/箭头/失效) const STONE_FAINT := Color8(140, 124, 100) # 灰石弱化(占位提示文) -const STONE_DEEP := Color8(85, 77, 65) # 灰石深化(「已用」槽位墨——PANEL_DATA 槽牌 5.6:1 / 石皮 5.0:1,UI 设计对齐批 N1 2026-10-06;旧 STONE_FAINT 对亮底双向 <4.5:1) +const STONE_DEEP := Color8(85, 77, 65) # 灰石深化(「已用」槽位墨——PANEL_DATA 槽牌 5.6:1 / 石皮 5.0:1;STONE_FAINT 对亮底双向 <4.5:1,故另立此档) const DARK_UPCOMING := Color8(64, 58, 52) # 未达暗字(底/文同值) const BRICK := Color8(201, 175, 131) # 棋盘·未开掩尘地砖 #C9AF83 const FLOOR := Color8(179, 154, 120) # 棋盘·已开裸土 #B39A78 -const CONTACT_GLOW := Color8(214, 236, 255) # 可挖域接触带微光(蓝族浅一档·近白蓝——art-bible §3.2 v2.8 定稿; - # 旧绿相 DIG_EDGE 随画法切换退役 2026-09-26 批) +const CONTACT_GLOW := Color8(214, 236, 255) # 可挖域接触带微光(蓝族浅一档·近白蓝——art-bible §3.2 v2.8) const CONTACT_GLOW_DEEP := Color8(150, 190, 230) # 接触带呼吸暗端(lerp 目标) const DIGIT_PLATE := Color8(245, 234, 211) # 数字色牌(素色暖纸白直角牌——art-bible §4.1;数字一律垫牌, - # 可读不依赖格底——原则二;2026-09-26 呈现修复批落码) + # 可读不依赖格底——原则二) const DIGIT_PLATE_EDGE := Color8(210, 198, 172) # 色牌牌缘线 -const SLOT_BACKDROP := Color8(62, 54, 44) # B 区状态图标槽实底(深墨棕——白图标对比承载)#3E362C(P7 乙 2026-10-06 对齐) -const SLOT_BACKDROP_SOFT := Color8(128, 106, 78) # 图标槽实底·柔和档(迭代 26 T5②——BCard 图标槽明度差降档:对米色卡面 3.7:1〔旧深档 8.7:1 过硬〕,白图标 5.1:1 ≥3:1 图形对比硬约束;B 区状态槽仍用深档 SLOT_BACKDROP) +const SLOT_BACKDROP := Color8(62, 54, 44) # B 区状态图标槽实底(深墨棕——白图标对比承载)#3E362C +const SLOT_BACKDROP_SOFT := Color8(128, 106, 78) # 图标槽实底·柔和档(BCard 图标槽明度差降档:对米色卡面 3.7:1〔深档 8.7:1 过硬〕,白图标 5.1:1 ≥3:1 图形对比硬约束;B 区状态槽仍用深档 SLOT_BACKDROP) -const BG_ROOT := Color8(58, 46, 34) # 屏幕根底 #3A2E22(UI 落码批 M0 2026-10-04——配色总纲「提暖提亮禁近黑」,旧近黑 #1E1914 退役) -const BG_OVERLAY := Color8(54, 43, 32) # 模态遮罩底 #362B20(同批换代,旧 #1C1612 退役) -const BG_BRIGHT := Color8(69, 55, 35) # 暖亮档底 #453723(M0 新增——标题/营地/商店等暖亮屏根底) -const CANDLE := Color8(246, 198, 103) # 烛光黄 #F6C667(M0 新增——主操作色/候选节点/钥石徽章底; +const BG_ROOT := Color8(58, 46, 34) # 屏幕根底 #3A2E22(配色总纲「提暖提亮禁近黑」) +const BG_OVERLAY := Color8(54, 43, 32) # 模态遮罩底 #362B20 +const BG_BRIGHT := Color8(69, 55, 35) # 暖亮档底 #453723(标题/营地/商店等暖亮屏根底) +const CANDLE := Color8(246, 198, 103) # 烛光黄 #F6C667(主操作色/候选节点/钥石徽章底; # 与 §4.1 奖励金 #F0A828 分轨——圣经 §7.2 琥珀双岗注记) const DIM := Color(0.08, 0.06, 0.05) # 遮罩基色(用时乘 alpha) const TOAST_BG := Color(0.94, 0.91, 0.84, 0.95) # toast 面底 const TIP_BG := Color(0.16, 0.12, 0.09, 0.96) # tooltip 深底 -# 呈现杂色档(T4 裸色收口批 2026-10-02——各视图裸 Color8 字面量单点化;值 = 收口时各来源行现值快照) +# 呈现杂色档(各视图裸 Color8 字面量单点化) const STAGE_BG := Color8(62, 52, 42) # B 区舞台暗底(方向稿 render_battle_screen——battle_stage_view 面板底) const BEAM_LIGHT := Color8(255, 236, 200) # B 区顶光柱暖光(用时乘 alpha 渐隐——battle_stage_view 光柱层) const STAND_STONE := Color8(150, 130, 100) # 站桩石板地台·板身(standee_body 方向稿取色) const STAND_STONE_EDGE := Color8(90, 76, 58) # 站桩石板地台·描边 -const STAND_STONE_RIM := Color8(196, 172, 132) # 站桩石板地台·顶缘受光线(board_cell_unit 口沿高光已并档至此——清扫批 2026-10-02) -const CAMP_HEADER_BAND := Color8(110, 69, 38) # 营地柜台头带深棕 #6E4526(4-camp.png 方向稿取色——P7 乙 2026-10-06 对齐 demo --wood-deep) +const STAND_STONE_RIM := Color8(196, 172, 132) # 站桩石板地台·顶缘受光线 +const CAMP_HEADER_BAND := Color8(110, 69, 38) # 营地柜台头带深棕 #6E4526(4-camp.png 方向稿取色;对齐 demo --wood-deep) const CAMP_ROW_PLATE := Color8(240, 230, 206) # 营地行板暖米(同上) const CAMP_BADGE_PANEL := Color8(40, 32, 24) # 营地钥石徽暗底(同上) -const HP_BAR_BACK := Color8(40, 34, 32) # 迷你血条深底 #282220(关卡画面样张 v1 冻结——P7 乙 2026-10-06 对齐;兼 N1 血数垫牌) +const HP_BAR_BACK := Color8(40, 34, 32) # 迷你血条深底 #282220(兼血数垫牌) # BBCode 十六进制(RichTextLabel 用;与上同值) const HEX_GOLD := "f0a828" const HEX_INK := "33261b" const HEX_ON_GOLD := "3a2a08" -# 结算行/叙事行语义档(T4 收口批——battle_log_view 行格式化与 narrator 横幅行的裸 hex 单点化; -# 名随呈现语义、值 = 2026-09 起各行现值快照,色值逐字节不变) +# 结算行/叙事行语义档(battle_log_view 行格式化与 narrator 横幅行的裸 hex 单点化; +# 名随呈现语义) const HEX_LOG_ROUND := "9a8a72" # 轮次前缀/零值行暖灰石 const HEX_LOG_GAIN := "e0b860" # 收益金(GP 袋/商店行/败判定/节点横幅) const HEX_LOG_LOSS := "c47c7c" # 损失红(GP 流失/负效果) @@ -220,7 +217,7 @@ const DOT_OFF := PANEL_BORDER # ── 减动效(battle.md §Transitions 内建承诺:开启时时长减半;结算逐行兑现为信息载体降速不跳过)── -# 唯一入口 = 设置面开关(迭代 8 卡④ 转正;切片期调整板开关已随其退役,调整板本体 14.5 收进调试浮窗) +# 唯一入口 = 设置面开关(调整板本体在调试浮窗) static var motion_scale := 1.0 # 1.0 常态 / 0.5 减动效 static var victory_fx_style := "crest" # 胜利演出风格(P-C5 两套并存——"crest"碎砖拼纹章[默认冻结件]/"dust"尘金粒子;切换=调试浮窗,会话级) @@ -229,15 +226,15 @@ static func motion(dur: float) -> float: return dur * motion_scale -# ── 单位/特效纹理路径单点(棋盘小人贴图批 2026-09-25)── -# 素材 PNG 不入 git(用户裁定)——装载必须经 load_tex(exists 守卫),缺位返回 null 走各消费点 +# ── 单位/特效纹理路径单点 ── +# 素材 PNG 不入 git——装载必须经 load_tex(exists 守卫),缺位返回 null 走各消费点 # 的字形/无演出回退路径;禁 preload(素材缺位树上直接断言炸脚本,冒烟安全红线) const TEX_HERO_IDLE := "res://assets/art/character/character_hero_idle.png" const TEX_HERO_WALK := "res://assets/art/character/character_hero_walk.png" -const TEX_HERO_PORTRAIT := "res://assets/art/character/character_hero_portrait.png" # B 区站桩立绘·normal 态(48px 档,迭代 6 T3 换装=new-normal 源) -const TEX_HERO_ATTACK := "res://assets/art/character/character_hero_attack.png" # B 区站桩立绘·attack 态(迭代 6 T3 三态切换) -const TEX_HERO_HIT := "res://assets/art/character/character_hero_hit.png" # B 区站桩立绘·hit 态(迭代 6 T3 三态切换) -# 敌种立绘(B 区站桩 2026-09-26 槽接线批)——文件键 = 数据表主键 enemy_id(圣经 §8.3 命名规范), +const TEX_HERO_PORTRAIT := "res://assets/art/character/character_hero_portrait.png" # B 区站桩立绘·normal 态(48px 档) +const TEX_HERO_ATTACK := "res://assets/art/character/character_hero_attack.png" # B 区站桩立绘·attack 态(三态切换) +const TEX_HERO_HIT := "res://assets/art/character/character_hero_hit.png" # B 区站桩立绘·hit 态(三态切换) +# 敌种立绘(B 区站桩)——文件键 = 数据表主键 enemy_id(圣经 §8.3 命名规范), # 键集 = art-bible §4.6.4 八敌种;素材批入库前全部缺位(load_tex→null→字形回退),入库即显示零代码换装 const TEX_ENEMY_GOBLIN := "res://assets/art/character/character_enemy_goblin.png" # 地精 const TEX_ENEMY_BUGBEAR := "res://assets/art/character/character_enemy_bugbear.png" # 熊地精 @@ -248,7 +245,7 @@ const TEX_ENEMY_DUERGAR := "res://assets/art/character/character_enemy_duergar.p const TEX_ENEMY_HOOK_HORROR := "res://assets/art/character/character_enemy_hook_horror.png" # 钩爪恐魔 const TEX_ENEMY_DUERGAR_KING := "res://assets/art/character/character_enemy_duergar_king.png" # 灰矮人石君王 -# 框材组纹理槽(样张 v2 冻结批 T2 2026-09-28——♻ 复用件量化改色入包,产物 = tools/quantize_ui_skin.py, +# 框材组纹理槽(♻ 复用件量化改色入包,产物 = tools/quantize_ui_skin.py, # 全 CC0;缺位 = load_tex null → 程序化回退原路径,冒烟安全) const TEX_PANEL_STONE := "res://assets/art/ui/panel_stone.png" # 石板亮面板九宫格 48×48 const TEX_BUTTON_STONE := "res://assets/art/ui/button_stone.png" # 按钮九宫格·常态(可按的砖) @@ -259,14 +256,14 @@ const TEX_ICON_KEYSTONE := "res://assets/art/ui/icon_keystone.png" # const TEX_ICON_FORGE := "res://assets/art/ui/icon_forge.png" # 柜台一·属性锻造 const TEX_ICON_WORKSHOP := "res://assets/art/ui/icon_workshop.png" # 柜台二·道具工坊 const TEX_ICON_ATLAS := "res://assets/art/ui/icon_atlas.png" # 柜台三·奖励格图鉴 -# 节点图标五键(关卡画面样张 v1 冻结批 M-2 迭代 4 T2——20px 烘焙 1:1 消费,WARM 单色; +# 节点图标五键(20px 烘焙 1:1 消费,WARM 单色; # 对象键 = node_type 文件侧延伸 §8.3;缺位 = load_tex null → 字形回退) const TEX_NODE_BATTLE := "res://assets/art/ui/node_battle.png" # 节点图标·战斗房 const TEX_NODE_REWARD := "res://assets/art/ui/node_reward.png" # 节点图标·奖励房 const TEX_NODE_REST := "res://assets/art/ui/node_rest.png" # 节点图标·恢复房 const TEX_NODE_BOSS := "res://assets/art/ui/node_boss.png" # 节点图标·Boss 房 const TEX_NODE_SHOP := "res://assets/art/ui/node_shop.png" # 节点图标·商店房 -# 手绘功能图标十键(UI 落码批 M1 2026-10-04——20×20 像素 1:1/整数倍消费〔§8.2 甲类纪律〕; +# 手绘功能图标十键(20×20 像素 1:1/整数倍消费〔§8.2 甲类纪律〕; # 源=demo 原型 src 盘上件搬运;缺位 = load_tex null → 字形回退不炸) const TEX_ICON_SWORD := "res://assets/art/ui/icon_sword.png" # 图标·攻击系(锻造行/攻击强化卡) const TEX_ICON_SHIELD := "res://assets/art/ui/icon_shield.png" # 图标·护甲系 @@ -287,8 +284,8 @@ static func load_tex(path: String) -> Texture2D: return null -# ── 屏底氛围层(UI 设计对齐批 T5 2026-10-06——demo .tilebg opacity .14/.vignette/.beams 对齐; -# 旧「石纹全屏满铺不透」退役——demo 石纹只作弱质感,聚焦靠暗角)── +# ── 屏底氛围层(demo .tilebg opacity .14/.vignette/.beams 对齐; +# demo 石纹只作弱质感,聚焦靠暗角)── const BACKDROP_TILE_ALPHA := 0.14 # demo .tilebg{opacity:.14} const BG_MAP_TOP := Color8(74, 59, 42) # 地图屏渐变顶 #4A3B2A(demo #v-map 180deg 0%;低点 40% = BG_ROOT #3A2E22) @@ -323,16 +320,16 @@ static func vignette_rect() -> TextureRect: var tr := TextureRect.new() tr.texture = t tr.stretch_mode = TextureRect.STRETCH_SCALE - tr.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR # 平滑渐变件白名单(迭代 26 T2——全局 Nearest 下显式豁免) + tr.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR # 平滑渐变件白名单(全局 Nearest 下显式豁免) tr.set_anchors_preset(Control.PRESET_FULL_RECT) tr.mouse_filter = Control.MOUSE_FILTER_IGNORE return tr # 斜光带(demo #v-start .beams——repeating-linear-gradient 102deg,暖白 5% 窄带 240-340/560px; -# 程序纹理循环带,确定性生成零随机。迭代 26 T4 光柱硬边修(grilling Q7 裁=连续 alpha): -# 带内 alpha 0→0.05→0 横向过渡(旧匀净+零过渡硬边梯形退役)+纵向衰减上亮下暗; -# 纹理 filter=显式 LINEAR 白名单(与暗角/地图渐变同血统,见 T2) +# 程序纹理循环带,确定性生成零随机。光柱采用连续 alpha: +# 带内 alpha 0→0.05→0 横向过渡+纵向衰减上亮下暗; +# 纹理 filter=显式 LINEAR 白名单(与暗角/地图渐变同血统) static func beams_rect() -> TextureRect: var img := Image.create(560, 560, false, Image.FORMAT_RGBA8) var ca := cos(0.2094) # 12°(102deg 带轴的垂直倾角) @@ -353,7 +350,7 @@ static func beams_rect() -> TextureRect: var tr := TextureRect.new() tr.texture = ImageTexture.create_from_image(img) tr.stretch_mode = TextureRect.STRETCH_TILE - tr.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR # 平滑渐变件白名单(迭代 26 T2 Q7 裁——连续 alpha 与暗角/地图渐变同血统) + tr.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR # 平滑渐变件白名单(连续 alpha 与暗角/地图渐变同血统) tr.set_anchors_preset(Control.PRESET_FULL_RECT) tr.mouse_filter = Control.MOUSE_FILTER_IGNORE return tr @@ -373,13 +370,13 @@ static func gradient_base(top: Color, low: Color, stop := 0.4) -> TextureRect: var tr := TextureRect.new() tr.texture = t tr.stretch_mode = TextureRect.STRETCH_SCALE - tr.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR # 平滑渐变件白名单(迭代 26 T2——全局 Nearest 下显式豁免) + tr.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR # 平滑渐变件白名单(全局 Nearest 下显式豁免) tr.set_anchors_preset(Control.PRESET_FULL_RECT) tr.mouse_filter = Control.MOUSE_FILTER_IGNORE return tr -# CJK 随包字体(2026-09-27 用户拍板 Fusion Pixel OFL——CJK 覆盖+授权干净;命名遵 art-bible §8.3 +# CJK 随包字体(Fusion Pixel OFL——CJK 覆盖+授权干净;命名遵 art-bible §8.3 # 全小写 snake_case 域前缀)。守卫装载同 load_tex 纪律:缺位返回 null(引擎回退字体接手,不炸)。 const FONT_UI := "res://assets/fonts/ui_font_fusion_pixel_zh_hans.ttf" @@ -390,8 +387,8 @@ static func load_font(path: String) -> Font: return null -# ── 字号档位表(UI 设计对齐批 P3 甲 2026-10-06——WB G1 六档;全站 UiKit.label/字号 override 只许取 -# 本表,裸数字字号退役。归档映射:10/11/12→CAPTION、13/14→HINT、15/16→BODY、17/18/20→SUB、 +# ── 字号档位表(六档;全站 UiKit.label/字号 override 只许取 +# 本表。归档映射:10/11/12→CAPTION、13/14→HINT、15/16→BODY、17/18/20→SUB、 # 21/22/24/26→TITLE、32/40→H1(就近归档);棋盘数字公式 maxi(18, ceil(格边×0.5)) 与站桩血数 # 11px 条带内读数豁免不入表(art-bible §7.4)── const FS_CAPTION := 12 # 装饰 caption/分区小字/微计数(§7.4 豁免下限) @@ -401,7 +398,7 @@ const FS_SUB := 18 # 副标题/小组标题(=棋盘数字下限同值) const FS_TITLE := 24 # 屏标题/横幅/价格 const FS_H1 := 34 # 主标题/演算暴击 -# ── 秘宝解锁条件计数键 → 呈现标签(迭代 22 秘宝批 T4——秘宝匣柜台条件进度文案单点;键域= +# ── 秘宝解锁条件计数键 → 呈现标签(秘宝匣柜台条件进度文案单点;键域= # TreasureItemTable.UNLOCK_COUNTER_KEYS 封闭枚举,键出域走「条件」兜底不炸)── const TREASURE_REQ_LABELS := {"adventure_cleared": "通关", "boss_kill_count": "Boss击杀", "vision_used": "真视使用"} # 秘宝档位 → 呈现名(契约 2 三档;legendary 传说空集合法不在柜) @@ -409,10 +406,10 @@ const TREASURE_TIER_LABELS := {"common": "普通", "excellent": "优秀", "rare" # ── StyleBox 工厂 ── # margin = (左, 上, 右, 下);border_w = 0 即无边框(根底/遮罩用) -# 圆角率单点(UI 设计对齐批 P5 甲 2026-10-06——容器/按钮全站唯一圆角值;数据框/数字牌/AP 点阵/准线/血条 -# =0 直角不变;底座椭圆 17/结算金印 200/状态脉冲环 100 圆形 = §7.1 明示例外保留。取值=代拍板 5,可推翻) +# 圆角率单点(容器/按钮全站唯一圆角值;数据框/数字牌/AP 点阵/准线/血条 +# =0 直角不变;底座椭圆 17/结算金印 200/状态脉冲环 100 圆形 = §7.1 明示例外保留) const RADIUS_OBJECT := 5 -# 九宫格切片(P4 乙 2026-10-06——panel 石皮 8→16 与 demo .plate9 slice16 对齐;button 维持 8、仪式框维持 12) +# 九宫格切片(panel 石皮 16 与 demo .plate9 slice16 对齐;button 维持 8、仪式框维持 12) const PANEL_SLICE := 16.0 static func panel_flat(bg: Color, border: Color, corner: int = 0, border_w: int = 1, margin: Vector4 = Vector4.ZERO) -> StyleBoxFlat: var sb := StyleBoxFlat.new() @@ -427,8 +424,8 @@ static func panel_flat(bg: Color, border: Color, corner: int = 0, border_w: int return sb -# color 缺省哨兵 = alpha<0(真实用色不取负 alpha)——传色即一次到位(旧「label() 后跟 -# add_theme_color_override」两行式收单行);省略时保持旧默认:bold=INK_LABEL / 非 bold=主题缺省 +# color 缺省哨兵 = alpha<0(真实用色不取负 alpha)——传色即一次到位;省略时缺省 +# bold=INK_LABEL / 非 bold=主题缺省 static func label(text: String, size: int, bold: bool, color: Color = Color(-1, -1, -1, -1)) -> Label: var l := Label.new() l.text = text @@ -440,7 +437,7 @@ static func label(text: String, size: int, bold: bool, color: Color = Color(-1, return l -# ── 模态壳工厂(T4 收口批 2026-10-02——各 overlay 手搓 dim+Center+VBox/Panel 骨架单点化)── +# ── 模态壳工厂(各 overlay 手搓 dim+Center+VBox/Panel 骨架单点化)── # dim = 全屏半透明遮罩(全屏锚定纪律同既有各 overlay);center 全屏锚定居中;with_panel = 内容包 # PanelContainer(panel_sb 缺省 = 主题默认板——settlement_review 同款);box = 内容列 #(min_size/separation 参数化,min_size ZERO = 不设)。返回 Dictionary{dim, center, panel, box} @@ -475,8 +472,8 @@ static func modal_shell(parent: Control, dim_color: Color, min_size := Vector2.Z return {"dim": dim, "center": center, "panel": panel, "box": box} -# ── 全屏页壳(UI 设计对齐批 T6/T7 2026-10-06——demo #v-shop/#v-bonus 全屏页形态落地: -# 06 在册 D2 商店全屏化/D1 竖卡 232×352。暖底+石纹弱质感+暗角+56px 通栏顶条+内容列; +# ── 全屏页壳(demo #v-shop/#v-bonus 全屏页形态落地: +# 商店全屏化 + 竖卡 232×352。暖底+石纹弱质感+暗角+56px 通栏顶条+内容列; # 商店=暖亮底、三选一=根底,两屏同构差异仅底色与顶条工具件)── const PAGE_TOP_H := 56.0 @@ -518,9 +515,9 @@ static func scaled(base: int, pct: int) -> int: return maxi(1, int(round(float(base) * (100.0 + float(pct)) / 100.0))) -# 宽度纪律(ui-struct-probe 批 T3——全站按钮最小宽度基准 216+SIZE_FILL:VBox 列内拉满列宽等宽, +# 宽度纪律(全站按钮最小宽度基准 216+SIZE_FILL:VBox 列内拉满列宽等宽, # HBox 行内不抢余宽(EXPAND_FILL 会把行撑爆——营地底条 1616px 实证);角落小件/紧凑位传 0 豁免) -# 钮高纪律(2026-10-06 用户令「对齐好、不要那么细」——标题屏主钮 26px 对常规钮 38px 不齐的治根): +# 钮高纪律(统一全站钮高,消除标题屏主钮与常规钮不齐): # 全站常规钮统一最小高 40(主操作钮/危险钮经 button() 同高对齐,压扁形态从此不存在); # 豁免域与宽度纪律同款——min_w=0 紧凑位(HUD 顶条小钮/角标)不抬行高 const BUTTON_MIN_H := 40.0 @@ -535,7 +532,7 @@ static func button(text: String, min_w := 216.0) -> Button: return b -# ── 框材纹理工厂(样张 v2 冻结批 T2——§7.1 容器穿戏服、数据素面;缺位回退 flat/主题默认) ── +# ── 框材纹理工厂(§7.1 容器穿戏服、数据素面;缺位回退 flat/主题默认) ── # 九宫格 StyleBoxTexture(texture_margin 8px——quantize 脚本同值);tint 供消费点微调色调 static func _tex_sb(tex: Texture2D, margin: float, tint := Color.WHITE) -> StyleBoxTexture: var sb := StyleBoxTexture.new() @@ -549,8 +546,8 @@ static func _tex_sb(tex: Texture2D, margin: float, tint := Color.WHITE) -> Style # 石板亮面板(B 区舞台/C 区主面板/图例——容器穿戏服;数据框仍 panel_flat 素面 §7.1) -# Q1 丙(2026-10-06):content margin 低于切片的分量自动抬到切片——切片加大到 16 后石框纹理不吃内容 -# (T0 实查 9 消费面 7 处 margin<16;工厂单点 clamp,调用点零改) +# content margin 低于切片的分量自动抬到切片——切片 16 后石框纹理不吃内容 +# (9 消费面 7 处 margin<16;工厂单点 clamp,调用点零改) static func panel_skinned(margin: Vector4 = Vector4.ZERO, tint := Color.WHITE) -> StyleBox: var m := Vector4(maxf(margin.x, PANEL_SLICE), maxf(margin.y, PANEL_SLICE), maxf(margin.z, PANEL_SLICE), maxf(margin.w, PANEL_SLICE)) @@ -592,8 +589,7 @@ static func icon_rect(tex_path: String, px: float) -> TextureRect: return tr -# 钥石徽(badge 工厂件——Q10 甲收编 2026-10-06:原营地顶栏钥石徽本地拼装〔camp_overlay_view〕 -# 参数化收编,消费方 = 营地覆盖层 + 状态面板钥石余额行(迭代 17 卡③)。形制 = 烛光黄底+木色描边 +# 钥石徽(badge 工厂件——消费方 = 营地覆盖层 + 状态面板钥石余额行。形制 = 烛光黄底+木色描边 # +钥石图标(icon_rect 守卫装载,缺位=纯文本回退)+深墨字;零新素材零新色值——值全取现行 token) class KeystoneBadge: extends PanelContainer @@ -620,10 +616,10 @@ static func keystone_badge(text: String, icon_path := TEX_ICON_KEYSTONE, icon_px return KeystoneBadge.new(text, icon_path, icon_px) -# 按钮皮·五态矩阵(迭代 26 T1——UI 交互与观感批;甲/乙案值=grilling 两轮八裁落文,逐实例 override 不动主题层) -# 悬停=乙案:常态图+modulate 提亮(0.06 档与 primary_button 现行 lightened(0.06) 同纪律,零新素材); -# 禁用=甲案:本族底+α0.45 幽灵化(与 font_disabled_color 同纪律),取代旧「disabled=按压图」错配; -# 焦点=甲案:INK 2px 内缩 1px 环(与 font_focus_color=INK 同源;引擎 focus 样式盒叠加绘制,不遮钮底) +# 按钮皮·五态矩阵(逐实例 override 不动主题层) +# 悬停:常态图+modulate 提亮(0.06 档与 primary_button 现行 lightened(0.06) 同纪律,零新素材); +# 禁用:本族底+α0.45 幽灵化(与 font_disabled_color 同纪律); +# 焦点:INK 2px 内缩 1px 环(与 font_focus_color=INK 同源;引擎 focus 样式盒叠加绘制,不遮钮底) const BUTTON_HOVER_LIFT := Color(1.06, 1.06, 1.06, 1.0) # 悬停提亮档(modulate 乘数>1=中间调提亮,高光像素封顶不漂) const BUTTON_GHOST_ALPHA := 0.45 # 禁用幽灵化 α(与文字禁用同档) const BUTTON_FOCUS_RING_W := 2.0 # 焦点环宽 px @@ -659,10 +655,10 @@ static func _apply_button_skin(b: Button) -> void: b.add_theme_color_override("font_disabled_color", Color(INK, BUTTON_GHOST_ALPHA)) -# ── UI 落码批 M10 公共件(2026-10-04——bcard 竖卡工厂/拨杆开关/样式滑杆/动词按钮/tooltip 主题; -# 消费方 = M2 标题/M3 营地/M4 设置/M6 商店/M7 三选一。单点纪律同 §7.1:新件只加不改旧件)── +# ── 公共件(bcard 竖卡工厂/拨杆开关/样式滑杆/动词按钮/tooltip 主题; +# 消费方 = 标题/营地/设置/商店/三选一屏。单点纪律同 §7.1:新件只加不改旧件)── -# 动词按钮(图标+动词+悬停说明三件套——M2 标题屏按钮组/通用;icon 缺位=纯文字不炸) +# 动词按钮(图标+动词+悬停说明三件套——标题屏按钮组/通用;icon 缺位=纯文字不炸) static func verb_button(text: String, icon_path: String, tip := "") -> Button: var b := button(text) var tex := load_tex(icon_path) @@ -716,7 +712,7 @@ static func danger_button(text: String, tip := "", min_w := 216.0) -> Button: return b -# 卡顶类型色带·Bayer 有序抖动(UI 设计对齐批 P8 甲 2026-10-06——bcard band 平涂 ColorRect 退役; +# 卡顶类型色带·Bayer 有序抖动( # demo CSS 平滑渐变/blur 违反像素纪律,改 4×4 Bayer 有序抖动台阶:α 由深至 0,2px 元胞逐行降覆盖; # 纯静态绘制零动效(减动效无涉);Bayer 阶数=实现细节白名单项,取 4×4) class DitherBand: @@ -725,7 +721,7 @@ class DitherBand: func _init(c: Color) -> void: band = c - custom_minimum_size = Vector2(0, 8) # 8px = 4×4 Bayer 全周期(原平涂条 6px) + custom_minimum_size = Vector2(0, 8) # 8px = 4×4 Bayer 全周期 func _draw() -> void: var bayer := [[0, 8, 2, 10], [12, 4, 14, 6], [3, 11, 1, 9], [15, 7, 13, 5]] @@ -739,7 +735,7 @@ class DitherBand: draw_rect(Rect2(float(rx) * cell, float(ry) * cell, cell, cell), band, true) -# bcard 竖卡工厂(商店/三选一同构卡——M6/M7 共用;M7.1 差异仅=价签 vs ✓选择章) +# bcard 竖卡工厂(商店/三选一同构卡——两屏共用;差异仅=价签 vs ✓选择章) # set_selected 经 mark/样式换装 class BCard: extends PanelContainer @@ -749,30 +745,30 @@ class BCard: var desc_l: Label var price_l: Label var foot_l: Label - var body: VBoxContainer # 内容列(消费方经 add_footer 插件到底注前——M6 购买钮挂位) + var body: VBoxContainer # 内容列(消费方经 add_footer 插件到底注前——购买钮挂位) var _sb_normal: StyleBox var _sb_sel: StyleBox func _init(title: String, desc: String, band: Color, icon_path: String, price := "", footnote := "") -> void: var tex := UiKit.load_tex(UiKit.TEX_PANEL_STONE) - _sb_normal = UiKit.panel_skinned(Vector4(12, 10, 12, 10)) if tex != null else UiKit.panel_flat(PANEL_DATA, PANEL_BORDER,RADIUS_OBJECT, 1, Vector4(12, 10, 12, 10)) # 回退=数据板单点(P7 乙后同值,字面量退役) - _sb_sel = UiKit.panel_flat(PANEL_DATA, Color8(138, 90, 52), RADIUS_OBJECT, 2, Vector4(12, 10, 12, 10)) # 选中底=数据板单点(P7 乙后同值) + _sb_normal = UiKit.panel_skinned(Vector4(12, 10, 12, 10)) if tex != null else UiKit.panel_flat(PANEL_DATA, PANEL_BORDER,RADIUS_OBJECT, 1, Vector4(12, 10, 12, 10)) # 回退=数据板单点 + _sb_sel = UiKit.panel_flat(PANEL_DATA, Color8(138, 90, 52), RADIUS_OBJECT, 2, Vector4(12, 10, 12, 10)) # 选中底=数据板单点 add_theme_stylebox_override("panel", _sb_normal) - custom_minimum_size = Vector2(232, 352) # D1(UI 设计对齐批 T6 2026-10-06——demo .bcard 232×352;原 216×300) - size_flags_vertical = Control.SIZE_SHRINK_CENTER # 行容器不纵向拉伸(卡恒 352 高居中——T7 实测 HBox fill 拉到 ~536 修) + custom_minimum_size = Vector2(232, 352) # demo .bcard 232×352 + size_flags_vertical = Control.SIZE_SHRINK_CENTER # 行容器不纵向拉伸(卡恒 352 高居中——HBox fill 会拉到 ~536) var box := VBoxContainer.new() box.add_theme_constant_override("separation", 8) add_child(box) body = box - var band_r := DitherBand.new(band) # P8 甲:卡顶类型色带=Bayer 有序抖动带(随各 TG_* 逐卡着色) + var band_r := DitherBand.new(band) # 卡顶类型色带=Bayer 有序抖动带(随各 TG_* 逐卡着色) box.add_child(band_r) mark = UiKit.label("✓",FS_BODY, true, Color8(58, 42, 8)) mark.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT mark.visible = false box.add_child(mark) - # 图标槽(demo .ic 76×76 槽底+图标 60=20px 源 3 整数倍——P6 甲④ 2× 档升 3× 随 D1 对齐) + # 图标槽(demo .ic 76×76 槽底+图标 60=20px 源 3 整数倍) var slot := PanelContainer.new() - slot.add_theme_stylebox_override("panel", UiKit.panel_flat(SLOT_BACKDROP_SOFT, PANEL_BORDER, 0, 1)) # 迭代 26 T5② 明度差降档(柔和档;白图标 ≥3:1 硬约束在役) + slot.add_theme_stylebox_override("panel", UiKit.panel_flat(SLOT_BACKDROP_SOFT, PANEL_BORDER, 0, 1)) # 明度差降档(柔和档;白图标 ≥3:1 硬约束在役) slot.custom_minimum_size = Vector2(76, 76) slot.size_flags_horizontal = Control.SIZE_SHRINK_CENTER box.add_child(slot) @@ -795,7 +791,7 @@ class BCard: var spacer := Control.new() spacer.size_flags_vertical = Control.SIZE_EXPAND_FILL box.add_child(spacer) - price_l = UiKit.label(price,FS_TITLE, true, GOLD_INK) # 尾裁微批a 2026-10-08——GOLD 对货架板 1.46:1 越带,换深金墨 5.21:1(三选一价签恒空串隐藏零波及) + price_l = UiKit.label(price,FS_TITLE, true, GOLD_INK) # GOLD 对货架板 1.46:1 越带,换深金墨 5.21:1(三选一价签恒空串隐藏零波及) price_l.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER price_l.visible = price != "" box.add_child(price_l) @@ -846,7 +842,7 @@ static func switch_toggle(initial: bool) -> SwitchToggle: return SwitchToggle.new(initial) -# 样式滑杆/tooltip 主题两处局部做法已退役(迭代 25 UI 全局主题批 2026-10-13——词条迁 -# game/assets/theme/main_theme.tres 全局主题单点:滑轨 slider/grabber_area/grabber、 -# TooltipPanel/TooltipLabel;旧实现同批删除,禁新旧并存。消费方几何内联: -# settings_overlay 音量滑轨 / debug_overlay _slider_row) +# 样式滑杆/tooltip 主题词条单点迁 +# game/assets/theme/main_theme.tres 全局主题:滑轨 slider/grabber_area/grabber、 +# TooltipPanel/TooltipLabel;禁新旧并存。消费方几何内联: +# settings_overlay 音量滑轨 / debug_overlay _slider_row diff --git a/game/smoke/adventure_monte_carlo.gd b/game/smoke/adventure_monte_carlo.gd index d36c32ac..28ba0148 100644 --- a/game/smoke/adventure_monte_carlo.gd +++ b/game/smoke/adventure_monte_carlo.gd @@ -1,5 +1,4 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# Date: 2026-09-21 # 冒险全流程期望扫描(三关连探零加成基线批量试玩——run_adventure 的蒙特卡洛批量工具, # 补 level_monte_carlo 只测单关的空白面):固定 atk+0%/hp+0%(零天赋格加成,关间大奖励 # 按冒险结构现行设计自动兑付),逐局独立种子,输出: @@ -34,23 +33,23 @@ func _initialize() -> void: var route := "min" if args.size() >= 4 and args[3] in ["min", "max"]: route = args[3] - # 同调分层开关(迭代 11 第①批 T8——off=现行基线零装配零扰动;on=贪心装配画像,确定性同种子可复放) + # 同调分层开关(off=现行基线零装配零扰动;on=贪心装配画像,确定性同种子可复放) var attune_mode := "off" if args.size() >= 5 and args[4] in ["off", "on"]: attune_mode = args[4] - # 商店分层开关(迭代 11 第②批 T5——off=legacy 对照缺省零扰动;on=共享池货架面,终局池读数随行) + # 商店分层开关(off=legacy 对照缺省零扰动;on=共享池货架面,终局池读数随行) var shop_mode := "off" if args.size() >= 6 and args[5] in ["off", "on"]: shop_mode = args[5] - # 特性/树分层开关(迭代 12 T7/T10——off=基线;formed=成型画像开局注入五事件族 14 件成型集 + # 特性/树分层开关(off=基线;formed=成型画像开局注入五事件族 14 件成型集 # 〔测量面专用 params.relics_seed——真实局规则改写型特性只走局内随机渠道〕;ab_a/ab_b=Fork posture 两侧 - # rule 键集——A/B 面两侧差 <~3pp 验收载体;rules=任意树规则键集注入〔逗号分隔 args[7]——迭代 21 V19 三组配对载体〕) + # rule 键集——A/B 面两侧差 <~3pp 验收载体;rules=任意树规则键集注入〔逗号分隔 args[7]——V19 三组配对载体〕) var feat_mode := "off" if args.size() >= 7 and args[6] in ["off", "formed", "ab_a", "ab_b", "rules"]: feat_mode = args[6] var feat_profile := {} if feat_mode == "formed": - # 迭代 20 T8 画像换代——旧 14 件随老 27 件退役;新画像=五事件族覆盖 14 件 + # 成型画像=五事件族覆盖 14 件 # (开格 4/封印 3/踩雷 4/节奏 2/战斗 1——每族含跨事件账本件,账本件=攒层/计数面 MC 读数承载) feat_profile = {"mode": "on", "seed_ids": [ "twin_pick", "geologist", "hard_hat", "frontier_miner", @@ -63,7 +62,7 @@ func _initialize() -> void: elif feat_mode == "ab_b": feat_profile = {"mode": "off", "tree_rules": ["posture_bulwark"]} elif feat_mode == "rules": - feat_profile = {"mode": "off", "tree_rules": String(args[7] if args.size() >= 8 else "").split(",")} # 迭代 21 V19——任意键集配对注入 + feat_profile = {"mode": "off", "tree_rules": String(args[7] if args.size() >= 8 else "").split(",")} # V19——任意键集配对注入 var db = load("res://core/config_db.gd").new() if not db.load_tables("res://data/tables", false): print("表加载失败") @@ -71,10 +70,10 @@ func _initialize() -> void: return var attune_profile := {} if attune_mode == "on": - # 贪心画像:Slots=3(迭代 21 V14 换代——槽位判定源=树同调位节点点亮数,模拟画像=三节点 - # 全点亮常量;原「中间进度计数经谓词表求值」随 attunement_growth 谓词表退役);装配序 = + # 贪心画像:Slots=3(槽位判定源=树同调位节点点亮数,模拟画像=三节点 + # 全点亮常量);装配序 = # 表序 passive 优先至 Slots-1 + 首个 active(slots=3 → [淬毒刃纹, 标中殉爆, 掘进蓄能], - # provisional 画像归调参批);Y = 营地升级 Lv1 表值 1。autoplay 默认不刷——Y 仅注入容量, + # provisional 画像归调参);Y = 营地升级 Lv1 表值 1。autoplay 默认不刷——Y 仅注入容量, # 刷新消费归玩家策略面(钓鱼归玩家)。 var slots: int = 3 var passives: Array = [] @@ -126,7 +125,7 @@ func _initialize() -> void: "mine_dmg": int(st.get("mine_dmg", 0)), "taken": int(st["hero_dmg"]) + int(st.get("mine_dmg", 0)), "refreshes": int(st["refreshes"]), "choices": int(st["choices"]), - # 封印经济五字段(迭代14②判式换代批 T1——η=seal_hit÷seal_placed、标空率=seal_miss÷seal_placed + # 封印经济五字段(η=seal_hit÷seal_placed、标空率=seal_miss÷seal_placed # 派生归分析侧;gain/penalty=结算流水行值合计(原始行值口径,等价换算归判读侧——登记)) "seal_placed": int(st.get("seal_placed", 0)), "seal_hit": int(st.get("seal_hit", 0)), "seal_miss": int(st.get("seal_miss", 0)), @@ -141,7 +140,7 @@ func _initialize() -> void: "wallet_count": (st["wallet_events"] as Array).size(), } if shop_mode == "on": - # pool 面增量字段(迭代 11 第②批 T5——off 行零新增保对拍逐位干净) + # pool 面增量字段(off 行零新增保对拍逐位干净) rec["shop_mode"] = "pool" rec["shop_buys"] = int(st.get("shop_buys", 0)) rec["pool_stock"] = st.get("pool_stock", {}) diff --git a/game/smoke/auto_player.gd b/game/smoke/auto_player.gd index 5adb5d68..37f092a0 100644 --- a/game/smoke/auto_player.gd +++ b/game/smoke/auto_player.gd @@ -1,5 +1,4 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# Date: 2026-09-13(自动玩家策略单一实现) # 自动玩家策略集(headless 冒烟/扫描/转储共用的理性玩家近似): # choose_dig = 挖最近可挖格(先移到邻接已开格)。 # 无 window_selection(道具窗口确定性选择——道具窗口已下线)。 @@ -28,13 +27,13 @@ static func choose_dig(minesweeper) -> Dictionary: return {} -# ==================== 普通策略档 v2·基础定式画像(2026-09-19 用户拍板——替代旧"无推理最近格"口径) ==================== +# ==================== 普通策略档 v2·基础定式画像 ==================== # 扫雷推理分级(经典定式文献口径):新手级 = 单数字满足规则——「数字 = 邻雷未开数 ⇒ 全是雷(满足即标)」 # 「数字 = 已封印数 ⇒ 余邻全安全(满足即开)」,教学一眼会、正常玩家两局即会的最低门槛判断; # 进阶级 = 联动定式(1-1 / 1-2 / 1-2-1 / 1-2-2-1 / 子集缩减)与概率分析——本切片归完美档 subset 推理承载, # 不入普通画像(新手不可靠掌握)。本档语义 = 只做新手级推理 + 无处可推时按既有口径盲挖边界格(新手冲动)+ -# 不主动刷新(新手无刷新策略意识)。测量定位:教会基础规则后的真实玩家下限近似(旧"乱点/最近格"口径测的是 -# 无认知玩家下限,对通关率带判读失真——2026-09-18/19 普通画像 0%/5% 越带下界与真人方向性结论矛盾)。 +# 不主动刷新(新手无刷新策略意识)。测量定位:教会基础规则后的真实玩家下限近似 +# (乱点/最近格口径测的是无认知玩家下限,对通关率带判读失真,不作普通画像)。 # 普通画像单步决策入口(每动作一查——挖掘揭示新数字后重推理):move/dig/seal/stop 四值(无 refresh)。 static func novice_action(minesweeper) -> Dictionary: @@ -74,7 +73,7 @@ static func _deduce_single(minesweeper) -> Dictionary: return {"safe": _row_major(safe), "mines": _row_major(mines)} -# ==================== 完美策略档(2026-09-14 用户拍板:OQ7 技能轴上界测量仪——只作测量,非玩法数值) ==================== +# ==================== 完美策略档(OQ7 技能轴上界测量仪——只作测量,非玩法数值) ==================== # 策略语义:零盲挖(只挖已证安全格 ⇒ 构造保证零踩雷)· 已证危险格全封印(封印先于挖——封印 = 纯收益 # 〔轮末 weaken + 魔法 首次充能〕且雷上封印不阻连锁)· 卡死且刷新资源可用 → 轮内刷新 # (经 settlement.player_request_refresh 核心编排)· 否则停手(残 AP 1:1 转存 RAP——下轮刷新资源)。 @@ -210,7 +209,7 @@ static func _row_major(cells: Dictionary) -> Array: return out -# 卡死赌挖选格(普通档 v3.1 2026-10-01——模拟档位重构):概率启发近似真人「挑看起来最安全的一格」。 +# 卡死赌挖选格(普通档 v3.1):概率启发近似真人「挑看起来最安全的一格」。 # 危险度 = 该格对每个邻接已证数字约束取(余雷数/未知数)比值中的最小值(= 任一邻数字视角下的 # 最低雷占比——single 已证安全格在进入本函数前已被 perfect_action 消化,故卡死态比值恒 >0); # 同危险度行主序先到先得。纯查询面零 RNG(确定性保回放);寻路同 choose_dig(目标已开 8 邻 diff --git a/game/smoke/board_shot_probe.gd b/game/smoke/board_shot_probe.gd index 6a367141..3c0688a6 100644 --- a/game/smoke/board_shot_probe.gd +++ b/game/smoke/board_shot_probe.gd @@ -7,10 +7,10 @@ # 护栏:headless fail-fast(shot_probe 同款);空纹理取证 fail——取证段失败=闸红, # 零字节/空纹理不允许静默落盘;board_meta.json 取样坐标落盘(棋盘视图全局矩形—— # golden 前置裁剪坐标源,禁硬编码像素)。 -# 迭代 30 卡① T2-④ 双帧取证:每关抓 微光开(生产默认态·Q4 丙案)/关(golden 基线保护面) +# 双帧取证:每关抓 微光开(生产默认态·Q4 丙案)/关(golden 基线保护面) # 两帧——① 开帧逐像素判定「非生效格零变化」(禁整格染色/禁越圈;生效格内只准落在内缘 # 带 = cell÷8)② 每个生效格须有实绘像素(微光不空转)③ 关帧即 golden 对比帧(原名落盘, -# 基线 2026-09-30 代不重制——契约 1 off 态基线)。隔离纪律 = 与 type_glow_shot_probe 同款: +# 基线不重制——契约 1 off 态基线)。隔离纪律 = 与 type_glow_shot_probe 同款: # 前置 UiKit.motion_scale=0.5 冻结接触带呼吸相位(静态带色),两帧差异唯一定位在类型微光。 extends Node @@ -41,7 +41,7 @@ func _ready() -> void: push_error("[board_shot] 表加载失败") get_tree().quit(1) return - # 双帧单一变量隔离(迭代 30 卡①):冻结接触带呼吸相位——motion_scale<1.0 ⇒ _apply_contact_bands + # 双帧单一变量隔离:冻结接触带呼吸相位——motion_scale<1.0 ⇒ _apply_contact_bands # 施静态色(减动效停格路径)。必须在 rebuild 前置位(rebuild/set_dig_glow_enabled 按当时相位 # 重施带色)。golden 侧影响:静态带色=呼吸周期中值,与基线捕获相的像素差最坏 ≈灰度24 于 # 接触带像素(占比 <0.4%),≤2% 判据不受影响;停格同时令「非生效格零变化」可精确判定。 @@ -77,17 +77,17 @@ func _ready() -> void: add_child(view) # 身份解析接线(生产同源——main.gd:251 set_identity_resolver(_identity_lookup)):必须在 # rebuild / set_dig_glow_enabled 前接好,二者尾链 _recompute_glow 同步读身份建作用集。 - # 裸视图不接 = _identity_cb 无效 ⇒ info 恒 null ⇒ 作用集恒空(2026-10-17 首两次实跑 - # 三关 glow=0 根因——双帧比对空转、PASS 假绿)。现值经 _cur_settlement 成员读入 + # 裸视图不接 = _identity_cb 无效 ⇒ info 恒 null ⇒ 作用集恒空(三关 glow=0 根因—— + # 双帧比对空转、PASS 假绿)。现值经 _cur_settlement 成员读入 # (仿生产 run_scope.settlement;bind 传参有 Callable 类型校验坑,见成员注)。 view.set_identity_resolver(_probe_identity_lookup) view.rebuild(settlement.minesweeper.current_board(), settlement.minesweeper) # 进挖掘相位(生产态 = hud_presenter.set_dig_glow_enabled(not settling) 接线——裸视图默认 - # _dig_glow=false,接触带与类型微光同源门控都不渲染;golden 基线 2026-09-30 代即捕获于 + # _dig_glow=false,接触带与类型微光同源门控都不渲染;golden 基线即捕获于 # 该裸态。双帧取证要求生产默认态,故显式开——两帧均含静态接触带(motion_scale=0.5 停格), # 差异唯一定位在类型微光开关) view.set_dig_glow_enabled(true) - # 抓帧前等入场动画完结(迭代 19 卡① S2 观察项根因修复 2026-10-08):rebuild 有全板淡入 + # 抓帧前等入场动画完结(S2 观察项根因):rebuild 有全板淡入 # motion(0.2)+R0 涟漪逐格延迟显形(motion(0.04×离板心距离)+motion(0.12),最远格 ≈0.56s), # 原制 6 个 process_frame 热机后 ≈0.1s=捕在涟漪中途——逐跑帧时序抖动使揭示 alpha 漂移, # golden L2/L3 跨 2% 容差线波动(实测 0.00-2.53%)。改时间制 1.2s(2×余量)=锚定动画完结态。 @@ -151,7 +151,7 @@ func _probe_identity_lookup(c: Vector2i): return _cur_settlement.query_reward_identity(c) -# 双帧逐像素比对(迭代 30 卡① T2-④-①②):所有变化像素必须落在生效格的内缘带内 +# 双帧逐像素比对:所有变化像素必须落在生效格的内缘带内 # (de < cell÷8——带外含砖心零侵入=禁整格染色/禁越圈);每个生效格须有实绘像素(不空转)。 func _check_dual_frames(tag: String, view, glow_cells: Dictionary, off_img: Image, on_img: Image) -> void: var board = view.board() diff --git a/game/smoke/board_stat_probe.gd b/game/smoke/board_stat_probe.gd index 0777f4a6..3dae7f2e 100644 --- a/game/smoke/board_stat_probe.gd +++ b/game/smoke/board_stat_probe.gd @@ -1,6 +1,5 @@ # VERTICAL SLICE - NOT FOR PRODUCTION # 定位:分析工具·非验收件——零断言取数工具,不出入任何闸。 -# Date: 2026-09-19 # 棋盘板形统计探针(判式"实测板形"口径的数据源): # 对 board_gen.tres 每行 (L, D) 生成 N 张板,统计幸存雷数 |M| 与安全格数 |S| # 的均值 / 最小 / 最大("先布后删"后的落地值——名义值 density×(W×H−9) 不含删除段)。 diff --git a/game/smoke/calibrate_boards.gd b/game/smoke/calibrate_boards.gd index 680c9852..54836ef1 100644 --- a/game/smoke/calibrate_boards.gd +++ b/game/smoke/calibrate_boards.gd @@ -1,6 +1,5 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# Date: 2026-09-22 -# 棋盘口径校准(分析会话取数工具——冒险零加成批完成度分母实证): +# 棋盘口径校准(分析会话取数工具——冒险零加成完成度分母实证): # 逐 board_gen 行真实生成 N 板,统计 实际雷数/安全格数/R₀ 初始展开占比—— # 生成期「先布后删+可推理率重试」使实际雷数远低于表口径 round(d×(W×H−9)), # 日志侧只有清图板可反推 safe_total(未清图深度无样本),本工具给全网格精确分母。 @@ -36,7 +35,7 @@ func _initialize() -> void: "mine_density": float(row.mine_density), "inferability_target": float(row.inferability_target), "solver_rules": String(row.solver_rules), "min_safe_count": int(row.min_safe_count), "max_gen_attempts": int(row.max_gen_attempts), "board_type": String(row.board_type), - # 初始展开收窄批(迭代14①)两新参数透传(.get 缺省与生成器防御口径一致) + # 初始展开收窄两参数透传(.get 缺省与生成器防御口径一致) "shave_ring_radius": int(row.get("shave_ring_radius", 1)), "r0_max_cap": int(row.get("r0_max_cap", 0)), } diff --git a/game/smoke/damage_probe.gd b/game/smoke/damage_probe.gd index 38bbc3bd..cffa9d02 100644 --- a/game/smoke/damage_probe.gd +++ b/game/smoke/damage_probe.gd @@ -1,6 +1,6 @@ # VERTICAL SLICE - NOT FOR PRODUCTION # 定位:诊断工具·非验收件——不出入任何闸(probe_gate/render_gate/run_smoke 全不涉)。 -# Date: 2026-09-13(playtest-2026-09-12 报告 Top1——零承伤根因分割探针) +# playtest-2026-09-12 报告 Top1——零承伤根因分割探针 # 检查面:H1 hero_defense 池仅 off_guard 正向行(×0 墙结构面不存在); # H2 Boss/敌攻击链健康——fresh 池下非蓄力拍 d_tick = max(下限, 池乘区(掷点档位基线))。 # 快照盲区说明:settlement_snapshot 取在衰减段之后,时效 1 的 ac_up 当轮授予当轮衰减—— @@ -106,7 +106,6 @@ func _run_boss(db, seed_val: int, dig: bool) -> Dictionary: # 逐轮:授予行汇总 → 重建战斗段时点池值(effect_pool_map 表驱动归属)→ 敌行动行逐行打印 -#(T6 收口批:原形参 verbose 为死参——打印行为无档位差异,随批删除) func _print_rounds(db, math, run: Dictionary) -> void: var groups := _round_groups(run.rows) var beats := _played_beats(run, db) @@ -192,7 +191,7 @@ func _analyze_round(db, math, rows: Array, beats: Dictionary) -> Dictionary: elif t == "damage" and String(row.get("source_class", "")) == "enemy_action": var baseline: int = int(row.get("baseline", 0)) var attach: int = int(row.get("attach", 0)) - # 掷点口径重建(2026-09-16 护甲等级掷点批):基线按行留档档位打折(暴击 ×倍率),附加必中 + # 掷点口径重建:基线按行留档档位打折(暴击 ×倍率),附加必中 var tier: int = int(row.get("tier", 100)) var crit: bool = bool(row.get("crit", false)) var base_factor: float = float(tier) * (float(db.settlement.crit_multiplier) / 100.0 if crit else 1.0) @@ -212,7 +211,7 @@ func _analyze_round(db, math, rows: Array, beats: Dictionary) -> Dictionary: return {"pd": pd, "pe": pe, "grants": grants, "lines": lines, "ticks": ticks} -# 拍名重建(敌人技能池批):pending_skill 字段 = 该结算开轮摇定的动作 id(快照取在结算末尾)—— +# 拍名重建:pending_skill 字段 = 该结算开轮摇定的动作 id(快照取在结算末尾)—— # round r 的拍 = 快照 r 的 enemies[0].pending_skill。快照 enemies 空时(敌死亡轮)回退 "?"——该轮敌已无行动行。 func _played_beats(run: Dictionary, db) -> Dictionary: var beats := {} diff --git a/game/smoke/defense_scan.gd b/game/smoke/defense_scan.gd index 20bea6bb..26b369e3 100644 --- a/game/smoke/defense_scan.gd +++ b/game/smoke/defense_scan.gd @@ -1,5 +1,5 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# Date: 2026-09-13(playtest-2026-09-12 Q1 复核——"安全格减伤是否过量导致满血打完 Boss") +# playtest-2026-09-12 Q1 复核——"安全格减伤是否过量导致满血打完 Boss" # 口径:逐结算轮统计 ac_up 授予层数(AC10→11→12)与该轮敌方实伤, # 分割"高 AC 轮"(叠满 = AC12,期望减免 28.75%)与基线轮(AC10,期望减免 21.25%)的承伤读数。 # 运行:Godot_console.exe --headless --path . --script res://smoke/defense_scan.gd -- [N] [seed0] diff --git a/game/smoke/dump_battle.gd b/game/smoke/dump_battle.gd index b411ef41..051e8c73 100644 --- a/game/smoke/dump_battle.gd +++ b/game/smoke/dump_battle.gd @@ -1,6 +1,5 @@ # VERTICAL SLICE - NOT FOR PRODUCTION # Validation Question: 玩家能否无指导在一场完整战斗中经历「开战→挖掘规划→轮末结算逐行兑现→胜/负」并逐行归因(P2) -# Date: 2026-09-10 # 一次性检查脚本:打印一场完整战斗的结算步骤流 + 棋盘摘要(肉眼验收 P2 归因质量)。 # 运行:Godot_console.exe --headless --path . --script res://smoke/dump_battle.gd extends SceneTree diff --git a/game/smoke/experiment_density.gd b/game/smoke/experiment_density.gd index 40c2ea6f..03c46dc6 100644 --- a/game/smoke/experiment_density.gd +++ b/game/smoke/experiment_density.gd @@ -1,5 +1,4 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# Date: 2026-09-10 # 一次性实验:不同 mine_density 下的 R₀ 占比 / 幸存雷数 / 残余挖掘量 / 推理率——为切片临时调参提供数据。 extends SceneTree diff --git a/game/smoke/fx_probe.gd b/game/smoke/fx_probe.gd index 69d38bf1..18ca7cac 100644 --- a/game/smoke/fx_probe.gd +++ b/game/smoke/fx_probe.gd @@ -36,7 +36,7 @@ func _ready() -> void: if not sb.is_dead(): problems.append("mark_dead 后 is_dead 应真") - # ①b 命中火花(迭代 6 T4 终稿——打击瞬间特效计数) + # ①b 命中火花(打击瞬间特效计数) var sb2 = sb_script.new("enemy") sb2.box = Vector2(150, 176) add_child(sb2) @@ -77,7 +77,7 @@ func _ready() -> void: if n_fx < 2: problems.append("结算光带应含带体+前导缘线 ≥2 节点,实得 %d" % n_fx) - # ---- ④b 轮切换横幅双态(迭代 8 卡⑦——常态=淡入驻留消隐动画链;减动效=静态呈现零动画)---- + # ---- ④b 轮切换横幅双态(常态=淡入驻留消隐动画链;减动效=静态呈现零动画)---- sfx.play_round_banner(3) await get_tree().process_frame var banner_nodes := 0 @@ -104,7 +104,7 @@ func _ready() -> void: if int(sfx.probe_settlement_marks()) != 2: problems.append("逐条结算标出未落位(状态脉冲+数字浮现——三轮 #3),实得 %s" % sfx.probe_settlement_marks()) - # ---- ⑤ 主角三态切换(迭代 6 T3——attack/hit 短驻自回 + 死亡复活态回 idle) ---- + # ---- ⑤ 主角三态切换(attack/hit 短驻自回 + 死亡复活态回 idle) ---- var hero_sb = sb_script.new("hero") hero_sb.box = Vector2(150, 176) add_child(hero_sb) @@ -133,7 +133,7 @@ func _ready() -> void: if hero_sb.is_dead() or String(hero_sb.hero_state_probe().get("state", "")) != "idle": problems.append("主角死亡后 set_hero 复活失败(is_dead 应假+态回 idle)") - # ---- ⑥ 主角受击/死亡路由(迭代 6 T5——battle_stage 主角早退拆除的呈现链断言) ---- + # ---- ⑥ 主角受击/死亡路由(battle_stage 主角走完整呈现链的断言) ---- var db2 = load("res://core/config_db.gd").new() if db2.load_tables("res://data/tables", false): var stage2 = BattleStageView.new(db2) diff --git a/game/smoke/fx_shot_probe.gd b/game/smoke/fx_shot_probe.gd index 9ca77525..37c74cd4 100644 --- a/game/smoke/fx_shot_probe.gd +++ b/game/smoke/fx_shot_probe.gd @@ -8,8 +8,8 @@ extends Node const ProbeUiUtil := preload("res://smoke/probe_ui_util.gd") # T6 收口:树寻址/隔离样板单点 -# ── 演出采样窗口口径(拍板点:headless/窗口化帧率不定,帧时刻以墙钟近似锚定;改窗口 = 改抓帧 -# 时刻观测面,非断言语义。窗口值与原字面量逐一同值——T6 收口批仅提具名。) ── +# ── 演出采样窗口口径(headless/窗口化帧率不定,帧时刻以墙钟近似锚定;改窗口 = 改抓帧 +# 时刻观测面,非断言语义。窗口值与字面量同值——仅提为具名常量。) ── const T_DIG_FLIGHT := 0.12 # 挖格行到达/弹道在飞窗口(settle_batch 回执后停留) const T_SETTLE := 0.35 # 结算排播窗口(行到达后二连抓) const T_ROUND_TICK := 0.25 # 停手轮末(敌方攻击弹道/受击闪白 0.2-1.6s 流过)连抓 6 帧的采样步距 @@ -29,7 +29,7 @@ func _ready() -> void: add_child(main) await get_tree().process_frame ProbeUiUtil.isolate_save(main, "fx_shot_probe", false, true, false) - # 隔离档即时应用(迭代 19 卡① T1——真实档 fullscreen 态会污染抓帧尺寸〔shot_probe 同款修正〕) + # 隔离档即时应用(真实档 fullscreen 态会污染抓帧尺寸〔shot_probe 同款口径〕) main.settings_store.apply() for i in 8: await get_tree().process_frame # UI 装配完成等足帧(canvas_item 空引用窗口) diff --git a/game/smoke/layout_probe.gd b/game/smoke/layout_probe.gd index 7d5b2994..a87e0665 100644 --- a/game/smoke/layout_probe.gd +++ b/game/smoke/layout_probe.gd @@ -72,7 +72,7 @@ func _check_one(label: String, main: Node) -> void: # 不遍历战斗屏宿主的全部后代。变异验证第二发证——向装配器注入一个全幅 ColorRect # (挂在 battle_root 的内层根下)时探针仍全绿:「未登记兄弟控件」这一缺陷类不在本探针 # 拦截面内。要拦它得改为递归遍历全子树找重叠,那是另一套判据(且极易误报容器父子关系), - # 归后续批按需立,不在本批范围。 + # 本探针不设此判据。 var bv: Control = main.board_view if bv == null: _problems.append("[%s] board_view = null" % label) diff --git a/game/smoke/level_autoplay.gd b/game/smoke/level_autoplay.gd index b9579868..01db2653 100644 --- a/game/smoke/level_autoplay.gd +++ b/game/smoke/level_autoplay.gd @@ -1,5 +1,4 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# Date: 2026-09-11 # 日志合规:任何模拟运行与真人试玩同日志——操作记录 / 轮次状态 / 战斗结束 / 通关结束 全量 JSONL。 # logger=null 时自建会话(每局一文件),批量调用方传共享 logger(log_run 局次标记切分)。 # 关卡自动通关策略(理性玩家近似)——呈现层数值调整板的批量模拟与 headless 扫描 @@ -22,15 +21,15 @@ # 实现注:信号处理体全部为静态方法 + bind 传状态——GDScript 多行 lambda 内嵌 match/控制流的解析不可靠。 extends RefCounted -const AutoPlayer := preload("res://smoke/auto_player.gd") # O4 收口:自动玩家策略单一实现 +const AutoPlayer := preload("res://smoke/auto_player.gd") # 自动玩家策略单一实现 -# ── 普通档 v3 失误注入参数(2026-10-01 用户规格:踩雷期望=完美+2/板、每板少挖几个正确格)── -# 标雷→误挖转化率:v3.2 实证 0.22 时普通档 0/100 全灭(首轮大量已证封印=保底命中,非真人失误 -# 形态——真人几乎不挖自己封印的格);降 0.10 = 偶发真手滑,主踩雷源=卡死赌挖(不确定性概率命中) +# ── 普通档 v3 失误注入参数(踩雷期望=完美+2/板、每板少挖几个正确格)── +# 标雷→误挖转化率:主踩雷源=卡死赌挖(不确定性概率命中),误挖只作偶发真手滑—— +# 真人几乎不挖自己封印的格(p 过高会让首轮已证封印变保底命中,非失误形态) const NORMAL_MINE_SLIP_P := 0.10 # 安全挖跳过率:每板安全格 ~70-90 × p ≈ 3-5 次漏挖(信息与推进双损失) const NORMAL_SKIP_DIG_P := 0.05 -# 空闲提前赌挖率(v3.4):已证安全格在手时小概率先赌一格——完美系把不确定性攒到残局 +# 空闲提前赌挖率:已证安全格在手时小概率先赌一格——完美系把不确定性攒到残局 # (残局 hazard→1=扫雷),真人早赌滚信息(低 hazard 期吃掉不确定性);p×~40 安全 AP/板 ≈ 4 次 const NORMAL_IDLE_GAMBLE_P := 0.10 @@ -52,7 +51,7 @@ static func run_level(db, seed_val: int, level_index: int, atk_pct: int, hp_pct: "boss_depth": -1, "hp_at_boss": -1, "rows": [], "timeout": false, "log_path": "", "policy": policy, "refreshes": 0, "mine_hits": 0, "mine_dmg": 0, "visited_ids": [], "choices": 0, "last_battle_enemies": [], - # 封印经济五字段(迭代14②判式换代批 T1——runsum 读数面;聚合自结算流水 source_class, + # 封印经济五字段(runsum 读数面;聚合自结算流水 source_class, # 零新随机源零核心改动;η=seal_hit÷seal_placed 与标空率派生归分析侧) "seal_placed": 0, "seal_hit": 0, "seal_miss": 0, "seal_hit_gain": 0, "seal_miss_penalty": 0, "prng": _policy_rng(seed_val), "mine_slips": 0, "skip_digs": 0, "shop_buys": 0, @@ -81,9 +80,9 @@ static func run_level(db, seed_val: int, level_index: int, atk_pct: int, hp_pct: # 单关驱动段(run_level 抽取——零自动推进停点 + 战斗自动玩家;policy 经 st 入 _autoplay_battle) -# 停点前移批 2026-09-23:入口停点(node_index 尚 -1 = 进节点前无 current_node)也经本分支驱动—— -# 读 next_candidate_ids 候选(入口单候选)→ pick_next_node,同一 _enter_node 与旧自动进入逐位 -# 等价(零 RNG 漂移);入口 pick 不计 st.choices(单候选强制选路,计数口径与旧测量面逐位同构)。 +# 入口停点(node_index 尚 -1 = 进节点前无 current_node)也经本分支驱动—— +# 读 next_candidate_ids 候选(入口单候选)→ pick_next_node,同一 _enter_node 等价(零 RNG 漂移); +# 入口 pick 不计 st.choices(单候选强制选路,计数口径与测量面同构)。 static func _drive_level(runner, st: Dictionary, logger, policy: String, route: String) -> void: st["policy"] = policy var guard_battles := 20 @@ -103,11 +102,11 @@ static func _drive_level(runner, st: Dictionary, logger, policy: String, route: _autoplay_battle(runner, this_settlement, st, logger) -# 三关连探冒险驱动(冒险结构实现批 2026-09-21)——AdventureRunner 编排:主种子恰一次 +# 三关连探冒险驱动——AdventureRunner 编排:主种子恰一次 # (start_adventure 唯一 new_adventure 调用点)、大奖励立即确认、冒险终局置 result/summary。 # 返回结构 = run_level 同族 + summary / wallet_events / encounter_max_hp_seq / reward_events / # visited_ids(全冒险节点行进序列——跨关累计,非末关 runner 的 visited 随实例更替,此处为唯一全量面)。 -# 2026-09-22 数值验证工具批:增 hero_override 尾参(永久强化 flat 注入透传——缺省 {} 与既有调用方 +# hero_override 尾参 = 永久强化 flat 注入透传(缺省 {} 与既有调用方 # 逐位一致零行为变更)+ run 行携带该参数(分析侧按元进度档切分)+ 败退敌人名采集 # (last_battle_enemies——末场战斗敌方显示名序列,失败局即死亡遭遇)。 static func run_adventure(db, seed_val: int, atk_pct: int, hp_pct: int, collect_rows: bool = false, @@ -132,36 +131,36 @@ static func run_adventure(db, seed_val: int, atk_pct: int, hp_pct: int, collect_ "log_path": "", "policy": policy, "refreshes": 0, "mine_hits": 0, "mine_dmg": 0, "visited_ids": [], "choices": 0, "last_battle_enemies": [], "summary": {}, "wallet_events": [], "encounter_max_hp_seq": [], "reward_events": [], - "feat_mode": String(relic.get("mode", "off")), # 特性分层开关(迭代 12 T7——off=316-f 通用竞争/on=成型画像优先捕捞 relic) + "feat_mode": String(relic.get("mode", "off")), # 特性分层开关(off=316-f 通用竞争/on=成型画像优先捕捞 relic) "shop_gp_seq": [], # 商店房到达余额序(逐关 1 次——GP 跨关延续验收取数面) - # 封印经济五字段(迭代14②判式换代批 T1——与 run_level 同口径,见彼处注释) + # 封印经济五字段(与 run_level 同口径,见彼处注释) "seal_placed": 0, "seal_hit": 0, "seal_miss": 0, "seal_hit_gain": 0, "seal_miss_penalty": 0, "prng": _policy_rng(seed_val), "mine_slips": 0, "skip_digs": 0, "shop_buys": 0, - "adv": true, # v3 档位行为开关(选路评分/失误注入/商店购买只挂冒险测量面——单关夹具保持旧语义零扰动) + "adv": true, # v3 档位行为开关(选路评分/失误注入/商店购买只挂冒险测量面——单关夹具语义不变) "level_templates": [], # 逐关图模板名(关卡节点图生成 v0.4 分层出数) } adr.step_row.connect(_on_step_row.bind(adr, st, collect_rows)) adr.node_entered.connect(_on_adventure_node_entered.bind(adr, st, logger)) adr.wallet_changed.connect(_on_adventure_wallet.bind(st, logger)) - # 三选一停点驱动(迭代 10 奖励重构批——big_reward_paid 退役:确定性策略候选取首件、 - # 兑付后推进下一关——零随机流自开,同种子逐位可复放;满位替换策略随迭代 22 T5 拆除) + # 三选一停点驱动(确定性策略候选取首件、 + # 兑付后推进下一关——零随机流自开,同种子逐位可复放;无满位替换策略) adr.curio_choice_presented.connect(_on_adventure_bonus.bind(st, adr)) adr.curio_resolved.connect(_on_adventure_curio_resolved.bind(st, adr)) adr.adventure_finished.connect(_on_adventure_finished.bind(st, logger)) adr.set_hero_override(atk_pct, hp_pct) - # 同调分层注入(迭代 11 第①批 T8——缺省 {} 与既有调用方逐位一致零行为变更) + # 同调分层注入(缺省 {} 与既有调用方逐位一致零行为变更) var adv_params := {"hero_override": hero_override, "first_script": false} if not attune.is_empty(): adv_params["attunement"] = attune.get("equipped", []) adv_params["attune_refresh_y"] = int(attune.get("refresh_y", 0)) - # 特性注入(迭代 12 T7——formed 画像=开局注入七流派各 2 件档一成型集;测量面专用) + # 特性注入(formed 画像=开局注入七流派各 2 件档一成型集;测量面专用) if relic.has("seed_ids"): adv_params["relics_seed"] = relic.get("seed_ids", []) - # 树规则键注入(迭代 12 T10——A/B 面读数载体:fork 激活侧 effects rule 键集透传) + # 树规则键注入(A/B 面读数载体:fork 激活侧 effects rule 键集透传) if relic.has("tree_rules"): adv_params["tree_rules"] = relic.get("tree_rules", []) - # 商店分层注入(迭代 11 第②批 T5——缺省 legacy 与既有调用方逐位一致零行为变更;pool=共享池货架面) + # 商店分层注入(缺省 legacy 与既有调用方逐位一致零行为变更;pool=共享池货架面) var pool_shop: bool = String(shop.get("mode", "")) == "pool" if pool_shop: adv_params["shop_mode"] = "pool" @@ -181,10 +180,10 @@ static func run_adventure(db, seed_val: int, atk_pct: int, hp_pct: int, collect_ if adr.runner() != null: adr.runner().restore_hero_base() if pool_shop: - # 终局池读数(迭代 11 第②批 T5——摘要 additive 键 pool_stock:_settle 清账前快照, + # 终局池读数(摘要 additive 键 pool_stock:_settle 清账前快照, # 商店买走 vs 奖励领走 vs 枯竭的终局面;事后读 adr.pool_stock 会被收束清账重置=满库假象) st["pool_stock"] = (st.get("summary", {}).get("pool_stock", {}) as Dictionary).duplicate(true) - st["relics"] = (st.get("summary", {}).get("relics", []) as Array).duplicate() # 特性终局持有集(迭代 12 T1——摘要 additive 键清账前快照,同 pool_stock 模式) + st["relics"] = (st.get("summary", {}).get("relics", []) as Array).duplicate() # 特性终局持有集(摘要 additive 键清账前快照,同 pool_stock 模式) st.log_path = logger.log_path() if own_session: logger.close_session() @@ -212,7 +211,7 @@ static func _on_adventure_node_entered(node: Dictionary, info: Dictionary, adr, st.boss_depth = int(node.get("node_depth", -1)) st.hp_at_boss = int(adr.ledger["hero_hp"]) elif t == "reward": - # 奖励节点三选一(迭代 10 追加批——共享池确定性策略;TP0 起 316-f 判读:1 级最稀有、 + # 奖励节点三选一(共享池确定性策略;TP0 起 316-f 判读:1 级最稀有、 # 同档并列取最左;替换放弃新件;兑付后 continue_after_node 回图选路) var ndraw: Dictionary = adr.node_curio_candidates() var ncands: Array = ndraw.get("candidates", []) as Array @@ -223,8 +222,8 @@ static func _on_adventure_node_entered(node: Dictionary, info: Dictionary, adr, adr.present_node_curio(ncands) var npick: Dictionary = _pick_token(ncands, String(st.get("feat_mode", "off"))) if adr.apply_node_curio(String(npick.get("kind", "")), String(npick.get("tier", "")), String(npick.get("feat_id", ""))): - # T5 门票拿到即开——候选已被替换为专长三选一,就地再选一轮(确定性策略同款 316-f); - # 不作此分支则节点停点悬空→选路卡死(MC timeout 形态,2026-10-05 批内实测) + # 门票拿到即开——候选已被替换为专长三选一,就地再选一轮(确定性策略同款 316-f); + # 不作此分支则节点停点悬空→选路卡死(MC timeout 形态) if String(npick.get("kind", "")) == "feat_ticket": var fcands: Array = (adr.node_curio_pending_state().get("candidates", []) as Array) if not fcands.is_empty(): @@ -239,9 +238,9 @@ static func _on_adventure_node_entered(node: Dictionary, info: Dictionary, adr, elif t == "shop": st.shop_gp_seq.append(int(info.get("gp", -1))) if String(st.get("shop_mode", "legacy")) == "pool": - _autoplay_shop_pool(r, st) # 共享池货架贪心(迭代 11 第②批 T5——买一件=奖励面少一件的机会成本画像维持贪心语义) + _autoplay_shop_pool(r, st) # 共享池货架贪心(买一件=奖励面少一件的机会成本,画像维持贪心语义) else: - _autoplay_shop(r, st) # 贪心买齐(2026-10-01——旧零购离开退役:GP 局内死钱,真人实证两店全购) + _autoplay_shop(r, st) # 贪心买齐(GP 局内死钱——真人实证两店全购) r.continue_after_node() if logger != null: logger.log_node(node, info, r.node_index) @@ -256,7 +255,7 @@ static func _on_adventure_wallet(event: String, gp_val: int, extra: Dictionary, logger.log_wallet(event, gp_val, extra) -# 三选一停点驱动(迭代 10——确定性策略;TP0 起 316-f 判读:1 级最稀有、同档并列取最左; +# 三选一停点驱动(确定性策略;TP0 起 316-f 判读:1 级最稀有、同档并列取最左; # 奖励事件随 reward_events 留档) static func _on_adventure_bonus(payload: Dictionary, st: Dictionary, adr) -> void: st.reward_events.append({"curio_pick": payload.duplicate(true)}) @@ -269,9 +268,9 @@ static func _on_adventure_bonus(payload: Dictionary, st: Dictionary, adr) -> voi st.result = "advance_failed" -# 三选一确定性选件(TP0 316-f——1 级优先度=最稀有〔迭代 20 四级:legendary>rare>excellent>common〕、2 级=最左; +# 三选一确定性选件(TP0 316-f——1 级优先度=最稀有〔四级:legendary>rare>excellent>common〕、2 级=最左; # 候选并列同档取最左=稳定序保证。空候选/未知档位 = 回退最左防御口径。 -# 成型画像(迭代 12 T7——relic 模式 on:候选含 relic 令牌时优先在 relic 集内按 316-f 择一 +# 成型画像(relic 模式 on:候选含 relic 令牌时优先在 relic 集内按 316-f 择一 # 〔贪心捕捞→特性入局→成型画像全流派覆盖——R3 乙单锚承载〕;off=relic 与属性加成型特性同规则竞争) static func _pick_token(candidates: Array, feat_mode: String = "off") -> Dictionary: var pool: Array = candidates @@ -314,7 +313,7 @@ static func _on_adventure_curio_resolved(result: Dictionary, st: Dictionary, adr st.result = "advance_failed" -# 商店贪心买齐(2026-10-01 模拟档位重构):GP 局内死钱——买得起就买( affordable 集里挑最便宜的 +# 商店贪心买齐:GP 局内死钱——买得起就买( affordable 集里挑最便宜的 # 反复买到达不上任何商品为止,guard 防死循环)。确定性(零随机流);购买出账/加算区入账全走 # runner.buy_product 核心编排(与呈现层购买同一出账路径,wallet_changed 信号照常采集)。 static func _autoplay_shop(r, st: Dictionary) -> void: @@ -336,7 +335,7 @@ static func _autoplay_shop(r, st: Dictionary) -> void: st.shop_buys = int(st.get("shop_buys", 0)) + 1 -# 商店共享池贪心(迭代 11 第②批 T5):货架三选一同构面贪心买齐——affordable 集挑最便宜反复买 +# 商店共享池贪心:货架三选一同构面贪心买齐——affordable 集挑最便宜反复买 # (每次买后全重抽、货架随买随换,枯竭/不可负担即止,guard 防死循环)。购买走 runner.buy_pool_item # 核心编排(与呈现层购买同一出账+池消费路径,wallet_changed 信号照常采集)。确定性(零随机流)。 static func _autoplay_shop_pool(r, st: Dictionary) -> void: @@ -366,7 +365,7 @@ static func _on_adventure_finished(summary: Dictionary, st: Dictionary, logger) logger.log_level_end(summary) -# 策略流 RNG(2026-10-01 模拟档位重构):种子派生自局种子 × 黄金比率常数 + 偏移——与核心统一流 +# 策略流 RNG:种子派生自局种子 × 黄金比率常数 + 偏移——与核心统一流 # (rng_service 单盐派生)零共享零扰动;逐局确定性保持(同种子 ⇒ 同决策序列 ⇒ 同回放) static func _policy_rng(seed_val: int) -> RandomNumberGenerator: var prng := RandomNumberGenerator.new() @@ -374,7 +373,7 @@ static func _policy_rng(seed_val: int) -> RandomNumberGenerator: return prng -# 路径轴选路(2026-10-01 目标价值评分制——机械最小编号退役):候选按节点类型评分取最高, +# 路径轴选路(目标价值评分制):候选按节点类型评分取最高, # 同分 tie-break 沿 route 方向(min=小编号/max=大编号——verifier 双窗轴保持)。 # 评分语义(确定性,零随机流):rest=伤重高值(缺口比例×100)/shop=买得起高值(GP 局内死钱, # 真人实证两店全购)/reward=占位低值(MC 夹具解锁空集=零兑付直通)/boss=缓冲低值(有店有_rest @@ -399,7 +398,7 @@ static func _route_pick(runner, route: String, st: Dictionary) -> int: s = 10.0 var cheapest := 1 << 30 if String(st.get("shop_mode", "legacy")) == "pool": - for c in runner.shop_shelf(): # pool 面:货架现价(迭代 11 第②批 T5) + for c in runner.shop_shelf(): # pool 面:货架现价 cheapest = mini(cheapest, int(c.get("price", 1 << 30))) else: for p in runner.shop_products(): @@ -434,7 +433,7 @@ static func _on_step_row(row: Dictionary, _runner, st: Dictionary, collect_rows: _note_enemy(String(row.get("text", "")), st) # 施放行(毒爆挂毒等——伤害行可能缺席的死亡遭遇仍可归因) if row.source_class == "mine_hit": st.mine_hits += 1 # 踩雷证据行(负向兑付——完美档断言恒 0;盲挖惩罚链埋点) - # 封印经济聚合(迭代14②判式换代批 T1——自结算流水聚合,零新随机源): + # 封印经济聚合(自结算流水聚合,零新随机源): # ⚠ 行侧判据考证实录:结算段对存续增益实例每轮复发行 effect 行且复用实例 source_class #(battle_orchestrator 状态列举行)——source_class=seal_hit 的行 ≠ 标中事件。事件行唯一判据 # = 授予行专带 highlight="seal_hit"(实测 87 行 == 受理封印 87 动作,1:1 精确); @@ -456,7 +455,7 @@ static func _on_step_row(row: Dictionary, _runner, st: Dictionary, collect_rows: st.rows.append(row) -# 敌方显示名采集(数值验证工具批 2026-09-22):敌方行动/施放行文本首词 = 单位显示名 +# 敌方显示名采集:敌方行动/施放行文本首词 = 单位显示名 #(攻击行「地精 撕咬(暴击)」、施放行「地精 施放 毒雾」——显示名不含空格,去重连续重复) static func _note_enemy(text: String, st: Dictionary) -> void: if text.is_empty(): @@ -480,7 +479,7 @@ static func _on_node_entered(node: Dictionary, info: Dictionary, runner, st: Dic st.boss_depth = int(node.get("node_depth", -1)) st.hp_at_boss = runner.hero_hp elif t == "reward": - runner.continue_after_node() # 奖励点 = 内容待拍板直通节点(格面资源批 2026-09-15) + runner.continue_after_node() # 奖励点 = 内容未定直通节点 elif t == "rest": st.rest_healed = int(info.get("healed", 0)) st.hp_before_rest = int(info.get("hp", 0)) - st.rest_healed @@ -503,17 +502,16 @@ static func _on_level_finished(p: Dictionary, st: Dictionary, logger) -> void: static func _autoplay_battle(runner, settlement, st: Dictionary, logger) -> void: - # 策略档经 _decide_act 单点分派(T6 样板收口批 2026-10-02——原 _autoplay_battle/_autoplay_battle_perfect - # 双循环逐行相同仅差 act 来源行,合并单循环;三档决策语义逐位不变,见 _decide_act)。 - # 普通策略档 v3(2026-10-01 用户重定义):完美策略 + 受控失误注入——v2「新手级单步推理+盲挖 - # 兜底」画像被真人实证推翻(零加成真人首通三关踩 23 雷 vs v2 普通档 L2 条件通关率 10.6%)。 + # 策略档经 _decide_act 单点分派(单循环承载三档——三档决策语义逐位不变,见 _decide_act)。 + # 普通策略档 v3:完美策略 + 受控失误注入(标定依据=真人实证: + # 零加成真人首通三关踩 23 雷)。 # v3 语义 = 会玩的普通玩家:推理与完美档同源(subset 解算/封印/卡死刷新),失误只注入两手—— # 标雷误挖(NORMAL_MINE_SLIP_P)+ 安全挖跳过(NORMAL_SKIP_DIG_P)。连续拒绝 ≥3 = 编排违约防御。 - # 完美策略档(2026-09-14):单步决策循环——move/dig/seal 经 排雷玩法 settle_batch 提交, + # 完美策略档:单步决策循环——move/dig/seal 经 排雷玩法 settle_batch 提交, # refresh 经 settlement.player_request_refresh(战斗结算 核心编排:行动经济 扣 RAP + 退役 + 当场换新板), # stop 出内环走统一停手提交。连续拒绝 ≥3 = 编排违约防御(fail-fast 语义,停手防死循环)。 - # 2026-10-01 上界修正:选路改目标价值评分(_route_pick)+ 商店贪心买齐(_autoplay_shop)—— - # 「完美」须是元游戏意义上的上界(会购物会补给),不再只是扫雷子游戏上界。 + # 上界口径:选路=目标价值评分(_route_pick)+ 商店贪心买齐(_autoplay_shop)—— + # 「完美」是元游戏意义上的上界(会购物会补给),不只扫雷子游戏上界。 var round_guard := 60 while st.result == "" and runner.current_battle() == settlement and settlement.battle_result == "" and round_guard > 0: round_guard -= 1 @@ -543,7 +541,7 @@ static func _autoplay_battle(runner, settlement, st: Dictionary, logger) -> void if kind == "refresh": st.refreshes = int(st.refreshes) + 1 elif kind == "seal": - st.seal_placed = int(st.get("seal_placed", 0)) + 1 # 封印数(η 分母=全部封印数——迭代14② Q5 裁决;失误注入转化封印不计数=转化后实为挖) + st.seal_placed = int(st.get("seal_placed", 0)) + 1 # 封印数(η 分母=全部封印数〔Q5〕;失误注入转化封印不计数=转化后实为挖) rejects = 0 else: rejects += 1 @@ -553,7 +551,7 @@ static func _autoplay_battle(runner, settlement, st: Dictionary, logger) -> void logger.log_action("stop", Vector2i(-1, -1), _accepted(out_s), {"round": start_round}) -# 普通档 v3 失误注入(2026-10-01 用户规格):三类—— +# 普通档 v3 失误注入:三类—— # ①标雷误挖:把「封印已证雷」动作直接转成「挖该格」(真人手滑原型:知道是雷、位置点错, # 踩雷吃伤且该雷奖励报废);期望踩雷增量 ≈ 每板已证雷数 × NORMAL_MINE_SLIP_P(目标完美+2/板) # ②安全挖跳过:把「挖已证安全格」动作转成本轮停手(少挖几个正确的雷——信息与推进双损失) @@ -596,7 +594,7 @@ static func _gamble_action(plan: Dictionary, settlement) -> Dictionary: return {"kind": "move", "cell": plan.hero_cell} -# 战斗决策单行分派(T6 双循环合并抽取——原两循环唯一差异行): +# 战斗决策单行分派: # perfect 档 = 完美策略单步决策(上界口径); # normal 档 v3 = 完美+受控失误注入(冒险测量面 adv=true);单关机制夹具保持 v2 新手画像(adv 缺省)。 # 决策函数纯读板面/编排面(零 RNG 消费——失误流独走 st.prng,见 _apply_normal_slips)。 diff --git a/game/smoke/monte_carlo.gd b/game/smoke/monte_carlo.gd index 211a4273..cb88c195 100644 --- a/game/smoke/monte_carlo.gd +++ b/game/smoke/monte_carlo.gd @@ -1,5 +1,4 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# Date: 2026-09-11 # 战斗期望蒙特卡洛:当前参数下"胜轮数 / 每轮承伤 / 清图次数 / 开格数"的分布实测。 # 政策 = 理性玩家近似:挖最近可挖格(AutoPlayer 单一实现)。 # 运行:Godot_console.exe --headless --path . --script res://smoke/monte_carlo.gd diff --git a/game/smoke/probe_ui_util.gd b/game/smoke/probe_ui_util.gd index 6a4799ce..ac62c948 100644 --- a/game/smoke/probe_ui_util.gd +++ b/game/smoke/probe_ui_util.gd @@ -28,7 +28,7 @@ static func find_button(root: Node, needle: String, mode: String = "prefix") -> return null -# CheckButton 同款寻址(ui_click_probe 历史语义 = contains——设置面旧入口退役断言用) +# CheckButton 同款寻址(ui_click_probe 语义 = contains——断言设置面旧入口不在) static func find_check_button(root: Node, needle: String) -> CheckButton: if root == null: return null @@ -92,9 +92,9 @@ static func _text_match(text: String, needle: String, mode: String) -> bool: #(隔离 cfg 名 = _settings.cfg,与被收口探针原文件名逐一同名);refresh_resume = 组合根 # 「继续上局」按钮重刷;swap_save = 是否换注全局 SaveManager(营地先行段只换 meta 侧不换 SaveManager)。 # 返回隔离 SaveManager 实例(调用方常需后续直读余额/重读档)。 -# 迭代 27 T1——SaveManager/MetaProgression 升格 autoload 后隔离面改单例原地重置 +# SaveManager/MetaProgression 是 autoload 单例——隔离面走单例原地重置 #(attach_path 沿 RngService.set_master_seed 先例;MetaProgression 持 save 引用透传, -# swap_save=false 分支换 meta 侧引用=独立 iso 实例,语义同旧「只换 meta 不换 save_manager」)。 +# swap_save=false 分支换 meta 侧引用=独立 iso 实例,只换 meta 不换 save_manager)。 static func isolate_save(main, tag: String, mark_first_done: bool = false, with_settings: bool = false, refresh_resume: bool = false, swap_save: bool = true): var save_path := "user://%s.json" % tag diff --git a/game/smoke/reward_expectation.gd b/game/smoke/reward_expectation.gd index 4087900e..4a4f1840 100644 --- a/game/smoke/reward_expectation.gd +++ b/game/smoke/reward_expectation.gd @@ -1,5 +1,4 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# Date: 2026-09-11(2026-09-15 格面资源批重写:类型频次测量——供给控制器批口径随可选类删除退役) # 奖励期望测量:逐深度实测 |非封锁格|(safe ∪ mines ∖ R₀)分布、格面资源类型频次 # (应涌现自正向行九型权重 attack 14 / defense 11 / blast 16 / heal 4 / weaken 8 / pierce 8 / magic 8 / action 6 / gp 2,合计 77——reward.tres 现行)、 # 封锁格零泄漏(R₀ 格不在摇号清单)——走真实 地图战斗资源.roll_board 管线。 diff --git a/game/smoke/rhythm_batch.gd b/game/smoke/rhythm_batch.gd index 55dbde78..ebf9851f 100644 --- a/game/smoke/rhythm_batch.gd +++ b/game/smoke/rhythm_batch.gd @@ -1,5 +1,4 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# Date: 2026-09-19 # 技能池节奏读数批量采集(06 待办「技能池节奏体验验证」机器半边正式读数): # 60 distinct seeds × 双策略 × 两关,atk/hp 零加成基线——单网格组合避免种子重复 # (4200 系 0/484 假象教训:节奏/EV 读数须 ≥50 distinct seeds,见台账 89)。 diff --git a/game/smoke/screen_flow_probe.gd b/game/smoke/screen_flow_probe.gd index 7dd788d1..ef4119d0 100644 --- a/game/smoke/screen_flow_probe.gd +++ b/game/smoke/screen_flow_probe.gd @@ -1,4 +1,4 @@ -# screen_flow_probe.gd — L3 屏壳切换探针(迭代 29 T4) +# screen_flow_probe.gd — L3 屏壳切换探针 # 判的是「跑起来之后,屏与场景的切换对不对」:菜单 ⇄ 营地 ⇄ 冒险 ⇄ 终局 的主流程与回退路径, # 每一步断言 **屏级互斥**(同一时刻最多一个屏可见)+ 流程状态位落到正确值。 # 与 ui_click_probe 的分工:那件走的是「点某个按钮有没有反应」的行为走查(含战斗推进与结算数值面); diff --git a/game/smoke/shot_probe.gd b/game/smoke/shot_probe.gd index e107ea80..09d6e3ab 100644 --- a/game/smoke/shot_probe.gd +++ b/game/smoke/shot_probe.gd @@ -23,7 +23,7 @@ var _meta := {} # 控件实测几何(全局 rect——shot_checker 文字框 func _ready() -> void: - # 运行前提=窗口化真渲染面:headless 下 frame_post_draw 永不触发+视口纹理恒空——无此守卫时 headless 调用方必挂死(2026-10-02 挂死灾害批护栏) + # 运行前提=窗口化真渲染面:headless 下 frame_post_draw 永不触发+视口纹理恒空——无此守卫时 headless 调用方必挂死 if DisplayServer.get_name() == "headless": print("[shot_probe] FAIL — 本探针必须窗口化运行(headless 无渲染面,截图必空);headless 自动闸禁跑本探针(正主=tools/probe_gate.sh)") get_tree().quit(1) @@ -36,17 +36,17 @@ func _ready() -> void: add_child(main) await get_tree().process_frame # ── 存档/元进度/设置三面隔离(ui_click_probe 同款——真档零污染;历史语义 = contains 寻址) ── - # 迭代 28 T4:refresh_resume 开——续玩钮按隔离档(无断点)定基,菜单截图/golden 基线不依赖 + # refresh_resume 开——续玩钮按隔离档(无断点)定基,菜单截图/golden 基线不依赖 # 真实档断点态(boot 关系由冒烟 _smoke_boot_chain V2d 断,此处只保截图确定性) ProbeUiUtil.isolate_save(main, "smoke_shot_probe", false, true, true) - # 隔离档即时应用(迭代 19 卡① T1——main 装配已按真实设置恢复过窗口态〔本机实测:真实档 + # 隔离档即时应用(main 装配已按真实设置恢复过窗口态〔本机实测:真实档 # fullscreen=true 时窗口进全屏,视口纹理 2304x1440≠1280 基准档,checker 尺寸/取样全盘失真〕; # apply 隔离档出厂默认=窗口化 1280x800,恢复本探针设计前提。探针侧环境修正,零运行时改动) main.settings_store.apply() await get_tree().process_frame - # ① 菜单(启动态)——帮助文腿整个退役(载体玩法速览牌 2026-10-06 用户令退役,checker 对应断言段同撤); - # 副标题件 2026-10-16 用户令整个删除(无意义标语),菜单文字锚只剩标题 - # 自检一(迭代 28 T4):boot 态顶层可见全屏层=start_overlay(内容层树遍历——屏壳是容器不当候选: + # ① 菜单(启动态)——无帮助文腿(玩法速览牌不在画面,checker 无对应断言段); + # 无副标题件,菜单文字锚只剩标题 + # 自检一:boot 态顶层可见全屏层=start_overlay(内容层树遍历——屏壳是容器不当候选: # camp 壳 boot 态 vis=true 但成员恒隐,裸树遍历自顶向下会先命中透明壳) var top: Node = null var top_rx := -1 @@ -66,7 +66,7 @@ func _ready() -> void: if top != main._start_overlay: _problems.append("boot 态顶层可见层≠start_overlay(实测 %s——菜单被埋)〔装配生命批 V4〕" % (top.name if top != null else "null")) - # 自检二(迭代 28 T4):菜单标题 label 必须 is_visible_in_tree 且 rect 落屏内 + # 自检二:菜单标题 label 必须 is_visible_in_tree 且 rect 落屏内 #(对比度只判反差不判「字在」——本条+checker 墨色占比共同补内容判据) var vp := get_viewport().get_visible_rect() for pair in [["menu_title", "Dungeon Sweeper"]]: @@ -81,7 +81,7 @@ func _ready() -> void: _problems.append("菜单文字 rect 越出视口: %s(%s ⊄ %s)〔装配生命批 V4〕" % [String(pair[1]), str(gr), str(vp)]) _meta[String(pair[0])] = ProbeUiUtil.label_rect(main._start_overlay, String(pair[1])) await _snap("menu") - # ①b 设置面(迭代 19 卡① T1 扩屏——settingsbtn 真实信号路径,开合同款真实钮) + # ①b 设置面(settingsbtn 真实信号路径,开合同款真实钮) var setbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "设置", "prefix") if setbtn == null: _problems.append("设置入口缺失(开始层 settingsbtn)") @@ -100,7 +100,7 @@ func _ready() -> void: else: set_close.pressed.emit() await get_tree().process_frame - # ①c 生涯页(迭代 19 卡① T1 扩屏——careerbtn 真实信号路径,ui_struct_probe 同款入口链) + # ①c 生涯页(careerbtn 真实信号路径,ui_struct_probe 同款入口链) var careerbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "生涯", "prefix") if careerbtn == null: _problems.append("生涯入口缺失(开始层 careerbtn)") @@ -134,7 +134,7 @@ func _ready() -> void: if close_btn != null: close_btn.pressed.emit() await get_tree().process_frame - # ③ 关卡画面(开始冒险→停点出图——冒险开始即出图,停点前移批语义) + # ③ 关卡画面(开始冒险→停点出图——入口停点语义) var lvbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "开始冒险", "contains") if lvbtn == null: _problems.append("开始冒险按钮缺失(开始层 lvbtn)") @@ -143,7 +143,7 @@ func _ready() -> void: for i in 4: await get_tree().process_frame await _snap("level") - # GP 常驻徽章断言(迭代 9 卡⑪核验——读数=runner.gp 现值,刷新=写路径回执后重查〔open_choices〕) + # GP 常驻徽章断言(读数=runner.gp 现值,刷新=写路径回执后重查〔open_choices〕) var gp_label: Label = ProbeUiUtil.find_label(main.level_screen, "◈ ") if gp_label == null or not gp_label.is_visible_in_tree(): _problems.append("GP 徽章不可见(关卡画面顶栏)") @@ -162,13 +162,13 @@ func _ready() -> void: _meta["hero_panel"] = _node_rect(ProbeUiUtil.find_by_script(main, "hero_info_panel_view")) _meta["stage_view"] = _node_rect(main.stage) _meta["board_zone"] = _node_rect(main.board_zone) - # draw calls 真机测量(迭代 9 卡⑦——基线 270→目标 <200;窗口化渲染帧读数, + # draw calls 真机测量(基线 270→目标 <200;窗口化渲染帧读数, # 取值时机=战斗截图同帧后一帧——呈现终态满负荷) await get_tree().process_frame var dc := int(Performance.get_monitor(Performance.RENDER_TOTAL_DRAW_CALLS_IN_FRAME)) _meta["battle_draw_calls"] = dc print("[shot_probe] battle draw_calls=%d(基线 270/目标 <200)" % dc) - # ⑤ 状态面板(迭代 19 卡① T1 扩屏——战斗屏状态角标真实信号路径;层在战斗屏之上开合) + # ⑤ 状态面板(战斗屏状态角标真实信号路径;层在战斗屏之上开合) var pb: Button = main.board_zone.status_badge if pb == null or not pb.visible or pb.disabled: _problems.append("状态面板入口角标缺失/置灰(战斗屏 board_zone)") @@ -196,7 +196,7 @@ func _ready() -> void: if mf != null: mf.store_string(JSON.stringify(_meta)) mf.close() - # ── 最小自检:七件存在且非零字节(迭代 19 卡① T1 扩屏后口径) ── + # ── 最小自检:七件存在且非零字节 ── for s in ["menu", "settings", "career", "camp", "level", "battle", "status"]: var p := out_dir.path_join("shot_%s.png" % s) if not FileAccess.file_exists(p): diff --git a/game/smoke/skill_rhythm_probe.gd b/game/smoke/skill_rhythm_probe.gd index fe11f8c0..a4298e91 100644 --- a/game/smoke/skill_rhythm_probe.gd +++ b/game/smoke/skill_rhythm_probe.gd @@ -1,6 +1,5 @@ # VERTICAL SLICE - NOT FOR PRODUCTION # 定位:分析工具·非验收件——零断言取数工具,不出入任何闸。 -# Date: 2026-09-19 # 技能池节奏探针:地精一伙 (1,1) 750 出招零突刺异常的定位—— # ① 表侧:resolve_enemy_rowset(1,1) 的池快照内容; # ② 摇号侧:隔离 SkillLottery.draw 大样本份额; @@ -14,7 +13,7 @@ func _initialize() -> void: var db = load("res://core/config_db.gd").new() db.load_tables("res://data/tables", false) - # ① 表侧(2026-10-07 行集多行批 T2 机械适配——行集数组取首行,零内容期行为零变化) + # ① 表侧(行集数组取首行,零内容期行为不变) var row = db.resolve_enemy_rowset(1, 1)[0] print("[1] row(1,1) display=", row.get("display_name"), " unit_count=", row.get("unit_count"), " pool=", row.get("pool")) diff --git a/game/smoke/smoke_all.gd b/game/smoke/smoke_all.gd index 751ca2ea..902d50d2 100644 --- a/game/smoke/smoke_all.gd +++ b/game/smoke/smoke_all.gd @@ -1,6 +1,5 @@ # VERTICAL SLICE - NOT FOR PRODUCTION # Validation Question: 玩家能否无指导在一场完整战斗中经历「开战→挖掘规划→轮末结算逐行兑现→胜/负」并逐行归因(P2) -# Date: 2026-09-10 # headless 冒烟入口(承数据配置冒烟框架:extends SceneTree + autoload 显式实例化)。 # 运行:Godot_console.exe --headless --path --script res://smoke/smoke_all.gd extends SceneTree @@ -25,7 +24,7 @@ func check(cond: bool, label: String, quiet: bool = false) -> void: print(" [FAIL] " + label) -# WCAG 相对亮度/对比度(迭代 25 UI 全局主题批 V2——滑轨两段对比度断言用) +# WCAG 相对亮度/对比度(滑轨两段对比度断言用) func _theme_rel_luminance(c: Color) -> float: var lin := func(ch: float) -> float: return ch / 12.92 if ch <= 0.03928 else pow((ch + 0.055) / 1.055, 2.4) @@ -49,8 +48,8 @@ func _initialize() -> void: print(" error: [%s] %s" % [d.category, d.message]) var rng = load("res://core/rng_service.gd").new() rng.set_master_seed(42) - # 统一流黄金向量(数据配置 AC-3——2026-09-27 统一流裁决单盐重登记:单盐沿用并流前 board_gen 盐, - # scope 0-3 与旧 R3 board_gen 向量逐位连续;Python 参考实现逐位交叉验证一致;并流前分盐向量随批作废) + # 统一流黄金向量(数据配置 AC-3:单盐沿用 board_gen 盐, + # scope 0-3 与 board_gen 向量逐位连续;Python 参考实现逐位交叉验证一致) check(rng.derive_at(0) == 8672514112661456564, "统一流向量 m=42 scope=0(=旧 board_gen scope0 连续性锚)") check(rng.derive_at(1) == 8834291164406037215, "统一流向量 m=42 scope=1") check(rng.derive_at(2) == 7714373262647006282, "统一流向量 m=42 scope=2") @@ -73,11 +72,11 @@ func _initialize() -> void: if load_ok: _run_core_smoke(db, rng) - _split_tail() # 迭代 27 T1 V2/V3——场景拆分+会话物化断言(挂树帧推进型异步尾段;摘要与退出码随尾段落) + _split_tail() # V2/V3——场景拆分+会话物化断言(挂树帧推进型异步尾段;摘要与退出码随尾段落) -# ---- 场景拆分/会话物化异步尾段(迭代 27 T1——autoload 挂载需过 _initialize 后首帧〔run_all.gd 头注时序〕, -# 挂 main.tscn 的断言在帧后执行;摘要打印与 quit 从 _initialize 移本尾段)---- +# ---- 场景拆分/会话物化异步尾段(autoload 挂载需过 _initialize 后首帧〔run_all.gd 头注时序〕, +# 挂 main.tscn 的断言在帧后执行;摘要打印与 quit 在本尾段)---- func _split_tail() -> void: await process_frame await process_frame @@ -95,7 +94,7 @@ func _split_tail() -> void: quit(1 if _failures > 0 else 0) -# ---- 类型闸断言(迭代 27 T5 V7——project.godot warning 配置在位〔源码断言〕+审计器脚本在位; +# ---- 类型闸断言(V7——project.godot warning 配置在位〔源码断言〕+审计器脚本在位; # 审计器归零判定走 static_scan S9 闸机,此处兜配置面)---- func _smoke_type_gate() -> void: var pj: String = FileAccess.get_file_as_string("res://project.godot") @@ -106,7 +105,7 @@ func _smoke_type_gate() -> void: "V7 类型审计器闸机在位(static_scan S9 → tools/audit_type_hints.py)〔迭代27 T5〕") -# ---- 卫生件 grep 闸(迭代 27 T6 V8——死代码/字符串 Callable/影子账残留零命中;源码扫描面)---- +# ---- 卫生件 grep 闸(V8——死代码/字符串 Callable/影子账残留零命中;源码扫描面)---- func _smoke_hygiene_gates() -> void: var callables := 0 for d in ["res://core", "res://presentation", "res://data"]: @@ -153,7 +152,7 @@ func _smoke_hygiene_gates() -> void: check(outside_calls == 0, "V1d 层序落位单口(_apply_layer_contract 之外 move_child 调用点=%d 应=0)〔装配生命批 V1〕" % outside_calls) -# ---- 三屏场景化断言(迭代 27 T1 V2——独立实例化+关键节点在位+组合根树序/z 序保序)---- +# ---- 三屏场景化断言(V2——独立实例化+关键节点在位+组合根树序/z 序保序)---- func _smoke_scene_split() -> void: print("--- 迭代27 T1 三屏场景化(V2:屏壳独立实例化+组合根装配保序)---") # ① 三屏壳独立实例化(F6 等价——headless 直挂;视图代码构建在屏壳 _ready) @@ -218,7 +217,7 @@ func _smoke_scene_split() -> void: # 顶层可见内容层(V1a 用——候选=合同模态/全屏态+两屏壳的 boot 内容成员;屏壳本身是容器不当候选: -# camp 壳 boot 态 vis=true 但成员恒隐,裸树遍历自顶向下会先命中透明壳〔装配生命批诊断订正①〕) +# camp 壳 boot 态 vis=true 但成员恒隐,裸树遍历自顶向下会先命中透明壳) func _topmost_visible_layer(main: Node) -> Node: var candidates: Array[Node] = [main._start_overlay, main._battle_root, main._inter_overlay, main.legend_overlay, main.node_overlay, main.level_screen, main.curio_overlay, @@ -239,7 +238,7 @@ func _topmost_visible_layer(main: Node) -> Node: return best -# ---- boot 链路时序后置条件(迭代 28 T2——装配修复后启动态六断言;只立行为可判断言,不造假时序)---- +# ---- boot 链路时序后置条件(启动态六断言;只立行为可判断言,不造假时序)---- func _smoke_boot_chain() -> void: print("--- 迭代28 T2 boot 链路时序后置条件(V2:六断言)---") var main: Node = load("res://presentation/main.tscn").instantiate() @@ -291,7 +290,7 @@ func _smoke_boot_chain() -> void: # ⑤ 闲时会话(_ready 即建、永非 null、在树) check(main.run_scope != null and not main.run_scope.is_adventure and main.run_scope.is_inside_tree(), "V2e run_scope 非空且为闲时会话(is_adventure=false+is_inside_tree)〔装配生命批 V2〕") - # ⑥ 调试浮窗 boot 不开+菜单角标在(2026-10-16 用户令修正:菜单优先——boot 不自动开浮窗, + # ⑥ 调试浮窗 boot 不开+菜单角标在(菜单优先——boot 不自动开浮窗, # 入口=开始屏右下角「调试」角标+对局中两屏角标) check(not main.debug_overlay.visible, "V2f 调试浮窗 boot 不自动开(菜单优先)〔2026-10-16 用户令〕") @@ -304,7 +303,7 @@ func _smoke_boot_chain() -> void: DirAccess.remove_absolute(p) -# ---- 生命周期存活性矩阵(迭代 28 T3——九阶段×五引用面;驱动复用 V3 debug seed 开局路径+ +# ---- 生命周期存活性矩阵(九阶段×五引用面;驱动复用 V3 debug seed 开局路径+ # _auto_play_round 活战斗模式+ui_struct resume 夹具模式,不另起点击链)---- # 阶段映射说明:计划书十阶段中「开局停点」与「地图选路」在本现行流程同为关卡画面停点态 #(level_started→choices_presented 同步到达,无可观测中间态)——合并为 V3b 一处断言。 @@ -419,7 +418,7 @@ func _smoke_lifecycle_matrix() -> void: await process_frame var open_extra: Dictionary = {"mf_start": false} if modal_name == "debug": - open_extra = {"mf_start": true} # 调试浮窗=浮于菜单之上的 Dialog(不隐藏开始层——迭代 18 卡⑦形态) + open_extra = {"mf_start": true} # 调试浮窗=浮于菜单之上的 Dialog(不隐藏开始层) await _stage_faces(main, "V3g 模态开·%s" % modal_name, "null", "null", "null", open_extra) if modal_name == "settings": main._on_settings_closed() @@ -580,7 +579,7 @@ func _face_liveness(name: String, v, want: String) -> String: return "" -# ---- 会话物化断言(迭代 27 T1 V3——两连局复位/无脏状态残留;原手工复位清单消亡的行为级证明)---- +# ---- 会话物化断言(V3——两连局复位/无脏状态残留)---- func _smoke_run_lifecycle() -> void: print("--- 迭代27 T1 会话物化(V3:两连局复位+脏状态不残留)---") var main: Node = load("res://presentation/main.tscn").instantiate() @@ -601,7 +600,7 @@ func _smoke_run_lifecycle() -> void: "V3 开局建会话(is_adventure+adventure 在座)") check(main.run_scope.hints_shown.is_empty(), "V3 新会话局态零值") - # 注入脏状态(旧手工清单时代的典型泄漏源——新会话必须整体吞掉;迭代 27 T3——刷新计数已单源化入编排器,不再属会话脏面) + # 注入脏状态(典型泄漏源——新会话必须整体吞掉;刷新计数单源化在编排器,不属会话脏面) main.run_scope.hints_shown["chord"] = true main.run_scope.boss_active = true main.run_scope.last_gain_amount = 77 @@ -701,7 +700,7 @@ func _run_core_smoke(db, rng) -> void: _smoke_node_map_templates() -# ---- 关卡节点图生成·模板池冒烟(M-3 迭代 5 T5——v0.4 §P0.6 断言面)---- +# ---- 关卡节点图生成·模板池冒烟(v0.4 §P0.6 断言面)---- func _smoke_node_map_templates() -> void: # ① 扩签:node_map 入用途标签封闭词表(派生零改动——标签只进事件日志) var svc = load("res://core/rng_service.gd").new() @@ -721,7 +720,7 @@ func _smoke_node_map_templates() -> void: rng0.new_adventure(910001) var runner0 = load("res://core/level_runner.gd").new(_db, rng0) var c_before: int = rng0.counter() - check(runner0.start_level_external(2, {"hero_hp": 20, "gp": 0}, {}, # 迭代 27 T3——start_level_external 签名收口(bonus 参数随 RunLedger 单类下传退役) + check(runner0.start_level_external(2, {"hero_hp": 20, "gp": 0}, {}, # start_level_external 签名收口(bonus 参数由 RunLedger 单类下传) Callable(self, "_smoke_rest_stub"), {}, true, 0), "强制 template_pick=0 起关受理") check(rng0.counter() == c_before, "强制取模板零 RNG 消耗(零抽签——首次脚本语义)") var tpl0: Dictionary = {} @@ -778,7 +777,7 @@ func _smoke_rest_stub(pct: int, hp: int, max_hp: int) -> int: return mini(int(floor(float(max_hp) * float(pct) / 100.0)), max_hp - hp) -# ---- 冒险结构实现批冒烟(2026-09-21——AdventureTable 建表 + AdventureRunner + 冒险验收断言)---- +# ---- 冒险结构冒烟(AdventureTable 建表 + AdventureRunner + 冒险验收断言)---- # 令牌候选匹配(TP0——kind+tier 复合身份;冒烟断言面共用) func _smoke_find_token(candidates: Array, kind: String, tier: String) -> Dictionary: @@ -789,7 +788,7 @@ func _smoke_find_token(candidates: Array, kind: String, tier: String) -> Diction return {} -# ① 冒险表(单行全局 Rule 4 豁免——建表与接线闸;TP0 令牌池换代:配额结构/件值对/池总量域检) +# ① 冒险表(单行全局 Rule 4 豁免——建表与接线闸;TP0 令牌池:配额结构/件值对/池总量域检) func _smoke_adventure_table() -> void: print("--- 冒险表(AdventureTable——令牌池行值单点:回血/配额/件值对/同调位)---") check(_db.adventure != null, "db.adventure 已加载(adventure.tres 入 manifest)") @@ -813,8 +812,7 @@ func _smoke_adventure_table() -> void: "cap 占位在域(案②提前退役——99=实质无上限,实数归调参批)〔专长批 V8 形态面〕") check(Attunement.slots(_db, null) == 0, "同调位读数源=树同调位节点点亮数(迭代 21 T4 槽位收编——null 档求值 0;谓词表已退役)〔天赋树批 V14〕") - # 迭代 22 T1——新目录 12 件全量换代(V1/V2 断言落点;旧提灯段随 fog_lantern 行退役摘除, - # 装配→战斗贯通与空装配基线本体保留换主语 morning_order) + # 同调目录 12 件(V1/V2 断言落点;装配→战斗贯通与空装配基线的现行主语 = morning_order) var trows: Array = _db.treasure_attunement_rows() var tid_set := {} for r in trows: @@ -868,9 +866,9 @@ func _smoke_adventure_table() -> void: check(orch_e.begin_battle({"level_index": 1, "node_depth": 0, "hero_hp": int(_db.hero.max_hp)}) and not orch_e.attune_has("morning_order"), "空装配基线:不带 attunement 起战 attune_has=false(off 态零扰动)〔秘宝批换主语〕") - # V9 静态词表断言(迭代 22 T6——棋盘事实不可变契约 3:新 12 行 triggers do.kind 与 effect_kinds - # 全集零棋盘改写类词〔rewrite_board 已除名/remove_mines/cell_removal=改写族——remove_mines 现役 - # 语义=爆破工兵包旧通道随行退役,新表零引用〕;效果只允许信息呈现与开格动作) + # V9 静态词表断言(棋盘事实不可变契约 3:12 行 triggers do.kind 与 effect_kinds + # 全集零棋盘改写类词〔rewrite_board/remove_mines/cell_removal=改写族——现表零引用〕; + # 效果只允许信息呈现与开格动作) var rewrite_words := ["rewrite_board", "remove_mines", "cell_removal"] var v9_ok := true for r9 in trows: @@ -881,7 +879,7 @@ func _smoke_adventure_table() -> void: if rewrite_words.has(String((tr9 as Dictionary).get("do", {}).get("kind", ""))): v9_ok = false check(v9_ok, "新 12 行效果词零棋盘改写类(危险格/安全格分布同池冻结——真视/开格动作外无写面)〔秘宝批 V9〕") - # 覆盖检查(迭代 22 T6——效果三方向覆盖:信息〔巢穴预告/线香/天眼/阔视野带〕/行动资源〔晨操令/ + # 覆盖检查(效果三方向覆盖:信息〔巢穴预告/线香/天眼/阔视野带〕/行动资源〔晨操令/ # 双管装填/试炼镐/储备罐〕/操作能力〔远程镐/信标网络〕+抉择刷新〔刷新练习/刷新执照〕——dimension_tags 静态投影) var tag_set := {} for r10 in trows: @@ -889,8 +887,8 @@ func _smoke_adventure_table() -> void: tag_set[String(tg)] = true check(tag_set.has("info") and tag_set.has("action") and tag_set.has("plan"), "效果三方向覆盖在册(信息/行动资源/操作能力=plan·抉择刷新——12 件目录结构对齐设计权威)〔秘宝批 V10 覆盖半〕") - # V18 装配面空目录合法态(迭代 22 T6——白板档全未解锁:柜台投影 12 行全未解锁+mode 分派正确; - # 池空兜底/商店空货架两部分归奇物/商店侧另批〔卡片 §4〕) + # V18 装配面空目录合法态(白板档全未解锁:柜台投影 12 行全未解锁+mode 分派正确; + # 池空兜底/商店空货架两部分归奇物/商店侧断言面〔卡片 §4〕) var mp_v18 = load("res://core/meta_progression.gd").new(_db, _meta_new_save(_META_SMOKE_PATHS[12])) var v18_ok := true var locked_n := 0 @@ -910,7 +908,7 @@ func _smoke_adventure_api() -> void: print("--- 冒险结构 API 闸(重复开始拒绝 · 入口停点 · 放弃两态受理)---") var adr = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(42)) adr.set_hero_override(900, 400) # 首战速胜档(放弃的非战斗受理要走到选路态) - # 停点前移批 2026-09-23:入口停点观测(信号序 + 入口候选快照——容器写回规避 lambda 按值捕获) + # 入口停点观测(信号序 + 入口候选快照——容器写回规避 lambda 按值捕获) var sig_seq: Array = [] var obs := {"entry_cands": []} adr.level_started.connect(_api_mark_started.bind(sig_seq)) @@ -945,7 +943,7 @@ func _smoke_adventure_api() -> void: check(not adr.abandon(), "结算后重复 abandon 拒绝(结算受理只算一次——state=idle)") -# 停点前移批 2026-09-23 观测桩(信号序采集——bind 容器写回,签名按各信号实参定制) +# 观测桩(信号序采集——bind 容器写回,签名按各信号实参定制) func _api_mark_started(_li: int, _dn: String, seq: Array) -> void: seq.append("level_started") @@ -965,7 +963,7 @@ func _smoke_adventure() -> void: print("--- 冒险结构验收(三关序列 · 大奖励 · 摘要五件事 · 账本封闭)---") var autoplay = load("res://smoke/level_autoplay.gd") # ① 表与覆盖义务(序列关数 = 行集关数;行集内每个战斗/Boss 节点跨表精确行集——覆盖义务断言; - # 2026-10-07 行集多行批:「精确行」改「精确行集」口径——enemy 侧同坐标多行合法,坐标级键聚合天然兼容) + # 精确行集口径——enemy 侧同坐标多行合法,坐标级键聚合天然兼容) check(int(_db.level.rows.size()) == 3, "序列关数 = 行集关数(三关正式序列生效)") var bg_keys := {} for row in _db.board_gen.rows: @@ -1004,7 +1002,7 @@ func _smoke_adventure() -> void: if (ev as Dictionary).has("curio_pick"): picks.append((ev as Dictionary)["curio_pick"]) elif (ev as Dictionary).has("node_curio_pick"): - node_picks += 1 # 奖励节点三选一(追加批——每关奖励节点各 1 次) + node_picks += 1 # 奖励节点三选一(每关奖励节点各 1 次) elif (ev as Dictionary).has("curio_resolved"): resolves.append((ev as Dictionary)["curio_resolved"]) check(picks.size() == 2 and resolves.size() == 2 + node_picks, @@ -1034,7 +1032,7 @@ func _smoke_adventure() -> void: cand_ok = false var seen := {} for c in cands: - # 身份键 = kind|tier|feat_id(迭代14① T4 断言基线复核——TP0 v2.2 relic 按 feat_id 分列 + # 身份键 = kind|tier|feat_id(TP0 v2.2 relic 按 feat_id 分列 # 不参与同 kind 去重〔_token_identity relic: 前缀〕,同 tier 三枚不同流派件=三个不同选项合法态) var ckey := "%s|%s|%s" % [String((c as Dictionary).get("kind", "")), String((c as Dictionary).get("tier", "")), String((c as Dictionary).get("feat_id", ""))] if seen.has(ckey): @@ -1044,7 +1042,7 @@ func _smoke_adventure() -> void: var hp_before: int = int(p.get("hp_before", -1)) var hp_after: int = int(p.get("hp_after", -1)) # 模拟档 v3.4 商店贪心购血合法抬升(L2/L3 店在 Boss 前)——回血口径窗口 = 加算区件 + 购血余量 0..15 - # T17 账本口径修复随批:置满/回血封顶改生效上限口径(flat 后乘调试浮窗 pct)——窗口同步 ×5(本段 pct=400) + # 账本生效上限口径:置满/回血封顶按生效上限(flat 后乘调试浮窗 pct)——窗口同步 ×5(本段 pct=400) var heal_ok_i := false for extra in 46: var m := int(round(float(int(_db.hero.max_hp) + hp_acc + extra) * 5.0)) @@ -1071,8 +1069,8 @@ func _smoke_adventure() -> void: var seq: Array = st["encounter_max_hp_seq"] var k := 5.0 # hp+400 ⇒ 调试浮窗百分比后乘 ×5(加算先加、百分比后乘——生效次序口径) var exp_base := maxi(1, int(round(float(int(_db.hero.max_hp)) * k))) - # 模拟档 v3.4 商店贪心购血(数值修复批)合法抬升——上限窗口 = 基础 + 加算区 3 件 + 购血余量; - # 大生命 +10(迭代 20 T2 四级换代:优秀档)——上界按大件最坏构成 3×10+购血 15=+45(TP0 放宽承袭) + # 模拟档 v3.4 商店贪心购血合法抬升——上限窗口 = 基础 + 加算区 3 件 + 购血余量; + # 大生命 +10(优秀档)——上界按大件最坏构成 3×10+购血 15=+45(TP0 放宽承袭) var hp_ceiling := maxi(1, int(round(float(int(_db.hero.max_hp) + 3 * int(_db.adventure.curio_value("max_hp", "excellent")) + 15) * k))) var seq_ok := seq.size() > 0 and int(seq[0]) == exp_base for v in (seq as Array): @@ -1123,7 +1121,7 @@ func _smoke_adventure() -> void: var adr6 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(7)) adr6.set_hero_override(900, 400) check(adr6.start_adventure(7, {"first_script": true}), "重复拒绝场景:冒险启动(seed 7——固定模板 0 同上)") - adr6.runner().pick_next_node(int(adr6.runner().next_candidate_ids()[0])) # 停点前移批 2026-09-23:入口停点 pick 进首战 + adr6.runner().pick_next_node(int(adr6.runner().next_candidate_ids()[0])) # 入口停点 pick 进首战 var b6 = adr6.runner().current_battle() var st6 := _adv_st() var g6 := 30 @@ -1188,7 +1186,7 @@ func _smoke_adventure() -> void: var expect_acc: int = acc_shop + (int(a8._curio_result.get("value", 0)) if picked2 == "max_hp" else 0) check(int(a8.run_ledger.bonus.get("max_hp", -1)) == expect_acc, "三选一属性件与商店购买同账累加(max_hp=%d = %d + 三选一%s)" % [int(a8.run_ledger.bonus.get("max_hp", -1)), acc_shop, picked2]) - var max_eff8: int = a8.effective_max_hp() # T17 口径修复随批:账本生效上限含调试浮窗 pct(a8 已 set 400) + var max_eff8: int = a8.effective_max_hp() # 账本生效上限含调试浮窗 pct(a8 已 set 400) check(int(a8.ledger["hero_hp"]) <= max_eff8, "通关部分回血封顶(hp %d ≤ 生效上限 %d——血回满语义退役)" % [int(a8.ledger["hero_hp"]), max_eff8]) check(a8.continue_to_next_level(), "兑付后推进受理(下一关开始)") @@ -1215,7 +1213,7 @@ func _smoke_adventure() -> void: autoplay._autoplay_battle(a10.runner(), b10, st10, null) check(a10.runner().current_battle() == null and a10.abandon(), "非战斗期(选路态)abandon 受理") # ⑪ 池耗即枯竭 + 池收缩 + 满血回 0(TP0——white-box:耗尽 attack/ap 令牌后候选零出现; - # 种类次数上限退役,「达上限剔除」语义由牌库耗尽承载) + # 无种类次数上限,「达上限剔除」语义由牌库耗尽承载) var a11 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(11)) check(a11.start_adventure(11, {"first_script": true, "treasure_unlocked": {"wide_scout_band": true}}), "剔牌库/替换场景:冒险启动(seed 11——道具解锁集只含 wide_scout_band)") @@ -1230,8 +1228,8 @@ func _smoke_adventure() -> void: check(not draw_kinds.has("attack") and not draw_kinds.has("ap"), "池耗即枯竭(attack/ap 令牌耗尽不出候选——%s)" % str(draw)) check((draw as Array).size() >= 2, "池耗后候选恒 ≥2(稀有/罕见档余量——防「三选项全不可选」死角)") - # 池收缩(迭代 11 同调批 T7——aux 卡退役出三选一牌库:重复抽样零 aux 候选;同调位替换两路 - # white-box 测试随停点渠道退役拆除——机械惰性承载,零投放零行为) + # 池收缩(aux 不入三选一牌库:重复抽样零 aux 候选;同调位替换两路 + # white-box 测试属停点渠道,零投放零行为) var treasure_seen := false for i in 40: for t in a11._draw_curio_candidates(): @@ -1249,7 +1247,7 @@ func _smoke_adventure() -> void: a12._on_level_finished({"result": "victory", "hp": max_full, "node_index": 1, "node_id": 1, "node_type": "shop"}) check(int(cap["payload"].get("heal_gained", -1)) == 0, "满血通关回血 0 合法(封顶口径——heal_gained=0 非负溢出)") - # ⑬ 奖励节点共享池(迭代 10 追加批——同库同池同摘牌;TP0:attack 令牌耗尽后节点域同样零出现) + # ⑬ 奖励节点共享池(同库同池同摘牌;TP0:attack 令牌耗尽后节点域同样零出现) var a13 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(13)) check(a13.start_adventure(13, {"first_script": true, "treasure_unlocked": {"wide_scout_band": true}}), "节点共享池场景:冒险启动(seed 13)") @@ -1276,11 +1274,11 @@ func _smoke_adventure() -> void: "放弃摘要:abandoned · 未打穿(已获大奖励不追回——同失败型结算)") -# ---- 专长重设计实装冒烟(迭代 20 T3——feats 四级换代 · 案D 池接线 · V3 订阅面逐件三列)---- +# ---- 专长冒烟(feats 四级 · 案D 池接线 · V3 订阅面逐件三列)---- func _smoke_feats() -> void: print("--- 专长重设计实装(feat_table 四级 · 专长带池接线 · 订阅面逐件)---") - # ① 现行表牌库构成:重设计 30 件全量入池——102 数值令牌+30 relic 令牌(四级 rarity 直映射;迭代 31 卡② 完美保险迁入) + # ① 现行表牌库构成:30 件全量入池——102 数值令牌+30 relic 令牌(四级 rarity 直映射) check(_db.feats != null and (_db.feats.rows as Array).size() == 30, "feat_table 已加载(30 件=基础 27+迁入 2+卡② 完美保险 1——迭代 31 卡② 换代)") check(_db.feats.validate().is_empty(), "feat_table.validate 零违例(四级 rarity/cap 域/trigger 词表/行键白名单全过)") var a_r0 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(71)) @@ -1294,7 +1292,7 @@ func _smoke_feats() -> void: tier_counts[tk] = int(tier_counts.get(tk, 0)) + 1 check(feat_tokens == 30 and int(tier_counts.get("common", 0)) == 12 and int(tier_counts.get("excellent", 0)) == 9 and int(tier_counts.get("rare", 0)) == 9 and a_r0._curio_deck.size() == 132, "专长带入池:30 件四级直映射(普通 12/优秀 9/稀有 9/传说 0)——牌库 102+30=132〔专长批 V2+卡② 完美保险迁入〕") - # ② 旧 27 件退役钉面(V2——arcane_ember 系旧件表首行;全仓 grep 零残留归批末静态核查) + # ② 旧 27 件零残留钉面(V2——arcane_ember 系旧件表首行;全仓 grep 零残留归静态核查) check(_db.feats.row_by_id("arcane_ember").is_empty() and _db.feats.row_by_id("magma_body").is_empty(), "旧 27 件已退役:arcane_ember/magma_body 表内零残留〔专长批 V2〕") check(_db.treasure_items.row_by_id("venom_edge").is_empty() and _db.treasure_items.row_by_id("seal_burst").is_empty(), @@ -1348,7 +1346,7 @@ func _smoke_feats() -> void: deck_relic += 1 check(deck_relic == 5 and a_r._curio_deck.size() == 107, "专长带入池:5 行 relic 每件 1 张(四级 rarity 直映射)——牌库 102+5=107") - # T4 渠道白名单断言(迭代 15 卡②——渠道轴定位:通关渠道只出专长/节点渠道零专长) + # 渠道白名单断言(渠道轴定位:通关渠道只出专长/节点渠道零专长) var feat_seen: Dictionary = {} var node_relic_seen := false for i in 60: @@ -1615,7 +1613,7 @@ func _smoke_feats() -> void: and orch0._fx_emit("mine_hit", {"damage": 5}).is_empty() and orch0._fx_emit("battle_won", {"round": 1}).is_empty(), "零持有订阅=零命中(relic 关着零扰动——伤害管线既有行为逐位不变)") - # ⑦c 特性持有呈现段(2026-10-04 用户反馈补齐——C 区「特性」节;呈现换代面=06 在册不随批) + # ⑦c 特性持有呈现段(C 区「特性」节;呈现面在 06 在册) var panel = load("res://presentation/views/hero_info_panel_view.gd").new() panel.set_feat_holdings([]) check(not panel._feat_section.visible, "特性段空态隐藏(视图空态纪律同特性段)") @@ -1635,7 +1633,7 @@ func _adv_drive_to_shop(a, st: Dictionary, autoplay) -> bool: if String(st["result"]) != "": return false if a._pending_next_level: - # 三选一停点确认(迭代 10——确定性选件后推进,与 run_adventure 自动策略同口径;TP0 令牌化) + # 三选一停点确认(确定性选件后推进,与 run_adventure 自动策略同口径;TP0 令牌化) if not a._curio_pending.is_empty(): var bcands: Array = a._curio_pending["candidates"] var bpick: Dictionary = autoplay._pick_token(bcands) @@ -1652,7 +1650,7 @@ func _adv_drive_to_shop(a, st: Dictionary, autoplay) -> bool: continue var t := String(r.current_node().get("type", "")) if t == "reward": - # 奖励节点三选一(迭代 10 追加批——确定性选件、替换放弃新件、兑付确认回图;TP0 令牌化) + # 奖励节点三选一(确定性选件、替换放弃新件、兑付确认回图;TP0 令牌化) var ndraw: Dictionary = a.node_curio_candidates() var ncands: Array = ndraw.get("candidates", []) as Array if not ncands.is_empty(): @@ -1674,9 +1672,9 @@ func _adv_st() -> Dictionary: -# ---- 战斗屏棋盘布局·格边长公式回归(2026-09-19 真人试玩 bug⑥:L2 12×12 板下缘被裁约 1/6 格高—— -# 旧公式 N×cell ≤ 可用高−12 未计 (N−1)×2px 网格间距,网格实高溢出被 clip_contents 裁掉; -# 修复 = 公式计入间距 + 垂直预留 24px〔上 12/下 12——底部不贴 D 区边框〕)---- +# ---- 战斗屏棋盘布局·格边长公式回归(真人试玩 bug⑥:L2 12×12 板下缘被裁约 1/6 格高—— +# 公式 N×cell ≤ 可用高−12 必须计入 (N−1)×2px 网格间距,否则网格实高溢出被 clip_contents 裁掉; +# 现公式 = 计入间距 + 垂直预留 24px〔上 12/下 12——底部不贴 D 区边框〕)---- func _smoke_layout_cell_formula() -> void: print("--- 棋盘布局格边长公式(底部预留回归)---") var board_generator = load("res://core/board_generator.gd").new() @@ -1694,7 +1692,7 @@ func _smoke_layout_cell_formula() -> void: board_view.free() -# ---- 未开格类型微光·数据侧断言(迭代 30 卡① T2-①——V1 作用集恒等/V2 九型归组封闭/V7 零玩法写入)---- +# ---- 未开格类型微光·数据侧断言(V1 作用集恒等/V2 九型归组封闭/V7 零玩法写入)---- # 夹具纪律:身份回调形状与 reward_economy.query_identity 同构({reward_id, cell_type, tier}); # 位点覆盖表 _glow_type_overrides(Vector2i → cell_type)+封锁集 _glow_blocked(Vector2i → true, # 返回 null = 不在摇号清单的封锁格)。哈希兜底按坐标确定性散列——全缸可复现。 @@ -1961,7 +1959,7 @@ func _ms_digest(ms, ae) -> Array: return [[int(ms.hero_pos().x), int(ms.hero_pos().y)], rev, seals, ae.ap, ae.phase, ms.seal_count()] -# ---- 地图战斗资源·身份面单元冒烟(格面资源批:roll 恰一次 / 雷安同池 / 幂等 / 清图批尾)---- +# ---- 地图战斗资源·身份面单元冒烟(格面资源:roll 恰一次 / 雷安同池 / 幂等 / 清图批尾)---- func _smoke_reward_identity_unit() -> void: print("--- 地图战斗资源·格面资源身份面 ---") @@ -2008,7 +2006,7 @@ func _smoke_reward_identity_unit() -> void: check(reward_economy.grant(eligible[0].cell) == null, "映射退役后 grant 拒绝(生命周期闭合)") -# ---- 地图战斗资源·伤害量值区间批冒烟(2026-09-14:身份批 roll 域内 + 中点锚 + 变异实际流动 + 定值行不受扰)---- +# ---- 地图战斗资源·伤害量值区间冒烟(roll 域内 + 中点锚 + 变异实际流动 + 定值行不受扰)---- # ---- 排雷玩法 封印动作耗尽末点 AP 回归(playtest 缺陷②——v1 冒烟盲区:自动玩家不用封印)---- @@ -2022,7 +2020,7 @@ func _smoke_seal_ap_exhausted() -> void: settlement.round_started.connect(func(ri): rounds.append(ri)) check(settlement.begin_battle({"level_index": 1, "node_depth": 4, "hero_hp": int(_db.hero.max_hp)}), "回归战斗启动(Boss 行——D0 20HP 级会被盲挖粉尘秒杀,无法承载封印回归场景)") var minesweeper = settlement.minesweeper - # 恰花 (AP-1) 点挖掘,留末点给封印(表驱动——2026-09-16 AP 压速批 8→6 不再写死) + # 恰花 (AP-1) 点挖掘,留末点给封印(表驱动——AP 从表读不写死) var ap_total: int = int(_db.action_economy.ap_per_round) for i in range(ap_total - 1): if settlement.action_economy.phase != "Active" or settlement.action_economy.ap == 0: @@ -2047,7 +2045,7 @@ func _smoke_seal_ap_exhausted() -> void: check(rounds.size() >= 2, "封印动作耗尽 AP 触发轮末结算并进入第 2 轮(rounds=%s)" % str(rounds)) -# ---- 关卡节点地图·线性推进冒烟(2026-09-11 关卡扩展批)---- +# ---- 关卡节点地图·线性推进冒烟---- func _smoke_level() -> void: print("--- 关卡节点地图·线性推进(战×2→道具→战×2→恢复→Boss)---") @@ -2060,7 +2058,7 @@ func _smoke_level() -> void: check(win.boss_depth == 4, "Boss 节点以 Dmax=4 解析(棋盘生成 第三轴登记约定)") check(win.hp_at_boss >= 1 and win.hp_at_boss <= int(_db.hero.max_hp) * 3, "进 Boss HP 携带在域内(%d)" % win.hp_at_boss) # ② 恢复点:回复 = min(floor(生效max_hp×pct/100), 缺口)——hp+100% 档生效 max = 基线×2 - # seed 42(2026-09-19 充能退役批换种:原 4242 因主角输出模型变化在恢复点前败北——探针目的 = 验回复公式,种子仅载体) + # seed 42(探针目的 = 验回复公式,种子仅载体) var rest = autoplay.run_level(_db, 42, 1, 100, 100) if rest.result != "start_failed" and rest.hp_before_rest >= 0: var eff_max := maxi(1, int(round(float(_db.hero.max_hp) * 2.0))) # hp_pct=100(run_level 已恢复基线) @@ -2083,7 +2081,7 @@ func _smoke_level() -> void: "模拟后 hero 表恢复基线(atk=%d hp=%d ac=%d——对配置快照)" % [int(_db.hero.atk), int(_db.hero.max_hp), int(_db.hero.armor_class)]) -# ---- 迭代 24 N3:敌方攻击类型轴(2026-10-13——表列/单位快照/单据载荷/矩阵命中证词)---- +# ---- 敌方攻击类型轴(表列/单位快照/单据载荷/矩阵命中证词)---- # 克制矩阵命中证词 = 同种子三甲型配对实测(不是查表存在性证词):同种子下 armor_roll 流消费逐位一致、 # 阈值(hero armor_class)不变,三甲型唯一差异 = 克制点数 cdelta(normal_vs_light 0 / heavy −1 / ward +1) # → heavy 伤害 == light −1、ward == light +1(要求基线伤害 ≥ 2——地板 1 会吞 −1 位移)。 @@ -2145,17 +2143,16 @@ func _smoke_enemy_attack_type() -> void: check(payload_at == "normal", "敌方伤害技单据载荷 attack_type 非空(= %s——第 9 参传值面,迭代 24 N3)" % payload_at) -# ---- 护甲等级掷点批·换装护栏(2026-09-16 用户拍板:百分比减伤行整体退役换装 AC,无双轨)---- -# ① 换装在位:defense_up 状态行/池映射/奖励行三处全无残留,ac_up 三处就位(unit=ac,2026-09-20 改只续时不叠层); +# ---- 护甲等级掷点·AC 单轨护栏(无 percent 减伤双轨)---- +# ① defense_up 状态行/池映射/奖励行三处零残留,ac_up 三处就位(unit=ac·只续时不叠层); # ② 免伤墙归零护栏泛化保留(BUG-0003 事故类永久免疫):hero_defense 池任何 percent 行 -# magnitude × max_stack > pool_clamp_lo——单效果叠满不可触池底(off_guard 已于 2026-09-18 -# 结构修复批退离 hero_defense 池换装 AC 轴,池内现无 percent 行——本断言防未来负向行回归时静默造墙); -# ③ 单位表 armor_class 字段:主角 10(暂定)/ 敌方行 0(暂定——正式值归怪物设定批); +# magnitude × max_stack > pool_clamp_lo——单效果叠满不可触池底(池内现无 percent 行——本断言防未来负向行回归时静默造墙); +# ③ 单位表 armor_class 字段:主角 10(暂定)/ 敌方行 0(暂定——正式值归怪物文档); # ④ 掷点参数域:档位边界升序/档位值降序无零档/骰面与暴击参数在域(加载校验双保险)。 func _smoke_ac_swap_guard() -> void: print("--- 护甲等级掷点批·换装护栏 ---") - # ① 换装在位(三处无双轨) + # ① 三处无双轨 check(_db.status_effect_row("defense_up").is_empty(), "状态表 defense_up 行已退役(无双轨)") var ac_row: Dictionary = _db.status_effect_row("ac_up") check(not ac_row.is_empty() and String(ac_row.get("target_side", "")) == "hero" \ @@ -2190,14 +2187,14 @@ func _smoke_ac_swap_guard() -> void: "主角 armor_class 在域内(%d——暂定基准随表走)" % int(_db.hero.armor_class)) var ac_band := true var ac_detail := "" - var heavy_names := ["熊地精重击手", "灰矮人重装手"] # U2 裁 v1 硬梯度(2026-09-29):逐行手设值 8/9,非精英编码位 + var heavy_names := ["熊地精重击手", "灰矮人重装手"] # 逐行手设值 8/9,非精英编码位 for row in _db.enemy.rows: var ac: int = int(row.get("armor_class", -1)) var dname := String(row.get("display_name", "?")) var boss_row: bool = String(row.get("enemy_id", "")).ends_with("_chief") or \ String(row.get("enemy_id", "")) == "drider" or String(row.get("enemy_id", "")) == "duergar_king" var heavy_row: bool = dname in heavy_names - # 杂鱼 0~5;重击手/重装手 8~9(U2 返工批手设精英值);Boss 8~12 台阶 + # 杂鱼 0~5;重击手/重装手 8~9(手设精英值);Boss 8~12 台阶 var lo := 8 if (boss_row or heavy_row) else 0 var hi := 12 if boss_row else (9 if heavy_row else 5) if ac < lo or ac > hi: @@ -2213,9 +2210,9 @@ func _smoke_ac_swap_guard() -> void: boss_ac[int(row.get("level_index", 0))] = int(row.get("armor_class", 0)) check(int(boss_ac.get(1, 0)) < int(boss_ac.get(2, 0)) and int(boss_ac.get(2, 0)) < int(boss_ac.get(3, 0)), "Boss AC 关卡台阶严格递增(%d < %d < %d)" % [int(boss_ac.get(1, 0)), int(boss_ac.get(2, 0)), int(boss_ac.get(3, 0))]) - # ③c 迭代 24 N1(2026-10-13):(1,2) 降档锚定 + 第一关总量曲线护栏 - # 降档裁决沿革:2026-09-24 阶名化解方案(50 血系设计非填错)实机未达预期,按体验反馈重裁 hp 22 / ac 2; - # 敌种 bugbear 与池 attack6/charge2/heavy2 钉死不动(防顺手改多——hobgoblin 无立绘,改敌种案已否决); + # ③c (1,2) 降档锚定 + 第一关总量曲线护栏 + # (1,2) 锚定值 hp 22 / ac 2; + # 敌种 bugbear 与池 attack6/charge2/heavy2 钉死不动(防顺手改多); # 曲线护栏 = 相邻节点「hp × 中位数量」总量比 ≤ 2.5(12/10/22/35/72 现行全绿;不用单调不回撤——会红在 (1,0)→(1,1)) var l12_row: Dictionary = {} for row in _db.enemy.rows: @@ -2259,7 +2256,7 @@ func _smoke_ac_swap_guard() -> void: check(bounds == [3, 7] and discounts == [75, 50, 25], "档位表拍板值在位(缺口 1-3 → ×0.75 · 4-7 → ×0.5 · 8+ → ×0.25——无零档)") -# ---- 护甲等级掷点批·行为面(2026-09-16 拍板验收:折扣档分布 / nat20 暴击 / 伤害下限 / 棋盘来源必中)---- +# ---- 护甲等级掷点·行为面(折扣档分布 / nat20 暴击 / 伤害下限 / 棋盘来源必中)---- func _smoke_armor_roll() -> void: print("--- 护甲等级掷点(查档纯函数 + 暴击 + 伤害下限 + AC12 分布 + 棋盘必中)---") @@ -2280,8 +2277,8 @@ func _smoke_armor_roll() -> void: for roll in range(1, 21): ev_sum += DamageMath.roll_discount_percent(roll, 10, _db.settlement.roll_tier_bounds, _db.settlement.roll_tier_discounts) check(ev_sum == 1575, "AC10 EV 锚:期望系数合计 %d/2000 = 期望减免 21.25%%(nat20 恒全额含内)" % ev_sum) - # ② nat20 暴击(行为面):并流批(2026-09-27 统一流裁决)后掷点位随全局序漂移——探针改为按行为面扫描 - # 「主角先手首掷 = 20」的种子,不再假设 armor_roll scope0 位 + # ② nat20 暴击(行为面):探针按行为面扫描 + # 「主角先手首掷 = 20」的种子,不假设 armor_roll scope0 位 var crit_seed := -1 var crit_rows := {} for s in range(1, 800): @@ -2294,15 +2291,15 @@ func _smoke_armor_roll() -> void: "nat20 → 行留档 roll=20 + crit 标记(主角先手普通分量)") check(int(crit_rows.get("normal", -1)) == 2 * int(_db.hero.atk) and int(crit_rows.get("value", -1)) == 2 * int(_db.hero.atk), "nat20 → 普通分量 ×2(%d = 2×%d,暴击倍率只乘该分量,穿刺/魔法不吃)" % [int(crit_rows.get("normal", -1)), int(_db.hero.atk)]) - # ③ 削弱续时(行为面):授予→衰减一轮→再授予 → 层数保持 1、剩余结算数重置(2026-09-18 结构 - # 修复批叠层改续时——削弱 ×2 叠满池触底 ×0 的免伤轮结构性根治,旧 ×2 叠层采样通道随批退役) + # ③ 削弱续时(行为面):授予→衰减一轮→再授予 → 层数保持 1、剩余结算数重置 + # (削弱为续时语义,无叠层通道) var weaken_probe := _weaken_refresh_probe() check(int(weaken_probe.get("layers", -1)) == 1 and int(weaken_probe.get("remaining", -1)) == 2, "削弱重复授予 → 层数保持 1、剩余结算数重置 2(续时语义——结构性消饱和)") check(int(weaken_probe.get("pool", -999)) == int(_db.status_effect_row("weaken").magnitude), "削弱单层池读数 = 行值(enemy_output 池单层贡献——×2 叠满触底 ×0 不可达,免伤轮根治)") # ④ AC11 折扣档分布(行为面):ac_up 逐轮授给(时效 1)→ Boss 行攻击拍逐拍判定 - # (2026-09-20 主角增益续时批后 ac_up 层数恒 1——局内可达 AC 上限 10+1=11,探针随行下调) + # (ac_up 层数恒 1——局内可达 AC 上限 10+1=11,探针随行取值) var tiers := _ac11_tier_samples() var tier_distinct := {} var tiers_valid := true @@ -2331,8 +2328,8 @@ func _smoke_armor_roll() -> void: check(all_positive, "全战斗流零 v=0 伤害行(伤害下限全局生效)") check(attack_ok, "hero_attack/enemy_action 伤害行掷点读数+档位随行留档(P2 归因)") check(board_ok, "棋盘来源伤害行零掷点字段(爆裂/直伤/清障炸药/奖励即时必中全额)") - # ⑥ 全来源伤害下限(2026-09-20 用户拍板:任何伤害落地取值域 [1,+∞) 无上限——棋盘克制直伤此前 - # 靠表值 2+(−1)=1 贴底无结构保证,反噬/地形变异/爆裂同为表值直落,本批全部收进 damage_floor 闸内) + # ⑥ 全来源伤害下限(任何伤害落地取值域 [1,+∞) 无上限——棋盘克制直伤/反噬/地形变异/爆裂 + # 全部收在 damage_floor 闸内) var df: int = int(_db.settlement.damage_floor) check(DamageMath.counter_component(2, -1, df) == 1, "棋盘克制直伤贴底 → 下限 1(点数 2 vs 不利修正 −1)") check(DamageMath.counter_component(1, -3, df) == 1, "克制修正触底穿透 → 下限 1(点数 1 vs 修正 −3)") @@ -2355,7 +2352,7 @@ func _first_hero_attack_rows(seed_val: int) -> Dictionary: return {} -# 削弱续时探测(2026-09-18 结构修复批——旧 _weaken_zero_round_rows ×2 叠层采样随批退役): +# 削弱续时探测: # 授予 → 衰减一轮 → 再授予,读 weaken 实例投影 {layers, remaining, pool}。 # 直授通道(来源格真实坐标惯例——沿前例);depth 2 板(D2 熊地精)仅作宿主,行为与敌种无关。 func _weaken_refresh_probe() -> Dictionary: @@ -2370,14 +2367,14 @@ func _weaken_refresh_probe() -> Dictionary: settlement._status_effects.apply_effect("weaken", src) # 续时:remaining ← 2,层数不动 for eff in settlement._status_effects.query_active("enemy"): if String(eff.effect_id) == "weaken": - # T6 收口批:改走伤害控制器公有算术面 clamped_pool(原编排器 _clamped_pool 薄委托的直呼退役) + # 走伤害控制器公有算术面 clamped_pool return {"layers": int(eff.layers), "remaining": int(eff.remaining_settlements), "pool": int(settlement._damage.clamped_pool("enemy_output"))} return {} # AC11 折扣档采样:每停手轮前直授 ac_up ×1(时效 1 逐轮衰减)——敌拍逐拍判定留档。 -# (2026-09-20 主角增益续时批:ac_up 只续时不叠层、层数恒 1——原 ×2 授给达 AC12 的采样随批降为 AC11; -# 敌人技能池批:拍序改为摇号制,原 AC 批定影种子不再保证档位多样性——扫描种子取首个 ≥2 档样本集。) +# (ac_up 只续时不叠层、层数恒 1——采样上限取 AC11; +# 技能出招为摇号制——扫描种子取首个 ≥2 档样本集。) func _ac11_tier_samples() -> Array: for seed_offset in range(20): var rng = load("res://core/rng_service.gd").new() @@ -2404,12 +2401,12 @@ func _ac11_tier_samples() -> Array: return [] -# ---- 主角乘区接线 + 硬化折半方向(2026-09-18 结构修复批护栏)---- +# ---- 主角乘区接线 + 硬化折半方向 ---- # 同种子停手轮恒同掷点(效果只改乘区、不动掷点流)→ 落地伤害精确关系: -# 增伤 = 基线 ×1.5、乏力 = ×0.75(hero_offense 池乘攻击合计——2026-09-19 充能退役后 = 单分量,直乘旁路退役); -# 硬化 = 基线 ×0.5 且 < 基线(enemy_defense 池负值折半——+100 翻倍符号 bug 随批纠正)。 -# 基线构成(加法核 2026-09-18 + 充能退役 2026-09-19):基线 100——hero 攻击类型=normal(锻造工坊配置默认值, -# 迭代 23 T2 起 hero.tres 两轴删除)对轻甲中性 0 修正(目标 = L1 地精轻甲;AC 0 恒全额非暴击种子)。 +# 增伤 = 基线 ×1.5、乏力 = ×0.75(hero_offense 池乘攻击合计 = 单分量,无直乘旁路); +# 硬化 = 基线 ×0.5 且 < 基线(enemy_defense 池负值折半)。 +# 基线构成:基线 100——hero 攻击类型=normal(锻造工坊配置默认值, +# hero.tres 无两轴字段)对轻甲中性 0 修正(目标 = L1 地精轻甲;AC 0 恒全额非暴击种子)。 func _smoke_pool_wiring() -> void: print("--- 主角乘区接线 + 硬化折半方向 ---") var base_row := _hero_attack_row_with({}, 100, 20260918) @@ -2452,7 +2449,7 @@ func _smoke_board_generator() -> void: var row = _db.resolve_board_gen(L, 0) check(not row.is_empty(), "BoardGen 行解析 (%d,0)" % L) if L == 2: - # R1 ceil 口径(2026-09-18 拍板):无精确行向上取整保证偏难——L2 深度 3 为恢复点无行,解析到深度 4 + # R1 ceil 口径:无精确行向上取整保证偏难——L2 深度 3 为恢复点无行,解析到深度 4 var ceil_row: Dictionary = _db.resolve_board_gen(2, 3) check(int(ceil_row.get("node_depth", -1)) == 4, "R1 ceil 解析 (2,3)→(2,4)(向上取整偏难)") var b1 = board_generator.generate(L, 0, _rng.open_stream("board_gen"), _db) @@ -2483,9 +2480,9 @@ func _smoke_board_generator() -> void: check(_board_dump(b2) == _board_dump(b3), "L%d 同种子两次生成逐格相同" % L) var b4 = board_generator.generate(L, 0, _mk_stream("board_gen", 778), _db) check(_board_dump(b2) != _board_dump(b4), "L%d 异种子产物不同(退化护栏)" % L) - # ---- 初始展开收窄批断言(迭代14① T4)---- + # ---- 初始展开收窄断言 ---- # ① 结构断言:R₀ ≤ cap(正式表行投值,合法性闸承载——出图必过);② r0_cap_rejected 尝试事实在位; - # ③ ring_removed 量级:剃雷域收窄后 ≤ 域内候选危险格数(5×5−出生 9=16——全域剃雷退役); + # ③ ring_removed 量级:≤ 域内候选危险格数(5×5−出生 9=16——无全域剃雷); # ④ 闸压线行为:cap=9(出生保障面下限)时出图必 r0≤9 或 accept_worst 非法标记(三分出口诚实降级,玩家永不卡死) var cap_val: int = int(row.get("r0_max_cap", 0)) check(cap_val >= BoardData.SPAWN_AREA_CELLS, "L%d r0_max_cap 正式行投值在位(%d ≥ 出生保障面 9——板面 30%% 锚)" % [L, cap_val]) @@ -2504,13 +2501,13 @@ func _smoke_board_generator() -> void: func _mk_stream(stream_name: String, scope: int) -> RandomNumberGenerator: - # 并流批(2026-09-27 统一流裁决):stream_name 降格为调用点自述标签(不参与派生),保留参数零改调用方 + # stream_name = 调用点自述标签(不参与派生),保留参数零改调用方 var rg := RandomNumberGenerator.new() rg.seed = _rng.derive_at(scope) return rg -# ---- 地形变异 框架面(首批类型定稿批 2026-09-19:四行两轴×两关 + 门控 + 跨字段互锁)---- +# ---- 地形变异 框架面(四行两轴×两关 + 门控 + 跨字段互锁)---- func _smoke_variation_framework() -> void: print("--- 地形变异 框架面(首批四类型 + 候选池门控 + 跨字段互锁)---") @@ -2549,8 +2546,8 @@ func _errs_has_cross_field(errs: Array) -> bool: return false -# ---- 全局作用域变异 断言面(2026-10-04 迭代 14 ③号卡首发批立面;2026-10-16 用户令屏蔽贫矿脉删行后 -# 改测「全局池空 → region 兜底回落」路径——互锁负样本/门控三维/资源面偏斜守恒与合成序/快照投影不变)---- +# ---- 全局作用域变异 断言面(「全局池空 → region 兜底回落」路径 +# ——互锁负样本/门控三维/资源面偏斜守恒与合成序/快照投影不变)---- # 取号计数桩(variant_place 取号断言——子类拦截计数,派生与取数语义零改动) class _CountVariantRng extends RngServiceCore: @@ -2561,7 +2558,7 @@ class _CountVariantRng extends RngServiceCore: return super.open_stream(purpose) -# 板行覆盖桩(迭代14① T4——cap 压线行为断言;接口面 = resolve_board_gen 单点) +# 板行覆盖桩(cap 压线行为断言;接口面 = resolve_board_gen 单点) class _BoardRowStub: var row: Dictionary func resolve_board_gen(_L: int, _D: int) -> Dictionary: @@ -2727,7 +2724,7 @@ func _board_resource_dump(settlement) -> Dictionary: return dump -# ---- 地形变异 布置段(首批类型定稿批 2026-09-19——棋盘设置顺序第 4 步断言面)---- +# ---- 地形变异 布置段(棋盘设置顺序第 4 步断言面)---- # 布置发生在编排器战斗初始化(install 初始展开 + roll_board 资源格之后),生成器产物零变异—— # 本段经 begin_battle 走完整初始化序后断言:门控一致性 / 布置域 / 数量公式 / 连通片上限 / 确定性。 @@ -2778,8 +2775,8 @@ func _smoke_variant_placement(L: int) -> void: var expect_cap: int = int(round(float(cand_count) * float(_db.variation.percent_of_cells) / 100.0)) \ + (L - 1) * int(_db.variation.per_level_bonus) check(vcells.size() <= expect_cap, "L%d 变异格数 %d ≤ 公式上限 %d(可挖池百分比 + 关卡递增)" % [L, vcells.size(), expect_cap]) - # 数量公式量随候选池缩放(2026-09-21 基数修正批):L1 无关卡加成,极小池(<10 格)可 round 至 0—— - # 零布置为合法态(同池空口径);非零断言改为条件式,公式量>0 时才要求非零(L2/L3 关卡加成保底恒>0) + # 数量公式量随候选池缩放:L1 无关卡加成,极小池(<10 格)可 round 至 0—— + # 零布置为合法态(同池空口径);非零断言为条件式,公式量>0 时才要求非零(L2/L3 关卡加成保底恒>0) check(expect_cap == 0 or vcells.size() > 0, "L%d 公式量>0 时非零布置(极小池 round 至 0 = 合法零布置——2026-09-21 基数修正批)" % L) var pack_max: int = int(_db.variation.pack_max) var vset := {} @@ -2855,14 +2852,14 @@ func _smoke_full_battle(L: int, D: int, label: String) -> void: has_verdict = true if row.get("source_class", "") == "hero_attack": hero_attacks += 1 - # 单分量伤害构成行(2026-09-19 充能退役批):hero_attack 行必须携带实际攻击类型键 + 掷点读数(P2 归因) - # 迭代 23 T2:类型键主语换代——hero.tres 两轴删除,实际攻击类型=锻造工坊配置默认值(本夹具零注入) + # 单分量伤害构成行:hero_attack 行必须携带实际攻击类型键 + 掷点读数(P2 归因) + # 类型键主语 = 锻造工坊配置默认值(hero.tres 无两轴字段;本夹具零注入) var atk_t: String = String(_db.forge_default_attack_type()) if not (row.has(atk_t) and row.has("roll") and row.has("ac") and row.has("tier")): hero_breakdown_ok = false check(has_verdict, "%s 步骤流含判定行" % label) - # 案C(2026-10-06 用户裁):授予段不再产出伤害——进入战斗段时主角恒存活且场上有敌, - # 先手必兑;旧「挖掘期兑付可在授予段单独击杀、零先手合法」结局随地图账迁战斗段末整体消失。 + # 案C:授予段不产出伤害——进入战斗段时主角恒存活且场上有敌, + # 先手必兑(地图账在战斗段末整体结账)。 check(hero_attacks >= 1, "%s 主角先手攻击行必存在(2026-09-11 拍板① + 案C 地图账殿后)×%d" % [label, hero_attacks]) check(hero_breakdown_ok, "%s 主角攻击行携带类型键与掷点读数(单分量——充能退役批)" % label) @@ -2882,7 +2879,7 @@ func _run_battle(L: int, D: int, axes: Dictionary = {}) -> Dictionary: var minesweeper = settlement.minesweeper var action_economy = settlement.action_economy var enc := {"level_index": L, "node_depth": D, "hero_hp": _db.hero.max_hp} - enc.merge(axes, true) # 迭代 23 T4——两根类型轴注入尾参(锻造工坊批对拍用;缺省零注入=回退面) + enc.merge(axes, true) # 两根类型轴注入尾参(缺省零注入=回退面) if not settlement.begin_battle(enc): out.stream.append({"type": "verdict", "value": "begin_failed"}) return out @@ -2894,7 +2891,7 @@ func _run_battle(L: int, D: int, axes: Dictionary = {}) -> Dictionary: out.result = "timeout" out.terminated = out.result == "victory" or out.result == "defeat" if out.terminated: - # P0-3 回归断言(2026-10-02 修复批):notify_combat_end 曾被并进行尾注释从不执行—— + # P0-3 回归断言:notify_combat_end 曾被并进行尾注释从不执行—— # 战斗收束后相位必须回 Idle(RAP 清零),任何「相位卡 Waiting」回归在此被抓 check(action_economy.phase == "Idle", "战斗收束后行动经济相位回 Idle(notify_combat_end 生效,实测=%s)" % String(action_economy.phase)) @@ -2922,11 +2919,11 @@ func _auto_play_round(settlement, out: Dictionary) -> void: -# ---- 地图战斗资源·伤害量值区间批冒烟(2026-09-14:身份批 roll 域内 + 中点锚 + 变异实际流动 + 定值行不受扰)---- +# ---- 地图战斗资源·伤害量值区间冒烟(roll 域内 + 中点锚 + 变异实际流动 + 定值行不受扰)---- func _smoke_power_interval() -> void: print("--- 地图战斗资源·伤害量值区间(上阶/下阶随机)---") - # ① 表侧静态锚(配置推导——2026-09-23 重构,改表不再断锚):凡带 power_min/power_max 的行 = 区间行, + # ① 表侧静态锚(配置推导——改表不断锚):凡带 power_min/power_max 的行 = 区间行, # 校验配对齐全(lo ≤ hi)+ power = floor 中点(行动经济 条款①期望当量锚);其余行必须零区间字段。 # 行清单与区间值全部随表走——现行区间行 heal_minor/clear_blast 只是恰然,不再是锚。 var interval_rows := {} # rid → [lo, hi](读表) @@ -2978,7 +2975,7 @@ func _smoke_power_interval() -> void: check(in_domain, "24 板全区间行快照 power ∈ [power_min, power_max](含清图槽)") check(fixed_ok, "定值行快照 power 恒等表值——区间批零外溢") # 定值行(区间 lo==hi 的行,如 heal_minor)roll 恒等表值;区间行(lo int: -# ---- 行动经济·轮内刷新冒烟(2026-09-12 方案 A 用户拍板:Active 相位当场换图继续挖)---- +# ---- 行动经济·轮内刷新冒烟(方案 A:Active 相位当场换图继续挖)---- func _smoke_active_refresh() -> void: print("--- 行动经济·轮内刷新(方案 A)---") @@ -3019,14 +3016,14 @@ func _smoke_active_refresh() -> void: settlement.step_row.connect(func(row): if row.source_class == "safe_cell": ct["safe_rows"] += 1 # 结算流中 safe_cell 来源行(含兑付/未生效——每格必有行) - # 结算中(Waiting 相位——段内)发起刷新必须被拒(等待期换图通道 2026-09-15 整体移除的回归探针: + # 结算中(Waiting 相位——段内)发起刷新必须被拒(等待期换图通道回归探针: # 衰减行恒在每结算出现,借其在段内同步探测一次) if String(row.get("type", "")) == "decay" and not bool(ct["waiting_probe_hit"]): ct["waiting_probe_hit"] = true ct["waiting_refresh_rejected"] = not settlement.player_request_refresh()) check(settlement.begin_battle({"level_index": 1, "node_depth": 4, "hero_hp": int(_db.hero.max_hp)}), "轮内刷新战斗启动(Boss 行 150HP——承载多轮样本)") var minesweeper = settlement.minesweeper - # 轮 1–3:零挖掘停手攒 RAP = 3×AP(每轮全转存;表驱动——2026-09-16 AP 压速批 8→6 不再写死) + # 轮 1–3:零挖掘停手攒 RAP = 3×AP(每轮全转存;表驱动——AP 从表读不写死) for i in range(3): minesweeper.settle_batch([{"action": "stop"}]) var rap_banked: int = 3 * int(_db.action_economy.ap_per_round) @@ -3057,7 +3054,7 @@ func _smoke_active_refresh() -> void: minesweeper.settle_batch([{"action": "dig", "cell": plan3.dig_cell}]) var ok3: bool = settlement.player_request_refresh() check(not ok3, "第 3 次刷新被拒(每轮兜底上限 2——RAP %d 足额仍拒)" % settlement.action_economy.rap) - # V5(迭代 27 T3——刷新双账收口):受理计数单源=结算快照 economy.refresh_used,与 can_refresh 门一致 + # V5(刷新双账收口):受理计数单源=结算快照 economy.refresh_used,与 can_refresh 门一致 check(int(settlement.presentation_snapshot().get("refresh_used", -1)) == 2, "V5 快照刷新计数=2(受理单源——main 副本已删)〔迭代27 T3〕") check(not settlement.can_refresh(), "V5 上限达门禁一致(can_refresh 与快照计数同源)〔迭代27 T3〕") @@ -3132,7 +3129,7 @@ func _smoke_difficulty_table() -> void: _db.difficulty.rows.clear() # 还原空表(后续冒烟/关卡断言基线) -# ---- 攻击类型 × 护甲克制 + 标错惩罚冒烟(2026-09-12 克制批:护甲快照/克制矩阵/充能/反噬三选一)---- +# ---- 攻击类型 × 护甲克制 + 标错惩罚冒烟(护甲快照/克制矩阵/充能/反噬三选一)---- func _smoke_damage_types() -> void: print("--- 攻击类型 × 护甲克制 + 标错惩罚 ---") @@ -3143,12 +3140,12 @@ func _smoke_damage_types() -> void: check(enemy_system_b.spawn(1, 2, int(_db.hero.max_hp)) and String(enemy_system_b.all_enemies()[0].armor_type) == "light", "bugbear 护甲 = light(护甲类型重配批 2026-09-18:关卡 1 全轻甲)") var enemy_system_c = load("res://core/unit_container.gd").new(_db) check(enemy_system_c.spawn(1, 4, int(_db.hero.max_hp)) and String(enemy_system_c.all_enemies()[0].armor_type) == "light", "ogre_chief 护甲 = light(护甲类型重配批 2026-09-18:关卡 1 全轻甲)") - # ② 克制矩阵表值在位(2026-09-18 加法核换装:三档点数 克制 +1 / 中性 0 / 被克 −1——percent 量纲退役) + # ② 克制矩阵表值在位(三档点数 克制 +1 / 中性 0 / 被克 −1,加法核非 percent) var am: Dictionary = _db.settlement.armor_effectiveness check(int(am.normal.light) == 0 and int(am.normal.ward) == 1 and int(am.normal.heavy) == -1, "普通行:轻甲 0 / 魔法护甲 +1 / 重甲 −1(加法核)") check(int(am.pierce.light) == -1 and int(am.pierce.ward) == 1 and int(am.pierce.heavy) == 0, "穿刺行:轻甲 −1 / 魔法护甲 +1 / 重甲 0 中性(用户拍板)") check(int(am.magic.light) == 0 and int(am.magic.ward) == -1 and int(am.magic.heavy) == 1, "魔法行:轻甲 0 / 魔法护甲 −1 / 重甲 +1(加法核)") - # ③ 标错(类型化负向兑付)+ 标中正向兑付(2026-09-19 充能退役后封印命中只兑格面资源正向;Boss 行多轮样本;板真相直读保证 hit/miss 确定性) + # ③ 标错(类型化负向兑付)+ 标中正向兑付(封印命中只兑格面资源正向;Boss 行多轮样本;板真相直读保证 hit/miss 确定性) var run1 = _run_seal_backlash_round(20260912) var miss_rows := 0 var negative_rows := 0 @@ -3159,7 +3156,7 @@ func _smoke_damage_types() -> void: if String(row.get("source_class", "")) == "seal_miss" and String(row.get("type", "")) in ["effect", "damage"]: negative_rows += 1 # 标错的负向兑付行(该安全格资源的负向字典行——effect/直伤) if String(row.get("source_class", "")) == "seal_hit": - hit_rows += 1 # 标中的正向兑付行(该危险格资源的正向字典行——2026-09-19 充能退役后标中只走格面资源正向) + hit_rows += 1 # 标中的正向兑付行(该危险格资源的正向字典行——标中只走格面资源正向) check(miss_rows >= 1, "标错封印产生 seal_miss 归因行(×%d)" % miss_rows) check(negative_rows >= 1, "标错封印兑付该安全格资源的负向字典行(×%d——attack/defense/weaken 效果行或 heal 直伤行)" % negative_rows) check(hit_rows >= 1, "封印命中兑付该危险格资源的正向字典行(×%d——充能退役后无魔法分量,正向=格面资源)" % hit_rows) @@ -3215,16 +3212,16 @@ func _find_seal_target(minesweeper, want_mine: bool) -> Dictionary: return {} -# ---- 封印不可逆四情况冒烟(2026-09-19 用户拍板全套落地:禁撤封印 + 挖封印格兑付改判)---- +# ---- 封印不可逆四情况冒烟(禁撤封印 + 挖封印格兑付改判)---- # 四情况:① 插危险格不动 = 标中奖励照常;② 插危险格再挖开 = 只受挖雷一层惩罚(mine_hit 照常)标中不发; # ③ 插安全格不动 = 标空惩罚照常;④ 插安全格再挖开 = 零惩罚零奖励(正向兑付作废、标空不判)。 -# 退役面:seal_pull 出目录(out_of_catalog);重复封印仍 seal_present 拒绝。 -# 场景 A(④ + 退役面):标安全格 → seal_pull 拒绝 → 重复封印拒绝 → 直接挖开 → 收轮。 +# 拒绝面:seal_pull 出目录(out_of_catalog);重复封印仍 seal_present 拒绝。 +# 场景 A(④ + 拒绝面):标安全格 → seal_pull 拒绝 → 重复封印拒绝 → 直接挖开 → 收轮。 # 场景 B(②):标危险格 → 直接挖开 → 收轮。 # 场景 C(①③):标安全格 + 标危险格 → 不挖收轮 → 标空/标中判定照常。 func _smoke_seal_irreversible_quadrants() -> void: print("--- 封印不可逆四情况(禁撤封印 + 挖封印格兑付改判)---") - # 场景 A:安全格直挖(情况④)+ seal_pull/重复封印退役面 + # 场景 A:安全格直挖(情况④)+ seal_pull/重复封印拒绝面 var rng_a = load("res://core/rng_service.gd").new() rng_a.set_master_seed(20260919) var settle_a = load("res://core/battle_orchestrator.gd").new(_db, rng_a) @@ -3388,7 +3385,7 @@ func _smoke_encounter_roll() -> void: counts.append(settlement.presentation_snapshot().enemies.size()) # 区间生效:20 个种子应出现 1 和 2(D0 [1,2]) check(counts.has(1) and counts.has(2), "D0 区间 [1,2] 两值均出现(分布 %s)" % str(counts)) - # 域内断言带标签(原恒真 check(true) 已废——断言必须能抓住失效,code-review 2026-09-12) + # 域内断言带标签(断言必须能抓住失效,禁恒真 check(true)) var all_in_domain := true for c in counts: if c < 1 or c > 2: @@ -3436,7 +3433,7 @@ func _smoke_encounter_roll() -> void: check(scan_bad == 0, "全深度 × 12 种子 spawn 全域内(%d 场,∈[unit_count, unit_count_max] 且 ≥1)——空遭遇不可达(Bug#1 回归)" % scan_total) -# 模板感知取节点表(M-3 迭代 5 T5——row.templates 非空取模板 0=现行固定图,保持既有断言语义) +# 模板感知取节点表(row.templates 非空取模板 0=现行固定图,保持既有断言语义) func _level_active_nodes(level_index: int) -> Array: for row in _db.level.rows: if int(row.level_index) == level_index: @@ -3459,8 +3456,8 @@ func _level_battle_nodes(level_index: int) -> Array: # ---- 战斗段 fresh 池攻击链回归(playtest-2026-09-12 报告 Bug#2 沉淀—— -# 「Boss 攻击拍零兑现」实为旧 defense_up 数据 ×2 叠满 = 池触底 ×0(设计语义);本断言钉死: -# 池为空时攻击链必须按掷点档位足额兑现——2026-09-16 护甲等级掷点批改口径: +# 「Boss 攻击拍零兑现」= 叠满触底 ×0;本断言钉死: +# 池为空时攻击链必须按掷点档位足额兑现,口径: # d_tick = max(damage_floor, pool_damage(floor(基线×档位%), 0, 0)),档位读数随行重建可归因)---- func _smoke_attack_chain_fresh_pool() -> void: @@ -3499,7 +3496,7 @@ func _encounter_replay(seed_val: int) -> Array: return out -# ==================== 清图奖励双份兑付链 / 轮内刷新 provenance 守卫 / 窗口锚行(2026-09-15 补覆盖批) ==================== +# ==================== 清图奖励双份兑付链 / 轮内刷新 provenance 守卫 / 窗口锚行 ==================== # 清图 = 全安全格开完。清图测试用"真雷封印(零误标→完美排雷)+ AutoPlayer 逐轮清图"真实流驱动; # DifficultyTable 注入 hp_mult=10 把 Boss 血量抬到 1500,保证清图批次发生在战斗结束之前(测试台账,跑完即还原)。 @@ -3611,15 +3608,15 @@ func _smoke_refresh_provenance_guard() -> void: # ==================== 格面资源批新增覆盖(极性路由 / 负向字典 / 资源面 / 五段全序) ==================== # 极性路由断言(战斗结算 验收):挖安全格/封印命中只出正向、挖危险格/标错封印只出负向、兑付行指回来源格。 -# 正向字典效果集 = {attack_up, ac_up, weaken}(ac_up = 2026-09-16 护甲等级掷点批换装,原 defense_up) -# + spark_aoe/heal_minor(flat)+ gp_gain(九型批 2026-09-20——GP 袋,escrow 缓冲路由键非增益容器行); -# 负向字典效果集 = {enrage, off_guard, sapped}(percent)+ 直伤(heal flat)/ alert 警觉(blast percent——2026-09-20 换装) -# + gp_loss(九型批——破财,escrow 缓冲路由键)。 +# 正向字典效果集 = {attack_up, ac_up, weaken} +# + spark_aoe/heal_minor(flat)+ gp_gain(GP 袋,escrow 缓冲路由键非增益容器行); +# 负向字典效果集 = {enrage, off_guard, sapped}(percent)+ 直伤(heal flat)/ alert 警觉(blast percent) +# + gp_loss(破财,escrow 缓冲路由键)。 const POSITIVE_EFFECTS := ["attack_up", "ac_up", "weaken", "gp_gain"] const NEGATIVE_EFFECTS := ["enrage", "off_guard", "sapped", "alert", "gp_loss"] -# 构造验收谓词(hunt 用——并流批后种子按行为面扫描:四触达 + 标空封印负向兑付行在案) +# 构造验收谓词(hunt 用——种子按行为面扫描:四触达 + 标空封印负向兑付行在案) func _polarity_probe_accepts(probe: Dictionary) -> bool: if not (bool(probe["seal_hit_done"]) and bool(probe["seal_miss_done"])): return false @@ -3639,7 +3636,7 @@ func _polarity_probe_accepts(probe: Dictionary) -> bool: func _smoke_polarity_routing() -> void: print("--- 极性路由(挖安全格正向 / 挖危险格负向 / 标中正向 / 标空负向)---") - # 并流批(2026-09-27 统一流裁决)后战斗随机值面漂移——构造种子改行为面扫描(谓词见 _polarity_probe_accepts) + # 战斗随机值面随全局序漂移——构造种子按行为面扫描(谓词见 _polarity_probe_accepts) var probe := {} var polarity_seed := -1 for s in [20260918, 20260919, 20260920, 20260921, 42, 4242, 7, 100, 20260922, 123, 2024, 31337, 555, 1111, 2222, 20260923, 999, 777]: @@ -3694,7 +3691,7 @@ func _smoke_polarity_routing() -> void: if eff != "" and not POSITIVE_EFFECTS.has(eff): hit_ok = false check(hit_ok, "封印命中 → 该危险格资源的正向兑付行(origin 指回危险格,效果 ∈ 正向字典)") - # 条款3 条件二封印溢价断言(迭代14② T4——标中兑付行数值 = 同型正向 ×(1+δ)): + # 条款3 条件二封印溢价断言(标中兑付行数值 = 同型正向 ×(1+δ)): # δ 读 settlement.seal_hit_premium(125 provisional);九型正向行值全固定(唯一区间行 clear_blast # 系清图槽不入格池)⇒ 逐型期望全确定。整数量级四舍五入域注记:ac_up/action 1 点量纲取整后不变 # =整数粒度地板——等号压线判读在当量聚合面(audit 工具/registry clause3_inequality),非断言面。 @@ -3811,7 +3808,7 @@ func _rows_at(rows: Array, source_class: String, cell) -> Array: # 断言每型的兑付形态(enrage/off_guard/sapped 效果行、heal 直伤行、blast 警觉行、action 行动点排队)。 func _smoke_negative_dictionary() -> void: print("--- 负向字典逐型直验(sapped 在位 / heal 直伤 / blast 警觉 / action 行动点)---") - # 数据面:sapped 行在位(状态表七行 + effect_pool_map 收编) + # 数据面:sapped 行在位(状态表七行 + effect_pool_map 映射在位) var sapped: Dictionary = _db.status_effect_row("sapped") check(not sapped.is_empty() and String(sapped.get("target_side", "")) == "hero" \ and int(sapped.get("magnitude", 0)) == -25 and int(sapped.get("duration_settlements", 0)) == 1 \ @@ -3820,15 +3817,15 @@ func _smoke_negative_dictionary() -> void: check(String(_db.settlement.effect_pool_map.get("sapped", "")) == "hero_offense", "effect_pool_map 收编 sapped → hero_offense(attack_up 镜像池)") # 行为面:逐型负向兑付形态(真实板 + 真实路由路径) - # 数值压缩批(2026-09-17):heal 权重 15→3 后单板五型齐备不再必然(无 heal 板概率 ≈1/3)—— - # 改多板扫描,取第一块五型齐备的板做行为断言。 + # heal 权重低(无 heal 板概率 ≈1/3)——单板五型齐备不再必然: + # 本断言多板扫描,取第一块五型齐备的板做行为断言。 var settlement = null var board = null var by_type := {} # cell_type → 首个非封锁格(query_identity 雷安同池——危险格可查) var rows: Array = [] for seed_i in range(6): - # 每板独立 rng 实例(迭代 7 T1 修正——复用实例重播种触发 set_master_seed 的 _counter==0 守卫; - # 原版第一板即 break 掩盖了该违例,aux 供给挤占后多板扫描暴露) + # 每板独立 rng 实例(复用实例重播种触发 set_master_seed 的 _counter==0 守卫; + # 单板 break 会掩盖该违例,多板扫描才暴露) var rng = load("res://core/rng_service.gd").new() rng.set_master_seed(20260919 + seed_i) settlement = load("res://core/battle_orchestrator.gd").new(_db, rng) @@ -3847,16 +3844,16 @@ func _smoke_negative_dictionary() -> void: if r0.has(c) or by_type.size() == 5: continue var ident = settlement.query_reward_identity(c) - # aux 身份不入五型轴(秘宝内容批 2026-09-29——五型齐备=格面资源历史断言轴, + # aux 身份不入五型轴(五型齐备=格面资源断言轴, # aux 供给挤占不改变本断言语义;扫描排除 aux 身份格) if ident != null and String(ident.cell_type) != RewardTable.TREASURE_ITEM_TYPE and not by_type.has(String(ident.cell_type)): by_type[String(ident.cell_type)] = c - # break 条件=percent_map 三型齐备(迭代 7 T1——aux 供给挤占下 weaken/defense 收集时机漂移, + # break 条件=percent_map 三型齐备(aux 供给挤占下 weaken/defense 收集时机漂移, # 直验可达性优先;五型多样性 check 保留不动) if by_type.has("attack") and by_type.has("defense") and by_type.has("weaken"): break check(by_type.size() == 5, "扫描 6 板内出现五型齐备板(%s)" % str(by_type.keys())) - # attack/defense/weaken:负向字典行走 apply_effect(off_guard 2026-09-18 换装 ac 轴——兑付形态不变) + # attack/defense/weaken:负向字典行走 apply_effect(off_guard 走 ac 轴——兑付形态不变) var percent_map := {"attack": "enrage", "defense": "off_guard", "weaken": "sapped"} for ctype in percent_map.keys(): if not by_type.has(ctype): @@ -3867,7 +3864,7 @@ func _smoke_negative_dictionary() -> void: var eff: String = percent_map[ctype] check(_has_source_row(rows, "effect", "mine_hit") and _has_effect_id(rows, eff), "%s 型负向 → %s 效果行(mine_hit 来源指回该格)" % [ctype, eff]) - # heal:负向 = 主角直伤(表值——数值压缩批 4→1;不经增益状态) + # heal:负向 = 主角直伤(表值;不经增益状态) if by_type.has("heal"): rows.clear() var hp_before: int = int(settlement.presentation_snapshot().hero.hp) @@ -3879,7 +3876,7 @@ func _smoke_negative_dictionary() -> void: if String(row.get("reward_id", "")) == "heal_backlash": backlash_power = int(row.power) check(hp_after == hp_before - backlash_power, "heal 型负向 → 主角直伤 %d(%d → %d,不经增益状态)" % [backlash_power, hp_before, hp_after]) - # blast:负向 = 警觉(敌方护甲等级 +1 percent 行——2026-09-20 伏击退役换装) + # blast:负向 = 警觉(敌方护甲等级 +1 percent 行) if by_type.has("blast"): rows.clear() var snap_b: Dictionary = settlement._reward_economy.query_full_snapshot(by_type["blast"]) @@ -3889,7 +3886,7 @@ func _smoke_negative_dictionary() -> void: if String(eff_a.effect_id) == "alert": alert_ok = true check(alert_ok, "blast 型负向 → 警觉(敌方护甲等级 +1 状态在位)") - # action:负向 = 下轮行动点 −1 / 正向 = +1(排队,轮开始兑现——八型批 2026-09-20;确定性直验不依赖板面摇号) + # action:负向 = 下轮行动点 −1 / 正向 = +1(排队,轮开始兑现;确定性直验不依赖板面摇号) rows.clear() var d0: int = settlement.action_economy.pending_ap_delta() settlement._grant_routed({"reward_id": "ap_drain", "cell_type": "action", "polarity": "negative", "display_name": "迟滞", "power": 1}, "negative", "mine_hit", Vector2i(0, 0), 1) @@ -3986,7 +3983,7 @@ func _smoke_settlement_segments() -> void: if decays != 1 or verdicts != 1: decay_verdict_ok = false # 衰减/判定每结算恰一次 check(order_ok, "每轮行相位单调(授予→增益/减益→战斗→衰减→判定)") - # 案C 段内序(2026-10-06 用户裁):段内伤害序 = 主角先手 →〔连珠矢随先手段〕→ 敌方逐个 → 地图账殿后。 + # 案C 段内序:段内伤害序 = 主角先手 →〔连珠矢随先手段〕→ 敌方逐个 → 地图账殿后。 # 地图账 = 全部棋盘来源伤害行 + 主角倒下不兑留痕行;违序(先于先手或插进敌方还手中间)即失败。 var mapdmg_ok := true for ri_key in by_round.keys(): @@ -4025,7 +4022,7 @@ func _row_phase(row: Dictionary, ri: int) -> int: "cast": return 2 "damage": - return 2 # 案C(2026-10-06 用户裁):全部伤害兑付=战斗段(主角先手/敌方还手/地图账殿后统一结账) + return 2 # 案C:全部伤害兑付=战斗段(主角先手/敌方还手/地图账殿后统一结账) "reward_ineffective": return 2 if String(row.get("forfeit", "")) == "hero_down" else 0 # 战斗段末地图账不兑留痕 vs 授予段未生效 match String(row.get("source_class", "")): @@ -4108,13 +4105,13 @@ func _has_effect_id(rows: Array, effect_id: String) -> bool: return false -# 手搓战斗状态袋单点(T6 收口批——7 处字面量收编;_autoplay_battle 直接消费的最小字段族。 +# 手搓战斗状态袋单点(7 处字面量收在一处;_autoplay_battle 直接消费的最小字段族。 # 大字段族同构袋仍走 _adv_st()——_drive_level/_autoplay_battle 全字段消费面) func _battle_st(policy: String) -> Dictionary: return {"result": "", "rounds": 0, "refreshes": 0, "mine_hits": 0, "hero_dmg": 0, "policy": policy} -# ==================== 敌人技能池批(2026-09-16 用户拍板——开轮摇号出招系统) ==================== +# ==================== 敌人技能池(开轮摇号出招系统) ==================== # 六项验收断言(proposal-skill-pool.md〔提案已吸收退役 git a6833b6a——现行事实源=敌人系统.md 技能池节〕 §8 批 1):同种子回放逐位复现 / 单敌轨迹独立复放 / # EV 抽样对锚 / 死亡打断作废 / 空池不可能 / 加载校验拒绝。 @@ -4154,7 +4151,7 @@ func _smoke_skill_pool_data() -> void: if String(entry.skill_id) == "venom_burst" and String(row.enemy_id) != "drider": venom_sole_ok = false check(venom_sole_ok, "毒爆独占性(仅蛛化卓尔精灵池引用——Boss 专属池独占技纪律)") - # 新效应词汇批(2026-09-19):妨害技首发行 + off_guard 落点 + 实装面收窄 + # 妨害技首发行 + off_guard 落点 + 实装面收窄 var snare: Dictionary = _db.skill.row_by_id("web_snare") check(not snare.is_empty() and String(snare.type) == "debuff" and String(snare.buff_ref) == "off_guard" and int(snare.buff_duration) == 2 and int(snare.cooldown_beats) == 4, @@ -4168,7 +4165,7 @@ func _smoke_skill_pool_data() -> void: var off_guard_row: Dictionary = _db.status_effect_row("off_guard") check(not off_guard_row.is_empty() and String(off_guard_row.target_side) == "hero" and String(off_guard_row.unit) == "ac", "失衡状态行(hero · ac 轴——妨害技落点,ConfigDB side 守卫正例)") - # 迭代 24 N2(2026-10-13):普通敌错峰两新行——毒吐/盾击(V3) + # 普通敌错峰两新行——毒吐/盾击(V3) var spit: Dictionary = _db.skill.row_by_id("venom_spit") check(not spit.is_empty() and String(spit.display_name) == "毒吐" and String(spit.type) == "damage" \ and is_equal_approx(float(spit.damage_mult), 1.6) and int(spit.cooldown_beats) == 2 and not spit.has("rider_mult"), @@ -4189,7 +4186,7 @@ func _smoke_skill_pool_data() -> void: check(spit_sole_ok, "毒吐投放面(仅 (2,5)/(2,6)/(2,7) 巨蜘蛛族——首遇位 (2,4) 池不动,迭代 24 N2/Q6)") check(bash_sole_ok, "盾击投放面(仅 (3,0)/(3,5)/(3,7) 灰矮人族——钩爪恐魔零触碰,迭代 24 N2)") # 行集键 = (level_index, node_depth, enemy_id)——分支节点图批起 bugbear 等敌种跨关异池,enemy_id 不再唯一; - # 2026-10-07 行集多行批:同坐标混编多行后每行各一池,键升维到三元组(行序 = 文件序 = 契约序) + # 同坐标混编多行时每行各一池,键升维到三元组(行序 = 文件序 = 契约序) var expect_pools := { "1_0_goblin": {"attack": 9, "lunge": 1}, "1_1_goblin": {"attack": 9, "lunge": 1}, @@ -4234,7 +4231,7 @@ func _smoke_skill_pool_data() -> void: if n != 1: basic_count_ok = false check(basic_count_ok, "每池恰一行普攻(空池不可能的加载校验同款)") - # 迭代 24 N2 复查(V4):池构成纪律零违反——增益 ≤1 / 妨害 ≤1(敌人系统 v0.13 结构冻结;载入期 + # 池构成纪律复查(V4):零违反——增益 ≤1 / 妨害 ≤1(敌人系统 v0.13 结构冻结;载入期 # validate_skill_pool_links 已硬闸,此处冒烟侧显式复核新投放后仍绿) var comp_ok := true for row in _db.enemy.rows: @@ -4251,7 +4248,7 @@ func _smoke_skill_pool_data() -> void: if n_buff > 1 or n_debuff > 1: comp_ok = false check(comp_ok, "逐池增益 ≤1 · 妨害 ≤1(池构成纪律——迭代 24 N2 毒吐/盾击投放后复查)") - # Boss 半血解锁技·编排集成断言(迭代14④ T6——真实编排回路:半血 → 下轮开轮闩检查 → 解锁行恰一次) + # Boss 半血解锁技·编排集成断言(真实编排回路:半血 → 下轮开轮闩检查 → 解锁行恰一次) var st_unlock: Dictionary = {"rows": []} var sett_u = load("res://core/battle_orchestrator.gd").new(_db, _fresh_rng(4242)) sett_u.step_row.connect(func(row): st_unlock["rows"].append(row)) @@ -4283,7 +4280,7 @@ func _smoke_skill_pool_data() -> void: if es2.rollable_skills(u).is_empty(): rollable_ok = false check(rollable_ok, "全深度实例 spawn 后可摇集合恒非空(普攻恒冷却 0——容器级断言,L1/L2 双关卡)") - # 状态表新行 + 敌方防御池收编 + # 状态表新行 + 敌方防御池映射 var empower: Dictionary = _db.status_effect_row("empower") var fortify: Dictionary = _db.status_effect_row("fortify") check(not empower.is_empty() and String(empower.target_side) == "enemy" and int(empower.magnitude) == 100, @@ -4295,9 +4292,9 @@ func _smoke_skill_pool_data() -> void: "effect_pool_map 收编 empower/fortify(敌方防御池 enemy_defense 入表)") -# ② 同种子回放逐位复现(D3 大地精——原熊地精双雄,多实例同种) -# ③「单敌轨迹独立复放」随并流批退役(2026-09-27 统一流裁决):子流派生向量退役后单敌轨迹无法 -# 脱离全序重建(位置与其它流取数交错);同种子全战斗逐位复现由 ② 全对拍承载,单点定位归事件日志。 +# ② 同种子回放逐位复现(D3 大地精,多实例同种) +# 单敌轨迹不独立复放——轨迹取数与其它流交错,无法脱离全序重建; +# 同种子全战斗逐位复现由 ② 全对拍承载,单点定位归事件日志。 func _smoke_skill_pool_replay_independence() -> void: var seed_val := -1 for s in range(1, 60): @@ -4306,8 +4303,8 @@ func _smoke_skill_pool_replay_independence() -> void: seed_val = s break check(seed_val > 0, "多实例种子可达(seed=%d——D3 遭遇 ≥2 实例)" % seed_val) - # 数值压缩批(2026-09-17):敌 hp 18→6 后 hero_atk=1 十轮内必然击杀(实例错位、轨迹断裂)—— - # 观测窗 10 轮→5 轮(5 拍 ×1 伤 < 6 HP 全员存活;仍覆盖保底 M=4 的触发窗)。 + # 敌 hp 低(表值 6)时 hero_atk=1 十轮内必然击杀(实例错位、轨迹断裂)—— + # 观测窗取 5 轮(5 拍 ×1 伤 < 6 HP 全员存活;仍覆盖保底 M=4 的触发窗)。 var rounds := 5 var run1 := _record_pool_trajectories(seed_val, rounds) var run2 := _record_pool_trajectories(seed_val, rounds) @@ -4339,7 +4336,7 @@ func _record_pool_trajectories(seed_val: int, rounds: int) -> Dictionary: # 带宽口径:熊地精/酋长 EV 结构性恒 1(普攻 1 + 重击 2 与蓄力/硬化 0 加权守恒)→ 窄带; # 地精突刺池受保底闸抬升(唯一特殊技 w=1/10,保底 M=4 把突刺率从自然 10% 抬到 ~20%+)→ 宽带登记。 func _smoke_skill_pool_ev_anchor() -> void: - var bands := {"goblin": [1.00, 1.20], "bugbear": [0.97, 1.03], "ogre_chief": [1.10, 1.30]} # 酋长重锚〔迭代14④ T5——震地怒击半血解锁入池,含闸长期速率上移:实测 1.1948;EV 锚批注 enemy.tres 同批换代〕 + var bands := {"goblin": [1.00, 1.20], "bugbear": [0.97, 1.03], "ogre_chief": [1.10, 1.30]} # 酋长重锚(震地怒击半血解锁入池,含闸长期速率上移:实测 1.1948;EV 锚注 enemy.tres) var species := ["goblin", "bugbear", "ogre_chief"] var rng = load("res://core/rng_service.gd").new() rng.set_master_seed(20260921) @@ -4454,7 +4451,7 @@ func _smoke_skill_pool_validation_reject() -> void: check(not et2.validate().is_empty(), "加载校验拒绝:池权重 ≤ 0") et2.rows.assign([{"enemy_id": "x", "display_name": "x", "pool": []}]) check(not et2.validate().is_empty(), "加载校验拒绝:空池(禁)") - # 新效应词汇批(2026-09-19):妨害 / 必中附加分量校验组 + # 妨害 / 必中附加分量校验组 skill_table.rows.assign([ {"skill_id": "w1", "display_name": "w1", "type": "debuff", "buff_ref": "off_guard", "buff_duration": 2, "cooldown_beats": 4}, {"skill_id": "w2", "display_name": "w2", "type": "debuff", "buff_ref": "off_guard", "buff_duration": 2, "cooldown_beats": 4}]) @@ -4483,10 +4480,9 @@ func _has_err_category(errs: Array, category: String) -> bool: return false -# ⑦ 新效应词汇批实装探针(2026-09-19——妨害技蛛网束缚 + 毒爆必中附加分量,实装面 = L2 Boss 卓尔): +# ⑦ 实装探针(妨害技蛛网束缚 + 毒爆必中附加分量,实装面 = L2 Boss 卓尔): # 停手轮驱动 (2,9)——零挖掘零封印 → 零池,伤害行可逐拍精确复算;种子 hunt 至少各命一粒毒爆伤害行 # 与蛛网束缚施放行;毒分量随开战掷定的攻击基线缩放(atk 区间 2–4 → rider 1–3)。 -# (2026-09-21 商店房批连带:Boss 重编号 8→9——(2,8) 现为商店房无战斗行,驱动点随行迁移。) func _smoke_debuff_rider() -> void: var venom_seed := -1 var venom_check_ok := true @@ -4552,7 +4548,7 @@ func _smoke_debuff_rider() -> void: check(snare_seed > 0, "蛛网束缚落主角:施放后掷点阈值 = 基准 AC + 失衡幅度(off_guard ac 轴端到端,seed=%d)" % snare_seed) -# ---- 分支节点图批冒烟:图合法性校验 + L2 幽暗地域图版行进(2026-09-17——关卡节点地图 v1.0 图版落地)---- +# ---- 分支节点图冒烟:图合法性校验 + L2 幽暗地域图版行进(关卡节点地图 v1.0 图版)---- func _smoke_level_graph() -> void: print("--- 关卡节点地图·分支节点图(L2 幽暗地域)---") @@ -4609,7 +4605,7 @@ func _smoke_level_graph() -> void: var orphan_errs: Array = lt.validate() check(_has_err_category(orphan_errs, "structural"), "图校验拒绝:孤儿节点(从入口不可达 / 双入口同体违例)") # ④ L2 选路推进:min / max 双路径全通(确定性路径轴——零随机流自开) - # 并流批(2026-09-27 统一流裁决)后战斗随机值面漂移——max 路径种子改行为面扫描(路线形状/商店/选路口为断言本体) + # 战斗随机值面随全局序漂移——max 路径种子按行为面扫描(路线形状/商店/选路口为断言本体) var win_min = autoplay.run_level(_db, 42, 2, 200, 100, false, null, "normal", "min", 0) check(win_min.result == "victory", "L2·满配 min 路径通关(实测:%s)" % win_min.result) check(win_min.boss_depth == 9, "L2 Boss 以编号 9 解析(终点编号最大——商店房批重编号 8→9)") @@ -4617,10 +4613,10 @@ func _smoke_level_graph() -> void: check(win_min.choices >= 3, "选路口发生 %d 次(每节点兑付后——零自动推进)" % win_min.choices) # max 路径 = 存储种子(T17 改造——废除逐种子扫描):本项目核心承诺=确定性复放(同代码同表 # 同种子逐位一致),「能赢且路径符合的种子」是恒定事实,采一次存死即可。旧形态 range(42,300) - # 逐种子全关卡通关扫描找命中,期望路径过期时 258 次模拟撞 180s 闸(台账 257 + 2026-10-02 + # 逐种子全关卡通关扫描找命中,期望路径过期时 258 次模拟撞 180s 闸(台账 257 + # 出度≤2 重建两次实证)。存储种子常态一次跑完;图表/数值有意变更致本断言红=快速失败(一次 # 即红非扫描超时),重采=临时脚本跑同款 run_level 循环取首命中种子回填(离线一次性)。 - const MAX_PATH_SEED := 43 # 2026-10-05 判式换代批重采(封印溢价 δ=1.25 落地致种子 42 战局位移=败于终点;同款循环首命中——断言注释既定程序,临时脚本用后即删) + const MAX_PATH_SEED := 43 # 种子重采程序:同款循环首命中(断言注释既定程序,临时脚本用后即删) var win_max: Dictionary = autoplay.run_level(_db, MAX_PATH_SEED, 2, 200, 100, false, null, "normal", "max", 0) check(win_max.result == "victory" and win_max.visited_ids == [0, 2, 6, 7, 8, 9], "L2·满配 max 路径(max 取最大编号候选)通关 = 0→2(奖励)→6→7→8(商店零购离开)→9(存储种子 %d——T17 出度≤2 拍板模板 0 重建)" % MAX_PATH_SEED) @@ -4647,8 +4643,7 @@ func _smoke_level_graph() -> void: "兑付确认后才出现选路口(continue_after_node 泛化语义)候选 = [5, 6]") check(runner.pick_next_node(6) and runner.current_battle() != null, "选编号 6(巨蜘蛛巢群)开战") # ⑥ L2 锚行首遇战:基线 0 加成 · 完美档(零盲挖 = 零踩雷上限口径)多种子扫描 - # (Package B 第 7 轮阶段拔高后锚行 45→50 退出绿档——13/12 全胜改多数胜 + 零踩雷恒要求, - # 2026-09-23 拍板 B 接受现曲线;还原绿档需回调锚行血量,归用户决策) + # (绿档口径 = 12 局多数胜 + 零踩雷恒要求;还原全胜档需回调锚行血量,归用户决策) var green_ok := true var green_min_hp := 99999 var green_wins := 0 @@ -4675,7 +4670,7 @@ func _smoke_level_graph() -> void: check(green_wins >= 7, "首遇战胜局 ≥7/12(实际 %d——阶段拔高后锚行退出绿档,多数胜口径)" % green_wins) check(green_min_hp > 0, "首遇战胜后 HP 下探读数 %d(>0——绿档记录)" % green_min_hp) # ⑦ 跨表行完整:L2 每战斗/Boss 节点 (2, 编号) 在 board_gen 与 enemy 精确行集(加载校验同款显式复述; - # 2026-10-07 行集多行批:「精确行」口径改「精确行集」——enemy 侧同坐标多行合法,键聚合坐标级天然兼容) + # 精确行集口径——enemy 侧同坐标多行合法,键聚合坐标级天然兼容) var bg_keys := {} for row in _db.board_gen.rows: bg_keys["%d_%d" % [int(row.level_index), int(row.node_depth)]] = true @@ -4691,7 +4686,7 @@ func _smoke_level_graph() -> void: if not bg_keys.has(key) or not en_keys.has(key): cross_ok = false check(cross_ok, "跨表行完整:L2 全部战斗/Boss 节点在 board_gen + enemy 精确行集(7 节点)") - # ⑦a 定点:L2 首遇行集与 Boss 行集(2026-10-07 行集多行批口径——断言行集构成而非单行: + # ⑦a 定点:L2 首遇行集与 Boss 行集(精确行集口径——断言行集构成而非单行: # 零内容期每坐标恰一行 = 单元素行集;行序 = 文件序,首行即叙述取数面) var l2_spider_set: Array = _db.resolve_enemy_rowset(2, 4) var l2_spider_ids := {} @@ -4705,7 +4700,7 @@ func _smoke_level_graph() -> void: l2_boss_ids[String(r.get("enemy_id", ""))] = true check(l2_boss_ids.has("drider") and l2_boss_ids.size() == 1 and String(l2_boss_set[0].get("armor_type", "")) == "ward", "蛛化卓尔精灵 Boss 行集 (2,9) = {drider} 恰一行且首行魔法甲(护甲类型重配批 2026-09-18:关卡 2 唯一非轻甲;商店房批重编号 (2,8)→(2,9);P4 乙 Boss 行集多行合法——零内容期仍单行)") - # ⑦b 定点:首批混编遭遇行集 (2,5)(2026-10-07 迭代 18 卡⑤投放——R6 行序契约运行面: + # ⑦b 定点:混编遭遇行集 (2,5)(R6 行序契约运行面: # 行集两行文件内相邻、行序 = 声明序 = 生成序;静态最坏骰和 Σ(unit_count_max,固定行缺省 = unit_count) ≤ 4) var l2_mix_set: Array = _db.resolve_enemy_rowset(2, 5) var mix_shape_ok: bool = l2_mix_set.size() == 2 \ @@ -4721,7 +4716,7 @@ func _smoke_level_graph() -> void: check(int(l2_mix_set[1].get("unit_count", 0)) == 2 and int(l2_mix_set[1].get("unit_count_max", 0)) == 3 \ and int(l2_mix_set[1].get("hp", 0)) == 26 and int(l2_mix_set[1].get("armor_class", -1)) == 2, "首批混编新行 (2,5,giant_spider) 行值 = 复制 (2,6) 巢群行(P4 甲零数值新增——2-3 只/hp 26/atk [1,2]/light/ac 2;既有 19 行现值零变更)") - # ---- 第三关内容批(2026-09-20)L3 灰矮人矿城断言段 ---- + # ---- L3 灰矮人矿城断言段 ---- # ⑧ L3 行集结构(复用 L2 九节点图模板——6 战 + Boss + 奖励 + 恢复,真实岔路 4 处) var l3 := {} for row in _db.level.rows: @@ -4785,7 +4780,7 @@ func _smoke_level_graph() -> void: check(green3_ok, "L3 首遇位绿档:成长代理档口径(atk_pct=200/hp_pct=100)完美档 12 种子首遇战(节点 0 灰矮人)全胜且零踩雷") check(green3_min_hp > 0, "L3 首遇战胜后 HP 下探读数 %d(>0——绿档记录)" % green3_min_hp) - # ⑫ 混编行集运行面正反断言(2026-10-07 行集多行批——T4 组 D 新增):注入坐标 (1,5)/(1,6) = + # ⑫ 混编行集运行面正反断言:注入坐标 (1,5)/(1,6) = # L1 节点图与全部既有扫描面之外的新深度(ceil 请求命中注入行集——新 L 会被 ceil 封顶到 L3 不可用), # 断言后立即还原表,后续断言面零污染。R3 fail-fast 正反验证 + R6 行序运行面验证。 var mix_row_a := {"level_index": 1, "node_depth": 5, "enemy_id": "goblin", "display_name": "地精", "unit_count": 1, "hp": 10, "atk": 2, "pool": [{"skill_id": "attack", "weight": 9}]} @@ -4818,7 +4813,7 @@ func _fresh_rng(seed_val: int): return rng -# ==================== GP+商店房实施批冒烟(2026-09-21——接 L3 断言段后) ==================== +# ==================== GP+商店房冒烟 ==================== # ① GP 到账(战斗完成入账恰一次 + Boss 关级加值)② escrow 隔离(格面兑付入缓冲/破财不透支) # ③ 商店三收口(购买出账/加算区/余额不足拒/离开/收束清零)④ 图不变式(商店必经位/跨表行集迁移) # ⑤ 九型与 gp_drop 流(奖励字典 18 格 + 黄金向量)。 @@ -5048,7 +5043,7 @@ func _smoke_shop_room() -> void: var gp0: int = runner.gp check(runner.buy_product("atk_up"), "购买 atk_up 受理(现价 6)") check(runner.gp == gp0 - 6, "钱包扣现价 6(%d → %d)" % [gp0, runner.gp]) - check(int(runner.run_ledger.bonus.get("atk", -1)) == 1 and int(runner.run_ledger.bonus.get("max_hp", -1)) == 0 and int(runner.run_ledger.bonus.get("armor_class", -1)) == 0, # 迭代 27 T3——加算区住 RunLedger + check(int(runner.run_ledger.bonus.get("atk", -1)) == 1 and int(runner.run_ledger.bonus.get("max_hp", -1)) == 0 and int(runner.run_ledger.bonus.get("armor_class", -1)) == 0, # 加算区住 RunLedger "统一冒险加算区 atk +1(bonus={atk,max_hp,armor_class} 账本)") by_id = _shop_products_by_id(runner.shop_products()) check(int(by_id["atk_up"]["price"]) == 8 and int(by_id["atk_up"]["purchased"]) == 1, @@ -5089,8 +5084,8 @@ func _smoke_shop_room() -> void: check(runner.effective_atk() == int(_db.hero.atk) + 1, "主角攻击生效值 = 2+1(基础表值 + 加算区)") check(runner.pick_next_node(9) and runner.current_battle() != null, "选 Boss(节点 9)开战") var snap: Dictionary = runner.current_battle().presentation_snapshot() - # max_hp 期望按实际购买笔数推导(迭代14① T4 断言基线复核——棋盘换代改变战局 GP 流,可购笔数 - # 随经济漂移;断言语义=「加算区笔数×3 全额入战斗开始参数」,不再锚死恰好 1 笔) + # max_hp 期望按实际购买笔数推导(可购笔数 + # 随经济漂移;断言语义=「加算区笔数×3 全额入战斗开始参数」,不锚死恰好 1 笔) check(int(snap["hero"].get("atk", -1)) == int(_db.hero.atk) + 1 and int(snap["hero"].get("max_hp", -1)) == int(_db.hero.max_hp) + 3 * hp_buys, "战斗开始参数 = 基础表值 + 加算区(atk %d = 2+1 / max_hp %d = %d+%d×3)" % [int(snap["hero"].get("atk", -1)), int(snap["hero"].get("max_hp", -1)), int(_db.hero.max_hp), hp_buys]) # 冒险收束(Boss 胜或败北——基线裸装口径任一结局)→ 钱包清零 @@ -5156,7 +5151,7 @@ func _smoke_shop_graph() -> void: "L1 行集零改动(单链 Boss (1,4)——教学期最小修订面)") -# ---- ⑤ 商店共享池(M-4 迭代 11 第②批 T5——三选一同构/乘法价/跨渠道共账/切边/断点扩键)---- +# ---- ⑤ 商店共享池(三选一同构/乘法价/跨渠道共账/切边/断点扩键)---- func _smoke_shop_pool() -> void: print("--- 商店共享池(抽3买1全重抽 · 乘法定价 ceil · 池空硬闸 · 切边零入店)---") @@ -5363,14 +5358,14 @@ func _smoke_nine_types_gp_stream() -> void: if String(row.get("reward_id", "")) == "gp_lose": gp_neg = int(row.weight) check(cell_rows == 18, "奖励字典 18 行(九型×正负 18 格——aux 挖格投放四行已退役 2026-10-01 用户拍板甲:战斗/挖格不掉道具,秘宝唯一来路=三选一共享池〔节点/通关〕;清图槽独立批尾不计)") - # 危险格负向直伤当量(迭代 8 卡⑧——真人反馈「三雷 3/4 血无后果感」投值:三行各抬 +3 档,负向≈正向 2 倍定价) - var mine_power := {"heal_backlash": 6, "pierce_snare": 8, "magic_recoil": 8} # 数值修复批 2026-10-01 再抬档(旧 4/5/5,见 numfix 报告) + # 危险格负向直伤当量(负向≈正向 2 倍定价——真人反馈「三雷 3/4 血无后果感」的投值口径) + var mine_power := {"heal_backlash": 6, "pierce_snare": 8, "magic_recoil": 8} # 危险格负向直伤当量(抬档值;依据见 numfix 报告) for row in _db.reward.rows: var rid := String(row.get("reward_id", "")) if mine_power.has(rid): check(int(row.get("power", -1)) == int(mine_power[rid]), "危险格负向直伤 %s power=%d(卡⑧投值)" % [rid, int(mine_power[rid])]) - # 正向权重结构校验(配置推导,2026-09-23 重构):正向 cell 行权重 ≥1(必在池)、负向行权重恒 0(不入池)、 + # 正向权重结构校验(配置推导):正向 cell 行权重 ≥1(必在池)、负向行权重恒 0(不入池)、 # 合计即配置自身的和(改表自动跟随,不再硬编码合计值)。 var pos_all_in_pool := true var neg_all_zero := true @@ -5388,8 +5383,8 @@ func _smoke_nine_types_gp_stream() -> void: check(rng.counter() == 0, "derive_at 纯函数不推计数器(统一流全局计数器恒 0——并流后纯函数语义不变,gp_drop 专用向量随分盐作废、统一向量中央断言)") -# ---- 元进度·MetaTable 表结构(元进度实现批 T1——行值全 provisional 归元进度设计批配读数; -# conversion 覆盖恰三,Boss 两档 first ≥ repeat;forge_products 行族已退役)---- +# ---- 元进度·MetaTable 表结构(行值全 provisional 归元进度设计文档配读数; +# conversion 覆盖恰三,Boss 两档 first ≥ repeat)---- func _smoke_meta() -> void: print("--- 元进度·MetaTable 表结构 ---") var meta_tbl = _db.meta @@ -5415,7 +5410,7 @@ func _smoke_meta() -> void: _career_overlay_projection() -# ---- 锻造工坊·两根类型轴所有权移交(迭代 23 T2——V5 前半:hero.tres 两轴删除+锻造配置默认值)---- +# ---- 锻造工坊·两根类型轴所有权移交(V5 前半:hero.tres 两轴删除+锻造配置默认值)---- # 后半(build_adventure_params 注入默认值/选中覆盖)随 T4 注入接线同批断言;写口/解锁面归 T3。 func _smoke_forge_axes() -> void: print("--- 锻造工坊·类型轴所有权移交(T2)---") @@ -5425,7 +5420,7 @@ func _smoke_forge_axes() -> void: # 锻造配置默认值 = normal/light(常驻持有——与柜台解锁状态解耦,未点亮也照常可读) check(_db.forge_default_attack_type() == "normal" and _db.forge_default_armor_type() == "light", "锻造配置默认值 attack_type=normal / armor_type=light(常驻持有)〔锻造工坊批 V5〕") - # 单位快照回退面:spawn 三参形态(零注入)= 锻造配置默认值(行为连续——原 hero.tres normal/light) + # 单位快照回退面:spawn 三参形态(零注入)= 锻造配置默认值 var uc = load("res://core/unit_container.gd").new(_db) check(uc.spawn(1, 0, int(_db.hero.max_hp)), "spawn 受理(三参形态——两轴缺省回退面)") check(String(uc.hero_unit().get("attack_type", "")) == "normal" @@ -5571,7 +5566,7 @@ func _smoke_forge_axes() -> void: "树零攻防来源复核(12 行 effects 键集无 atk/armor_class——契约 1)〔锻造工坊批 V10〕") -# ---- 状态面板只读投影一致性(迭代 17 卡③——R4 数据只读同源:状态面板展示值逐项 == MetaProgression +# ---- 状态面板只读投影一致性(R4 数据只读同源:状态面板展示值逐项 == MetaProgression # 访问器读数;投影拼装与 main._status_data 同构(同访问器族同序)。只读性连接巡检与零动效 # 断言归 ui_struct_probe 呈现侧,本段只管数据面)---- func _status_panel_projection() -> void: @@ -5579,7 +5574,7 @@ func _status_panel_projection() -> void: _meta_smoke_cleanup() var sv = _meta_new_save(_META_SMOKE_PATHS[0]) var mp = load("res://core/meta_progression.gd").new(_db, sv) - # 已购态夹具:余额非零 + 秘宝匣首件解锁——投影可辨非全零白板(属性锻造段已随柜台退役删除) + # 已购态夹具:余额非零 + 秘宝匣首件解锁——投影可辨非全零白板 sv.add_keystone(37) sv.unlock_item("morning_order") sv.write_to_disk() @@ -5629,7 +5624,7 @@ func _status_panel_projection() -> void: po.free() -# ---- 生涯页只读投影一致性(迭代 18 卡④——汇总段六类九项逐行 == SaveManager 计数访问器/ +# ---- 生涯页只读投影一致性(汇总段六类九项逐行 == SaveManager 计数访问器/ # MetaProgression 访问器读数;投影拼装与 main._career_data 同构(同访问器族同序)。 # 只读性连接巡检与零动效断言归 ui_struct_probe 呈现侧,本段只管数据面+旧档载入显示 # (v5 样档升 v6——完成定义 6「计数域缺省补零、页正常显示」))---- @@ -5638,7 +5633,7 @@ func _career_overlay_projection() -> void: var sv = _meta_new_save(_META_SMOKE_PATHS[9]) var mp = load("res://core/meta_progression.gd").new(_db, sv) # 已玩态夹具:两局收束(一通一止)+ 钥石非零——投影可辨非全零白板 - # (账号成长态三投影已删——2026-10-12 用户裁:生涯页不统计天赋树与账号成长态,只统计终身计数) + # (生涯页不统计天赋树与账号成长态,只统计终身计数) sv.add_keystone(45) sv.apply_adventure_summary({"result": "completed", "cleared": true, "levels_cleared": 3, "stopped_at": 0, "keystone_total": 0, "master_seed": 21}) @@ -5721,14 +5716,14 @@ func _meta_new_save(path: String): return sv -# ---- 元进度 ②树购买面(迭代 21 T2——购买受理/持久/余额不足拒绝/未知节点拒绝; -# 几何定价段随属性锻造柜台退役消亡,行价=表值 flat 单价)---- +# ---- 元进度 ②树购买面(购买受理/持久/余额不足拒绝/未知节点拒绝; +# 行价=表值 flat 单价)---- func _meta_pricing_and_buy() -> void: print("--- 元进度·树购买面(隔离档 smoke_meta_buy/dry)---") _meta_smoke_cleanup() var sv = _meta_new_save(_META_SMOKE_PATHS[0]) var mp = load("res://core/meta_progression.gd").new(_db, sv) - # ③ 购买成功:级+1、余额−价;buy 内含写盘——reload 后持久(树全钥石单币——2026-10-07 用户裁甲) + # ③ 购买成功:级+1、余额−价;buy 内含写盘——reload 后持久(树全钥石单币) sv.add_keystone(1000) var bal0: int = sv.keystone_balance() var price0: int = int(_db.tree_node("sp_hp").get("price", 0)) @@ -5752,7 +5747,7 @@ func _meta_injection() -> void: print("--- 元进度·注入可见与白板(隔离档 smoke_meta_white/dry)---") var sv = _meta_new_save(_META_SMOKE_PATHS[1]) var mp = load("res://core/meta_progression.gd").new(_db, sv) - # 树生命淬炼注入(迭代 21 T4 换代公式:基础值+树淬炼 flat+锻造路线加值位预留 0——2 级 = +10; + # 树生命淬炼注入(公式:基础值+树淬炼 flat+锻造路线加值位预留 0——2 级 = +10; # 注入走调试口径直置等级〔两分法——购买链已在 _smoke_tree 覆盖,此处隔离行门槛干扰〕) sv.set_tree_level("sp_hp", 2) check(int(mp.hero_override().get("max_hp", -1)) == 2 * int(_db.tree_node("sp_hp").get("effects", {}).get("max_hp", 0)), @@ -5795,7 +5790,7 @@ func _meta_settle_and_workshop() -> void: var mp = load("res://core/meta_progression.gd").new(_db, sv) var row1: Dictionary = _db.meta_boss_keystone_row(1) var row2: Dictionary = _db.meta_boss_keystone_row(2) - # ⑥ 逐杀掉落收束入账(迭代 10——掉落已在冒险内逐杀入账〔summary.keystone_total 含全部〕, + # ⑥ 逐杀掉落收束入账(掉落已在冒险内逐杀入账〔summary.keystone_total 含全部〕, # keystone_drops 明细随摘要归档;首杀标记仍由 apply 逐通关关次置位) var d1: Dictionary = mp.settle_adventure({"result": "failed", "cleared": false, "levels_cleared": 1, "stopped_at": 2, "keystone_total": int(row1.get("first_kill", 0)), @@ -5836,8 +5831,8 @@ func _meta_settle_and_workshop() -> void: "stopped_at": 1, "keystone_total": 0, "master_seed": 15}) check(dz["boss_drops"].is_empty() and sv.keystone_balance() == bal_before and sv.clear_count(1) == cc1_before, "败北零通关摘要:零入账零标记(钥石只增不减——验收1;败北局 clear_counts 不变)") - # ⑧ 秘宝解锁服务(迭代 22 T2——V3 钥石购买/V4 条件解锁;注入=直调解锁写口+直置存档生涯计数, - # 不走正常资源积累流程——卡片 7.1 测试方式;旧工坊渠道段随行族退役摘除) + # ⑧ 秘宝解锁服务(V3 钥石购买/V4 条件解锁;注入=直调解锁写口+直置存档生涯计数, + # 不走正常资源积累流程——卡片 7.1 测试方式) var sv_u = _meta_new_save(_META_SMOKE_PATHS[11]) var mp_u = load("res://core/meta_progression.gd").new(_db, sv_u) sv_u.add_keystone(10) @@ -5884,7 +5879,7 @@ func _meta_settle_and_workshop() -> void: "stopped_at": 1, "keystone_total": 0, "master_seed": i}) check(sv_c.recent_summaries().size() == 10 and int(sv_c.recent_summaries()[0].get("master_seed", -1)) == 11, "摘要 cap 10 且最新在前(12 连 settle 截断后 seed 11 居首)") - # ⑪ 同调位账本(迭代 11 第①批 T4——装配持久/满位禁选/Y 升级语义;写口 = MetaProgression 同调段) + # ⑪ 同调位账本(装配持久/满位禁选/Y 升级语义;写口 = MetaProgression 同调段) var sv_a = _meta_new_save(_META_SMOKE_PATHS[6]) var mp_a = load("res://core/meta_progression.gd").new(_db, sv_a) check(Attunement.slots(_db, sv_a) == 0 and int(mp_a.attune_camp_status()["refresh"]["charges"]) == 0, @@ -5915,12 +5910,11 @@ func _meta_settle_and_workshop() -> void: var mp_a2 = load("res://core/meta_progression.gd").new(_db, sv_a2) check((mp_a2.attune_camp_status()["equipped"] as Array).has("morning_order"), "装配关系读回持久(reload 后投影一致——写新件 id)〔秘宝批 V15〕") - # ⑫ 充能重置 / 刷新双计数器(迭代 11 第①批;clamp white-box 断言随 attunement_growth 谓词表 - # 退役摘除——迭代 21 T5,V20 摘除清单) + # ⑫ 充能重置 / 刷新双计数器 var a12 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(12)) check(a12.start_adventure(12, {"attunement": ["incense_stick", "sky_eye"]}), "充能重置场景:装配冒险启动(seed 12)〔秘宝批 V8 换主语〕") - check(int(a12.run_ledger.attune_charges.get("incense_stick", -1)) == 1 and int(a12.run_ledger.attune_charges.get("sky_eye", -1)) == 1, # 迭代 27 T3——充能账住 RunLedger + check(int(a12.run_ledger.attune_charges.get("incense_stick", -1)) == 1 and int(a12.run_ledger.attune_charges.get("sky_eye", -1)) == 1, # 充能账住 RunLedger "充能账本按装备 active_charged 件重置(新目录表值:线香 battle 级 1 次/天眼 level 级 1 次——周期重置点归 V8 逐形态面)") a12._attunement = [] a12._attune_refresh_x = 1 @@ -5934,7 +5928,7 @@ func _meta_settle_and_workshop() -> void: a12._reset_refresh_x() check(a12._attune_refresh_x == 0 and a12.attune_refresh_left() == 0, "刷新 X 每碰三选一重置(不结转;新目录无 bonus_refresh 行源——X 机制保留恒 0 空转,存量加仓走 _refresh_stock=刷新练习 V8)〔秘宝批换代〕") - # ⑬ 主菜单开局传参面(迭代 19 卡⓪①③——开新/续玩两入口同调三键随开局下传防回归:真实入口此前 + # ⑬ 主菜单开局传参面(开新/续玩两入口同调三键随开局下传防回归:真实入口曾 # 三键恒空(缺陷①),冒烟夹具直呼 runner 参数面拦不住——此处直呼 main.build_adventure_params # 单测统一构造面(static 免实例化整菜单场景;真实两入口共用本构造),取值与营地投影同源) var sv_e = _meta_new_save(_META_SMOKE_PATHS[8]) @@ -5961,9 +5955,8 @@ func _meta_settle_and_workshop() -> void: and int(p_resume.get("attune_refresh_y", -1)) == mp_e.attune_refresh_charges() and (p_resume.get("tree_rules", []) as Array) == rules_e, "主菜单继续上局参数面:三键与开新冒险同源同值(续玩不吃白板开局)") - # 尾裁微批b(2026-10-08 卡⓪受理闭环)——续玩路径 tree_rules 受理断言:resume_adventure 此前 - # 只收 attunement/attune_refresh_y 两键(tree_rules 暂不消费在册披露),受理补齐后直呼 runner - # 续玩参数面(v2 旧断点夹具同式最小断点——smoke ⑫ 受理路径同形)验 _tree_rules 与传入一致。 + # 续玩路径 tree_rules 受理断言:直呼 runner 续玩参数面 + # (v2 旧断点夹具同式最小断点——smoke ⑫ 受理路径同形)验 _tree_rules 与传入一致。 var adr_res = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(19)) var bp_min: Dictionary = {"level_index": 1, "node_id": -1, "hero_hp": 40, "gp": 5, "bonus": {"atk": 0, "max_hp": 0, "armor_class": 0}, "shop_purchased": {}, @@ -5976,16 +5969,16 @@ func _meta_settle_and_workshop() -> void: _meta_smoke_cleanup() -# ---- 天赋树冒烟(迭代 21 T1/T2——v0.8 12 节点换代:schema/购买面/Fork 一节点双态/彩蛋特化)---- +# ---- 天赋树冒烟(v0.8 12 节点:schema/购买面/Fork 一节点双态/彩蛋特化)---- func _smoke_tree() -> void: print("--- 天赋树(12 节点 · 购买面 · Fork 双态 · 彩蛋觉醒)---") - # 〔天赋树批 V1〕结构换代:12 行 + schema 零违例 + # 〔V1〕结构:12 行 + schema 零违例 check(_db.meta_tree != null and (_db.meta_tree.rows as Array).size() == 12, "meta_tree 已加载(12 节点=脊柱 2〔生命/命中淬炼一线一节点 cap4〕+锻造 2〔钥匙+彩蛋——彩蛋含在锻造 2 内非第 13 行〕+钥石 2〔秘宝匣/刷新升级〕+同调 6〔socket 3+Fork 3 双态〕——v0.8 终态)〔天赋树批 V1〕") check(_db.meta_tree.validate().is_empty(), "MetaTreeTable.validate 零违例(脉/类型/币词表出域即拒/Fork 三组每组恰一且持 a/b 双效果键/彩蛋 ≤3/effects 键封闭/零 archetype)") - # 彩蛋行硬要求(契约 9 红线落点):effects 键集 ⊆ {max_hp, hit}——旧表 :402/:405 atk/armor_class 分量换代件 + # 彩蛋行硬要求(契约 9 红线落点):effects 键集 ⊆ {max_hp, hit} var ley: Dictionary = _db.meta_tree.row_by_id("easter_ley") var ley_ok: bool = not ley.is_empty() for k in (ley.get("effects", {}) as Dictionary).keys(): @@ -6054,8 +6047,8 @@ func _smoke_tree() -> void: _meta_smoke_cleanup() -# ---- 天赋树六键行为冒烟(迭代 21 T3——V10:开局姿态窗/危险直觉限次/财富之道聚散/守侧失误补偿; -# 引擎直构 + 编排授予段直注(_grant_seg._judge_seal=结算授予段封印判定单口——迭代27 T2 随段迁址))---- +# ---- 天赋树六键行为冒烟(V10:开局姿态窗/危险直觉限次/财富之道聚散/守侧失误补偿; +# 引擎直构 + 编排授予段直注(_grant_seg._judge_seal=结算授予段封印判定单口))---- func _smoke_tree_rules() -> void: print("--- 天赋树六键行为(V10:窗/限次/聚散/守侧)---") # 开局姿态组:每关首轮窗(battle_index 事实——引擎直构) @@ -6128,7 +6121,7 @@ func _smoke_tree_rules() -> void: "守⑤:末轮判出不返(queue 只在 notify_round_start 兑现、战亡即弃——无跨战泄漏)") # 按关重置清零点(adventure_runner._start_current_level) var ar = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(777003)) - ar.run_ledger.adventure_counters = {"tree_sense_sharp_used": 2, "tree_sense_guard_used": 1, "unrelated_key": 9} # 迭代 27 T3——计数账住 RunLedger + ar.run_ledger.adventure_counters = {"tree_sense_sharp_used": 2, "tree_sense_guard_used": 1, "unrelated_key": 9} # 计数账住 RunLedger ar._reset_tree_limited_counters() check(not ar.run_ledger.adventure_counters.has("tree_sense_sharp_used") and not ar.run_ledger.adventure_counters.has("tree_sense_guard_used") and int(ar.run_ledger.adventure_counters.get("unrelated_key", 0)) == 9, @@ -6164,8 +6157,8 @@ func _smoke_tree_rules() -> void: _meta_smoke_cleanup() -# ---- 战斗日志视图·行格式化呈现层同步闸(2026-09-20 真人试玩卡断 bug 回归:八型批伏击退役拆除 -# 伤害行 attach 字段后本视图拆行分支漏网未同步——敌方首笔攻击行带 baseline 无 attach, +# ---- 战斗日志视图·行格式化呈现层同步闸(真人试玩卡断 bug 回归: +# 伤害行 attach 字段变更后本视图拆行分支漏网未同步——敌方首笔攻击行带 baseline 无 attach, # _format_row Invalid access 使结算段中途夭折、界面卡死。行协议变更必须同步呈现层〔战斗结算 §行协议〕, # 本段把现行行形态逐型喂进真实视图:拆行残留与行字段错位在此转红)---- func _smoke_battle_log_view() -> void: @@ -6178,7 +6171,7 @@ func _smoke_battle_log_view() -> void: var enemy_txt: String = view.parsed_text() check(enemy_txt.contains("撕咬") and enemy_txt.contains("〔掷 15 vs 护甲 12"), "敌方伤害行格式化(baseline 行不读退役 attach)") check(not enemy_txt.contains("伏击") and not enemy_txt.contains("基线"), "退役伏击/基线拆行文案不再出现") - # 主角攻击行·单分量模型(充能退役后 payload 只带实际攻击类型一键——修复前 pierce/magic 型即崩) + # 主角攻击行·单分量模型(payload 只带实际攻击类型一键——pierce/magic 多键即崩) view.append_row({"type": "damage", "display_name": "主角攻击", "value": 4, "pierce": 4, "roll": 20, "ac": 13, "tier": 100, "crit": true, "killed": true, "source_class": "hero_attack", "round_index": 2}) @@ -6206,8 +6199,8 @@ func _smoke_battle_log_view() -> void: check(view.parsed_text().length() > before, "行型 %s 格式化落地(解析文本增长)" % String(row_type)) -# ---- UI 全局主题冒烟(迭代 25 UI 全局主题批 2026-10-13——需求卡片 §7 验收清单 V1-V6)---- -# V1 挂载覆盖 / V2 滑轨两段修复 / V3 预盖件运行时证词 / V4 换代退役零残留 / +# ---- UI 全局主题冒烟(需求卡片 §7 验收清单 V1-V6)---- +# V1 挂载覆盖 / V2 滑轨两段 / V3 预盖件运行时证词 / V4 旧形态零残留 / # V5 回归(本冒烟全绿即回归网)/ V6 中文字体防御(挂主题后 default_font 顶掉 custom_font 也不丢字形) func _smoke_global_theme() -> void: print("--- UI 全局主题(main_theme.tres 挂载与词条断言)---") @@ -6284,7 +6277,7 @@ func _smoke_global_theme() -> void: check(ob.has_theme_stylebox("normal") and ob.has_theme_stylebox("hover") and ob.has_theme_stylebox("pressed") and ob.has_theme_color("font_color"), "V3 OptionButton 词条存在(预盖)") - # V4:换代退役——源码零残留(剥注释行后扫;ui_kit 两函数+挂载行+滑轨工厂) + # V4:旧形态源码零残留(剥注释行后扫;ui_kit 两函数+挂载行+滑轨工厂) for path in ["res://presentation/views/ui_kit.gd", "res://presentation/ui_assembler.gd", "res://presentation/views/settings_overlay.gd", "res://presentation/views/debug_overlay.gd"]: var src: String = FileAccess.get_file_as_string(path) @@ -6305,7 +6298,7 @@ func _smoke_global_theme() -> void: tpanel.free(); tlabel.free(); cbx.free(); cbt.free(); pm.free(); ob.free(); lbl.free() -# ---- 按钮五态矩阵冒烟(迭代 26 T1——四工厂产物逐实例 override 断言;V1/V2)---- +# ---- 按钮五态矩阵冒烟(四工厂产物逐实例 override 断言;V1/V2)---- func _smoke_button_five_states() -> void: print("--- UI 按钮五态矩阵(四工厂五态样式盒)---") var uikit_s = load("res://presentation/views/ui_kit.gd") @@ -6379,7 +6372,7 @@ func _smoke_button_five_states() -> void: check(focus_hits == "", "V2 红线维持 focus 族词条零定义%s" % ("" if focus_hits == "" else "(违例:" + focus_hits + ")")) -# ---- 全局纹理过滤冒烟(迭代 26 T2——工程设置 Nearest+平滑渐变件 LINEAR 白名单;V3)---- +# ---- 全局纹理过滤冒烟(工程设置 Nearest+平滑渐变件 LINEAR 白名单;V3)---- func _smoke_texture_filter() -> void: print("--- UI 全局纹理过滤(Nearest+白名单三件)---") var v = ProjectSettings.get_setting("rendering/textures/canvas_textures/default_texture_filter") @@ -6423,7 +6416,7 @@ func _smoke_texture_filter() -> void: "V3 状态图标显式 LINEAR 不丢(status_slot_row.gd)") -# ---- <4.5:1 文字位换墨冒烟(迭代 26 T3——站桩徽标两族亮档+RAP 行深石墨;V4)---- +# ---- <4.5:1 文字位换墨冒烟(站桩徽标两族亮档+RAP 行深石墨;V4)---- func _smoke_contrast_inks() -> void: print("--- UI 残余 <4.5:1 文字位换墨(V4 对比度锚定)---") var uikit_s = load("res://presentation/views/ui_kit.gd") @@ -6448,11 +6441,11 @@ func _smoke_contrast_inks() -> void: check(not ap_src.contains("STONE_FAINT"), "V4 RAP 反馈行旧墨 STONE_FAINT 清零(含注记面)") -# ---- 元素细节余②③冒烟(迭代 26 T5——BCard 图标槽明度差降档+商店居中+营地四栏等高)---- +# ---- 元素细节余②③冒烟(BCard 图标槽明度差降档+商店居中+营地四栏等高)---- func _smoke_element_details() -> void: print("--- UI 元素细节余②③(图标槽降档+布局修)---") var uikit_s = load("res://presentation/views/ui_kit.gd") - # ②白图标 ≥3:1 图形对比硬约束(代拍板6)+降档方向锚定 + # ②白图标 ≥3:1 图形对比硬约束+降档方向锚定 var r_white := _theme_contrast(Color.WHITE, uikit_s.SLOT_BACKDROP_SOFT) check(r_white >= 3.0, "T5② BCard 图标槽白图标对比 %.2f:1 ≥3:1(硬约束)" % r_white) var r_new := _theme_contrast(uikit_s.SLOT_BACKDROP_SOFT, uikit_s.PANEL_DATA) @@ -6475,7 +6468,7 @@ func _smoke_element_details() -> void: check(camp_src.count("SIZE_SHRINK_CENTER") >= 3, "T5③ 三处锁文垂直居中在位") -# ---- 诊断转储钮退役冒烟(迭代 26 T5b——角落钮退出玩家画面+转储入口迁调试浮窗;V6)---- +# ---- 诊断转储钮冒烟(角落钮不在玩家画面+转储入口在调试浮窗;V6)---- func _smoke_diag_button_retired() -> void: print("--- UI 诊断转储钮退役(V6:玩家画面清零+浮窗可达)---") var main_src: String = FileAccess.get_file_as_string("res://presentation/main.gd") @@ -6519,8 +6512,8 @@ func _smoke_save() -> void: w.add_keystone(7) w.set_tree_level("sp_hp", 2) w.set_tree_level("sp_hit", 1) - w.set_fork_side("fg_posture", "b") # 树域写入(属性锻造域已退役——forge_levels 域清退换代件) - w.set_forge_route_level("spear", 3) # 锻造工坊域写入(迭代 23 T5——等级+直购解锁+选中标记) + w.set_fork_side("fg_posture", "b") # 树域写入 + w.set_forge_route_level("spear", 3) # 锻造工坊域写入(等级+直购解锁+选中标记) w.add_forge_unlock("spear") w.set_forge_weapon("spear") w.set_forge_armor("ward") @@ -6601,7 +6594,7 @@ func _smoke_save() -> void: "迁移链 0→1(测试钩)→7(生产) 写盘 version == 7(v7=锻造工坊域,迭代 23 T5——v6=生涯终身计数域迭代 18 卡④)") # ⑧ 域界干净:meta 永久进度域不含局内资源键(行动点/RAP/GP/道具库存/生命账本不入档——契约 2; - # 迭代 8 卡①修订:扫描收窄到 meta 域——断点域=冒险进行中瞬态快照,生命/GP 按拍板面入域豁免) + # 扫描收窄到 meta 域——断点域=冒险进行中瞬态快照,生命/GP 属豁免面) var disk_parsed = JSON.parse_string(FileAccess.open(paths[0], FileAccess.READ).get_as_text()) var meta_text := JSON.stringify((disk_parsed as Dictionary).get("meta", {})) var banned := ["\"ap\"", "\"rap\"", "\"gp\"", "\"inventory\"", "\"hero_hp\""] @@ -6647,7 +6640,7 @@ func _smoke_save() -> void: and r9.recent_summaries().size() == 2 and r9.boss_first_kill_marked(3), "集成写盘读回全量保持") - # ⑪ 断点域(迭代 8 卡①):七字段写读往返逐位一致+附随件+值拷贝出户+清除+旧档迁移合法空态 + # ⑪ 断点域:七字段写读往返逐位一致+附随件+值拷贝出户+清除+旧档迁移合法空态 var fbp = sm_script.new(paths[9]) check(not fbp.has_breakpoint(), "断点:新档无断点(合法空态——「继续上局」隐藏)") fbp.set_breakpoint({ @@ -6698,7 +6691,7 @@ func _smoke_save() -> void: check(fo.write_to_disk() and int(JSON.parse_string(FileAccess.open(paths[9], FileAccess.READ).get_as_text()).get("version", -1)) == 7, "v1 旧档迁移后写盘 version == 7(v1→v7 链式——锻造工坊域 2026-10-12)") - # ⑫ v2 旧档→v3 兼容(迭代 10 g 裁——semver 向后兼容:旧断点零丢失、新代码可续玩) + # ⑫ v2 旧档→v3 兼容(semver 向后兼容:旧断点零丢失、新代码可续玩) var fv2 = sm_script.new(paths[10]) var fv2f := FileAccess.open(paths[10], FileAccess.WRITE) fv2f.store_string(JSON.stringify({"version": 2, "meta": {"keystone_balance": 7}, @@ -6715,7 +6708,7 @@ func _smoke_save() -> void: check(adr_v2.resume_adventure(fv2.breakpoint_snapshot(), {"hero_override": {}}), "v2 旧断点续玩受理(缺 bonus 附随件走常规重建路径——g 裁 semver 口径)") - # ⑬ 生涯终身计数域(迭代 18 卡④):v5 旧档升 v6 缺省补零 + 升档幂等 + 收束自增恰一 + # ⑬ 生涯终身计数域:v5 旧档升 v6 缺省补零 + 升档幂等 + 收束自增恰一 #(真实旧档形态=计数域两键不存在;升档只增不改——既有 meta 值零触碰,存档红线 S2 断言面) var f13 = sm_script.new(paths[11]) var fv5u := FileAccess.open(paths[11], FileAccess.WRITE) @@ -6739,7 +6732,7 @@ func _smoke_save() -> void: check(f13b.adventure_total() == 2 and f13b.adventure_cleared() == 1, "收束自增恰一·中止局(放弃局:仅总局数+1,通关局数不动)") - # ⑮ 旧档破坏性废弃(迭代 21 T5——契约 4:换代前结构检测=树域废弃重置,禁迁移禁折算)〔天赋树批 V16〕 + # ⑮ 旧档破坏性废弃(契约 4:换代前结构检测=树域废弃重置,禁迁移禁折算)〔V16〕 var f15 = sm_script.new(paths[13]) var fv16 := FileAccess.open(paths[13], FileAccess.WRITE) fv16.store_string(JSON.stringify({"version": 6, "meta": {"keystone_balance": 33, @@ -6754,7 +6747,7 @@ func _smoke_save() -> void: f15.add_keystone(50) check(mp16.tree_buy("sp_hp") and f15.tree_level("sp_hp") == 1, "废弃重置后后续购买正常受理(无残留脏节点)") - # ⑯ 锻造工坊域 forge_routes(迭代 23 T5——V8):v6 旧档缺键补齐=初始持有态+无特效域+域界干净 + # ⑯ 锻造工坊域 forge_routes(V8):v6 旧档缺键补齐=初始持有态+无特效域+域界干净 var f16 = sm_script.new(paths[14]) var fv6 := FileAccess.open(paths[14], FileAccess.WRITE) fv6.store_string(JSON.stringify({"version": 6, "meta": {"keystone_balance": 21, @@ -6781,7 +6774,7 @@ func _smoke_save() -> void: (snap.get("levels", {}) as Dictionary)["sword"] = 99 check(f16.forge_route_level("sword") == 0, "forge_routes_snapshot 值拷贝出户(改快照不渗档)〔锻造工坊批 V8〕") - # ⑭ 收束链入账(迭代 18 卡④ T2——真实收束挂点全链恰一:主流程 adventure_finished → + # ⑭ 收束链入账(真实收束挂点全链恰一:主流程 adventure_finished → # MetaProgression.settle_adventure → apply_adventure_summary 单口;两夹具经同链入账) var mp13 = load("res://core/meta_progression.gd").new(_db, f13b) mp13.settle_adventure({"result": "failed", "cleared": false, "levels_cleared": 2, diff --git a/game/smoke/t17_defer_probe.gd b/game/smoke/t17_defer_probe.gd index 5e7fda9f..efbb2ae0 100644 --- a/game/smoke/t17_defer_probe.gd +++ b/game/smoke/t17_defer_probe.gd @@ -1,5 +1,5 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# 演播后排窗定点探针(T17 用户令「伤害过程演完才切战斗胜利结算窗」——对应本改动的唯一关联测试): +# 演播后排窗定点探针(规则=「伤害过程演完才切战斗胜利结算窗」——该行为的唯一关联测试): # 真实信号路径驱动一场战斗到击杀胜利(结算行在排播队列),断言两条: # ①胜利同帧:终局面未开 + 挂起态在案 + 队列非空(旧行为=同帧 flush+开窗,本断言即红——判别性); # ②排播放完:终局面开启(演播完边沿派发——_on_pump_ended)。 diff --git a/game/smoke/type_glow_shot_probe.gd b/game/smoke/type_glow_shot_probe.gd index ab4f0701..b86a4aeb 100644 --- a/game/smoke/type_glow_shot_probe.gd +++ b/game/smoke/type_glow_shot_probe.gd @@ -1,5 +1,5 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# 未开格类型微光渲染取证探针(迭代 30 卡① T2 像素侧——V4 禁侵/V5 不压破/V6 五组互辨)。 +# 未开格类型微光渲染取证探针(像素侧——V4 禁侵/V5 不压破/V6 五组互辨)。 # 必须**窗口化**运行(headless 无渲染面,抓帧恒空): # Godot_console.exe --path . res://smoke/type_glow_shot_probe.tscn -- <输出目录> # 流程:起一板(真实 LevelRunner + settle_batch 驱动 18 步 novice——自然揭示数字/封印)→ 注入夹具身份回调 @@ -22,7 +22,7 @@ const FIXTURE_TYPES := ["attack", "defense", "blast", "heal", "weaken", # 同屏组数不足 5 = 取证失败(见 _report 硬断言)——幸存集若变,探针报红而非静默少测。 const FIXTURE_DIR_TYPES := ["attack", "gp", "defense", "pierce", "weaken", "blast", "magic", "heal"] -# 判据阈值(provisional——首版取严;实现报告登记,复核转正归战斗一屏样张批) +# 判据阈值(provisional——首版取严;实现报告登记,复核转正归战斗一屏样张) const CORE_PAD_FRAC := 0.20 const GRAY_CR_MIN := 1.20 diff --git a/game/smoke/ui_click_probe.gd b/game/smoke/ui_click_probe.gd index 11ffef68..90938a1a 100644 --- a/game/smoke/ui_click_probe.gd +++ b/game/smoke/ui_click_probe.gd @@ -1,6 +1,5 @@ # VERTICAL SLICE - NOT FOR PRODUCTION # 实现 GDD:design/ux/battle.md(§AC 场景级测试 + §Interaction Map——UI 行为随机化探针 v3)。 -# Date: 2026-09-12 # 合成鼠标事件走真实呈现层路径(BoardView.click_cell / 按钮信号 → 组合根动作通道), # 随机混合玩家行为——封印/撤封印、提前停手、弃图刷新确认链、图例模态、明细回看模态、 # tooltip 悬停、无效点击——扫描结算停滞(缺陷②回归载体) @@ -24,11 +23,11 @@ var _ap_spent_this_round := 0 var _problems: Array = [] # 新增覆盖的问题收集(退出码合并判定) var _tested_legend := false var _tested_review := false -var _tested_end_review := false # 迭代 6 T7——终局面板回看入口(z 序修复回归) +var _tested_end_review := false # 终局面板回看入口(z 序修复回归) var _tested_refresh_chain := false var _tested_tooltip := false -var _tested_status := false # 迭代 17 卡③——状态面板角标开合/守卫断言(每 run 一次) -var _tested_map_status := false # 迭代 17 卡③——地图屏角标一次性 case(选路态零扰动) +var _tested_status := false # 状态面板角标开合/守卫断言(每 run 一次) +var _tested_map_status := false # 地图屏角标一次性 case(选路态零扰动) var _inter_confirms := 0 # 大奖励屏确认计数(冒险推进停点——首见确认推进 L2,再见 = L2 通关收口) var _settlement_confirms := 0 # 卡⑥ 胜利结算框确认计数(观测面——每场普通战斗胜利恰一) var _route_clicks := 0 # 选路覆盖层点击计数(岔路使用率观测面) @@ -46,11 +45,11 @@ func _ready() -> void: add_child(main) await get_tree().process_frame var t_ui_ready := Time.get_ticks_msec() - t0 - # 调试浮窗 boot 不开(2026-10-16 用户令修正:菜单优先——入口=UI 最顶层全局浮层角标, + # 调试浮窗 boot 不开(菜单优先——入口=UI 最顶层全局浮层角标, # 任何 UI 不遮挡;浮层角标遮挡判据见设置面段) if main.debug_overlay.visible: _problems.append("调试浮窗 boot 自动开(菜单优先失守)") - # ---- 营地购买合成点击路径(元进度实现批——campbtn/购买/关闭全走真实按钮信号路径; + # ---- 营地购买合成点击路径(campbtn/购买/关闭全走真实按钮信号路径; # 隔离存档换注 main.meta 保确定性(禁碰真实档 user://save.json);陈旧档段首清理)---- for p0 in ["user://smoke_click_probe_reset.json", "user://smoke_click_probe_reset.json.tmp"]: if FileAccess.file_exists(p0): @@ -88,7 +87,7 @@ func _ready() -> void: iso_chk.load_from_disk() if int(iso_chk.tree_level("sp_hp")) != 1: _problems.append("营地树购买未持久(reload 后级 != 1)") - # Fork 双态切换点击路径(V20 换代——购=解锁默认 A,钮切 B;前置=同调位 1,先点亮) + # Fork 双态切换点击路径(V20——购=解锁默认 A,钮切 B;前置=同调位 1,先点亮) var socket_btn: Button = null for card in main.camp_overlay._tree_buy_btns: if String(card.node_id) == "att_socket1": @@ -126,7 +125,7 @@ func _ready() -> void: await get_tree().process_frame if main.camp_overlay.visible or not main._start_overlay.visible: _problems.append("营地关闭后未恢复开始层") - # ---- 设置面段(迭代 8 卡④——隔离 store 换注禁碰真实 user://settings.cfg;真实按钮信号路径)---- + # ---- 设置面段(隔离 store 换注禁碰真实 user://settings.cfg;真实按钮信号路径)---- for p0 in ["user://smoke_click_probe_settings.cfg"]: if FileAccess.file_exists(p0): DirAccess.remove_absolute(p0) @@ -171,7 +170,7 @@ func _ready() -> void: _problems.append("音量滑杆未实时生效(master bus db %f ≠ %f)" % [AudioServer.get_bus_volume_db(master_idx), expect_db]) if absf(iso_s.volume_linear - 0.3) > 0.001: _problems.append("音量未入 store(%f ≠ 0.3)" % iso_s.volume_linear) - # 调试入口断言(2026-10-16 用户令:全局浮层角标=UI 最顶层、任何 UI 不遮挡——本段设置面 + # 调试入口断言(全局浮层角标=UI 最顶层、任何 UI 不遮挡——本段设置面 # 开中正是遮挡场景:浮层角标此时仍应可见;点击开浮窗路径归 tune_probe) if main.debug_badge == null or not main.debug_badge.visible: _problems.append("设置面开中调试浮层角标不可见(最顶层浮层失守——被遮挡)") @@ -183,7 +182,7 @@ func _ready() -> void: await get_tree().process_frame if main.settings_overlay.visible or not main._start_overlay.visible: _problems.append("设置面关闭后未恢复开始层") - # 旧入口退役断言(卡④ AC③——测试调整板不再含减动效开关;14.5 起载体=调试浮窗) + # 旧入口零残留断言(卡④ AC③——测试调整板不含减动效开关;14.5 起载体=调试浮窗) var legacy_motion = ProbeUiUtil.find_check_button(main.debug_overlay, "减动效") if legacy_motion != null: _problems.append("调整板减动效旧入口未退役(设置面唯一入口失守——卡④ AC③)") @@ -192,7 +191,7 @@ func _ready() -> void: _problems.append("开始菜单缺退出游戏按钮(二轮 D1)") if ProbeUiUtil.find_button(main.settings_overlay, "退出游戏", "prefix") != null: _problems.append("设置面仍含退出游戏按钮(二轮 D1——只在一级菜单出现)") - # ---- 生涯页段(迭代 18 卡④——入口点击链+关闭回返,真实按钮信号路径;本页只读零写, + # ---- 生涯页段(入口点击链+关闭回返,真实按钮信号路径;本页只读零写, # 值断言归冒烟投影段与 ui_struct 结构族,此处只验开合路径与零跳转)---- var career_btn: Button = ProbeUiUtil.find_button(main._start_overlay, "生涯", "prefix") if career_btn == null: @@ -227,14 +226,14 @@ func _ready() -> void: elif resume_btn0.visible: _problems.append("无断点态继续上局按钮未隐藏(卡② AC①——新档合法空态)") main.debug_overlay.set_sliders(400, 200) # 高加成保 L1 可通关——L2 岔路选路段只能经冒险推进到达(单关直入口退役) - main.debug_overlay.seed_edit.text = "42" # 种子钉死(迭代 18 卡⑦审计🔴——种子框默认改空后空框=非首局随机,行为走查确定性禁依赖默认分支) + main.debug_overlay.seed_edit.text = "42" # 种子钉死(种子框默认为空=非首局随机,行为走查确定性禁依赖默认分支) var t1 := Time.get_ticks_msec() main._start_adventure_from_menu() await get_tree().process_frame - # 停点前移批 2026-09-23:关卡开始 = 入口选路停点——press_candidate 图上命中路径选入口候选进首战(候选按钮退役 2026-09-28) + # 关卡开始 = 入口选路停点——press_candidate 图上命中路径选入口候选进首战 #(首格可点 AC 口径随之含入口选路一步:菜单点击 → 停点呈现 → pick → 棋盘安装) if main.level_screen.visible: - # 独立性断言(形态升格批 2026-09-28):独立屏激活期战斗屏宿主整体隐藏 + # 独立性断言:独立屏激活期战斗屏宿主整体隐藏 if main._battle_root.visible: _problems.append("独立屏激活期战斗屏宿主未隐藏(零透出契约失守)") main.level_screen.press_candidate(0) @@ -253,8 +252,8 @@ func _ready() -> void: first_cell_ms, t_total, t_ui_ready]) const ACTION_BUDGET_FRAMES := 20000 # 主循环帧预算(坏态挂死兜底上限——常态通关远低于此;有挂帧证据才收紧,勿让坏态等满预算才报) var action_budget := ACTION_BUDGET_FRAMES - # 2026-10-02 修复批(P0-2):c44fb1b 加 bonus 分支时把本 while 循环体整体去缩进——continue 落在 - # 循环外成解析错误、探针不可加载且改后无人实跑。此处还原循环体缩进,bonus 分支保留为体内兄弟分支。 + # P0-2 回归:本 while 循环体缩进必须整体在循环内——continue 落在 + # 循环外成解析错误、探针不可加载。bonus 分支保留为体内兄弟分支。 while not _done and action_budget > 0: action_budget -= 1 await get_tree().process_frame @@ -263,10 +262,10 @@ func _ready() -> void: _seals_placed.clear() continue if main.curio_overlay.visible: - # 迭代 10 三选一停点(CurioPickOverlay——奖励节点/通关兑付共用面;T17 硬锁批适配—— - # 本探针此前未适配该层,走到即卡死)。两态分派:result 态(兑付反馈——点继续推进)/ - # 待选态(点首件+确认)。真实信号路径全线。〔替换子态随迭代 22 T5 拆除——装配不可变契约。〕 - # T1 D1——三选一停点输入锁定断言(停点态断言面:待选/兑付两态共用此层)。 + # 三选一停点(CurioPickOverlay——奖励节点/通关兑付共用面,须与硬锁态适配, + # 未适配则走到即卡死)。两态分派:result 态(兑付反馈——点继续推进)/ + # 待选态(点首件+确认)。真实信号路径全线。〔无替换子态——装配不可变契约。〕 + # 三选一停点输入锁定断言(停点态断言面:待选/兑付两态共用此层)。 if not main._input_locked(): _problems.append("三选一停点打开时输入未锁定") if main.curio_overlay._continue_btn.visible: @@ -279,8 +278,8 @@ func _ready() -> void: _seals_placed.clear() continue if main.shop_overlay.visible: - # 商店房覆盖层(GP+商店房批——L2 商店为 Boss 前必经位):零购离开(真实 leave 信号路径)放行选路。 - # T1 D1 分派链序修正:商店层=选路页上的模态覆盖(迭代 11 商店房重构后停点呈现为 + # 商店房覆盖层(L2 商店为 Boss 前必经位):零购离开(真实 leave 信号路径)放行选路。 + # 分派链序:商店层=选路页上的模态覆盖(停点呈现为 # level_screen+shop 双 visible)——必须先于 level_screen 分派,否则下层候选点击 # 空转烧尽预算(实证:lv2 商店停点双 visible 循环 12000 帧 done=false)。 main.shop_overlay.leave_pressed.emit() @@ -288,7 +287,7 @@ func _ready() -> void: continue if main.level_screen.visible: # 节点图选路口(零自动推进停点)——图上命中路径交替选候选(岔路使用行为;布局决策 2 改造) - # 迭代 17 卡③——地图屏角标一次性 case:选路前经角标开/关状态面板(层在地图屏之上开合, + # 地图屏角标一次性 case:选路前经角标开/关状态面板(层在地图屏之上开合, # 关闭后地图屏选路态零扰动——P2 甲层级语义) if not _tested_map_status and not main.status_panel.visible: _tested_map_status = true @@ -330,7 +329,7 @@ func _ready() -> void: _seals_placed.clear() continue if main._end_overlay.is_open() and main._settlement_stop_pending: - # 卡⑥ 战斗胜利总结结算框(真实信号路径——每场普通胜利到达):断言已拍板面后点「下一节点」 + # 战斗胜利总结结算框(真实信号路径——每场普通胜利到达):断言已拍板面后点「下一节点」 if not main._input_locked(): _problems.append("胜利结算框打开时输入未锁定") var gp_line: String = "%s %s" % [main._end_overlay._gp_name.text, main._end_overlay._gp_val.text] # 两列账行(审计差距④)——名/值列拼回整串断言 @@ -346,8 +345,8 @@ func _ready() -> void: _problems.append("胜利结算框「下一节点」未进选路页(卡⑥ AC②)") continue if main._end_overlay.is_open(): - # 冒险终局(失败/放弃/打穿)——单关直入口退役后无二段入口,见终局即收口(模态断言照旧) - # T17 适配(迭代 10 三选一链):_adventure_mode 仍真且非选路挂起=中途结算面(Boss 胜利 + # 冒险终局(失败/放弃/打穿)——无单关直入口,见终局即收口(模态断言照旧) + # 三选一链适配:_adventure_mode 仍真且非选路挂起=中途结算面(Boss 胜利 # 总结「继续」后挂三选一→真终局未到)——真实信号路径点继续推进。 # T17 演播后排窗适配:真终局 vs 中途结算面判据=adventure.state(冒险结构三态—— # 战斗胜利停点=running / 真终局(失败/放弃/打穿)=settling)。旧判据 @@ -371,7 +370,7 @@ func _ready() -> void: "settling": diag.settling, } if JSON.stringify(st) == JSON.stringify(_last_state): - # 排播演播期豁免(T17 硬锁 v3 随批——合法停顿态):演播期棋盘锁生效、probe 点击被吞、 + # 排播演播期豁免(硬锁 v3——合法停顿态):演播期棋盘锁生效、probe 点击被吞、 # 逻辑态恒定属预期。判据=纯队列(与 main 锁同源)。Waiting 收尾等待期**不豁免**—— # 锁若把收尾链卡死,此处 stall 照报(探测面)。 # T1 D1 处置=保留豁免+注记:冻结/缓存/重放语义不再靠豁免绕行,由 _locktest_tick @@ -455,8 +454,8 @@ func _ready() -> void: main._end_overlay._btn.pressed.emit() # 真实按钮信号路径(_btn=继续/返回共用句柄) await get_tree().process_frame if not main._start_overlay.visible: - # T17 豁免:放弃路径收口时终局「返回」后仍挂三选一/关卡推进残留态(迭代 10 停点链), - # 战败态前提失配——记录不计 problem(返回路径已由 T17 第 27 项实机目检验证)。 + # 豁免:放弃路径收口时终局「返回」后仍挂三选一/关卡推进残留态(停点链), + # 战败态前提失配——记录不计 problem(返回路径已实机目检)。 if not _closed_via_abandon: _problems.append("断点段:终局返回未回开始菜单") var resume_btn: Button = ProbeUiUtil.find_button(main._start_overlay, "▶ 继续上局", "prefix") @@ -560,8 +559,8 @@ func _run_modal_probes_once() -> void: main.legend_overlay.close() if main.legend_overlay.is_open() or main._input_locked(): _problems.append("图例关闭后未恢复输入/可见性") - # ②/②b 明细回看模态探针退役(M9/P-C7——冒险中回看归「生涯」,06 登记) - # ⑤ 状态面板(迭代 17 卡③——P1 丁角标真实信号路径 + P2 甲模态语义 + P1 守卫 + R3 锁恢复): + # ②/②b 明细回看模态无探针(M9/P-C7——冒险中回看归「生涯」,06 登记) + # ⑤ 状态面板(P1 丁角标真实信号路径 + P2 甲模态语义 + P1 守卫 + R3 锁恢复): # 角标打开 → 只读层可见+输入锁定+余额徽非空 → 「继续」关闭恢复;图例开着 → 角标置灰且点击被守卫兜住 if not _tested_status and not main.legend_overlay.is_open() and not main.status_panel.visible: _tested_status = true @@ -596,7 +595,7 @@ func _run_modal_probes_once() -> void: main.legend_overlay.close() # ③ tooltip(状态效果槽悬停——来源+语义+剩余):有槽可见时触发 if not _tested_tooltip: - var row = main.stage.hero_standee.slot_row # 状态 tooltip 载体 2026-09-26 迁 B 区站桩 + var row = main.stage.hero_standee.slot_row # 状态 tooltip 载体(B 区站桩) for child in row.get_children(): if child is PanelContainer and child.visible and child.has_meta("eff"): _tested_tooltip = true @@ -624,7 +623,7 @@ func _run_modal_probes_once() -> void: _problems.append("轮内刷新后相位丢失(%s)" % main.run_scope.settlement.action_economy.phase) if main.run_scope.settlement.minesweeper.current_board() == board_before: _problems.append("轮内刷新未当场换图") - # V5(迭代 27 T3——刷新双账收口):轮内计数单源=结算快照(main 副本已删)+ HUD 余量一致 + # V5(刷新双账收口):轮内计数单源=结算快照(main 副本已删)+ HUD 余量一致 var used_now: int = int(main.run_scope.settlement.presentation_snapshot().get("refresh_used", 0)) if used_now != 1: _problems.append("刷新轮内计数错误(%d)" % used_now) diff --git a/game/smoke/ui_contrast_probe.gd b/game/smoke/ui_contrast_probe.gd index 22dc312b..f5ef2088 100644 --- a/game/smoke/ui_contrast_probe.gd +++ b/game/smoke/ui_contrast_probe.gd @@ -9,12 +9,12 @@ extends Node const MIN_RATIO := 4.5 # R1 过渡白名单:呈现层(ui_kit.gd 之外)允许的裸 Color8( 在册处——file→恰计数。 -# T4a 已把 T0 实测全量 25 处/10 文件全部原值搬运收 ui_kit(2026-10-06)——本表应为空表; +# 产品码裸取色已全部收进 ui_kit——本表应为空表; # 新增裸取色 = 本闸红(先立常量再消费)。 const BARE_COLOR8_WL := {} -# 测点表:[名称, 墨色, 直背景, 墨α](语义见行尾;新增文字位随批入表,白名单豁免须注理由) +# 测点表:[名称, 墨色, 直背景, 墨α](语义见行尾;新增文字位入表,白名单豁免须注理由) func _pairs() -> Array: return [ ["站桩血数·垫牌", Color(1, 1, 1), UiKit.HP_BAR_BACK, 0.95], # N1-1/2 白 α.95 压 HP_BAR_BACK 素牌 @@ -28,38 +28,38 @@ func _pairs() -> Array: ["锚·正文墨/数据板", UiKit.INK, UiKit.PANEL_DATA, 1.0], # 全站锚点:正文墨对数据板 ["锚·暖白/屏根", UiKit.WARM, UiKit.BG_ROOT, 1.0], # 全站锚点:暗底正文 ["锚·暖白弱/舞台底", UiKit.WARM_FAINT, UiKit.STAGE_BG, 1.0], # 全站锚点:B区辅助墨 - ["钥石徽·深墨/烛光黄", UiKit.INK_ON_GOLD, UiKit.CANDLE, 1.0], # 迭代17卡③——badge 工厂件文字(营地徽+状态面板余额行同形制) - ["生涯页·行名墨/暖亮页底", UiKit.WARM, UiKit.BG_BRIGHT, 1.0], # 迭代18卡④——生涯页行名列/提示文(WARM_SOFT 同族亮墨) - ["生涯页·行值墨/暖亮页底", UiKit.CANDLE, UiKit.BG_BRIGHT, 1.0], # 迭代18卡④——生涯页数值列(烛光黄 bold) - ["生涯页·组帽墨/暖亮页底", UiKit.INK_L_GOLD, UiKit.BG_BRIGHT, 1.0],# 迭代18卡④——生涯页分组小节头(金亮 bold) - # ---- 迭代19卡②旧界面呈现断言回补批(2026-10-08)——旧屏文字位追溯收测;石皮纹面板 + ["钥石徽·深墨/烛光黄", UiKit.INK_ON_GOLD, UiKit.CANDLE, 1.0], # badge 工厂件文字(营地徽+状态面板余额行同形制) + ["生涯页·行名墨/暖亮页底", UiKit.WARM, UiKit.BG_BRIGHT, 1.0], # 生涯页行名列/提示文(WARM_SOFT 同族亮墨) + ["生涯页·行值墨/暖亮页底", UiKit.CANDLE, UiKit.BG_BRIGHT, 1.0], # 生涯页数值列(烛光黄 bold) + ["生涯页·组帽墨/暖亮页底", UiKit.INK_L_GOLD, UiKit.BG_BRIGHT, 1.0],# 生涯页分组小节头(金亮 bold) + # ---- 旧屏文字位追溯收测;石皮纹面板 # (panel_skinned)缺素材回退牌色 PANEL_DATA,机检按回退牌色计(素材不入 git 冒烟安全惯例)。 - # 存量违例对首跑红=登记呈报不修(处置权归用户)→ 2026-10-08 尾裁微批a 用户裁甲另立修复批 - # 回绿:7 对随代码侧换墨同步改指新常量(比率见各行尾注)。 - ["结算·判定墨/结算板", UiKit.INK_TITLE, UiKit.PANEL_DATA, 1.0], # 迭代19卡②——battle_end 判定行(INK_TITLE 亮底标题墨) - ["结算·GP账行墨/结算板", UiKit.GOLD_INK, UiKit.PANEL_DATA, 1.0], # 迭代19卡②——battle_end 战利品 GP 行名/值(尾裁微批a 换深金墨 5.21:1;原 GOLD_DEEP 2.67 越带) - ["结算·账行墨/结算板", UiKit.INK_LABEL, UiKit.PANEL_DATA, 1.0], # 迭代19卡②——battle_end 钥石/加成账行(标签深墨) - ["商店·行卡名墨/暗底行卡", UiKit.WARM_SOFT, UiKit.BG_OVERLAY, 1.0], # 迭代19卡②——legacy 行卡商品名(尾裁微批a 显式传暖白次级 9.53:1;原 bold 缺省 INK_LABEL 1.12 越带) - ["商店·行卡现价墨/暗底行卡", UiKit.WARM_SOFT, UiKit.BG_OVERLAY, 1.0],# 迭代19卡②——legacy 行卡「现价 N GP」 - ["商店·行卡已购墨/暗底行卡", UiKit.WARM_FAINT, UiKit.BG_OVERLAY, 1.0],# 迭代19卡②——legacy 行卡「已购 N 档」 - ["商店·爬价规则墨/暖亮页底", UiKit.WARM_SOFT, UiKit.BG_BRIGHT, 1.0],# 迭代19卡②——货架面爬价规则行(page_shell 亮底) - ["商店·货架卡名墨/货架板", UiKit.INK_TITLE, UiKit.PANEL_DATA, 1.0], # 迭代19卡②——bcard 货架卡商品名(iter16 换 TG 带后未机检位) - ["商店·货架价签墨/货架板", UiKit.GOLD_INK, UiKit.PANEL_DATA, 1.0], # 迭代19卡②——bcard 价签「N ◈」(尾裁微批a 换深金墨 5.21:1;原 GOLD 1.46 越带) - ["营地·等级章字/头带深棕", UiKit.INK_ON_DEEP, UiKit.CAMP_HEADER_BAND, 1.0],# 迭代19卡②——锻造行 Lv 章(木底小章亮墨) - ["营地·柜台头带字/头带深棕", UiKit.WARM, UiKit.CAMP_HEADER_BAND, 1.0], # 迭代19卡②——三柜台头带标题(暖白 bold) - ["营地·铭牌副题墨/铭牌板", UiKit.STONE_DEEP, UiKit.PANEL_DATA, 1.0],# 迭代19卡②——营地铭牌副题「跨局成长账本…」(尾裁微批a 换灰石深化 5.98:1;原 STONE 3.59 越带) - ["营地·行名墨/行板", UiKit.INK, UiKit.CAMP_ROW_PLATE, 1.0], # 迭代19卡②——锻造/工坊行名(墨族压暖米行板) - ["营地·行价格墨/行板", UiKit.STONE_DEEP, UiKit.CAMP_ROW_PLATE, 1.0],# 迭代19卡②——锻造行「N 钥石」价签/工坊进度行(尾裁微批a 换灰石深化 6.70:1;原 STONE 4.02 越带) - ["营地·树分组头墨/柜台板", UiKit.GOLD_INK, UiKit.PANEL_DATA, 1.0],# 迭代19卡②——天赋树脉分组头「·锻造脉·」(尾裁微批a 换深金墨 5.21:1;原 GOLD_DEEP 2.67 越带) - ["营地·树行名墨/柜台板", UiKit.INK_LABEL, UiKit.PANEL_DATA, 1.0], # 迭代19卡②——天赋树行「名 Lv0/1」(标签深墨) - ["营地·工坊状态墨/行板", UiKit.GOLD_INK, UiKit.CAMP_ROW_PLATE, 1.0],# 迭代19卡②——工坊状态字「已解锁」(尾裁微批a 换深金墨 5.84:1;原 GOLD_DEEP 3.00 越带·最不利现役态) - ["营地·最近冒险墨/暖亮底", UiKit.WARM_SOFT, UiKit.BG_BRIGHT, 1.0], # 迭代19卡②——底栏最近冒险条带(暖白次级) - ["设置·警示文/设置板", UiKit.INK_HINT, UiKit.PANEL_DATA, 1.0], # 迭代19卡②——设置警示文/后果说明(暖棕提示墨) - ["设置·选项标签/设置板", UiKit.INK_LABEL, UiKit.PANEL_DATA, 1.0], # 迭代19卡②——设置行标签/状态字(标签深墨) - ["三选一·停点头部墨/暗页底", UiKit.WARM_SOFT, UiKit.BG_ROOT, 1.0], # 迭代19卡②——三选一停点头部/回血反馈行(page_shell 根底档) - ["三选一·卡名墨/货架板", UiKit.INK_TITLE, UiKit.PANEL_DATA, 1.0], # 迭代19卡②——bcard 选项卡名(与商店货架同构卡) - ["迷雾·记忆墨/灰罩合成底", UiKit.FOG_MEMORY_INK, # 迭代19卡②——fog_state2 记忆板 α.66 压 floor avg #453020 - Color(UiKit.FOG_MEMORY_PLATE.r * 0.66 + 69.0 / 255.0 * 0.34, # 合成底(素材侧值无常量形态——取 art-bible §389 迭代16 T0 在册复算值,素材换装随批更新; + # 存量违例对首跑红=登记呈报不修(处置权归用户)。 + # 已回绿对:随代码侧换墨同步改指新常量(比率见各行尾注)。 + ["结算·判定墨/结算板", UiKit.INK_TITLE, UiKit.PANEL_DATA, 1.0], # battle_end 判定行(INK_TITLE 亮底标题墨) + ["结算·GP账行墨/结算板", UiKit.GOLD_INK, UiKit.PANEL_DATA, 1.0], # battle_end 战利品 GP 行名/值(深金墨 5.21:1) + ["结算·账行墨/结算板", UiKit.INK_LABEL, UiKit.PANEL_DATA, 1.0], # battle_end 钥石/加成账行(标签深墨) + ["商店·行卡名墨/暗底行卡", UiKit.WARM_SOFT, UiKit.BG_OVERLAY, 1.0], # legacy 行卡商品名(显式传暖白次级 9.53:1) + ["商店·行卡现价墨/暗底行卡", UiKit.WARM_SOFT, UiKit.BG_OVERLAY, 1.0],# legacy 行卡「现价 N GP」 + ["商店·行卡已购墨/暗底行卡", UiKit.WARM_FAINT, UiKit.BG_OVERLAY, 1.0],# legacy 行卡「已购 N 档」 + ["商店·爬价规则墨/暖亮页底", UiKit.WARM_SOFT, UiKit.BG_BRIGHT, 1.0],# 货架面爬价规则行(page_shell 亮底) + ["商店·货架卡名墨/货架板", UiKit.INK_TITLE, UiKit.PANEL_DATA, 1.0], # bcard 货架卡商品名(换 TG 带后未机检位) + ["商店·货架价签墨/货架板", UiKit.GOLD_INK, UiKit.PANEL_DATA, 1.0], # bcard 价签「N ◈」(深金墨 5.21:1) + ["营地·等级章字/头带深棕", UiKit.INK_ON_DEEP, UiKit.CAMP_HEADER_BAND, 1.0],# 锻造行 Lv 章(木底小章亮墨) + ["营地·柜台头带字/头带深棕", UiKit.WARM, UiKit.CAMP_HEADER_BAND, 1.0], # 三柜台头带标题(暖白 bold) + ["营地·铭牌副题墨/铭牌板", UiKit.STONE_DEEP, UiKit.PANEL_DATA, 1.0],# 营地铭牌副题「跨局成长账本…」(灰石深化 5.98:1) + ["营地·行名墨/行板", UiKit.INK, UiKit.CAMP_ROW_PLATE, 1.0], # 锻造/工坊行名(墨族压暖米行板) + ["营地·行价格墨/行板", UiKit.STONE_DEEP, UiKit.CAMP_ROW_PLATE, 1.0],# 锻造行「N 钥石」价签/工坊进度行(灰石深化 6.70:1) + ["营地·树分组头墨/柜台板", UiKit.GOLD_INK, UiKit.PANEL_DATA, 1.0],# 天赋树脉分组头「·锻造脉·」(深金墨 5.21:1) + ["营地·树行名墨/柜台板", UiKit.INK_LABEL, UiKit.PANEL_DATA, 1.0], # 天赋树行「名 Lv0/1」(标签深墨) + ["营地·工坊状态墨/行板", UiKit.GOLD_INK, UiKit.CAMP_ROW_PLATE, 1.0],# 工坊状态字「已解锁」(深金墨 5.84:1·最不利现役态) + ["营地·最近冒险墨/暖亮底", UiKit.WARM_SOFT, UiKit.BG_BRIGHT, 1.0], # 底栏最近冒险条带(暖白次级) + ["设置·警示文/设置板", UiKit.INK_HINT, UiKit.PANEL_DATA, 1.0], # 设置警示文/后果说明(暖棕提示墨) + ["设置·选项标签/设置板", UiKit.INK_LABEL, UiKit.PANEL_DATA, 1.0], # 设置行标签/状态字(标签深墨) + ["三选一·停点头部墨/暗页底", UiKit.WARM_SOFT, UiKit.BG_ROOT, 1.0], # 三选一停点头部/回血反馈行(page_shell 根底档) + ["三选一·卡名墨/货架板", UiKit.INK_TITLE, UiKit.PANEL_DATA, 1.0], # bcard 选项卡名(与商店货架同构卡) + ["迷雾·记忆墨/灰罩合成底", UiKit.FOG_MEMORY_INK, # fog_state2 记忆板 α.66 压 floor avg #453020 + Color(UiKit.FOG_MEMORY_PLATE.r * 0.66 + 69.0 / 255.0 * 0.34, # 合成底(素材侧值无常量形态——取 art-bible §389 在册复算值,素材更新随动; UiKit.FOG_MEMORY_PLATE.g * 0.66 + 48.0 / 255.0 * 0.34, # 三关逐关 avg 缺在册且素材不入 git 不可实查——最坏情况判据扩对归移交) UiKit.FOG_MEMORY_PLATE.b * 0.66 + 32.0 / 255.0 * 0.34), 1.0], ] diff --git a/game/smoke/ui_input_probe.gd b/game/smoke/ui_input_probe.gd index aa149238..2c4fc76a 100644 --- a/game/smoke/ui_input_probe.gd +++ b/game/smoke/ui_input_probe.gd @@ -1,11 +1,11 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# push_input 端到端输入探针(2026-09-12 场景结构批登记项转义务、 -# Node2D 迁移批 Risks 缓解面)。现役探针全走 BoardView.click_cell 直调(合成鼠标事件零命中已实证)—— +# push_input 端到端输入探针(场景结构登记项转义务 + Node2D 呈现层 Risks 缓解面)。 +# 现役探针全走 BoardView.click_cell 直调(合成鼠标事件零命中已实证)—— # 本探针是真实输入路径的唯一自动化覆盖:鼠标事件 → 壳层 _gui_input → 板级公式换算(_cell_at)→ # 悬停/点选/chord 既有出口 → 组合根信号。四 case:①悬停可挖域(金框+十字光标)②悬停禁入 # (hover_forbidden 信号+灰禁红框)③悬停已开格(路径预览点迹+移动光标)④右键封印(seal_place # 到达组合根+核心封印态)⑤双击 chord(禁入格双左击,核心拒挖零副作用)⑥左键挖(dig 到达组合根+核心揭格) -# ⑦英雄精灵世界落位(棋盘小人贴图批回归闸——SubViewport 世界坐标判据,素材缺位树跳过) +# ⑦英雄精灵世界落位(回归闸——SubViewport 世界坐标判据,素材缺位树跳过) # ⑧影子构成与贴脚 ⑨右移朝向+到位回站帧+缩放档 ⑩变格边长即时重排 ⑪贴图缺位回退字形 #(⑧–⑪=Node2D 展示几何/状态面单元化断言)。 # 事件路径:Viewport.push_input(ev, in_local_coords=true)——落点用 BoardView.cell_center_local @@ -27,14 +27,14 @@ func _ready() -> void: main = load("res://presentation/main.tscn").instantiate() add_child(main) await get_tree().process_frame - # 存档隔离(迭代 8 卡①②——断点写盘面随冒险挂 main.save_manager;探针禁碰真实档 user://save.json, + # 存档隔离(断点写盘面随冒险挂 main.save_manager;探针禁碰真实档 user://save.json, # 同 ui_click_probe 隔离纪律。首次冒险布尔位置位=对齐真实档游玩史口径,模板抽签路径不变; # isolate_save 先删后建——上次运行的残留断点会触发互斥确认早退) ProbeUiUtil.isolate_save(main, "smoke_input_probe_save", true, false, true) - main.debug_overlay.seed_edit.text = "42" # 种子钉死(迭代 18 卡⑦审计🔴——种子框默认改空后空框=非首局随机,探针确定性禁依赖默认分支) + main.debug_overlay.seed_edit.text = "42" # 种子钉死(种子框默认为空=非首局随机,探针确定性禁依赖默认分支) main._start_adventure_from_menu() await get_tree().process_frame - # ---- ⑫ 图上命中真实输入(关卡画面实装批 2026-09-28 回归闸):入口停点候选节点中心 + # ---- ⑫ 图上命中真实输入(回归闸):入口停点候选节点中心 # push_input 真实鼠标路径 motion+click → 悬停预承诺置位 → route_chosen 到达组合根。 # 由来=真机 bug:深层节点(L1 Boss 内容 x=802)在固定画布命中区外,press_candidate 直调 # 命中函数探针全绿、真鼠标点不中——本 case 封住输入管线,⑬封住几何拟合。 @@ -129,7 +129,7 @@ func _ready() -> void: _pre_fail("先导移动未到达(actions=%s hero=%s→%s)" % [str(_actions), hero0, ms.hero_pos()]) return # ---- 目标格实证选取(不写死坐标;两枚相邻可挖格 + 禁入格 + 已开格)---- - # 并流批(2026-09-27 统一流裁决)后首战板面种子随全局序漂移——_diggable(主角 8 邻未开域) + # 首战板面种子随全局序漂移——_diggable(主角 8 邻未开域) # 不足两枚时,沿已开区真点击移位到「≥2 未开邻」的前沿格再选;移位失败即收手交由选取失败分支报状态 for _expand in range(16): if bv.diggable_probe().size() >= 2: @@ -207,8 +207,8 @@ func _ready() -> void: await get_tree().process_frame if not ms.has_seal(seal_t): _problems.append("case④ 核心封印态未落位") - # ---- case④b 封印纹理槽回归断言(P0-1 修复批 2026-10-02):T13 批曾在 paint 尾部无条件 - # `u.tex_seal = null` 覆盖 T17 批的条件赋值=素材在位时封印不可见(headless 缺盘走字形回退 + # ---- case④b 封印纹理槽回归断言(P0-1):paint 尾部若无条件 + # `u.tex_seal = null` 会覆盖条件赋值=素材在位时封印不可见(headless 缺盘走字形回退 # 掩盖)——有盘断言纹理在槽、缺盘断言字形回退,两分支防双写踩踏复活 ---- var seal_unit = bv.cells_probe().get(seal_t) if bv._seal_tex != null: @@ -230,7 +230,7 @@ func _ready() -> void: await get_tree().process_frame if not ms.is_revealed(dig_t): _problems.append("case⑥ 核心揭格未落位(目标=%s)" % dig_t) - # ---- case⑦ 英雄精灵世界落位(棋盘小人贴图批回归闸 2026-09-26):精灵在 SubViewport 世界内, + # ---- case⑦ 英雄精灵世界落位(回归闸):精灵在 SubViewport 世界内, # 落位 = 格×步距 + 脚底锚(横=格中线/纵=格底往上 25% 线=HERO_GROUND_FRAC 自底边口径——「脚踩 # 格子 1/4 处·从下往上数」;禁带壳层 _svp_container.position 居中偏移——上批误用壳层 # cell_origin 实测右偏 ~7 格+偏离格心,实机截图用户报缺陷)。素材缺位树(hero==null,字形 @@ -242,8 +242,8 @@ func _ready() -> void: + Vector2(bv.cell_size * 0.5, bv.cell_size * (1.0 - bv.HERO_GROUND_FRAC)) if bv._world.hero.position.distance_to(expect) > 0.5: _problems.append("case⑦ 英雄精灵世界落位偏移 pos=%s expect=%s" % [str(bv._world.hero.position), str(expect)]) - # ---- case⑧ 影子构成与贴脚(小人立体感批回归闸 2026-09-26):椭圆影=英雄子件、中心贴脚锚 - #(上批 (0,2) 下坠脱脚用户报缺陷)、z 相对回落格面之上英雄之下、黑色半透明、渐变纹理组件 + # ---- case⑧ 影子构成与贴脚(回归闸):椭圆影=英雄子件、中心贴脚锚 + #((0,2) 下坠脱脚=用户报缺陷)、z 相对回落格面之上英雄之下、黑色半透明、渐变纹理组件 # 合成;父子 use_parent_material 双挂(结算期随世界去饱和与格面同口径)。 ---- if bv._world.hero != null: var kids: Array = bv._world.hero.get_children() @@ -261,7 +261,7 @@ func _ready() -> void: _problems.append("case⑧ 影子纹理非径向渐变组件(%s)" % str(sh.texture)) if not sh.use_parent_material or not bv._world.hero.use_parent_material: _problems.append("case⑧ 去饱和材质链漏挂(shadow=%s hero=%s)" % [str(sh.use_parent_material), str(bv._world.hero.use_parent_material)]) - # ---- case⑨ 右移朝向+到位回站帧+缩放档(贴图批回归闸):素材基准朝左——向右移动 flip_h=true; + # ---- case⑨ 右移朝向+到位回站帧+缩放档(回归闸):素材基准朝左——向右移动 flip_h=true; # 到位(0.3s 墙钟 > 位移 Tween 140ms)纹理回站帧、scale 恒 1.5 均匀档。无可达右邻已开格跳过。 ---- if bv._world.hero != null: var hp9: Vector2i = ms.hero_pos() @@ -312,7 +312,7 @@ func _ready() -> void: _problems.append("case⑪ 缺位态数字格字形被破坏(glyph=%s 应=%d)" % [u11.glyph, digit11]) bv._hero_tex_idle = tex_saved bv.refresh() - # ---- case⑭ 变异角标(迭代 6 T6——flat_damage 未开格视觉标记;resolver 注入面+落位+复位) ---- + # ---- case⑭ 变异角标(flat_damage 未开格视觉标记;resolver 注入面+落位+复位) ---- var mark_t: Vector2i = _pick_forbidden(bv, ms) # 任一未开格(禁入=未开非相邻) if mark_t.x >= 0: bv.set_variant_mark_resolver(func(_c): return "flat_damage") @@ -325,7 +325,7 @@ func _ready() -> void: _problems.append("case⑭ 角标未随 resolver 复位(mutation_mark=%s)" % str(bv.cells_probe()[mark_t].mutation_mark)) else: _problems.append("case⑭ 无未开格可验(板面异常)") - # ---- case⑮ 视野迷雾(迭代 11 第④批 T5——三态呈态/半径圈/移动跟随/开关两态零扰动/提灯插值位; + # ---- case⑮ 视野迷雾(三态呈态/半径圈/移动跟随/开关两态零扰动/提灯插值位; # 纯呈现零逻辑——迷雾开关切换前后 minesweeper 状态摘要逐位一致) ---- var fogp: Dictionary = bv.fog_params_probe() if int(bv.FOG_RADIUS) != 8 or int(fogp["lantern"]) != 0 or not fogp["enabled"]: @@ -392,9 +392,8 @@ func _ready() -> void: if int(bv.cells_probe()[Vector2i(0, 0)].fog_state) == 0 \ and absi(0 - hero15.x) + absi(0 - hero15.y) > int(bv.FOG_RADIUS): _problems.append("case⑮ 迷雾复开后远角未复原遮蔽(fog_state=0)") - # 视野加成接线断言(迭代 22 秘宝批 T4 换代——旧提灯 +2 主语随 fog_lantern 行退役; - # 新主语=阔视野带参数注入 set_fog_glow_bonus(4) → 半径 8+4:dist==R+1 格由雾态转可见, - # 卸装复原 lantern=0;纯接线零逻辑——半径算式迷雾批已在位) + # 视野加成接线断言(主语=阔视野带:参数注入 set_fog_glow_bonus(4) → 半径 8+4: + # dist==R+1 格由雾态转可见,卸装复原 bonus=0;纯接线零逻辑——半径算式归迷雾断言面) var ring_cell := Vector2i(-99, -99) for y in b15.height: for x in b15.width: @@ -417,7 +416,7 @@ func _ready() -> void: _problems.append("case⑮ 视野加成清零后雾参数未复原(lantern 应=0)") if int(bv.cells_probe()[ring_cell].fog_state) == 0: _problems.append("case⑮ 视野加成清零后 dist==R+1 格未复原遮蔽") - # 装配链级断言(迭代 22 秘宝批 T4 换代——wide_scout_band 装配链贯通:①装配→开局参数面 + # 装配链级断言(wide_scout_band 装配链贯通:①装配→开局参数面 # 〔build_adventure_params 统一构造〕②装配集→呈现桥〔_sync_treasure_glow 消费 # attune_param_sum 只读出口→set_fog_glow_bonus〕→视野 +4 生效与卸装复原。 # settlement.attunement 手动注入=模拟 begin_battle enc 注入后的运行态〔注入面本体归 @@ -439,7 +438,7 @@ func _ready() -> void: if int(bv.cells_probe()[ring_cell].fog_state) == 0: _problems.append("case⑮ 卸装后 dist==R+1 格未复原遮蔽") main.save_manager.set_attunement_equipped([]) - # ---- case⑯ 状态面板输入锁语义(迭代 17 卡③ R3——开层锁棋盘、关层恢复无残留;真实 push_input + # ---- case⑯ 状态面板输入锁语义(R3——开层锁棋盘、关层恢复无残留;真实 push_input # 路径:入口角标本体 press+release 真点击 → 状态面板开;锁期挖掘点击零穿透;「继续」关层后 # 同格挖掘重新到达——锁语义与既有模态同款,无状态残留。置于全 case 之尾:取格若需前沿移位 #(真实点击 move 扩大可挖域),其板面扰动不再波及任何既有断言——域恰 2 枚时 seal_t 带封印+ @@ -492,7 +491,7 @@ func _ready() -> void: await get_tree().process_frame if not _has_action(status_dig, "dig") or not ms.is_revealed(status_dig): _problems.append("case⑯ 关闭后挖掘未到达(恢复无残留验证失守)") - # ---- case⑰ 未开格类型微光(迭代 30 卡① T2-③——活板面走查:作用集恒等/开格灭/移动复亮 + # ---- case⑰ 未开格类型微光(活板面走查:作用集恒等/开格灭/移动复亮 # 与出圈灭/相位门控/开关两态零扰动。与冒烟段数据面断言分工:此处走真实点击路径) ---- if not bool(bv.type_glow_probe().get("enabled", false)): _problems.append("case⑰ 微光默认态非开(生产默认开——Q4 丙案)") diff --git a/game/smoke/ui_probe.gd b/game/smoke/ui_probe.gd index 1fa5dbe7..c5644303 100644 --- a/game/smoke/ui_probe.gd +++ b/game/smoke/ui_probe.gd @@ -1,6 +1,5 @@ # VERTICAL SLICE - NOT FOR PRODUCTION # 实现 GDD:design/ux/battle.md(场景级 headless 探针——四区布局实例化断言;entry 17②③)。 -# Date: 2026-09-12 # 项目运行模式(autoload 在位)实例化 main.tscn,直接驱动 _start_adventure_from_menu()(完整冒险——唯一试玩入口), # 断言真实构建(棋盘/主角站桩/敌方站桩/AP 点阵/明细带/数据框;无 A 区进度条断言与 E 区道具面板; # 英雄/敌人 = 站桩断言)。 @@ -16,12 +15,12 @@ func _ready() -> void: add_child(main) await get_tree().process_frame var problems: Array = [] - # ---- 放弃入口(2026-09-21 用户拍板——台账 119):默认隐藏(非冒险模式无冒险可放弃——开始层/调试两层)---- + # ---- 放弃入口(台账 119):默认隐藏(非冒险模式无冒险可放弃——开始层/调试两层)---- if main.level_screen.abandon_btn == null or main.level_screen.abandon_btn.visible: print("[ui_probe] FAIL — 放弃按钮默认应隐藏(非冒险模式关)") get_tree().quit(1) return - # ---- 营地覆盖层(元进度实现批——主菜单入口/开合/余额文案/购买禁用态; + # ---- 营地覆盖层(主菜单入口/开合/余额文案/购买禁用态; # 隔离存档换注 main.meta 保确定性(禁碰真实档 user://save.json——SaveManager 路径注入纪律; # 营地先行段只换 meta 不换 save_manager——冒险段换注零档在前)---- ProbeUiUtil.isolate_save(main, "smoke_ui_probe_camp", false, false, false, false) @@ -56,13 +55,13 @@ func _ready() -> void: problems.append("营地关闭后未恢复开始层(开合往返失守)") # 换回全新零档(营地段购买态不泄入后续冒险段——确定性;先删后建防陈旧档泄入) ProbeUiUtil.isolate_save(main, "smoke_ui_probe_camp", true, false, true) - main.debug_overlay.seed_edit.text = "42" # 种子钉死(迭代 18 卡⑦——种子框默认改空后空框=非首局随机;本探针 start_single 第五路同吃此框,确定性禁依赖默认分支) + main.debug_overlay.seed_edit.text = "42" # 种子钉死(种子框默认为空=非首局随机;本探针 start_single 第五路同吃此框,确定性禁依赖默认分支) main._start_adventure_from_menu() await get_tree().process_frame await get_tree().process_frame - # ---- 入口选路停点(停点前移批 2026-09-23:关卡开始即出节点图——level_started 后、首战前弹选路层; - # press_candidate 图上命中路径 pick 入口单候选进首战——候选按钮退役 2026-09-28)---- - # ---- 独立性断言(形态升格批 2026-09-28:独立屏激活期战斗屏宿主整体隐藏,零透出)---- + # ---- 入口选路停点(关卡开始即出节点图——level_started 后、首战前弹选路层; + # press_candidate 图上命中路径 pick 入口单候选进首战)---- + # ---- 独立性断言(独立屏激活期战斗屏宿主整体隐藏,零透出)---- if not main.level_screen.visible: problems.append("关卡开始未弹入口选路停点(level_screen 应可见)") elif main._battle_root.visible: @@ -84,7 +83,7 @@ func _ready() -> void: await get_tree().process_frame if main.run_scope.adventure == null or String(main.run_scope.adventure.state) != "running": problems.append("首战中放弃未被拒(战斗域单事务在飞——state 应保持 running)") - # ---- 既有断言(回归基线;A 区进度条断言随 停点前移批 2026-09-23 退役——节点链进度由关卡画面独立屏承载)---- + # ---- 既有断言(回归基线;A 区无进度条——节点链进度由关卡画面独立屏承载)---- if main.board_view.cells_probe().is_empty(): problems.append("棋盘格未生成(cells=0)") if main.board_view.board() == null: @@ -115,10 +114,10 @@ func _ready() -> void: if main._row_queue.is_empty() \ and (main.log_view.mode() != "dig" or main.log_view.custom_minimum_size.y != 24.0): problems.append("B 区明细带挖掘期应收起 24px(mode=%s h=%s)" % [main.log_view.mode(), str(main.log_view.custom_minimum_size.y)]) - # E 区道具面板已随可选类删除下线(格面资源批 2026-09-15)——四区构建由其余断言覆盖 + # E 区无道具面板——四区构建由其余断言覆盖 - # ---- 敌方站桩投影(顺位徽标/意图三档动作动画占位——敌人系统×4;2026-09-20 全站桩拍板)---- - # B 区站桩 Node2D 迁移批 T3(2026-09-26)断言等价改写(台账 171 改判记录):enemy_box 子件 + # ---- 敌方站桩投影(顺位徽标/意图三档动作动画占位——敌人系统×4,全站桩)---- + # B 区站桩子件伴随件化(壳层 tooltip 载体)——断言口径见台账 171: # 伴随件化(壳层 tooltip 载体),穿透明(子件 _name_label/_armor_icon/_intent_badge)改本体 # 探针出口 stage.enemy_body_at(i).name_line_probe()/intent_probe()——呈现口径逐字保持 var standee = main.stage.enemy_body_at(0) @@ -128,7 +127,7 @@ func _ready() -> void: var name_line: Dictionary = standee.name_line_probe() if String(name_line.name) == "" or String(name_line.armor_icon) == "": problems.append("敌立绘名字行缺失(名字或护甲类型图标占位为空——2026-09-26 终裁:AC 不展示、类型图标化)") - # 三档动作动画占位契约(表现层升级批拍板:不显示技能名——图标档位 + 一次性动画) + # 三档动作动画占位契约(不显示技能名——图标档位 + 一次性动画) standee.set_pending("damage", "") var intent_on: Dictionary = standee.intent_probe() if not bool(intent_on.visible) or String(intent_on.text) != "⚔": @@ -136,7 +135,7 @@ func _ready() -> void: standee.set_pending("basic", "") if bool(standee.intent_probe().visible): problems.append("普攻应零表示(意图指示应隐藏)") - # 站桩纹理非空断言(迭代 6 T2——八敌真图落位;缺位回退链保持的对照面) + # 站桩纹理非空断言(八敌真图落位;缺位回退链保持的对照面) if not bool(standee.portrait_probe().get("has_tex", false)): problems.append("敌立绘纹理未落位(素材管线 48px 档——迭代 6 T2;缺位回退链不应在此态触发)") if main.stage.hero_standee == null or not main.stage.hero_standee.has_world_hp_bar: @@ -166,8 +165,8 @@ func _ready() -> void: slots_row.set_effects([]) if not slots_row._slots.is_empty(): problems.append("BUG-0001 回归:空态未清槽(%d)" % slots_row._slots.size()) - # ---- 图标键回归(HUD框架 图标键契约:状态表九行全映射〔定稿 PNG 纹理,2026-09-24 状态图标接入批〕、 - # 格面资源 cell_type 九型全映射〔gp 键 = 九型批 2026-09-20〕;查不到的键 fail-fast + ? 占位 + # ---- 图标键回归(HUD框架 图标键契约:状态表九行全映射〔定稿 PNG 纹理〕、 + # 格面资源 cell_type 九型全映射〔含 gp 键〕;查不到的键 fail-fast + ? 占位 # ——此处钉死映射不残缺,未知键断言由 _icon_tex/_badge_glyph 承担)---- for eid in ["attack_up", "ac_up", "alert", "weaken", "enrage", "off_guard", "sapped", "empower", "fortify"]: if not StatusSlotRow.EFFECT_ICON.has(eid) or StatusSlotRow.EFFECT_ICON[eid] == null: @@ -191,8 +190,8 @@ func _ready() -> void: problems.append("失衡图标键未映射(texture=null)") slots_row.set_effects([]) # ---- L2 单场段(debug_session 单场原语 + 去饱和接口可用性;雾格机制已整体移除,不再断言变体呈现)---- - # 2026-09-13 单场用户入口已删——探针直调 debug_session 原语(battle_created/ready 仍经组合根接线; - # _reset_run_scope 复现原 _start_single 的提示去重复位) + # 单场无用户入口——探针直调 debug_session 原语(battle_created/ready 仍经组合根接线; + # _reset_run_scope 复现 _start_single 的提示去重复位) main._begin_session(false) main._debug.start_single(2) await get_tree().process_frame @@ -200,7 +199,7 @@ func _ready() -> void: if main.board_view.board() == null: problems.append("L2 单场未启动(board=null)") else: - # 地形变异 首批类型定稿批(2026-09-19):L2 板允许带变异(岩浆/烬覆)——布置域断言 = + # 地形变异:L2 板允许带变异(岩浆/烬覆)——布置域断言 = # 变异格全在初始展开区外(closed_only 结构保障) var b0 = main.board_view.board() var r0p := {} @@ -212,8 +211,8 @@ func _ready() -> void: break main.board_view.set_desaturated(true) main.board_view.set_desaturated(false) - # ---- GP 终局行(迭代 6 T7 卡⑩):summary gp_final 键取数+胜利面板 GP 行呈现(C5:GP 行只上冒险终局面板; - # 迭代 27 T3——影子账随批退役,原清零转存断言换代为 summary 键断言)---- + # ---- GP 终局行:summary gp_final 键取数+胜利面板 GP 行呈现(C5:GP 行只上冒险终局面板; + # 断言面 = summary 键,无影子账清零转存)---- # (置于战斗态断言之后——合成收束会灰化站桩并清 settlement 引用,具污染性) var meta_saved = main.meta.save for p2 in ["user://smoke_ui_probe_settle_scratch.json", "user://smoke_ui_probe_settle_scratch.json.tmp"]: diff --git a/game/smoke/ui_struct_probe.gd b/game/smoke/ui_struct_probe.gd index 9eff9bbf..16ff114b 100644 --- a/game/smoke/ui_struct_probe.gd +++ b/game/smoke/ui_struct_probe.gd @@ -48,9 +48,9 @@ func _ready() -> void: else: problems.append("[camp] 营地入口按钮缺失(驱动中断)") - # ---- 生涯页(迭代 18 卡④):入口点击链(合成点击真路径=pressed.emit→组合根 _open_career)→ + # ---- 生涯页:入口点击链(合成点击真路径=pressed.emit→组合根 _open_career)→ # 结构断言族→只读巡检(契约 3)+零动效契约+零跳转契约(提纲 P4 甲)→组合根真实路径关闭。 - #(登记序/树序契约已推广为全模态 _modal_registry_contract——boot 段统一跑,生涯专属件同批退役)---- + #(登记序/树序契约统一在全模态 _modal_registry_contract——boot 段跑)---- var careerbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "生涯", "prefix") if careerbtn != null: careerbtn.pressed.emit() @@ -82,7 +82,7 @@ func _ready() -> void: # ---- 冒险簇(真流推进:开冒险→地图选路态→选战斗节点→战斗 HUD)---- ProbeUiUtil.isolate_save(main, "smoke_ui_struct_probe_adv", true, false, true) - main.debug_overlay.seed_edit.text = "42" # 种子钉死(迭代 18 卡⑦——种子框默认改空后空框=非首局随机,结构采样确定性禁依赖默认分支) + main.debug_overlay.seed_edit.text = "42" # 种子钉死(种子框默认为空=非首局随机,结构采样确定性禁依赖默认分支) main._start_adventure_from_menu() _settle(4) await _audit("level_map", [main.level_screen]) @@ -93,7 +93,7 @@ func _ready() -> void: _settle(6) _audit("battle_hud", [main.board_zone, main.info_panel, main.stage]) _standeefit_contract(main) - # ---- 状态面板(迭代 17 卡③):组合根真实路径开层→结构断言→关闭。附只读性契约 + # ---- 状态面板:组合根真实路径开层→结构断言→关闭。附只读性契约 #(R4——子树信号连接白名单巡检)与零动效契约(R5/P4 甲——零 AnimationPlayer/零 tween)。 # 巡检信号名清单=子树全控件的 get_signal_list() 全集(不放行任何未列名信号——新连接 # 一律红,须先入册审查);白名单={视图自身 _emit_closed, 组合根 _on_status_closed}。 @@ -107,7 +107,7 @@ func _ready() -> void: if main.status_panel.visible: problems.append("[status] 关闭后层未隐藏(模态栈单口失守)") - # ---- 图例层(迭代 19 卡②——两枚从未过结构族的旧模态之一):ap_bar legend_toggled + # ---- 图例层(旧模态、首过结构族):ap_bar legend_toggled # 信号真路径开(board_zone 信号→组合根 _on_legend_toggled→_open_modal)→结构断言族→ # closed 信号真路径关(close()→组合根 _on_modal_closed)。 main.board_zone.legend_toggled.emit() @@ -129,7 +129,7 @@ func _ready() -> void: main._end_overlay.close() _settle() - # ---- 节点结算层(迭代 19 卡②——两枚从未过结构族的旧模态之二):rest 兑付真路径开 + # ---- 节点结算层(旧模态、首过结构族):rest 兑付真路径开 #(组合根 _open_modal 登记册+show_rest 合成喂入)→结构断言族→continue_pressed 信号真路径关 #(press_continue→组合根 _on_node_continue→_close_modal)。 main._open_modal(main.node_overlay) @@ -160,7 +160,7 @@ func _ready() -> void: _settle() await _audit("shop", [main.shop_overlay]) - # ---- ⑦resume 专项:续玩停点恢复(2026-10-06 用户实机 main.gd:717 报错回归闸)---- + # ---- ⑦resume 专项:续玩停点恢复(main.gd:717 报错回归闸)---- # 三选一停点续玩分支在 level_started 之前同步 curio_choice_presented.emit(adventure_runner # resume 提前 return)——GP 总结 lambda 求值时 runner 尚未赋值,修复前 717 炸 null。 ProbeUiUtil.isolate_save(main, "smoke_ui_struct_probe_resume", true) @@ -225,7 +225,7 @@ func _pick_battle_node(main: Node) -> int: return -1 -# ⑧status 只读性契约(迭代 17 卡③ R4):状态面板子树全控件 × 游戏语义信号连接巡检——清单外零连接。 +# ⑧status 只读性契约(R4):状态面板子树全控件 × 游戏语义信号连接巡检——清单外零连接。 # 巡检信号名清单(需求卡片 v1.1「巡检信号名清单落码时列全进探针」)= 玩家交互可携带写意图的通道 # 全集(按钮按下/拨杆/文本/滑值/选项/键盘焦点)+ 本层外发信号 closed;引擎内部布局生命线信号 # 不计(child_order_changed/item_rect_changed/visibility_changed/size_flags_changed/ @@ -263,7 +263,7 @@ func _status_readonly_contract(main: Node) -> void: problems.append("[status][readonly] 信号连接数=%d 应=2(关闭钮 pressed+closed 外发——多连接=写通路嫌疑)" % conn_count) -# ⑨status 零动效契约(迭代 17 卡③ R5/P4 甲——零动效直开直关路径存在断言): +# ⑨status 零动效契约(R5/P4 甲——零动效直开直关路径存在断言): # 子树零 AnimationPlayer + 视图源码零 tween/动效包装调用(源码 token 扫描=ui_contrast 静态段同手法) func _status_zero_motion_contract(main: Node) -> void: var overlay: Control = main.status_panel @@ -280,7 +280,7 @@ func _status_zero_motion_contract(main: Node) -> void: problems.append("[status][motion] 视图源码含「%s」(R5 零动效直开直关破——P4 甲)" % token) -# ---- 生涯页契约族(迭代 18 卡④——需求卡片契约 3/4+提纲 P3/P4 甲)---- +# ---- 生涯页契约族(需求卡片契约 3/4+提纲 P3/P4 甲)---- # ⑩career 只读性契约(契约 3——状态面板 ⑧ 同形制):生涯页子树全控件 × 游戏语义信号连接巡检—— # 清单外零连接。白名单={视图自身 _emit_closed〔返回钮〕, 组合根 _on_career_closed};页内任何 @@ -325,11 +325,11 @@ func _career_zero_motion_contract(main: Node) -> void: problems.append("[career][motion] 视图源码含「%s」(零动效直开直关破)" % token) -# ⑫模态登记/树序全量合同(装配生命批 V1——原 career 专属登记序契约推广到全部模态+屏壳; +# ⑫模态登记/树序全量合同(V1——career 专属登记序契约推广到全部模态+屏壳; # 判据=main.LAYER_CONTRACT 单一事实源:登记册序==合同模态序、直接子层树序==合同序逐对相等。 # 两特例按合同数据表达:level_screen 宿住冒险屏壳(树序随宿主=全模态之下,遮挡语义归模态栈 # screen_state 登记)、camp_overlay 成员与 camp_screen 屏壳同槽(屏壳树序代言成员登记位)。 -# 旧 _career_registry_contract 的断言(career=状态面板后/确认弹窗前、树序同步)被本全量合同覆盖,同批退役) +# _career_registry_contract 的断言(career=状态面板后/确认弹窗前、树序同步)由本全量合同覆盖) func _modal_registry_contract(main: Node) -> void: var list: Array = main._modals._list # ① 登记册序==合同模态序(逐位点名——合同是登记序唯一事实源) @@ -385,7 +385,7 @@ func _career_nojump_contract(main: Node) -> void: # ⑥standee 专项:B 区站桩内容矩形 ⊆ 252px 舞台矩形(内缩 8px)且不被裁切 -# (UI 设计对齐批 N2 2026-10-06——名行基线离盒底 1px 同型高危写法返修回归闸; +# (名行基线离盒底 1px 同型高危写法返修回归闸; # 内容矩形=StandeeBody.content_rect(),最低绘制元素=底座下缘) func _standeefit_contract(main: Node) -> void: var st: Node = main.stage @@ -496,7 +496,7 @@ func _audit(screen: String, roots: Array) -> void: var b: Control = all_buttons[j] if _wl(screen, "overlap", a) or _wl(screen, "overlap", b): continue - # 滚动区跨界豁免(迭代 18 卡⑦——当局数据区块加高列表后实证:恰好一枚在 ScrollContainer + # 滚动区跨界豁免(实证:当局数据区块加高列表后,恰好一枚在 ScrollContainer # 内时,其未剪裁内容矩形与滚区外控件的全局矩形交叠是滚动态样貌非布局缺陷; # 同滚区两钮仍查——同一容器 stacking 真重叠照红) if _in_scroll(a) != _in_scroll(b): @@ -505,7 +505,7 @@ func _audit(screen: String, roots: Array) -> void: problems.append("[%s][overlap] %s 与 %s 矩形相交(%s ∩ %s)" % [ screen, a.name, b.name, a.get_global_rect(), b.get_global_rect()]) # ②equal_width + equal_height:同一直接父容器内 ≥2 可见按钮宽度/高度差 >1px - #(钮高族 2026-10-06 用户令「对齐好、不要细」——主钮 26px 对常规 38px 不齐回归闸;纪律=ui_kit BUTTON_MIN_H) + #(钮高族判据「对齐好、不要细」——主钮 26px 对常规 38px 不齐回归闸;纪律=ui_kit BUTTON_MIN_H) var groups := {} for b in all_buttons: var k: Node = b.get_parent() diff --git a/game/smoke/ui_tune_probe.gd b/game/smoke/ui_tune_probe.gd index a51837af..62575e88 100644 --- a/game/smoke/ui_tune_probe.gd +++ b/game/smoke/ui_tune_probe.gd @@ -1,5 +1,5 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# Date: 2026-09-11(加成应用契约 = 组合根单一应用路径) +# 加成应用契约 = 组合根单一应用路径 # 调试浮窗场景探针(原数值调整板收进 debug_overlay; # 角标挂宿主 / 启动即开 / 当局数据只读区块 / 输入锁防护配套): # 驱动真实 UI 路径——①全局浮层角标开窗(UI 最顶层「调试」钮点击路径)+悬浮菜单之上+登记册末位树序 @@ -35,12 +35,12 @@ func _ready() -> void: add_child(main) await get_tree().process_frame var problems: Array = [] - # 基线读表(2026-09-18 随数值压缩批改表值驱动——旧字面量 6/50、12/75 已随 hero 表压缩失效) + # 基线读表(表值驱动——不写字面量) var base_atk := int(main.db.hero.atk) var base_hp := int(main.db.hero.max_hp) var boosted_atk := base_atk * 2 # 攻击滑条 100 → ×2 var boosted_hp := int(round(base_hp * 1.5)) # 生命滑条 50 → +50% - # ① 全局浮层角标开窗(2026-10-16 用户令:调试入口=UI 最顶层浮层,任何 UI 不遮挡—— + # ① 全局浮层角标开窗(调试入口=UI 最顶层浮层,任何 UI 不遮挡—— # main 直接子层、LAYER_CONTRACT 末位 float 类;boot 菜单优先不开浮窗,角标真实点击路径开窗; # 悬浮于菜单之上——开始层不隐藏;树序新基准=登记册末位(确认弹窗之后=绘制序最上)) main.debug_badge.pressed.emit() @@ -87,7 +87,7 @@ func _ready() -> void: problems.append("hero 表被运行时改写(E4 违例:atk=%s hp=%s,期望恒基线 %d/%d)" % [str(main.db.hero.atk), str(main.db.hero.max_hp), base_atk, base_hp]) # ⑧ 单次加成生效回归断言:应用加成 + 启动单场战斗 → 呈现快照 hero 必须是"基线 × 单次加成" # (攻击 ×2 / 生命 +50%)——旧缺陷(残留值被当基线再乘)在 encounter 参数链上同样被抓获 - # 存档隔离(迭代 8 卡①——停点断点写盘随 main.save_manager;探针禁碰真实档,同族探针隔离纪律; + # 存档隔离(停点断点写盘随 main.save_manager;探针禁碰真实档,同族探针隔离纪律; # isolate_save 先删后建——上次运行的残留断点会触发互斥确认早退) ProbeUiUtil.isolate_save(main, "smoke_tune_probe_save", true, false, false) main.debug_overlay.set_sliders(100, 50) @@ -101,7 +101,7 @@ func _ready() -> void: problems.append("开冒险路径未显式关浮窗(T2 防护失守)") if int(main.run_scope.adventure.master_seed) != 42: problems.append("显式种子未达冒险(master_seed=%s ≠ 42——真实路径显式优先失守)" % str(main.run_scope.adventure.master_seed)) - # 停点前移批 2026-09-23:关卡开始 = 入口选路停点——真实按钮路径选入口候选进首战再读呈现快照 + # 关卡开始 = 入口选路停点——真实按钮路径选入口候选进首战再读呈现快照 if main.level_screen.visible: main.level_screen.press_candidate(0) await get_tree().process_frame @@ -111,7 +111,7 @@ func _ready() -> void: problems.append("战斗加成单次生效违例(atk=%s max_hp=%s,期望 %d/%d)" % [ str(hero.get("atk", "?")), str(hero.get("max_hp", "?")), boosted_atk, boosted_hp]) # ⑨ 对局中可开(18卡⑦ P2 甲/T2 防护——S1+ 停机点回归闸):战斗屏角标真实信号路径开窗; - # 棋盘输入不锁、状态角标不置灰(旧 has_open 判据在「默认开×遮挡复活」下必锁死的破约回归面); + # 棋盘输入不锁、状态角标不置灰(「默认开×遮挡复活」下必锁死的破约回归面); # 对局中批量模拟/两层调试两钮禁用;当局数据六项与只读访问器逐项一致;关闭钮真实路径收窗恢复 var dbg_badge: Button = main.debug_badge if dbg_badge == null or not dbg_badge.visible: @@ -161,7 +161,7 @@ func _ready() -> void: main.debug_overlay.seed_edit.text = "777" if main._seed_value() != 777: problems.append("显式种子输入未优先(_seed_value != 777——C1 ①失守)") - # 迭代 27 T1——SaveManager 升格 autoload 后换注改原地 attach(首局态挂载+恢复隔离档); + # SaveManager 是 autoload 单例——换注走原地 attach(首局态挂载+恢复隔离档); # --script 模式无裸 autoload 标识符——经 main 节点路径解析 var sm = main.get_node("/root/SaveManager") sm.attach_path("user://smoke_tune_probe_seed.json") # 全新空档——first_adventure_done=false(首局态;新档缺省面) diff --git a/game/smoke/verifier_batch.gd b/game/smoke/verifier_batch.gd index 6096d913..065af3f5 100644 --- a/game/smoke/verifier_batch.gd +++ b/game/smoke/verifier_batch.gd @@ -1,5 +1,5 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# Date: 2026-09-22(判定端 tools/balance_verifier.py 的数据源,本文件零判定逻辑) +# 判定端 tools/balance_verifier.py 的数据源,本文件零判定逻辑 # 两段一次采集,stdout 以「VJSON 」前缀行出机器读 JSON(其余行为人读进度/摘要): # adventure 段 全冒险连探基线(run_adventure 零永久强化)× 双画像 × na——止步分布、败退节点 # (摘要 defeat 明细 + 末场战斗敌方名)与逐关条件通关率派生源;inject 档行带 @@ -19,8 +19,8 @@ # 绝不碰 user://save.json(与 smoke 存档隔离纪律同源)。 extends SceneTree -# 迭代 21 T5 换代——属性锻造柜台退役后花费策略主语=树脊柱两节点(钥石单币;攻/AC 无树来源 -# 〔契约 9——唯一入口=锻造工坊路线,本批未实装〕,原三轴序收敛两节点序) +# 花费策略主语=树脊柱两节点(钥石单币;攻/AC 无树来源 +# 〔契约 9——唯一入口=锻造工坊路线,未实装〕) const SPEND_ORDERS := { "hp_first": ["sp_hp", "sp_hit"], "atk_first": ["sp_hit", "sp_hp"], @@ -109,7 +109,7 @@ func _emit(row: Dictionary) -> void: # ---- adventure 段:全冒险连探基线(零永久强化——止步分布/败退节点归因/逐关条件通关率派生源); -# inject 档 = 同种子流配对的 OFAT 边际读数(换算率标定批——行带 inject_tag/override flat 三键) ---- +# inject 档 = 同种子流配对的 OFAT 边际读数(行带 inject_tag/override flat 三键) ---- func _seg_adventure(db, autoplay, logger, opt: Dictionary, counts: Dictionary) -> void: var ov: Dictionary = opt.override @@ -184,7 +184,7 @@ func _seg_campaign(db, autoplay, logger, opt: Dictionary, counts: Dictionary) -> # 花费策略(贪心——按优先序反复买当前可负担的最高优先项;树行门槛随买随涨自然外溢到次节点 -# ——迭代 21 T5 换代:购买原语 buy_forge→tree_buy,行门槛=节点等级轴) +# ——购买原语 tree_buy,行门槛=节点等级轴) func _spend(meta, policy_name: String) -> Array: var out: Array = [] var order: Array = SPEND_ORDERS.get(policy_name, SPEND_ORDERS["hp_first"]) diff --git a/game/tests/.gates/baseline.json b/game/tests/.gates/baseline.json index 4c091ca6..8adb2d9d 100644 --- a/game/tests/.gates/baseline.json +++ b/game/tests/.gates/baseline.json @@ -1,53 +1,57 @@ { - "note": "存量基线·首次自动生成;闸况变化时本脚本会判红,需人工确认后重生成;2026-10-17 人工确认重生成 06 条目:af94ce97 把 gdd_lint 记为存量红(01 篇 R5),该红已由 fcb8c3f8 补流程图消除,实测 --docs 域 06 exit=0,故基线改回绿。2026-10-18 新增闸件 08c 流水线闸(tools/pipeline_gate.py 注册上电),手工加入绿记录(roadmap 压缩批实测 --docs 域 exit=0),其余条目原样保留。", - "gates": { - "01 冒烟全量": { - "exit": "0", - "fp": "green" - }, - "02 单元套件": { - "exit": "0", - "fp": "green" - }, - "03 探针 --click": { - "exit": "0", - "fp": "green" - }, - "04 探针 --full": { - "exit": "0", - "fp": "green" - }, - "05 渲染闸": { - "exit": "0", - "fp": "green" - }, - "06 gdd_lint": { - "exit": "0", - "fp": "green" - }, - "07 doc_link": { - "exit": "0", - "fp": "green" - }, - "08 doc_term": { - "exit": "0", - "fp": "green" - }, - "08c 流水线闸": { - "exit": "0", - "fp": "green" - }, - "09 静态扫描": { - "exit": "1", - "fp": "4354b2aa72a7" - }, - "10 熵增闸": { - "exit": "0", - "fp": "green" - }, - "11 回放确定性对拍": { - "exit": "SKIP", - "fp": "skip" + "note": "存量基线·首次自动生成;闸况变化时本脚本会判红,需人工确认后重生成;2026-10-17 人工确认重生成 06 条目:af94ce97 把 gdd_lint 记为存量红(01 篇 R5),该红已由 fcb8c3f8 补流程图消除,实测 --docs 域 06 exit=0,故基线改回绿。2026-10-18 新增闸件 08c 流水线闸(tools/pipeline_gate.py 注册上电),手工加入绿记录(roadmap 压缩批实测 --docs 域 exit=0),其余条目原样保留。", + "gates": { + "01 冒烟全量": { + "exit": "0", + "fp": "green" + }, + "02 单元套件": { + "exit": "0", + "fp": "green" + }, + "03 探针 --click": { + "exit": "0", + "fp": "green" + }, + "04 探针 --full": { + "exit": "0", + "fp": "green" + }, + "05 渲染闸": { + "exit": "0", + "fp": "green" + }, + "06 gdd_lint": { + "exit": "0", + "fp": "green" + }, + "06b 变更记录节": { + "exit": "0", + "fp": "green" + }, + "07 doc_link": { + "exit": "0", + "fp": "green" + }, + "08 doc_term": { + "exit": "0", + "fp": "green" + }, + "08c 流水线闸": { + "exit": "0", + "fp": "green" + }, + "09 静态扫描": { + "exit": "1", + "fp": "4354b2aa72a7" + }, + "10 熵增闸": { + "exit": "0", + "fp": "green" + }, + "11 回放确定性对拍": { + "exit": "SKIP", + "fp": "skip" + } } - } } \ No newline at end of file diff --git a/game/tests/run_all.gd b/game/tests/run_all.gd index 83c64933..7e9113e0 100644 --- a/game/tests/run_all.gd +++ b/game/tests/run_all.gd @@ -40,44 +40,44 @@ func _suites() -> Array: # example_test.gd 是协议活样板(tests/unit/README 明示),不进生产 manifest—— # 样板件占位断言跑绿没有信息量,且占据「27 套件」计数。文件保留作模板(同类先例见下 fog_lantern 摘除行)。 {"path": "res://tests/unit/data_config/config_db_test.gd", "expect": 0}, - {"path": "res://tests/unit/data_config/forge_table_test.gd", "expect": 0}, # 迭代 23 锻造工坊批 T1——六路线 schema 正反(V1)+特效留空(V11)+几何价格梯(V2 半边) + {"path": "res://tests/unit/data_config/forge_table_test.gd", "expect": 0}, # 六路线 schema 正反(V1)+特效留空(V11)+几何价格梯(V2 半边) {"path": "res://tests/unit/data_config/config_db_fatal_oob_test.gd", "expect": 1}, - {"path": "res://tests/unit/data_config/treasure_target_violation_test.gd", "expect": 1}, # 迭代 7 T1——真视窄域护栏 + {"path": "res://tests/unit/data_config/treasure_target_violation_test.gd", "expect": 1}, # 真视窄域护栏 # negative=true=负面套件:坏表/违规输入是它的测试目标,输出里必然带 Parse Error, # 脚本错误扫描对它属误伤——豁免只放行这一件,且仅限「错误扫描」一闸(退出码与断言下限照判)。 - {"path": "res://tests/unit/data_config/reward_dangling_treasure_test.gd", "expect": 1, "negative": true}, # 迭代 7 T1——秘宝双表校验 + {"path": "res://tests/unit/data_config/reward_dangling_treasure_test.gd", "expect": 1, "negative": true}, # 秘宝双表校验 {"path": "res://tests/unit/data_config/rng_service_test.gd", "expect": 0}, - {"path": "res://tests/unit/core/treasure_items_test.gd", "expect": 0}, # 迭代 7 T7——秘宝结构冻结断言面 - {"path": "res://tests/unit/core/breakpoint_resume_test.gd", "expect": 0}, # 迭代 8 卡①/T9——断点往返/续玩确定性/幂等/退出清断点 - {"path": "res://tests/unit/core/curio_refresh_paid_test.gd", "expect": 0}, # 2026-10-06——三选一刷新免费双源+GP 付费档(对齐商店 MC-1:价曲线/优先序/停点清零/钱包单口) - {"path": "res://tests/unit/presentation/pacing_queue_test.gd", "expect": 0}, # 迭代 8 卡⑦ AC⑤/T9——排空零分叉/零丢行/延迟双态 - {"path": "res://tests/unit/presentation/reward_overlay_test.gd", "expect": 0}, # 迭代 7 hotfix——奖励节点 UI 直验(盲区补漏) - {"path": "res://tests/unit/presentation/forge_workbench_test.gd", "expect": 0}, # 迭代 23 锻造工坊批 T6——工作间两区六路线 UI 直验(V13 自动化前置面) + {"path": "res://tests/unit/core/treasure_items_test.gd", "expect": 0}, # 秘宝结构冻结断言面 + {"path": "res://tests/unit/core/breakpoint_resume_test.gd", "expect": 0}, # 断点往返/续玩确定性/幂等/退出清断点 + {"path": "res://tests/unit/core/curio_refresh_paid_test.gd", "expect": 0}, # 三选一刷新免费双源+GP 付费档(对齐商店 MC-1:价曲线/优先序/停点清零/钱包单口) + {"path": "res://tests/unit/presentation/pacing_queue_test.gd", "expect": 0}, # AC⑤/T9——排空零分叉/零丢行/延迟双态 + {"path": "res://tests/unit/presentation/reward_overlay_test.gd", "expect": 0}, # 奖励节点 UI 直验(盲区补漏) + {"path": "res://tests/unit/presentation/forge_workbench_test.gd", "expect": 0}, # 工作间两区六路线 UI 直验(V13 自动化前置面) {"path": "res://tests/unit/battle_settlement/damage_math_test.gd", "expect": 0}, {"path": "res://tests/unit/battle_settlement/damage_controller_test.gd", "expect": 0}, - {"path": "res://tests/unit/battle_settlement/skill_unlock_test.gd", "expect": 0}, # 迭代14④ T6——Boss 半血解锁技·容器机制(门谓词/闩不可逆/双面过滤/保底不逼锁定/零扰动) + {"path": "res://tests/unit/battle_settlement/skill_unlock_test.gd", "expect": 0}, # Boss 半血解锁技·容器机制(门谓词/闩不可逆/双面过滤/保底不逼锁定/零扰动) {"path": "res://tests/unit/contracts/system_contracts_test.gd", "expect": 0}, {"path": "res://tests/unit/presentation/ui_font_asset_test.gd", "expect": 0}, {"path": "res://tests/unit/presentation/terrain_tile_sets_test.gd", "expect": 0}, - # fog_lantern_wiring_test 随提灯载体行退役摘除(迭代 22 T1——V13 旧验证约束同生死;呈现桥换代断言归 T4 阔视野带参数面) + # 提灯载体行不在册(呈现桥断言归阔视野带参数面) {"path": "res://tests/unit/core/effect_words_t1_test.gd", "expect": 0}, - {"path": "res://tests/unit/core/treasure_effects_test.gd", "expect": 0}, # 迭代 22 秘宝批 T3——新目录 12 件逐件行为(V7 附属表正常/边界/反例) - {"path": "res://tests/unit/core/tree_rules_v11_test.gd", "expect": 0}, # 迭代 21 天赋树批 V11——六键合成行闭集校验 # 迭代 20 T1——词表扩签封闭性(V1:新词在册/出域四路被拒/adventure 计数器往返/mod_eq 预评估口径) - {"path": "res://tests/unit/core/tree_requires_level_test.gd", "expect": 0}, # R1 机制位批 2026-10-13——requires_level 等级阈值前置(schema 四拒一过+判定三态+投影两态) - {"path": "res://tests/unit/core/pool_case_d_test.gd", "expect": 0}, # 迭代 20 T2——池结构案D 行为(V6 令牌三态/V7 曝光槽 2+1 回退/V8 概率上限解耦提前退役) - {"path": "res://tests/unit/core/feat_vouchers_test.gd", "expect": 0}, # 迭代 20 T4——凭证五件+留任二件(V9 路由逐件/F-1 存量账/V10 留任路由+AP 属性轴) - {"path": "res://tests/unit/core/settle_segments_test.gd", "expect": 0}, # 迭代 27 T2——结算五段 Segment(V4:直接 new/编排器接线/真实一轮走段序) - {"path": "res://tests/unit/presentation/modal_flow_test.gd", "expect": 0}, # 迭代 27 T4——模态编排纯逻辑(V6:直接 new/互斥域谓词/三例外锁/演播后排窗) - # ---- L2 集成层(迭代 29 T3 建承载——跨系统用例,与 unit/ 的隔离断言面分工)---- + {"path": "res://tests/unit/core/treasure_effects_test.gd", "expect": 0}, # 新目录 12 件逐件行为(V7 附属表正常/边界/反例) + {"path": "res://tests/unit/core/tree_rules_v11_test.gd", "expect": 0}, # V11 六键合成行闭集校验 # V1 词表扩签封闭性(新词在册/出域四路被拒/adventure 计数器往返/mod_eq 预评估口径) + {"path": "res://tests/unit/core/tree_requires_level_test.gd", "expect": 0}, # R1 requires_level 等级阈值前置(schema 四拒一过+判定三态+投影两态) + {"path": "res://tests/unit/core/pool_case_d_test.gd", "expect": 0}, # 池结构案D 行为(V6 令牌三态/V7 曝光槽 2+1 回退/V8 概率上限解耦提前退役) + {"path": "res://tests/unit/core/feat_vouchers_test.gd", "expect": 0}, # 凭证五件+留任二件(V9 路由逐件/F-1 存量账/V10 留任路由+AP 属性轴) + {"path": "res://tests/unit/core/settle_segments_test.gd", "expect": 0}, # 结算五段 Segment(V4:直接 new/编排器接线/真实一轮走段序) + {"path": "res://tests/unit/presentation/modal_flow_test.gd", "expect": 0}, # 模态编排纯逻辑(V6:直接 new/互斥域谓词/三例外锁/演播后排窗) + # ---- L2 集成层(跨系统用例,与 unit/ 的隔离断言面分工)---- {"path": "res://tests/integration/save_rng_roundtrip_test.gd", "expect": 0}, # 存档⇄RNG 快照往返(SaveManager 迁移链 × 断点消费 × RNG 续跑 × 停点态确定性) - # ---- 迭代 29 T5 覆盖补洞:此前零指名的 core 四件与呈现层两件 ---- + # ---- core 四件与呈现层两件的直接单测 ---- {"path": "res://tests/unit/core/board_generator_test.gd", "expect": 0}, # 棋盘生成(尺寸合表/数字=八邻雷数/同种子逐位一致/可推理自洽) {"path": "res://tests/unit/core/minesweeper_rules_test.gd", "expect": 0}, # 排雷规则(装板不变量/挖的 face 规则/揭示推进/封印/目录外拒) {"path": "res://tests/unit/core/config_db_resolver_test.gd", "expect": 0}, # 配置解析(ceil 偏难语义/行集行序/难度 clamp) {"path": "res://tests/unit/core/config_db_cross_validator_test.gd", "expect": 0}, # 跨表校验(正向零错/悬空 skill_id/side 反向) {"path": "res://tests/unit/presentation/hud_presenter_test.gd", "expect": 0}, # HUD 投影文案(逐拒绝原因/兜底不空) {"path": "res://tests/unit/presentation/battle_narrator_test.gd", "expect": 0}, # 战斗叙述(数值带入/胜负互异/收束态恒定) - {"path": "res://tests/unit/presentation/type_glow_test.gd", "expect": 0}, # 迭代 30 卡① T2-②——未开格类型微光数据面(九型归组封闭/清单外显式失败/冻结色相只准动明度/α170·带宽cell÷8锚定/合成空间阶梯单调+模型CR≥1.20/probe API 形状) + {"path": "res://tests/unit/presentation/type_glow_test.gd", "expect": 0}, # 未开格类型微光数据面(九型归组封闭/清单外显式失败/冻结色相只准动明度/α170·带宽cell÷8锚定/合成空间阶梯单调+模型CR≥1.20/probe API 形状) ] diff --git a/game/tests/static_scan.sh b/game/tests/static_scan.sh index 873816ad..4cf5a2ce 100644 --- a/game/tests/static_scan.sh +++ b/game/tests/static_scan.sh @@ -1,10 +1,10 @@ #!/usr/bin/env bash # tests/static_scan.sh — 静态扫描域 S1–S8 可执行子集 # 规则全集与动机:design/engineering/architecture/architecture.md「测试与质量域」节 -# 正式工程(core/ 存在)时执行;否则优雅跳过(工程在 game/core——2026-09-24 转正结构批后仓库根布局)。 +# 正式工程(core/ 存在)时执行;否则优雅跳过(工程在 game/core——仓库根布局)。 # 纪律:新违规案例必须先补本脚本规则再修码(design/engineering/code-conventions.md 缺陷-规范对照表)。 set -u -cd "$(dirname "$0")/../.." # 迭代 27 T5 修正——2026-09-24 布局迁移后 /.. 落 game/ 致 game/core 守卫恒跳过(静默空转遗产),S 闸规则路径均为仓根相对 +cd "$(dirname "$0")/../.." # S 闸规则路径均为仓根相对(落点错会致 game/core 守卫恒跳过=静默空转) if [ ! -d game/core ]; then echo "[static_scan] game/core 不存在(工程未创建)——跳过,退出 0" @@ -13,7 +13,7 @@ fi fail=0 -# ── 扫描路径单点 + 零命中自检(迭代 29 T6)── +# ── 扫描路径单点 + 零命中自检 ── # 静默空转比红更危险:S3 曾把路径写成裸 `core`(仓根无此目录,实际是 game/core), # 恒零命中恒绿、什么都不扫,直到本批才被发现。故每条规则的扫描路径必须是单点变量, # 且规则自己先数一遍扫描面文件数——数为零一律判红(这样路径写歪时自检会跟着一起歪、一起红)。 @@ -35,7 +35,7 @@ require_scan_face() { # require_scan_face <规则名> <目录> — 扫描面 return 0 } -# S9 — 类型闸(迭代 27 T5——code-conventions §4 机器闸:产品码无类型容器/有值返回缺类型/参数缺类型) +# S9 — 类型闸(code-conventions §4 机器闸:产品码无类型容器/有值返回缺类型/参数缺类型) if python tools/audit_type_hints.py; then echo "[static_scan] S9 ok" else @@ -43,7 +43,7 @@ else fail=1 fi -# S10 — 文件头闸(code-conventions §1.4.1 第二轮 2026-10-15:头注 ≤8 行+日期/变更叙事黑名单) +# S10 — 文件头闸(code-conventions §1.4.1:头注 ≤8 行+日期/变更叙事黑名单) if python tools/audit_file_headers.py; then echo "[static_scan] S10 ok" else @@ -53,7 +53,7 @@ fi # S1/S2 — 玩法代码禁 randomize()/自建 RandomNumberGenerator/全局随机函数(绕开 RngService 的口子) -# 2026-09-24 首次实跑收敛(转正结构批):违规签名=裸 randomize/rand* 调用(实例方法 .randi() 排除) +# 违规签名=裸 randomize/rand* 调用(实例方法 .randi() 排除) # + RngService 之外的 RandomNumberGenerator.new();接收服务注入流的类型标注不属违规(core 五文件 15 处实证) if require_scan_face "S1/S2" "$DIR_CORE"; then hits=$(grep -rnE '\brandomize[[:space:]]*\(|(^|[^.[:alnum:]_])randi[[:space:]]*\(|(^|[^.[:alnum:]_])randf[[:space:]]*\(|(^|[^.[:alnum:]_])randf_range[[:space:]]*\(' \ @@ -69,7 +69,7 @@ if [ "$hits" -gt 0 ]; then echo "[static_scan] S4 FAIL: core 引擎/UI 依赖命 fi # S3 — core/ 禁 ConfigDB 外 data 表加载(schema class_name 直引豁免) -# 路径修正(迭代 29 T6):原扫裸 `core`——仓根无此目录,恒零命中恒绿(静默空转);实际为 game/core。 +# 扫描路径必须写 game/core——写裸 `core` 仓根无此目录,恒零命中恒绿(静默空转)。 # 豁免:①注释行 ②game/core/config_db.gd 自身(数值单一事实源的正主,它的单点 load 是本规则的例外)。 if require_scan_face "S3" "$DIR_CORE"; then hits=$(grep -rnE '\b(load|preload)[[:space:]]*\(|ResourceLoader\.load' "$DIR_CORE" --include='*.gd' 2>/dev/null \ diff --git a/game/tests/unit/battle_settlement/skill_unlock_test.gd b/game/tests/unit/battle_settlement/skill_unlock_test.gd index b65b55d6..54fa6d1a 100644 --- a/game/tests/unit/battle_settlement/skill_unlock_test.gd +++ b/game/tests/unit/battle_settlement/skill_unlock_test.gd @@ -1,6 +1,6 @@ # tests/unit/battle_settlement/skill_unlock_test.gd — Boss 半血解锁技·单位容器机制单元测试 # 运行:godot --headless --path game --script res://tests/unit/battle_settlement/skill_unlock_test.gd -# 覆盖(迭代14④ 技能池执行批 T6):门谓词(hp ≤ round(max_hp×pct/100))/闩不可逆(治疗抬血不解锁)/ +# 覆盖:门谓词(hp ≤ round(max_hp×pct/100))/闩不可逆(治疗抬血不解锁)/ # 双面过滤(rollable+special 不入锁定)/保底不逼锁定(保底集合排除锁定)/解锁即可摇(冷却初值 0)/ # 普通行无字段逐位零扰动(goblin 池快照零 unlock 键、过滤恒空转)/同种子确定性(容器零随机)。 # 红线:期望值由表读值推导(零玩法数值字面量);零自建 RNG。 diff --git a/game/tests/unit/core/board_generator_test.gd b/game/tests/unit/core/board_generator_test.gd index 12130ee0..d35262af 100644 --- a/game/tests/unit/core/board_generator_test.gd +++ b/game/tests/unit/core/board_generator_test.gd @@ -1,4 +1,4 @@ -# tests/unit/core/board_generator_test.gd — 棋盘生成直接单测(迭代 29 T5 补洞:该模块此前零指名) +# tests/unit/core/board_generator_test.gd — 棋盘生成直接单测 # 断言面 = 生成的棋盘自洽:尺寸与表一致、雷数在域、数字恒等于八邻雷数、同种子逐位可复现、 # 可推理性度量与清图判定自洽。期望值一律由盘上数出来(零玩法数值字面量)。 # 运行:godot --headless --path game --script res://tests/unit/core/board_generator_test.gd diff --git a/game/tests/unit/core/breakpoint_resume_test.gd b/game/tests/unit/core/breakpoint_resume_test.gd index 1a2fcb66..92323340 100644 --- a/game/tests/unit/core/breakpoint_resume_test.gd +++ b/game/tests/unit/core/breakpoint_resume_test.gd @@ -86,7 +86,7 @@ func _init() -> void: var battle_d = runner_d.current_battle() Kit.check_quiet(_board_fingerprint(battle_d.minesweeper.current_board()) == fp_b, "二次续玩板逐位同(幂等)") - # ---- Part 5:三选一停点中断→续玩(迭代 10 奖励重构——候选不重抽、已兑付不重付、次数计数一致)---- + # ---- Part 5:三选一停点中断→续玩(候选不重抽、已兑付不重付、次数计数一致)---- var rng_e = load("res://core/rng_service.gd").new() var sm_e = SaveManagerScript.new(_bp_path) var adr_e = AdventureRunnerScript.new(db, rng_e) @@ -128,7 +128,7 @@ func _init() -> void: Kit.check_quiet(String(got_result["r"].get("picked", "")) == picked_e, "P5 已兑付不重付(resolved 重发同件)") Kit.check_quiet(adr_g.continue_to_next_level(), "P5 已兑付续玩后推进受理(下一关开始)") - # ---- Part 6:装配存档回归(迭代 19 卡④立,迭代 22 秘宝批 T4 主语换代——装配→停点→回局载体态 + # ---- Part 6:装配存档回归(装配→停点→回局载体态 # 一致:params.attunement 随续玩受理面重建再注入战斗〔begin_battle enc 携带〕;呈现态每战重算归 # 呈现桥(main._sync_treasure_glow),本断言钉核心层装载往返——回局后 attune_has 只读出口读数一致)---- var rng_h = load("res://core/rng_service.gd").new() diff --git a/game/tests/unit/core/config_db_cross_validator_test.gd b/game/tests/unit/core/config_db_cross_validator_test.gd index 9868a779..9d18836f 100644 --- a/game/tests/unit/core/config_db_cross_validator_test.gd +++ b/game/tests/unit/core/config_db_cross_validator_test.gd @@ -1,4 +1,4 @@ -# tests/unit/core/config_db_cross_validator_test.gd — 跨表校验直接单测(迭代 29 T5 补洞:该模块此前零指名) +# tests/unit/core/config_db_cross_validator_test.gd — 跨表校验直接单测 # 断言面 = 敌人技能池跨表链接校验:悬空 skill_id 必报、施放类 side 反向挂接必报、 # 池构成纪律(普攻恰一行)越界必报、全对齿时零错(正向面防误伤)。 # 表对象由夹具直构(不碰生产表),期望值由注入内容数出来。 diff --git a/game/tests/unit/core/config_db_resolver_test.gd b/game/tests/unit/core/config_db_resolver_test.gd index 820392e8..132d5cb5 100644 --- a/game/tests/unit/core/config_db_resolver_test.gd +++ b/game/tests/unit/core/config_db_resolver_test.gd @@ -1,5 +1,5 @@ -# tests/unit/core/config_db_resolver_test.gd — 配置解析直接单测(迭代 29 T5 补洞:该模块此前零指名) -# 断言面 = ceil 进度键解析语义(2026-09-18 用户拍板:向上取整保证偏难)、行集多行的行序保序、 +# tests/unit/core/config_db_resolver_test.gd — 配置解析直接单测 +# 断言面 = ceil 进度键解析语义(向上取整保证偏难)、行集多行的行序保序、 # 难度修饰乘数的 clamp 域。行集由夹具注入,不碰生产表——期望值由注入行数出来。 # 运行:godot --headless --path game --script res://tests/unit/core/config_db_resolver_test.gd extends SceneTree diff --git a/game/tests/unit/core/curio_refresh_paid_test.gd b/game/tests/unit/core/curio_refresh_paid_test.gd index 7e778c75..de765073 100644 --- a/game/tests/unit/core/curio_refresh_paid_test.gd +++ b/game/tests/unit/core/curio_refresh_paid_test.gd @@ -1,5 +1,5 @@ extends SceneTree -# 三选一刷新免费双源 + GP 付费档单测(2026-10-06 用户令——三选一刷新对齐商店 MC-1: +# 三选一刷新免费双源 + GP 付费档单测(三选一刷新对齐商店 MC-1: # 免费位 X/Y 用尽后转 GP 付费,同旋钮同曲线同钱包)。 # 守面:付费价曲线(ceil(商店基价×曲线^本次停点已付费刷))/免费优先序 X→Y/付费刷新零触碰免费位/ # 停点在途谓词(无停点禁扣钱)/停点重建清零付费计数(对齐商店进店清零)/钱包单口支出 spend_gp。 @@ -52,7 +52,7 @@ func _init() -> void: Kit.check_quiet(lr.spend_gp(31) == false and int(lr.gp) == 30, "余额不足拒绝零副作用") Kit.check_quiet(lr.spend_gp(20) == true and int(lr.gp) == 10, "足额支出扣账(30→10)") - # ---- ⑥ Y 断点随存(2026-10-13 缺陷修批——旧缺陷:续玩自参数面整额重注入=用完 Y 退菜单再续玩满血复活)---- + # ---- ⑥ Y 断点随存(缺陷锚:续玩自参数面整额重注入=用完 Y 退菜单再续玩满血复活)---- var bp_y := {"level_index": 1, "hero_hp": 10, "attune_refresh_y": 2} var adr_r = load("res://core/adventure_runner.gd").new(db, load("res://core/rng_service.gd").new()) Kit.check_quiet(adr_r.resume_adventure(bp_y, {"hero_override": {}, "attune_refresh_y": 3}), "续玩受理(最小断点+参数面)") diff --git a/game/tests/unit/core/effect_words_t1_test.gd b/game/tests/unit/core/effect_words_t1_test.gd index 16082ffd..a40634ad 100644 --- a/game/tests/unit/core/effect_words_t1_test.gd +++ b/game/tests/unit/core/effect_words_t1_test.gd @@ -1,5 +1,5 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# 效果引擎词表扩签封闭性单测(迭代 20 专长实装批 T1——需求卡片 V1 验收条目)。 +# 效果引擎词表扩签封闭性单测(需求卡片 V1 验收条目)。 # 覆盖:①扩签后四词表仍封闭(新事件/新效果类型/新事实/新算子在册+出域值全部被拒—— # validate_trigger_row 加载期报错 / dispatch 运行期 fail-fast);②合法新词行零违例; # ③adventure 域计数器 export/seed 往返(T6 承载面);④mod_eq 取模余数算子(双管镐落法)。 diff --git a/game/tests/unit/core/feat_vouchers_test.gd b/game/tests/unit/core/feat_vouchers_test.gd index 74df521a..1aff0b32 100644 --- a/game/tests/unit/core/feat_vouchers_test.gd +++ b/game/tests/unit/core/feat_vouchers_test.gd @@ -1,7 +1,7 @@ # VERTICAL SLICE - NOT FOR PRODUCTION # 凭证件留任二件+两件出池+完美保险专长单测(刷新券/储备金袋/时沙 三件路由+留任二件——刷新写错账修复钉面)。 # 覆盖:刷新券→刷新存量账(非 _attune_refresh_x——写错账复发反例)/储备金袋→RAP/时沙→首轮 AP 池; -# 迭代 31 卡② 凭证件裁削批——同调电池整件删除、完美保险迁专长:两件出池反例(词表/兑付/符号清零/断点缺键)、 +# 同调电池整件删除、完美保险迁专长:两件出池反例(词表/兑付/符号清零/断点缺键)、 # 配额净删锚(稀有 7/总量 102)、完美保险专长验收组(装载/限次一次/计数纯净/两账相减判定/跨战清零/事件不吞); # 留任 2 件路由与值不变(GP 钱包/当即回血)+行动点上限归属性轴(bonus.ap 落点)。 # 运行:godot --headless --path game --script res://tests/unit/core/feat_vouchers_test.gd(expect 0) @@ -42,7 +42,7 @@ func _init() -> void: Kit.check_quiet(a.refresh_curio() and a.refresh_stock() == 0, "刷新消耗序:X/Y 空时吃存量账〔专长批 V9〕") a._node_curio_pending = {} - # 摘牌:选中即消尽(T4 修正——旧早退路径零摘牌缺陷同批退役) + # 摘牌:选中即消尽(禁早退路径零摘牌) var deck_refresh_before: int = a.pool_stock("refresh") Kit.check_quiet(deck_refresh_before == 0 or true, "牌库 refresh 令牌读数在域(投放 %d)" % deck_refresh_before) @@ -54,7 +54,7 @@ func _init() -> void: Kit.check_quiet(a._apply_curio_pick("time_sand", "rare", 2), "时沙兑付受理〔专长批 V9〕") Kit.check_quiet(a._time_sand_queue == 2, "时沙:首轮 AP 队列 +2(池增量非上限)〔专长批 V9〕") - # V23 两件出池(迭代 31 卡② 凭证件裁削批 R1——同调电池删除/完美保险迁专长) + # V23 两件出池(R1——同调电池删除/完美保险迁专长) Kit.check_quiet(not db.adventure.CURIO_KINDS.has("attune_battery") and not db.adventure.CURIO_KINDS.has("perfect_insurance"), "出池词表:CURIO_KINDS 零两件(三选一池物理不可再出)〔卡② R1〕") @@ -71,7 +71,7 @@ func _init() -> void: a._seed_attune_charges() Kit.check_quiet(int(a.run_ledger.attune_charges.get("incense_stick", -1)) != 99, "账本保留:删件后 _seed_attune_charges 仍按装备重置充能账(attune_charges 语义零变化)〔卡② R1〕") - # V24 配额净删锚(R3——用户裁「净删」,rare 9→7/总量 104→102) + # V24 配额净删锚(R3——「净删」口径,rare 9→7/总量 104→102) var rare_sum := 0 var rare_kinds: Array[String] = [] for k in db.adventure.CURIO_KINDS: @@ -111,7 +111,7 @@ func _init() -> void: # V16——断点扩容往返:新账本随断点快照/续玩回填(breakpoint_resume_test P5 同构) var sm = load("res://core/save_manager.gd").new("user://_feat_vouchers_bp.json") sm.load_from_disk() - a.run_ledger.adventure_counters = {"pain_layers": 3, "twin_digs": 5} # 迭代 27 T3——四账住 RunLedger + a.run_ledger.adventure_counters = {"pain_layers": 3, "twin_digs": 5} # 四账住 RunLedger a._refresh_stock = 2 a.set_save_manager(sm) a._on_level_finished({"result": "victory", "hp": 10, "node_index": 1, "node_id": 1, "node_type": "shop"}) @@ -127,7 +127,7 @@ func _init() -> void: Kit.check_quiet(b3.resume_adventure(bp_legacy, {}), "V16:旧档含 battery_pending 键续玩受理(缺键/多键零报错)〔卡② R1〕") Kit.check_quiet(int(b2.run_ledger.adventure_counters.get("pain_layers", -1)) == 3 and b2.refresh_stock() == 2, "V16:续玩回填逐项一致(计数恢复——跨战账不丢)〔专长批 V16〕") - # V25 完美保险专长验收组(迭代 31 卡② T4/T5——R2 全项:装载/限次一次/计数纯净/两账相减/跨战清零/事件不吞) + # V25 完美保险专长验收组(R2 全项:装载/限次一次/计数纯净/两账相减/跨战清零/事件不吞) var fi: Dictionary = db.feats.row_by_id("perfect_insurance") Kit.check_quiet(not fi.is_empty() and String(fi.get("rarity", "")) == "rare" and String(fi.get("desc", "")).find("雷") == -1 and String(fi.get("desc", "")).find("封印") >= 0, diff --git a/game/tests/unit/core/minesweeper_rules_test.gd b/game/tests/unit/core/minesweeper_rules_test.gd index b95c08f9..3552ff8d 100644 --- a/game/tests/unit/core/minesweeper_rules_test.gd +++ b/game/tests/unit/core/minesweeper_rules_test.gd @@ -1,4 +1,4 @@ -# tests/unit/core/minesweeper_rules_test.gd — 排雷规则直接单测(迭代 29 T5 补洞:该模块此前零指名) +# tests/unit/core/minesweeper_rules_test.gd — 排雷规则直接单测 # 断言面 = 装板后的盘面不变量与意图受理:装板零揭示、安全格余量=安全格总数、挖安全格后揭示 # 且余量递减、封印落封印态、禁挖面拒绝、清图判定随揭示推进。期望值一律由盘上数出来。 # 运行:godot --headless --path game --script res://tests/unit/core/minesweeper_rules_test.gd diff --git a/game/tests/unit/core/treasure_effects_test.gd b/game/tests/unit/core/treasure_effects_test.gd index d00b8978..e98f59e6 100644 --- a/game/tests/unit/core/treasure_effects_test.gd +++ b/game/tests/unit/core/treasure_effects_test.gd @@ -1,5 +1,5 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# 新目录 12 件逐件行为断言(迭代 22 秘宝批 T3——V7 附属表:正常效果/边界/反例三列核心行)。 +# 新目录 12 件逐件行为断言(V7 附属表:正常效果/边界/反例三列核心行)。 # 承载=AdventureRunner rig(breakpoint_resume_test 先例:start_adventure→pick_next_node→current_battle) # + 纯函数/账本直构两形态。每件「正常→边界→反例」顺序落断言;装配集直注 params.attunement(调试注入 # 口径——槽位与解锁不经正常流程,卡片 7.1)。 @@ -71,7 +71,7 @@ func _init() -> void: var ob4 = orch_s.new(db, rng4) Kit.check_quiet(ob4.begin_battle({"level_index": 1, "node_depth": 0, "hero_hp": int(db.hero.max_hp), "attunement": ["trial_pick"]}), "试炼镐:装配起战") - # 自动兑付(反哺批⑤ 2026-10-12 用户裁):无玩家入口——揭示缓冲点即时计数,满 charge_n 自动 + # 自动兑付:无玩家入口——揭示缓冲点即时计数,满 charge_n 自动 # grant_ap(cell_revealed 先于本格扣费→AP 归零恰逢满点时先兑再扣、轮不结束)。直调揭示处理器 # 构造 7+1 格序列(缓冲路径与真挖格同链;授予段无积点段无二次计数) var ap_before4 := int(ob4.action_economy._ap) @@ -94,7 +94,7 @@ func _init() -> void: Kit.check_quiet(int(ob4b.action_economy._ap) == ap_base and not bool(ob4b.attune_convert_state().get("assembled", true)), "试炼镐反例:未装配零兑付零计数(AP=整轮表值、读数口 assembled=false)") - # ④b 自动兑付件 C 区展示行(反哺批⑤补——charges=0 不入骑库存〔_reseed 注入循环跳过〕, + # ④b 自动兑付件 C 区展示行(charges=0 不入骑库存〔_reseed 注入循环跳过〕, # 展示行=C 区悬停浮窗进度唯一承载:handle=-1 非库存句柄+note 进度;空骑库存桩直构投影链) var rng4c = load("res://core/rng_service.gd").new(); rng4c.set_master_seed(253) var ob4c = orch_s.new(db, rng4c) @@ -269,7 +269,7 @@ func _init() -> void: Kit.check_quiet(ob12b.minesweeper.seal_range_free == false, "信标网络反例:未装配封印可达豁免=缺省 false(零装配零扰动)") - # ⑬ 真视使用计数链(受理成功恰计一次——RunLedger 单类持账;迭代 27 T3 换代) + # ⑬ 真视使用计数链(受理成功恰计一次——RunLedger 单类持账) var rng13 = load("res://core/rng_service.gd").new(); rng13.set_master_seed(321) var ob13 = orch_s.new(db, rng13) var lg13 = load("res://core/run_ledger.gd").new() @@ -286,7 +286,7 @@ func _init() -> void: Kit.check_quiet(int(lg13.vision_counter.get("used", 0)) == 1, "计数链正常:受理成功恰 +1(信标网络解锁行为条件数据源)") - # ⑭ 装配不可变(迭代 22 秘宝批 T6——V6:冒险全程装配快照三面同源且零写口—— + # ⑭ 装配不可变(V6:冒险全程装配快照三面同源且零写口—— # 写口唯一=营地 toggle_attunement〔meta_progression〕,runner/level/battle 无装配写口) var rng14 = load("res://core/rng_service.gd").new(); rng14.set_master_seed(331) var adr14 = runner_s.new(db, rng14) @@ -339,7 +339,7 @@ func _cell_at(orch, c: Vector2i) -> Vector2i: return Vector2i(-9, -9) -# 自动兑付件展示行测试桩(反哺批⑤——空骑库存 runner 桩:charges=0 件不入骑库存, +# 自动兑付件展示行测试桩(空骑库存 runner 桩:charges=0 件不入骑库存, # 展示行合成逻辑在 treasure_interact_controller.inventory_projection 末段) class StubAutoInvRunner: extends RefCounted diff --git a/game/tests/unit/data_config/config_db_test.gd b/game/tests/unit/data_config/config_db_test.gd index 1837847c..7c040828 100644 --- a/game/tests/unit/data_config/config_db_test.gd +++ b/game/tests/unit/data_config/config_db_test.gd @@ -58,7 +58,7 @@ func _test_progress_resolution(db) -> void: and String(got.get("board_type", "")) == String(probe_row.get("board_type", ""))) # enemy 行集同通道:同 (L,D) 行集数组非空(关卡节点地图 前置——battle 节点双表精确行集契约; - # 2026-10-07 行集多行批 T2 机械适配——返回形态单行改行集数组,精确性断言换代随批 T4) + # 行集面契约:返回形态是行集数组,精确性断言随行集面) var en_got: Array = db.resolve_enemy_rowset(int(probe_row.level_index), int(probe_row.node_depth)) Kit.check("enemy 行集同坐标解析非空(双表精确行契约)", not en_got.is_empty()) @@ -93,7 +93,7 @@ func _test_variant_pool_gate(db) -> void: for row in rows: if String(row.get("scope", "region")) != "region": if global_row.is_empty(): - global_row = row # global 行第三维门控另测(全局作用域变异批 2026-10-04) + global_row = row # global 行第三维门控另测(全局作用域变异) continue var tags: Array = row.get("board_types", []) if gated_row.is_empty() and not tags.is_empty(): @@ -155,7 +155,7 @@ func _test_shop_accessors(db) -> void: # ---- MetaTable 消费面 ---- func _test_meta_accessors(db) -> void: - # forge_products 行族断言已摘除(迭代 21 T5——行族/访问器随属性锻造柜台退役,V20 清单) + # 无 forge_products 行族断言(行族/访问器不在表,V20 清单) var key_rows: Array = db._meta_rows("boss_keystone") if not key_rows.is_empty(): var klv: int = int(key_rows[0].level_index) @@ -188,7 +188,7 @@ func _test_manifest_dir_sync(db) -> void: Kit.check("TABLE_MANIFEST 与 data/tables 目录逐文件同步(无缺登/无悬登)", synced) -# ---- 行集构成纪律(2026-10-07 敌人表行集多行批——EnemyTable.validate 正反验证;资源直构不碰生产表)---- +# ---- 行集构成纪律(EnemyTable.validate 正反验证;资源直构不碰生产表)---- # 纪律三条(敌人系统 v0.15):①行集内 enemy_id 唯一(dup_key 既有通道)②同坐标多行文件内相邻 # (rowset_rule——行序即契约,R6 加载期兜底)③行集实例总数 ≤4(骰后值运行面,spawn 守卫——冒烟侧验证)。 diff --git a/game/tests/unit/data_config/forge_table_test.gd b/game/tests/unit/data_config/forge_table_test.gd index dac61575..ac80b023 100644 --- a/game/tests/unit/data_config/forge_table_test.gd +++ b/game/tests/unit/data_config/forge_table_test.gd @@ -44,7 +44,7 @@ func _test_production_rows(db) -> void: if ks != expect_keys: keys_closed = false Kit.check("六行字段键集恰 = ROW_KEYS 闭集(无特效参数位)〔锻造工坊批 V11〕", keys_closed) - # 初始持有恰长剑+轻甲(语义继承自已退役属性锻造行) + # 初始持有恰长剑+轻甲 var initial := [] for row in rows: if bool(row.get("initial_owned", false)): @@ -190,8 +190,8 @@ func _test_negative_cases() -> void: # ---- V11:效果类型闭集零新增(满级特效本期不开新词)---- -# 实数订正(L2 在册):卡片 F11「24 种」系 2026-10-07 设计文档事实快照——迭代 20 T1 +7、迭代 22 T3 +1 -# 后现行 31;本批零扩签,钉现行数(将来任何一批加词即转红提示复核)。 +# 实数订正(L2 在册):卡片 F11「24 种」系设计文档事实快照, +# 现行 31;本套件零扩签,钉现行数(将来任何加词即转红提示复核)。 func _test_effect_kinds_closed() -> void: Kit.check("效果引擎效果类型闭集 32 种(锻造工坊批零新增口径随迭代 31 卡② 扩签 forgive_seal_miss 换代)〔锻造工坊批 V11〕", diff --git a/game/tests/unit/data_config/reward_dangling_treasure_test.gd b/game/tests/unit/data_config/reward_dangling_treasure_test.gd index 3c4642a2..83102d2a 100644 --- a/game/tests/unit/data_config/reward_dangling_treasure_test.gd +++ b/game/tests/unit/data_config/reward_dangling_treasure_test.gd @@ -20,7 +20,7 @@ func _inject_violation() -> bool: return false var s := f.get_as_text() f.close() - # 追加式注入(2026-10-01 战斗掉落渠道退役随批——现行表已无 aux 行可作锚):向 rows 尾追加 + # 追加式注入(现行表已无 aux 行可作锚):向 rows 尾追加 # 一块引用已退役 loot_compass 的 aux 投放行,双表校验须拦(retired 不入投放面)。 var inject := ', {\n\n"reward_id": "treasure_dangling_probe",\n"cell_type": "treasure_item",\n"polarity": "positive",\n"effect_id": "loot_compass",\n"display_name": "悬空探针",\n"power": 0,\n"weight": 1,\n"pool_tag": "cell",\n"tier": 1\n}' var idx := s.rfind("\n}]") diff --git a/game/tests/unit/data_config/rng_service_test.gd b/game/tests/unit/data_config/rng_service_test.gd index 0ead1ddd..a7ce3bfe 100644 --- a/game/tests/unit/data_config/rng_service_test.gd +++ b/game/tests/unit/data_config/rng_service_test.gd @@ -49,7 +49,7 @@ func _test_counter_ledger() -> void: rng.open_stream("armor_roll") var c2: int = rng.counter() Kit.check("open_stream 逐次推进全局计数器(+1/次)", c1 == c0 + 1 and c2 == c0 + 2) - # 用途标签只进事件日志不参与派生——同 scope 同派生种子(2026-09-27 统一流裁决口径) + # 用途标签只进事件日志不参与派生——同 scope 同派生种子(统一流口径) var rng_x = _fresh_service() var rng_y = _fresh_service() var s1: int = int(rng_x.open_stream("board_gen").seed) diff --git a/game/tests/unit/presentation/battle_narrator_test.gd b/game/tests/unit/presentation/battle_narrator_test.gd index 4aa803d2..e604500f 100644 --- a/game/tests/unit/presentation/battle_narrator_test.gd +++ b/game/tests/unit/presentation/battle_narrator_test.gd @@ -1,4 +1,4 @@ -# tests/unit/presentation/battle_narrator_test.gd — 战斗叙述直接单测(迭代 29 T5 补洞:该模块此前零指名) +# tests/unit/presentation/battle_narrator_test.gd — 战斗叙述直接单测 # 断言面 = 纯函数文案:休整/商店/终局三类叙述把数值带进去(玩家读数面由这里出)、 # 胜负两态文案互异、未知输入有兜底不吐空串。期望值由注入内容数出来。 # 运行:godot --headless --path game --script res://tests/unit/presentation/battle_narrator_test.gd diff --git a/game/tests/unit/presentation/forge_workbench_test.gd b/game/tests/unit/presentation/forge_workbench_test.gd index b1b95e38..e0c09afe 100644 --- a/game/tests/unit/presentation/forge_workbench_test.gd +++ b/game/tests/unit/presentation/forge_workbench_test.gd @@ -1,5 +1,5 @@ extends SceneTree -# 锻造工坊工作间 UI 直验套件(迭代 23 T6——V13 人闸的自动化前置面:两区结构/钮态/意图信号/锁定态纪律) +# 锻造工坊工作间 UI 直验套件(V13 人闸的自动化前置面:两区结构/钮态/意图信号/锁定态纪律) # 覆盖:锁定态零行板零购买路径(占位纪律延续)· 两区各三路线 · 初始持有行购买钮(几何价 20)· # 待解锁行解锁钮(200)+无购买钮 · 选中钮当前态禁用 · 余额不足禁用态 · 满级无购买钮 · # 三意图信号外发(UI 只发意图——契约 9,写口归 MetaProgression 由冒烟侧覆盖)。 diff --git a/game/tests/unit/presentation/hud_presenter_test.gd b/game/tests/unit/presentation/hud_presenter_test.gd index 94c9baa1..7912de12 100644 --- a/game/tests/unit/presentation/hud_presenter_test.gd +++ b/game/tests/unit/presentation/hud_presenter_test.gd @@ -1,4 +1,4 @@ -# tests/unit/presentation/hud_presenter_test.gd — HUD 投影直接单测(迭代 29 T5 补洞:该模块此前零指名) +# tests/unit/presentation/hud_presenter_test.gd — HUD 投影直接单测 # 断言面 = 纯函数投影:动作结果文案按拒绝原因逐类落字(玩家看到的每句提示都由这里出)、 # 未知原因有兜底文案(不吐空串)、棋盘变异行投影随表走。期望值由注入内容数出来。 # 运行:godot --headless --path game --script res://tests/unit/presentation/hud_presenter_test.gd diff --git a/game/tests/unit/presentation/pacing_queue_test.gd b/game/tests/unit/presentation/pacing_queue_test.gd index c98d6ff5..e218bdb7 100644 --- a/game/tests/unit/presentation/pacing_queue_test.gd +++ b/game/tests/unit/presentation/pacing_queue_test.gd @@ -19,7 +19,7 @@ func _init() -> void: var main: Node = load("res://presentation/main.tscn").instantiate() root.add_child(main) await process_frame - # 隔离换注(迭代 27 T1——SaveManager 升格 autoload 后改原地 attach:先删后建防陈旧档泄入, + # 隔离换注(SaveManager 是 autoload——原地 attach:先删后建防陈旧档泄入, # 读盘在 attach 内完成;meta 经 save 引用透传零重建) for p in ["user://test_pacing_queue_save.json", "user://test_pacing_queue_save.json.tmp"]: if FileAccess.file_exists(p): diff --git a/game/tests/unit/presentation/reward_overlay_test.gd b/game/tests/unit/presentation/reward_overlay_test.gd index 86387ef1..1d585c97 100644 --- a/game/tests/unit/presentation/reward_overlay_test.gd +++ b/game/tests/unit/presentation/reward_overlay_test.gd @@ -1,10 +1,10 @@ extends SceneTree -# 三选一覆盖层 UI 直验套件(迭代 7 T5-hotfix 转正;迭代 10 追加批随面迁移改写)—— -# 原守 node_overlay.show_reward_items;奖励节点三选一与通关三选一合并共用 CurioPickOverlay 后, -# 本套件改守共用面的「功能存在 ≠ 功能可达」盲区:选择外发/强制确认两段式/结果态。 -# 〔替换子面板两路段随迭代 22 秘宝批 T5 拆除——装配不可变契约 1,overlay replace 态退役。〕 +# 三选一覆盖层 UI 直验套件—— +# 守 node_overlay.show_reward_items 的继任共用面;奖励节点三选一与通关三选一共用 CurioPickOverlay, +# 本套件守共用面的「功能存在 ≠ 功能可达」盲区:选择外发/强制确认两段式/结果态。 +# 〔无替换子面板路段——装配不可变契约 1,overlay 无 replace 态。〕 # 运行:godot --headless --path game --script res://tests/unit/presentation/reward_overlay_test.gd(expect 0) -# T6 收口批:断言走 test_kit 计数(Kit.check)+ 失败即停早退协议保留(顺序状态机——坏态下后继断言无效)。 +# 断言走 test_kit 计数(Kit.check)+ 失败即停早退协议(顺序状态机——坏态下后继断言无效)。 const Kit := preload("res://tests/unit/test_kit.gd") # 断言 + 失败即停(原直写 print FAIL + quit(1) + return 样板单点化——早退语义逐位保持) @@ -31,13 +31,13 @@ func _run() -> void: {"id": "gp", "text": "GP 袋\nGP +20"}, {"id": "ap", "text": "行动点提升\n每战首轮 AP +1"}, ]) - # M7 bcard 换装适配(2026-10-05 奇物批 T2 连带):三选一卡自 M7 起为 BCard(PanelContainer) 非 Button—— - # 原 `c is Button` 计数自 M7 后恒 0(基线红成因,主区 3c4291d 起红在案)。改数 _choice_box 子节点数,断言语义不变(三卡呈现)。 + # bcard 形态:三选一卡为 BCard(PanelContainer) 非 Button—— + # 用 `c is Button` 计数会恒 0(基线红成因,主区 3c4291d 起红在案)。本面数 _choice_box 子节点数,断言语义=三卡呈现。 var btns: int = ov._choice_box.get_child_count() if not _req("选择态应三卡呈现且确认/继续隐藏(btns=%d)" % btns, ov.visible and btns == 3 and not ov._confirm_btn.visible and not ov._continue_btn.visible): return - # ①b 刷新面投喂(2026-10-06 对齐商店 MC-1——投喂前隐藏/免费位点亮/GP 付费档禁用态/真实钮路径外发) + # ①b 刷新面投喂(对齐商店 MC-1——投喂前隐藏/免费位点亮/GP 付费档禁用态/真实钮路径外发) if not _req("投喂前刷新钮应隐藏(未投喂上下文如店内门票面无刷新)", not ov._refresh_btn.visible): return diff --git a/game/tests/unit/presentation/terrain_tile_sets_test.gd b/game/tests/unit/presentation/terrain_tile_sets_test.gd index e4ac400b..ddaa0454 100644 --- a/game/tests/unit/presentation/terrain_tile_sets_test.gd +++ b/game/tests/unit/presentation/terrain_tile_sets_test.gd @@ -3,7 +3,7 @@ # 事实源:board_gen.tres board_type 词表 v1.1(dungeon/underdark/deep_underdark——从表读值,禁写死); # 色相域方向 = art-bible §4.3 三关方向(underdark 灰白蓝紫 / deep_underdark 蓝黑紫黑); # 图底分离 = 圣经 §8.5(已开地面明度低于未开墙体)。 -# 前置守卫:素材不入 git(用户裁定)——fresh checkout 无瓦片文件时本套件跳过(打印注记,不红); +# 前置守卫:素材不入 git——fresh checkout 无瓦片文件时本套件跳过(打印注记,不红); # 源 dungeon 套在盘而换色套缺位 = 回归(换色脚本在库可复现)。 extends SceneTree @@ -115,7 +115,7 @@ func _load_stats(board_dir: String, fname: String, top_half: bool) -> Dictionary return {"h": h_sum / n_h, "v": v_sum / n_v} -# 数字呈现模式对比断言(L2/L3 亮瓦融字缺陷修复 2026-10-01——甲案机检面,v3.4 扩三态): +# 数字呈现模式对比断言(L2/L3 亮瓦融字缺陷的甲案机检面,v3.4 扩三态): # 每个图型走 BoardView 同一归一+测光+选模式管线(禁测试侧另写算法),断言: # ①dungeon=亮墨族直画(对 p90 ≥4.5 且对均值 ≥2.5);②underdark/deep_underdark=色牌垫底 # (双峰纹理直画不可救——渲染帧取证深墨隐形实证,牌上深墨 12:1);③直画模式的双门槛值照抄 diff --git a/game/tests/unit/presentation/type_glow_test.gd b/game/tests/unit/presentation/type_glow_test.gd index 8fa16e9c..5f045044 100644 --- a/game/tests/unit/presentation/type_glow_test.gd +++ b/game/tests/unit/presentation/type_glow_test.gd @@ -1,8 +1,8 @@ -# tests/unit/presentation/type_glow_test.gd — 未开格类型微光数据面直验(迭代 30 卡① T2-②) +# tests/unit/presentation/type_glow_test.gd — 未开格类型微光数据面直验 # 断言面 = 纯函数/常量域(无渲染):① 九 cell_type → 五组封闭判定(含清单外显式失败、 # 禁子串匹配、与卡顶带 tg_band 的归组差异锚定——Q3 甲案两带并存);② 五组色值冻结面 -# (HSV 对照 art-bible §4.2 冻结值只准动明度档——2026-10-17 群伤组一案停机呈报后用户裁 -# #A61D37,本测试即该裁定的守门件);③ 呈现参数锚定(α170/带宽 cell÷8);④ 合成空间 +# (HSV 对照 art-bible §4.2 冻结值只准动明度档——群伤组 +# #A61D37 为终值,本测试即该判据的守门件);③ 呈现参数锚定(α170/带宽 cell÷8);④ 合成空间 # 阶梯单调 + 相邻组模型 CR ≥1.20(色弱灰度互辨的数据面预判,终审在渲染取证探针实测); # ⑤ probe API 形状(默认开/空态键集)。 # 运行:godot --headless --path game --script res://tests/unit/presentation/type_glow_test.gd @@ -27,7 +27,7 @@ const TYPE_EXPECT := { "pierce": UiKitScript.GLOW_PIERCE, "blast": UiKitScript.GLOW_AOE, "magic": UiKitScript.GLOW_MAGIC, } -# provisional 明度档终值(2026-10-17 用户裁后)——逐位锚定,谁改色值这里红 +# provisional 明度档终值——逐位锚定,谁改色值这里红 const IMPL := { "BUFF": Color8(247, 223, 67), "HEAL": Color8(104, 208, 66), "PIERCE": Color8(48, 166, 166), "MAGIC": Color8(123, 91, 214), @@ -92,7 +92,7 @@ func _test_frozen_hue_face() -> void: var ds: float = absf(m.s - f.s) Kit.check("冻结色相保持:%s ΔH=%.3f° ≤0.2° 且 ΔS=%.4f ≤0.01(只动明度档)" % [g, dh * 360.0, ds], dh <= 0.2 / 360.0 and ds <= 0.01) - # 群伤组专锚(2026-10-17 停机呈报→用户裁 #A61D37):H/S 与冻结逐位一致、V=0.65 档 + # 群伤组专锚(#A61D37):H/S 与冻结逐位一致、V=0.65 档 var aoe_f: Color = FROZEN["AOE"] var aoe_m: Color = UiKitScript.TG_GLOW_AOE Kit.check("群伤组专项:H 与冻结 #FF2D55 差 %.4f°(零移动)" % (absf(aoe_m.h - aoe_f.h) * 360.0), diff --git a/reports/iter30-反哺点-2026-10-17.md b/reports/iter30-反哺点-2026-10-17.md index 33f9f9ae..d2d4f7ba 100644 --- a/reports/iter30-反哺点-2026-10-17.md +++ b/reports/iter30-反哺点-2026-10-17.md @@ -6,8 +6,8 @@ | # | 文件 · 节 | 改成什么 | 依据 | |---|---|---|---| | 1 | `design/gdd/06-待办清单.md` :429-435 | ①「未开格类型微光」条目状态:待办 → **完成**(批末重闸全绿后);②:431「候选值,样张批冻结」色相措辞修正为「色相 = art-bible §4.2 样张 v2 冻结值(既裁),本批只动明度」——06 :431 自身 2026-09-30 口径已声明「只承载实施状态、不承载定义」,措辞修正属批内机械面;③:435 旧读数(bonus_pick_overlay 位点)刷新为现行读数;④明度档 provisional 值登记去向 = 第 4 条 art-bible 修订条目,复核义务移交样张卡 | Q2 甲案裁定;art-bible :66/:551 冻结依据;§5 行 1 | -| 2 | `design/gdd/systems/表现与支撑/HUD框架.md` :140 / :269 | ①:140 实装状态行「游戏内待实施批」→「**已实装(迭代 30 卡① 2026-10-17)**」;②:269 验收行去「待实施批落地后验收」括注、转正式验收行;③版本历史追加一行(同批体例) | Q4 丙案默认开已入库;§5 行 2 | -| 3 | `design/gdd/08-Alpha版本标准.md` 「五 · 表现」表 | 新增「未开格类型微光」行:待做 → **在役**;行内注「明度档 provisional 值(Q2 甲案),战斗一屏样张批复核转正」;版本历史追加 | Q2 甲案;Alpha 判据(阻塞主流程/无法联调才算 alpha 阻塞——呈现增强不属);§5 行 3 | +| 2 | `design/gdd/systems/表现与支撑/HUD框架.md` :140 / :269 | ①:140 实装状态行「游戏内待实施批」→「**已实装(迭代 30 卡① 2026-10-17)**」;②:269 验收行去「待实施批落地后验收」括注、转正式验收行;③文首状态行换代(同批体例) | Q4 丙案默认开已入库;§5 行 2 | +| 3 | `design/gdd/08-Alpha版本标准.md` 「五 · 表现」表 | 新增「未开格类型微光」行:待做 → **在役**;行内注「明度档 provisional 值(Q2 甲案),战斗一屏样张批复核转正」;文首状态行换代 | Q2 甲案;Alpha 判据(阻塞主流程/无法联调才算 alpha 阻塞——呈现增强不属);§5 行 3 | | 4 | `design/art/art-bible.md` §4.2 修订条目(Q2 项) | 以修订条目登记五组明度档 provisional 值:芥末黄 #F7DF43/黄绿 #68D042/青 #30A6A6/紫罗兰 #7B5BD6/绯红 **#A61D37**(冻结 #FF2D55 的 V=0.65 档,色相零移动);注明生成口径 = 渲染合成空间(伽马)阶梯、相邻组模型 CR 1.245/1.234/1.239/1.270、复核归样张批。§4.2/§4.6.3 权威面零改动;§2.1 修订条目不追加(Q5 甲案静态、条件分支不触发) | Q2 甲案;2026-10-17 停机呈报用户裁「换更暗档 #A61D37」留痕(实现报告 §二-1);§5 行 4 | | 5 | `roadmap.md` 迭代 30 行 | 编入笔已在案(2026-10-16 用户令);批内状态更新 = 卡① 完成(卡②样张批、卡③观感批串行待启),批末重闸 `--code` 全绿读数 | 三卡串行序位;§5 行 5 | | 6 | `design/gdd/06-待办清单.md`(Q3 甲案追加) | ①「卡顶带与格面带分工」说明写入文档注记面(art-bible §4.2 或 HUD框架 微光节):两带并存、TG_* 卡顶带管货架卡面、TG_GLOW_* 管未开格微光,禁互为引用;②另登 06 一条新待办「卡顶色带与格面微光两带统一」(TG_* 迁移 = 原 T3 条件卡内容,Q3 甲案不并入本批) | Q3 甲案(不并入);§5 行 6 | @@ -17,13 +17,13 @@ 七条全部回写完成(文档批 `iter30-fb-20261017`,2026-10-17): -- 第 1 条(06 待办清单)→ **已回写**:条目状态待办→已完成(入库 7ffd1dc0、冒烟 1151/0、单测 34 套、探针 case⑰、07 ㉘ 人闸五项);色相措辞修正为「样张 v2 冻结既裁值」;2026-10-05 实查读数刷新(bonus_pick_overlay.gd 已改名 curio_pick_overlay.gd:97、TG_* 五族在役 ui_kit.gd:49-53、裸 Color8 读数作废);明度档 provisional 值登记去向按第 4 条落 art-bible 版本历史 v3.15 -- 第 2 条(HUD框架)→ **已回写**:实装状态行转「已实装(迭代 30 卡① 2026-10-17 入库,合并 `7ffd1dc0`)」;验收行转正式验收(去「待实施批落地后验收」括注);版本历史追加 v0.19 -- 第 3 条(08)→ **已回写**:「五 · 表现」表新增「未开格类型微光(五组色相+明度档)」行(在役;明度档 provisional 值,样张批复核转正);版本历史追加 v1.9、文头状态行换代 -- 第 4 条(art-bible)→ **已回写**:五组明度档 provisional 值+生成口径(渲染合成空间伽马阶梯、相邻组模型 CR 1.245/1.234/1.239/1.270、判据线 1.20、实测最弱对 1.232、群伤暗档停机呈报留痕)落版本历史 v3.15;§4.2/§4.6.3 权威面零改动、§2.1 未追加(Q5 甲案静态);头注「现行为」漏更顺带订正 v3.11→v3.15 +- 第 1 条(06 待办清单)→ **已回写**:条目状态待办→已完成(入库 7ffd1dc0、冒烟 1151/0、单测 34 套、探针 case⑰、07 ㉘ 人闸五项);色相措辞修正为「样张 v2 冻结既裁值」;2026-10-05 实查读数刷新(bonus_pick_overlay.gd 已改名 curio_pick_overlay.gd:97、TG_* 五族在役 ui_kit.gd:49-53、裸 Color8 读数作废);明度档 provisional 值登记去向按第 4 条落 art-bible v3.15 文首登记 +- 第 2 条(HUD框架)→ **已回写**:实装状态行转「已实装(迭代 30 卡① 2026-10-17 入库,合并 `7ffd1dc0`)」;验收行转正式验收(去「待实施批落地后验收」括注);文首状态行换代 v0.19 +- 第 3 条(08)→ **已回写**:「五 · 表现」表新增「未开格类型微光(五组色相+明度档)」行(在役;明度档 provisional 值,样张批复核转正);文头状态行换代 v1.9 +- 第 4 条(art-bible)→ **已回写**:五组明度档 provisional 值+生成口径(渲染合成空间伽马阶梯、相邻组模型 CR 1.245/1.234/1.239/1.270、判据线 1.20、实测最弱对 1.232、群伤暗档停机呈报留痕)落 v3.15 文首登记;§4.2/§4.6.3 权威面零改动、§2.1 未追加(Q5 甲案静态);头注「现行为」漏更顺带订正 v3.11→v3.15 - 第 5 条(roadmap)→ **已回写**:迭代进度行与迭代 30 表行状态列同步卡①已入库(2026-10-17,7ffd1dc0;②③待 `/iter` 发令) - 第 6 条(06 Q3 甲案追加)→ **已回写**:两带分工注记落 HUD框架 微光节口径史注记后(卡顶带=条目级静态色带/格面微光=棋盘格内动态微光,禁互为引用);06 新增「卡顶色带与格面微光两带统一」待办条 -- 第 7 条(07)→ **已回写**:新增 ㉘ 节五项人闸(五组一眼可分/不遮数字〔环不外溢〕/出圈灭入圈复亮/整屏不脏/群伤暗档 #A61D37 观感〔provisional,读数归样张批〕),版本历史追加 v1.5 +- 第 7 条(07)→ **已回写**:新增 ㉘ 节五项人闸(五组一眼可分/不遮数字〔环不外溢〕/出圈灭入圈复亮/整屏不脏/群伤暗档 #A61D37 观感〔provisional,读数归样张批〕),文首状态行换代 v1.5 ## 附:不占反哺点条数的遗留(归实现报告 §六) diff --git a/reports/iter31-反哺点-2026-10-19.md b/reports/iter31-反哺点-2026-10-19.md index b864f871..ce991abf 100644 --- a/reports/iter31-反哺点-2026-10-19.md +++ b/reports/iter31-反哺点-2026-10-19.md @@ -24,7 +24,7 @@ | # | 位置 | 改成什么 | 依据 | |---|---|---|---| -| 11 | v3.18 版本历史行⑤与件表注「归独立批」指针 | 销号:代码侧已落地(删件/迁出/配额净删/引擎扩签/订阅式改写五项全落),指针改指本迭代合回 commit | 卡② §5 首行 | +| 11 | v3.18 登记⑤与件表注「归独立批」指针 | 销号:代码侧已落地(删件/迁出/配额净删/引擎扩签/订阅式改写五项全落),指针改指本迭代合回 commit | 卡② §5 首行 | | 12 | §1.3 异质性账清单 | 「完美资格」账的写法可补一句「豁免走订阅式自有累加账,不改写误标账」 | 卡② 契约 2 落地形态(实现无反哺新设计,仅既有陈述的换代) | ## 四、07-体验验证清单(`design/gdd/07-体验验证清单.md`) diff --git a/reports/需求卡片-ESC浮窗与营地顶栏批-2026-10-18.md b/reports/需求卡片-ESC浮窗与营地顶栏批-2026-10-18.md index 77bd5e2d..2891632b 100644 --- a/reports/需求卡片-ESC浮窗与营地顶栏批-2026-10-18.md +++ b/reports/需求卡片-ESC浮窗与营地顶栏批-2026-10-18.md @@ -206,4 +206,4 @@ --- -**修订记录**:v1.0→v1.1(2026-10-18 grilling 子 Agent 对抗审查回写)——事实订正 5 处:F9 刷新链路失实(营地刷新腿随 CampOverlay 退役、`_refresh_presentations` 是战斗侧腿)→契约 5 改挂卡④营地刷新单口+T2 刷新时机清单;E2「调试接口直改钥石」能力不存在(DebugOverlay 钥石只读)→改隔离存档实例直写(smoke 先例);F2 行号拆分(_open_settings :1055-1057);F8 :191→:192;估时算术 2.5–3.5d→3–4.5d。自扩订正:契约 2 标卡的从严收窄+Q3 请用户确认。卡内可收 8 项:契约 3 放宽语境分支、契约 7 遮挡结论+栈语义、契约 4 前提成文、T1 语境判据、T2 刷新时机+golden 联动、T3 探针宿主定 screen_flow_probe+badge 断言+变异补二条、V1 按 Q1 分拆、V4/V6/V8/V9 订补。跨卡对齐:HUD 刷新单口(§0 接口+卡④ T3 定义)、子界面返回钮承诺(Q1 甲案前提=卡④ T3)、终局落点不变量(T0 互证)、探针路径依赖卡②③链(§0)。新增待裁点 Q2 浮窗关闭路径、Q3 Esc 范围确认。用户面裁决(裁决 9/10)零改动。 +**审查回写要点**:v1.0→v1.1(2026-10-18 grilling 子 Agent 对抗审查回写)——事实订正 5 处:F9 刷新链路失实(营地刷新腿随 CampOverlay 退役、`_refresh_presentations` 是战斗侧腿)→契约 5 改挂卡④营地刷新单口+T2 刷新时机清单;E2「调试接口直改钥石」能力不存在(DebugOverlay 钥石只读)→改隔离存档实例直写(smoke 先例);F2 行号拆分(_open_settings :1055-1057);F8 :191→:192;估时算术 2.5–3.5d→3–4.5d。自扩订正:契约 2 标卡的从严收窄+Q3 请用户确认。卡内可收 8 项:契约 3 放宽语境分支、契约 7 遮挡结论+栈语义、契约 4 前提成文、T1 语境判据、T2 刷新时机+golden 联动、T3 探针宿主定 screen_flow_probe+badge 断言+变异补二条、V1 按 Q1 分拆、V4/V6/V8/V9 订补。跨卡对齐:HUD 刷新单口(§0 接口+卡④ T3 定义)、子界面返回钮承诺(Q1 甲案前提=卡④ T3)、终局落点不变量(T0 互证)、探针路径依赖卡②③链(§0)。新增待裁点 Q2 浮窗关闭路径、Q3 Esc 范围确认。用户面裁决(裁决 9/10)零改动。 diff --git a/reports/需求卡片-主菜单三入口化批-2026-10-18.md b/reports/需求卡片-主菜单三入口化批-2026-10-18.md index 62adcc96..611406a1 100644 --- a/reports/需求卡片-主菜单三入口化批-2026-10-18.md +++ b/reports/需求卡片-主菜单三入口化批-2026-10-18.md @@ -186,4 +186,4 @@ --- -**修订记录**:v1.0→v1.1(2026-10-18 grilling 子 Agent 对抗审查回写)——事实订正:F10 探针影响面从「五探针」重列为 20+ 位点全量表(漏列 fx_shot/t17_defer/ui_tune/ui_input/layout/ui_click 断点段/ui_struct resume 专项/shot_probe career+level 段/smoke V2d/V3g/V3i 等);F5 `_refresh_resume_button` 消费面补全并补列 camp_shop_presenter.gd 实施本体;F12 art-bible :433 合并条款 excision 表述订正;F11 补 render_gate 菜单 golden 段与 golden_baseline_refresh.sh --menu;新增 F13(07 两处引述)。自扩标注:契约 5「同批或在先」标卡内推导、契约 6 标仓库纪律成文。卡内可收:契约 5 补卡④中间态条款、§9 第 1 条组帽必撤明写、§9 第 2 条删除面订正(卡④不复用)、V5 ConfirmDialog 多消费方表述、V 表补既有断言族/左列几何/七屏链三项。用户面裁决(裁决 1)零改动。 +**审查回写要点**:v1.0→v1.1(2026-10-18 grilling 子 Agent 对抗审查回写)——事实订正:F10 探针影响面从「五探针」重列为 20+ 位点全量表(漏列 fx_shot/t17_defer/ui_tune/ui_input/layout/ui_click 断点段/ui_struct resume 专项/shot_probe career+level 段/smoke V2d/V3g/V3i 等);F5 `_refresh_resume_button` 消费面补全并补列 camp_shop_presenter.gd 实施本体;F12 art-bible :433 合并条款 excision 表述订正;F11 补 render_gate 菜单 golden 段与 golden_baseline_refresh.sh --menu;新增 F13(07 两处引述)。自扩标注:契约 5「同批或在先」标卡内推导、契约 6 标仓库纪律成文。卡内可收:契约 5 补卡④中间态条款、§9 第 1 条组帽必撤明写、§9 第 2 条删除面订正(卡④不复用)、V5 ConfirmDialog 多消费方表述、V 表补既有断言族/左列几何/七屏链三项。用户面裁决(裁决 1)零改动。 diff --git a/reports/需求卡片-二三关棋盘观感批-2026-10-16.md b/reports/需求卡片-二三关棋盘观感批-2026-10-16.md index de31174b..4ce4b3f1 100644 --- a/reports/需求卡片-二三关棋盘观感批-2026-10-16.md +++ b/reports/需求卡片-二三关棋盘观感批-2026-10-16.md @@ -4,7 +4,7 @@ - **指路订正(2026-10-20)**:徽章卡(迭代 30 卡①)已按 doc-conventions §11「吸收即死」退役,本卡对其三处指路句改为结论内联+提交号 `7ffd1dc0`,裁决内容零变更。 - 来源:[06-待办清单](../design/gdd/06-待办清单.md)「第二 / 三关棋盘观感——亮度与对比度」小节(2026-10-13 用户裁定条)+ [playnote](../design/research/playnote.md) 用户试玩原始记录:「UI优化,第二第三关的棋盘看着太累了;不知道是因为亮度还是对比度的原因,看着非常费劲,非常不舒服」 - 归属:**表现层美术修批**(06 在册条目直接写卡;两轴归属 = [HUD框架](../design/gdd/systems/表现与支撑/HUD框架.md)(UI 轴)+ [美术圣经](../design/art/art-bible.md)(素材轴),定性前两方共裁——沿用 06 条裁决) -- 排期:**已编入迭代 30(2026-10-16 用户令编入,roadmap 行已在案;批内状态刷新列反哺点)**。同迭代三卡串行序位第 3:未开格类型徽章批卡(迭代 30 卡①,已入库合并 7ffd1dc0,卡片已退役)→[战斗一屏样张批卡](需求卡片-战斗一屏样张批-2026-10-16.md)→本卡(徽章→样张→观感)。**并行例外**:本卡 T1/T1b 采样与定性读数允许与前两卡并行穿插——依据=采样是只读动作(出帧/读数/样张均不触碰 golden 三张、样张主板、§5 同步面文档等汇聚文件),落码修改(T2 起)仍按上述序位串行。开工门 = U0,须用户 `/iter` 发令;且 T1 出口定性人闸未过之前禁止动码——该闸 = [06 本条](../design/gdd/06-待办清单.md)既有裁决硬步骤(「开工前先过『素材轴 / UI 轴』定性人闸」,2026-10-13 用户裁定;[08 版本历史](../design/gdd/08-Alpha版本标准.md) v0.3 同款注),**不是待裁点**(v1.1 撤销原 Q1,见 §10)。 +- 排期:**已编入迭代 30(2026-10-16 用户令编入,roadmap 行已在案;批内状态刷新列反哺点)**。同迭代三卡串行序位第 3:未开格类型徽章批卡(迭代 30 卡①,已入库合并 7ffd1dc0,卡片已退役)→[战斗一屏样张批卡](需求卡片-战斗一屏样张批-2026-10-16.md)→本卡(徽章→样张→观感)。**并行例外**:本卡 T1/T1b 采样与定性读数允许与前两卡并行穿插——依据=采样是只读动作(出帧/读数/样张均不触碰 golden 三张、样张主板、§5 同步面文档等汇聚文件),落码修改(T2 起)仍按上述序位串行。开工门 = U0,须用户 `/iter` 发令;且 T1 出口定性人闸未过之前禁止动码——该闸 = [06 本条](../design/gdd/06-待办清单.md)既有裁决硬步骤(「开工前先过『素材轴 / UI 轴』定性人闸」,2026-10-13 用户裁定;[08 git 提交史](../design/gdd/08-Alpha版本标准.md) v0.3 同款注),**不是待裁点**(v1.1 撤销原 Q1,见 §10)。 - **立场前提(用户原话,本卡设计的第一约束)**:此条立项原因就是用户实机觉得现在的画面累眼、且对「纯程序化重产现状」明确不满——「如果还是用原有方式弄出来的东西,有没有可能还是我不满意的?」。本卡对此的正面回应 = ①第一步定性用**可量化的读数归因**(明度直方图 / 相邻格对比 / 高频能量 / WCAG 对),禁止凭感觉猜轴;②两条修法各自的产出物写清**相对现状新增什么**(§6 T2 两案效果上限表);③**诚实的效果声明**:观感是主观项,机检只能证伪(读数红 = 必有问题)不能证真(读数绿 ≠ 用户满意),**阻塞性人闸全部前置**(T1 定性闸 + 契约 4 方向闸),入库后实机目检按 2026-10-12 用户令口径**登记不阻塞**——目检项登记进 `reports/iter30-实现报告-<完成日>.md` 实机目检总清单(「入册 07」列反哺点;[AGENTS.md](../AGENTS.md) 红线「真人检测只登记不阻塞——禁以等目检为停工理由」口径不变),用户复判否决走 §7 V4 回补机制(行回待做 + 06 立残留条,落文按 v3 口径归文档批)。防「改一轮还是不满意」的机制 = **先出改前/改后并排对比读数样张给用户定性确认方向,方向过了人闸才落码**(🔴 契约 4)——方向若被否决,返工停在样张层,不烧落码与基线。 --- @@ -248,7 +248,7 @@ **统一来源(逐条留痕均引此令)**:「2026-10-16 用户令:三卡全部待裁项按推荐方案裁决(用户将裁权授出,由主线会话代拍板留痕)」。以下 Q2/Q3 各行引该令留痕;两案选项原文照录,供后续复看。 -**已裁移除项(原 Q1「定性报告要不要用户过目才进 T2」)——撤销结论不动(2026-10-16 用户令未触及,维持 grilling 结论)**:06 本条条内已明文裁决——「开工前须先定性(沿用既有裁决)……**开工前先过『素材轴 / UI 轴』定性人闸**」(06:449/:453,2026-10-13 用户裁定条;08 版本历史 v0.3 同款注「P2 棋盘观感标『Alpha 阶段需完成 · 开工前过素材轴/UI 轴定性人闸』」)。「要不要过闸」不成立为问句,本卡处置 = 落为 T1 出口**流程硬步骤**(P1/V1),闸上同时冻结轴归因与 V2 目标带数值——**既裁人闸,不占裁点**。 +**已裁移除项(原 Q1「定性报告要不要用户过目才进 T2」)——撤销结论不动(2026-10-16 用户令未触及,维持 grilling 结论)**:06 本条条内已明文裁决——「开工前须先定性(沿用既有裁决)……**开工前先过『素材轴 / UI 轴』定性人闸**」(06:449/:453,2026-10-13 用户裁定条;08 的 git 提交史同款注「P2 棋盘观感标『Alpha 阶段需完成 · 开工前过素材轴/UI 轴定性人闸』」)。「要不要过闸」不成立为问句,本卡处置 = 落为 T1 出口**流程硬步骤**(P1/V1),闸上同时冻结轴归因与 V2 目标带数值——**既裁人闸,不占裁点**。 ### Q2 · 素材轴修法走哪案:程序换色重校(甲)还是瓦片重产(乙)?——**延裁留痕** @@ -284,7 +284,7 @@ | 4 | recolor 能力边界 | 头注方法=仅对 `terrain_*_dungeon.png` 按 wall/facade/floor/crater 四族槽重映射、输出 underdark/deep_underdark 两套;实盘 board/ 目录两套各 21 件(**墙 16+地 5**)与脚本输入面完全对齐,`flag_seal.png` 不在输入面。v1.0 F2「墙类 21 件」**件数错**(21 为总数,16 唯一墙名单单点 `TILE_WALL_NAMES`)。「纹理太碎调不动」有实证:recolor 头注定死亮度秩序逐像素保持(方法学上限)+ 2026-10-14 美术审计结论区「第二/三关地面=近黑斑加亮筋双峰纹理,盯久了累,不是再叠一层界面能救的」(该审计 md 在盘;同日另存 2026-10-06 旧审计 HTML,其棋盘相关结论未涉 L2L3 瓦片碎度) | `tools/recolor_terrain_tiles.py:1-12`;`game/presentation/views/board_view.gd:81-88`(16 件名数组+头注「16 唯一墙瓦片名单」);`design/research/美术审计-cursor会话存档-2026-10-14.md` 结论区;Glob `game/assets/art/board/` 两套件名清点 | F2 订正件数+flag_seal 例外注;甲案行写明输入面全覆盖;T1 归因判据与 Q2 引审计实证 | | 5 | 文字位条分工句 | 06:451 原文在册:「两条不同面,不互相替代,各自保留」;三处文字位=站桩名行/敌顺位徽标/RAP 反馈行,06:443 已随迭代 26 T3 完成——v1.0 P2 语义与原文一致 | 06:451, :437-443 | P2 补原文引述 | | 6 | V 条判具 | V2=样张 v3(主板)+T1b 分关读数+shot_checker A–D**+F**(v1.0 漏 F 判据,2026-10-15 已入闸)+`terrain_tile_sets_test`/`ui_contrast_probe`(两探针实存);V3=`golden_baseline_refresh.sh` **实存**且用法查明:缺省模式=棋盘三张(probe 抓帧→crop→覆盖 `game/tests/golden/`),`--menu`=菜单全屏,素材缺位拒跑,呈现批 agent 自换代+提交说明强制写触发原因(其头注 Q5/Q6/S3 在册) | `tools/golden_baseline_refresh.sh:2-14, :52-76`;`tools/shot_checker.py:8-19` | C5/契约 6/T4/V2/V3 补齐实操步骤与 F 断言 | -| 7 | Q1/Q3 已裁检索 | **Q1 属已裁项**:06:449 条内明文「开工前须先定性(沿用既有裁决)」+ 状态行「开工前先过定性人闸」(2026-10-13 用户裁定)+ 08 版本历史 v0.3 同款注——v1.0 一边在 P1 引该裁决、一边把同一闸列为 Q1 待裁,自相矛盾,触用户红线。Q3(同批与否)与 Q2(甲/乙)全库检索**无既裁**(06 单条覆盖两关但未裁批次数;playnote 无;git log 无)——保留为待裁 | 06:445-453;08:220(v0.3);playnote.md:5;git log 2026-10 检索 | Q1 从 §10 删除、改 P1/T1 出口/V1 流程硬步骤引用(§10 载明移除理由);Q2/Q3 保留 | +| 7 | Q1/Q3 已裁检索 | **Q1 属已裁项**:06:449 条内明文「开工前须先定性(沿用既有裁决)」+ 状态行「开工前先过定性人闸」(2026-10-13 用户裁定)+ 08 的 git 提交史同款注——v1.0 一边在 P1 引该裁决、一边把同一闸列为 Q1 待裁,自相矛盾,触用户红线。Q3(同批与否)与 Q2(甲/乙)全库检索**无既裁**(06 单条覆盖两关但未裁批次数;playnote 无;git log 无)——保留为待裁 | 06:445-453;08:220(v0.3);playnote.md:5;git log 2026-10 检索 | Q1 从 §10 删除、改 P1/T1 出口/V1 流程硬步骤引用(§10 载明移除理由);Q2/Q3 保留 | | 8 | 中立性 | v1.0 四处「推荐」:Q1(已裁项附裁决,撤销后消失)、T1 出口句(撤销)、T3「推荐=同批」与 §10 Q3「推荐 甲」(**无既裁依据→中立化**)、Q2 立场句「开工默认先做甲案候选样张」(改写为白名单内样张层探针动作,非路线裁决) | 全文 grep 推荐=0 残留(仅剩「已删字样」自述与列名注) | 列头改「卡片立场(不代裁)」;§10/§6 T3 中立化 | | 9 | 跨卡依赖 | 两卡同抢 L2/L3 板面:徽章批(类型微光实装者,其 T0-② 五组明度档以未开格底 L≥0.30 为基线——本卡改的正是该基线;art-bible :379 已册「格底与微光同在未开格面,邻近色相有吞没风险」互辨复测义务;其 §4「不动格底/瓦片/四槽」系单向避撞);样张批(Q1 丙案语义=样张反提素材规格、Q3 路线选型——本卡乙案重产与其冻结次序互锁) | `徽章卡(迭代 30 卡①,合并 7ffd1dc0,卡片已退役):13/82/109`;`需求卡片-战斗一屏样张批:33/59/70-71/168/170`;art-bible:379 | 新增 **§4B 跨卡依赖**(X1/X2/X3 三行+结论笔:次序与规格联动问题,不新增裁点,随 Q2/Q3 呈报交用户定序);§8 L3 增⑥跨卡次序破裂停机型 | | 10 | 外加翻案(非清单内,敌意自查所得) | **契约 5/完成定义 3/V4/T5「目检未过禁宣布完成/在役」与 2026-10-12 用户令红线冲突**:AGENTS.md「真人检测只登记不阻塞——禁以等目检为停工理由」(入库先例:迭代 25/26/28 均入库翻行、07 目检留残,git 提交 d337c9e5 立规)。另:F1「L1 10×10」不全——`board_gen.tres` level_index 1 段含一行 **12×12 dungeon**;F10/C6:类型微光引擎未实装(徽章批 F2 引 HUD框架实装状态行佐证),v1.0 把它当实机可测层不成立 | AGENTS.md:68;git log d337c9e5;roadmap 迭代 25/28 行「残留人闸=目检」先例;`game/data/tables/board_gen.tres` 行段实查 | 契约 5 重写(阻塞闸全前置:T1 定性闸+契约 4;V4 改登记不阻塞+回补机制:否决→08 行回待做+06 记残留重开);F1 补两板型注;F10/T1 微光测面降为样张 v2 证据级别并注升级路径 | diff --git a/reports/需求卡片-存档制数据层改造批-2026-10-18.md b/reports/需求卡片-存档制数据层改造批-2026-10-18.md index 14d43a7b..c81ed365 100644 --- a/reports/需求卡片-存档制数据层改造批-2026-10-18.md +++ b/reports/需求卡片-存档制数据层改造批-2026-10-18.md @@ -1,6 +1,6 @@ # 需求卡片:存档制数据层改造批(隐式单档 → 3 存档位)· 营地交互重做卡① -- 版本:**v1.2**(2026-10-18 grilling 轮次裁定回写——Q1 旧档归属裁定甲〔迁 1 号位,代拍板留痕〕、Q2 交付序列裁定甲〔推荐案,用户令按推荐执行〕;卡④回设计段不影响本卡链路——卡③在工程批内;v1.1 审查回写内容见文末修订记录) +- 版本:**v1.2**(2026-10-18 grilling 轮次裁定回写——Q1 旧档归属裁定甲〔迁 1 号位,代拍板留痕〕、Q2 交付序列裁定甲〔推荐案,用户令按推荐执行〕;卡④回设计段不影响本卡链路——卡③在工程批内;v1.1 审查回写内容见文末审查回写要点) - 来源:[需求澄清-营地交互重做-2026-10-18.md](../design/research/需求澄清-营地交互重做-2026-10-18.md)(唯一事实源:④结构树「选档界面:3 存档位,新档/进档/删档」、⑤裁决 2/3/4、⑦切批原则①)+ [存档序列化](../design/gdd/systems/表现与支撑/存档序列化.md) P2 后置条 - 归属:数据层承载面(`game/core/save_manager.gd`)——营地交互重做五卡之一;用户可见面由卡③(选档界面)承载 - 排期:未编入(2026-10-18 用户令:需求卡片不预占迭代号,批次归属按工作量另裁) @@ -192,4 +192,4 @@ --- -**修订记录**:v1.0→v1.1(2026-10-18 grilling 子 Agent 对抗审查回写)——事实订正:F6 注入路径 6→18 条并补全清单面、F8 出处改引 iter30 实现报告、F7 行号 :16→:20;启动激活态闭环:_ready 初态钉死(T1/完成定义 3)、切槽实例同一性(契约 6)、写盘目标与无激活拒绝(契约 6/T2);新增契约 9 窥视三态;S-1「启动不隐式激活」降格条件化、S-2「盘面即时生效」标卡内工程规定;隔离面清点扩为全清单(T0);Q1 补执行前置检查列;验收补启动态/各槽迁移/旧档机检三类断言与两类变异注入;新增待裁点 Q2 交付序列。用户面裁决(裁决 2/3/4)零改动。 +**审查回写要点**:v1.0→v1.1(2026-10-18 grilling 子 Agent 对抗审查回写)——事实订正:F6 注入路径 6→18 条并补全清单面、F8 出处改引 iter30 实现报告、F7 行号 :16→:20;启动激活态闭环:_ready 初态钉死(T1/完成定义 3)、切槽实例同一性(契约 6)、写盘目标与无激活拒绝(契约 6/T2);新增契约 9 窥视三态;S-1「启动不隐式激活」降格条件化、S-2「盘面即时生效」标卡内工程规定;隔离面清点扩为全清单(T0);Q1 补执行前置检查列;验收补启动态/各槽迁移/旧档机检三类断言与两类变异注入;新增待裁点 Q2 交付序列。用户面裁决(裁决 2/3/4)零改动。 diff --git a/reports/需求卡片-战斗一屏样张批-2026-10-16.md b/reports/需求卡片-战斗一屏样张批-2026-10-16.md index 280c20a3..923528b0 100644 --- a/reports/需求卡片-战斗一屏样张批-2026-10-16.md +++ b/reports/需求卡片-战斗一屏样张批-2026-10-16.md @@ -22,7 +22,7 @@ | P1 | 格子样张 v3 已冻结(2026-09-30,机检 17/17 全绿,四冻结①④重冻生效)。整屏四项的**机检代码在位且已对实机渲染帧跑过**(B 文字对比/C 明度三档带/D 文字禁压纹理+F 文字在判据),**唯 ③整屏焦点预算明文不可机检(E 段归人闸)**;§1.4 意义上的「整屏样张判定物」与四屏冻结记录两件从未产出 | [art-bible](../design/art/art-bible.md) §1.4(L64 闸条款/L68 v3 冻结记录);[shot_checker.py](../tools/shot_checker.py) 头注 L1-25;git 提交 053baeee(iter9-T8 卡⑤ 首跑实测 PASS);[render_gate.sh](../tools/render_gate.sh) ①段 L11-13 | | P2 | 现行 v3 脚本头注自称「战斗一屏样张方向稿生成脚本 v3-draft」,实际出的是 B/C/D 三区 1280×800 全内容合成图 + S2/S3/S4 附录 + A1–A6 程序化审计——但**冻结记录登记在格子样张闸名下**(圣经 §1.4 v3 段),且它验的是「格+一张合成 mockup」,不是「屏级气质判定物 + 四项逐项断言 + 冻结记录」三件齐 | [render_sample_sheet_v3.py](../tools/render_sample_sheet_v3.py) 头注 L2、L28「一屏样张 = B/C/D 三区全内容(1280×800 1:1 实比)」、L1100-1144 版式与断言清单;art-bible §1.4 L68 | | P3 | 看板十五件:✅4 / ◐8 / ⬜3(实点计数核过);「战斗一屏样张」行 = ⬜ 未开始,需求文档指针为战斗表现 + art-bible §5.1。**注:§5 已抽离至 [character-design.md](../design/art/character-design.md)(v1.7 批),指针系旧锚;同型旧锚另有 06:41「归属」栏一处**(写作「验收标准归战斗表现与美术圣经 §5.1 共裁」——正确锚应为 §1.4 整屏闸+§7.2 文字硬指标,§5.1 只管剪影轮廓),T0 两处一并订正 | [art-status-checklist.md](../design/art/art-status-checklist.md) L5/L13-14;06:41 | -| P4 | 旧冻结样张产物 `sample-batch-v3-final-2026-09-30.png` 磁盘实测不在盘(`artwork/mockups/` 现存 v0/v2/v31/v32/v33/v34/v35-draft 等同系列图与 level-map-sheet-v1),06 在册 P0①(死指涉条,其原记状态至 2026-10-16 前悬而未决)**已由 Q5 裁甲案(2026-10-16 用户令),处置落 T0**(2026-10-14 审计会话存档 :290/:316 仍记「未读到」)。**订正:06:611 原文写「art-bible 第 68/527 行」,现行为 68 与 562**(527 行实为 §9.1 正面参考表,不含该指涉;562=v3.2 版本历史行)——T0 订正面对 art-bible:68/:562 与 06:611 的行号自身一并核。**同类死指涉另检出一处(v1.1 新增)**:art-bible §8.2 L490 指路 `design/qa/m3-iter9-t8-rulings-2026-09-30.md`(迭代 9 三裁决呈报单)该文件已在提交 8e02dcf0「存量超期清理批」删除,盘上不存在——裁决结论本身已由 art-bible §8.2/§8.4 与 06:465-471 承载,指路须改指现行文档或改「描述性出处」 | 2026-10-16 目录实查;06:609-615;design/research/美术审计-cursor会话存档-2026-10-14.md:290,:316;git 只读查询(053baeee 建件/8e02dcf0 删件) | +| P4 | 旧冻结样张产物 `sample-batch-v3-final-2026-09-30.png` 磁盘实测不在盘(`artwork/mockups/` 现存 v0/v2/v31/v32/v33/v34/v35-draft 等同系列图与 level-map-sheet-v1),06 在册 P0①(死指涉条,其原记状态至 2026-10-16 前悬而未决)**已由 Q5 裁甲案(2026-10-16 用户令),处置落 T0**(2026-10-14 审计会话存档 :290/:316 仍记「未读到」)。**订正:06:611 原文写「art-bible 第 68/527 行」,现行为 68 与 562**(527 行实为 §9.1 正面参考表,不含该指涉;562=v3.2 登记行)——T0 订正面对 art-bible:68/:562 与 06:611 的行号自身一并核。**同类死指涉另检出一处(v1.1 新增)**:art-bible §8.2 L490 指路 `design/qa/m3-iter9-t8-rulings-2026-09-30.md`(迭代 9 三裁决呈报单)该文件已在提交 8e02dcf0「存量超期清理批」删除,盘上不存在——裁决结论本身已由 art-bible §8.2/§8.4 与 06:465-471 承载,指路须改指现行文档或改「描述性出处」 | 2026-10-16 目录实查;06:609-615;design/research/美术审计-cursor会话存档-2026-10-14.md:290,:316;git 只读查询(053baeee 建件/8e02dcf0 删件) | | P5 | 素材不入 git(归档纪律 art-bible §8.3 L500),v3 脚本 `asset_root()` 做「本仓库→主检出 D:/code/g-plan2」两级回退,且 OUT_PNG 落笔前 `os.makedirs(..., exist_ok=True)`——**故 worktree 分支内可直接跑(v1.0 的「不可直接跑」判断证伪)**;真实约束是**产物落进该 worktree 的 `artwork/mockups/`,而 `artwork/` 整目录不入库**,冻结件不随合并进 master,须按 §8.3 归档纪律打包(这亦是 P4 丢件的成因)。素材在盘实测:board 瓦片 64 件、character 立绘/小人、`game/assets/ui/icons` 状态图标 18 件、fusion-pixel 字体齐 | 脚本头注 L31 + `asset_root` L50-56 + L62/L1147-1149;art-bible §8.3 L500;2026-10-16 目录实查 | | P6 | 样张 v1 曾被用户**四原因整体否决**(2026-09-28),四条已全部断言化。**权威映射表在脚本写报告的那段代码里(L1156-1160),不在头注**——头注只逐条标了 ①③ 的编号,②④ 需从映射表补:①**显示太丑(总纲)**→ A6 观感密度+装饰变体 ≥2 种;②**封印色冲突**→ 封印黑 #000000(A1a 色板对表自动覆盖);③**立体感不够**→ A3 图底分离阈值上调+F6 顶面/立面双明度带 Δ≥18+F7 整板悬崖 DEPTH_PX 与游戏渲染常量同源;④**微光格只留微光**→ F5c 微光段零 draw_inlay(另见 art-bible v2.12 角嵌退役批)。注:脚本头注 L23 仍写 A3 Δ≥55、L1157 仍写「整板明度 std ≥50.9」,两处均是**旧口径残留文本**,现行定值以圣经 §1.4 v3 记录为准(A3b Δ≥30、A6 明度梯度均值 ≥4.70) | 脚本 L12-26(F1–F7/A1–A6 头注)+L1156-1160(四否决映射表);art-bible L68(Δ≥30 定值)/L570(v2.13「v1 四否决原因断言化收官」)/L569(v2.12 ④) | | P7 | 用户气质否决另有两例点名先例:①站桩排版旧格式「盒顶固定 y 与盒内居中在高盒下拉开血条-立绘空洞」2026-10-06 用户点名否决,由 art-bible §8.2「站桩立绘排版 = 方案二」代替(L496);②playnote 立绘批评,**逐字原文**:「现在的立绘太丑了,像素化的粒度太低了,导致根本看不清立绘;看是否可以改回用较为高清的图片?」(playnote.md:9,文件本身无日期;日期系 06「资产升档重产批」条 2026-10-06 注所记「同日 playnote 立绘批评」,裁定日为 2026-10-13 归美术线) | [playnote.md](../design/research/playnote.md):9;art-bible §8.2 L496;06:465-471/06「立绘清晰度回退评估」条 | @@ -243,7 +243,7 @@ |---|---|---|---| | D1 | **类型微光色值与明度档的冻结口径** | 徽章卡(迭代 30 卡①,已入库合并 7ffd1dc0,卡片已退役)Q2 与其 S6 行 | **已改实(2026-10-16 用户令:三卡全部待裁项按推荐方案裁决〔用户将裁权授出,由主线会话代拍板留痕〕——徽章卡 Q2 已裁甲案:明度档取 provisional 值)**:「徽章卡 Q2 先裁」义务随其裁定关闭;**其复核转正义务落本卡样张冻结件**——本卡 T2 新增 H5 组间明度档复核+组间互辨抽测、T3 呈转正结论、写入完成定义第 2 条交付义务(见 §1/§3)。事实核对保留为对表依据:五组**色相**确已随样张 v2 定稿(art-bible §4.2 L218「样张 v2 定稿(2026-09-28)」+HUD框架:140 同记——「样张 v2 已冻结」与 08「战斗一屏样张=待做」并不矛盾:前者是**格子样张**序列(§1.4 L66/L68),后者是**整屏样张**序列(§1.4 L64),两条序列各有其闸),本卡不承接色相重冻义务;「徽章卡若裁乙(等本卡总闸)」分支不再发生。**本卡禁把色相值列进 Q 项**(已按契约 6 关闭) | | D2 | **棋盘瓦片重产 vs 换色**(素材线同一入口) | [二三关棋盘观感卡](需求卡片-二三关棋盘观感批-2026-10-16.md) Q2(甲 recolor 换色 / 乙 远程生图重产) | **已改实(2026-10-16 用户令)**:序位裁定=徽章→样张→观感、本卡位第 2——观感卡排本卡之后,「同窗呈报两案代价」义务关闭;该卡 L2/L3 落地对本卡整屏②明度三档带与 A6 观感密度读数的复核,属该卡开工时按其 V2(A6 ≥4.70 保持)自跑的复验项,本卡冻结记录注明本样张基线读数供其对表即可;本卡 Q1 已裁丙案(非乙案),与其 Q2 各案不再有工期串行耦合 | -| D3 | **触碰面重叠与合入次序** | 三张卡共同 | 三卡都写 06/08/07/art-bible 版本历史/roadmap/active.md,徽章卡另动 `presentation/views`+冒烟,本卡另动 `tools/` 样张面。按 roadmap.md:93「单迭代串行」与 roadmap.md:101「一迭代 = 一次合并登记」⇒ 三卡禁止三线并行。**已改实(2026-10-16 用户令):三卡串行序位=徽章→样张→观感,本卡位第 2**;「一次合并、批内分波」组织方式随序位裁定确定,v1.1「不预设结论、归用户排期令」呈报框架关闭。**v1.3 注**:三卡文档直写义务已按文档同步闸 v3 全部转反哺点(落 `reports/`),汇聚文件重叠消解,但串行序位裁定不失效——golden 基线与冻结内容的先后依赖仍在(D1/D2) | +| D3 | **触碰面重叠与合入次序** | 三张卡共同 | 三卡都写 06/08/07/art-bible 的 git 提交史/roadmap/active.md,徽章卡另动 `presentation/views`+冒烟,本卡另动 `tools/` 样张面。按 roadmap.md:93「单迭代串行」与 roadmap.md:101「一迭代 = 一次合并登记」⇒ 三卡禁止三线并行。**已改实(2026-10-16 用户令):三卡串行序位=徽章→样张→观感,本卡位第 2**;「一次合并、批内分波」组织方式随序位裁定确定,v1.1「不预设结论、归用户排期令」呈报框架关闭。**v1.3 注**:三卡文档直写义务已按文档同步闸 v3 全部转反哺点(落 `reports/`),汇聚文件重叠消解,但串行序位裁定不失效——golden 基线与冻结内容的先后依赖仍在(D1/D2) | | D4 | **门禁语义改动的先后** | 迭代 29 测试分层与门禁语义修正批 | **已结案(2026-10-16 合入 master,合并提交 fff4f120;roadmap.md:88 状态=✅ 已入库)**:该批改的 `tools/run_all_gates.sh`/探针判定/退出码权威语义(其契约 2「三硬闸不可绕过」)已在现行闸内生效,本卡 V7 的闸口径直接按当期语义执行(本批 → `--code`)并按其当期读数采基线;原「该批先行/本卡先行」两种分支随之消解,本卡仍不改写任何判定脚本。(原两分支表述留档供沿革查 git log) | | D5 | **08 表现表同一表的多行改写** | 三卡+08 v1.6 定稿纪律 | 08 头注 L5 明文「Alpha 内容范围冻结,增删条目须经用户裁决」——三卡都只有**改状态列**的权限,**无一行可新增/删除**;本卡 T5 回写仅动「战斗一屏样张」一行,若需要为新条目动集合,一律 L3 呈报。**v1.3 注**:该「回写」执行为反哺点条目(仅动该行的改写要求照录进清单),零直改 | @@ -272,7 +272,7 @@ ## 9. grilling 审查记录(v1.1,2026-10-16,对抗审查员;逐攻击面给结论/证据/处置) -**审查方法**:卡片每一处引用逐一开文件核行号与措辞;Q1–Q6 逐条全库检索既有条款与裁决(design/gdd/06、08 及其版本历史、design/art/art-bible.md、character-design.md、art-status-checklist.md、systems/战斗循环/战斗表现.md、systems/表现与支撑/HUD框架.md、ux/battle.md、design/research/playnote.md、roadmap.md、active 侧状态记录残留、`tools/` 与 `game/` 实码、git 只读历史);与迭代 30 另两张并行卡逐 Q 比对互斥面。**只编辑本卡,未动任何其他文件;git 仅只读查询。** +**审查方法**:卡片每一处引用逐一开文件核行号与措辞;Q1–Q6 逐条全库检索既有条款与裁决(design/gdd/06、08 及其 git 提交史、design/art/art-bible.md、character-design.md、art-status-checklist.md、systems/战斗循环/战斗表现.md、systems/表现与支撑/HUD框架.md、ux/battle.md、design/research/playnote.md、roadmap.md、active 侧状态记录残留、`tools/` 与 `game/` 实码、git 只读历史);与迭代 30 另两张并行卡逐 Q 比对互斥面。**只编辑本卡,未动任何其他文件;git 仅只读查询。** ### G1 事实引用核实(攻击面 1) @@ -331,6 +331,6 @@ ### G9 审查中判定为「本卡无权处置、已登记呈报」的文档面 -`tools/render_sample_sheet_v3.py` 头注 L23/L1157 旧口径残留文本;06:39「尺子还没造出来」与 shot_checker 现状有差;06:41/checklist:14 的 §5.1 旧锚;06:611 行号读数(68/527 应为 68/562);**art-bible §8.2 L490 指路 m3-iter9-t8-rulings 文件已在 8e02dcf0 删除(死指涉第二例,属 Q5 同族,处置口径与 Q5 同案在本批一并呈报)**;战斗表现:83/:116「四区」旧措辞;art-bible 头注 L3 仍写「现行为 v3.11」而版本历史已到 v3.14。**以上均为他文件文本,本审查一律未改**,只作为本批 T0 订正面对表登记;其中头注版本号与他文档措辞是否订正,归各文档自身纪律与用户裁决。 +`tools/render_sample_sheet_v3.py` 头注 L23/L1157 旧口径残留文本;06:39「尺子还没造出来」与 shot_checker 现状有差;06:41/checklist:14 的 §5.1 旧锚;06:611 行号读数(68/527 应为 68/562);**art-bible §8.2 L490 指路 m3-iter9-t8-rulings 文件已在 8e02dcf0 删除(死指涉第二例,属 Q5 同族,处置口径与 Q5 同案在本批一并呈报)**;战斗表现:83/:116「四区」旧措辞;art-bible 头注 L3 仍写「现行为 v3.11」而当时文末变更表已到 v3.14。**以上均为他文件文本,本审查一律未改**,只作为本批 T0 订正面对表登记;其中头注版本号与他文档措辞是否订正,归各文档自身纪律与用户裁决。 > **v1.3 口径换代注(2026-10-17 文档同步闸 v3)**:本节为 v1.1 时点的审查实录,原文不重写;其中「doc 三闸」一类闸件枚举字样与「写入文档/登记 06」类落文表述,按 v3 口径只读为历史记录——闸清单与域划分的唯一出处恒为 `tools/run_all_gates.sh`(本批按改动域跑 `--code` 档),文档落文一律列进 `reports/iter30-反哺点-<完成日>.md` 归文档批。 \ No newline at end of file diff --git a/reports/需求卡片-营地场景图新建批-2026-10-18.md b/reports/需求卡片-营地场景图新建批-2026-10-18.md index 68f400f8..119bdbd8 100644 --- a/reports/需求卡片-营地场景图新建批-2026-10-18.md +++ b/reports/需求卡片-营地场景图新建批-2026-10-18.md @@ -305,4 +305,4 @@ --- -**修订记录**:v1.0→v1.1(2026-10-18 grilling 子 Agent 对抗审查回写)——事实订正 6 处:E1「48 色工具全仓不在役」→截屏级不在役/素材级二器在役(F17/§9-5/V10/T5 连带);E2「camp golden」五处不存在→删并立契约 10 不建;E3 F7 行号(_start_adventure :579-597 等);E4 F14 .gitignore:51+「恒无」表述订正;E5 存档序列化 :122→:121(卡⑤同订);E6 行号微漂(ui_struct_probe :41-49、smoke_all :170-171、camp.md :19-20)。自扩订正:契约 10 标仓库纪律成文。卡内可收 15 项:presenter 承接面(T3/契约 4)、叠层规则派生(T2/§9-2)、ConfirmDialog 消费方编排(T4)、生涯探针驱动改缆+返回钮文案坑(T3/T5)、图鉴占位态(T3)、screen_flow 键新语义(T5)、HUD 刷新单口(T2/T3)、深员改指表(T5)、源码断言段重写(T5)、shot_probe 收闭改缆(T5)、forge_workbench_test 迁移+§5 补 tests 可写面(T5/§5)、断点确认段补列(F8/T5)、contrast 段核签(T5)、素材命名指针(T1)、终稿落盘口径(T1/契约 9/§5)。跨卡对齐:HUD 刷新挂点(§0 接口+卡⑤订正)、ConfirmDialog 类事实双向失效(Q5)、开层互斥/关层收闭(T3+卡③ T2)、探针文件分界(T5)、`_refresh_resume_button` 不复用(T4)。验收补:V1 拆半、V3 扩、V4 扩、V12 留痕行、变异补二条。新增待裁点 Q5 三出口弹窗、Q6 规格缺口连带;估时 8.5–11.5d→9–12d。用户面裁决(①④⑤裁决 5/10)零改动。 +**审查回写要点**:v1.0→v1.1(2026-10-18 grilling 子 Agent 对抗审查回写)——事实订正 6 处:E1「48 色工具全仓不在役」→截屏级不在役/素材级二器在役(F17/§9-5/V10/T5 连带);E2「camp golden」五处不存在→删并立契约 10 不建;E3 F7 行号(_start_adventure :579-597 等);E4 F14 .gitignore:51+「恒无」表述订正;E5 存档序列化 :122→:121(卡⑤同订);E6 行号微漂(ui_struct_probe :41-49、smoke_all :170-171、camp.md :19-20)。自扩订正:契约 10 标仓库纪律成文。卡内可收 15 项:presenter 承接面(T3/契约 4)、叠层规则派生(T2/§9-2)、ConfirmDialog 消费方编排(T4)、生涯探针驱动改缆+返回钮文案坑(T3/T5)、图鉴占位态(T3)、screen_flow 键新语义(T5)、HUD 刷新单口(T2/T3)、深员改指表(T5)、源码断言段重写(T5)、shot_probe 收闭改缆(T5)、forge_workbench_test 迁移+§5 补 tests 可写面(T5/§5)、断点确认段补列(F8/T5)、contrast 段核签(T5)、素材命名指针(T1)、终稿落盘口径(T1/契约 9/§5)。跨卡对齐:HUD 刷新挂点(§0 接口+卡⑤订正)、ConfirmDialog 类事实双向失效(Q5)、开层互斥/关层收闭(T3+卡③ T2)、探针文件分界(T5)、`_refresh_resume_button` 不复用(T4)。验收补:V1 拆半、V3 扩、V4 扩、V12 留痕行、变异补二条。新增待裁点 Q5 三出口弹窗、Q6 规格缺口连带;估时 8.5–11.5d→9–12d。用户面裁决(①④⑤裁决 5/10)零改动。 diff --git a/reports/需求卡片-选档界面新建批-2026-10-18.md b/reports/需求卡片-选档界面新建批-2026-10-18.md index 33a9f7b9..28442dad 100644 --- a/reports/需求卡片-选档界面新建批-2026-10-18.md +++ b/reports/需求卡片-选档界面新建批-2026-10-18.md @@ -199,4 +199,4 @@ --- -**修订记录**:v1.0→v1.1(2026-10-18 grilling 子 Agent 对抗审查回写)——事实订正:F6 行号 :458-461→:458-462;F2 补 ConfirmDialog 形态实证(零 payload/直开绕栈/静态常驻接线);F7 窥视读器标卡①未实现交付物+「通关次数」口径锁定;自扩订正:契约 8「拔电源不丢」父注按 Q1 条件化、Q1 乙案「一键直入」补层级张力注。卡内可收:契约 3 立 ConfirmDialog 消费方机制(禁双常驻接线)、契约 6 补直开豁免、契约 4 补两步路径记载、T1 补返回钮/禁置灰残留/预选高亮态、T2 补动线序与开层互斥、T3 补夹具注入与 ConfirmDialog 变异注入、T0 补既有断言面清点、V 表补三行、§8 L3 落空项订正。跨卡对齐:ConfirmDialog 机制卡③立卡④守、营地开层互斥与卡④ T3 同口径、断点确认探针段归卡④ T5 接收(卡② T2 明列移交)。新增待裁点 Q2 坏档第三态、Q3 先行落点过渡态。用户面裁决(裁决 2/3/4)零改动。 +**审查回写要点**:v1.0→v1.1(2026-10-18 grilling 子 Agent 对抗审查回写)——事实订正:F6 行号 :458-461→:458-462;F2 补 ConfirmDialog 形态实证(零 payload/直开绕栈/静态常驻接线);F7 窥视读器标卡①未实现交付物+「通关次数」口径锁定;自扩订正:契约 8「拔电源不丢」父注按 Q1 条件化、Q1 乙案「一键直入」补层级张力注。卡内可收:契约 3 立 ConfirmDialog 消费方机制(禁双常驻接线)、契约 6 补直开豁免、契约 4 补两步路径记载、T1 补返回钮/禁置灰残留/预选高亮态、T2 补动线序与开层互斥、T3 补夹具注入与 ConfirmDialog 变异注入、T0 补既有断言面清点、V 表补三行、§8 L3 落空项订正。跨卡对齐:ConfirmDialog 机制卡③立卡④守、营地开层互斥与卡④ T3 同口径、断点确认探针段归卡④ T5 接收(卡② T2 明列移交)。新增待裁点 Q2 坏档第三态、Q3 先行落点过渡态。用户面裁决(裁决 2/3/4)零改动。 diff --git a/roadmap.md b/roadmap.md index 84faa575..6a21bb60 100644 --- a/roadmap.md +++ b/roadmap.md @@ -89,7 +89,7 @@ 5. **重闸**(批末 Tn):`tools/run_all_gates.sh` **按本批改动域跑**(触及 `game/` → `--code`,这是代码域唯一触发;不触及 `game/` 的一切路径 → `--docs`;一次改动同批混触两域 → 不带参数全量),所选域全绿——闸件清单、顺序与域划分只在该脚本里定义,本文件与 AGENTS.md/规约均不另列;改闸件自身(`tools/` 下机检脚本与闸壳)不占合回全量,质量义务=落批时的变异验证;涉核心的 MC 与基线逐位比对、素材批的机检断言另行。 6. **人闸**(停机交付):真人目检清单 + 代拍板追认清单 + 异步终审触点(样张类)——本循环内唯一必经人审。 7. **异常分级**:L1 自救(一次重试)→ L2 记录继续(连续 3 次同红灯升级)→ L3 停机写报告等用户。 -8. **批次完成后的五步登记**:①06 条目状态按 doc-conventions §12.1 推进(做完整条删除)②本文件顶部「当前位」三行换代,涉及里程碑移动时同步里程碑表 ③**实现批禁写本文件与 `design/`**(2026-10-17 用户裁:代码实现批只准写 `reports/`),该改哪一行写进 `reports/iter-反哺点-<日期>.md`,由文档批执行 ④阶段变更改 stage.txt ⑤批末闸序列**按本批改动域**全绿留痕(回执 commit 对齐分支尖)。 +8. **批次完成后的五步登记**:①06 条目状态按 doc-conventions §12.1 推进(做完整条删除)②本文件顶部「当前位」三行换代,涉及里程碑移动时同步里程碑表 ③**实现批禁写本文件与 `design/`**(代码实现批只准写 `reports/`),该改哪一行写进 `reports/iter-反哺点-<日期>.md`,由文档批执行 ④阶段变更改 stage.txt ⑤批末闸序列**按本批改动域**全绿留痕(回执 commit 对齐分支尖)。 ## 维护纪律 diff --git a/tools/analyze_playtest.py b/tools/analyze_playtest.py index d18b2718..94752ed0 100644 --- a/tools/analyze_playtest.py +++ b/tools/analyze_playtest.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- """试玩日志统计分析工具(消费 playtest_logger 的 JSONL——user://logs/playtest_*.jsonl)。 -统计口径(2026-09-17 用户定义): +统计口径: · 每轮获得的奖励(效果/治疗/奖励伤害/未生效)与充能点数 · 实际造成伤害 / 实际受到伤害 / 恢复总量 · 增伤贡献(attack_up + 充能穿刺/魔法)、减伤贡献(hero_defense×enemy_output 池挡下的承伤) @@ -13,16 +13,16 @@ 两种日志格式: · 旧格式(step 行无 payload):反事实按比例近似(误差每行 ±1~2,多 floor 链无法逆精确); 掷点折扣与 ac_up 对敌方判定的影响不可恢复,忽略(已标注)。 - · 新格式(2026-09-17 起 step 行携带 roll/ac/tier/crit/normal/pierce/magic/baseline/attach): + · 新格式(step 行携带 roll/ac/tier/crit/normal/pierce/magic/baseline/attach): 反事实按 DamageMath 公式逐行精确重算。 - · 新效应词汇批(2026-09-19):敌方伤害行携带 rider(必中附加分量)——计为敌方招式成分, + · 敌方伤害行携带 rider(必中附加分量)——计为敌方招式成分, 无减伤世界(cf_tn)含 rider、无奖励世界(cf_tr)保留 rider 只剥伏击附加。 表值硬编码溯源(表值变更须同步——单一事实源仍在 .tres): · status_effects.tres:attack_up 50 / weaken −65 / enrage 25 / off_guard 25 / sapped −25(percent) · settlement.tres:pool_clamp [-100,100] · crit_multiplier 200 - · 【2026-09-20 八型批】伏击机制退役(blast 负向换装警觉=敌方 AC+1,掷点分布型,不再有 flat 附加项)—— - M_AMB 置 0 保持反事实管道兼容旧日志;新日志不再携带 ambush 效果行 + · 伏击机制已退役(blast 负向=警觉,敌方 AC+1,掷点分布型,无 flat 附加项)—— + M_AMB 置 0 保持反事实管道兼容旧日志;新日志不携带 ambush 效果行 · skills.tres:突刺/撕咬 1.5 · 重击 2.0 · 毒爆 2.5 · 普攻 1.0 · armor_effectiveness:pierce 克 ward 150 / heavy 50;magic 克 heavy 150 / ward 50;normal 恒 100 """ @@ -34,7 +34,7 @@ import sys # ---- 表值区(溯源见文件头) ---- POOL_CLAMP = (-100, 100) CRIT_MULT = 200 -M_AMB = 0 # 伏击已退役(2026-09-20 八型批)——反事实剥除项归零,旧日志兼容读 +M_AMB = 0 # 伏击已退役——反事实剥除项归零,旧日志兼容读 SKILL_MULT = {"普通攻击": 1.0, "突刺": 1.5, "重击": 2.0, "撕咬": 1.5, "毒爆": 2.5} EFFECT_TEXT_MAP = { # 旧日志无 effect_id——按明细行文本反查 "增伤": "attack_up", "护甲强化": "ac_up", "削弱": "weaken", "暴走": "enrage", @@ -100,8 +100,8 @@ def parse_log(path): def analyze_runs(rows, label, tier=None, policy=None): """tier = (atk_pct, hp_pct):只统计该天赋档(None = 全档)。 - policy = "normal"/"perfect":只统计该策略画像(清图支配性对账批 2026-09-19—— - 双画像同文件时分开聚合做配对对照;None = 全画像混算,旧口径不变)。""" + policy = "normal"/"perfect":只统计该策略画像 + (双画像同文件时分开聚合做配对对照;None = 全画像混算)。""" runs = [] # [{meta, rows}] cur = None for r in rows: @@ -203,7 +203,7 @@ def analyze_run_core(rows, meta): cur_b["taken"] += v if k == "node" and r.get("type") == "rest": out["rest_heal"] += int(r.get("healed", 0)) - # 弃图刷新与轮出口(清图支配性对账批 2026-09-19 增补读数——此前日志有行无分析) + # 弃图刷新与轮出口(常设读数) elif k == "action" and r.get("op") == "refresh": if r.get("accepted", False): out["refresh_ok"] += 1 @@ -250,7 +250,7 @@ def print_run_report(label, stats): print(" 平均结算轮数 :%.1f" % avg(group, "rounds")) print(" 平均每局奖励件数 :%.1f(%.2f 件/轮)" % ( avg(group, "rewards_n"), avg(group, "rewards_n") / max(1.0, avg(group, "rounds")))) - # 弃图刷新面(清图支配性对账批 2026-09-19:刷新板数÷总板数 = 弃图率) + # 弃图刷新面:刷新板数÷总板数 = 弃图率 boards = sum(s["battles"] + s["refresh_ok"] for s in group) refreshes = sum(s["refresh_ok"] for s in group) print(" 平均每局弃图刷新 :%.2f 次(被拒 %.2f 次) 弃图率:%.0f%%" % ( @@ -452,7 +452,7 @@ def analyze(rows, label): if exact_mode: base = float(s.get("baseline", v)) att = int(s.get("attach", 0)) - rider = int(s.get("rider", 0)) # 必中附加分量(新效应词汇批 2026-09-19)——敌方招式成分,非棋盘来源 + rider = int(s.get("rider", 0)) # 必中附加分量——敌方招式成分,非棋盘来源 rolled = rolled_component(base, int(s.get("tier", 100)), bool(s.get("crit")), 100) pre = rolled + att + rider cf_nored = max(1, pre) diff --git a/tools/audit_file_headers.py b/tools/audit_file_headers.py index 9de9dd56..3153e32d 100644 --- a/tools/audit_file_headers.py +++ b/tools/audit_file_headers.py @@ -4,7 +4,7 @@ 文件头 = .gd 文件顶部连续注释区:连续的空行或 # 注释行,首个非注释代码行止。 本脚本只实现机械可判子集(两类白名单的人判面见规范正文): - R0 载体:头注非空时首行必须以 `##` 文档注释开头(清偿批落地起生效); + R0 载体:头注非空时首行必须以 `##` 文档注释开头; R1 行数上限:头注注释行(非空)> 8 行; R2 日期:头注出现日期模式(2026-09-12 / 2026年9月 一类)——日期只属于 git log 与迭代报告; R3 变更叙事词:「迭代N / 本迭代」、批次叙事复合词(本批/拆件批/改造批……)、「迁移到/改名为」 diff --git a/tools/audit_type_hints.py b/tools/audit_type_hints.py index fe012c24..2c2d7a1a 100644 --- a/tools/audit_type_hints.py +++ b/tools/audit_type_hints.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -"""audit_type_hints.py — 迭代27 T5 类型闸机器审计(code-conventions §4 语言纪律的机器闸)。 +"""audit_type_hints.py — 类型闸机器审计(code-conventions §4 语言纪律的机器闸)。 产品码 = game/core + game/data + game/presentation(smoke/tests 豁免——测量面容器直构是惯例)。 三条规则: diff --git a/tools/balance_verifier.py b/tools/balance_verifier.py index db03663a..f83463b3 100644 --- a/tools/balance_verifier.py +++ b/tools/balance_verifier.py @@ -4,21 +4,21 @@ r"""数值验证工具(判定端)——自动化评判 + 元进度爬升测 两段采集(数据源 = smoke/verifier_batch.gd,本文件驱动它并做全部判定): adventure 段 全冒险连探基线(零永久强化)——逐关条件通关率派生 + 止步分布 + 败退节点归因(层/节点/敌人); - 换算率标定批起支持 inject 注入档(永久强化 flat OFAT——与白板同种子流配对,行带 + adventure 段支持 inject 注入档(永久强化 flat OFAT——与白板同种子流配对,行带 inject_tag/override,标定面 = 逐关条件通关率差) campaign 段 营地循环战役(隔离档真实元进度账本:注入→冒险→收束入账→买锻造)——爬升曲线; 行带 spend 花费序标签(多轨迹合并采集按序分组判定) 评判标准(溯源): ① 逐关条件通关率(冒险口径派生——打通 k-1 关才到达第 k 关,通关数/到达数):单关直入口口径 - (分带批 2026-09-20,难度曲线与Boss v0.16)满血零上下文进关,与真实冒险的条件通关率脱节, - 曾误导曲线调参——已随单关试玩入口一并退役(2026-09-23 用户拍板);旧带值锚定直入口读数不可比, - 带重锚归曲线调参批——重锚前本表只测不判。 - ② 元循环目标(用户提案 2026-09-22,数字待确认):累计通过 5 次第 k 层的冒险后,第 k+1 层的 + (难度曲线与Boss v0.16)满血零上下文进关,与真实冒险的条件通关率脱节、会误导曲线调参, + 已随单关试玩入口一并退役;旧带值锚定直入口读数不可比, + 带重锚归曲线调参——重锚前本表只测不判。 + ② 元循环目标(数字待确认):累计通过 5 次第 k 层的冒险后,第 k+1 层的 条件通关率(滑窗)应进入该层验收带——判定同①随口径退役暂停(重锚前只给滑窗读数与触发点)。 - ③ 魔法道具面:道具工坊六件按通关次数解锁(阈值 1/1/2/2/3/3),局内效果未实装(归 Alpha 魔法道具批)—— + ③ 魔法道具面:道具工坊六件按通关次数解锁(阈值 1/1/2/2/3/3),局内效果未实装(归 Alpha 魔法道具)—— 本工具只报解锁时点,不入判定。 - ④ 换算率标定(2026-09-23 批新增):OFAT 注入档 vs 白板的同种子配对逐关条件通关率差 + ④ 换算率标定:OFAT 注入档 vs 白板的同种子配对逐关条件通关率差 → 每级带平移量点估计±SE(配对 bootstrap)→ 与 meta.tres 现行表值对照、给建议投值。 护甲行强条目:读数必须按解锁后参数实测(本段即重测面),不得用基线外推。 @@ -35,7 +35,7 @@ r"""数值验证工具(判定端)——自动化评判 + 元进度爬升测 python tools/balance_verifier.py --from-raw # 免重跑,对既有采集重新判定/出报告 输出:控制台判定结论 + sim-data/balance-verifier-<时间戳>.md(报告)+ 同名 .raw.jsonl(原始逐局数据)。 两件均落 sim-data/(整目录不入 git,读数以最新一份为准)。 -兼容注:2026-09-23 前的旧 raw.jsonl 含 level 段(直入口单关)行——本版判定自动忽略, +兼容注:旧 raw.jsonl 含 level 段(直入口单关)行——判定自动忽略, 逐关读数一律由冒险行派生。 """ import argparse @@ -57,10 +57,10 @@ VJSON_PREFIX = "VJSON " ERROR_MARKERS = ("SCRIPT ERROR", "Parse Error") # ---- 判定标准区(溯源见文件头) ---- -# 直入口验收带(原 LEVEL_BANDS)已随单关直入口口径退役(2026-09-23 用户拍板)—— -# 逐关/检查点判定全部暂停(judge_band 传 band=None = 只测不判),带重锚归曲线调参批。 +# 直入口验收带已随单关直入口口径退役—— +# 逐关/检查点判定全部暂停(judge_band 传 band=None = 只测不判),带重锚归曲线调参。 # 带重锚后换算率平移随之启用:带按 band_shift_for(override) 平移后套用(表值驱动,④ 段供数)。 -CAMPAIGN_CLEARS_TARGET = 5 # 元循环检查点:累计通过第 k 层的冒险次数(用户提案 2026-09-22,待确认) +CAMPAIGN_CLEARS_TARGET = 5 # 元循环检查点:累计通过第 k 层的冒险次数(数字待确认) CAMPAIGN_WINDOW = 10 # 检查点滑窗局数(条件通关率的窗口) CAMPAIGN_MIN_ATTEMPTS = 5 # 滑窗内少于此局数 = 数据不足(不出判定) LEVEL_CN = {1: "第一层", 2: "第二层", 3: "第三层"} @@ -269,7 +269,7 @@ def valid_adventure_runs(rows, policy, baseline_only=False): def analyze_adventure_levels(rows): - """逐关条件通关率(冒险口径派生——直入口口径退役 2026-09-23;白板档): + """逐关条件通关率(冒险口径派生——直入口口径已退役;白板档): 到达第 k 关 ⇔ levels_cleared >= k-1;通关第 k 关 ⇔ levels_cleared >= k。 条件通关率 = 通关数 / 到达数(L1 的到达数 = 全部有效局——冒险即从第一关开始)。""" out = {} @@ -545,7 +545,7 @@ def report(args, rows, meta): A(f" - {lb} ×{c}") A("") - # ③ 元循环爬升(多花费序轨迹分组——换算率标定批起 campaign 行带 spend 标签) + # ③ 元循环爬升(多花费序轨迹分组——campaign 行带 spend 标签) A("## ③ 营地循环爬升(用户判据④:5 次通关 → 下一层可过)") A("") for spend in campaign_spend_tags(rows): diff --git a/tools/clear_dominance_audit.py b/tools/clear_dominance_audit.py index 4d0e420c..5589fcba 100644 --- a/tools/clear_dominance_audit.py +++ b/tools/clear_dominance_audit.py @@ -10,7 +10,7 @@ R_res = n_s × E_dig;X_res = E[踩雷] × V_mine;Δr = ⌈(n_s + E[踩雷]) ÷ AP_r⌉ s_ref = D_ref;停手侧 RAP 机会收益按零计价(显式假设)。 -本工具 2026-09-19 随对账重跑批建立,是难度曲线调参批的常设重跑入口: +本工具是难度曲线调参的常设重跑入口: 所有输入可经命令行覆盖(--d-ref --c-clear --ap-r --iota ...), 重跑时按当期 .tres 行值更新默认值即可,公式本体不动。 @@ -18,17 +18,15 @@ flat 类 E = 表值;percent 类 E = |层数×行值|÷100 × D_ref(每结算每层); AC 轴换算 = AC 点数 × 5pp(d20 线性)× D_ref(假设登记,见审计报告)。 -【2026-10-05 判式换代批口径(迭代14②号卡 T0)】 - - 池 67→77(补 action 6 / gp 2;clear_blast 系清图槽对象不入格池)。 - - 直伤雷负向三行 6/8/8(backlash/snare/recoil,2026-10-01 数值修复+10-03 转正); +【现行判式口径】 + - 池权重合计 77(含 action 6 / gp 2;clear_blast 系清图槽对象不入格池)。 + - 直伤雷负向三行 6/8/8(backlash/snare/recoil); 正向 pierce_strike/magic_bolt 维持 flat 2;heal_minor 2(Package B 第 2 轮)。 - - 清图槽 C_MIN/MAX 8/18→24/40(中点 32);AP_r 6→8(2026-09-16 压速批 8→6 后回摆)。 - - off_guard 换 ac 轴 −1(0.2u 模型:点数×5pp×D_ref=0.2 当量/每敌拍)。 - - 伏击历史口径(口径甲 u×m_amb / AMBUSH_MAG/STACKS)退役删除——伏击机制已退役, - V_mine 只保留现行矩阵加权口径(原口径乙升为主口径)。 - - V_mine 换现行九型负向字典(enrage/off_guard/警觉/backlash/sapped/snare/recoil/ + - 清图槽 C_MIN/C_MAX = 24/40(中点 32);AP_r = 8。 + - off_guard 走 ac 轴 −1(0.2u 模型:点数×5pp×D_ref=0.2 当量/每敌拍)。 + - V_mine 为九型负向字典口径(enrage/off_guard/警觉/backlash/sapped/snare/recoil/ ap_drain/gp_lose——ap_drain 按 A6 flat 1、gp_lose 按 A5 代理 2 计)。 - - 新增 β 比值带判读与逐型净期望输出(原方案报告 §四/§九,已退役 git 1da9a41): + - β 比值带判读与逐型净期望输出: β(u)=V_mine/E_dig ∈ [1.2, 2.5];条件一 (1−ρ̂)E_dig−ρ̂V_mine ≥ 0(下限 0,上限归 β_hi); 条件二 E[标中兑付] ≥ (1+δ)·E_dig(δ=1.25 provisional,兑付溢价形态 a)。 """ @@ -36,16 +34,16 @@ import argparse import math -# ============ 现行值链(2026-10-05 判式换代批快照,出处见各注释;重跑批按当期 .tres 更新) ============ +# ============ 现行值链(出处见各注释;重跑按当期 .tres 更新) ============ -D_REF = 4 # settlement.tres equivalence_ref_damage(2026-09-17 压缩批 12→4) +D_REF = 4 # settlement.tres equivalence_ref_damage P_PERFECT = 200 # settlement.tres(percent,÷100 = ×2 双份交付) -C_MIN, C_MAX = 24, 40 # reward.tres clear_blast power_min/max(2026-10-01 数值修复批 8/18→24/40);期望口径 = 中点 32 -AP_R = 8 # action_economy.tres ap_per_round(2026-09-16 压速批 8→6 后回摆 8) +C_MIN, C_MAX = 24, 40 # reward.tres clear_blast power_min/max;期望口径 = 中点 32 +AP_R = 8 # action_economy.tres ap_per_round DIG_COST = 1 # action_economy.tres dig_ap_cost IOTA = 0.88 # board_gen.tres inferability_target(判式 ι 代理) -# 效果行值(status_effects.tres,2026-10-05 快照) +# 效果行值(status_effects.tres) ATTACK_UP_PCT = 50 # 增伤 +50%,duration 1,hero 侧 AC_UP_POINT = 1 # 护甲强化 +1 AC,duration 1 WEAKEN_PCT = 65 # 削弱 −65%(有效拍 1:duration 2 先兑付后衰减) @@ -54,14 +52,14 @@ SAPPED_PCT = 25 # 乏力 −25%,hero 侧 OFF_GUARD_AC = 1 # 失衡 AC −1(0.2u 模型:1 点 × 5pp × D_ref = 0.2 当量/每敌拍) ALERT_EQUIV = 0.2 # 警觉(敌 AC+1×1拍):主角每拍恰 1 攻 × 1 拍寿命 ⇒ 0.2 当量,u 无关(假设 A4) -# 直伤/群伤 flat 值(reward.tres,2026-10-05 快照) +# 直伤/群伤 flat 值(reward.tres) SPARK_AOE = 1 # 爆裂粉尘(全体存活敌) -HEAL_MINOR = 2 # 急救敷料(Package B 第 2 轮 1→2) -HEAL_BACKLASH = 6 # 反噬震荡(主角直伤,2026-10-01 4→6 / 10-03 转正) +HEAL_MINOR = 2 # 急救敷料(Package B 第 2 轮) +HEAL_BACKLASH = 6 # 反噬震荡(主角直伤) PIERCE_STRIKE = 2 # 穿刺弹(单目标克制直伤,必中全额) MAGIC_BOLT = 2 # 魔法矢(同上) -PIERCE_SNARE = 8 # 穿刺陷阱(主角直伤,2026-10-01 5→8 / 10-03 转正) -MAGIC_RECOIL = 8 # 魔法反噬(主角直伤,2026-10-01 5→8 / 10-03 转正) +PIERCE_SNARE = 8 # 穿刺陷阱(主角直伤) +MAGIC_RECOIL = 8 # 魔法反噬(主角直伤) AP_UP = 1 # 行动点 +1(当量 = flat 表值 1,机会成本口径更高仅登记——假设 A6) GP_COIN = 3 # GP 袋 +3 GP(gp 当量 = flat power 代理——假设 A5,口径空白登记) GP_LOSE = 2 # 破财 −2GP(同上代理) @@ -73,21 +71,21 @@ ARMOR_EFFECT = { # attack_type → {armor_type: 点数};切片 L1 全轻 "normal": {"light": 0, "ward": 1, "heavy": -1}, } -# 格面资源池正向权重(reward.tres,2026-10-05 快照,合计 77) +# 格面资源池正向权重(reward.tres,合计 77) # 类型 → (权重);负向行 weight=0 不参与摇号,类型分布 = 正向权重 # clear_blast pool_tag=clear_default 系清图槽对象,不入格池(地图战斗资源.md §清图槽)。 POOL_WEIGHTS = {"attack": 14, "defense": 11, "blast": 16, "heal": 4, "weaken": 8, "pierce": 8, "magic": 8, "action": 6, "gp": 2} -# β 比值带(2026-10-04 用户裁 P4:[1.2, 2.5];u=3 登记态 1.17 微破下限=点名不强制回滚) +# β 比值带 [1.2, 2.5](u=3 登记态 1.17 微破下限=点名不强制回滚) BETA_LO, BETA_HI = 1.2, 2.5 -# δ 旗溢价(2026-10-04 用户裁 P3:形态 a 兑付溢价,δ=1.25 provisional ⇒ 兑付按同型正向 ×(1+δ)) +# δ 旗溢价(形态 a 兑付溢价,δ=1.25 provisional ⇒ 兑付按同型正向 ×(1+δ)) DELTA = 0.25 # 板形(|M| 幸存雷 / |S| 安全格)双口径 -# 名义 = density×(W×H−9) 初布值(2026-09-14 重算批参考板形口径,连续性参照) +# 名义 = density×(W×H−9) 初布值(参考板形口径,连续性参照) # 实测 = smoke/board_stat_probe.gd 200 样本/行均值("先布后删"落地值,主流读数) -# (实测值沿用 2026-09-19 board_stat_probe 读数;板形行值此后未变,不强制复跑) +# (实测值沿用 board_stat_probe 读数;板形行值未变,不强制复跑) BOARDS = { "L1前段·名义(10x10)": {"M": 23, "S": 77}, "L1后段·名义(12x12)": {"M": 34, "S": 110}, @@ -143,7 +141,7 @@ def v_mine(u: float, d_ref: float) -> float: def w_flag_hit(u: float, d_ref: float, prem_pct: int = 125) -> float: """标中旗兑付聚合当量 W(u)——整数量级实现口径(与机制同式:各型四舍五入取整后折算)。 - 迭代14② T4 起为条件二常设判读式:条件二 = W(u) ≥ (1+δ)·E_dig(u)。 + 条件二常设判读式:条件二 = W(u) ≥ (1+δ)·E_dig(u)。 取整跟随机制(GDScript round=半分远离零),非 Python banker's rounding。 1 点量纲行(ac_up/action/spark)取整地板=×1.0——u=3 聚合微欠的成因(登记面)。 """ @@ -239,7 +237,7 @@ def main() -> None: "✗破下限(登记态)" if beta < BETA_LO else "✗破上限") blind_nom = (1 - args.rho_nominal) * ed - args.rho_nominal * vm blind_meas = (1 - args.rho_measured) * ed - args.rho_measured * vm - # 条件二(T4 起机制在位):W=整数量级标中兑付聚合(取整跟随机制),阈值 =(1+δ)·E_dig + # 条件二(机制在位):W=整数量级标中兑付聚合(取整跟随机制),阈值 =(1+δ)·E_dig wfh = w_flag_hit(u, args.d_ref, int(round((1 + args.delta) * 100))) thresh = (1 + args.delta) * ed cond2 = "✓转绿" if wfh >= thresh else "✗微欠(整数量级取整地板,登记面)" diff --git a/tools/doc_term_audit.py b/tools/doc_term_audit.py index 371a2294..39a9ace7 100644 --- a/tools/doc_term_audit.py +++ b/tools/doc_term_audit.py @@ -4,8 +4,9 @@ r"""doc_term_audit.py — GDD 退役术语扫描(半自动) 动机:机制换名/退役批(如 2026-09-20 伏击→警觉)之后,正文里容易残留旧措辞的 "现行语义"引用——修订记录与退役注记里的旧词是合法历史,混在一起肉眼难分。 本工具维护一份退役词表,全文档扫描命中并按上下文分两类: - [疑似现行] 该行不含日期/退役/换装等白名单信号,也没落在版本历史节——人工判读 - [留档类] 行内带日期、退役/作废/换装/继任/留档/历史等信号,或位于修订记录节——默认忽略 + [疑似现行] 该行不含日期/退役/换装等白名单信号——人工判读 + [留档类] 行内带日期、退役/作废/换装/继任/留档/历史等信号——默认忽略 +(变更记录类节自 2026-10-19 起由 gdd_lint R4 禁设,本工具不再为其设节级豁免) 用法: python tools/doc_term_audit.py # 扫默认范围,报告模式(exit 0) @@ -68,7 +69,7 @@ RETIRED_TERMS = [ DEFAULT_DIRS = ["design/gdd"] # 用语规范 A 表补充词专项补扫:随批/台账 两词本身是上方行级白名单信号(行内出现即归 -# 留档类),主扫描对它们自豁免;本通道只做版本历史节外的专项报告,供后续触碰批清偿。 +# 留档类),主扫描对它们自豁免;本通道只做节外残留的专项报告,供后续触碰批清偿。 SUPPLEMENT_TERMS = [ ("随批", "2026-10-15", "顺带", "用语规范 A 表(doc-conventions 第 4 节)"), ("台账", "2026-10-15", "状态记录", "用语规范 A 表(doc-conventions 第 4 节)"), @@ -123,15 +124,16 @@ TERM_CONTEXT_EXEMPT = { "拔旗|撤旗": re.compile(r"件派生动词白名单|第三盘面动作|非信息类"), } -# 行级白名单信号:命中任一即归"留档类" +# 行级白名单信号:命中任一即归"留档类"(变更记录类词面不入白名单——此类节自 2026-10-19 +# 起由 gdd_lint R4 禁设,出现即违规,不得借白名单隐身) WHITELIST_RE = re.compile( r"2026-\d{2}-\d{2}" r"|退役|作废|换装|继任|留档|历史口径|已下线|随批|随伏击|不再|已删除" r"|\bv0\.\d+" - r"|修订记录|版本历史|履行回执|台账" + r"|履行回执|台账" ) -# 节级白名单:版本历史/修订记录/用语规范节内整段豁免(用语规范节的不用列是内容本身) -SECTION_RE = re.compile(r"^#{1,6}\s*(版本历史|修订记录|用语规范)") +# 节级白名单:用语规范节内整段豁免(该节列的是被禁术语本身,属内容而非残留) +SECTION_RE = re.compile(r"^#{1,6}\s*(用语规范)") COMMENT_RE = re.compile(r"^\s*[;#]") diff --git a/tools/gdd_lint.py b/tools/gdd_lint.py index 041b744a..03f9463d 100644 --- a/tools/gdd_lint.py +++ b/tools/gdd_lint.py @@ -2,26 +2,26 @@ r"""gdd_lint.py — GDD lean 格式门禁 用法: - python tools/gdd_lint.py # 检查 design/gdd/ 下全部系统级 GDD(默认范围) + python tools/gdd_lint.py # 检查 design/gdd/ 根层 GDD + roadmap.md(默认范围) + python tools/gdd_lint.py --changelog-only # 只跑 R4 变更记录节禁令,扫描面扩到全 design/ 树 python tools/gdd_lint.py ... # 检查指定文件 python tools/gdd_lint.py --json # 机器可读输出(供 gate/CI 使用) 规则(口径权威 = design/engineering/doc-conventions.md 第 5–6 节文档骨架与结构纪律): R1 散文段落 ≤ 240 字(代码块/表格/列表/引用不计) R2 表格字符占比(词条表分域豁免,见 R2_EXEMPT 注) - R3 正文禁止修订注记:~~删除线~~、"作废"、括号内"日期+评审/修订/拍板/裁决/核销"(版本历史节豁免; - 登记处/清单按 RULE_EXEMPT 分域豁免) - R4 必须有「版本历史」节且含表格(登记处按 RULE_EXEMPT 分域豁免) + R3 正文禁止修订注记:~~删除线~~、"作废"、括号内"日期+评审/修订/拍板/裁决/核销" + (登记处/清单按 RULE_EXEMPT 分域豁免) + R4 禁止变更记录节:出现「版本历史/修订记录/变更记录/修改记录/更新记录/更新日志」标题即红 + (沿革只进 git commit log;扫描面 = 全 design/ + roadmap.md,见 --changelog-only) R5 流程/状态类章节必须含代码块图(字符画或 Mermaid);清单节/词条节按 RULE_EXEMPT 分域豁免 R6 表格列数一致(含转义 \| 识别) R7 括号嵌套跨度 ≤ 80 字(长括号 = 审计注记挤进正文的信号;登记处/清单按 RULE_EXEMPT 分域豁免) R8 核心规则表:规则列必须是"谁·何时·做什么"陈述句所在的可读表——说明/要点列 禁止出现编号引用(AC-x/F-x/EC-x/E-x/OQ-x/Rule-x/义务),引用只允许在依据类列 R9 一页纸节点:任一标题节点的直接内容(到下一标题为止)≤ 80 行——装不下就拆子节点 - R10 版本历史版本号唯一:版本历史/修订记录节表格首列提取 v\d+(\.\d+)* 或裸数字编号查重 - (表头/分隔行/空值/日期式首列跳过);无版本历史表的文档不适用——存在性归 R4 R11 计数词漂移:正文禁用旧计数口径——"10 类行/行型封闭为 10 类/10 类封闭协议/行型 10 类" - →9 类、"七型/五型 × 正负"→八型、"15 类"→9 类、"14 格"→十六格;版本历史/修订记录节、 + →9 类、"七型/五型 × 正负"→八型、"15 类"→9 类、"14 格"→十六格; 留档/作废/退役/历史/旧/改型/随批/顺延等轨迹措辞行、`;` 注释行豁免(现行口径见 owner GDD 与 术语表) """ import argparse @@ -39,14 +39,15 @@ MAX_PAREN_SPAN = 80 # 规则分域(2026-10-03 用户裁「测试要快/要准」优化批):R1/R2 的体裁前提是「规范文」 # (短段+表格化);登记处/清单/概念文的自然形态就是长条目与叙事散文,硬套=自 2026-09-20 -# 上线起 8/8 常红零过滤价值(test-perf-report-2026-10-02 §6.2 实证)。R3/R4/R7 不豁免—— -# 「provenance 出正文、版本历史在案」对一切体裁有效。 +# 上线起 8/8 常红零过滤价值(test-perf-report-2026-10-02 §6.2 实证)。R3/R7 不豁免—— +# 「provenance 出正文」对一切体裁有效;R4 变更记录节禁令自 2026-10-19 起对一切体裁有效。 R1_EXEMPT = { "06-待办清单.md", # 全项目待办登记处:现状/状态/方案长条目为体裁 "07-体验验证清单.md", # 体验验证读数清单:同上 } R2_EXEMPT = { "01-核心循环.md", # 循环概念文:叙事散文为体裁 + "03-内容规模.md", # 规模框架文:多维档位靠散文交代,结构表只有一张 "04-美术音频方向.md", # 美术方向文:同上 "05-不做清单.md", # 清单文:条目散文为体裁 "06-待办清单.md", @@ -54,28 +55,27 @@ R2_EXEMPT = { "术语表.md", # 词条表:表格为主体形态,表格占比高是体裁本身 } # 规则粒度分域豁免(2026-10-15 用户令「清单类文件与术语表不做 GDD 规范性检查」)。 -# 原则:**按规则豁免,不按文件拉黑**——体裁规则(R3/R4/R5/R7)对登记处/清单/词条表 -# 不适用,但机械可判的完整性规则(R6/R8/R9/R10/R11)一律不豁免,真缺陷不得藏起来。 +# 原则:**按规则豁免,不按文件拉黑**——体裁规则(R3/R5/R7)对登记处/清单/词条表 +# 不适用,但机械可判的完整性规则(R4/R6/R8/R9/R11)一律不豁免,真缺陷不得藏起来。 # 各条理由: # R3 正文禁修订注记——登记处/清单的条目「带日期+裁决来源」是设计目的本身 # (条目要能回答「这条谁在何时裁的」),禁它等于禁登记处的核心价值。 -# R4 必须有版本历史节——06 是「解决即移除」的状态登记,条目不按版本累积, -# 强塞版本历史表反而制造第二套需同步的真相。 # R5 流程/状态类节须含代码块图——节名含「流程/生命周期」即触发,但 07 的 # 「㉖…全流程走查」「㉗…目检」是目检清单节、术语表的「开发流程」是词条节, # 两者都不是流程描述,属节名误匹配。 # R7 括号跨度 ≤80 字——长括注在登记处/清单里是常态(现状+裁决+归属挤在一行)。 RULE_EXEMPT = { - "06-待办清单.md": {"R3", "R4", "R7"}, + "06-待办清单.md": {"R3", "R7"}, "07-体验验证清单.md": {"R3", "R5", "R7"}, "术语表.md": {"R5"}, } DEFAULT_DIR = "design/gdd" DEFAULT_EXCLUDE = {"game-concept.md", "game-pillars.md", "systems-index.md"} -VERSION_SECTION = "版本历史" -# 版本历史/修订记录节(R10 查重域与 R11 豁免域共用;battle.md 等用「修订记录」同名节) -HISTORY_SECTION_RE = re.compile(r"(版本历史|修订记录)") +# R4 变更记录节标题(2026-10-19 用户裁「沿革只进 git」——原「必须有版本历史节」反转为此禁令, +# 同一组正则既拦新写也扫残留;R11 不再对其豁免,因为这类节本身即违规)。 +# 只认标题行(`#`…`######` 或 Setext underline),正文行内提及这些词不误伤。 +CHANGELOG_SECTION_RE = re.compile(r"^\s*#{1,6}\s*\S*?(版本历史|修订记录|变更记录|修改记录|更新记录|更新日志)") FLOW_SECTION_RE = re.compile(r"(流程|生命周期)") # R11 计数词漂移对照锚表(行协议 9 类 / 格面资源八型 / 权重 74)。 @@ -89,11 +89,6 @@ CURRENT_COUNTS = [ ] # R11 轨迹措辞豁免:留档/作废/退役/历史/旧 + 改型/随批/顺延(文档历史轨迹句「同批改型」) R11_TRACE_RE = re.compile(r"(留档|作废|退役|历史|旧|改型|随批|顺延)") -# R10 版本号提取:v 前缀优先,裸数字编号兜底;日期式首列(修订记录表)整体跳过 -VER_TOKEN_RE = re.compile(r"[vV]\d+(?:\.\d+)*") -BARE_VER_RE = re.compile(r"^\d+(?:\.\d+)*$") -DATE_CELL_RE = re.compile(r"\d{4}-\d{2}-\d{2}") -SEPARATOR_ROW_RE = re.compile(r"^\|[\s\-|:]+$") DATE_KEYWORD_RE = re.compile( r"[((][^()()]*\d{4}-\d{2}-\d{2}[^()()]*" @@ -102,12 +97,9 @@ DATE_KEYWORD_RE = re.compile( def parse(text): - """按行解析:返回代码块行集合、版本历史节行集合、表格块列表、散文段落列表、 - 版本历史/修订记录节表格列表(R10 查重域)。""" - code_lines, version_lines, tables, paras = set(), set(), [], [] - version_tables = [] - cur_table, cur_para, cur_section = [], [], "" - cur_table_hist = False + """按行解析:返回代码块行集合、表格块列表、散文段落列表。""" + code_lines, tables, paras = set(), [], [] + cur_table, cur_para = [], [] in_code = False for raw in text.splitlines(): stripped = raw.strip() @@ -118,24 +110,18 @@ def parse(text): paras.append(" ".join(cur_para)) cur_para = [] if cur_table: - (version_tables if cur_table_hist else tables).append(cur_table) - cur_table, cur_table_hist = [], False + tables.append(cur_table) + cur_table = [] continue - if raw.startswith("## "): - cur_section = stripped.lstrip("#").strip() if stripped.startswith("|"): if cur_para: paras.append(" ".join(cur_para)) cur_para = [] cur_table.append(raw) - if cur_section == VERSION_SECTION: - version_lines.add(raw) - if HISTORY_SECTION_RE.search(cur_section): - cur_table_hist = True continue if cur_table: - (version_tables if cur_table_hist else tables).append(cur_table) - cur_table, cur_table_hist = [], False + tables.append(cur_table) + cur_table = [] is_para = ( stripped and not in_code @@ -144,8 +130,6 @@ def parse(text): ) if in_code: code_lines.add(raw) - elif cur_section == VERSION_SECTION: - version_lines.add(raw) elif is_para: cur_para.append(stripped) elif cur_para: @@ -154,8 +138,8 @@ def parse(text): if cur_para: paras.append(" ".join(cur_para)) if cur_table: - (version_tables if cur_table_hist else tables).append(cur_table) - return code_lines, version_lines, tables, paras, version_tables + tables.append(cur_table) + return code_lines, tables, paras def unescaped_pipes(line): @@ -180,9 +164,14 @@ def paren_spans(text): MAX_NODE_LINES = 80 +def changelog_hits(text): + """R4 域:返回变更记录类标题行列表(任何标题级别、任何体裁文件一律不得存在)。""" + return [l for l in text.splitlines() if CHANGELOG_SECTION_RE.match(l)] + + def lint_file(path): text = Path(path).read_text(encoding="utf-8") - code_lines, version_lines, tables, paras, version_tables = parse(text) + code_lines, tables, paras = parse(text) issues, infos = [], [] # R9 一页纸节点:每个标题的直接内容 ≤ MAX_NODE_LINES 行 @@ -224,10 +213,8 @@ def lint_file(path): else: infos.append(f"表格占比 {ratio}%") - # R3 修订注记(版本历史节豁免;代码块豁免;登记处/清单按 RULE_EXEMPT 豁免) - body_no_code = "\n".join( - l for l in text.splitlines() if l not in code_lines and l not in version_lines - ) + # R3 修订注记(代码块豁免;登记处/清单按 RULE_EXEMPT 豁免——变更记录节已整体禁设,无豁免域) + body_no_code = "\n".join(l for l in text.splitlines() if l not in code_lines) for m in (() if "R3" in ex else re.finditer(r"~~.+?~~", body_no_code)): issues.append(f"R3 删除线残留: …{m.group(0)[:40]}…") if "R3" not in ex and re.search(r"作废", body_no_code): @@ -241,34 +228,10 @@ def lint_file(path): for m in DATE_KEYWORD_RE.finditer(body_no_code): issues.append(f"R3 正文修订注记: {m.group(0)[:50]}") - # R4 版本历史(登记处按 RULE_EXEMPT 豁免——条目「解决即移除」,不按版本累积) - if "R4" not in ex: - if VERSION_SECTION not in text: - issues.append(f"R4 缺「{VERSION_SECTION}」节") - elif not any(l.strip().startswith("|") for l in version_lines): - issues.append(f"R4 「{VERSION_SECTION}」节无表格") - - # R10 版本历史版本号唯一性(实证撞号:v0.19 曾被并行两批同时占用) - ver_seen = {} # key: 归一版本号 → [首次原样 token, 出现次数] - for table in version_tables: - for row in table[1:]: # 首行 = 表头 - if SEPARATOR_ROW_RE.match(row.strip()): - continue - cells = [c.strip() for c in re.split(r"(? 1: - issues.append(f"R10 版本历史版本号重复: {first}({count} 处)") + # R4 禁设变更记录节(2026-10-19 用户裁「沿革只进 git」——原「必须有版本历史节」反转; + # 一切体裁与登记处无豁免,标题行本身即违规,节内容不再逐行判) + for l in changelog_hits(text): + issues.append(f"R4 禁设变更记录节: {l.strip()[:50]}(沿革只进 git commit log)") # R5 流程章节须含代码块图(清单节/词条节按 RULE_EXEMPT 豁免——节名含「流程」 # 即触发,但目检清单节与术语词条节不是流程描述,属节名误匹配) @@ -280,7 +243,7 @@ def lint_file(path): if pending_flow and not has_code and "R5" not in ex: issues.append(f"R5 「{cur_section}」节无流程图(须含代码块字符画/Mermaid)") cur_section = stripped.lstrip("#").strip() - pending_flow = bool(FLOW_SECTION_RE.search(cur_section)) and cur_section != VERSION_SECTION + pending_flow = bool(FLOW_SECTION_RE.search(cur_section)) has_code = False elif stripped.startswith("```") and cur_section: has_code = True @@ -320,17 +283,14 @@ def lint_file(path): ) break - # R11 计数词漂移对照(锚表 CURRENT_COUNTS;版本历史/修订记录节与轨迹措辞行豁免) - in_code11, hist11 = False, False + # R11 计数词漂移对照(锚表 CURRENT_COUNTS;轨迹措辞行豁免——变更记录节本身归 R4 禁设) + in_code11 = False for raw in text.splitlines(): stripped = raw.strip() if stripped.startswith("```"): in_code11 = not in_code11 continue - if raw.startswith("## "): - hist11 = bool(HISTORY_SECTION_RE.search(stripped.lstrip("#").strip())) - continue - if in_code11 or hist11 or stripped.startswith(";") or R11_TRACE_RE.search(raw): + if in_code11 or stripped.startswith(";") or R11_TRACE_RE.search(raw): continue # yaml/yml 的 # 行内注释是登记轨迹,不入正文扫描 line = raw.split("#", 1)[0] if str(path).endswith((".yaml", ".yml")) else raw @@ -352,23 +312,34 @@ def lint_file(path): def main(): ap = argparse.ArgumentParser(description="GDD lean 格式门禁") - ap.add_argument("files", nargs="*", help="待检查文件(默认 design/gdd/ 下系统级 GDD)") + ap.add_argument("files", nargs="*", help="待检查文件(默认 design/gdd/ 根层 GDD + roadmap.md)") + ap.add_argument("--changelog-only", action="store_true", + help="只跑 R4 变更记录节禁令,扫描面扩到全 design/ 树+roadmap.md") ap.add_argument("--json", action="store_true", help="JSON 输出") args = ap.parse_args() - if args.files: + if args.changelog_only: + targets = sorted( + p for p in list(Path("design").rglob("*.md")) + list(Path("reports").glob("*.md")) + [Path("roadmap.md")] + if p.is_file() + ) + elif args.files: targets = [Path(f) for f in args.files] else: root = Path(DEFAULT_DIR) targets = sorted( - p for p in root.glob("*.md") - if p.name not in DEFAULT_EXCLUDE and not re.search(r"review|report", p.name, re.I) + p for p in list(root.glob("*.md")) + [Path("roadmap.md")] + if p.name not in DEFAULT_EXCLUDE + and not re.search(r"review|report|handoff", p.name, re.I) ) if not targets: print(f"未找到待检文件({DEFAULT_DIR}/)", file=sys.stderr) sys.exit(2) results = [lint_file(p) for p in targets] + if args.changelog_only: + for r in results: + r["issues"] = [i for i in r["issues"] if i.startswith("R4")] failed = [r for r in results if r["issues"]] if args.json: diff --git a/tools/gen_theme_icons.py b/tools/gen_theme_icons.py index b5ff694c..c7510790 100644 --- a/tools/gen_theme_icons.py +++ b/tools/gen_theme_icons.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -"""UI 全局主题批小位图生成脚本(迭代 25 T0,2026-10-13)。 +"""UI 全局主题小位图生成脚本。 产出(→ game/assets/art/ui/gen/,纯色/几何、像素风): slider_grabber.png 滑轨柄·常 12×12 CANDLE #F6C667 + PANEL_BORDER #786E58 1px 描边 @@ -14,7 +14,7 @@ checkbox_checked_disabled.png 勾选框·选·废 14×14 同底边 + STONE_DEEP 对勾 色值全部取自 game/presentation/views/ui_kit.gd 既有常量(溯源表见 game/assets/theme/README.md)—— -不新增美术素材、不动美术圣经 §7(迭代 25 契约)。滚动条柄不走位图:Godot 4 ScrollBar 的 +不新增美术素材、不动美术圣经 §7。滚动条柄不走位图:Godot 4 ScrollBar 的 grabber 是 StyleBox(非 Icon),纯色 StyleBoxFlat 直接承载(见 main_theme.tres)。 ♻ 可重跑:本脚本幂等,重复执行覆盖产出;改色值只改本脚本顶部常量后重跑 + 重导。 diff --git a/tools/golden_baseline_refresh.sh b/tools/golden_baseline_refresh.sh index ed8a7697..09a92c79 100644 --- a/tools/golden_baseline_refresh.sh +++ b/tools/golden_baseline_refresh.sh @@ -1,14 +1,14 @@ #!/usr/bin/env bash -# golden 基线换代辅助(迭代 19 卡① T2 2026-10-08——呈现类改动批专用;迭代 28 T4 扩菜单全屏基线路径)。 +# golden 基线换代辅助(呈现类改动批专用;含棋盘与菜单全屏两种基线路径)。 # 权限口径(Q6):呈现类改动批内 agent 自行换代+提交说明**强制写明触发原因**;数值/逻辑批禁碰。 # 前置条件(Q5/S3):素材必须齐盘(本脚本逐项守卫,缺位即拒跑退出 1=基线禁锚回退态; # 缺位时先拷主区素材+导入边车再跑)。 # 模式: -# --menu(迭代 28 T4 新增):shot_probe 启动态菜单整屏帧 → game/tests/golden/menu_boot.png。 -# 全屏基线可行性前置已验证:菜单连续帧差 0.0000%/max_diff=0(2026-10-15 帧差诊断——光柱为 +# --menu:shot_probe 启动态菜单整屏帧 → game/tests/golden/menu_boot.png。 +# 全屏基线可行性前置已验证:菜单连续帧差 0.0000%/max_diff=0(光柱为 # 程序生成静态贴片、零动画着色器,全屏基线不抖动);采集确定性=探针隔离档(无断点+出厂 # 设置 1280×800),与 render_gate 的 shot_menu 对比段同源同帧。 -# 缺省(棋盘,原口径):board_shot_probe 抓 L1-L3 整屏帧+board_meta.json → golden_board_crop.py +# 缺省(棋盘):board_shot_probe 抓 L1-L3 整屏帧+board_meta.json → golden_board_crop.py # 按 meta 取样坐标裁棋盘区(禁硬编码像素)→ 覆盖 game/tests/golden/ 三张基线。 # 过程截图落 mktemp 临时区即弃(Q2),只有基线产物入库。 # 用法: tools/golden_baseline_refresh.sh [game目录] [--menu] 触发原因写进当批提交说明(强制)。 diff --git a/tools/golden_board_crop.py b/tools/golden_board_crop.py index e74e8f5e..94d6caa3 100644 --- a/tools/golden_board_crop.py +++ b/tools/golden_board_crop.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 -r"""golden_board_crop.py — 棋盘 golden 前置裁剪(迭代 19 卡① T2 2026-10-08)。 +r"""golden_board_crop.py — 棋盘 golden 前置裁剪。 board_shot_probe 截整屏视口(get_viewport().get_texture()),golden 逐像素对比前须裁出棋盘区。 本工具按 board_meta.json 取样坐标(board_shot_probe 输出的棋盘视图实测全局矩形)裁剪, -**禁硬编码像素**(迭代 15③ 挂账口径——布局改动只须重跑探针刷新 meta,裁剪代码零改动)。 +**禁硬编码像素**(口径:布局改动只须重跑探针刷新 meta,裁剪代码零改动)。 用法: python tools/golden_board_crop.py <截图目录> <输出目录> 输出: <输出目录>/board_.png(tag=meta 键,如 L1_dungeon)。 diff --git a/tools/golden_compare.py b/tools/golden_compare.py index 817d6ec8..af8bbea6 100644 --- a/tools/golden_compare.py +++ b/tools/golden_compare.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -r"""golden_compare.py — C 档黄金图对比(迭代 9 卡⑰b 2026-09-30;呈现层测试分级·周期重闸件)。 +r"""golden_compare.py — C 档黄金图对比(呈现层测试分级·周期重闸件)。 用法: python tools/golden_compare.py <黄金图目录> <新截图目录> [屏清单...] 默认屏清单 = shot_menu.png shot_camp.png shot_level.png shot_battle.png。 @@ -8,7 +8,7 @@ r"""golden_compare.py — C 档黄金图对比(迭代 9 卡⑰b 2026-09-30; ① 四屏存在且尺寸一致(与黄金图逐屏比对); ② 逐像素灰度差 >16 的像素占比 ≤2%(抗锯齿/微噪声容差带——结构级变化必超带); ③ changed 占比 >2% 即 FAIL(视觉回归信号——逐屏列差异热区提示)。 -基准冻结=2026-09-30(v3.5 视觉落码+营地终稿+分辨率案甲后);资产升档批换代时显式重制基准。 +基准冻结于 v3.5 视觉落码+营地终稿+分辨率案甲后;资产升档换代时显式重制基准。 退出码: 0 = 全过 / 1 = 有失败。 """ import sys diff --git a/tools/log_analysis.py b/tools/log_analysis.py index 18c225a5..b7db4116 100644 --- a/tools/log_analysis.py +++ b/tools/log_analysis.py @@ -33,7 +33,7 @@ from collections import Counter, defaultdict # ---------------------------------------------------------------- 常量与映射 -# step 行已知键(schema 事实源 = playtest_logger.gd _on_step_row,2026-09-16 版) +# step 行已知键(schema 事实源 = playtest_logger.gd _on_step_row) STEP_KNOWN_KEYS = {"kind", "type", "source", "cell", "round", "text", "value", "highlight"} # AC 掷点批候选字段名(落批后按实际字段名在此登记——预留的一行适配点) diff --git a/tools/palette_check.py b/tools/palette_check.py index ecbb5cb0..b1cc3d87 100644 --- a/tools/palette_check.py +++ b/tools/palette_check.py @@ -1,20 +1,19 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -"""B2 色板检查器(圣经 §8.3①挂点实现 · 立绘定档批 2026-10-07)。 +"""B2 色板检查器(圣经 §8.3①挂点实现)。 -⚠⚠ 口径纪律(2026-10-07 实跑后订正,**勿改回**)——两处极易写错: +⚠⚠ 口径纪律(**勿改回**)——两处极易写错: 1. **48 色上限不是「每张 PNG 的色数」**。§4.1 的「全作色板硬上限 48 色」指 **设计色板 token**(UI 语义色/墨色/材质色那套),不是像素画的独立色数。 像素画单张另有**32 色冻结**口径,由 standee_asset_check 管(像素域)。 - 初版把 48 套到每张 PNG 上⇒ 12 张全红(误报率 100%),已作废。 - 本器改为:单张色数**只报读数不判红**;48 只在 --tokens 模式下校验色板表。 + 本器口径:单张色数**只报读数不判红**;48 只在 --tokens 模式下校验色板表。 2. **近色 ≥8/255 是「新色入板双门」,不是存量两两互查**。§4.1 原文: 「**新色**入板须同时过两道门……②与既有任一色的 RGB 三通道差 ≥8/255」。 它管的是**新增色 vs 既有色板**。对存量色两两互查会把 AI 生成的明暗渐变 全部打成近色(实测 drider 22 组 / 巨蜘蛛 82 组)⇒ 噪声淹没真问题。 - 本器改为:近色**只对新增色集**判(新增色 vs 基线色板)。 + 本器口径:近色**只对新增色集**判(新增色 vs 基线色板)。 另:必须排除全透明像素 (0,0,0,0)(同standee_asset_check 的坑)。 diff --git a/tools/parity_anchor.py b/tools/parity_anchor.py index 26d07ae1..a5c7605c 100644 --- a/tools/parity_anchor.py +++ b/tools/parity_anchor.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -"""parity_anchor.py — 迭代27重构「逐位一致对拍」锚工具(代码架构技术债修复批〔迭代 27〕§7 V1 核心验收;该卡已按 doc-conventions §11「吸收即死」退役,git 历史可考) +"""parity_anchor.py — 「逐位一致对拍」锚工具(架构重构前后逐位一致验收;原需求卡已按「吸收即死」退役,凭据见 git 提交史) 载体 = adventure_monte_carlo.gd 同种子批量完整局(SceneTree headless,自持 ConfigDB,零渲染)。 三变体钉死(种子面错开,覆盖 base / 同调账 / 商店-GP 账三类 T2/T3 重构面): diff --git a/tools/path_check.py b/tools/path_check.py index b976e13c..2f5dd793 100644 --- a/tools/path_check.py +++ b/tools/path_check.py @@ -188,12 +188,13 @@ def main(): print(" · %-46s ← %s" % (ref, where[0])) print("\n=== 退役命名扫描 ===") - # ⚠ 口径纪律:退役命名**只在代码与素材清单里是违规**;文档的版本历史与叙述性文件 - # 提到这些名字属正常,不是违规。故扫描面只含:代码(.gd/.tscn) + 素材清单 - # (design/art/*.md,且文件名不含「版本历史」),其余一律不扫; + # ⚠ 口径纪律:退役命名**只在代码与素材清单里是违规**;叙述性文档提到这些名字属正常, + # 不是违规。故扫描面只含:代码(.gd/.tscn) + 素材清单(design/art/*.md),其余一律不扫; # .git/.workbuddy/.zcode/archive 在目录层就排除。 # 2026-10-07 初版全仓扫 .md 曾把历史记述全判成违规,故收窄到上述两面(当日还额外跳过 - # 根目录会话状态文件,该文件已于 2026-10-18 用户裁废除,跳过项一并删除)。 + # 根目录会话状态文件,该文件已于 2026-10-18 用户裁废除,跳过项一并删除; + # 「版本历史」文件名跳过项亦于 2026-10-19 变更记录节禁设批删除——此类节改由 + # gdd_lint.py --changelog-only 全 design/ 扫,本工具不再分派豁免)。 hits = 0 scan_exts = (".gd", ".tscn") for dirpath, dirnames, names in os.walk(repo): @@ -206,9 +207,7 @@ def main(): if any(s in rel for s in (".workbuddy", ".zcode")): continue is_code = fn.endswith(scan_exts) - is_manifest = (fn.endswith(".md") - and os.sep + "art" + os.sep in fp - and "版本历史" not in fn) + is_manifest = (fn.endswith(".md") and os.sep + "art" + os.sep in fp) if not (is_code or is_manifest): continue try: diff --git a/tools/pixelize_candidates.py b/tools/pixelize_candidates.py index 7ae9208e..5d397d47 100644 --- a/tools/pixelize_candidates.py +++ b/tools/pixelize_candidates.py @@ -2,10 +2,10 @@ # -*- coding: utf-8 -*- """远程生图候选 → 像素化候选稿 v3(v1.3 五步流程第 4 步)。 -v3 演进(2026-09-27 用户四问题:脏点/模糊/信息丢失/白边): - - 档位翻倍: 普通怪 96 / 精英 128 / Boss 192(终值仍归战斗一屏样张批) +v3 设计要点(对应四类问题:脏点/模糊/信息丢失/白边): + - 档位翻倍: 普通怪 96 / 精英 128 / Boss 192(终值仍归战斗一屏样张) - 去底去影 = 「奶油描边屏障法」: 描边膨胀 3px 作屏障,从图缘一口吞掉底色+地面影 - (v1 的影色相规则对 hook_horror 同色系必误吞,废弃) + (影色相规则对同色系必误吞,禁用) - 白边 = 吃描边: 主色距离门 + 「底色↔主色线段」反锯齿混合带桥(限层深,防深入本体) - 教训: 不做第二遍低膨胀洪泛——JPEG 噪点在描边开 1-2px 缺口会洪灌本体 (duergar 甲面被吃空实证);屏障只跑一遍 dil=3 @@ -15,7 +15,7 @@ v3 演进(2026-09-27 用户四问题:脏点/模糊/信息丢失/白边): python tools/pixelize_candidates.py <目录> --standee48 [--standee-out ] # 九张 48px 站桩槽位档(八敌 pixel-1+主角 normal; # 底中锚/NEAREST/统一比例保体量/画布高恒 48) ---fixer(2026-09-29 迭代 6 T1 管线正式化,收编 09-28 手工批次): rust pixelfixer(Retro-Diffusion, +--fixer: rust pixelfixer(Retro-Diffusion, MIT, D:/code/pixel-art-fixer)对原图先做网格检测+重建(收网格),v3 去底后再跑封闭灰袋清除 (三闸=近底色∧中性灰∧组件不触图缘——防误伤盔甲与影);--fixer-exe 可换引擎路径。 """ @@ -28,7 +28,7 @@ FIXER_EXE = FIXER_EXE_DEFAULT # --fixer-exe 可覆写(__main__ 解析) STANDEE_SLOT_H = 48 # 主角站桩源档高(×2 整数放大=盒高 96——圣经 §8.2) STANDEE_SLOT_W_MAX = 75 # 盒宽 150 的一半(超宽才按宽收,现八敌+主角均不触) -# 八敌站桩源档高 = 生物体型,不是强度档位(2026-10-06 用户裁定) +# 八敌站桩源档高 = 生物体型,不是强度档位 # 口径:体量按「这只生物本来多大」定;强度改由别的通道承载(Boss 的紫赤色相独占、 # 精英的垂直延伸、HUD 意图徽标)。因此下表与 §5.5 的普通/精英/Boss 档位**不对齐**—— # 例如钩爪恐魔是普通怪却比精英灰矮人大,灰矮人是精英却比普通/精英熊地精小。 @@ -348,7 +348,7 @@ def strip(spr, path): sheet.save(path) def remove_closed_gray_bags(im): - """封闭灰袋清除(09-28 批手工步骤收编):本体轮廓内困住的底色/灰袋,图缘洪泛够不着。 + """封闭灰袋清除:本体轮廓内困住的底色/灰袋,图缘洪泛够不着。 三闸全过才除(防误伤盔甲与影): ①近底色(四角底色距离门) ②中性灰(低饱和) ③连通组件不触图缘(封闭——贴缘的地面影属开放区,洪泛已处理)。 @@ -457,14 +457,14 @@ def dom_block_resize(im, nw, nh): def build_standee48(batch_root, out_dir, extra_hero_states=("attack", "hit")): - """出八敌 + 主角的站桩源档。源 = 八敌 pixel-1 + 主角 normal_1x(追加 attack/hit,T3 起默认)。 + """出八敌 + 主角的站桩源档。源 = 八敌 pixel-1 + 主角 normal_1x(追加 attack/hit,默认启用)。 - 口径(2026-10-06 用户裁定,取代旧的「统一比例」): + 口径: 1. 八敌各自按 STANDEE_TIER_H 定高——那是生物体型,不是强度档位。 - 旧口径是「全敌共用 48/最大值」一个系数,结果普通怪只剩 21–24px, - 全部低于可读门槛(实测门槛约 32px,48px 舒适),钩爪恐魔被压成一团糊。 + (实测可读门槛约 32px,48px 舒适;若全敌共用「48/最大值」一个系数, + 普通怪被压到 21–24px 低于门槛、钩爪恐魔糊成一团——禁用统一比例。) 2. 主角仍按 STANDEE_SLOT_H(48)定高。 - 3. 画布高度 = 该角色自己的档高(不再是统一 48);内容裁透明边后底中锚贴底缘。 + 3. 画布高度 = 该角色自己的档高;内容裁透明边后底中锚贴底缘。 4. 降采样走 dom_block_resize(块内众数投票,零插值)。 """ os.makedirs(out_dir, exist_ok=True) diff --git a/tools/probe_gate.sh b/tools/probe_gate.sh index 7b69c3b4..d4f46866 100644 --- a/tools/probe_gate.sh +++ b/tools/probe_gate.sh @@ -1,21 +1,20 @@ #!/usr/bin/env bash -# 轻闸探针正主(2026-10-02 挂死灾害批落籍)——headless 安全段固化,禁再手拼同款 Godot 命令。 +# 轻闸探针正主——headless 安全段固化,禁再手拼同款 Godot 命令。 # 三闸:①每段 timeout 守卫(挂死=FAIL 不静默)②段前预清+段后清本 game 目录孤儿 Godot # (按命令行精确匹配本 game 路径,不误杀其他 worktree 会话的合法进程)③末尾残留清点=批末闸(必须 0)。 -# 段:ui_input_probe=默认必跑;ui_struct_probe=默认必跑(ui-struct-probe mini-loop 2026-10-05 注册—— -# 全 UI 屏结构断言:按钮互压/等宽/出屏/零尺寸/标题屏双列);ui_contrast_probe=默认必跑(UI 设计对齐批 -# T2 2026-10-06 注册——UI 文字对比度机检 ≥4.5:1 无区域例外,测点表随批维护);--click=加跑 ui_click_probe 行为走查 -# (自退出+退出码闸;超时多半=探针未适配新停点层,归 probe适配批)。 -# layout_probe=默认必跑(2026-10-15 建——分辨率几何断言,档位表是数据/断言是一份函数, +# 段:ui_input_probe=默认必跑;ui_struct_probe=默认必跑( +# 全 UI 屏结构断言:按钮互压/等宽/出屏/零尺寸/标题屏双列);ui_contrast_probe=默认必跑( +# UI 文字对比度机检 ≥4.5:1 无区域例外,测点表随改动维护);--click=加跑 ui_click_probe 行为走查 +# (自退出+退出码闸;超时多半=探针未适配新停点层,需做探针适配)。 +# layout_probe=默认必跑(分辨率几何断言,档位表是数据/断言是一份函数, # 增删档位只改表内一行;用 content_scale_size 改逻辑视口,headless 下真生效—— -# 旧 ui_layout_probe 用 get_window().size 在 headless 下不改变视口,其「1920 档恒定」 -# 断言是永远为真的假断言,随该探针退役)。 -# 判定口径(迭代 29 T1 三硬闸):每段走 verdict 函数——①退出码为唯一权威判据(PASS 串降级为日志) +# get_window().size 在 headless 下不改变视口,其「1920 档恒定」类断言是 +# 永远为真的假断言,禁用)。 +# 判定口径(三硬闸):每段走 verdict 函数——①退出码为唯一权威判据(PASS 串降级为日志) # ②脚本错误扫描命中即红(tools/error_scan.py,标记与 run_smoke.py 同源)③PASS 串保留为附加判据。 -# --full 段(迭代 19 卡① T3 收编 2026-10-08——重闸件):ui_probe/ui_tune_probe/t17_defer_probe/fx_probe -# 四件带断言探针收进(此前游离在一切闸外只能手敲);轻闸默认段断言面零删减零改动(--full 只增不改)。 -# 渲染面归 render_gate.sh 正主(窗口化:shot_probe 七屏+fx_shot/board_shot 取证+棋盘 golden 逐像素)—— -# 旧头注「shot_probe 禁入本闸……归真人目检」纪律句随三闸口径扩容改写退役(2026-10-07 用户授权=历史偷懒标记)。 +# --full 段(重闸件):ui_probe/ui_tune_probe/t17_defer_probe/fx_probe +# 四件带断言探针;轻闸默认段断言面零删减零改动(--full 只增不改)。 +# 渲染面归 render_gate.sh 正主(窗口化:shot_probe 七屏+fx_shot/board_shot 取证+棋盘 golden 逐像素)。 # 用法: tools/probe_gate.sh [game目录] [--click] [--full] 缺省 game 目录=脚本所在仓库的 game/(worktree 内自动指向该 worktree) # 依赖: Git Bash(coreutils timeout/taskkill) + PowerShell;Godot 路径可用环境变量 GODOT_BIN 覆盖。 set -u @@ -124,7 +123,7 @@ if [ "$WITH_CLICK" -eq 1 ]; then verdict "ui_click_probe" "$TMP/clk.log" "$st" "click_probe" || _rc=1 fi -# ── --full 收编段(迭代 19 卡① T3 2026-10-08——四件带断言探针入闸;实测时长 ui_probe 17.4s/ +# ── --full 段(四件带断言探针入闸;实测时长 ui_probe 17.4s/ # ui_tune_probe 49.6s/t17_defer_probe 63.0s/fx_probe 21.9s,timeout 120=2-7×余量) ── if [ "$WITH_FULL" -eq 1 ]; then echo "======== ui_probe(--full 收编) ========" diff --git a/tools/quantize_ui_skin.py b/tools/quantize_ui_skin.py index c69c88c7..22b8737e 100644 --- a/tools/quantize_ui_skin.py +++ b/tools/quantize_ui_skin.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -"""UI 框材组量化改色脚本(M-1 迭代 2 T2,2026-09-28)。 +"""UI 框材组量化改色脚本。 ♻ 复用件 → 复用闸①色板量化:全部产物按明度重映射到 art-bible §4.1/§7.2 token 渐变带, 不保留原包杂色;闸②禁入带=token 色天然合规;闸③灰度可辨=图标四形互异;闸④授权=全 CC0。 @@ -105,7 +105,7 @@ def main(): jobs.append(("icon_forge.png", recolor_flat(Image.open(src_path(*(icon_dir + ("sword.png",)))), ICON_WARM))) jobs.append(("icon_workshop.png", recolor_flat(Image.open(src_path(*(icon_dir + ("flask_full.png",)))), ICON_WARM))) jobs.append(("icon_atlas.png", recolor_flat(Image.open(src_path(*(icon_dir + ("book_open.png",)))), ICON_WARM))) - # 节点图标五件(board-game-icons 64px→20px 烘焙,WARM 单色——关卡画面样张 v1 冻结形制,M-2 迭代 4 T2; + # 节点图标五件(board-game-icons 64px→20px 烘焙,WARM 单色——关卡画面样张 v1 冻结形制; # 战=bow/赏=award/疗=campfire/王=crown_b/商=pouch,语义近似+灰度互辨,色相不承载身份 §4.6) node_jobs = (("node_battle.png", "bow.png"), ("node_reward.png", "award.png"), ("node_rest.png", "campfire.png"), ("node_boss.png", "crown_b.png"), diff --git a/tools/recolor_terrain_tiles.py b/tools/recolor_terrain_tiles.py index 0c35eadc..d297dd5f 100644 --- a/tools/recolor_terrain_tiles.py +++ b/tools/recolor_terrain_tiles.py @@ -1,4 +1,4 @@ -# tools/recolor_terrain_tiles.py — 高墙/地面瓦片程序换色(T6,M-1 迭代 1) +# tools/recolor_terrain_tiles.py — 高墙/地面瓦片程序换色 # 用法: # python tools/recolor_terrain_tiles.py # 产 underdark + deep_underdark 两套到源目录 # python tools/recolor_terrain_tiles.py --palettes underdark diff --git a/tools/render_gate.sh b/tools/render_gate.sh index c2365766..3ca4a1ac 100644 --- a/tools/render_gate.sh +++ b/tools/render_gate.sh @@ -1,28 +1,26 @@ #!/usr/bin/env bash -# 渲染闸正主(迭代 19 卡① 自动化验收补齐批 2026-10-08 落码——T1/T2)——窗口化自动闸。 -# 迭代 15③ 挂账「渲染五闸」机器补跑半随本闸落籍(shot_probe/golden_compare/board_shot 三件入闸; -# fx_probe 逻辑层归 probe_gate --full——归宿对账见卡①任务书 §一; -# ui_layout_probe 原列此处,2026-10-15 用户裁「无使用的探针删除」随批退役,1920 档布局机检面待补)。 +# 渲染闸正主——窗口化自动闸。 +# 范围(渲染五闸的机器面:shot_probe/golden_compare/board_shot 三件入闸; +# fx_probe 逻辑层归 probe_gate --full;1920 档布局机检面待补)。 # 骨架复用 probe_gate:①每段 timeout 守卫(挂死=FAIL 不静默)②段前预清+段后清本 game 目录孤儿 # Godot(按命令行精确匹配本 game 路径,不误杀其他 worktree 会话)③末尾残留清点=批末闸(必须 0)。 # 段: -# ① shot_probe 七屏窗口化截图(menu/settings/career/camp/level/battle/status——迭代 19 卡① T1 扩屏) +# ① shot_probe 七屏窗口化截图(menu/settings/career/camp/level/battle/status) # → tools/shot_checker.py A-D 语义断言自动判定(A 屏级骨架全屏/B 文字对比度/C 明度三档带/ # D 文字禁压纹理;E 焦点预算=语义面仍归人闸不机检)。首跑存量 FAIL 按 S1 停机点全量呈报登记 06。 # ② 取证段(Q7:超时/零字节/文件缺失任一即 FAIL——「渲染真实发生」必须成立,不做像素判定): # fx_shot_probe 三时刻抓帧(行到达/结算排播/轮末连帧)+ board_shot_probe L1-L3 棋盘抓帧。 -# ③ 棋盘 golden 逐像素(T2):board 整屏帧按 board_meta.json 取样坐标裁剪棋盘区 +# ③ 棋盘 golden 逐像素:board 整屏帧按 board_meta.json 取样坐标裁剪棋盘区 # (tools/golden_board_crop.py——禁硬编码像素)→ tools/golden_compare.py 对 # game/tests/golden/ 三张基线(容差 provisional:差 ≤16/changed ≤2%,S2 停机点口径)。 -# 素材缺位=判红(2026-10-17 改;此前是 SKIP 不判红——但缺盘时这一段根本不对比,闸末仍打 -# 「全绿」exit 0,等于空跑判绿。基线生成期素材缺位=L3 停机,运行期同样无权出验收结论)。 +# 素材缺位=判红:缺盘时这一段根本不对比,若 SKIP 则闸末照样打 +# 「全绿」exit 0,等于空跑判绿。基线生成期素材缺位=L3 停机,运行期同样无权出验收结论。 # ④ 基准档 1280 单档(Q4)。1920 档注记:16:9 全屏下 stretch=canvas_items/aspect=keep 等比 -# 1.35×+左右黑边各 96px,构图与基准档一致(迭代 9 分辨率案甲)——分辨率维度不重复建闸。 -# (原由 ui_layout_probe 两档断言承担,探针已随 2026-10-15 裁「无使用的探针删除」退役, -# 1920 布局机检面现无承载,待补。) +# 1.35×+左右黑边各 96px,构图与基准档一致(分辨率案甲)——分辨率维度不重复建闸。 +# (1920 布局机检面现无承载,待补。) # 过程产物纪律(Q2):一切截图 PNG 落 mktemp 临时区,闸毕即弃——任何过程 PNG 禁入 git; # 例外=game/tests/golden/ 基线(测试资产入库,.gitignore 已核不挡)。 -# 窗口化运行会短暂弹 Godot 窗口(本机可开窗口径,2026-10-07 用户令);禁改 --headless 跑本闸 +# 窗口化运行会短暂弹 Godot 窗口(本机可开窗口径);禁改 --headless 跑本闸 # (headless 无渲染面,探针内 fail-fast 护栏会红——那是护栏生效不是闸红)。 # 用法: tools/render_gate.sh [game目录] 缺省 game 目录=脚本所在仓库的 game/(worktree 内自动指向该 worktree) # 依赖: Git Bash(coreutils timeout/taskkill) + PowerShell + python(PIL);Godot 路径可用环境变量 GODOT_BIN 覆盖。 @@ -113,9 +111,8 @@ if [ ! -d "$REPO/game/tests/golden" ]; then elif [ ! -s "$BD/board_meta.json" ]; then echo "[render_gate] SKIP — board_meta.json 缺失(取证段已红),golden 对比不判" else - # 素材缺位=判红(2026-10-17 由 SKIP 改):缺盘态下这一段一个像素都不比,而闸末照样打印 - # 「全绿」退出码 0——那是空跑判绿,比误红危险得多(2026-10-16 菜单废基线事故正是靠它蒙过 - # worktree 自检的)。基线锚在素材齐盘态(Q5),缺盘态本就无权出验收结论。 + # 素材缺位=判红:缺盘态下这一段一个像素都不比,而闸末照样打印 + # 「全绿」退出码 0——那是空跑判绿,比误红危险得多。基线锚在素材齐盘态(Q5),缺盘态本就无权出验收结论。 _asset_miss=0 for a in assets/fonts/ui_font_fusion_pixel_zh_hans.ttf \ assets/art/board/seal_mark.png \ diff --git a/tools/render_level_map_sheet.py b/tools/render_level_map_sheet.py index 271d4666..51b25083 100644 --- a/tools/render_level_map_sheet.py +++ b/tools/render_level_map_sheet.py @@ -1,28 +1,28 @@ # -*- coding: utf-8 -*- -"""关卡画面样张验收图生成脚本 v1(2026-09-28,M-2 迭代 4 T1)。 +"""关卡画面样张验收图生成脚本 v1。 -闸形 A(M-1 迭代 2 先例,2026-09-27 拍板):断言集从 level-map.md AC + art-bible 硬指标直接推导 -(本样张无历史否决原因输入),生成即验,全过即冻结落码;气质终审 = 批末用户目检(=M-2 出口闸)。 +闸形 A:断言集从 level-map.md AC + art-bible 硬指标直接推导 +(本样张无历史否决原因输入),生成即验,全过即冻结落码;气质终审 = 批末用户目检。 断言集(事实源=level-map.md AC/Accessibility + art-bible §4.1/§4.2/§2.7/§7): L1 五节点类型图标互辨(灰度截图可分类——level-map AC;kenney-board-game-icons CC0 五键) L2 节点四态(已过暗金/当前金/候选亮金描边/未来暗)灰度可分类 + Boss 紫赤描边灰度可辨 L3 数字对比硬指标(§4.1):顶栏 GP 徽章/底栏读数对屏底与对数据框 ≥4.5:1;节点字面(图标)对方块底 ≥4.5:1 L4 禁入带 HSV300°-345° 零命中(Boss 紫赤环 = §4.2 唯一合法占用者,环区白名单) - L5 画布随图自适应:深层节点在呈现/命中域内(routebug 83c11a1 回归;公式与 level_map_screen.gd 同源解析) + L5 画布随图自适应:深层节点在呈现/命中域内(routebug 回归防护;公式与 level_map_screen.gd 同源解析) L6 独立屏底:不透明屏底(BG_ROOT+石纹底噪,非半透暗幕零透出) L7 字形占位区不侵入:图标区与编号区 bbox 零重叠,双双不越方块内缘 A1a 色板对表圣经 §4.1 冻结值;A1b 禁入带扫描见 L4 A5 画布四缘 2px 净空;SRC 同源断言:画布公式/停点标题常量自 level_map_screen.gd 解析 样张内容 = level-map.md Layout 三分区 1:1 实比(顶栏关卡名+GP 徽章/节点图区/底栏状态组+放弃按钮) + 岔路停点主屏 + 入口停点对照屏 + S3 换层色板示意(§2.7/§4.3 色相层进,信息层恒定)。 -冻结值登记(样张通过值 → T2/T3 落码): +冻结值登记(样张通过值,供后续落码): 图标形制=kenney 64px 五键 NEAREST 22px,WARM 单色重着色,当前金底改 INK_ROUTE 墨(双色墨制); - 已过暗金冻结新值 GOLD_DONE #68562C(旧 GOLD_DIM 对双色墨均 <4.5:1,对比硬指标逼守); + 已过暗金冻结新值 GOLD_DONE #68562C(双色墨均须过 ≥4.5:1 对比硬指标,故逼守此值); 通道质感=STONE 2px/候选 GOLD_LIT 3px/悬停 4px 直角折线(中点肘形);画布公式=level_map_screen 同源; 底栏=暗底直角细线数据框+暖白读数;屏底=BG_ROOT+backdrop_stone 平铺。 素材不入 git——先查本仓库,缺位回退主检出(D:/code/g-plan2)。 -输出 = artwork/mockups/level-map-sheet-v1-2026-09-28.png(v1 命名——v1 被覆盖欠账教训先例) +输出 = artwork/mockups/level-map-sheet-v1-2026-09-28.png(文件名带版本与日期,防重渲染覆盖) + 机检报告(中间产物,吸收即死不入 git——doc-conventions §11)。 用法:python tools/render_level_map_sheet.py """ @@ -265,7 +265,7 @@ CHAIN = make_graph( def draw_screen(nodes, title, level_name, gp, visited, current, cands, hover=-1, cold_shift=False): img = Image.new("RGBA", (1280, 800), BG_ROOT + (255,)) - # 屏底石纹底噪(M-1 框材件;换层示意=cold_shift 时整体冷调——§4.3 wall_ambient 槽示意) + # 屏底石纹底噪(框材件;换层示意=cold_shift 时整体冷调——§4.3 wall_ambient 槽示意) noise = Image.open(asset_root(*BACKDROP)).convert("RGB") tile = Image.new("RGB", (1280, 800)) for ty in range(0, 800, noise.size[1]): diff --git a/tools/render_sample_sheet.py b/tools/render_sample_sheet.py index ae9a1cff..67b9e00c 100644 --- a/tools/render_sample_sheet.py +++ b/tools/render_sample_sheet.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- -"""战斗一屏样张验收图生成脚本 v2(2026-09-28,M-1 迭代 2 T1)。 +"""战斗一屏样张验收图生成脚本 v2。 -v1 用户否决四原因(2026-09-28)全部断言化——生成即验,不过闸不出图: +四项否决原因全部断言化——生成即验,不过闸不出图: F1 未开格 = 方案甲缘件 8 邻拼装(词表查表,禁整块 center 铺满) F2 旗仅出现于未开格 F3 小人脚锚 = 自底边 25% 线(⚠ 纵向比例一律自底边口径) @@ -9,7 +9,7 @@ v1 用户否决四原因(2026-09-28)全部断言化——生成即验,不过闸 F5 微光仅带状:接触带微光只画英雄格周界空间侧;类型微光禁整格染色;微光格零附加图形(角嵌退役) F6 墙格顶面/立面双明度带(否决③立体感——南向临地墙格 Δ≥18,体积感机器代理) F7 整板悬崖 DEPTH_PX 与 game 渲染常量同源(board_view.gd 解析——否决③立体感) -程序化审计(§9 初级验收授权 + 迭代 2 扩展): +程序化审计(§9 初级验收授权): A1 色板对表圣经冻结色板 + 禁入带(HSV 300°-345°)全图扫描 A2 拼缝周界闭合(墙↔地边界墙侧 2px 墨线带亮度 <70) A3 明度对比(数字墨×色牌 WCAG ≥4.5:1;图底分离 Δ≥55——否决③,v1 实测 61.9 上调逼守) @@ -23,7 +23,7 @@ v1 用户否决四原因(2026-09-28)全部断言化——生成即验,不过闸 素材不入 git——先查本仓库,缺位回退主检出(D:/code/g-plan2)。 词表事实源 = design/research/board-tile-vocab-plan-a-2026-09-26.md;画法参数事实源 = design/research/画法参数四源对照表-2026-09-26.md(四源对表先行产物)。 -输出 = artwork/mockups/sample-batch-v2-2026-09-28.png(v2 命名欠账清偿——v1 曾被重渲染覆盖) +输出 = artwork/mockups/sample-batch-v2-2026-09-28.png(文件名带版本与日期,防重渲染覆盖) + 机检报告(中间产物,吸收即死不入 git——doc-conventions §11)。 用法:python tools/render_sample_sheet.py """ @@ -63,12 +63,12 @@ INK_COLD = (19, 46, 54) # 青墨 1-3 #132E36 INK_OCHRE = (60, 37, 12) # 赭墨 4-5 #3C250C INK_RUST = (74, 30, 20) # 锈墨 6-8 #4A1E14 PLATE = (245, 234, 211) # 数字色牌 #F5EAD3 -SEAL_BLACK = (0, 0, 0) # 封印黑 #000000(旗朱→封印紫→封印黑 2026-09-28——紫与微光蓝族色相冲突退役) +SEAL_BLACK = (0, 0, 0) # 封印黑 #000000(紫与微光蓝族色相冲突,禁回紫) DANGER_RED = (168, 50, 31) # 危险红 #A8321F REWARD_GOLD = (240, 168, 40) # 奖励金 #F0A828 -HERO_BLUE = (46, 134, 222) # 小人蓝 #2E86DE(候选,样张批冻结——对照表 §5.1) +HERO_BLUE = (46, 134, 222) # 小人蓝 #2E86DE(候选,已冻结——对照表 §5.1) RED_MINE = (150, 44, 36) # 引爆雷字朱(游戏 UiKit.RED_MINE) -# 候选(样张批冻结项——对照表 §5) +# 候选(已冻结项——对照表 §5) CONTACT_GLOW = (214, 236, 255) # 接触带微光:小人蓝族浅两档(近白蓝) GLOW_GROUPS = { # §4.2 类型微光五组候选 "attack": (214, 193, 58), "heal": (92, 184, 58), "pierce": (46, 158, 158), @@ -143,7 +143,7 @@ def hero_sprite_transparent(src): HERO = hero_sprite_transparent(HERO_SRC) -# 裁除透明留白(v1 预筛发现:素材底部 7 行全透明——直接缩放则视觉脚浮于锚线上方 ~10px。 +# 裁除透明留白(素材底部 7 行全透明——直接缩放则视觉脚浮于锚线上方 ~10px。 # 裁后按内容 bbox 缩放,视觉脚底 = 脚锚线。游戏内 BoardWorld.ensure_hero 用原素材同病 # (视觉脚浮 ~10px)——呈现缺陷登记移交,本样张按设计规则出图) _HB = HERO.getbbox() @@ -223,7 +223,7 @@ def floor_variant(x, y): def apply_d_projection(board, gmap, cell): - """高墙感 D 投影档(2026-09-27 用户挑档;迭代 1 T2 同款参数——研究件 64px 拼版实测定比): + """高墙感 D 投影档(研究件 64px 拼版实测定比): 南临空墙格 = 立面口沿高光 2px Color8(196,172,132) + 双段暗带(0.16/0.25 格边,黑罩 α0.60/0.82); 北邻墙地面格 = 三段渐隐投影(顶带 0.22 格边,α0.28 起)。立体断言 F6/A6 的渲染承载。""" overlay = Image.new("RGBA", board.size, (0, 0, 0, 0)) @@ -292,9 +292,9 @@ def parse_game_const(path_parts, pattern): DEPTH_PX, DEPTH_PX_SRC = parse_game_const( ("game", "presentation", "views", "board_view.gd"), r"const DEPTH_PX\s*:?=\s*([0-9.]+)") -DENSITY_MIN = 4.70 # 观感密度下限(明度梯度均值)= v1 同口径实测 4.09 × 1.15(否决①总纲代理,迭代 2 白名单校准) +DENSITY_MIN = 4.70 # 观感密度下限(明度梯度均值)= v1 同口径实测 4.09 × 1.15(否决①总纲代理,白名单校准) FACADE_MIN = 18.0 # 顶面/立面双明度带下限(否决③体积感机器代理) -WALL_FLOOR_MIN = 55 # 图底分离下限(v1 断言 40→上调,v1 实测 61.9) +WALL_FLOOR_MIN = 55 # 图底分离下限(v1 实测 61.9,上调逼守) def _gd_darkened(c, k): @@ -524,7 +524,7 @@ def render_main_board(): cell = CELL_D records = [] - # 类型微光(未开格,F5b——角嵌退役批 2026-09-28:微光格只留微光,零角嵌/箭头/加号附加形) + # 类型微光(未开格,F5b——微光格只留微光,零角嵌/箭头/加号附加形) for (gx, gy, kind) in GLOW_CELLS: draw_type_glow(glow, gx * cell, gy * cell, cell, kind) board.alpha_composite(glow) @@ -627,7 +627,7 @@ def draw_standee(canvas, ox, oy, kind, name, enemy_id, order=1, armor="light", d.text((ox + W // 2, pbox_y + 30), glyph, font=F_INTENT, fill=col, anchor="mm") # 底座 d.rectangle([ox + 26, oy + 158, ox + W - 26, oy + 168], fill=(90, 82, 70), outline=(110, 100, 84)) - # 敌名行:护甲类型图标+纯名字(2026-09-26 终裁——AC 数值不展示) + # 敌名行:护甲类型图标+纯名字(AC 数值不展示) if kind == "enemy": d.text((ox + 16, oy + 172), ARMOR_ICONS[armor], font=F_NAME, fill=ARMOR_COLORS[armor], anchor="lm") d.text((ox + 30, oy + 172), name, font=F_NAME, fill=(30, 26, 22), anchor="lm") @@ -766,7 +766,7 @@ def run_checks(board, placement, records, band, gmap, canvas_img=None): viol.append(((gx, gy), diff)) check("F5b", "类型微光禁整格染色(中心 50% 区零染色像素)", not viol, "违例格 %s" % viol if viol else "五格中心区全净") - # F5c 微光格零附加图形(角嵌退役批 2026-09-28)——源码自检:微光段禁 draw_inlay 调用 + # F5c 微光格零附加图形——源码自检:微光段禁 draw_inlay 调用 # (像素层无法区分微光弥散与纹理墨线,回归防护在管线层断言;观感归批末目检) src = open(__file__, encoding="utf-8").read() seg = src[src.find("# 类型微光(未开格,F5b"):src.find("# 数字格(已开")] diff --git a/tools/render_sample_sheet_v3.py b/tools/render_sample_sheet_v3.py index a7ada074..b0abafe5 100644 --- a/tools/render_sample_sheet_v3.py +++ b/tools/render_sample_sheet_v3.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- -"""战斗一屏样张方向稿生成脚本 v3-draft(2026-09-29,art-bible v3.0 中修案 B 首批)。 +"""战斗一屏样张方向稿生成脚本 v3-draft(art-bible v3.0 中修案 B)。 -v3.0 口径(方向稿=目检先行闸,冻结归机检批): +v3.0 口径(方向稿=目检先行闸,冻结归机检): V1 格底明度分档:已开格底压暗至世界底层档(候选 L 0.08–0.14;§8.5 注记——压暗仅方向稿示意,终稿归地板素材选型/重产) V2 数字亮墨直画:亮族三档(冷亮/暖白/金亮,L≥0.75),色牌降级=复杂格底(物件纹样/装饰变体)后备 V3 装饰物件级解禁演示:小石块堆(专属装饰形状家族,圆钝三角形,零信息纪律不变) @@ -9,7 +9,7 @@ v3.0 口径(方向稿=目检先行闸,冻结归机检批): A3 断言改造:亮墨×实测已开格底 WCAG ≥4.5:1(色牌后备组维持深墨×牌 ≥4.5:1) 基于 v2 脚本定点补丁生成(_v3_patch.py),v2 冻结产物管线不动。 -v1 用户否决四原因(2026-09-28)全部断言化——生成即验,不过闸不出图: +四项否决原因全部断言化——生成即验,不过闸不出图: F1 未开格 = 方案甲缘件 8 邻拼装(词表查表,禁整块 center 铺满) F2 旗仅出现于未开格 F3 小人脚锚 = 自底边 25% 线(⚠ 纵向比例一律自底边口径) @@ -17,7 +17,7 @@ v1 用户否决四原因(2026-09-28)全部断言化——生成即验,不过闸 F5 微光仅带状:接触带微光只画英雄格周界空间侧;类型微光禁整格染色;微光格零附加图形(角嵌退役) F6 墙格顶面/立面双明度带(否决③立体感——南向临地墙格 Δ≥18,体积感机器代理) F7 整板悬崖 DEPTH_PX 与 game 渲染常量同源(board_view.gd 解析——否决③立体感) -程序化审计(§9 初级验收授权 + 迭代 2 扩展): +程序化审计(§9 初级验收授权): A1 色板对表圣经冻结色板 + 禁入带(HSV 300°-345°)全图扫描 A2 拼缝周界闭合(墙↔地边界墙侧 2px 墨线带亮度 <70) A3 明度对比(数字墨×色牌 WCAG ≥4.5:1;图底分离 Δ≥55——否决③,v1 实测 61.9 上调逼守) @@ -31,7 +31,7 @@ v1 用户否决四原因(2026-09-28)全部断言化——生成即验,不过闸 素材不入 git——先查本仓库,缺位回退主检出(D:/code/g-plan2)。 词表事实源 = design/research/board-tile-vocab-plan-a-2026-09-26.md;画法参数事实源 = design/research/画法参数四源对照表-2026-09-26.md(四源对表先行产物)。 -输出 = artwork/mockups/sample-batch-v3-final-2026-09-30.png(v3.5 冻结批产物转正——2026-09-30 批 A) +输出 = artwork/mockups/sample-batch-v3-final-2026-09-30.png(v3.5 冻结口径的正式产物) + 机检报告(中间产物,吸收即死不入 git;断言定值=A3b Δ≥30/A4 尺寸基线)。 用法:python tools/render_sample_sheet_v3.py """ @@ -77,12 +77,12 @@ INK_L_WARM = (240, 226, 200) # 暖白 4-5 #F0E2C8(关卡屏 WARM 同族) INK_L_GOLD = (248, 227, 168) # 金亮 6-8 #F8E3A8 FLOOR_DARK_GAMMA = 1.75 # 已开格底压暗曲线(方向稿示意):gamma 保纹理相对对比 FLOOR_DARK_GAIN = 0.92 -SEAL_BLACK = (0, 0, 0) # 封印黑 #000000(旗朱→封印紫→封印黑 2026-09-28——紫与微光蓝族色相冲突退役) +SEAL_BLACK = (0, 0, 0) # 封印黑 #000000(紫与微光蓝族色相冲突,禁回紫) DANGER_RED = (168, 50, 31) # 危险红 #A8321F REWARD_GOLD = (240, 168, 40) # 奖励金 #F0A828 -HERO_BLUE = (46, 134, 222) # 小人蓝 #2E86DE(候选,样张批冻结——对照表 §5.1) +HERO_BLUE = (46, 134, 222) # 小人蓝 #2E86DE(候选,已冻结——对照表 §5.1) RED_MINE = (150, 44, 36) # 引爆雷字朱(游戏 UiKit.RED_MINE) -# 候选(样张批冻结项——对照表 §5) +# 候选(已冻结项——对照表 §5) CONTACT_GLOW = (214, 236, 255) # 接触带微光:小人蓝族浅两档(近白蓝) GLOW_GROUPS = { # §4.2 类型微光五组候选 "attack": (214, 193, 58), "heal": (92, 184, 58), "pierce": (46, 158, 158), @@ -186,7 +186,7 @@ def hero_sprite_transparent(src): HERO = hero_sprite_transparent(HERO_SRC) -# 裁除透明留白(v1 预筛发现:素材底部 7 行全透明——直接缩放则视觉脚浮于锚线上方 ~10px。 +# 裁除透明留白(素材底部 7 行全透明——直接缩放则视觉脚浮于锚线上方 ~10px。 # 裁后按内容 bbox 缩放,视觉脚底 = 脚锚线。游戏内 BoardWorld.ensure_hero 用原素材同病 # (视觉脚浮 ~10px)——呈现缺陷登记移交,本样张按设计规则出图) _HB = HERO.getbbox() @@ -266,7 +266,7 @@ def floor_variant(x, y): def apply_d_projection(board, gmap, cell): - """高墙感 D 投影档(2026-09-27 用户挑档;迭代 1 T2 同款参数——研究件 64px 拼版实测定比): + """高墙感 D 投影档(研究件 64px 拼版实测定比): 南临空墙格 = 立面口沿高光 2px Color8(196,172,132) + 双段暗带(0.16/0.25 格边,黑罩 α0.60/0.82); 北邻墙地面格 = 三段渐隐投影(顶带 0.22 格边,α0.28 起)。立体断言 F6/A6 的渲染承载。""" overlay = Image.new("RGBA", board.size, (0, 0, 0, 0)) @@ -335,9 +335,9 @@ def parse_game_const(path_parts, pattern): DEPTH_PX, DEPTH_PX_SRC = parse_game_const( ("game", "presentation", "views", "board_view.gd"), r"const DEPTH_PX\s*:?=\s*([0-9.]+)") -DENSITY_MIN = 4.70 # 观感密度下限(明度梯度均值)= v1 同口径实测 4.09 × 1.15(否决①总纲代理,迭代 2 白名单校准) +DENSITY_MIN = 4.70 # 观感密度下限(明度梯度均值)= v1 同口径实测 4.09 × 1.15(否决①总纲代理,白名单校准) FACADE_MIN = 18.0 # 顶面/立面双明度带下限(否决③体积感机器代理) -WALL_FLOOR_MIN = 55 # 图底分离下限(v1 断言 40→上调,v1 实测 61.9) +WALL_FLOOR_MIN = 55 # 图底分离下限(v1 实测 61.9,上调逼守) def _gd_darkened(c, k): @@ -560,20 +560,20 @@ def draw_hero_on_board(board, ox, oy, cell, hx, hy, records, digit=None): records.append(("hero", hx, hy, fx, fy, digit)) -FACADE_FRAC = 0.30 # E 格墙面高度(新 v3.5:用户指令 30%) +FACADE_FRAC = 0.30 # E 格墙面高度(v3.5 定值 30%) def draw_facade(board, x0, y0, cell): - """v3.3 E 格墙面(用户方案:地面格南邻墙 → 南部承接墙面展示)。 + """v3.3 E 格墙面(地面格南邻墙 → 南部承接墙面展示)。 墙面=墙顶同款岩块材质(center 瓦片纹理直接贴,明度 ×0.85 表达垂直面),禁平涂新颜色: 北端=墙脚阴线(与地面交界),南端=檐口亮棱(与墙顶交界,受光棱线)。""" d = ImageDraw.Draw(board) fy0 = y0 + int(cell * (1.0 - FACADE_FRAC)) wall_top = WALLS["center"].resize((cell, cell), Image.NEAREST) face = wall_top.crop((0, 0, cell, cell - fy0 + y0)) - # 新 v3.5 ①:(b) 与 (c) 墙顶同色——顶面材质原亮度直贴,零暗档 + # v3.5 ①:(b) 与 (c) 墙顶同色——顶面材质原亮度直贴,零暗档 board.paste(face, (x0, fy0)) d.rectangle([x0, fy0, x0 + cell, fy0 + 1], fill=(52, 42, 32)) # 墙脚阴线(地面/墙面交界) - # v3.4:墙面底缘不画任何线——墙面直接接到南侧墙顶(用户裁:白边导致两截) + # 墙面底缘不画任何线——墙面直接接到南侧墙顶(白边会导致两截) def is_facade_cell(gmap, x, y): @@ -642,7 +642,7 @@ def render_main_board(): cell = CELL_D records = [] - # 类型微光(未开格,F5b——角嵌退役批 2026-09-28:微光格只留微光,零角嵌/箭头/加号附加形) + # 类型微光(未开格,F5b——微光格只留微光,零角嵌/箭头/加号附加形) for (gx, gy, kind) in GLOW_CELLS: draw_type_glow(glow, gx * cell, gy * cell, cell, kind) board.alpha_composite(glow) @@ -769,7 +769,7 @@ def draw_standee(canvas, ox, oy, kind, name, enemy_id, order=1, armor="light", canvas.alpha_composite(sh, (ox, oy + 146)) d.rectangle([ox + 18, oy + 158, ox + W - 18, oy + 170], fill=(150, 130, 100), outline=(90, 76, 58)) d.rectangle([ox + 18, oy + 158, ox + W - 18, oy + 160], fill=(196, 172, 132)) - # 敌名行:护甲类型图标+纯名字(2026-09-26 终裁——AC 数值不展示) + # 敌名行:护甲类型图标+纯名字(AC 数值不展示) if kind == "enemy": d.text((ox + 16, oy + 172), ARMOR_ICONS[armor], font=F_NAME, fill=ARMOR_COLORS[armor], anchor="lm") d.text((ox + 30, oy + 172), name, font=F_NAME, fill=(240, 226, 200), anchor="lm") @@ -915,7 +915,7 @@ def run_checks(board, placement, records, band, gmap, canvas_img=None): viol.append(((gx, gy), diff)) check("F5b", "类型微光禁整格染色(中心 50% 区零染色像素)", not viol, "违例格 %s" % viol if viol else "五格中心区全净") - # F5c 微光格零附加图形(角嵌退役批 2026-09-28)——源码自检:微光段禁 draw_inlay 调用 + # F5c 微光格零附加图形——源码自检:微光段禁 draw_inlay 调用 # (像素层无法区分微光弥散与纹理墨线,回归防护在管线层断言;观感归批末目检) src = open(__file__, encoding="utf-8").read() seg = src[src.find("# 类型微光(未开格,F5b"):src.find("# 数字格(已开")] @@ -970,10 +970,10 @@ def run_checks(board, placement, records, band, gmap, canvas_img=None): check("A3a", "v3 亮墨×格底 WCAG≥4.5:1(直画可行性硬指标) + 色牌后备组 ≥4.5:1", all(r[1] >= 4.5 for r in ratios) and all(r[1] >= 4.5 for r in plate_ratios), "亮墨%s 格底L=%.3f;后备%s" % (ratios, floor_l, plate_ratios)) - # A3b 图底分离:v2 阈值 Δ≥55 系色牌制时代校定(当时地板 L0.036);v3 地板提亮至 L 0.08–0.14 带后 + # A3b 图底分离:色牌制时代阈值 Δ≥55 系地板 L0.036 校定;v3 地板提亮至 L 0.08–0.14 带后 # 与墙顶亮度差数学上必缩(墙顶 ~113 封顶,Δ≥55 要求地板 ≤L0.045,与带冲突)——v3.0 验收 2 已立 - # 「墙亮/空间暗明度差为合法分类通道」。v3.5 冻结批(2026-09-30 批 A)定值 Δ≥30(方向稿实测 38, - # 灰度一眼可分)——候选口径退役,正式阈值落锁。 + # 「墙亮/空间暗明度差为合法分类通道」。冻结定值 Δ≥30(方向稿实测 38, + # 灰度一眼可分)。 check("A3b", "图底分离读数(定值 Δ≥30——v3.5 冻结批落定,方向稿实测 38)", (wall_top - floor_px) >= 30, "墙顶 %.0f vs 地面 %.0f,Δ=%.0f(v2 阈值 55 系地板 L0.036 时代校定;v3.5 冻结定值 30)" % (wall_top, floor_px, wall_top - floor_px)) @@ -1020,12 +1020,12 @@ def run_checks(board, placement, records, band, gmap, canvas_img=None): gmean = sum(grad) / len(grad) check("A6", "观感密度:明度梯度均值 ≥%.2f(v1 实测 4.09 上调 15%%——高频细节能量)" % DENSITY_MIN, gmean >= DENSITY_MIN, "梯度均值 %.2f(低频双峰由 A3 承载)" % gmean) - # A5 画布缘净空(说明行/图例溢出永久断言——v1 预筛两 FATAL 同根因) + # A5 画布缘净空(说明行/图例溢出永久断言,两处同根因) edge_hits = edge_content(canvas_img) check("A5", "画布四缘 2px 净空(零溢出)", edge_hits == 0, "缘带内容像素 %d" % edge_hits) # A4 混排相融:小人/立绘/状态图标=在库原件;语义色==UiKit 常量 - # A4 v3.5 冻结批(2026-09-30 批 A)尺寸基线按现行资产实态固化——立绘 46×48/棋盘小人源 32×32 - # 硬等断言落锁(资产升档批若换代须显式解冻重校,断言失败=预期闸)。 + # A4 尺寸基线按现行资产实态固化——立绘 46×48/棋盘小人源 32×32 + # 硬等断言落锁(资产升档换代须显式解冻重校,断言失败=预期闸)。 check("A4", "混排相融(在库原件可载+UiKit 语义色对表+尺寸基线冻结:立绘 46×48/小人源 32×32)", PORTRAIT_SRC.size == (46, 48) and HERO_SRC.size == (32, 32), "小人源 %s(裁透明留白后 %s)/立绘 %s[冻结 46×48]/状态图标原件;INK/封印黑/奖励金 == ui_kit.gd" diff --git a/tools/repo_structure_audit.py b/tools/repo_structure_audit.py index 63dbbc96..025695fb 100644 --- a/tools/repo_structure_audit.py +++ b/tools/repo_structure_audit.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -"""仓库结构审计闸(熵增闸,2026-09-27 用户立项)。 +"""仓库结构审计闸(熵增闸)。 收口第四闸(与 doc_link_audit / doc_term_audit / gdd_lint 同列): 把目录三层裁定变成机器检查——任何会话乱放文件,收口时此处直接 FAIL。 @@ -15,7 +15,7 @@ 用法: python tools/repo_structure_audit.py # 全查,FAIL 时 exit 1 python tools/repo_structure_audit.py --json # 机器读输出 -依据: AGENTS.md「Project Layout」节(2026-09-27 目录三层收敛终态)。 +依据: AGENTS.md「Project Layout」节。 """ import sys from pathlib import Path @@ -23,15 +23,14 @@ from pathlib import Path ROOT = Path(__file__).resolve().parent.parent # 1) 顶层目录白名单(点开头目录一律忽略) -# reports/ 收编(2026-10-17 用户裁「迭代批禁写 design/」):迭代实现报告/代拍板追认单/GDD 反哺点 -# 清单的家——实现批只准往这里写,design/ 全目录对它只读。只放 .md,不放图(图像白名单不含此目录)。 +# reports/:迭代实现报告/代拍板追认单/GDD 反哺点 +# 清单的家——迭代批禁写 design/,只准往这里写,design/ 全目录对它只读。只放 .md,不放图(图像白名单不含此目录)。 TOP_DIRS = {"archive", "artwork", "design", "game", "sim-data", "tools", "reports"} # 2) 根目录文件白名单 ROOT_FILES = {"AGENTS.md", "README.md", "roadmap.md", "stage.txt", "review-mode.txt", ".gitignore", ".zcodeignore"} # 3) 图像允许目录(相对路径前缀;archive/ 为归档 zip 不扫) -# game/tests/golden/ 收编(迭代 19 卡① T2/T6 2026-10-08——棋盘 golden 基线=机检测试资产非美术素材, -# 素材齐盘态生成入库【基线换代权限 Q6】;T1 落库时漏改本白名单致熵增闸红,同批修订 commit 留痕) +# game/tests/golden/(棋盘 golden 基线=机检测试资产非美术素材,素材齐盘态生成入库【基线换代权限 Q6】) IMAGE_EXTS = {".png", ".jpg", ".jpeg", ".webp", ".gif", ".svg", ".pxo", ".psd", ".bmp"} IMAGE_PREFIXES = ("artwork/", "game/assets/", "design/art/references/", "design/engineering/architecture/", "game/tests/golden/") diff --git a/tools/run_all_gates.sh b/tools/run_all_gates.sh index bd0a61ac..9fa4d1bc 100644 --- a/tools/run_all_gates.sh +++ b/tools/run_all_gates.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# 重闸唯一入口(2026-10-15 用户令「迭代完成前必须全量跑一遍所有测试」)—— +# 重闸唯一入口(迭代完成前必须全量跑一遍所有测试)—— # 闸清单的唯一定义处。文档只写「收口跑本脚本」,禁在文档里另列闸件清单(那正是 iter27 # 漏跑 probe_gate --full 的成因:清单散落三份文档、彼此不一致、且无机器校验)。 # @@ -18,7 +18,7 @@ # 与闸壳)自身的改动不占合回全量——其质量义务=落批时的变异验证(test-conventions §6); # 闸真崩溃时合回闸 fail-closed(跑不出回执即拦),不以全量为兜底。 # **域划分只在本脚本里定义一处**——文档只写「按改动域跑本脚本」,禁另列闸清单(清单散落多处 -# 正是 iter27 漏跑 probe_gate --full 的成因)。 +# 正是既往漏跑 probe_gate --full 的成因)。 # # 判定口径:每道闸与 game/tests/.gates/baseline.json 里的存量基线比对—— # 基线绿 + 现绿 → 绿 @@ -50,11 +50,11 @@ done # 控制台编码:本仓库闸件输出中文与 ✅/✗ 符号。Windows GBK 控制台下 python 打印这些字符会抛 # UnicodeEncodeError——06/10 两闸直接崩(假红)、09 的 FAIL 行被写成乱码字节(指纹漂移, -# 与基线比必判「红项清单变化」假红)、末尾汇总自身崩掉打不出结论。2026-10-16 实踩。 +# 与基线比必判「红项清单变化」假红)、末尾汇总自身崩掉打不出结论。 export PYTHONIOENCODING=utf-8 # 回执与日志是中间产物(不入库),但 .gitignore 本身必须入库——漏了就等于把它们纳入版本管理。 -# 每次跑批前自愈重建,避免「清目录重跑」把 .gitignore 一起带走(2026-10-15 实踩)。 +# 每次跑批前自愈重建,避免「清目录重跑」把 .gitignore 一起带走。 mkdir -p "$STAMP_DIR" if [ ! -f "$STAMP_DIR/.gitignore" ]; then printf '# 本目录只入库 baseline.json(存量基线,需随代码走以保证各 worktree 判定口径一致)。\n# receipt.json 是每跑批覆写的当次回执、*.log 是跑批当场日志——两者都是中间产物,不入库。\nreceipt.json\n*.log\n' \ @@ -87,8 +87,8 @@ in_domain() { # in_domain return 1 } -# ── 素材齐盘预检(2026-10-17 加)── -# game/assets/art/** 与一切 *.import 边车都不入 git(.gitignore 2026-09-29 裁定「素材不入 git」), +# ── 素材齐盘预检 ── +# game/assets/art/** 与一切 *.import 边车都不入 git(.gitignore 裁定「素材不入 git」), # 所以 git worktree 检出的工程天生缺全部美术素材:main_theme.tres 解析失败 → 按钮五个样式盒全空 # → 冒烟 V1 成片假红;渲染闸又会因素材缺位把两段 golden 直接跳过(见 render_gate.sh)。 # 缺位即拒跑——禁带着空盘跑完,把「什么都没比」的回执当全绿合回。 @@ -180,12 +180,13 @@ fi if in_domain docs; then # ── 6. 文档三闸 ── gate "06 gdd_lint" "gdd_lint.log" "$PY" "$REPO/tools/gdd_lint.py" +gate "06b 变更记录节" "changelog.log" "$PY" "$REPO/tools/gdd_lint.py" --changelog-only gate "07 doc_link" "doc_link.log" "$PY" "$REPO/tools/doc_link_audit.py" --strict gate "08 doc_term" "doc_term.log" "$PY" "$REPO/tools/doc_term_audit.py" --strict # ── 8c. 流水线闸(06 条目状态机+roadmap 迭代总表+一次交叉核,判据=doc-conventions §12)── gate "08c 流水线闸" "pipeline.log" "$PY" "$REPO/tools/pipeline_gate.py" fi -# ── 6c. 回放确定性对拍(条件闸件——迭代 29 T3 收编;属代码域)── +# ── 6c. 回放确定性对拍(条件闸件;属代码域)── if in_domain code; then # 触面判定:本批 diff 相对 master 分叉点,命中下列路径面之一即「触面」。 # 触面也**不自动跑**——对拍调的是 MC 脚本,属「MC/统计类跑批发起前须用户批准」红线管辖; @@ -310,7 +311,7 @@ for n in names: continue if c["fp"] == "skip": # 本闸这次没跑(--quick 跳过/条件闸件未触面)——没有结果可比,不判闸况变化。 - # 2026-10-17 修:此前 SKIP 落进「基线绿 → 现红」分支,任何 --quick 回执都自带假红。 + # SKIP 不得落进「基线绿 → 现红」分支——否则任何 --quick 回执都自带假红。 not_run.append(n) continue if b["exit"] != "0" and c["exit"] != "0" and b["fp"] == c["fp"]: diff --git a/tools/run_smoke.py b/tools/run_smoke.py index 6ec49cad..15a1e8e1 100644 --- a/tools/run_smoke.py +++ b/tools/run_smoke.py @@ -6,8 +6,8 @@ r"""run_smoke.py — 冒烟运行器(脚本错误外部门禁) python tools/run_smoke.py --script res://smoke/smoke_all.gd python tools/run_smoke.py --godot <引擎路径> --path <切片目录> --timeout 180 -背景(2026-09-19 台账 83 实证): GDScript 运行时脚本错误(SCRIPT ERROR)不改变进程退出码、 -不计入冒烟失败数,且会静默中断所在冒烟函数的剩余断言——首跑「309 项 0 失败」实为断言未跑全。 +背景: GDScript 运行时脚本错误(SCRIPT ERROR)不改变进程退出码、 +不计入冒烟失败数,且会静默中断所在冒烟函数的剩余断言——摘要零失败也可能断言未跑全。 进程内无脚本错误陷阱 API(GDScript 无 try/catch),故闸设在外部:本包装除退出码与摘要行外, 另扫输出中的 SCRIPT ERROR / Parse Error,命中即判失败。 diff --git a/tools/shot_checker.py b/tools/shot_checker.py index a3abd825..8a6d9542 100644 --- a/tools/shot_checker.py +++ b/tools/shot_checker.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -r"""shot_checker.py — 整屏样张闸机检(迭代 9 卡⑤/T8 2026-09-30;B 档断言骨架扩全)。 +r"""shot_checker.py — 整屏样张闸机检(B 档断言骨架扩全)。 用法: python tools/shot_checker.py <截图目录> [屏清单...] 默认屏清单 = shot_menu.png shot_camp.png shot_level.png shot_battle.png(同目录 shot_meta.json @@ -8,14 +8,13 @@ r"""shot_checker.py — 整屏样张闸机检(迭代 9 卡⑤/T8 2026-09-30; 断言(整屏样张闸 §1.4 四项的机检可判面): A 屏级骨架: PNG 存在/尺寸=工程档/灰度 std≥8/唯一色数≥64(渲染真实发生); B 文字对比度: 已知文字框〔主墨/暖白 文字簇 vs 背景簇 p2/p98 极性无关〕WCAG ≥4.5:1 - (菜单副标题/战斗 C 区面板/结算明细提示——圣经 v3.5 §7.2 全局文字硬指标机检面; - 原「菜单·帮助文」腿随载体玩法速览牌退役同撤——迭代 19 卡① S1 裁 2026-10-08); + (战斗 C 区面板/结算明细提示等已知文字框——圣经 v3.5 §7.2 全局文字硬指标机检面); C 明度三档带: 战斗屏 信息面(C 区面板均值) > 世界中(棋盘区均值) > 世界底(舞台无光柱区均值) (§2 明度分层——层间灰度可分); D 文字禁压纹理: 各文字框背景主簇纯度 ≥0.5(±12 灰度带占比——文字下垫平滑容器非 busy 纹理); F 文字在判据: 菜单文字框内与中位灰度差 >60 的像素占比在 [2%, 55%] 带内(极性无关——亮字暗底/ 暗字亮底同判;对比度只判反差不判「字在」,被埋菜单坐标处有反差即过线的缺口由本判据补, - provisional 阈值由 2026-10-15 实测定); + provisional 阈值由窗口化实测定); E 焦点预算〔首焦唯一〕: 语义面无法机检 → 编入段闸实机目检清单(T15 人闸判定)。 退出码: 0 = 全过 / 1 = 有失败。 """ @@ -82,10 +81,10 @@ def check_text_box(img: Image.Image, box: tuple, name: str, failures: list) -> N def check_text_presence(img: Image.Image, box: tuple, name: str, failures: list, lo: float = 0.02, hi: float = 0.55, dev: int = 60) -> None: - """文字在判据(迭代 28 T4——对比度只判反差不判「字在」)。 + """文字在判据——对比度只判反差不判「字在」。 框内与中位灰度差 >dev 的像素占比须落在 [lo, hi] 带内:极性无关(亮字暗底/暗字亮底同判), - 文字簇量级带(实测菜单标题 13.1%/副标题 11.5%——2026-10-15 窗口化实测定 provisional)。 + 文字簇量级带(实测菜单标题 13.1%/副标题 11.5%,provisional 定带)。 出带=疑似空框/纯色块/文字被移出框(结构性移位)。 """ if not box: @@ -161,10 +160,7 @@ def main() -> int: if "shot_menu.png" in imgs: m = imgs["shot_menu.png"] check_text_presence(m, box_of(meta, "menu_title"), "菜单·标题", failures) - # 菜单·帮助文断言腿退役(迭代 19 卡① S1 裁 2026-10-08——载体玩法速览牌 2026-10-06 用户令 - # 退役「界面禁玩法文字墙」,锚/取样键/断言段三处同撤,不重锚) - # 菜单·副标题断言腿退役(2026-10-16 用户令——副标题件整个删除〔无意义标语〕, - # meta 键/断言两腿同撤,不重锚) + # 菜单·帮助文与副标题断言腿无承载(载体件已退役,不重锚) print("[shot_checker] 焦点预算〔首焦唯一〕= 目检项(T15 段闸人闸清单判定——语义面不机检)") if failures: print("[shot_checker] FAIL——") diff --git a/tools/skill_rhythm_audit.py b/tools/skill_rhythm_audit.py index 2662c597..05b80e32 100644 --- a/tools/skill_rhythm_audit.py +++ b/tools/skill_rhythm_audit.py @@ -3,7 +3,7 @@ """技能池出招节奏审计(消费 playtest_*.jsonl 的 enemy_action 行)。 对应 06 待办「单拍行为环的体验验证(改型:技能池节奏体验验证)」的机器半边。 -判读带(2026-09-19 用户拍板): +判读带: · 过涝 = 敌群连续出特殊技、无普攻基底——读数 = 单敌群同场战斗内最长连续特殊技连击 (连击 ≥3 记过涝信号,连击阈值 3 为代拍板默认:保底 M=4 与冷却 2-4 语义下 2 连属正常波动) · 过旱 = 按战斗整体:一场战斗里所有敌人都没用过特殊技记过旱样本;任一敌人用过即正常 @@ -66,7 +66,7 @@ def main(paths): "battles": 0, "casts": 0, "specials": 0, "cast_gaps": [], "round_gaps": [], "streaks": [], }) - # 过旱/过涝判读带(用户拍板 2026-09-19)——按战斗整体计 + # 过旱/过涝判读带——按战斗整体计 drought_battles = 0 # 过旱:全战斗零特殊技(有敌行动) no_action_battles = 0 # 首轮全灭/跳战:敌从未行动(单列不混计) normal_battles = 0 diff --git a/tools/standee_asset_check.py b/tools/standee_asset_check.py index 5d7385ed..0be3626d 100644 --- a/tools/standee_asset_check.py +++ b/tools/standee_asset_check.py @@ -1,15 +1,15 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -"""站桩素材机检(B1 硬闸升级 · 立绘定档批 2026-10-07)。 +"""站桩素材机检(B1 硬闸升级)。 升级依据=art-bible §8.3③ 挂点规格(审计 §07-2/3): - - 逐键校验档高(**原「宽 1..75」虚设区间退役**——宽度改为「源宽×2 ≤ 站桩盒宽 150」 - 的物理约束,档高改为逐键断言 STANDEE_TIER_H); + - 逐键校验档高(逐键断言 STANDEE_TIER_H),宽度按「源宽×2 ≤ 站桩盒宽 150」 + 物理约束校验; - 像素域色数 ≤32(**排除全透明像素**,见下方口径注); - 无非整数倍缩放痕迹(alpha 二值 + 无中间 α); - 描边亮度达标(亮描边暖白族,character-design §10硬规则「禁黑描边」)。 -⚠ 色数口径坑(2026-10-07 实踩,勿改回naive 统计): +⚠ 色数口径坑(勿改回naive 统计): naive `len(set(所有像素))` 会把全透明 (0,0,0,0) 计成一个色 ⇒ 报33 假红灯。 正确口径 = 只统计 alpha>0 像素的唯一 RGB。机检必须如此,否则天天误报。 @@ -47,16 +47,16 @@ REQUIRED = ["character_enemy_%s.png" % k for k in ENEMY_KEYS] + \ "character_hero_hit.png"] # ── 契约常量(全部有出处,禁复写第二份) ────────────────────────────── -COLOR_MAX = 32 # 圣经 §4.1/fixer 批 32 色冻结;机检口径=alpha>0 唯一 RGB +COLOR_MAX = 32 # 圣经 §4.1/fixer 32 色冻结;机检口径=alpha>0 唯一 RGB DISPLAY_SCALE = 2 # standee_body.gd:237 _portrait_sprite.scale = (2,2) BOX_W = 150 # standee_body.gd:29 var box := Vector2(150, 176) SRC_W_MAX = BOX_W // DISPLAY_SCALE # =75,源宽上限(×2 后须塞进盒宽) ALPHA_BIN = {0, 255} # 二值 alpha 域 -# 描边亮度阈值(2026-10-07 _tmp_probe_outline.py 实测标定): +# 描边亮度阈值(实测标定): # 敌人暖白边占比实测 54.1%–84.3%,主角 portrait/hit 实测 0.4%(无暖白描边,见下)。 # 敌人闸取 40%(低于实测下限 54.1% 留余量,高于噪声);主角**豁免**—— -# character-design §10要求亮描边,但现役三态主角实为暗边,属已知缺口, -# 不在本批(美术素材批 A 范围)修,机检只报读数不判红,避免闸永久红。 +# character-design §10要求亮描边,但现役三态主角实为暗边,属已知缺口(暂无修复安排), +# 机检只报读数不判红,避免闸永久红。 OUTLINE_WARM_L_MIN = 150 # 暖白 = 亮度 ≥150 且低饱和 OUTLINE_WARM_S_MAX = 0.35 OUTLINE_MIN_ENEMY = 40.0 # 敌人:暖白描边像素占轮廓像素 ≥40% @@ -87,12 +87,12 @@ def check(path, fn): w, h = im.size px = im.load() - # 断言①逐键档高(原「高恒 48」已随定档批退役) + # 断言①逐键档高 tier = expected_tier_h(fn) if tier is not None and h != tier: problems.append("档高应 %d(§8.2 逐键定档),实得 %d" % (tier, h)) - # 断言② 宽度物理约束:源宽 ×2 须塞进站桩盒宽 150(替代旧虚设区间 1..75) + # 断言② 宽度物理约束:源宽 ×2 须塞进站桩盒宽 150 if w > SRC_W_MAX: problems.append("源宽 %d ×2=%d 超站桩盒宽 %d(§8.2 高定宽随但不得溢出盒)" % (w, w * DISPLAY_SCALE, BOX_W)) diff --git a/tools/t17_fanout2_rebuild.py b/tools/t17_fanout2_rebuild.py index b88877b3..5c2b04a6 100644 --- a/tools/t17_fanout2_rebuild.py +++ b/tools/t17_fanout2_rebuild.py @@ -1,14 +1,14 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -"""T17 出度≤2 模板池重建器(2026-10-01 用户拍板「节点出度最大为 2」——一次性内容批工具)。 +"""T17 出度≤2 模板池重建器(规则「节点出度最大为 2」——一次性内容批工具)。 -背景:现行 L2/L3 十张网状模板存在出度 3-5 的节点(2026-09-29 层宽 4-5 规则的副作用—— -无出边上限约束时「前层广连全层」是层宽加宽的几何必然)。用户 T17 目检重申「一个节点 -只有后续两个分叉」→本工具按新规则全池重生成 L2/L3 十张: +背景:网状模板若无出边上限约束,「前层广连全层」是层宽加宽的几何必然, +会出出度 3-5 的节点;规则「一个节点只有后续两个分叉」要求全池重生成。 +本工具按新规则重生成 L2/L3 十张: 新规则两条件: -① 单节点出度 ≤2(用户 2026-10-01 拍板); -② BFS 层宽上限随出度约束调整为 4(数学:入口唯一下层宽序列 ≤1,2,4——原「上限 5」与 +① 单节点出度 ≤2; +② BFS 层宽上限随出度约束调整为 4(数学:入口唯一下层宽序列 ≤1,2,4——上限 5 与 出度 ≤2 不相容:层 2 达 5 宽需前层 3 节点各出 2 边,回溯入口即违 ①)。 五张骨架(层宽序列 1-2-4-1-1 / 1-2-3-2-1 / 1-2-2-2-1——最大层宽 4 应用足): @@ -16,7 +16,7 @@ 仅重连 next。L1 五链出度恒 1 零改动。 自校验(python 侧四检):出度 ≤2 / 层宽 ≤4 / 全节点可达 Boss / 入口唯一。 -Godot 端 LevelTable.validate(含本批新增第七检出度检)为最终闸。 +Godot 端 LevelTable.validate(含第七检出度检)为最终闸。 """ import json diff --git a/tools/t3_lever_scan.py b/tools/t3_lever_scan.py index 06a7ae99..5d5bc557 100644 --- a/tools/t3_lever_scan.py +++ b/tools/t3_lever_scan.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -"""T3 杠杆网格扫描驱动(M-3 迭代 5)——临时批内工具,批末评估去留。 +"""杠杆网格扫描驱动——临时批内工具,批末评估去留。 用法:python tools/t3_lever_scan.py [--n 100] [--seed0 73000] 流程:对 worktree 数据表打补丁 → 跑 adventure_monte_carlo.gd(N/策略,unique 逐局独立种子) diff --git a/tools/t5_build_templates.py b/tools/t5_build_templates.py index 18cdfeb8..8a073bd1 100644 --- a/tools/t5_build_templates.py +++ b/tools/t5_build_templates.py @@ -1,13 +1,13 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -"""T5 骨架池生成器(M-3 迭代 5——一次性内容批工具,生成 game/data/tables/level.tres 模板池)。 +"""T5 骨架池生成器(一次性内容批工具,生成 game/data/tables/level.tres 模板池)。 -15 张骨架 = 3 关 × 5(拍板点④)。U2 目检返工(2026-09-29)两条新规则: -① L1 单链前三位纯战斗(奖励/休整禁入前三——用户目检裁决); +15 张骨架 = 3 关 × 5(拍板点④)。U2 目检两条现行规则: +① L1 单链前三位纯战斗(奖励/休整禁入前三); ② L2/L3 网状图 BFS 同深度层节点数上限 5,新池应用足宽度(每张最大层宽 ≥4——分支加宽)。 约束:战斗/Boss node_depth = 遭遇表行;图形态 id = node_depth → L2/L3 战斗 ∈ {0,1,4,5,6,7}、Boss=9; L1 图形态两不可全(Boss 须最大 id vs 深度 4)→ L1 单链排列变体(战斗深度序单调)。 -商店房每关恰 1、Boss 前必经位(L1 设计态 = 零商店——商店房批教学期修订面)。 +商店房每关恰 1、Boss 前必经位(L1 例外 = 零商店,教学期设计)。 """ L1_BATTLES = [0, 1, 2, 3] L1_BOSS = 4