merge(master): 并入锻造工坊死链修复(fbf4bd29)与迟到的 iter33 卡② 主菜单三入口化——冲突消解:体验验证清单⑯取 master 迭33 新内容+本批术语换代;待办清单两条登记并存、本批条目状态改已完成;smoke_all.gd 维持退役(git rm),iter33 卡② 对 smoke_all 的断言换代(mn1 三钮/mn8 续玩钮族退役/mn9 选档层营地路径/mn2 渲染面计数)移植进 system_test.gd 对应四函数+新增 _count_visible_buttons
This commit is contained in:
commit
3c3310ec01
61 files changed
+8362
-1649
No files matched your search
@@ -102,7 +102,7 @@
|
||||
|
||||
### 3.1 格面资源徽章 19 枚(九型 × 正负 18 枚 + 清图槽 1 枚)⚙
|
||||
|
||||
- **要什么**:九家族(增伤/减伤/回复/爆裂/削弱/穿刺/魔法/行动/金币)各正负一枚 + 清图群伤一枚。**键名录读 `reward.tres` 与地图战斗资源 GDD 九型字典,本文不抄键名**(防再腐烂——2026-09-22 勘误先例:gp 组键名 gp_coin/gp_lose 以配置为准)。
|
||||
- **要什么**:九家族(增伤/减伤/回复/爆裂/削弱/穿刺/魔法/行动/GP)各正负一枚 + 清图群伤一枚。**键名录读 `reward.tres` 与地图战斗资源 GDD 九型字典,本文不抄键名**(防再腐烂——2026-09-22 勘误先例:gp 组键名 gp_coin/gp_lose 以配置为准)。
|
||||
- **风格/规格**:图标键契约 art-bible §4.6(冻结);**极性视觉 = 金族满框(正向)/ 红族缺框(负向)**,不新增语义色;徽章=附属小图标,非完整凸形(不构成第二焦点),栈位在旗之下、变异纹理之上;负向九枚 weight=0 纯字典,用于踩雷反噬结算呈现。
|
||||
- **来源**:⚙ 脚本管线(键契约件,程序化最稳);通用图标包只作造型参考,不直接入包。
|
||||
- **现状**:程序化占位徽标(文本/符号),够试玩不够观感。
|
||||
@@ -128,10 +128,11 @@
|
||||
- **风格/规格**:♻ 素材站复用优先——通用增益/减益图标包改色为墨族,按 §4.6.1 极性列统一叠极性视觉(有利=金族满框/有害=红族缺框,art-bible §4.6 通道分配全键族通用),过复用闸四道(灰度可辨=色弱冗余通道);⚙ 兜底程序化。一键一纹样、映射按 effect_id 全局恒定禁换图(图标键契约)。
|
||||
- **现状**:已接入(2026-09-24,定稿九枚入 HUD 状态槽,合并 71ae51c;色板量化豁免=用户逐键验收的自产件,非外采)。
|
||||
|
||||
### 3.5 营地与元进度件(2026-09-23 新登记,此前清单漏登记)
|
||||
### 3.5 营地场景图(2026-10-22 重写;原「营地与元进度件·三柜台」条目作废)
|
||||
|
||||
- **要什么**:钥石顶栏图标、永久强化条目图标(营地三柜台货架件)、柜台场景贴图(属性锻造/秘宝匣/奖励格图鉴)。
|
||||
- **来源/规格**:图标类 ♻ 通用钥匙/强化图标改色过闸;柜台场景贴图 ♻ 木石材质件拼装或 ✦ 插画级(烛光黄 `#F6C667` + 木色 `#8A5A34`,art-bible §4.4);排期归 UI 贴图重构批(营地现为程序化占位,状态记录 121⑧ 口径)。
|
||||
- **要什么**:营地场景图 9 张——`scene_camp_bg`(背景)+ `scene_camp_gate / forge / chest / notebook / dummy / board / campfire`(七个可点物件)+ `scene_camp_bed`(承载件)。钥石顶栏图标沿用现役 `icon_keystone`。
|
||||
- **来源/规格**:**✦ 插画级**(作者自跑远程生图管线);烛光黄 `#F6C667` + 木色 `#8A5A34`(art-bible §6.2);2× 源档出图、最近邻降采样到 1280×800;后处理=抠底/降采样/色板量化/描边统一。**每张出图须登记模型名+分辨率+seed+对话/日期**。
|
||||
- **排期**:营地交互重做**美术自立批**(不占迭代位;UI 贴图重构批已搁置)。终稿落 `game/assets/art/scene/`,消费常量 `UiKit.TEX_CAMP_*`。
|
||||
- **现状**:全占位。
|
||||
|
||||
### 3.6 字体(数字像素字 + 中文像素字)(2026-09-23 新登记,此前清单漏登记)
|
||||
@@ -172,7 +173,7 @@
|
||||
└─> 敌人卡形态裁决 ✅已完成(2026-09-20 拍板全站桩,卡片式退役)
|
||||
徽章(3.1)/节点图(3.2)/效果图标(3.4) —— 独立线,可随时插队
|
||||
♻ 复用件(3.2/3.4/3.5/3.6/演出粒子) —— 不依赖样张,可随时插队(入包闸 = §0 复用四道)
|
||||
字体(3.6)接入归表现批;营地件(3.5)归 UI 贴图重构批
|
||||
字体(3.6)接入归表现批;营地场景图(3.5)归营地交互重做美术自立批
|
||||
分辨率档位 ✅已定案(1280×800 + 1920×1080,2026-09-22 用户确认);art-bible §8 资产规范 ✅已成文(2026-09-23)——像素基准/画布/命名/帧数候选值就位,终值归样张批冻结
|
||||
```
|
||||
|
||||
|
||||
+15
-10
@@ -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.17,历次修订明细见 git 提交史
|
||||
> 项目: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.18,历次修订明细见 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 头身
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
> 本节服从第 1 节宣言「明快的地牢,轻快的扫荡,仔细的推理」。能量值为全作统一 0–10 刻度:0 静谧 → 10 沸腾。
|
||||
>
|
||||
> **明度分层(硬规则,2026-09-29 v3.0 替代「明度恒定」)**:明度按视觉层分带——**信息面层**(数字/UI 数据/预告/语义标识)最高、**世界中层**(格底顶面/角色/物件)居中、**世界底层**(背景/纵深/远景/已开空间)可更低;层间明度差服务空间纵深与光照(Moonlighter 式洞穴层次)。**禁令保留**:明度变化仍禁止用于**状态表达与情绪表达**——状态区分只允许**色相、饱和、运动、元素**四手段;roguelike 失败重开,世界无光暗记忆;Darkest Dungeon 式压暗仍在 §9.2 反面清单。**允许域**:空间纵深、光照氛围、形体塑造(砖缘立体面既有例外上升为通则)。类型微光的明度梯度(§4.2)属信息面层内梯度,不扰世界层明度档。
|
||||
> **明度分层(硬规则,2026-09-29 v3.0 替代「明度恒定」)**:明度按视觉层分带——**信息面层**(数字/UI 数据/预告/语义标识)最高、**世界中层**(格底顶面/角色/物件)居中、**世界底层**(背景/纵深/远景/已开空间)可更低;层间明度差服务空间纵深与光照(Moonlighter 式洞穴层次)。**禁令保留(2026-10-22 缩窄至情绪域)**:明度变化禁止用于**情绪表达**——画面不得靠压暗/渐晕阴沉下来;roguelike 失败重开,世界无光暗记忆;Darkest Dungeon 式压暗仍在 §9.2 反面清单。**状态表达不受本禁令约束**:状态可用明度、色相、饱和、运动、元素任一手段承载。roguelike 失败重开,世界无光暗记忆;Darkest Dungeon 式压暗仍在 §9.2 反面清单。**允许域**:空间纵深、光照氛围、形体塑造(砖缘立体面既有例外上升为通则)。类型微光的明度梯度(§4.2)属信息面层内梯度,不扰世界层明度档。
|
||||
|
||||
### 2.1 挖掘阶段(核心状态,占时最长)
|
||||
|
||||
@@ -135,7 +135,7 @@
|
||||
- **色彩性格**:全作最暖:烛光黄与木色,中等饱和,无棋盘式高对比
|
||||
- **氛围形容词**:温暖、笃实、归属
|
||||
- **能量**:3/10
|
||||
- **承载元素**:营地三柜台(属性锻造/秘宝匣/奖励格图鉴)在烛光下一字排开——场景构成、柜台亮光与钥石呈现位连同系统语义边界一并见 §6.2
|
||||
- **承载元素**:**一张可点击的营地场景图**——远景天空与远山,中景围栏与半开的营地大门,近景中央的篝火,左侧锻炉铁砧,右侧床铺与宝箱、床边的笔记本,另有木桩与挂在围栏上的布告板;点画面里的物件进入对应界面(冒险/锻造工坊/秘宝匣/生涯记录/天赋树/图鉴/离开营地)。钥石余额常驻画面顶部的一行小 HUD 栏。场景构成、七物件绑定与呈现位见 §6.2
|
||||
|
||||
### 状态间区分度自检
|
||||
|
||||
@@ -193,7 +193,7 @@
|
||||
- **数字墨双色制(2026-09-29 v3.0)**|1–8 **不做八色分色**,按密度分三档色温(冷=稀疏,暖=密集);**字形为唯一数值载体**,色温只作密度氛围。①**棋盘数字呈现=按板自适应三态**(2026-10-01 v3.4 修订——v3.3 深墨族方案经渲染帧取证证伪:underdark 系地板近黑斑与近白筋并存〔双峰纹理〕,深墨直画融黑斑同样隐形,任何墨族直画不可救):暗纹理板(dungeon 系)=**亮族**三档 1–3 冷亮青白 #D8ECF0/4–5 暖白 #F0E2C8/6–8 金亮 #F8E3A8 直画(样张 v3 冻结原样;判据=族最弱成员对 p90 ≥4.5:1 且对均值 ≥2.5:1);双峰纹理板(underdark/deep_underdark 系)=**色牌垫底**(素牌 DIGIT_PLATE + 深墨 #33261B 12:1,纹理免疫——v2 色牌形制在双峰板复役;判据=亮深两族皆不过门,深族均值门 3.0)。选模式管线落码单点 `board_view._digit_ink_mode`(三态:亮直/深直/落牌),机检面=`terrain_tile_sets_test` 三关呈现模式断言;**目视验证面=board_shot_probe 渲染帧取证**(机检≠看得清,2026-10-01 用户教训);缺盘平色回退态(#B39A78 中明度底)默认深墨直画;②**垫牌与 UI 数据墨=深墨族 `#33261B` 系**(L≤0.027 不变,§7.2)。八色必与红金蓝紫赤语义冲突,故弃。←原一/原二;P3
|
||||
- **封印黑 `#000000`**|封印(插旗)宣告色,无色相:玩家的宣告"此格封印"(色史:旗朱 `#C63D22` →封印紫 `#7C3AA8` 2026-09-26→**封印黑 2026-09-28 用户拍板**——紫色与微光蓝族〔魔法微光 256° 等〕色相冲突,黑色无色相天然避开 300°–345° 禁入带与全部微光色带;未开格墙顶明度 ≈113 对纯黑对比 ≥4.4:1,旗杆米白保可读)。旗朱随封印紫批退役〔棋盘侧〕,红族棋盘侧自此只剩危险红(2026-09-28 起人设背包旗=旗朱红矩形旗——旗色脱钩拍板,人设侧详见 character-design 背包旗条)。←原一;P2;封印紫批 2026-09-26;封印黑批 2026-09-28
|
||||
- **危险红 `#A8321F`**|危险色:雷=被惊动的巢穴,兑现档红,更深更沉(色值不变)。←原三;P2
|
||||
- **奖励金 `#F0A828`**|已兑现的收益:金币/宝箱/蜡封,全作唯一亮金。←P2;§2.3/2.4
|
||||
- **奖励金 `#F0A828`**|已兑现的收益:GP/宝箱/蜡封,全作唯一亮金。←P2;§2.3/2.4
|
||||
- **小人蓝 `#2E86DE`**|小人主色:棋盘唯一"己方",与光标准线同族(样张 v2 定稿 2026-09-28)。←P1;§2.1
|
||||
- **数字色牌 `#F5EAD3`**|数字底具,2026-09-29 v3.0 降级为**后备手段**:素色暖纸白直角小牌,仅复杂格底(物件纹样/变异纹带/微光叠加致直画对比不足)垫于数字正下方;素面无纹理、不随图类型/装饰变体变。←原二
|
||||
- **收益金亮档 `#E0B860`(GOLD_BRIGHT)**|UI 徽标可读性亮档 token(2026-10-14 迭代 26 反哺③登记转正):敌顺位徽标①②③与重甲徽标对舞台底 6.47:1(旧 GOLD_DEEP 3.26:1 越 §7.2 带);金族亮档,与奖励金 #F0A828 同族不同岗——奖励金=已兑现收益语义(§4.2 金条),本 token 只承载徽标可读性、不占收益语义。语义岗冲撞已裁:GOLD_DEEP/HERO_BLUE 常量本尊不动(standee 意图判据等语义岗在役)
|
||||
@@ -204,9 +204,11 @@
|
||||
|
||||
**色板增量纪律(2026-10-06 P2 对账批新增;数值状态 = **待定现用**)**:全作色板硬上限 **48 色**(现行 ≈45,余量 3——2026-10-14 迭代 26 新入 GOLD_BRIGHT/HERO_BLUE_BRIGHT/SLOT_BACKDROP_SOFT 三枚 UI 亮档/柔和档 token,均已过 §4.2 语义检查〔不占语义色段〕与 RGB 三通道差 ≥8/255 两道门;审计"色板逼近失控线"的封口条款);新色入板须同时过两道门:①§4.2 语义检查(不占语义色段/禁入带);②**与既有任一色的 RGB 三通道差 ≥8/255**——反例即审计实证:#3A2E22 ↔ #362B20 三通道差均 <5,肉眼不可辨,同板共存只增噪。不过门即触发「换色合并」(把意图色并进最近既有色),**禁加色绕行**;加色义务顺带登记于本表修订。**「待定现用」态释义(2026-10-06 用户立第三态)**:数值**现行即执法**(色板检查器按此拦,§8.3)——非候选(不存在"等冻结"空窗)、非死规(后续需求引入时可变);调整走本节修订并登记,改值 = 修订不是违约。
|
||||
|
||||
- **色板分层(2026-10-22 作者裁)**:色板分两层管理——① **语义/UI token 板**:全作共享,硬上限 **48 色**,管 UI 语义色、墨色、材质色,跨屏恒定;② **场景环境子板**:**每屏一套,≤32 色,允许跨屏不共享**(环境色=天空、地面、植被、石材、火焰等随场景走的颜色)。新增环境色仍须过两道门(§4.2 语义检查 + 与既有任一色 RGB 三通道差 ≥8/255),但**不占用 48 token 额度**;不过门照旧走「换色合并」,**禁加色绕行**。单张 PNG 的像素域色数上限 **≤32 色**另由 `standee_asset_check` 执法(像素域口径,与本表 token 口径互不干扰)。额度不足时呈报作者,由作者决定压缩或合并既有色。
|
||||
|
||||
### 4.2 语义色彩规则
|
||||
|
||||
> **适用域(2026-09-29 v3.0 立)**:本节「X 只说 Y」约束**信息层**(格内信息/UI 数据/预告/语义标识)与**语义物件**(金币=收益金、血条=危险红等);**纯环境氛围**(背景/装饰变体/远景/非语义物件)不受色相独占约束,改受 §3.4 焦点预算与低饱和后退约束(不抢读即可用色)。禁入带 300°–345°:信息层与语义物件禁入不变;环境层可入但限低饱和(高饱和紫赤仍 Boss 独占,§2.6)。
|
||||
> **适用域(2026-09-29 v3.0 立)**:本节「X 只说 Y」约束**信息层**(格内信息/UI 数据/预告/语义标识)与**语义物件**(GP=收益金、血条=危险红等);**纯环境氛围**(背景/装饰变体/远景/非语义物件)不受色相独占约束,改受 §3.4 焦点预算与低饱和后退约束(不抢读即可用色)。禁入带 300°–345°:信息层与语义物件禁入不变;环境层可入但限低饱和(高饱和紫赤仍 Boss 独占,§2.6)。
|
||||
|
||||
- **红只说危险**:危险红=兑现档(旗朱预告档随封印紫批退役,红族单档)。禁(信息层域):红禁止用于奖励、装饰性标识与常规 UI(微光群伤组除外——见「类型微光色带」条,其色相刻意错开语义红)。←原三;P2;§2.1;封印紫批 2026-09-26
|
||||
- **金只说收益与兑现**(奖励、结算、胜利)。禁(信息层与语义物件域):金禁止作危险障碍色、不上格底、不作日常 UI 强调(防通胀;微光通用增益组的芥末黄属「类型微光色带」条色带,非收益语义金)。←P2;P3;§2.2–2.4
|
||||
@@ -364,8 +366,11 @@
|
||||
### 6.2 营地场景
|
||||
|
||||
- **情绪与色域**:承载 §2.8——全作最暖:烛光黄 `#F6C667` × 木色 `#8A5A34`(§7.2),中等饱和,无棋盘式高对比。
|
||||
- **场景构成**:营地三柜台(属性锻造/秘宝匣/奖励格图鉴)在烛光下一字排开,钥石余额常驻顶栏;柜台 = 石板圆角容器(§7.1)+ 木石材质贴图;每购得一件永久强化,对应柜台亮起一格暖光——亮起只走饱和/色相手段,不动明度(§2)。
|
||||
- **事实源边界**:柜台与钥石的系统语义(解锁条件/价格/存档写入)归元进度 GDD 与 `MetaProgression`,本节只定画法;贴图与图标资产归清单 §3.5;现行以程序化占位承载(占位完成条款见 §7.1)。
|
||||
- **场景构成**:一张可点击的营地场景图(1280×800,与工程档同幅面)。远景=天空与远山;中景=木围栏与**半开的营地大门**(门洞内一条通向远处的小路);近景=中央篝火、左侧锻炉铁砧、右侧床铺与宝箱、床边的笔记本,另有木桩与挂在围栏上的布告板。七个可点物件的功能绑定归 `camp.md`,本节只定画法。
|
||||
- **交付形态**:**背景 1 层 + 七个物件各 1 层**(床铺为承载件、不可点),共 8 张透明 PNG + 一份坐标表(贴图矩形/命中矩形/z 序)。**篝火例外**:命中矩形只取下半(火堆),上半(火焰)只作特效展示。
|
||||
- **交互四态(零新素材,全部程序化)**:悬停=**轮廓亮边 + 浮动**(浮动须整像素吸附);按下=位移 1px;**禁用/未解锁=降明度 + 去饱和**(§2 已缩窄至情绪域,状态表达不受限),**仅锻炉(锻造工坊)与宝箱(秘宝匣)两件会有此态**;已解锁=常态。
|
||||
- **钥石余额**:常驻画面顶部的一行小 HUD 栏(高 48px,**浮层覆盖,不挤压画面**)。
|
||||
- **事实源边界**:解锁条件/价格/存档写入归元进度 GDD 与 `MetaProgression`;素材命名与路径归 `asset-path-map`;清单登记归 `art-assets-checklist` §3.5。
|
||||
|
||||
### 6.3 三关图类型色板候选(board_type 换挡方向)
|
||||
|
||||
@@ -428,12 +433,12 @@
|
||||
- **字体**:全局一套像素字——拉丁候选 Kenney Fonts(CC0)、中文候选缝合像素字体 Fusion Pixel(OFL)(清单 §3.6);墨色走主墨系(§7.2);换字体 = 全局决策。
|
||||
- **字号**:像素字体**整数倍缩放,禁非整数缩放**(像素模糊);下限(1280×800 基座;2026-09-29 v3.0 对齐 ux-designer PC 规范):棋盘数字 ≥18px(公式 = max(18, ceil(格边长 × 0.5))不变)、**正文/明细 ≥16px、tooltip ≥14px**(旧 14/13px 下限退役——1280×800 低于 1080p 基准,同字号实际更小)。
|
||||
- **字号档位表(2026-10-06 UI 设计对齐批 P3 甲——WB G1 六档)**:全站 UI 文字字号只经 `UiKit.FS_*` 单点取值,裸数字字号退役——`FS_CAPTION 12`/`FS_HINT 14`/`FS_BODY 16`/`FS_SUB 18`/`FS_TITLE 24`/`FS_H1 34`。旧 15 实测档按就近归档收编(10/11/12→CAPTION、13/14→HINT、15/16→BODY、17/18/20→SUB、21/22/24/26→TITLE、32/40→H1;T0 普查 107 静态位点全归档,数据驱动动态字号位点除外);棋盘数字公式 `maxi(18, ceil(格边长×0.5))` 与站桩血数 11px(条带内读数豁免)不入表。注:六档相邻比 12→14→16→18 三段 <1.25×,系 P3 裁决值优先于字重纪律的档差参考线,档差参考线对新层级设计仍有效。
|
||||
- **小字号豁免条款(2026-10-06 UI 设计对齐批 P11+Q5 甲,合并单条不开两口子)**:下款两类**豁免于本节下限**——①**条带内读数**:压在窄条带(血条/进度条等 ≤12px 高带)内居中的数字,受条带高度物理约束,维持 11px 下限,且必须按 §7.2 垫素色牌后计对比(实装=B 区站桩血数 11px 压 HP_BAR_BACK 牌 14.3:1);②**装饰性 overline/caption**:不承载须精确读取的信息、仅作分区标题或氛围小字者,可至 **12px**。**两类豁免逐处清单(2026-10-06 T6 判定落定)**:条带内读数=B 区站桩血数一处;装饰 caption 档(FS_CAPTION)在册面=主菜单分组 overline×2(「── 冒 险 ──」「── 营地与系统 ──」)/棋盘底操作提示条/营地柜台说明文与结构位预留注记/图例 RAP 词条说明/设置警示文两处/关卡地图底栏组标(生命/属性/特性)与分隔系/站桩消散提示/B 区状态槽微计数(×N●○)/bcard 脚注/RAP 反馈行/刷新余量徽标——清单外 11-13px 文字一律按正文/tooltip 下限提档,新增 caption 位须同批增补本清单。
|
||||
- **小字号豁免条款(2026-10-06 UI 设计对齐批 P11+Q5 甲,合并单条不开两口子)**:下款两类**豁免于本节下限**——①**条带内读数**:压在窄条带(血条/进度条等 ≤12px 高带)内居中的数字,受条带高度物理约束,维持 11px 下限,且必须按 §7.2 垫素色牌后计对比(实装=B 区站桩血数 11px 压 HP_BAR_BACK 牌 14.3:1);②**装饰性 overline/caption**:不承载须精确读取的信息、仅作分区标题或氛围小字者,可至 **12px**。**豁免逐处清单(2026-10-06 T6 判定落定,2026-10-22 随迭代 33 卡② 主菜单三入口化撤除「主菜单分组 overline×2」两处——组帽随旧钮组退役,余清单不动)**:条带内读数=B 区站桩血数一处;装饰 caption 档(FS_CAPTION)在册面=棋盘底操作提示条/营地柜台说明文与结构位预留注记/图例 RAP 词条说明/设置警示文两处/关卡地图底栏组标(生命/属性/特性)与分隔系/站桩消散提示/B 区状态槽微计数(×N●○)/bcard 脚注/RAP 反馈行/刷新余量徽标——清单外 11-13px 文字一律按正文/tooltip 下限提档,新增 caption 位须同批增补本清单。
|
||||
- **字重纪律(2026-09-29 v3.0 修订)**:层级手段解禁为三件——**字号档差(相邻层级 ≥1.25×)+ 墨色深浅 +(字体支持时)字重两档**;数字禁描边/阴影伪加粗不变(字形为唯一数值载体,§4.1 同源纪律)。
|
||||
|
||||
### 7.5 营地界面
|
||||
|
||||
- 三柜台界面画法 = §6.2 场景构成 + §7.2 最暖色域;柜台货架件 = 永久强化条目图标 + 价格(图标归清单 §3.5);钥石余额常驻顶栏(呈现位与系统语义边界见 §6.2);界面视觉终稿以表现层样张过审为前置(§1.4 整屏样张闸),现行以程序化占位承载(占位完成条款见 §7.1)。
|
||||
- 营地界面=**一张可点击的场景图 + 七物件点选**:点画面里的物件进入对应界面(冒险/锻造工坊/秘宝匣/生涯记录/天赋树/图鉴/离开营地)。场景图的画法、分层与四态见 §6.2;色域走 §7.2 最暖一档;钥石余额常驻顶部一行小 HUD 栏。界面视觉终稿以表现层样张过审为前置(§1.4 整屏样张闸)。
|
||||
|
||||
### 7.6 引擎原生控件与按钮状态规格(2026-10-14 迭代 25/26 反哺写入——原无条款,两批实现=临时权威,本批按呈报转正)
|
||||
|
||||
@@ -444,7 +449,7 @@
|
||||
- **五态齐全**:全站按钮(普通/主/危险三厂)必须五态非空——常态 / 悬停 / 按下 / 禁用 / 键盘焦点;任一态缺档即违本条(旧态:悬停填常态图=无反馈、禁用错配按压图、焦点全站空白)。
|
||||
- **悬停 = 常态图 + modulate 提亮**(乙案):提亮档 `Color(1.06,1.06,1.06)`,零素材;主钮承 `CANDLE.lightened(0.06)` 同纪律。
|
||||
- **按下 = 本族下沉**:石纹钮 `button_stone_pressed` 九宫格;危险钮补本族 pressed 深档(深红 `darkened(0.18)`——旧承石纹按压图错配退役)。
|
||||
- **禁用 = 本族底 + α0.45 幽灵化**(甲案):flat 两厂 bg+border 同 α 全幽灵化,取代旧「disabled=按压图」错配;文字禁用色同档。
|
||||
- **禁用 = 本族底 + α0.45 幽灵化**(甲案):flat 两厂 bg+border 同 α 全幽灵化,取代旧「disabled=按压图」错配;文字禁用色同档。 (注:本条管 **UI 按钮**;营地场景图里的**物件**禁用态另按 §6.2——降明度 + 去饱和,不走 α 幽灵化。)
|
||||
- **键盘焦点 = INK 2px 内缩 1px 环**(甲案):负 expand margin 实现内缩;引擎 focus 样式盒叠加绘制、不遮钮底(「三类钮底可辨性实比」设计语言成立);逐实例 override、**主题层零新增词条**(冒烟双红线在闸)。
|
||||
- 新增按钮位须同批过五态清单;验收 = §1.4 样张 + 冒烟五态断言。
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
| 关卡节点图图标组 | ◐ | [art-assets-checklist](art-assets-checklist.md) §3.2(正式 UI 设计未成文) |
|
||||
| 雷/封印印记/数字砖面全套 | ◐ | [art-bible](art-bible.md) §1.4/§3.2(前置:格子样张) |
|
||||
| 增益状态效果图标 9 枚 | ✅ 已接入(2026-09-24 状态记录 156) | [art-bible](art-bible.md) §4.6.1(候选原稿:状态图标批 2026-09-23 远程出图,归 candidates 档——路径描述性引用,归档纪律见 art-bible §8.3) |
|
||||
| 营地与元进度件 | ◐ | [art-bible](art-bible.md) §4.4 |
|
||||
| 营地场景图 | ◐ | [art-bible](art-bible.md) §6.2 |
|
||||
| 字体(数字像素字 + 中文像素字) | ◐ | [art-bible](art-bible.md) §4.4 |
|
||||
|
||||
## P3 演出类(样张后排期)
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|---|---|---|
|
||||
| `character/` | 角色棋盘帧 + B 区立绘 | character_hero_idle/walk(棋盘 32×32 朝左基准)、character_hero_portrait(B 区立绘 46×48)+ character_enemy_<键> 八敌 |
|
||||
| `fx/` | 特效帧 | shovel_swing_f0/f1/f2(挥铲三帧,握把锚 (18,12)) |
|
||||
| `scene/` | **场景图**(背景层 + 可点物件层;2026-10-22 新增,营地场景图首批) | `scene_camp_bg`(背景)+ `scene_camp_gate / forge / chest / notebook / dummy / board / campfire`(七个可点物件)+ `scene_camp_bed`(承载件,不可点) |
|
||||
| `board/` | 砖面/封印印记(三关换皮 + 封印印记件;2026-10-06 对账更正——旧 `board_floor/wall/pillar_dungeon_*` 命名退役) | terrain_floor_<board_type>_<n>.png(三关地面系)、seal_mark.png |
|
||||
|
||||
## 4. 坐标/朝向等工程侧约定备查
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
| 爆破工兵包 | 行动点 + 探巢的稀有秘宝 | aux_items |
|
||||
| 地精 / 熊地精 / 食人魔酋长 | 首发三敌种(末者为 Boss) | enemy |
|
||||
| 第一层 · 地精洞窟 | 首关层名 | level_table |
|
||||
| 封印 | 正式动作名(全库统一,非比喻、非呈现层别名)——对未开格(巢穴)实施封印,印记=封印印记 | terminology |
|
||||
| 封印 | 正式动作名(全库统一,非比喻、非呈现层别名)——对未开格实施封印,印记=封印印记 | terminology |
|
||||
|
||||
注意:上表六件秘宝为旧目录,已全数退役、只作素材库(新现行事实源=[秘宝](systems/跨局循环/秘宝.md)「目录(重设计 v1)」节——新目录 15 件为代号制、正式命名归用户);新目录正式命名定稿后本表同步。
|
||||
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
每场战斗都在一张雷图上打。战斗本身不用手操——你能做的全部决策,都在它的"准备期"里:
|
||||
|
||||
1. 开局一张新雷图,每轮发给你行动点,每轮预算见[行动经济](systems/排雷循环/行动经济.md)。
|
||||
2. 用行动点做排雷决策:挖开安全格,拿增益和道具;控制(封印)巢穴,削弱里面的怪物;点错惊动巢穴,怪物反而变强。
|
||||
3. 行动点用尽——或者你主动停手——这一轮结束,轮末自动结算:你这一轮扫雷攒下的因,逐行兑现成战斗的果。你拿的增益打了出去,你控制的巢穴变成怪物的虚弱,你惊动的巢穴变成怪物的警觉(护甲变硬、伤害数值轮末才落)。
|
||||
2. 用行动点做排雷决策:挖开安全格,拿增益和道具;控制(封印)危险格,削弱里面的怪物;点错惊动危险格,怪物反而变强。
|
||||
3. 行动点用尽——或者你主动停手——这一轮结束,轮末自动结算:你这一轮扫雷攒下的因,逐行兑现成战斗的果。你拿的增益打了出去,你控制的危险格变成怪物的虚弱,你惊动的危险格变成怪物的警觉(护甲变硬、伤害数值轮末才落)。
|
||||
4. 敌人没死光、你还活着,就进下一轮,同一张图接着挖;图开完了,发清图奖励,换一张新图接着打。
|
||||
|
||||
```
|
||||
开局:装一张新雷图 + 发本轮行动点
|
||||
→ 用行动点做排雷决策(挖安全格拿增益/道具 · 封印控制巢穴 · 点错惊动巢穴)
|
||||
→ 用行动点做排雷决策(挖安全格拿增益/道具 · 封印控制危险格 · 点错惊动危险格)
|
||||
→ 行动点用尽 或 主动停手 → 轮末自动结算:本轮攒的因逐行兑现成战斗的果
|
||||
→ 判定(先判你,再判敌人)
|
||||
你倒下 → 战斗失败 → 冒险结束(见「死了之后」)
|
||||
@@ -76,7 +76,7 @@
|
||||
存档级(钥石·永久强化)
|
||||
└ 冒险级(秘宝生效期·奇物·生命·GP·刷新存量——均为系统资源)
|
||||
└ 关卡级(预留档——现役零成员,保留扩展位)
|
||||
└ 节点级(敌方生命·增益容器·蓄力层·商店付费刷新计数)
|
||||
└ 节点级(敌方生命·状态池·蓄力层·商店付费刷新计数)
|
||||
└ 回合级(当前 AP 池·结算动作时点)
|
||||
```
|
||||
|
||||
@@ -85,10 +85,10 @@
|
||||
| 存档级 | 跨多个冒险,最大生命周期 | 元进度(钥石/永久强化)、同调位数量、秘宝工坊解锁 |
|
||||
| 冒险级 | 一段冒险(一轮闯关) | 秘宝生效期、奇物、生命、GP、刷新存量(均为系统资源) |
|
||||
| 关卡级 | 一关之内 | **预留档,现役零成员**(保留扩展位——「每关首次」类口径的归宿) |
|
||||
| 节点级 | 一次停点(进入→离开,不按节点类型分档) | 敌方生命、增益状态容器、蓄力层、商店付费刷新计数(每停点清零) |
|
||||
| 节点级 | 一次停点(进入→离开,不按节点类型分档) | 敌方生命、状态池、蓄力层、商店付费刷新计数(每停点清零) |
|
||||
| 回合级 | 一轮之内 | 当前 AP 池(每轮灌满、归零收轮)、结算动作发生的时点 |
|
||||
|
||||
节点级前提:节点链是有向无环图(DAG)——只向前走、无回头路、无环,节点只进一次,故「一次停点」=「这个节点的寿命」(参照哈迪斯/以撒的房间:多数房间有战斗,少数没有)。回合级**不存在跨轮效果**:跨轮的都是写入战斗级对象的一次性结算——增益活在增益状态容器(容器寿命=一场战斗=节点级),duration 是增益自身的属性;下轮 AP 写入战斗级 AP 队列([行动经济](systems/排雷循环/行动经济.md))。
|
||||
节点级前提:节点链是有向无环图(DAG)——只向前走、无回头路、无环,节点只进一次,故「一次停点」=「这个节点的寿命」(参照哈迪斯/以撒的房间:多数房间有战斗,少数没有)。回合级**不存在跨轮效果**:跨轮的都是写入战斗级对象的一次性结算——增益活在状态池(寿命=一场战斗=节点级),duration 是增益自身的属性;下轮 AP 写入战斗级 AP 队列([行动经济](systems/排雷循环/行动经济.md))。
|
||||
|
||||
### 结算模型:一次性结算与持续态
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
|
||||
每笔系统资源带两个坐标:**寿命档**(见上五档轴)与**形态**(见上总线/抽屉)。它们之间不设统一换算、也不立统一上位概念——**GP 与钥石是两条平行独立的系统资源**,按寿命档各归各档文档:GP 归[冒险结构](systems/冒险循环/冒险结构.md)「GP」节,钥石归[元进度](systems/跨局循环/元进度.md),行动点两笔归[行动经济](systems/排雷循环/行动经济.md),刷新两笔归[秘宝](systems/跨局循环/秘宝.md)。
|
||||
|
||||
增益容器(战斗内状态实例,寿命=一场战斗)**不是**系统资源,归[增益状态](systems/战斗循环/增益状态.md)。
|
||||
状态池(战斗内状态实例,寿命=一场战斗)**不是**系统资源,归[增益状态](systems/战斗循环/增益状态.md)。
|
||||
|
||||
旧称「账/账本」「独立资源」「系统数值」一律不再使用;其他文档引用本概念只写规范名「系统资源」加链接指回本节,禁止复述成员清单与寿命口径。
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
|
||||
- 行动点两笔(上限=冒险级属性/当前=回合级池):[行动经济](systems/排雷循环/行动经济.md)「每轮预算与价目」节
|
||||
- 刷新两笔(存量 Y/当次临时 X,X 挂「三选一呈现」):[秘宝](systems/跨局循环/秘宝.md)「三选一刷新双源」节
|
||||
- 增益容器(寿命=一场战斗,不属系统资源):[增益状态](systems/战斗循环/增益状态.md)
|
||||
- 状态池(寿命=一场战斗,不属系统资源):[增益状态](systems/战斗循环/增益状态.md)
|
||||
|
||||
## 道具三层职责与分界
|
||||
|
||||
@@ -153,7 +153,7 @@
|
||||
|
||||
| 层 | 档位语义 | 落地口 |
|
||||
|---|---|---|
|
||||
| 秘宝 | 档位越高,解锁条件越苛刻(通关数/Boss 击杀/生涯里程碑谓词);装配面同调位分档(槽位可装 ≤ 槽位档位的件,向下兼容) | `unlock_requires` 字段 + 工坊柜台 + 里程碑分档发槽 |
|
||||
| 秘宝 | 档位越高,解锁条件越苛刻(通关数/Boss 击杀/生涯里程碑谓词);装配面同调位分档(槽位可装 ≤ 槽位档位的件,向下兼容) | `unlock_requires` 字段 + 锻造工坊界面 + 里程碑分档发槽 |
|
||||
| 奇物 | 档位越高,出现概率越低(配额与权重) | 令牌池配额;专长 rarity 接 Boss 三选一按档配比/加权(约束见下) |
|
||||
| 地图战斗资源 | 档位=概率位 + 保底上限(T1-T4 四档池) | [地图战斗资源](systems/战斗循环/地图战斗资源.md)「四档概率结构与保底」节 |
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|---|---|---|
|
||||
| `战斗结算.md` | 轮末结算的编排与逐行兑现 | 已定稿·自旧体系迁移 |
|
||||
| `敌人系统.md` | 敌人数据、技能池出招、意图呈现 | 已定稿·自旧体系迁移 |
|
||||
| `增益状态.md` | 增益/减益状态的容器、叠层与衰减 | 已定稿·自旧体系迁移 |
|
||||
| `增益状态.md` | 增益/减益的状态池、叠层与衰减 | 已定稿·自旧体系迁移 |
|
||||
| `地图战斗资源.md` | 格面资源的产出、极性字典与清图奖励封装 | 已定稿·自旧体系迁移 |
|
||||
| `战斗表现.md` | 战斗动画与演出(旧体系未单独成文) | 范围草案·待设计 |
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
| `level-map.md` | 关卡画面 UX spec:选路枢纽独立屏三停点布局、GP 常驻徽章、底栏状态栏 | 定稿版·独立屏+视觉终稿已冻结 |
|
||||
| `node-reward.md` | 节点奖励屏 UX spec:奖励节点提升三选一选择面、六种令牌池与刷新双源(与商店货架同库;通关三选一候选=纯专长,见 level-clear) | v2.5·令牌池在役 |
|
||||
| `settlement-summary.md` | 结算总结 UX spec:战斗总结结算(战斗胜利面)与冒险总结结算(冒险终结面)——两面分节的纯呈现轻量 spec | v1.2·纯呈现已实装面成文 |
|
||||
| `camp.md` | 营地覆盖层 UX spec:三柜台呈现、钥石余额、退役/封存件状态语义(存档级/局外呈现面) | v1.1 |
|
||||
| `camp.md` | 营地场景 UX spec:可点击场景图与七物件点选、钥石余额、各功能界面入口(存档级/局外呈现面) | v1.1 |
|
||||
| `shop.md` | 商店覆盖层 UX spec:令牌级货架(与三选一同池)、GP 余额与付费刷新、购买/离开(中循环节点兑付呈现面) | v1.1 |
|
||||
|
||||
## 子系统命名对照表(中文规范名 ↔ 英文代号)
|
||||
|
||||
@@ -56,7 +56,7 @@ MVP 不加新状态;扩容走 `status_effects.tres` 加行 + [增益状态](sy
|
||||
|
||||
**一套元进度配置**(`data/tables/meta.tres`,现行行数读表为准):属性锻造商品三行(生命上限 / 基础攻击 / 护甲等级的 flat 档与几何定价参数)、Boss 钥石两档三行(首杀 / 重复杀)、秘宝匣阈值六行、区间平移换算率三行(数值占位 0 = 未标定合法态)。
|
||||
|
||||
数值全部 provisional(骨架先行、数值后置)——机制归[元进度](systems/跨局循环/元进度.md),数值标定随元进度设计批配读数。扩柜台或改定价结构走 `meta.tres` 加行 + [元进度](systems/跨局循环/元进度.md)补行。
|
||||
数值全部 provisional(骨架先行、数值后置)——机制归[元进度](systems/跨局循环/元进度.md),数值标定随元进度设计批配读数。扩锻造路线或改定价结构走 `meta.tres` 加行 + [元进度](systems/跨局循环/元进度.md)补行。
|
||||
|
||||
## 暂不做 / 后续再说
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
- **多波战斗**:Peglin 对比报告(2026-09-12)裁下的后置项。单场多波是战斗编排级的改动,波间状态保留规则也要重新定义,排 Alpha 期评估。
|
||||
- **遗物 / 构筑协同**:同批裁下。先做协同设计再谈加密度,没有协同的纯堆量只会稀释每件道具的存在感。
|
||||
- **战后回复**:同批裁下。要做得绑定敌方攻击力下调,单独加回复会直接破坏现有数值预期。
|
||||
- **元进度(钥石解锁 / 跨局成长)**:排 Alpha,首批已落地(营地三柜台 / 钥石 / 跨局注入)。铺量与标定仍是之后的事。
|
||||
- **元进度(钥石解锁 / 跨局成长)**:排 Alpha,首批已落地(营地 / 钥石 / 跨局注入)。铺量与标定仍是之后的事。
|
||||
- **反雪球机制**:MVP 不做。等 Alpha 拿到真实测试数据,再决定要不要治滚雪球、怎么治。
|
||||
- **正式音频、教学引导、战斗动画演出、设置与本地化**:MVP 内的打磨项,一律排后。先验证核心循环,再谈好听好看。
|
||||
- **连刷 / 换图资金跨战斗携带**:现行规则是每场战斗清零,防滚雪球。是否解禁连刷策略,等实测数据说话。
|
||||
+12
-11
@@ -2,7 +2,7 @@
|
||||
|
||||
> **一句话定位**:本文定义这个项目的 **Alpha 版本包含哪些东西**——它是里程碑 M3 的完成标准,也是判断"还差什么"的对照表。
|
||||
> **本文只列条目,不写内容**:每样东西是什么、规则怎么走,一律归各自的权威文档,本文只给指路链接。想知道某样东西的定义,请点链接,不要在本文里找解释。
|
||||
> **状态**:**已定稿(v1.12)**——2026-10-13 用户令定稿,此后十二次升版的明细见 git 提交史。Alpha 的内容范围自此冻结:增删条目一律须经用户裁决。
|
||||
> **状态**:**已定稿(v1.14)**——2026-10-13 用户令定稿,历次升版明细见 git 提交史。Alpha 的内容范围自此冻结:增删条目一律须经用户裁决。
|
||||
> **成文**:2026-10-13。
|
||||
|
||||
## 本文怎么用
|
||||
@@ -46,9 +46,9 @@ Alpha 内以玩法循环本身的内容与表现为主(棋盘、关卡、战
|
||||
| 条目 | 事实源 | 现状 |
|
||||
|---|---|---|
|
||||
| 冒险结构 | [冒险结构](systems/冒险循环/冒险结构.md) | 在役 |
|
||||
| 关卡节点地图 | [关卡节点地图](systems/冒险循环/关卡节点地图.md) | 在役(待重构,见下一条) |
|
||||
| 关卡节点图重构(增加可选节点) | [关卡节点地图](systems/冒险循环/关卡节点地图.md)+[关卡节点图生成](systems/冒险循环/关卡节点图生成.md) | 待做(文档设计已闭合,待写卡;单独成批,2 周时间盒;优先全量 v2.0,第一周结束若多终点与地图屏明显超载则分两步:先三关基础分叉+单终点可玩;出口判据见两份文档的验收标准,另加旧模板清理与真人目检选路有取舍) |
|
||||
| 关卡节点图生成 | 参数化长图:产出规格与生成参数 | 待做(规格 v1.0 已定稿;生成器实现与上一条同一批) |
|
||||
| 关卡节点地图 | [关卡节点地图](systems/冒险循环/关卡节点地图.md) | 在役(待重构,见下一条;信息迷雾类型可见性已随迭代 34 卡④ 实装,2026-10-22) |
|
||||
| 关卡节点图重构(增加可选节点) | [关卡节点地图](systems/冒险循环/关卡节点地图.md)+[关卡节点图生成](systems/冒险循环/关卡节点图生成.md) | 待做(文档设计已闭合;四张需求卡片已写——卡③敌人表深度带换代、卡④信息迷雾可见性已随迭代 34 合回(2026-10-22),卡①生成器核心、卡②消费侧换代已编迭代 35、待开工;出口判据见两份文档的验收标准,另加旧模板清理与真人目检选路有取舍) |
|
||||
| 关卡节点图生成 | [关卡节点图生成](systems/冒险循环/关卡节点图生成.md)(参数化长图:产出规格与生成参数) | 待做(规格 v1.1 已定稿;生成器核心批已写卡、已编迭代 35,待开工) |
|
||||
| 难度曲线与 Boss | [难度曲线与Boss](systems/冒险循环/难度曲线与Boss.md) | 在役 |
|
||||
| 奇物 | [奇物](systems/冒险循环/奇物.md) | 在役 |
|
||||
|
||||
@@ -92,7 +92,7 @@ Alpha 内以玩法循环本身的内容与表现为主(棋盘、关卡、战
|
||||
| 元进度配置 | `meta.tres` | 在役 |
|
||||
| 天赋树节点集 | `meta_tree.tres` | 在役 |
|
||||
| 锻造工坊路线行族 | `forge.tres` | 在役(定价 provisional 归 M4;表名订正与入库依据见 git 提交史) |
|
||||
| 混编遭遇行集 | `enemy.tres` | 在役(首批;第二批移挂 Beta,裁决与明细见 git 提交史) |
|
||||
| 混编遭遇行集 | `enemy.tres` | 在役(首批;第二批移挂 Beta,裁决与明细见 git 提交史;2026-10-22 迭代 34 起按〔关卡,行类,深度带〕三参寻址,行集键已迁移) |
|
||||
|
||||
---
|
||||
|
||||
@@ -100,10 +100,11 @@ Alpha 内以玩法循环本身的内容与表现为主(棋盘、关卡、战
|
||||
|
||||
| 条目 | 事实源 | 现状 |
|
||||
|---|---|---|
|
||||
| 主菜单 | —— | 在役 |
|
||||
| 主菜单 | —— | 在役(迭代 33 卡②三入口化:进入存档/设置/退出游戏——入口拓扑=进入存档→选档界面→进档/新档→营地覆盖层→〔营地交互重做卡④〕营地场景图与生涯笔记本;2026-10-22 用户裁换代〔反哺 #13〕) |
|
||||
| 开始覆盖层 | —— | 在役 |
|
||||
| 营地(天赋树 / 锻造工坊 / 秘宝匣 / 图鉴) | [camp](ux/camp.md) | 在役(锻造柜台占位面板注已解除;柜台贴图占位随营地交互重做列入 Alpha,见下行) |
|
||||
| 营地交互重做(五卡:存档制数据层/主菜单三入口/选档界面/营地场景图/Esc 浮窗与营地顶栏) | [camp](ux/camp.md)+[需求澄清](../../reports/需求澄清-营地交互重做-2026-10-18.md) | 待做(2026-10-21 用户裁:五卡整体列入 Alpha,含营地表现优化——可点击场景图/顶栏/Esc 浮窗。五卡已写、待编排;卡④营地场景图为最大件,挂三个用户侧前置未销号:美术渠道 A/B、点选反馈设计稿、参照物。出口=五卡各自验收标准通过+营地屏用户目检通过) |
|
||||
| 选档界面(3 存档位) | —— | 在役(迭代 33 卡③——空槽新档/有档进档/删档二次确认+摘要三项;2026-10-22 用户裁增行〔反哺 #8〕) |
|
||||
| 营地(天赋树 / 锻造工坊 / 秘宝匣 / 图鉴) | [camp](ux/camp.md) | 在役(场景图与七物件点选随营地交互重做列入 Alpha,见下行) |
|
||||
| 营地交互重做(五卡:存档制数据层/主菜单三入口/选档界面/营地场景图/Esc 浮窗与营地顶栏) | [camp](ux/camp.md)+[需求澄清](../../reports/需求澄清-营地交互重做-2026-10-18.md) | 部分在役(卡①②③ 已随迭代 33 实装合回,2026-10-22;卡④营地场景图 2026-10-21 用户令退回美术设计段,美术生成方案提案 2026-10-22 成文,余三个用户侧前置未销号:像素规格执行(Q6 甲过渡口径已裁)、点选反馈设计稿、参照物;卡⑤ Esc 浮窗随卡④ 代码波同行、未编排。2026-10-21 用户裁:五卡整体列入 Alpha。出口=五卡各自验收标准通过+营地屏用户目检通过) |
|
||||
| 生涯页 | [生涯](systems/跨局循环/生涯.md) | 在役(期一) |
|
||||
| 关卡地图屏 | [level-map](ux/level-map.md) | 在役 |
|
||||
| 战斗屏 | [battle](ux/battle.md) | 在役 |
|
||||
@@ -134,7 +135,7 @@ Alpha 内以玩法循环本身的内容与表现为主(棋盘、关卡、战
|
||||
| 机器可读的呈现断言(对比度 / 结构) | `game/tests/` | 在役 |
|
||||
| 分辨率两档(1280×800 / 1920×1080) | [HUD框架](systems/表现与支撑/HUD框架.md) | 在役 |
|
||||
| 绘制调用数达标 | —— | 在役 |
|
||||
| 真人试玩轮次 | [体验验证清单](../../体验验证清单.md) | 在役(义务维持;当前轮次未清) |
|
||||
| 真人试玩轮次 | [体验验证清单](../../体验验证清单.md) | 在役(义务维持;当前轮次未清:㉚/㉛ 未核销,迭代 34 三条目检项待登记) |
|
||||
|
||||
---
|
||||
|
||||
@@ -145,7 +146,7 @@ Alpha 内以玩法循环本身的内容与表现为主(棋盘、关卡、战
|
||||
| 像素美术风格与色板 | [美术圣经](../art/art-bible.md) | 在役 |
|
||||
| 棋盘瓦片与格面资源图标 | [美术圣经](../art/art-bible.md) | 在役 |
|
||||
| 未开格类型微光(五组色相+明度档) | [HUD框架](systems/表现与支撑/HUD框架.md) | 在役(明度档 provisional 值登记见 art-bible 的 git 提交史,复核转正归战斗一屏样张) |
|
||||
| 棋盘观感(第二 / 三关亮度与对比度) | [待办清单](../../待办清单.md) | 待做(先做素材轴/UI 轴对照截图定性,再按定轴修复;出口=用户实机目检第二、三关不再判「看着费劲」) |
|
||||
| 棋盘观感(第二 / 三关亮度与对比度) | [待办清单](../../待办清单.md) | 待做(开工前置=先做素材轴/UI 轴对照截图定性,再按定轴修复;旧卡 v1.4 存 reports/ 作素材、非已写卡状态,重启须重新立卡;出口=用户实机目检第二、三关不再判「看着费劲」) |
|
||||
| 立绘清晰度回退评估(是否改用高清图) | [角色设计](../art/character-design.md) | 待做(评估已结——2026-10-14 用户裁维持像素风、升级精细手绘像素、不回退高清图,裁决录=[美术审计-cursor会话存档](../../reports/美术审计-cursor会话存档-2026-10-14.md) §2.2;Alpha 范围=主角+三个 Boss 按新口径重产,其余敌种当前可读则保留到 Beta;出口=用户目检八敌体量关系通过且主角与三个 Boss 重产完成) |
|
||||
| 敌人立绘(全敌种) | [角色设计](../art/character-design.md) | 在役 |
|
||||
| 主角立绘三态 | [角色设计](../art/character-design.md) | 在役 |
|
||||
@@ -196,7 +197,7 @@ Alpha 内以玩法循环本身的内容与表现为主(棋盘、关卡、战
|
||||
| 第四关 | 排 Beta;全库无设计承载,N>3 走扩展批流程([03-内容规模](03-内容规模.md)) |
|
||||
| 生涯期二(历史冒险回看)与期三(图鉴) | 排 Beta;Alpha 只保留期一([生涯](systems/跨局循环/生涯.md)) |
|
||||
| 素材升档重产 | 排 Beta;原始动机已由八敌逐键定档解决,剩余提灯候选随 Beta 资产批重议([待办清单](../../待办清单.md)) |
|
||||
| 元进度件贴图终稿 | 排 Beta;元进度图标在 Alpha 保留占位,不碍在役判定([美术资产清单](../art/art-assets-checklist.md))——营地柜台贴图已随营地交互重做列入 Alpha(见「三 · 界面」表) |
|
||||
| 元进度件贴图终稿 | 排 Beta;元进度图标在 Alpha 保留占位,不碍在役判定([美术资产清单](../art/art-assets-checklist.md))——营地场景图已随营地交互重做列入 Alpha(见「三 · 界面」表) |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
>
|
||||
> 它是一个概念,不是一套东西。下面有**两根互不相干的轴**:
|
||||
>
|
||||
> - **分类轴**回答"给的是什么"——三个枚举:专长 / 属性值提升 / 资源;
|
||||
> - **分类轴**回答"给的是什么"——三个枚举:专长 / 属性值提升 / 补给;
|
||||
> - **渠道轴**回答"从哪来"——奖励节点 / 商店 / 关底 Boss 击败(即通过这一关)。
|
||||
>
|
||||
> 一个奇物属于哪个分类,不决定它从哪个渠道来;反过来也一样。两者的交叉由第 2 节那张开关表定死。
|
||||
@@ -116,7 +116,7 @@
|
||||
|
||||
老 27 件已全数退役,名单见[道具退役素材库](../../../content-archive/道具退役素材库.md)表二;`feats.tres` 在役行随重设计实装批删除替换。任何一件要进新体系须重新过准入校验、分界尺与定义卡三关,不默认继承。
|
||||
|
||||
## 资源(重设计·基础框架 v1)
|
||||
## 补给(重设计·基础框架 v1)
|
||||
|
||||
> 本节是补给分类的现行事实源。补给成员 = **转换源**:不是系统资源本身,是「到手即结算成一笔系统数值的凭证」——凭证加完消尽,被写入的系统资源各有自己的寿命档位(五档轴见[核心循环](../../01-核心循环.md)「生命周期轴」节)。判据句与归类方法见 §1.3/§1.4。**新凭证已随迭代 20 专长实装批落表(2026-10-11);2026-10-18 用户裁削两件后,现行成员=新 3+留任 2(同调电池删除、完美保险归专长——见 git 提交史 v3.18)。**
|
||||
|
||||
@@ -174,8 +174,8 @@
|
||||
|
||||
关内普通战斗节点 ──▶ 打完不给奇物,继续往下走
|
||||
│
|
||||
├─ 奖励节点 ──▶ 一次三选一(属性值提升 / 资源,专长凭证)
|
||||
├─ 商店 ──▶ 花钱买(属性值提升 / 资源,专长凭证)
|
||||
├─ 奖励节点 ──▶ 一次三选一(属性值提升 / 补给,专长凭证)
|
||||
├─ 商店 ──▶ 花钱买(属性值提升 / 补给,专长凭证)
|
||||
│
|
||||
关底 Boss 击败 ═══╗ ← 打掉关底 Boss 就是「通过这一关」,同一件事
|
||||
╰──────────╬──▶ 一次专长三选一(专长)
|
||||
@@ -222,9 +222,9 @@
|
||||
|
||||
#### 1.3 补给:转换源
|
||||
|
||||
资源这一类装的是"不抬高战斗属性、也不改规则,但让你更有余地"的东西。成员现行事实源=本文件「资源(重设计·基础框架 v1)」节的**凭证件表(新 3+留任 2)**;旧枚举四项的去向:行动点上限归属性值提升轴(见 1.2)、刷新次数由刷新券替代、GP 与回复留任为小 GP 袋/应急口粮。
|
||||
补给这一类装的是"不抬高战斗属性、也不改规则,但让你更有余地"的东西。成员现行事实源=本文件「补给(重设计·基础框架 v1)」节的**凭证件表(新 3+留任 2)**;旧枚举四项的去向:行动点上限归属性值提升轴(见 1.2)、刷新次数由刷新券替代、GP 与回复留任为小 GP 袋/应急口粮。
|
||||
|
||||
**资源为什么单独成一类**:它的成员不满足"抬高战斗属性"(那归属性值提升),也不满足"改写规则"(那归专长),但玩家拿到时的感受是一致的——"我能做的事变多了"。把它们跟属性提升混在一起,会让"加了多少攻击"这种可度量的提升和"多一次重抽"这种不可度量的余地摆在同一张候选卡上,玩家没法比。即时兑付的 GP 与回复同留本类、不独立成第四类(2026-10-05 用户定)——判据与资源完全同源,拆出去只会让读者多查一张表。
|
||||
**补给为什么单独成一类**:它的成员不满足"抬高战斗属性"(那归属性值提升),也不满足"改写规则"(那归专长),但玩家拿到时的感受是一致的——"我能做的事变多了"。把它们跟属性提升混在一起,会让"加了多少攻击"这种可度量的提升和"多一次重抽"这种不可度量的余地摆在同一张候选卡上,玩家没法比。即时兑付的 GP 与回复同留本类、不独立成第四类(2026-10-05 用户定)——判据与补给完全同源,拆出去只会让读者多查一张表。
|
||||
|
||||
**判据句**:补给成员是**转换源**——不是系统资源本身,而是「到手即结算成一笔系统数值的**凭证**」,凭证加完消尽;被写入的系统资源(GP 钱包/刷新存量/储备池/时沙暂记)各有自己的寿命档位。拿不准一项该归哪类时问三句:它进不进角色自己的属性数值(进→属性值提升);它改不改规则(改→专长);都不是、而是给某一笔系统资源做一次性加仓的,归补给。
|
||||
|
||||
@@ -253,7 +253,7 @@
|
||||
| 层 | 名称 | 例子 | 谁看得到 |
|
||||
|---|---|---|---|
|
||||
| 一层 总称 | **奇物**(Wondrous Item) | 「这一局你捞到的全部奇物」 | 全部玩家可见面 |
|
||||
| 二层 分类 | **专长** / **属性值提升** / **资源** | 「这四件是属性值提升」 | 帮百科与成就页可见;卡面与详情页**不出现** |
|
||||
| 二层 分类 | **专长** / **属性值提升** / **补给** | 「这四件是属性值提升」 | 帮百科与成就页可见;卡面与详情页**不出现** |
|
||||
| 三层 单件 | 具体那一件的名称 | 双管镐、疼痛记忆、生命上限 +1 | 全部玩家可见面 |
|
||||
|
||||
**两层是两件事,别混**:
|
||||
@@ -368,7 +368,7 @@
|
||||
|---|---|---|
|
||||
| GP 不进商店 | 二层·可计算条件 | 计价物不自售——商店的计价物是 GP |
|
||||
| 专长在非 Boss 渠道只给凭证 | 一层·分类自身的形态 | 见 2.2——防止用钱定点买构筑 |
|
||||
| 属性值提升与资源不出现在 Boss 渠道 | **不是约束** | 见 2.1——这是渠道轴的定位(Boss 是专长独占渠道),不属默认原则管辖 |
|
||||
| 属性值提升与补给不出现在 Boss 渠道 | **不是约束** | 见 2.1——这是渠道轴的定位(Boss 是专长独占渠道),不属默认原则管辖 |
|
||||
|
||||
#### 2.5 在册事项
|
||||
|
||||
@@ -379,7 +379,7 @@
|
||||
### 3. 作用对象与范围
|
||||
|
||||
- **作用对象**:角色本人,以及角色参与的结算过程。奇物不改敌人、不改棋盘生成、不改关卡内容。
|
||||
- **刷新券的例外**:凭证不进持有集——到手即结算进刷新存量账(冒险级)、加完消尽。它作用在三选一界面上,改的是"这一局里你能重抽几次",而不是角色身上的任何数字。它是资源里唯一一条作用对象不是角色的项——留在这里是因为它满足另外两条:当局获得、当局有效。
|
||||
- **刷新券的例外**:凭证不进持有集——到手即结算进刷新存量账(冒险级)、加完消尽。它作用在三选一界面上,改的是"这一局里你能重抽几次",而不是角色身上的任何数字。它是补给里唯一一条作用对象不是角色的项——留在这里是因为它满足另外两条:当局获得、当局有效。
|
||||
- **时间范围**:整局冒险。专长与属性值提升自获得起对本局剩余所有关卡生效,跨关携带且关间不清零;即时兑付凭证(小 GP 袋 / 应急口粮)拿到即结算消尽。
|
||||
- **归属范围**:不进账号永久进度,不带到下一次冒险。
|
||||
|
||||
@@ -393,7 +393,7 @@
|
||||
|
||||
| 阶段 | 说明 |
|
||||
|---|---|
|
||||
| 候选池构建 | 冒险开局时一次建成。三个分类的候选**现同处一个令牌池**:属性值提升与资源按配额铺开,专长按定义表的有效行铺开。 |
|
||||
| 候选池构建 | 冒险开局时一次建成。三个分类的候选**现同处一个令牌池**:属性值提升与补给按配额铺开,专长按定义表的有效行铺开。 |
|
||||
| 出现 | 玩家在渠道上看到 3 个候选(三选一的形式),看不到整个池。 |
|
||||
| 选定 | 玩家选定一项后消耗该成员的一张令牌(拿了才计、只刷出〔含刷新重展〕不计);该成员令牌耗尽后不再出现于任何渠道。选到「专长获取」时,立刻再开一次专长 N 选一——这次选择走专长的渠道语义,不占用原本的渠道。 |
|
||||
| 持有与兑付 | 专长与属性值提升进入持有集后立即生效,跨关携带。凭证即时结算入各自的账,不入持有集。 |
|
||||
@@ -417,7 +417,7 @@
|
||||
| 类型 | 内容 |
|
||||
|---|---|
|
||||
| 依赖(概念) | 角色、结算管线、行动点、地形、关卡节点地图、局内 GP 钱包、三选一界面 |
|
||||
| 依赖(数据) | `feats.tres`(专长定义行)、`adventure.tres`(属性值提升与资源的种类配额与值)、`shop.tres`(货架取舍) |
|
||||
| 依赖(数据) | `feats.tres`(专长定义行)、`adventure.tres`(属性值提升与补给的种类配额与值)、`shop.tres`(货架取舍) |
|
||||
| 输出(对外) | 持有集、生效中的分类投影、剩余候选池、可用重抽次数 |
|
||||
| 明确边界 | 不写账号进度、不改敌人与关卡内容、不承载具体数值 |
|
||||
|
||||
@@ -436,7 +436,7 @@
|
||||
| 专长定义行(标识 / 显示名 / 稀有度 / 效果说明 / 订阅行〔订阅哪个事件 on / 什么条件 when / 什么效果 do〕) | 各字段封闭枚举,行键白名单封闭;事件 / 效果类型 / 条件事实 / 算子四词表封闭(效果引擎单一事实源);稀有度档=新四级(普通/优秀/稀有/传说),schema 字段双脱钩(字段在、设计面按档配比加权) | `game/data/tables/feats.tres` |
|
||||
| 专长凭证(出现概率 / 配额 / 限购次数 / 保底计数阈值) | 整数,四参数全 provisional | 已入表(迭代15② 凭证行——`shop.tres` + `adventure_table.gd`) |
|
||||
| 属性值提升种类 | 封闭三项:生命上限 / AC / 攻击,扩项走文档修订 | `game/data/schemas/adventure_table.gd` |
|
||||
| 资源种类 | 种类现行事实源=「凭证件表(新 3+留任 2)」节;凭证已入表(迭代15②) | 同上 |
|
||||
| 补给种类 | 种类现行事实源=「凭证件表(新 3+留任 2)」节;凭证已入表(迭代15②) | 同上 |
|
||||
| 稀有度档位 | 封闭四级(普通 / 优秀 / 稀有 / 传说);配额是结构锚,改总量须重新拍板而非调参 | 同上 |
|
||||
| 各分类种类 × 档位的配额与值 | 整数 | `game/data/tables/adventure.tres` |
|
||||
| 专长获取的全局限量 | 整数(一局内可获得的次数上限) | 同上 |
|
||||
@@ -449,7 +449,7 @@
|
||||
3. 一个成员被拿走后消耗其一张令牌;令牌数=该成员出现次数上限,拿了才计、只刷出(含刷新重展)不计;令牌耗尽后该成员不再出现。
|
||||
4. 专长件的收益必须挂在声明的条件上——把 when 去掉后收益仍然成立的无条件数值件不是专长,归属性值提升。
|
||||
5. 玩家可见的文案不出现分类名与内部分组标签——只写效果,归类让玩家自己推断。
|
||||
6. 文档与代码里提到它时只有"奇物"这一个名字;需要区分时用"专长/属性值提升/资源"描述,禁止另造称呼。
|
||||
6. 文档与代码里提到它时只有"奇物"这一个名字;需要区分时用"专长/属性值提升/补给"描述,禁止另造称呼。
|
||||
7. 刷新凭证不进角色加算区、不进持有集——刷新券到手即结算进刷新存量账,只改三选一界面的可用重抽次数。
|
||||
8. 即时兑付凭证(小 GP 袋/应急口粮)不进持有集——到手即结算消尽。
|
||||
9. GP 不出现在商店货架上——这是「计价物不自售」可计算条件自动判定的结果,不是给 GP 单独立的一个分类;它确实是在分类白名单之外加的一道过滤,只是这道过滤可自动计算而非靠枚举。
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
|
||||
### 负向恒即时:惩罚没有库存语义
|
||||
|
||||
负向兑付的账户动作全部在授予段受理,不入库、不出窗口——惩罚不设库存、不留存量;其中**伤害形态(群伤/直伤类负向行)的扣血落地殿后到战斗段末**(2026-10-06 用户裁,单据暂存,见[战斗结算](战斗结算.md));主角在敌方还手中倒下则地图伤害账整体不兑(逐单留「未生效」行)。正向里的 percent 类(增益行)进[增益状态](增益状态.md)的容器;heal 正向当场结算;gp 正负两向(GP 袋 / 破财)当场执行——记入战斗内 GP 缓冲,战斗完成随 gp_dropped 与钱包结算(账本归[冒险结构](../冒险循环/冒险结构.md)),同样无库存语义。叠层饱和由战斗结算既有池 clamp 承载;blast 负向(警觉)与 action 负向(迟滞)直授无上限。
|
||||
负向兑付的账户动作全部在授予段受理,不入库、不出窗口——惩罚不设库存、不留存量;其中**伤害形态(群伤/直伤类负向行)的扣血落地殿后到战斗段末**(2026-10-06 用户裁,单据暂存,见[战斗结算](战斗结算.md));主角在敌方还手中倒下则地图伤害账整体不兑(逐单留「未生效」行)。正向里的 percent 类(增益行)进[增益状态](增益状态.md)的状态池;heal 正向当场结算;gp 正负两向(GP 袋 / 破财)当场执行——记入战斗内 GP 缓冲,战斗完成随 gp_dropped 与钱包结算(账本归[冒险结构](../冒险循环/冒险结构.md)),同样无库存语义。叠层饱和由战斗结算既有池 clamp 承载;blast 负向(警觉)与 action 负向(迟滞)直授无上限。
|
||||
|
||||
举证:本节为兑付语义,无计算。
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
# 增益状态
|
||||
|
||||
> 一句话:增益/减益状态的容器、叠层与衰减
|
||||
> 一句话:增益/减益的状态池、叠层与衰减
|
||||
> 状态:已定稿(自旧体系迁移)
|
||||
|
||||
## 设计目的
|
||||
|
||||
战斗里有一类效果不在当场一次性用掉,而要管上几次结算:挖开安全格拿到的主角增益、封印标中带来的怪物削弱、踩雷喂给怪物的增强(警觉——blast 型负向)、标错封印招来的负向兑付,都是这类。本文把它们统称"状态":发给主角的有益效果叫增益(失衡与乏力是例外——它们是发给主角的减益),发给敌人的负面效果叫减益;敌方侧的增强同样是状态——几个方向共用一本账。
|
||||
战斗里有一类效果不在当场一次性用掉,而要管上几次结算:挖开安全格拿到的主角增益、封印标中带来的怪物削弱、踩雷喂给怪物的增强(警觉——blast 型负向)、标错封印招来的负向兑付,都是这类。本文把它们统称"状态":发给主角的有益效果叫增益(失衡与乏力是例外——它们是发给主角的减益),发给敌人的负面效果叫减益;敌方侧的增强同样是状态——几个方向共用同一个状态池。
|
||||
|
||||
增益状态就是这本账:一个容器收下全部状态,用同一套规矩管理——发入、合并(同一种效果重复拿到时按表行策略处理:叠层加一,或只刷新剩余次数——读 `status_effects.tres` 逐行 stack_policy)、衰减(每次结算后剩余次数减一,减到零效果消失)、清空(战斗结束全部清除)。没有它,几类效果得各写一套计时逻辑,结算明细也无法逐行指回"这效果是我哪步棋带来的"。容器管机制、不管数值从哪来:某个效果该多大,由各收益系统的表去定,容器只照章入账、按次衰减。
|
||||
增益状态就是这一个状态池:它收下全部状态,用同一套规矩管理——发入、合并(同一种效果重复拿到时按表行策略处理:叠层加一,或只刷新剩余次数——读 `status_effects.tres` 逐行 stack_policy)、衰减(每次结算后剩余次数减一,减到零效果消失)、清空(战斗结束全部清除)。没有它,几类效果得各写一套计时逻辑,结算明细也无法逐行指回"这效果是我哪步棋带来的"。状态池管机制、不管数值从哪来:某个效果该多大,由各收益系统的表去定,状态池只照章入列、按次衰减。
|
||||
|
||||
## 系统范围
|
||||
|
||||
边界这样划:容器只管"效果存进来之后"的一生——受理、存续、倒数、清空。效果"该不该发、发几次"由战斗结算在轮末兑现时裁决,容器只记账;"发进来之后在伤害公式里怎么用"是战斗结算的消费侧规则;"画成什么样"归呈现层。
|
||||
边界这样划:状态池只管"效果存进来之后"的一生——受理、存续、倒数、清空。效果"该不该发、发几次"由战斗结算在轮末兑现时裁决,状态池只登记;"发进来之后在伤害公式里怎么用"是战斗结算的消费侧规则;"画成什么样"归呈现层。
|
||||
|
||||
负责:
|
||||
|
||||
@@ -37,28 +37,28 @@
|
||||
扫雷阶段:挖格 / 封印 / 踩雷 ──(事实流)──▶ 战斗结算(轮末逐行兑现)──(授予 / 查询兑付 / 衰减)──▶ 增益状态 ──▶ 效果落进结算公式
|
||||
```
|
||||
|
||||
增益状态站在轮末结算这一段,是战斗结算身后的状态仓库:扫雷攒下的因里,凡是"要管上几次结算"的那部分都存在它这里。扫雷事实不直接进容器——战斗结算每轮把事实兑换成状态发入,兑付时再来读生效清单。
|
||||
增益状态站在轮末结算这一段,是战斗结算身后的状态仓库:扫雷攒下的因里,凡是"要管上几次结算"的那部分都存在它这里。扫雷事实不直接进状态池——战斗结算每轮把事实兑换成状态发入,兑付时再来读生效清单。
|
||||
|
||||
## 核心规则
|
||||
|
||||
### 一个容器管全部方向:增益减益同账本
|
||||
### 一个状态池管全部方向
|
||||
|
||||
主角的增益与减益、敌方的削弱与增强——各个方向的效果在容器里是同一种东西,都叫状态实例(容器里的一份效果,带层数与剩余次数),走同一套受理、合并、倒数、清除的语义。踩雷的惩罚与封印标中的收益共用同一本账,玩家能在同一种读法下看到雷的两面:一边喂强敌人,一边拆它的皮。
|
||||
主角的增益与减益、敌方的削弱与增强——各个方向的效果在状态池里是同一种东西,都叫状态实例(状态池里的一份效果,带层数与剩余次数),走同一套受理、合并、倒数、清除的语义。踩雷的惩罚与封印标中的收益共用同一个状态池,玩家能在同一种读法下看到雷的两面:一边喂强敌人,一边拆它的皮。
|
||||
|
||||
容器四条硬规矩:
|
||||
状态池四条硬规矩:
|
||||
|
||||
| 规矩 | 含义 |
|
||||
|---|---|
|
||||
| 寿命 = 一场战斗 | 战斗开始时容器为空,结束全部清空,不跨到下一场战斗 |
|
||||
| 寿命 = 一场战斗 | 战斗开始时状态池为空,结束全部清空,不跨到下一场战斗 |
|
||||
| 跨轮跨图延续 | 同一场战斗里换新雷图、弃图刷新都不清空——状态跟着战斗走,不跟图走 |
|
||||
| 全程零随机 | 授予、合并、衰减、列举顺序全部确定,可回放 |
|
||||
| 敌方侧共享 | 对敌效果一律对全体存活敌人生效,层数全体共享一份(单体寻址是后置扩展位) |
|
||||
|
||||
举证:本节为容器结构规则,无计算。
|
||||
举证:本节为状态池结构规则,无计算。
|
||||
|
||||
### 授予只在结算时发生:事实换状态的唯一入口
|
||||
|
||||
状态只在轮末结算时发入容器。挖掘期的挖格、封印、踩雷都不直接改容器——棋盘只上报"发生了什么"的事实,战斗结算在每轮结算时把事实统一兑换成状态发进来。这个授予入口是唯一的:棋盘和奖励背包都没有直通通道。
|
||||
状态只在轮末结算时发入状态池。挖掘期的挖格、封印、踩雷都不直接改状态池——棋盘只上报"发生了什么"的事实,战斗结算在每轮结算时把事实统一兑换成状态发进来。这个授予入口是唯一的:棋盘和奖励背包都没有直通通道。
|
||||
|
||||
每笔状态随身携带归因记录:来源类别五选一、来自哪个格子、发生在第几轮。结算明细因此能逐行回答"这效果是我哪步棋带来的"。
|
||||
|
||||
@@ -70,15 +70,15 @@
|
||||
| 清图奖励 | 清图奖励槽含增益时 | 随行定,路径归[地图战斗资源](地图战斗资源.md)定稿 |
|
||||
| 标空封印 | 轮末封印判定标空(标了但格不是雷) | 该安全格格面资源的负向兑付(极性矩阵"标错"分支——2026-09-15 起不再三选一);载体裁决归[战斗结算](战斗结算.md) |
|
||||
|
||||
容器是只记账、不裁决的仓库:上游叫它施加几次,它就入账几次。同一笔事实被重复转化两次,就入两层——它不去重、不合并事实,"事实到授予恰好一次"由战斗结算保证。同轮多笔授予按调用方给定的次序先后入列,容器保证入账顺序稳定可读。
|
||||
状态池是只登记、不裁决的仓库:上游叫它施加几次,它就登记几次。同一笔事实被重复转化两次,就入两层——它不去重、不合并事实,"事实到授予恰好一次"由战斗结算保证。同轮多笔授予按调用方给定的次序先后入列,状态池保证入列顺序稳定可读。
|
||||
|
||||
状态一经发入立即生效,没有"待生效"中间态——授予它的那轮结算就是它的第一次兑付。
|
||||
|
||||
举证:本节为授予路径与记账规则,无计算。
|
||||
举证:本节为授予路径与登记规则,无计算。
|
||||
|
||||
### 同名状态再拿到:叠层、刷新、并存
|
||||
|
||||
同一种状态还没消失又拿到一份,怎么合并由状态表每行的合并策略字段说了算,共三种。合并在授予那一刻由容器完成;多个状态在结算里按什么先后起作用,是战斗结算的编排——两件事互不干扰。
|
||||
同一种状态还没消失又拿到一份,怎么合并由状态表每行的合并策略字段说了算,共三种。合并在授予那一刻由状态池完成;多个状态在结算里按什么先后起作用,是战斗结算的编排——两件事互不干扰。
|
||||
|
||||
| 合并策略 | 重复授予时发生什么 | 说明 |
|
||||
|---|---|---|
|
||||
@@ -86,9 +86,9 @@
|
||||
| 刷新 | 剩余结算次数重置为该实例首次授予时的初始值,层数不变 | 刷新类内容行已就位——削弱行 weaken(2026-09-18 续时定案)、增益技行 empower / fortify、**主角增益行 attack_up / ac_up(2026-09-20 用户拍板「只续时不叠层」,全状态表增益/减益两侧合并语义就此统一为:主角可重复获取的增益与减益一律续时、不叠层)**;逐行读 `status_effects.tres` |
|
||||
| 并存 | 新建一份独立实例,两份各算各的 | 同上 |
|
||||
|
||||
并存分支没有满层上限,但容器规模天然有界:实例数的上界就是受理过的授予数——多受理一份就多一份实例,多少份在授予那一刻就完全确定,不会无限膨胀。
|
||||
并存分支没有满层上限,但状态池规模天然有界:实例数的上界就是受理过的授予数——多受理一份就多一份实例,多少份在授予那一刻就完全确定,不会无限膨胀。
|
||||
|
||||
叠加是纯加法:几层就是几倍的行值。叠到行上限后再授予同款会被拒绝,容器一个字不变;但这份奖励不会被无声吞掉——结算明细多一行"奖励未生效"(满层后白拿的那份,如实留痕),连来源一起写明,玩家看得到"这层白拿了"。浪费诚实、可规划。
|
||||
叠加是纯加法:几层就是几倍的行值。叠到行上限后再授予同款会被拒绝,状态池一个字不变;但这份奖励不会被无声吞掉——结算明细多一行"奖励未生效"(满层后白拿的那份,如实留痕),连来源一起写明,玩家看得到"这层白拿了"。浪费诚实、可规划。
|
||||
|
||||
无论重复来自玩家直接踩出的格子,还是连锁展开自动开出的奖励格,都走同一个授予入口、同样产生溢出行、同样留痕。
|
||||
|
||||
@@ -112,11 +112,11 @@
|
||||
|
||||
举证:本节为衰减时序规则,无计算。
|
||||
|
||||
### 幅度与量纲:容器只做加法,换算归结算
|
||||
### 幅度与量纲:状态池只做加法,换算归结算
|
||||
|
||||
容器对每个状态只记两件数值的事:幅度(一个整数)和量纲(百分比还是固定值)。百分比量纲的叠层是纯加法——两层合计 = 2 × 单行幅度(叠层策略行,读 `status_effects.tres` 暴走 enrage 行),不是 1.5 的平方;固定值量纲几层就乘几。
|
||||
状态池对每个状态只记两件数值的事:幅度(一个整数)和量纲(百分比还是固定值)。百分比量纲的叠层是纯加法——两层合计 = 2 × 单行幅度(叠层策略行,读 `status_effects.tres` 暴走 enrage 行),不是 1.5 的平方;固定值量纲几层就乘几。
|
||||
|
||||
**结论**:容器输出的有效值 = 层数 × 行值,原样给出、不封顶不保底;把百分比合计换算成乘数、并在 −100 个百分点处设地板,是[战斗结算](战斗结算.md)的消费侧规则——地板保证减益不会把属性打到绝对负值,最低压到"归零"为止。
|
||||
**结论**:状态池输出的有效值 = 层数 × 行值,原样给出、不封顶不保底;把百分比合计换算成乘数、并在 −100 个百分点处设地板,是[战斗结算](战斗结算.md)的消费侧规则——地板保证减益不会把属性打到绝对负值,最低压到"归零"为止。
|
||||
|
||||
```
|
||||
有效值 = 层数 × 行值(量纲标签随值原样输出,不进乘法)
|
||||
@@ -124,12 +124,12 @@
|
||||
|
||||
两个现行例子读起来是这样:
|
||||
|
||||
| 例子 | 容器输出 | 消费侧读法 |
|
||||
| 例子 | 状态池输出 | 消费侧读法 |
|
||||
|---|---|---|
|
||||
| 暴走叠两层 | +(2 × enrage 行幅度)(读表;越出单行取值域,原样输出) | 压在天花板 +100% 上:敌方输出乘区封顶 ×2(削弱已改续时——"叠两层压地板 −100% 归零"的读法随 2026-09-18 结构修复批退役) |
|
||||
| 主角盾牌加护再拿一份 | 层数恒 1、剩余结算次数重置(refresh——2026-09-20 主角增益续时批) | 不经任何池:掷点判定阈值 = 主角基准(读 hero 表)+ 层数(现行 +1——上限 2 层叠读取法退役,局内可达 AC 上限 11) |
|
||||
|
||||
容器还有一条快照纪律:实例的幅度、初始次数、量纲在授予那一刻从表行拷贝。战斗中配置表即使被重载,已授予实例不受任何影响,只影响后续授予。
|
||||
状态池还有一条快照纪律:实例的幅度、初始次数、量纲在授予那一刻从表行拷贝。战斗中配置表即使被重载,已授予实例不受任何影响,只影响后续授予。
|
||||
|
||||
### 现在有哪些状态:现行九行内容
|
||||
|
||||
@@ -158,9 +158,9 @@
|
||||
| empower 蓄力 | 敌方输出倍率增益(enemy_output 池——蓄力技载体;幅度读表) | 敌方 | 见 `status_effects.tres` empower 行 | duration 读表 = 1 个有效增益拍 / 刷新 | 敌方技能施放(2026-09-16 敌人技能池批) |
|
||||
| fortify 硬化 | 敌方防御提升(**敌方防御池 enemy_defense**——硬化技载体;负值入池 = 主角攻击折半,2026-09-18 符号纠正——旧正值实际翻倍) | 敌方 | 见 `status_effects.tres` fortify 行 | duration 读表 = 1 个有效增益拍 / 刷新 | 敌方技能施放(2026-09-16 敌人技能池批) |
|
||||
|
||||
empower 与 fortify 是敌方技能池增益技在容器侧的数据落点(技能行 buff_ref 引用,施放时长由技能行覆盖——技能冷却与增益持续是两个计时器):两行 duration 表值(读表)的口径是"先兑付后衰减含施放当轮"——施放发生在第 N 结算战斗段,存活到第 N+1 结算战斗段才兑付"下一拍",即"持续 1 个有效结算"(proposal 语义的容器落地)。敌方防御池(enemy_defense)是第四个乘区池:敌方作为防守方的百分比修正池,消费面 = [战斗结算](战斗结算.md)主角攻击的池乘区——四池对称(敌打主角 = hero_defense × enemy_output,主角打敌 = hero_offense × enemy_defense),容器语义零延伸:仍是同构实例、side-wide 加算、不封顶不保底。
|
||||
empower 与 fortify 是敌方技能池增益技在状态池侧的数据落点(技能行 buff_ref 引用,施放时长由技能行覆盖——技能冷却与增益持续是两个计时器):两行 duration 表值(读表)的口径是"先兑付后衰减含施放当轮"——施放发生在第 N 结算战斗段,存活到第 N+1 结算战斗段才兑付"下一拍",即"持续 1 个有效结算"(proposal 语义的状态池落地)。敌方防御池(enemy_defense)是第四个乘区池:敌方作为防守方的百分比修正池,消费面 = [战斗结算](战斗结算.md)主角攻击的池乘区——四池对称(敌打主角 = hero_defense × enemy_output,主角打敌 = hero_offense × enemy_defense),状态池语义零延伸:仍是同构实例、side-wide 加算、不封顶不保底。
|
||||
|
||||
削弱行是当量锚在容器侧的数据落点:封印标中的收益折算成统一价值后,必须严格高于最低档主角增益——"封印标中必须比随便挖一格更值",否则没人愿意封印。这条锚的契约归[行动经济](../排雷循环/行动经济.md),对照验收归[战斗结算](战斗结算.md);暴走与失衡两行分别是 attack/defense 型负向(极性矩阵"标错/踩雷"分支兑付)在容器侧的数据落点:行内容与载体裁决归它,本表只承载行值(失衡已换装 AC 轴不入池——2026-09-18 结构修复批)。**失衡另有第二来源**:敌方妨害技(2026-09-19 新效应词汇批——蛛化卓尔精灵"蛛网束缚",敌方技能施放来源、duration 由技能行 buff_duration 覆盖)——容器零新语义,同构实例照常受理;乏力 sapped = 妨害第二词汇,载体已落地(L3 Boss 灰矮人石君王独占妨害技「大地脉动」,2026-09-20 第三关内容批)。
|
||||
削弱行是当量锚在状态池侧的数据落点:封印标中的收益折算成统一价值后,必须严格高于最低档主角增益——"封印标中必须比随便挖一格更值",否则没人愿意封印。这条锚的契约归[行动经济](../排雷循环/行动经济.md),对照验收归[战斗结算](战斗结算.md);暴走与失衡两行分别是 attack/defense 型负向(极性矩阵"标错/踩雷"分支兑付)在状态池侧的数据落点:行内容与载体裁决归它,本表只承载行值(失衡已换装 AC 轴不入池——2026-09-18 结构修复批)。**失衡另有第二来源**:敌方妨害技(2026-09-19 新效应词汇批——蛛化卓尔精灵"蛛网束缚",敌方技能施放来源、duration 由技能行 buff_duration 覆盖)——状态池零新语义,同构实例照常受理;乏力 sapped = 妨害第二词汇,载体已落地(L3 Boss 灰矮人石君王独占妨害技「大地脉动」,2026-09-20 第三关内容批)。
|
||||
|
||||
## 依赖与输出
|
||||
|
||||
@@ -168,24 +168,24 @@ empower 与 fortify 是敌方技能池增益技在容器侧的数据落点(技
|
||||
|
||||
| 方向 | 系统 | 接口要点 |
|
||||
|---|---|---|
|
||||
| 调用方 | [战斗结算](战斗结算.md) | 五个入口的唯一调用方:战斗开始(开账)、授予(唯一进货口)、查询生效清单(兑付消费)、轮末衰减、战斗结束(清空);事实转授予、兑付作用顺序、换算与地板都在它一侧 |
|
||||
| 调用方 | [战斗结算](战斗结算.md) | 五个入口的唯一调用方:战斗开始(初始化)、授予(唯一进货口)、查询生效清单(兑付消费)、轮末衰减、战斗结束(清空);事实转授予、兑付作用顺序、换算与地板都在它一侧 |
|
||||
| 上游 | [数据配置](../表现与支撑/数据配置.md) | 状态表的字段定义承载与统一读取;本系统是该表的回填责任方 |
|
||||
| 相邻 | [排雷玩法](../排雷循环/排雷玩法.md) | 棋盘事实的事件源头;与本容器零直接接口——事实一律经战斗结算转化 |
|
||||
| 相邻 | [排雷玩法](../排雷循环/排雷玩法.md) | 棋盘事实的事件源头;与本状态池零直接接口——事实一律经战斗结算转化 |
|
||||
| 相邻 | [行动经济](../排雷循环/行动经济.md) | 契约相邻、无运行时接口:五条经济契约在本侧的数据落点就是状态表行值 |
|
||||
| 下游 | [地图战斗资源](地图战斗资源.md) | 清图奖励含增益时经授予入口进入;增益与削弱档位的锚验收方之一 |
|
||||
| 下游 | [HUD 框架](../表现与支撑/HUD框架.md) | 状态栏数据源;有利/有害极性呈现、无状态时空槽隐藏、状态到图标的映射,三义务归口 |
|
||||
|
||||
容器对外是一组封闭的被动入口,全部布尔或计数返回:战斗开始(开账)、授予(唯一进货口)、查询生效清单(只读,按授予先后排列)、轮末衰减(返回本轮移除数)、战斗结束(全清回空)。它不发任何事件、不做任何界面动作——呈现刷新点在战斗结算编排完成之后。
|
||||
状态池对外是一组封闭的被动入口,全部布尔或计数返回:战斗开始(初始化)、授予(唯一进货口)、查询生效清单(只读,按授予先后排列)、轮末衰减(返回本轮移除数)、战斗结束(全清回空)。它不发任何事件、不做任何界面动作——呈现刷新点在战斗结算编排完成之后。
|
||||
|
||||
## P0 最小闭环
|
||||
|
||||
1. 战斗结算通知战斗开始:容器开账,空容器进入可用状态。
|
||||
1. 战斗结算通知战斗开始:状态池初始化,空池进入可用状态。
|
||||
2. 轮末结算时,战斗结算把这一轮的扫雷事实兑换成授予:挖开安全格给主角上增益、封印标中削弱敌人、踩雷给敌方上增强、标空封印触发反噬——授予入口是唯一进货口。
|
||||
3. 容器按表行合并策略受理(新建 / 叠一层 / 刷新),实例立即生效并携带归因记录。
|
||||
3. 状态池按表行合并策略受理(新建 / 叠一层 / 刷新),实例立即生效并携带归因记录。
|
||||
4. 战斗结算查询生效清单,逐行兑付进结算公式(有效值 = 层数 × 行值)。
|
||||
5. 兑付完做轮末衰减:全部实例剩余次数减一,归零移除——先兑付、后衰减。
|
||||
6. 战斗外授予、未知状态、满层授予一律被拒且容器不变;满层的"奖励未生效"行归战斗结算的结算明细。
|
||||
7. 战斗结束通知到达:全实例清空、容器回空,不跨到下一场战斗。
|
||||
6. 战斗外授予、未知状态、满层授予一律被拒且状态池不变;满层的"奖励未生效"行归战斗结算的结算明细。
|
||||
7. 战斗结束通知到达:全实例清空、状态池回空,不跨到下一场战斗。
|
||||
|
||||
## P1 / P2 后置
|
||||
|
||||
@@ -193,7 +193,7 @@ empower 与 fortify 是敌方技能池增益技在容器侧的数据落点(技
|
||||
|
||||
| 优先级 | 内容 | 后置原因 |
|
||||
|---|---|---|
|
||||
| P1 | 刷新、并存两类合并策略的后续内容行 | 语义已定义、容器已承载;刷新类已有内容(empower/fortify 2026-09-16 敌人技能池批、weaken 2026-09-18 续时定案),并存仍空,首个并存内容行上线时顺带补验收 |
|
||||
| P1 | 刷新、并存两类合并策略的后续内容行 | 语义已定义、状态池已承载;刷新类已有内容(empower/fortify 2026-09-16 敌人技能池批、weaken 2026-09-18 续时定案),并存仍空,首个并存内容行上线时顺带补验收 |
|
||||
| P1 | 清图奖励含增益的授予路径 | 来源类别已预留;内容与档位归[地图战斗资源](地图战斗资源.md)定稿 |
|
||||
| P1 | 单体寻址扩展位 | 现行对敌效果一律全体共享;首个"只作用于其中一个敌人"的效果上线时给实例加目标字段 |
|
||||
| P2 | 驱散 / 延时 / 转移接口 | 状态一旦生效,玩家没有任何手段摘掉、延后或挪给别人——省掉一整类界面复杂度是明确的设计决定;要加属于新增接口的修订,不是调参 |
|
||||
@@ -225,16 +225,16 @@ empower 与 fortify 是敌方技能池增益技在容器侧的数据落点(技
|
||||
|
||||
## 验收标准
|
||||
|
||||
- 容器寿命可答:战斗开始时为空;除战斗结束清空外没有任何入口能清空容器;战斗未开始或已结束时的授予一律被拒且容器不变。
|
||||
- 状态池寿命可答:战斗开始时为空;除战斗结束清空外没有任何入口能清空状态池;战斗未开始或已结束时的授予一律被拒且状态池不变。
|
||||
- 多向同构:主角侧增益与减益、敌方侧增强与削弱共用同一套受理、合并、倒数、清除语义,不存在第二套计时逻辑。
|
||||
- 授予即生效:状态发入当轮结算即兑付第一次,无"待生效"中间态。
|
||||
- 只记账不去重:同一事实被转化两次授予,入账两层——去重责任在战斗结算。
|
||||
- 只登记不去重:同一事实被转化两次授予,登记两层——去重责任在战斗结算。
|
||||
- 叠层不减钟:叠加策略行叠加只加层数,剩余次数保持首次授予定下的轨迹不变(刷新策略行则相反——层数不变、只重置剩余次数;两策略逐行读表)。
|
||||
- 满层拒绝原子且留痕:叠满后再授予返回失败、容器逐字不变;结算明细多一行"奖励未生效"(含来源)。
|
||||
- 满层拒绝原子且留痕:叠满后再授予返回失败、状态池逐字不变;结算明细多一行"奖励未生效"(含来源)。
|
||||
- 先兑付后衰减:每轮结算恰做一次衰减,归零实例当轮移除;停手轮、弃图刷新轮照常衰减。
|
||||
- 合成不设上下限:容器输出的有效值恒等于层数 × 行值,越出百分比域不封顶不保底;地板在战斗结算侧。
|
||||
- 合成不设上下限:状态池输出的有效值恒等于层数 × 行值,越出百分比域不封顶不保底;地板在战斗结算侧。
|
||||
- 快照抗重载:已授予实例的数值在战斗中不受配置表重载影响,只影响后续授予。
|
||||
- 确定性回放:同一授予序列驱动两个独立容器实例,生效清单(含排列顺序)与衰减轨迹逐项相同。
|
||||
- 确定性回放:同一授予序列驱动两个独立状态池实例,生效清单(含排列顺序)与衰减轨迹逐项相同。
|
||||
- 表实一致:配置表字段与 `data/schemas/status_effect_table.gd` 逐字段一致。
|
||||
|
||||
## 待办
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
| 行动点价目、停手与刷新扣费 | [行动经济](../排雷循环/行动经济.md) |
|
||||
| 棋盘怎么生成 | [棋盘生成](../排雷循环/棋盘生成.md) |
|
||||
| 单位血量递减、行动环与存活判定 | [敌人系统](敌人系统.md) |
|
||||
| 增益/减益状态的容器、叠层与效果实例 | [增益状态](增益状态.md) |
|
||||
| 增益/减益的状态池、叠层与效果实例 | [增益状态](增益状态.md) |
|
||||
| 格面资源行值、权重档位与极性字典 | [地图战斗资源](地图战斗资源.md) |
|
||||
| 关卡序列、关卡大奖励与失败 | [冒险结构](../冒险循环/冒险结构.md) |
|
||||
| 界面呈现与结算动画 | [HUD 框架](../表现与支撑/HUD框架.md)与[战斗表现](战斗表现.md) |
|
||||
@@ -144,11 +144,11 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 ×
|
||||
|
||||
| 兑付形态 | 覆盖 | 兑付方式 | 拒绝语义 |
|
||||
|---|---|---|---|
|
||||
| 增益(percent) | attack / defense / weaken 的正负两向 | 进入[增益状态](增益状态.md)的容器,本结算生效 | 叠层已满时拒收,记"奖励未生效"行 |
|
||||
| 增益(percent) | attack / defense / weaken 的正负两向 | 进入[增益状态](增益状态.md)的状态池,本结算生效 | 叠层已满时拒收,记"奖励未生效"行 |
|
||||
| 即时全体伤害(flat) | blast 正向 | 战斗段末对全体存活敌各扣表值生命(暂存单殿后统一落地) | 场上无敌可打时零兑付,记"奖励未生效"行 |
|
||||
| 即时治疗(flat) | heal 正向 | 主角按表值回复并封顶上限 | 满血时零兑付,记"奖励未生效"行 |
|
||||
| 直伤(flat) | heal 负向 | 主角在战斗段末扣表值生命(暂存单殿后统一落地),不经增益状态 | 主角倒下则地图账整体不兑,逐单留"未生效"行 |
|
||||
| 警觉加层 | blast 负向 | 敌方全体护甲等级 +1/层(读 `reward.tres` enemy_alert 行 → `status_effects.tres` alert 行),入增益状态容器 | 直授无上限;战斗段由防守方护甲等级读数消费 |
|
||||
| 警觉加层 | blast 负向 | 敌方全体护甲等级 +1/层(读 `reward.tres` enemy_alert 行 → `status_effects.tres` alert 行),入状态池 | 直授无上限;战斗段由防守方护甲等级读数消费 |
|
||||
| GP 缓冲(flat) | gp 正 / 负向 | GP 袋 / 破财按 power 记入战斗内 GP 缓冲(+power / −power);缓冲随战斗完成折进 battle_finished 的 gp_dropped 统一到账(GP 归[冒险结构](../冒险循环/冒险结构.md)) | 无拒收态——缓冲只在战斗边界与钱包结算,战斗域零钱包状态 |
|
||||
| 行动点修正 | action 正/负向 | 下轮行动点 ±power(action_economy 排队,下一轮开始兑现后清零;下限 0) | 排队净值不跨轮保留;明细记效果行(effect_id=ap_delta) |
|
||||
|
||||
@@ -188,7 +188,7 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 ×
|
||||
|
||||
战斗段是兑现的最后一刀。主角的基础攻击恒存在——这是项目拍板:若基线为零,百分比增益乘上去永远是零,增益系统就空转了。攻击力域 [1, 999]、0 于加载期拒绝,行值读主角表。顺序固定:主角先基础攻击顺位最前的存活敌人,随后按行序逐个存活敌人按本拍摇定技能还手;每个敌人依次走"按技能行兑现、结算伤害、执行上报(技能进冷却 + 保底计数)"三步且恰行动一次,主角不在其列;**最后兑地图伤害账**——授予段暂存的全部伤害单按授予段事件序补提交,与主角单、敌方单一起攒到战斗段尾统一结账(见[伤害单据与伤害控制器](#伤害单据与伤害控制器所有伤害走同一道门)一节)。主角中途倒下,剩余敌人全部停手,地图伤害账整体不兑(逐单留「未生效(主角已倒下)」行),直接进判定段。施放技不涉伤害、照旧当场落行。案C 后授予段不产出伤害,主角进入战斗段时恒存活、场上恒有敌——先手必兑。
|
||||
|
||||
**开轮摇号与敌方技能兑现**(2026-09-16 敌人技能池批):敌人每拍做什么由开轮摇号决定——每轮轮次开始时,本系统在换算层排除冷却中技能,按行序逐敌从 `behavior_roll` 封闭流的独立子流摇定本拍动作写入实例池(首轮同样摇号;每轮恰摇一次;轮内刷新换图不重摇),随后冷却递减。摇定后、兑现前死亡 → 本拍技能作废、不动手(死亡即不动手)。结算战斗段只按技能行兑现:伤害技走三乘法链(见下),增益技记一行施放行并把状态效果按技能行持续回合挂入[增益状态](增益状态.md)容器——0 伤害动作不掷不折。池模板、技能行、冷却与保底语义归[敌人系统](敌人系统.md)(引用不转述)。
|
||||
**开轮摇号与敌方技能兑现**(2026-09-16 敌人技能池批):敌人每拍做什么由开轮摇号决定——每轮轮次开始时,本系统在换算层排除冷却中技能,按行序逐敌从 `behavior_roll` 封闭流的独立子流摇定本拍动作写入实例池(首轮同样摇号;每轮恰摇一次;轮内刷新换图不重摇),随后冷却递减。摇定后、兑现前死亡 → 本拍技能作废、不动手(死亡即不动手)。结算战斗段只按技能行兑现:伤害技走三乘法链(见下),增益技记一行施放行并把状态效果按技能行持续回合挂入[增益状态](增益状态.md)的状态池——0 伤害动作不掷不折。池模板、技能行、冷却与保底语义归[敌人系统](敌人系统.md)(引用不转述)。
|
||||
|
||||
**三乘法链**(技能伤害的合成顺序,技能倍率乘在最前,其后既有链一字不动):
|
||||
|
||||
@@ -258,7 +258,7 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值
|
||||
|
||||
挖掘期刷新是玩家在挖掘中途主动换图,经[行动经济](../排雷循环/行动经济.md)扣费:扣费成功后按"旧板退役、生成新板、装板、资源预分配恰一次、变异布置"编排,本轮不打断——没有结算段、没有轮次结束。储备不足被拒是玩家决策的合法结果,不是编排错误。刷新图不发清图奖励,完美封印计数随装板重置。
|
||||
|
||||
战斗开始按固定序列开张:关上配置热重载的闸门、打开增益状态容器、掷骰定敌方实际数量、生成敌人、装板并预分配资源恰一次、变异布置([地形变异](../排雷循环/地形变异.md)——棋盘设置顺序第 4 步:生成棋盘 → 打开状态初始化 → 战斗资源格设置 → 变异格设置,消费 `variant_place` 封闭流)、发开轮通知并执行开轮摇号(摇定首轮各敌本拍动作)。上一关的大奖励(如血上限提升)经战斗开始入参的覆盖值通道生效,内容归[冒险结构](../冒险循环/冒险结构.md)。
|
||||
战斗开始按固定序列开张:关上配置热重载的闸门、初始化状态池、掷骰定敌方实际数量、生成敌人、装板并预分配资源恰一次、变异布置([地形变异](../排雷循环/地形变异.md)——棋盘设置顺序第 4 步:生成棋盘 → 打开状态初始化 → 战斗资源格设置 → 变异格设置,消费 `variant_place` 封闭流)、发开轮通知并执行开轮摇号(摇定首轮各敌本拍动作)。上一关的大奖励(如血上限提升)经战斗开始入参的覆盖值通道生效,内容归[冒险结构](../冒险循环/冒险结构.md)。
|
||||
|
||||
举证:本节为编排流程,无计算。
|
||||
|
||||
@@ -273,7 +273,7 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值
|
||||
| 上游 | [排雷玩法](../排雷循环/排雷玩法.md) | 订阅其三事件流(挖开格、封印判定、轮次结束);换图时调用装板与退役 |
|
||||
| 上游 | [棋盘生成](../排雷循环/棋盘生成.md) | 换图时调用其生成接口 |
|
||||
| 上游 | [敌人系统](敌人系统.md) | 单位接口全调用面:生成、查询、扣血、摇定写入、执行上报、默认目标、警觉授予、清场;护甲等级(防守方掷点判定读数)随单位数据供给;池模板与技能行数据归它 |
|
||||
| 上游 | [增益状态](增益状态.md) | 状态容器接口全调用面:开域、授予、读值、衰减、闭域 |
|
||||
| 上游 | [增益状态](增益状态.md) | 状态池接口全调用面:初始化、授予、读值、衰减、清空 |
|
||||
| 上游 | [地图战斗资源](地图战斗资源.md) | 格面资源接口:预分配、身份查询、受理、清图对象、当量供给投影、映射退役 |
|
||||
| 上游 | [冒险结构](../冒险循环/冒险结构.md) | 战斗触发、遭遇上下文与主角入参覆盖值(覆盖值通道已随冒险结构实现批正式接线——接口四件套正式侧承载) |
|
||||
| 下游 | [HUD 框架](../表现与支撑/HUD框架.md) | 明细流水是结算明细屏的统一数据源(未生效类行须带形状冗余防误读);状态读取走下方呈现只读面 |
|
||||
@@ -296,7 +296,7 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值
|
||||
|
||||
## P0 最小闭环
|
||||
|
||||
1. 战斗开始序列跑完(关闸门、开容器、掷骰定敌数、生成敌人、装板并预分配资源、发开轮通知 + 开轮摇号),进入第一轮挖掘期。
|
||||
1. 战斗开始序列跑完(关闸门、初始化状态池、掷骰定敌数、生成敌人、装板并预分配资源、发开轮通知 + 开轮摇号),进入第一轮挖掘期。
|
||||
2. 挖掘期本系统只缓冲事实流(开格、封印入结算队列),不做任何兑付。
|
||||
3. 轮末自动触发五段结算,触发与事件到达序无关。
|
||||
4. 授予段按判定基线过滤(被挖开的封印不入判定),再按极性矩阵三批兑现:开安全格兑正向(封印安全格直挖 = 四情况④零奖励作废行)、开危险格 / 标错封印兑负向(封印危险格直挖照常——四情况②)、清图发清图奖励对象(完美乘数读 settlement.tres p_perfect)。
|
||||
|
||||
@@ -188,7 +188,7 @@ Boss 专属身份 = 专属池承载:独占技能 + 权重轮廓(**技能错
|
||||
|---|---|---|
|
||||
| 上游 | [战斗结算](战斗结算.md) | 唯一编排调用方:开战生成、开轮摇号(随机消费)、结算内兑现/受击/执行上报的次序由它钉死;踩雷到警觉施加的转化(每颗雷恰一次)也由它编排 |
|
||||
| 上游 | [数据配置](../表现与支撑/数据配置.md) | 敌人表、主角表、技能表的 schema 承载与类型化读取;本系统是三表的回填责任方 |
|
||||
| 相邻 | [增益状态](增益状态.md) | 敌方侧增益状态(警觉)随八型批改由它承载与登记;层数容器与轮末衰减归它,层数由战斗结算读出后作参数传入——运行时零直接调用 |
|
||||
| 相邻 | [增益状态](增益状态.md) | 敌方侧增益状态(警觉)随八型批改由它承载与登记;层数登记与轮末衰减归它,层数由战斗结算读出后作参数传入——运行时零直接调用 |
|
||||
| 下游 | [战斗结算](战斗结算.md) | 胜负判定素材(敌全灭 / 主角归零)与伤害分量(基线 × 技能倍率)的供给方;护甲克制矩阵归它 |
|
||||
| 下游 | [地图战斗资源](地图战斗资源.md) | 固定顺位是道具伤害的默认目标规则;基础攻击恒在,奖励侧是基础攻击之外的规划面伤害 |
|
||||
| 下游 | [关卡节点地图](../冒险循环/关卡节点地图.md) | 遭遇构成(何时开战、坐标与数量怎么定)归它;跨战斗血量是否保留归冒险循环裁决 |
|
||||
|
||||
@@ -170,9 +170,9 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
|
||||
|
||||
**实施状态(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)。
|
||||
|
||||
### 营地覆盖层:四柜台并排(程序占位——视觉终稿归营地视觉批)
|
||||
### 营地:可点击场景图(旧四柜台并排形态已随卡④改版取代)
|
||||
|
||||
营地覆盖层自 2026-10-12(迭代 21 落地)为**四柜台并排**布局:①树淬炼(树脊柱界面形态,营地主界面)②锻造工坊(钥匙门+点亮展开工作间)③秘宝匣(钥匙门+目录与同调装配)④奖励格图鉴(常开无门槛)——宽度不足横向滚动兜底;全部程序占位视觉(占位纪律延续,2026-10-11 用户令),**视觉与布局终稿归 HUD 营地视觉批**(未立项)。结构现行事实源 = [天赋树](../跨局循环/天赋树.md)「营地=树:统一模型」节(2026-10-13 迭代 21 反哺⑤写入文档登记——本篇原无营地柜台登记面,顺带补缺)。
|
||||
营地形态**已换代为一张可点击的场景图 + 七物件点选**(2026-10-22 卡④美术设计段定稿,现行权威=[camp](../../ux/camp.md));2026-10-12(迭代 21 落地)起至换代前的旧形态为**四柜台并排**布局:①树淬炼(树脊柱界面形态,营地主界面)②锻造工坊(钥匙门+点亮展开工作间)③秘宝匣(钥匙门+目录与同调装配)④奖励格图鉴(常开无门槛)——宽度不足横向滚动兜底;全部程序占位视觉(占位纪律延续,2026-10-11 用户令),**视觉与布局终稿归 HUD 营地视觉批**(未立项)。结构现行事实源 = [天赋树](../跨局循环/天赋树.md)「营地=树:统一模型」节(2026-10-13 迭代 21 反哺⑤写入文档登记——本篇原无营地柜台登记面,顺带补缺)。
|
||||
|
||||
### 可访问性基线:看得清、不闪、纯鼠标玩得通
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
| 负责 | 说明 |
|
||||
|---|---|
|
||||
| 存档契约 | 单档 JSON 存档的域划分与读写约定(域清单见核心规则) |
|
||||
| 存档契约 | 3 存档位 JSON 存档的域划分与读写约定(域清单见核心规则;槽位承载见下「三存档位」段) |
|
||||
| 版本迁移 | 版本字段 + 读档时链式迁移 + 高版本拒读禁写 |
|
||||
| 读写时机 | 启动读盘;正式冒险收束写盘;原子写盘原语 |
|
||||
| 元进度的持久化承载 | 归档登记的职责口径:"元进度持久化框架"——钥石与解锁进度由本系统落盘 |
|
||||
@@ -58,7 +58,7 @@ SaveManager 不依赖任何玩法系统就能工作:它是被动的承载方
|
||||
|
||||
**唯一豁免 = `breakpoint` 断点域**(2026-09-29 迭代 8 卡①顺带修订):断点是冒险进行中的瞬态快照,不是跨局携带——里面的生命/GP/道具库存只在「续玩上局」时还原进局内,冒险收束(通关/失败/放弃)即整域清除,永远不会渗进永久进度。反面清单的管辖对象因此收窄为 `meta` 永久进度域(冒烟域界扫描顺带收窄到 meta 域);断点域自身的字段口径归[冒险结构](../冒险循环/冒险结构.md)登记。
|
||||
|
||||
存档是单文件 JSON(`user://save.json`),字典键一律字符串。数据模型(现行 = v6;示例值全为零值默认态):
|
||||
**三存档位(迭代 33 卡①,2026-10-22 反哺写入)**:存档是 3 个独立的 JSON 文件(`user://save_slot_1/2/3.json`,槽文件名只经 `slot_path()` 单点派生,槽 1 禁复用旧单档名),字典键一律字符串。写盘目标=当前激活槽的文件;启动(boot)不读任何槽文件——启动态=无激活态,不读写;激活态由选档界面的「新档」(`create_slot`)或「进档」(`activate_slot`)建立(选档界面归迭代 33 卡③)。数据模型(现行 = v6;示例值全为零值默认态):
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -107,14 +107,15 @@ SaveManager 不依赖任何玩法系统就能工作:它是被动的承载方
|
||||
|
||||
v4/v5/v6 各域缺键由读取方按默认值补齐(空集合/0),旧档零迁移损失;收束自增域(通关次数/Boss 计数/终身计数/真视使用计数)的唯一入账点 = `apply_adventure_summary`(vision_used 走 `add_vision_used` 收束)。**v6 域后扩列不升版先例**:`vision_used`(迭代 22,2026-10-12——迭代 21 同款口径;断点随件 `vision_counter_used` 同批新增;旧断点随件键 `bonus_aux_carry` 已随替换子交互拆除退役,迭代 22 T5)。
|
||||
|
||||
消费面纪律:其他系统只经 SaveManager 的类型化访问器(读余额/加钥石/花钥石、读写树等级等)与域更新原语(`apply_adventure_summary`)操作存档,不碰内部数据结构。
|
||||
消费面纪律:其他系统只经 SaveManager 的类型化访问器(读余额/加钥石/花钥石、读写树等级等)与域更新原语(`apply_adventure_summary`)操作存档,不碰内部数据结构。三条槽位纪律(迭代 33 卡①):一、无激活态下一切写盘路径拒绝并返回 false(boot 后未进档/未新档即结算或购买=不落盘,激活后照常);二、槽文件名单点派生——消费方禁各自拼槽文件名,测试与探针的隔离走注入口(`attach_slot_template`/`peek_summary_at`);三、UI 读别槽摘要只走窥视 API `peek_slot_summary(slot)`(不激活、不写内存、零盘面副作用),返回结构 `{"readable", "has_file", "keystone", "cleared", "total"}`——`readable`=槽文件可读(空槽=零值合法态可读;损坏/高版本/缺版本字段=不可读标记),`has_file`=槽主文件在盘与否(空槽/有档的操作集二分判定来处;非摘要第四项、零 UI 语义),三项摘要值(`keystone`/`cleared`/`total`)只在 `readable=true` 时有意义。
|
||||
|
||||
### 读写时机
|
||||
|
||||
```
|
||||
启动 ──▶ 读盘(load_from_disk:新档/损坏兜底/迁移链/高版本拒读,见下两节)
|
||||
正式冒险收束(adventure_finished)──▶ apply_adventure_summary 入账 ──▶ 原子写盘
|
||||
营地钥石消费(元进度实现批接线)──▶ 每笔变更后即时写盘
|
||||
启动 ──▶ 不读盘(boot 无激活态,不读写任何槽;只做一次旧单档迁移,见「版本与迁移」节)
|
||||
选档界面「新档」/「进档」──▶ create_slot / activate_slot(读盘=该槽文件,建立激活态;迭代 33 卡①/卡③)
|
||||
正式冒险收束(adventure_finished)──▶ apply_adventure_summary 入账 ──▶ 原子写盘(落当前激活槽)
|
||||
营地钥石消费(元进度实现批接线)──▶ 每笔变更后即时写盘(落当前激活槽)
|
||||
冒险停点(choices_presented 选路停点)──▶ 断点快照写盘(迭代 8 卡①)
|
||||
冒险三结局收束(通关/失败/放弃)──▶ 清除断点 + 原子写盘(迭代 8 卡①/T3 退出口径)
|
||||
```
|
||||
@@ -139,6 +140,8 @@ v4/v5/v6 各域缺键由读取方按默认值补齐(空集合/0),旧档零
|
||||
|
||||
迁移函数经 `register_migration(旧版本号, 函数)` 注册:函数把数据从「旧版本」改写成「旧版本 + 1」。生产迁移链现行六件(v2 起自注册):v1→v2 = 断点域补空;v2→v3 = 断点附随件与摘要 keystone_drops 补键(读取方 .get 兜底);v3→v4 = 同调三域补键;v4→v5 = 树域两键补齐(原挂接的「三体系迁移」体已随迭代 21 T5 攻防所有权切分删除——`save_manager.gd:96-98`、`meta_progression.gd:294-295` 实证;forge_levels 旧域同批清退,加载时按默认模型键集白名单收窄,`save_manager.gd:399-401`);v5→v6 = 生涯两终身计数域补零;**v6→v7 = 锻造工坊域 forge_routes 缺键补齐(迭代 23 T5——无结构迁移体,版本号推进仅为 schema_version 对齐;解锁态派生不落档:初始持有〔表 initial_owned〕∨ 直购〔unlocked 清单〕∨ 练满前一档〔levels[prereq]≥cap〕)**。任一步失败按损坏兜底处理。
|
||||
|
||||
旧单档一次性迁移(迭代 33 卡①,用户裁决 Q1 甲):本系统从单档制换代为 3 存档位制时,盘上残留的旧单档 `user://save.json` 在启动时被处理——文件**字节级原样搬运**进槽 1(`user://save_slot_1.json`,零解析零改造:损坏或高版本的旧档也原样迁入,之后由该槽进档时的损坏兜底/高版本拒读接管,不静默丢数据),源文件改名 `user://save.json.migrated.bak` 留痕不删;槽 1 文件已存在则不重迁(幂等,二次启动零操作);迁移失败(拷贝或改名失败)源文件保留、下次启动重试。留痕与结果记在启动日志(开发者向,非玩家面)。
|
||||
|
||||
### 损坏兜底
|
||||
|
||||
档案读不开(文件损坏、JSON 解析失败、结构出域、缺版本字段)时:原文件改名为 `<路径>.corrupt.bak`(已有同名备份则覆盖)留下现场,游戏用默认新档继续运行,并留下警告日志。两条底线:不静默丢档(坏档永远可人工找回)、不崩溃(坏档不挡玩)。
|
||||
@@ -162,7 +165,7 @@ MVP 不要求本系统的闭环([不做清单](../../05-不做清单.md)把单
|
||||
| 优先级 | 内容 | 后置原因 |
|
||||
|---|---|---|
|
||||
| ~~P1~~ | ~~快照与复盘的持久化承接~~ | **已兑现**(2026-09-29 迭代 8 卡①:断点域承载 + rng「主种子+计数器」快照契约回填面 `restore_adventure`) |
|
||||
| P2 | 多存档槽位 | 单档 MVP(2026-09-21 裁决);多档等有真实需求再立项 |
|
||||
| ~~P2~~ | ~~多存档槽位~~ | **已实现**(2026-10-22 迭代 33 卡①——3 存档位三文件制落地,口径见「三存档位」段;原「单档 MVP(2026-09-21 裁决)」后置条随兑现注销) |
|
||||
|
||||
## 调参表
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
| 负责 | 说明 |
|
||||
|---|---|
|
||||
| 钥石(存档级) | 钥石入存档、永不丢失;换强化花了多少、还剩多少 |
|
||||
| 营地三柜台 | 属性锻造 / 秘宝匣 / 奖励格图鉴——永久强化的全部内容承载(见核心规则) |
|
||||
| 营地功能界面 | 锻造工坊 / 秘宝匣 / 奖励格图鉴——永久强化的全部内容承载(见核心规则) |
|
||||
| Boss 重复击杀的钥石产出规则 | 首杀全量、重复杀固定小额(数值读表) |
|
||||
| 换算率表 | 永久强化对难度带影响的折算登记(区间平移换算率,见核心规则) |
|
||||
| 永久强化的跨局生效 | 解锁结果在开始新冒险时注入下一局(冒险开始参数面 + 覆盖值通道) |
|
||||
@@ -35,7 +35,7 @@
|
||||
| 换算率表数值行与配置表承载 | [数据配置](../表现与支撑/数据配置.md)——本系统登记键结构、设计批回填数值 |
|
||||
| 营地界面、钥石余额与解锁呈现 | [HUD 框架](../表现与支撑/HUD框架.md)——本批只拍交互框架(双入口),视觉与实现随对方 |
|
||||
| 难度区间模型本身 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md)——本文只经区间平移换算率接入 |
|
||||
| 奖励格图鉴的格子内容设计 | [地图战斗资源](../战斗循环/地图战斗资源.md)(差异化批,排 Alpha)——本文只登记柜台结构位 |
|
||||
| 奖励格图鉴的格子内容设计 | [地图战斗资源](../战斗循环/地图战斗资源.md)(差异化批,排 Alpha)——本文只登记功能界面结构位 |
|
||||
|
||||
## 在核心循环中的位置
|
||||
|
||||
@@ -55,25 +55,25 @@
|
||||
|
||||
**重复获取规则(2026-09-18 用户拍板)**:同一 Boss **首次击杀给大额**,之后的重复击杀只给**固定小额**——不设递减曲线,存档只记首杀标记位。设计意图:深度关的产出优势是长线驱动(配合定价几何递增,见下),重复刷老关仍有小额意义但不构成无上限的产出泵。两档数值与两渠道量级配比归元进度设计批配读数投值,行值读表。
|
||||
|
||||
### 营地三柜台:永久强化的内容承载
|
||||
### 营地功能界面:永久强化的内容承载
|
||||
|
||||
玩家结束一次冒险回到存档内的营地,用钥石在三柜台消费(2026-09-18 用户拍板):
|
||||
玩家结束一次冒险回到存档内的营地,用钥石在营地各功能界面消费(2026-09-18 用户拍板):
|
||||
|
||||
| 柜台 | 内容 | 解锁渠道 |
|
||||
| 功能界面 | 内容 | 解锁渠道 |
|
||||
|---|---|---|
|
||||
| 属性锻造 | 生命上限、基础攻击、护甲等级——三档可重复升级的属性强化 | 钥石直购 |
|
||||
| 秘宝匣 | 秘宝解锁与同调装配——**件的目录与效果权威定义在[秘宝](秘宝.md)「目录(重设计 v1)」**(12 件三档〔2026-10-11 裁回能器删/换装券撤/第四只手删〕;旧目录全退役只作素材库) | 解锁=混合制(基础件钥石购买/特定件条件解锁——见秘宝.md「道具从哪来」;装配只在冒险开始前配置,冒险中零更换途径〔2026-10-11 终裁〕);**迭代 22 实装批落地(2026-10-12)**:购买钮(余额不足禁用态)+条件解锁进度呈现+分档装配呈现(名后缀·档位/未解锁禁装)+空目录合法态;柜台数据投影=`treasure_shop_status`(解锁态/条件进度/价格单点);旧道具工坊渠道面(行族/词表/解锁函数)已顺带退役;钥石定价与阈值 provisional 归调参批 |
|
||||
| 秘宝匣 | 秘宝解锁与同调装配——**件的目录与效果权威定义在[秘宝](秘宝.md)「目录(重设计 v1)」**(12 件三档〔2026-10-11 裁回能器删/换装券撤/第四只手删〕;旧目录全退役只作素材库) | 解锁=混合制(基础件钥石购买/特定件条件解锁——见秘宝.md「道具从哪来」;装配只在冒险开始前配置,冒险中零更换途径〔2026-10-11 终裁〕);**迭代 22 实装批落地(2026-10-12)**:购买钮(余额不足禁用态)+条件解锁进度呈现+分档装配呈现(名后缀·档位/未解锁禁装)+空目录合法态;界面数据投影=`treasure_shop_status`(解锁态/条件进度/价格单点);旧道具工坊渠道面(行族/词表/解锁函数)已顺带退役;钥石定价与阈值 provisional 归调参批 |
|
||||
| 奖励格图鉴 | 特殊奖励格的解锁——更强效果的格面 | 结构位现定;格子内容排 Alpha,随[地图战斗资源](../战斗循环/地图战斗资源.md)差异化批落地 |
|
||||
|
||||
属性锻造的树形节点结构已随迭代 12 落地在役——**结构/节点/数值的现行事实源 = [天赋树](天赋树.md),本文不复制树侧内容、只作指路**;本柜台三档直线强化与树淬炼 flat 在注入面叠加生效(注入口径见下文「跨局注入」节)。
|
||||
属性锻造的树形节点结构已随迭代 12 落地在役——**结构/节点/数值的现行事实源 = [天赋树](天赋树.md),本文不复制树侧内容、只作指路**;本界面三档直线强化与树淬炼 flat 在注入面叠加生效(注入口径见下文「跨局注入」节)。
|
||||
|
||||
属性锻造的攻击、护甲两档已按[锻造工坊](锻造工坊.md) v0.6(成文时名「武器锻造」,2026-10-11 更名)设计定案转为武器与护甲的独立等级路线——**行族本体随迭代 21 T5 退役、路线为新建行族,已随迭代 23 实装入库(2026-10-12,新表 `forge.tres`)**。营地钥石入口族换代(2026-10-13 v1.18 迭代 23 反哺写入):buy_forge 随 forge_products 退役删除后,本柜台钥石消费写口 = **forge_buy_level(逐级锻造价)/ forge_buy_unlock(一次性解锁价)/ forge_select_weapon·armor(免费选中)**——写口唯一经 MetaProgression 锻造写口族(契约 9 写口单点,UI 只发意图);钥石定价历史考古参数 20 钥石/150% 公比见 `meta.tres:82-84` 退役批注,provisional 投值终值归 M4。
|
||||
|
||||
**营地统一(2026-10-11 天赋树设计会话裁案甲;2026-10-13 v1.20 迭代 21 反哺写入——「落地前维持现役」过渡态终结)**:树=营地本体,本属性锻造柜台已随迭代 21 退役、属性升级唯一入口=树脊柱淬炼节点(四柜台并排已实装,2026-10-12 入库)。**完整模型(四柜台并排/钥匙工作间/图鉴常开)唯一事实源 = [天赋树](天赋树.md)「营地=树:统一模型」节——本文只登记本柜台在系统内的去留,不复制树侧内容。**
|
||||
|
||||
**投值语言锁定(2026-09-18 数值语言拍板)**:三柜台属性强化一律 **flat 整数加减**("每级 +1 基础攻击"式,而非"+50% 攻击"式)——避开百分比词条被数值成长稀释的先例陷阱、守住数字可读性锚;具体每级数值仍归元进度设计批投值。
|
||||
**投值语言锁定(2026-09-18 数值语言拍板)**:营地属性强化一律 **flat 整数加减**("每级 +1 基础攻击"式,而非"+50% 攻击"式)——避开百分比词条被数值成长稀释的先例陷阱、守住数字可读性锚;具体每级数值仍归元进度设计批投值。
|
||||
|
||||
三条柜台纪律:**定价曲线一律几何递增**(每级费用按公比上浮——原则已拍板,起步价与公比数字归设计批配读数),与产出逻辑配套:深层关钥石产出多、后级强化贵,逼玩家往深处走。~~秘宝匣首版只挂通关次数渠道~~(历史排期裁决已消解:秘宝匣现役=钥石直购+条件解锁混合制,迭代 22 落地,2026-10-12)。**存档义务随柜台产生**:钥石余额、永久强化等级表、每关通关次数表、Boss 首杀标记位——四件已逐域登记在 registry `save_file` 条目(内容 owner = 元进度,承载 owner = [存档序列化](../表现与支撑/存档序列化.md))。
|
||||
各界面定价纪律:**定价曲线一律几何递增**(每级费用按公比上浮——原则已拍板,起步价与公比数字归设计批配读数),与产出逻辑配套:深层关钥石产出多、后级强化贵,逼玩家往深处走。~~秘宝匣首版只挂通关次数渠道~~(历史排期裁决已消解:秘宝匣现役=钥石直购+条件解锁混合制,迭代 22 落地,2026-10-12)。**存档义务随柜台产生**:钥石余额、永久强化等级表、每关通关次数表、Boss 首杀标记位——四件已逐域登记在 registry `save_file` 条目(内容 owner = 元进度,承载 owner = [存档序列化](../表现与支撑/存档序列化.md))。
|
||||
|
||||
护甲等级进首版属性柜台是 2026-09-18 拍板(用户选 A),其代价条款见下方换算率节的强条目登记。
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
|
||||
### 解锁界面:双入口框架
|
||||
|
||||
(2026-09-18 拍板)主菜单设营地独立入口(消费钥石、查看与管理永久强化);局内状态面板(原称暂停层,2026-10-13 改名——游戏非实时无暂停语义)也可查看钥石余额与已解锁清单(只读)。钥石余额在 HUD 常驻展示。呈现 spec 已出生:[ux/camp.md](../../ux/camp.md) v1.0(2026-09-30 审计拍板点 4A 裁决写入文档——退役/封存件「已退役/已解锁·能力封存中」呈现语义随 spec 落位);视觉终稿已随迭代 9 9A 段落码(2026-09-30)。本节锁框架与需求,呈现细节归 spec;局内状态面板入口已实装(2026-10-06 迭代 17 卡③〔时名暂停层〕——实机目检待用户,待办清单登记条在册)。
|
||||
(2026-09-18 拍板;入口拓扑随迭代 33 卡② 三入口化换代,2026-10-22 反哺写入)营地消费面(消费钥石、查看与管理永久强化)经主菜单「进入存档」→选档界面→进档/新档进入,主菜单不再设营地独立钮;局内状态面板(原称暂停层,2026-10-13 改名——游戏非实时无暂停语义)也可查看钥石余额与已解锁清单(只读)。钥石余额在 HUD 常驻展示。呈现 spec 已出生:[ux/camp.md](../../ux/camp.md) v1.0(2026-09-30 审计拍板点 4A 裁决写入文档——退役/封存件「已退役/已解锁·能力封存中」呈现语义随 spec 落位);视觉终稿已随迭代 9 9A 段落码(2026-09-30)。本节锁框架与需求,呈现细节归 spec;局内状态面板入口已实装(2026-10-06 迭代 17 卡③〔时名暂停层〕——实机目检待用户,待办清单登记条在册)。
|
||||
|
||||
### 单局循环零依赖:排期边界的推论
|
||||
|
||||
@@ -129,7 +129,7 @@ MVP 不要求本系统的闭环([不做清单](../../05-不做清单.md)整体
|
||||
|
||||
| 优先级 | 内容 | 后置原因 |
|
||||
|---|---|---|
|
||||
| P1 | 三柜台内容铺量与定价数字 | 柜台结构已定稿;清单明细、几何定价的起步价与公比、Boss 两档产出数值,随设计批配读数投值 |
|
||||
| P1 | 营地功能界面内容铺量与定价数字 | 界面结构已定稿;清单明细、几何定价的起步价与公比、Boss 两档产出数值,随设计批配读数投值 |
|
||||
| P1 | 秘宝匣钥石直购价 | **已投 provisional 占位**(普通档 10/优秀档 25 钥石,迭代 22 落地,2026-10-12);终值归调参批(原「首版只挂通关次数渠道」排期态随混合制落地消解) |
|
||||
| P1 | 奖励格图鉴的格子内容 | 排 Alpha,随[地图战斗资源](../战斗循环/地图战斗资源.md)差异化批 |
|
||||
| P1 | 换算率表数值行标定 | **已完成**(2026-09-23 换算率标定批——首版三行投值 6/9/1,护甲行强条目重测顺带履行并修复护甲断链)(原系笔误孤例,registry 与 meta.tres 均为 6/9/1——2026-09-30 勘误) |
|
||||
|
||||
@@ -1,25 +1,28 @@
|
||||
# 生涯
|
||||
|
||||
> **一句话定位**:主菜单里与营地平级的**局外只读界面**——营地管「花」(花钥石买永久强化),生涯管「看」(看自己跨局攒下的一切:累计战绩、历史冒险、图鉴收集)。冒险进行中不给任何数据回看(2026-10-04 用户裁决 P-C7 的延续),生涯是历史数据唯一的家。
|
||||
> **状态**:期一已实装(2026-10-07 迭代 18 卡④生涯界面实装批·期一——跨局汇总页+主菜单入口+终身计数域存档 v6 落地;期二/期三另行立项,本文不预占排期)。
|
||||
> **一句话定位**:营地里与三柜台平级的**局外只读界面**——营地管「花」(花钥石买永久强化),生涯管「看」(看自己跨局攒下的一切:累计战绩、历史冒险、图鉴收集)。冒险进行中不给任何数据回看(2026-10-04 用户裁决 P-C7 的延续),生涯是历史数据唯一的家。
|
||||
> **状态**:期一已实装(2026-10-07 迭代 18 卡④生涯界面实装批·期一——跨局汇总页+主菜单入口+终身计数域存档 v6 落地;期二/期三另行立项,本文不预占排期)。入口拓扑已随迭代 33 卡② 三入口化换代、营地里经笔记本接入归迭代 34 卡④(信息架构节 v1.1,2026-10-22 反哺写入)。
|
||||
> **来源**:[待办清单「『生涯』界面——冒险中数据回看的唯一承接处」条](../../../../待办清单.md)(2026-10-04 用户裁决 P-C7——冒险中不给数据回看,历史战报与结算明细的查看去向 = 新「生涯」界面)。
|
||||
|
||||
## 一、信息架构
|
||||
|
||||
生涯入口是主菜单一级按钮,与营地平级(2026-10-06 用户裁,备选案与淘汰依据见需求卡片 P1)。现行主菜单按钮组由 `build_start_overlay` 构造(`game/presentation/ui_assembler.gd:103`):「冒险」组(继续上局 / 开始冒险)与「营地与系统」组(营地 / 生涯〔期一已落位,营地钮与设置钮之间〕 / 设置 / 退出游戏)。具体行序排版属实装细节顺带落位(本文不画布局稿)。
|
||||
生涯入口经营地接入(目标结构=营地笔记本,迭代 34 卡④承载;迭代 33 卡② 三入口化后主菜单无生涯钮,现期无玩家可见入口,内部路径直调可达)。现行主菜单按钮组由 `build_start_overlay` 构造(`game/presentation/ui_assembler.gd:97`),只有三个一级钮(迭代 33 卡②,用户裁决 1):「进入存档」「设置」「退出游戏」——「进入存档」为唯一进度入口,点击打开选档界面(3 存档位,迭代 33 卡③)。
|
||||
|
||||
```
|
||||
主菜单(开始覆盖层)
|
||||
├─ 冒险组:继续上局 · 开始冒险
|
||||
└─ 营地与系统组:营地 · 生涯(期一已实装) · 设置 · 退出游戏
|
||||
主菜单(开始覆盖层,三入口)
|
||||
├─ 进入存档 → 选档界面(3 存档位;空槽「新档」/有档「进档」/「删档」二次确认)
|
||||
│ └─ 进档/新档 → 营地(迭代 34 卡④改为营地场景图;现期暂行落点=营地覆盖层)
|
||||
├─ 设置
|
||||
└─ 退出游戏
|
||||
|
||||
调试浮窗(迭代 18 卡⑦ P2 甲——入口迁宿主:开始层零调试入口;DS_DEBUG=1 会话浮窗启动即开,
|
||||
战斗屏 HUD 与关卡地图屏各一枚「调试」角标可再开)
|
||||
|
||||
生涯(局外只读面)
|
||||
├─ 跨局汇总(累计战绩与解锁总览)
|
||||
├─ 历史冒险回看(逐局摘要与单局明细)
|
||||
└─ 图鉴(敌人优先,秘宝/奇物随后)
|
||||
营地(存档内,进档/新档落点)
|
||||
└─ 生涯(局外只读面;入口=营地笔记本,迭代 34 卡④承载)
|
||||
├─ 跨局汇总(累计战绩与解锁总览)
|
||||
├─ 历史冒险回看(逐局摘要与单局明细)
|
||||
└─ 图鉴(敌人优先,秘宝/奇物随后)
|
||||
```
|
||||
|
||||
边界三条(均为 2026-10-06 用户裁 P4 甲):
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
| 代号 | item_id | 一句话 | 写哪笔系统资源/时点 | 解锁(迭代 22 实态) | 效果实现 |
|
||||
|---|---|---|---|---|---|
|
||||
| 晨操令 | morning_order | 每场战斗第 1 轮 +1 AP | AP 池/轮始 | 钥石 10 provisional | 订阅行 round_start→grant_ap |
|
||||
| 阔视野带 | wide_scout_band | 类型微光范围 8 格→12 格 | 视野参数/常时 | 钥石 10 provisional | 参数面 light_radius_bonus(+4) |
|
||||
| 阔视野带 | wide_scout_band | 视野照亮范围 8 格→12 格,类型微光不扩 | 视野参数/常时 | 钥石 10 provisional | 参数面 light_radius_bonus(+4) |
|
||||
| 试炼镐 | trial_pick | 每开 8 个安全格,当轮 AP +1(自动) | AP 池/开格自动兑付 | 钥石 10 provisional | ap_charge_safe 满 charge_n=8 自动 grant_ap(2026-10-12 反哺批⑤用户裁自动兑付) |
|
||||
| 刷新练习 | refresh_practice | 三选一刷新存量 +1 | 刷新存量/装配即得 | 钥石 10 provisional | 参数面 refresh_stock_grant |
|
||||
| 储备罐 | reserve_jar | 停手转存率 1:1 → 1.25:1 | 储备行动点(RAP)转存率参数/停手时 | 钥石 10 provisional | 参数面 rap_transfer_mult(125) |
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> 一句话:营地的武器与护甲成长——武器锻造区三条路线、护甲锻造区三条路线各练各的,钥石消费,一次冒险各选一件,满级特效留位本期不做
|
||||
> 状态:**v0.8 迭代 21 反哺④残余写入文档(2026-10-13)**——「树侧钥匙」句换代:钥匙节点 forge_workshop 已随迭代 21 实装在役(free 无前置、点亮展开本柜台、锁定态零购买路径),原「实装归待办清单」悬置指针终结。承 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)
|
||||
> 成文底稿:`reports/提案-武器锻造系统-2026-10-07.md`(提案过程稿——全部备选案与淘汰依据、用户原案逐条对照见彼;该件属过程件、非事实源,结论已按吸收即死逐条落进本文,删它不需再裁;**满级特效候选池已于 2026-10-21 迁入本文「满级特效扩展位」节,不再依赖过程稿**)
|
||||
> 成文底稿:提案过程稿《提案-武器锻造系统-2026-10-07》(**已退役**——中间产物吸收即死,2026-10-22 删除;全部备选案与淘汰依据、用户原案逐条对照已逐条落进本文,结论不依赖过程稿;**满级特效候选池已于 2026-10-21 迁入本文「满级特效扩展位」节**;考古=git 历史——删除批 603eba31,删除前全稿见历史版本 f958a03f)
|
||||
|
||||
## 设计目的
|
||||
|
||||
|
||||
@@ -318,7 +318,7 @@
|
||||
|
||||
**架构注记**:UI 不拥有任何游戏状态——全部读经核心只读面,全部写经组合根。呈现层信号载荷 schema 须在《HUD框架》成文(旧版状态记录 entry 17①,缺项即 blocking);场景级 headless 测试进 AC(entry 17②);覆盖层层级断言(缺陷⑤——任何模态覆盖层必须有"打开时遮挡物隐藏"断言)。
|
||||
|
||||
**更新触发注记(2026-09-12 评审增补——防实现层等待不存在的信号,旧版状态记录 entry 17 教训同类)**:封印与移动成功反馈**零事件外发**(排雷玩法发射面封闭)——经意图调用 `ActionOutcome` 返回值命令式驱动;AP/RAP 读数:行动经济无推送信号——组合根每次调用返回后重查;状态效果:增益状态纯被动容器零信号——状态栏刷新绑战斗结算的编排完成时点;奖励徽章:地图战斗资源 身份解析经 `query_identity` 只读回调(组合根注入 board_view),已开格揭显时查询——写路径回执后重查。
|
||||
**更新触发注记(2026-09-12 评审增补——防实现层等待不存在的信号,旧版状态记录 entry 17 教训同类)**:封印与移动成功反馈**零事件外发**(排雷玩法发射面封闭)——经意图调用 `ActionOutcome` 返回值命令式驱动;AP/RAP 读数:行动经济无推送信号——组合根每次调用返回后重查;状态效果:增益状态为纯被动状态池、零信号——状态栏刷新绑战斗结算的编排完成时点;奖励徽章:地图战斗资源 身份解析经 `query_identity` 只读回调(组合根注入 board_view),已开格揭显时查询——写路径回执后重查。
|
||||
|
||||
---
|
||||
|
||||
|
||||
+35
-26
@@ -1,35 +1,44 @@
|
||||
# 营地覆盖层 UX spec(camp)
|
||||
# 营地场景 UX spec(camp)
|
||||
|
||||
> 状态: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)(主菜单语境)
|
||||
> 状态:v2.0(2026-10-22 营地交互重做美术设计段;取代旧「四柜台覆盖层」形态)
|
||||
> 事实源:本 spec(呈现)+ [元进度](../systems/跨局循环/元进度.md)(机制)
|
||||
> 美术画法:[art-bible](../../art/art-bible.md) §6.2/§7.5;素材命名与路径:[asset-path-map](../../art/asset-path-map.md)
|
||||
> 相邻:[level-map.md](level-map.md)(主菜单语境)
|
||||
|
||||
## 定位
|
||||
|
||||
营地是存档内消费钥石的枢纽场所(界面壳,非机制实体——裁定见元进度):主菜单营地独立入口进入,玩家在此用钥石换永久强化、查看秘宝匣解锁与最近冒险。本 spec 只锁呈现;机制(定价/解锁/入账)全部归元进度。**循环层级:存档级(大循环/局外)呈现面**——本层只在存档语境可达(主菜单入口),冒险进行中不可达。
|
||||
营地=存档内的局外枢纽(存档语境可达,冒险进行中不可达)。形态=**一张可点击的营地场景图**:画面里有篝火、锻炉、床铺等物件,点物件进对应界面。**不是按钮列表式 UI。**
|
||||
|
||||
## 布局与交互
|
||||
## 场景构成与七物件绑定
|
||||
|
||||
- 石纹全屏底(样张 v2 冻结件,浅 dim 透出)+ 顶栏铭牌与钥石徽(余额常驻)。
|
||||
- 三柜台列:属性锻造(三档行:等级/价格/购买钮)、秘宝匣(**迭代 22 实装态呈现,2026-10-12**——见下方「秘宝匣柜台呈现细则」节)、奖励格图鉴(结构位)。
|
||||
- 树面板(图鉴柜台下段,现役程序占位):营地内天赋树的节点购买与 Fork A/B 面切换承载——系统现行事实源=[天赋树](../systems/跨局循环/天赋树.md)(33 节点在役),呈现终稿归 [HUD框架](../systems/表现与支撑/HUD框架.md);信号 `tree_buy_requested` / `tree_fork_toggled`。(本行 2026-10-09 补登——树侧跨文档遗留项清偿:此前本 spec 零树面板登记。)
|
||||
- 底栏:关闭钮 + 操作注记;最近冒险收底栏条带(逐行只读读数)。
|
||||
- 购买意图 `buy_requested(attr)` 经组合根转发 MetaProgression(纯视图 setter 面——零核心写调用、零系统资源写入持有);购买成功 `refresh_camp` 就地重刷(零重建回流)。
|
||||
- 开合与开始层互斥:打开本层前由组合根隐藏开始层(遮挡纪律 2.3——开始覆盖层非模态且树序在后)。
|
||||
| 物件 | 进入 | 备注 |
|
||||
|---|---|---|
|
||||
| 大门(半开,门洞内一条通向远处的小路) | 冒险 | 点大门永远先出确认:有未完冒险=三出口(继续上一段/开始新冒险/取消);无=是否开始新冒险 |
|
||||
| 锻炉·铁砧 | 锻造工坊 | **未解锁=禁用态**(降明度+去饱和) |
|
||||
| 宝箱 | 秘宝匣 | **未解锁=禁用态**(同上) |
|
||||
| 床铺旁笔记本 | 生涯记录 | 生涯页返回钮文案**禁含「营地」字样**(`ui_struct_probe.gd` nojump 禁词表) |
|
||||
| 木桩 | 天赋树 | |
|
||||
| 布告板 | 奖励格图鉴 | 内容冻结未激活,点进看占位——**不是禁用态** |
|
||||
| 篝火 | 离开营地回主菜单 | **必须二次确认**;命中区只含火堆、不含火焰 |
|
||||
| 床铺 | — | 承载件,**不可点** |
|
||||
|
||||
纵深=远景天空与远山/中景围栏与大门/近景篝火与左右物件(作者纵深稿)。坐标草案与验收判据见 [提案](../../../reports/提案-营地场景图美术生成方案-2026-10-22.md) §2.5/§5。
|
||||
|
||||
## 点选反馈(根态)
|
||||
|
||||
悬停=**轮廓亮边 + 浮动**(浮动须整像素吸附)+物件**名牌**(物件下方 8px 居中,FS_HINT 14,对比 ≥4.5:1);按下=位移 1px;禁用=降明度+去饱和;已解锁=常态。**四态零新素材**(全部程序化)。
|
||||
命中区:七件两两不相交、不越出画面、**不侵入顶栏禁区(y ≤ 48)**。
|
||||
|
||||
## 顶栏
|
||||
|
||||
钥石余额常驻画面顶部一行小 HUD 栏(高 48px、全宽窄条、**浮层覆盖在场景图上层,不挤压画面**)。刷新入口=营地刷新单口(卡⑤同口挂接)。
|
||||
|
||||
## 叠层与开合
|
||||
|
||||
各界面开合走模态栈单口,层序入 `LAYER_CONTRACT`。**承载形态(独立全屏页 vs 单一内页切换)与叠层规则归卡④ §9 代拍板域,本 spec 不预设值**;派生规则:独立全屏页=场景根隐藏/单一内页切换=场景根留底(「缩放虚化」为第三形态,禁批内自选)。ESC 浮窗(返回主菜单/设置/退出游戏)归卡⑤。
|
||||
|
||||
## 口径
|
||||
|
||||
- 呈现数据源 = MetaProgression 只读投影经组合根喂入;本层不持有系统资源、不算价。
|
||||
- 退役/封存件呈现语义已随旧目录整体退役消解(探宝罗盘/显影尘/地穴全图卷等状态行已删——迭代 22 旧 12 行删除后目录内零 deferred/retired 态,2026-10-12);
|
||||
- 双入口框架(主菜单入口+局内状态面板只读入口〔2026-10-13 由「暂停层」改名——游戏非实时无暂停语义〕)的需求面归元进度「解锁双入口框架」节;状态面板入口已实装(2026-10-06 迭代 17 卡③〔时名暂停层〕——实机目检待用户,待办清单登记条在册),其呈现面不归本 spec。
|
||||
|
||||
## 秘宝匣柜台呈现细则(迭代 22 实装态,2026-10-12)
|
||||
|
||||
秘宝匣柜台=解锁面+同调装配段两部分(数据投影=`treasure_shop_status` 单点):
|
||||
|
||||
- **解锁面**:逐件一行——钥石购买件带**购买钮**(余额不足=禁用态不隐藏;已解锁=钮消失转已解锁态);条件解锁件带**条件进度呈现**(计数键现值/阈值,如「通关 2/3」);件名后缀·档位(普通/优秀/稀有);悬停浮窗=行 `desc` 直读。
|
||||
- **装配段**(同调装配):装配行带**档位标签**(件档≤格档约束的可见面);未解锁件**禁装**(列表不可选);满位禁选;每件固定占 1 格。
|
||||
- **空目录合法态**:白板档(12 件全未解锁)柜台零可装行=合法态非缺陷(装配面空目录断言 V18 在役)。
|
||||
- **状态面板只读概览**:局内状态面板秘宝匣段=12 行只读清单(解锁态+装配态概览,零写入口——装配只在营地)。
|
||||
- 机制权威=元进度/秘宝.md;本节只锁呈现规则。
|
||||
- 呈现数据源=MetaProgression 只读投影经组合根喂入;本层不持有系统资源、不算价。
|
||||
- 「最近冒险」条带已撤下(卡④ Q4=甲),逐局历史回看归生涯。
|
||||
- 秘宝匣界面内部呈现(解锁面+同调装配段)保留为附录,待该界面立独立 spec 后迁出。
|
||||
@@ -61,7 +61,7 @@
|
||||
3. **兑付反馈**(确认后):选中件效果一行(如「攻击 +1」)+ 另两件已丢弃提示
|
||||
4. ~~同调位替换子交互~~(已随渠道退役:秘宝件自迭代 11① 起不再入三选一池、通关候选 = 纯专长,本屏无道具件候选——替换子交互不于本屏触发;同调装配归营地)
|
||||
|
||||
**禁入清单**(两铁律推导):战斗小循环数据(结算明细、状态效果——留在战斗屏);GP(呈现位已拍板 = 战斗总结结算 + 关卡画面常驻);**钥石增量与累计**(迭代 10 起归战斗总结结算增量行 + 冒险总结结算收束明细——本屏零钥石元素);营地柜台全量;冒险摘要五件事(末关时由相邻域冒险结算屏承载);已达上限件(不出现在候选)。
|
||||
**禁入清单**(两铁律推导):战斗小循环数据(结算明细、状态效果——留在战斗屏);GP(呈现位已拍板 = 战斗总结结算 + 关卡画面常驻);**钥石增量与累计**(迭代 10 起归战斗总结结算增量行 + 冒险总结结算收束明细——本屏零钥石元素);营地界面全量;冒险摘要五件事(末关时由相邻域冒险结算屏承载);已达上限件(不出现在候选)。
|
||||
|
||||
## States & Variants
|
||||
|
||||
|
||||
+4
-3
@@ -22,7 +22,7 @@
|
||||
|
||||
| 术语 | 定义 |
|
||||
|---|---|
|
||||
| 系统资源 | 战斗数值以外、由系统持有并会增减的数值容器——GP(冒险级)/钥石(存档级)/行动点当前值(回合级)与上限(冒险级)/储备行动点(跨轮保留)/刷新存量持久量与当次临时量(冒险级)/生命(冒险级)/主动件充能(冒险级)/时沙暂记(至下一战首轮兑付)。每笔带寿命档(五档轴)与形态(总线/抽屉)。定义见[核心循环](01-核心循环.md)「系统资源」节;旧称「账/账本」「独立资源」「系统数值」一律不再使用。**不属系统资源**:角色的攻击/生命上限/护甲(战斗数值)、增益容器(战斗内状态实例) |
|
||||
| 系统资源 | 战斗数值以外、由系统持有并会增减的数值容器——GP(冒险级)/钥石(存档级)/行动点当前值(回合级)与上限(冒险级)/储备行动点(跨轮保留)/刷新存量持久量与当次临时量(冒险级)/生命(冒险级)/主动件充能(冒险级)/时沙暂记(至下一战首轮兑付)。每笔带寿命档(五档轴)与形态(总线/抽屉)。定义见[核心循环](01-核心循环.md)「系统资源」节;旧称「账/账本」「独立资源」「系统数值」一律不再使用。**不属系统资源**:角色的攻击/生命上限/护甲(战斗数值)、状态池(战斗内状态实例) |
|
||||
| AP(行动点) | 每轮可执行动作的次数,属系统资源(回合级);每轮开始重置为表值(见[行动经济](systems/排雷循环/行动经济.md)) |
|
||||
| RAP(储备行动点) | 停手时把当轮没用完的行动点按转存率存入的储备池,跨轮保留、玩家可见可花 |
|
||||
| 停手 / 转存率 | 主动结束本轮的动作 / 停手时行动点转入 RAP 的比例(现役 1:1,可被秘宝改写) |
|
||||
@@ -40,7 +40,7 @@
|
||||
|---|---|
|
||||
| 秘宝 | 营地装配、整局冒险生效的角色机能件(见[秘宝](systems/跨局循环/秘宝.md)) |
|
||||
| 同调位 | 玩家出征前携带秘宝的装配槽(0 起步、基础 3 格) |
|
||||
| 秘宝匣 | 营地柜台之一:秘宝的解锁(钥石购买/条件解锁)与同调装配面 |
|
||||
| 秘宝匣 | 营地功能界面之一(场景图里点**宝箱**进入):秘宝的解锁(钥石购买/条件解锁)与同调装配面 |
|
||||
| 主动件 / 被动件 | 需要花充能主动使用的秘宝 / 装配后整局持续生效的秘宝 |
|
||||
| 自动兑付 | 无使用动作的秘宝效果兑付形态:满足条件(如试炼镐每开 8 个安全格)自动生效,无玩家发起入口(2026-10-12 用户裁——原「积点兑换钮」手动形态退役) |
|
||||
| 真视使用计数 | 真视类工具累计使用次数的生涯终身计数(存档域 `vision_used`)——信标网络的解锁行为条件(2026-10-12 迭代 22 新增) |
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
| 术语 | 定义 |
|
||||
|---|---|
|
||||
| 锻造工坊 | 营地四柜台之一:武器/护甲各三条锻造路线的升级与出场选择面,钥石单币消费(系统名 v0.3 由「武器锻造」更名;见[锻造工坊](systems/跨局循环/锻造工坊.md)) |
|
||||
| 锻造工坊 | 营地功能界面之一(场景图里点**锻炉·铁砧**进入):武器/护甲各三条锻造路线的升级与出场选择面,钥石单币消费(系统名 v0.3 由「武器锻造」更名;见[锻造工坊](systems/跨局循环/锻造工坊.md)) |
|
||||
| 武器锻造区 / 护甲锻造区 | 锻造工坊工作间内两区,机制层面零顺序门槛(8a 裁定的区名) |
|
||||
| 锻造路线 | 单件武器/单型甲的等级路线(每件独立等级、独立保留);行名统一「件名 + 锻造」= 长剑锻造 / 长枪锻造 / 法杖锻造、轻甲锻造 / 重甲锻造 / 魔法护甲锻造 |
|
||||
| 魔法护甲 | 三型甲之一(= 现役甲域 ward,基础 AC 最低、被普通攻击克);「魔法甲」系笔误、非别名,不单独登记 |
|
||||
@@ -69,6 +69,7 @@
|
||||
| 奇物 | 冒险途中获得的增益总称(当局清零;见[奇物](systems/冒险循环/奇物.md)) |
|
||||
| 专长 | 奇物的分类之一:改写规则的机制件 |
|
||||
| 专长凭证 | 换取一次专长三选一资格的凭证——奖励节点与商店不直接给专长,给凭证(原「凭证」,2026-10-11 用户裁更名) |
|
||||
| 专长获取 | 专长凭证这件物品的**物品名**(卡面与货架标题用);分类术语仍称「专长凭证」。分类术语与物品名分用两个词,互不替代 |
|
||||
| 地图战斗资源 | 战斗域的资源层:每格在装板期摇定资源类型身份(安全格/危险格同一类型池),回合内挖格/封印获取、按动作极性结算正负兑付的一次性收益(原「奖励道具经济」,2026-09-16 用户裁更名;见[地图战斗资源](systems/战斗循环/地图战斗资源.md)) |
|
||||
| 机能件 / 机制件 | 道具的作用二分:不改变结算规则、只扩大操作包络的为机能件(秘宝);使结算产生原本不存在的新行的为机制件(专长)。判定尺见[核心循环](01-核心循环.md)「道具三层职责与分界」节 |
|
||||
|
||||
|
||||
@@ -18,10 +18,10 @@ extends Resource
|
||||
## treasure_item 不在池种内(已出池);heal 恢复件在池(v2.2 令牌池口径)。
|
||||
## 资源凭证入池五件,两件出池:
|
||||
## 同调电池整件删除(呈现层零接线、玩家无分配途径——有 API 有账本唯独没有入口);
|
||||
## 完美保险整件迁出资源类归专长(它给的是规则豁免而非可调动的余量——判据见奇物.md §1.1,
|
||||
## 完美保险整件迁出补给类归专长(它给的是规则豁免而非可调动的余量——判据见奇物.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"] # 第七类(refresh=资源类成员——作为奇物授予的三选一重抽次数,作用对象=三选一界面非角色;见 registry refresh_boundary)
|
||||
"rap", "time_sand"] # 第七类(refresh=补给类成员——作为奇物授予的三选一重抽次数,作用对象=三选一界面非角色;见 registry refresh_boundary)
|
||||
## 令牌档位词表(跨层四级稀有度框架〔01-核心循环 v1.5 档名映射:普通→普通、
|
||||
## 稀有→优秀、罕见→稀有、传说=新增头奖位〕;1 级最稀有=legendary 优先)
|
||||
const TIERS: Array[String] = ["common", "excellent", "rare", "legendary"]
|
||||
@@ -56,7 +56,7 @@ const TIER_QUOTAS := {"common": 70, "excellent": 25, "rare": 7, "legendary": 0}
|
||||
@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]——恢复件(refresh 挤占 2 席位,总量 98 锚不变)
|
||||
@export var curio_quota_refresh_excellent: int = 2 # [0,99]——刷新次数件(资源类成员;provisional 归曲线调参)
|
||||
@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 归调参)
|
||||
|
||||
@@ -83,7 +83,7 @@ pool_shelf = [{
|
||||
"base_price": 5
|
||||
}, {
|
||||
"kind_id": "feat_ticket",
|
||||
"display_name": "奇物门票",
|
||||
"display_name": "专长获取",
|
||||
"base_price": 5
|
||||
}, {
|
||||
"kind_id": "heal",
|
||||
|
||||
@@ -44,7 +44,7 @@ rows = [{
|
||||
"item_id": "wide_scout_band",
|
||||
"display_name": "阔视野带",
|
||||
"dimension_tags": ["info"],
|
||||
"desc": "类型微光范围 8 格→12 格",
|
||||
"desc": "视野照亮范围 8 格→12 格",
|
||||
"tier": "common",
|
||||
"target": "none",
|
||||
"magnitude": 4,
|
||||
|
||||
@@ -16,13 +16,12 @@ var runner_get: Callable # () -> LevelRunner
|
||||
var open_modal: Callable
|
||||
var close_modal: Callable
|
||||
var refresh_presentations: Callable
|
||||
var refresh_resume_button: Callable
|
||||
|
||||
|
||||
func _init(db_ref, meta_get_cb: Callable, save_get_cb: Callable, camp_overlay_ref: CampOverlay,
|
||||
shop_overlay_ref: ShopOverlay, toast_ref: ToastStack, start_overlay_ref: Control,
|
||||
logger_ref, runner_get_cb: Callable, open_modal_cb: Callable, close_modal_cb: Callable,
|
||||
refresh_presentations_cb: Callable, refresh_resume_button_cb: Callable) -> void:
|
||||
refresh_presentations_cb: Callable) -> void:
|
||||
db = db_ref
|
||||
meta_get = meta_get_cb
|
||||
save_get = save_get_cb
|
||||
@@ -35,4 +34,3 @@ func _init(db_ref, meta_get_cb: Callable, save_get_cb: Callable, camp_overlay_re
|
||||
open_modal = open_modal_cb
|
||||
close_modal = close_modal_cb
|
||||
refresh_presentations = refresh_presentations_cb
|
||||
refresh_resume_button = refresh_resume_button_cb
|
||||
@@ -1,6 +1,6 @@
|
||||
## VERTICAL SLICE - NOT FOR PRODUCTION
|
||||
## 营地/商店投影控制器:营地开合/快照投影/锻造·同调·天赋树·Fork 购买切换 + 商店房购买/离开(pool 与 product 双面)。
|
||||
## 信号连接只归组合根(campbtn/camp_overlay/shop_overlay 信号接至本类 on_* 入口);模态栈/呈现刷新/续玩刷新与 runner 现值经组合根回调注入。
|
||||
## 信号连接只归组合根(camp_overlay/shop_overlay 信号接至本类 on_* 入口);模态栈/呈现刷新与 runner 现值经组合根回调注入(续玩刷新已随主菜单三入口化退役——卡② mn7)。
|
||||
## 写调用唯一经 MetaProgression 购买原语与 LevelRunner.buy_*——本类零直写,拒绝兜底 toast 保留原地。
|
||||
extends RefCounted
|
||||
|
||||
@@ -16,7 +16,6 @@ var _runner_get: Callable # () → 关卡推进器现值(组合根 la
|
||||
var _open_modal: Callable
|
||||
var _close_modal: Callable
|
||||
var _refresh_presentations: Callable
|
||||
var _refresh_resume_button: Callable
|
||||
|
||||
|
||||
func _init(ctx: CampFlowContext) -> void:
|
||||
@@ -33,7 +32,6 @@ func _init(ctx: CampFlowContext) -> void:
|
||||
_open_modal = ctx.open_modal
|
||||
_close_modal = ctx.close_modal
|
||||
_refresh_presentations = ctx.refresh_presentations
|
||||
_refresh_resume_button = ctx.refresh_resume_button
|
||||
|
||||
|
||||
# 打开营地(主菜单入口——开合与开始层互斥仿设置面先例:开始覆盖层非模态且树序在后,
|
||||
@@ -52,7 +50,6 @@ func open_camp() -> void:
|
||||
func on_camp_closed() -> void:
|
||||
_close_modal.call(camp_overlay) # 模态栈单口
|
||||
start_overlay.visible = true
|
||||
_refresh_resume_button.call() # 回菜单按断点在档态刷新
|
||||
_refresh_presentations.call() # 关闭后刷新顶栏(工坊解锁可能变了余额侧读数面)
|
||||
|
||||
|
||||
|
||||
@@ -162,8 +162,8 @@ func _curio_card_texts(candidates: Array) -> Array:
|
||||
var cid := "%s|%s|%s" % [kind, tier, rid]
|
||||
var text := ""
|
||||
if kind == "feat_ticket":
|
||||
text = "奇物门票
|
||||
选定即开一次奇物三选一(T5 门票——拿到即开不进持有集)"
|
||||
text = "专长获取
|
||||
选中或买下后立刻开一次专长三选一"
|
||||
elif kind == "relic":
|
||||
text = Narrator.feat_card_text(db.feat_row(rid))
|
||||
else:
|
||||
|
||||
+12
-41
@@ -67,8 +67,7 @@ var meta: MetaProgressionCore:
|
||||
var logger = null # 试玩日志器(JSONL 持久化 + 卡死诊断转储——呈现层组件)
|
||||
var _debug_entry := false # 调试会话门控(写死=true——恒开:启动即开浮窗+两屏角标点亮;_ready 赋值)
|
||||
var _seed_edit: LineEdit
|
||||
var _resume_btn: Button # 继续上局按钮句柄(有断点才亮)
|
||||
var confirm_dialog: ConfirmDialog # 通用确认弹窗(新冒险互斥确认弹窗化)
|
||||
var confirm_dialog: ConfirmDialog # 通用确认弹窗(消费方编排——现行消费方=选档删档确认;新冒险互斥确认已随卡②主菜单撤出,归卡④大门)
|
||||
var _confirm_consumer := "" # 确认弹窗消费方状态量(契约 3 编排——open 前设、分派后清)
|
||||
var _confirm_consumer_slot := 0 # 消费方附随槽号(delete_slot 消费方专用)
|
||||
var curio_overlay: CurioPickOverlay # 提升三选一覆盖层(level-clear.md v2 选择面承载;奖励节点共用)
|
||||
@@ -195,7 +194,6 @@ func _ready() -> void:
|
||||
_debug.battle_ready.connect(_on_debug_battle_ready)
|
||||
_build_ui()
|
||||
_begin_session(false) # 闲时会话(gp_ledger 等探针注入面自 _ready 起恒在——ui_probe 合成段时序)
|
||||
_refresh_resume_button() # 启动读盘后按断点在档态点亮「继续上局」
|
||||
_start_overlay.visible = true
|
||||
_debug_entry = true # 调试入口门控写死=true(不读 DS_DEBUG 环境变量;发布前清)
|
||||
debug_badge.visible = _debug_entry # 浮层角标可见性须门控落定后赋值(构建/连接在 _build_ui)
|
||||
@@ -315,10 +313,9 @@ func _build_ui() -> void:
|
||||
curio_overlay.continue_pressed.connect(_bonus.on_continue)
|
||||
curio_overlay.refresh_requested.connect(_bonus.on_refresh)
|
||||
|
||||
# 菜单屏接线(句柄经屏壳暴露)
|
||||
_menu_screen.lvbtn.pressed.connect(_start_adventure_from_menu)
|
||||
_menu_screen.resumebtn.pressed.connect(_resume_from_menu) # 续玩入口
|
||||
_resume_btn = _menu_screen.resumebtn
|
||||
# 菜单屏接线(句柄经屏壳暴露;三入口化——进入存档/设置/退出游戏,卡② mn3:
|
||||
# 进入存档钮落点=卡③选档层 _open_save_select,点击链在此闭环)
|
||||
_menu_screen.entersavebtn.pressed.connect(_open_save_select)
|
||||
# 调试入口=UI 最顶层全局浮层角标(任何 UI 不遮挡——菜单/战斗/地图三枚
|
||||
# 屏内角标由全局浮层承载;连接归组合根,树序/登记面见 LAYER_CONTRACT 末位)
|
||||
debug_badge = UiAssembler.build_debug_badge(self)
|
||||
@@ -328,7 +325,7 @@ func _build_ui() -> void:
|
||||
# 购买写调用唯一经 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)) # 构造参数收拢 context
|
||||
_open_modal, _close_modal, _refresh_presentations)) # 构造参数收拢 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)
|
||||
@@ -340,8 +337,6 @@ func _build_ui() -> void:
|
||||
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) # 生涯页一级入口(营地同组)
|
||||
_menu_screen.settingsbtn.pressed.connect(_open_settings) # 最小设置面入口
|
||||
_menu_screen.quitbtn.pressed.connect(_quit_game) # 退出游戏提级一级菜单
|
||||
|
||||
@@ -488,32 +483,23 @@ func _input_locked() -> bool:
|
||||
# ==================== 冒险模式入口(唯一试玩入口)====================
|
||||
|
||||
func _start_adventure_from_menu() -> void:
|
||||
# 互斥确认弹窗化:有断点时开新冒险弹实底确认框,
|
||||
# 「开新冒险」提交(弃旧断点+写盘)/「取消」回菜单
|
||||
if save_manager.has_breakpoint():
|
||||
var bp: Dictionary[Variant, Variant] = save_manager.breakpoint_snapshot()
|
||||
_confirm_consumer = "new_adventure" # 消费方编排(契约 3——open 前设消费方)
|
||||
confirm_dialog.open("已有未完冒险(第 %d 关)——开新冒险将覆盖旧断点" % maxi(1, int(bp.get("level_index", 1))),
|
||||
"开新冒险", "取消")
|
||||
return
|
||||
# 主菜单「开始冒险」钮已随三入口化撤出(卡② mn6——主菜单侧断点互斥确认链同步摘除,
|
||||
# 弹窗本体与两分支逻辑归卡④大门承接)。本函数为探针直调中间态保留(mn10——冒险段探针
|
||||
# 直调位点逐个登记实现报告「已知中间态」;卡④到位后由大门两分支换代)。无激活态写盘拒绝
|
||||
# 由卡① sv3 承接(结算不落盘)。
|
||||
_start_overlay.visible = false
|
||||
_start_adventure()
|
||||
|
||||
|
||||
# 确认弹窗分派(卡③ 契约 3):按 _confirm_consumer 路由——"new_adventure"=现役新冒险确认
|
||||
#(行为与原 _on_confirm_new_adventure 逐句等价)、"delete_slot"=卡③ 删档确认(确认才删、
|
||||
# 取消只关窗——裁决 3);分派面禁写死单一目标(卡④ 到位接入第三消费方不返工)。
|
||||
# 确认弹窗分派(卡③ 契约 3):按 _confirm_consumer 路由——"delete_slot"=卡③ 删档确认
|
||||
#(确认才删、取消只关窗——裁决 3)。"new_adventure" 消费方已随卡② 主菜单确认链摘除退役
|
||||
#(mn6/V5——主菜单零确认残留),分派机制保留(卡④ 到位接入第三消费方不返工)。
|
||||
func _on_confirm_accepted() -> void:
|
||||
confirm_dialog.close()
|
||||
match _confirm_consumer:
|
||||
"delete_slot":
|
||||
save_manager.delete_slot(_confirm_consumer_slot)
|
||||
save_select_overlay.open_save_select(_save_select_data()) # 就地刷新(该槽回空态)
|
||||
"new_adventure":
|
||||
save_manager.clear_breakpoint() # 提交即弃旧断点(覆盖语义对盘面即时生效)
|
||||
save_manager.write_to_disk()
|
||||
_start_overlay.visible = false
|
||||
_start_adventure()
|
||||
_confirm_consumer = ""
|
||||
|
||||
|
||||
@@ -529,17 +515,6 @@ func _quit_game() -> void:
|
||||
get_tree().quit()
|
||||
|
||||
|
||||
# 继续上局按钮可见性 = 断点在档态(启动读盘后与每次回开始菜单刷新)
|
||||
func _refresh_resume_button() -> void:
|
||||
if _resume_btn == null:
|
||||
return
|
||||
var has: bool = save_manager.has_breakpoint()
|
||||
_resume_btn.visible = has
|
||||
if has:
|
||||
var bp: Dictionary[Variant, Variant] = save_manager.breakpoint_snapshot()
|
||||
_resume_btn.text = "▶ 继续上局(第 %d 关 · 自最近停点恢复)" % maxi(1, int(bp.get("level_index", 1)))
|
||||
|
||||
|
||||
# 继续上局(resume_adventure 的消费入口):断点重建至最近停点
|
||||
func _resume_from_menu() -> void:
|
||||
if not save_manager.has_breakpoint():
|
||||
@@ -727,7 +702,6 @@ func _on_battle_end_continue() -> void:
|
||||
_begin_session(false)
|
||||
debug_overlay.reset_sliders()
|
||||
_start_overlay.visible = true
|
||||
_refresh_resume_button() # 回菜单按断点在档态刷新(收束后已清=隐藏)
|
||||
_refresh_presentations()
|
||||
|
||||
|
||||
@@ -1086,7 +1060,6 @@ func _open_settings() -> void:
|
||||
func _on_settings_closed() -> void:
|
||||
_close_modal(settings_overlay) # 模态栈单口
|
||||
_start_overlay.visible = true
|
||||
_refresh_resume_button()
|
||||
|
||||
|
||||
# ---- 局内状态面板·只读(入口角标在两屏装配段;开合与数据喂入归组合根)----
|
||||
@@ -1124,7 +1097,6 @@ func _open_career() -> void:
|
||||
func _on_career_closed() -> void:
|
||||
_close_modal(career_overlay) # 模态栈单口
|
||||
_start_overlay.visible = true
|
||||
_refresh_resume_button()
|
||||
|
||||
|
||||
# 生涯页快照投影(只读同源——每次开层实时读 SaveManager 计数访问器 + MetaProgression 访问器
|
||||
@@ -1164,7 +1136,6 @@ func _open_save_select() -> void:
|
||||
func _on_save_select_closed() -> void:
|
||||
_close_modal(save_select_overlay) # 模态栈单口
|
||||
_start_overlay.visible = true
|
||||
_refresh_resume_button()
|
||||
|
||||
|
||||
# 槽数据快照(只读同源——每次开层实时经卡① 窥视 API 逐槽取数拼装;零写调用)。
|
||||
|
||||
@@ -8,10 +8,7 @@ extends Control
|
||||
|
||||
var start_overlay: Control # 全屏菜单层(原 main._start_overlay——组合根可见性开关句柄不变)
|
||||
var box: VBoxContainer
|
||||
var lvbtn: Button
|
||||
var resumebtn: Button
|
||||
var campbtn: Button
|
||||
var careerbtn: Button
|
||||
var entersavebtn: Button
|
||||
var settingsbtn: Button
|
||||
var quitbtn: Button
|
||||
|
||||
@@ -23,9 +20,6 @@ func _ready() -> void:
|
||||
var start: Dictionary[Variant, Variant] = UiAssembler.build_start_overlay(self, get_node("/root/ConfigDB"))
|
||||
start_overlay = start.overlay
|
||||
box = start.box
|
||||
lvbtn = start.lvbtn
|
||||
resumebtn = start.resumebtn
|
||||
campbtn = start.campbtn
|
||||
careerbtn = start.careerbtn
|
||||
entersavebtn = start.entersavebtn
|
||||
settingsbtn = start.settingsbtn
|
||||
quitbtn = start.quitbtn
|
||||
@@ -86,11 +86,11 @@ static func build_overlays(host: Control, db) -> Dictionary:
|
||||
}
|
||||
|
||||
|
||||
# 开始覆盖层(返回 {overlay, box, lvbtn, resumebtn, campbtn, careerbtn, settingsbtn, quitbtn}——按钮接线归组合根;
|
||||
# 开始覆盖层(返回 {overlay, box, entersavebtn, settingsbtn, quitbtn}——按钮接线归组合根;
|
||||
# 随机种子/数值调整板/两层调试三散件不在主按钮组,收进调试浮窗——
|
||||
# 调试入口=UI 最顶层全局浮层角标(build_debug_badge,本层零调试入口)
|
||||
# 布局=双列 VBox(左操作 56% + 右舞台);按钮动词化+悬停解释
|
||||
#(解释全迁 tooltip,G5);lvbtn 为主操作钮(烛光黄 CANDLE);右列=立绘看台。**界面禁玩法文字墙
|
||||
#(解释全迁 tooltip,G5);entersavebtn 为主操作钮(烛光黄 CANDLE——主菜单三入口化唯一进度入口);右列=立绘看台。**界面禁玩法文字墙
|
||||
#(教学内容归 Beta 帮助手册〔教学引导定稿 P4 丙〕)**;本层无玩法速览牌;
|
||||
# tooltip 主题归全局主题单点(禁在 root 挂程序化 tooltip 主题)。
|
||||
# 返回键集如首行所列,接线归组合根)
|
||||
@@ -124,31 +124,15 @@ static func build_start_overlay(host: Control, db = null) -> Dictionary:
|
||||
box.add_child(title)
|
||||
box.add_child(HSeparator.new())
|
||||
|
||||
# 组帽·冒险
|
||||
box.add_child(UiKit.label("── 冒 险 ──",UiKit.FS_CAPTION, false, UiKit.WARM_FAINT))
|
||||
# 唯一试玩入口 = 正式「开始冒险」(三关序列);无单关测试直入口
|
||||
var resumebtn := UiKit.primary_button("▶ 继续上局") # 有断点才亮(可见性与关数文案归组合根刷新);主操作钮对齐 demo
|
||||
resumebtn.tooltip_text = "自最近停点恢复"
|
||||
resumebtn.visible = false
|
||||
box.add_child(resumebtn)
|
||||
# 主操作语义对齐 demo(有档时「继续上局」才是首动作=主黄钮,
|
||||
# 「开始冒险」=常规石钮;tooltip 保留)
|
||||
var lvbtn := UiKit.button("▶ 开始冒险")
|
||||
lvbtn.tooltip_text = "三关连探:地精洞窟 → 幽暗地域 → 灰矮人矿城"
|
||||
box.add_child(lvbtn)
|
||||
|
||||
# 组帽·营地与系统
|
||||
box.add_child(UiKit.label("── 营地与系统 ──",UiKit.FS_CAPTION, false, UiKit.WARM_FAINT))
|
||||
var campbtn := UiKit.verb_button("营地", UiKit.TEX_ICON_KEYSTONE, "永久强化:钥石换永久属性——跨局成长账本") # 主菜单营地入口
|
||||
box.add_child(campbtn)
|
||||
# 生涯页一级入口(与营地平级;页=局外只读跨局汇总,零跳转零购买)
|
||||
var careerbtn := UiKit.button("生涯")
|
||||
careerbtn.tooltip_text = "跨局生涯汇总:总局数 / 通关局数 / Boss 击杀 / 钥石余额 / 三柜台解锁概览(只读)"
|
||||
box.add_child(careerbtn)
|
||||
var settingsbtn := UiKit.button("设置") # 最小设置面入口
|
||||
# 三入口(主菜单三入口化——营地交互重做卡②,用户裁决 1:进入存档/设置/退出游戏;
|
||||
# 组帽双撤——冒险组帽组内零钮退化态不留、「营地与系统」帽指称失义,追认单留痕)
|
||||
var entersavebtn := UiKit.primary_button("进入存档") # 主操作钮(唯一进度入口)
|
||||
entersavebtn.tooltip_text = "选择一个存档位进入(新档 / 进档 / 删档)"
|
||||
box.add_child(entersavebtn)
|
||||
var settingsbtn := UiKit.button("设置") # 最小设置面入口(行为零变化——契约 2)
|
||||
settingsbtn.tooltip_text = "音量 / 全屏 / 减动效"
|
||||
box.add_child(settingsbtn)
|
||||
# 退出游戏与设置同层并行——只在一级菜单出现
|
||||
# 退出游戏与设置同层并行——只在一级菜单出现(行为零变化——契约 2)
|
||||
var quitbtn := UiKit.button("退出游戏")
|
||||
box.add_child(quitbtn)
|
||||
|
||||
@@ -190,8 +174,7 @@ static func build_start_overlay(host: Control, db = null) -> Dictionary:
|
||||
right.add_child(stage)
|
||||
|
||||
return {"overlay": overlay, "box": box,
|
||||
"lvbtn": lvbtn, "resumebtn": resumebtn,
|
||||
"campbtn": campbtn, "careerbtn": careerbtn,
|
||||
"entersavebtn": entersavebtn,
|
||||
"settingsbtn": settingsbtn, "quitbtn": quitbtn}
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ signal buy_requested(product_id: String) # legacy=product_id / pool=kind_id(
|
||||
signal leave_pressed
|
||||
|
||||
const ATTR_LABELS := {"atk": "攻击", "max_hp": "生命上限", "armor_class": "护甲"} # 档位文案轴(数据契约 attr 词表)
|
||||
const KIND_LABELS := {"attack": "攻击", "max_hp": "生命上限", "armor": "护甲", "ap": "行动点"} # 货架件值文案轴(共享池 kind 词表——迭代 11 第②批)
|
||||
const KIND_LABELS := {"attack": "攻击", "max_hp": "生命上限", "armor": "护甲", "ap": "行动点", "heal": "回复", "feat_ticket": "专长凭证"} # 货架件值文案轴(共享池 kind 词表——迭代 11 第②批)
|
||||
|
||||
var _gp_label: Label
|
||||
var _refresh_btn: Button # M6 呈现位——MC-1 起由 set_refresh_display 投喂启用
|
||||
@@ -204,8 +204,12 @@ func _build_shelf_card(holder: Control, c: Dictionary) -> Dictionary:
|
||||
icon_key = UiKit.TEX_ICON_SHIELD
|
||||
elif kl.contains("ap") or kl.contains("action") or kl.contains("pouch"):
|
||||
icon_key = UiKit.TEX_ICON_POUCH
|
||||
var card := UiKit.bcard(String(c.get("display_name", kind)),
|
||||
"%s %+d(本冒险)" % [String(KIND_LABELS.get(kind, kind)), int(c.get("value", 0))],
|
||||
var body := ""
|
||||
if kind == "feat_ticket":
|
||||
body = "开一次专长三选一"
|
||||
else:
|
||||
body = "%s %+d(本冒险)" % [String(KIND_LABELS.get(kind, kind)), int(c.get("value", 0))]
|
||||
var card := UiKit.bcard(String(c.get("display_name", kind)), body,
|
||||
UiKit.tg_band(kl), icon_key, # 类型色带单点(N4c/Q4 甲——货架与三选一同源判定,原固定默认带)
|
||||
"%d ◈" % int(c.get("price", 0)), String(KIND_LABELS.get(kind, kind)))
|
||||
var btn := UiKit.button("购买")
|
||||
|
||||
@@ -806,7 +806,7 @@ class BCard:
|
||||
|
||||
func add_footer(c: Control) -> void:
|
||||
body.add_child(c)
|
||||
body.move_child(c, body.get_child_index(foot_l))
|
||||
body.move_child(c, foot_l.get_index())
|
||||
|
||||
|
||||
static func bcard(title: String, desc: String, band: Color, icon_path: String, price := "", footnote := "") -> BCard:
|
||||
|
||||
@@ -28,23 +28,19 @@ func _ready() -> void:
|
||||
main = load("res://presentation/main.tscn").instantiate()
|
||||
add_child(main)
|
||||
await get_tree().process_frame
|
||||
ProbeUiUtil.isolate_save(main, "fx_shot_probe", false, true, false)
|
||||
ProbeUiUtil.isolate_save(main, "fx_shot_probe", false, true, true) # 末参=swap_save(卡②签名换代——原 refresh_resume 槽位语义退役)
|
||||
# 隔离档即时应用(真实档 fullscreen 态会污染抓帧尺寸〔shot_probe 同款口径〕)
|
||||
main.settings_store.apply()
|
||||
for i in 8:
|
||||
await get_tree().process_frame # UI 装配完成等足帧(canvas_item 空引用窗口)
|
||||
var lvbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "开始冒险", "contains")
|
||||
if lvbtn == null:
|
||||
_fail("开始冒险按钮缺失")
|
||||
return
|
||||
lvbtn.pressed.emit()
|
||||
main._start_adventure_from_menu() # 函数直调中间态(卡② mn10——开始冒险钮已撤)
|
||||
# 等关卡画面出图(choices_presented 异步到达——最多 3s 轮询)
|
||||
for i in 60:
|
||||
await get_tree().process_frame
|
||||
if main.level_screen != null and main.level_screen.visible:
|
||||
break
|
||||
if main.level_screen == null or not main.level_screen.visible:
|
||||
_fail("关卡画面未出现(lvbtn 路径)")
|
||||
_fail("关卡画面未出现(函数直调中间态路径)")
|
||||
return
|
||||
for i in 5:
|
||||
await get_tree().process_frame
|
||||
|
||||
@@ -89,14 +89,14 @@ static func _text_match(text: String, needle: String, mode: String) -> bool:
|
||||
# ── 存档/设置/元进度三面隔离(探针禁碰真实档 user://save.json——SaveManager 路径注入纪律) ──
|
||||
# tag = 隔离档名(不带扩展名,如 "smoke_input_probe_save"——各探针后缀保持不变);先删后建防陈旧档泄入。
|
||||
# mark_first_done = 对齐真实档游玩史口径(模板抽签路径不变);with_settings = 连设置面换注
|
||||
#(隔离 cfg 名 = <tag>_settings.cfg,与被收口探针原文件名逐一同名);refresh_resume = 组合根
|
||||
#(隔离 cfg 名 = <tag>_settings.cfg,与被收口探针原文件名逐一同名);
|
||||
# 「继续上局」按钮重刷;swap_save = 是否换注全局 SaveManager(营地先行段只换 meta 侧不换 SaveManager)。
|
||||
# 返回隔离 SaveManager 实例(调用方常需后续直读余额/重读档)。
|
||||
# SaveManager/MetaProgression 是 autoload 单例——隔离面走单例原地重置
|
||||
#(attach_path 沿 RngService.set_master_seed 先例;MetaProgression 持 save 引用透传,
|
||||
# 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):
|
||||
swap_save: bool = true): # refresh_resume 参数已随卡② _refresh_resume_button 删除退役(mn7)
|
||||
var save_path := "user://%s.json" % tag
|
||||
for p in [save_path, save_path + ".tmp", "user://%s_settings.cfg" % tag]:
|
||||
if FileAccess.file_exists(p):
|
||||
@@ -116,6 +116,22 @@ static func isolate_save(main, tag: String, mark_first_done: bool = false, with_
|
||||
main.get_node("/root/MetaProgression").save = iso # 只换 meta 侧(营地段语义)——SaveManager 全局不动
|
||||
if with_settings:
|
||||
main.settings_store = SettingsStoreScript.new("user://%s_settings.cfg" % tag)
|
||||
if refresh_resume:
|
||||
main._refresh_resume_button()
|
||||
return iso
|
||||
|
||||
# 营地经进档开层(卡② mn9 新路径——campbtn 已撤;槽模板注入隔离命名空间,防碰真实槽
|
||||
# user://save_slot_N.json——真实档红线)。创建=激活=暂行开营地(卡③ Q3 乙落点);
|
||||
# 驱动后写盘目标=隔离槽文件(持久化断言读 user://<tag>_slot_1.json)。返回 false=新档钮缺失(驱动中断)。
|
||||
static func open_camp_via_savesel(main, tag: String) -> bool:
|
||||
var sm = main.get_node("/root/SaveManager")
|
||||
sm.attach_slot_template("user://%s_slot_%%d.json" % tag)
|
||||
for i in range(1, 4): # 夹具清场——空槽起(陈旧槽文件会翻有档态、新档钮缺席)
|
||||
for suf in ["", ".tmp", ".corrupt.bak"]:
|
||||
var sp: String = sm.slot_path(i) + suf
|
||||
if FileAccess.file_exists(sp):
|
||||
DirAccess.remove_absolute(sp)
|
||||
main._open_save_select()
|
||||
var new_btn: Button = main.save_select_overlay._new_btns.get(1)
|
||||
if new_btn == null:
|
||||
return false
|
||||
new_btn.pressed.emit() # 真实按钮信号路径 → _on_save_select_new → create_slot+open_camp
|
||||
return true
|
||||
@@ -21,7 +21,7 @@ func _ready() -> void:
|
||||
await get_tree().process_frame
|
||||
|
||||
# 隔离存档(全 worktree 共享同一份 user://save.json——探针必须换注,禁碰真实档)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_screen_flow", false, false, false, false)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_screen_flow", false, false, false)
|
||||
await get_tree().process_frame
|
||||
|
||||
await _step_boot_menu()
|
||||
@@ -107,11 +107,10 @@ func _step_boot_menu() -> void:
|
||||
|
||||
# ---- ② 菜单 → 营地(真实按钮信号路径)----
|
||||
func _step_menu_to_camp() -> void:
|
||||
var campbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "营地", "prefix")
|
||||
if campbtn == null:
|
||||
_problems.append("②菜单→营地:营地按钮缺失")
|
||||
# 营地经进档开层(卡② mn9 新路径——campbtn 已撤;槽模板注入隔离命名空间)
|
||||
if not ProbeUiUtil.open_camp_via_savesel(main, "smoke_screen_flow_camp"):
|
||||
_problems.append("②菜单→营地:选档层新档钮缺失(新路径驱动中断)")
|
||||
return
|
||||
campbtn.pressed.emit()
|
||||
await _frames()
|
||||
_expect_exclusive("②菜单→营地", "营地")
|
||||
|
||||
@@ -123,6 +122,8 @@ func _step_camp_back_to_menu() -> void:
|
||||
return
|
||||
main.camp_overlay.closed.emit()
|
||||
await _frames()
|
||||
main._on_save_select_closed() # 关闭被栈还原的选档层(动线序中间态——卡④ 换代点)
|
||||
await _frames()
|
||||
_expect_exclusive("③营地→菜单(回退)", "菜单")
|
||||
|
||||
|
||||
@@ -130,9 +131,13 @@ func _step_camp_back_to_menu() -> void:
|
||||
# ---- 选档界面开合(卡③ sl10):函数直调开层(「进入存档」钮归卡② mn3)→屏级互斥采样→
|
||||
# 返回钮真实信号路径关闭→ESC 语境不响应(卡⑤ 契约 2 范围外——零实现即断言)。----
|
||||
func _step_save_select_open_back() -> void:
|
||||
ProbeUiUtil.isolate_save(main, "smoke_screen_flow_savesel", false, false, false, true)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_screen_flow_savesel", false, false, true)
|
||||
main.save_manager.attach_slot_template("user://smoke_screen_flow_savesel_slot_%d.json")
|
||||
main._open_save_select()
|
||||
var esb: Button = ProbeUiUtil.find_button(main._start_overlay, "进入存档", "prefix")
|
||||
if esb == null:
|
||||
_problems.append("[savesel] mn3 进入存档钮缺失(卡② 交付物)")
|
||||
return
|
||||
esb.pressed.emit() # 真实按钮信号路径 → _open_save_select(卡② mn3 点击链——卡③ 直调中间态就此闭环)
|
||||
await get_tree().process_frame
|
||||
var seals := _screen_seals()
|
||||
if not main.save_select_overlay.visible or not seals_check_single(seals):
|
||||
@@ -172,13 +177,8 @@ func seals_check_single(f: Dictionary) -> bool:
|
||||
|
||||
|
||||
func _step_menu_to_adventure() -> void:
|
||||
var lvbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "开始冒险", "contains")
|
||||
if lvbtn == null:
|
||||
lvbtn = ProbeUiUtil.find_button(main._start_overlay, "冒险", "contains")
|
||||
if lvbtn == null:
|
||||
_problems.append("④菜单→冒险:开始冒险按钮缺失")
|
||||
return
|
||||
lvbtn.pressed.emit()
|
||||
# 开始冒险钮已随三入口化撤出——函数直调中间态(卡② mn10;卡④ 大门两分支换代)
|
||||
main._start_adventure_from_menu()
|
||||
await _frames(3)
|
||||
_expect_exclusive("④菜单→冒险", "冒险")
|
||||
_expect_adventure_seal("④菜单→冒险", true)
|
||||
|
||||
+15
-22
@@ -5,7 +5,7 @@
|
||||
# Godot_console.exe --path . res://smoke/shot_probe.tscn -- <输出目录>
|
||||
# 流程 = 真实按钮信号路径驱动(ui_click_probe 同款;存档/设置/元进度三面换注隔离档——禁碰真实档,
|
||||
# 坑册「断点写盘随 save_manager 引用走」教训同款覆盖):菜单(启动态)→ 设置面(settingsbtn
|
||||
# 真实信号路径)→ 生涯页(careerbtn 同款)→ 营地(campbtn)→ 关卡画面(lvbtn→停点出图)→
|
||||
# 真实信号路径)→ 生涯页(函数直调中间态——卡② mn10)→ 营地(进档开层新路径——mn9)→ 关卡画面(函数直调中间态→停点出图)→
|
||||
# 战斗(level_screen.press_candidate(0) 真实选路提交)→ 状态面板(地图屏状态角标真实信号路径)。
|
||||
# 每屏双帧 + frame_post_draw 同步后抓 get_viewport().get_texture(),PNG 落输出目录;
|
||||
# 最小自检 = 七件存在且非零字节(像素方差断言归 tools/shot_checker.py——B 档骨架分工)。
|
||||
@@ -100,16 +100,13 @@ func _ready() -> void:
|
||||
else:
|
||||
set_close.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
# ①c 生涯页(careerbtn 真实信号路径,ui_struct_probe 同款入口链)
|
||||
var careerbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "生涯", "prefix")
|
||||
if careerbtn == null:
|
||||
_problems.append("生涯入口缺失(开始层 careerbtn)")
|
||||
else:
|
||||
careerbtn.pressed.emit()
|
||||
# ①c 生涯页(函数直调中间态——卡② mn10:careerbtn 已撤,卡④ 笔记本改挂前无 UI 路径)
|
||||
if true:
|
||||
main._open_career()
|
||||
for i in 3:
|
||||
await get_tree().process_frame
|
||||
if not main.career_overlay.visible or main._start_overlay.visible:
|
||||
_problems.append("生涯页未打开或开始层未隐藏(careerbtn 路径)")
|
||||
_problems.append("生涯页未打开或开始层未隐藏(函数直调中间态路径)")
|
||||
else:
|
||||
_meta["career_title"] = ProbeUiUtil.label_rect(main.career_overlay, "生 涯")
|
||||
await _snap("career")
|
||||
@@ -122,26 +119,22 @@ func _ready() -> void:
|
||||
await get_tree().process_frame
|
||||
if main.career_overlay.visible or not main._start_overlay.visible:
|
||||
_problems.append("生涯页关闭后页未隐藏或开始层未恢复")
|
||||
# ② 营地
|
||||
var campbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "营地", "contains")
|
||||
if campbtn == null:
|
||||
_problems.append("营地入口缺失(开始层 campbtn)")
|
||||
# ② 营地(进档开层新路径——卡② mn9;槽模板注入隔离命名空间)
|
||||
if not ProbeUiUtil.open_camp_via_savesel(main, "smoke_shot_probe_camp"):
|
||||
_problems.append("营地入口缺失(选档层新档钮——新路径驱动中断)")
|
||||
else:
|
||||
campbtn.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
await _snap("camp")
|
||||
var close_btn: Button = ProbeUiUtil.find_button(main.camp_overlay, "关闭营地", "contains")
|
||||
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)")
|
||||
else:
|
||||
lvbtn.pressed.emit()
|
||||
for i in 4:
|
||||
await get_tree().process_frame
|
||||
main._on_save_select_closed() # 关闭被栈还原的选档层(动线序中间态)
|
||||
await get_tree().process_frame
|
||||
# ③ 关卡画面(开始冒险→停点出图——入口停点语义;函数直调中间态 mn10)
|
||||
main._start_adventure_from_menu()
|
||||
for i in 4:
|
||||
await get_tree().process_frame
|
||||
await _snap("level")
|
||||
# GP 常驻徽章断言(读数=runner.gp 现值,刷新=写路径回执后重查〔open_choices〕)
|
||||
var gp_label: Label = ProbeUiUtil.find_label(main.level_screen, "◈ ")
|
||||
@@ -190,7 +183,7 @@ func _ready() -> void:
|
||||
if main.status_panel.visible:
|
||||
_problems.append("状态面板关闭后未隐藏(继续钮路径)")
|
||||
else:
|
||||
_problems.append("关卡画面未出现(lvbtn 路径)")
|
||||
_problems.append("关卡画面未出现(函数直调中间态路径)")
|
||||
# ── 几何元数据落盘(shot_checker 取样坐标源) ──
|
||||
var mf := FileAccess.open(out_dir.path_join("shot_meta.json"), FileAccess.WRITE)
|
||||
if mf != null:
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -20,17 +20,13 @@ func _ready() -> void:
|
||||
# 存档/设置两面隔离(ProbeUiUtil.isolate_save 现行事实源,先删后建防陈旧档泄入)——
|
||||
# 隔离面走 attach_path 原地重置 autoload 单例:组合根 save_manager/meta 是getter-only
|
||||
# 读视图,直接赋值无效,隔离必须落在单例上。
|
||||
ProbeUiUtil.isolate_save(main, "t17_defer_probe", false, true, false)
|
||||
ProbeUiUtil.isolate_save(main, "t17_defer_probe", false, true, true) # 末参=swap_save(卡②签名换代——原 refresh_resume 槽位语义退役)
|
||||
# 本探针验证完整动画档的演播后排窗——强制 motion_scale=1.0(隔离档替换在 boot 后,
|
||||
# 减动效已随真档 settings.cfg 应用于引擎态;减动效档=consume_now 快路、开窗即时,另属语义)
|
||||
UiKit.motion_scale = 1.0
|
||||
for i in 8:
|
||||
await get_tree().process_frame
|
||||
var lvbtn: Button = _find_button_by_sub(main._start_overlay, "开始冒险")
|
||||
if lvbtn == null:
|
||||
_fail("开始冒险按钮缺失")
|
||||
return
|
||||
lvbtn.pressed.emit()
|
||||
main._start_adventure_from_menu() # 函数直调中间态(卡② mn10——开始冒险钮已撤)
|
||||
for i in 60:
|
||||
await get_tree().process_frame
|
||||
if main.level_screen != null and main.level_screen.visible:
|
||||
|
||||
@@ -49,20 +49,20 @@ func _ready() -> void:
|
||||
# 任何 UI 不遮挡;浮层角标遮挡判据见设置面段)
|
||||
if main.debug_overlay.visible:
|
||||
_problems.append("调试浮窗 boot 自动开(菜单优先失守)")
|
||||
# ---- 营地购买合成点击路径(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):
|
||||
DirAccess.remove_absolute(p0) # 重置档段前清场兜底(营地/设置段不触该档——防陈旧断点泄入后续段)
|
||||
var iso_c = ProbeUiUtil.isolate_save(main, "smoke_click_probe_camp", false, false, false, false)
|
||||
var campbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "营地", "prefix")
|
||||
if campbtn == null:
|
||||
_problems.append("营地入口按钮缺失(开始层 campbtn)")
|
||||
# swap=true(整链换注——购买写盘经 autoload 落隔离槽文件,与下方持久化核验同源;
|
||||
# 原 swap=false 形态的写盘走 iso 实例旧路径,与槽文件断言不同源——卡② mn9 换代)
|
||||
var iso_c = ProbeUiUtil.isolate_save(main, "smoke_click_probe_camp", false, false, true)
|
||||
if not ProbeUiUtil.open_camp_via_savesel(main, "smoke_click_probe_camp"):
|
||||
_problems.append("营地入口缺失(选档层新档钮——mn9 新路径驱动中断)")
|
||||
else:
|
||||
campbtn.pressed.emit() # 真实按钮信号路径 → 组合根 _open_camp
|
||||
await get_tree().process_frame
|
||||
if not main.camp_overlay.visible:
|
||||
_problems.append("营地层未打开(点击路径)")
|
||||
_problems.append("营地层未打开(进档开层新路径)")
|
||||
elif main.camp_overlay._tree_buy_btns.is_empty():
|
||||
_problems.append("树淬炼柜台购买钮缺失(点击路径——四柜台重排后树=主界面)")
|
||||
else:
|
||||
@@ -83,7 +83,7 @@ func _ready() -> void:
|
||||
await get_tree().process_frame
|
||||
if int(iso_c.keystone_balance()) != bal_before - price:
|
||||
_problems.append("营地树购买未出账(%d→%d 应 −%d)" % [bal_before, iso_c.keystone_balance(), price])
|
||||
var iso_chk = load("res://core/save_manager.gd").new("user://smoke_click_probe_camp.json")
|
||||
var iso_chk = load("res://core/save_manager.gd").new("user://smoke_click_probe_camp_slot_1.json")
|
||||
iso_chk.load_from_disk()
|
||||
if int(iso_chk.tree_level("sp_hp")) != 1:
|
||||
_problems.append("营地树购买未持久(reload 后级 != 1)")
|
||||
@@ -117,12 +117,14 @@ func _ready() -> void:
|
||||
else:
|
||||
side_b.pressed.emit() # 合成切态点击 → _on_camp_fork_toggle → meta.tree_toggle_fork
|
||||
await get_tree().process_frame
|
||||
var iso_fk = load("res://core/save_manager.gd").new("user://smoke_click_probe_camp.json")
|
||||
var iso_fk = load("res://core/save_manager.gd").new("user://smoke_click_probe_camp_slot_1.json")
|
||||
iso_fk.load_from_disk()
|
||||
if String(iso_fk.fork_side("fg_posture")) != "b":
|
||||
_problems.append("Fork 切态未持久(reload 后激活态 != b)")
|
||||
main._on_camp_closed()
|
||||
await get_tree().process_frame
|
||||
main._on_save_select_closed() # 关闭被栈还原的选档层(动线序中间态——卡④ 换代点)
|
||||
await get_tree().process_frame
|
||||
if main.camp_overlay.visible or not main._start_overlay.visible:
|
||||
_problems.append("营地关闭后未恢复开始层")
|
||||
# ---- 选档界面行为走查(迭代 33 卡③):sl5 空槽新档链/sl6 有档槽进档链/sl7 删档二次确认双路径
|
||||
@@ -134,7 +136,7 @@ func _ready() -> void:
|
||||
var cp: String = csel_tpl % i + suf
|
||||
if FileAccess.file_exists(cp):
|
||||
DirAccess.remove_absolute(cp)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_click_probe_savesel", true, false, false, true)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_click_probe_savesel", true, false, true)
|
||||
main.save_manager.attach_slot_template(csel_tpl)
|
||||
var f_c2 := FileAccess.open(csel_tpl % 2, FileAccess.WRITE)
|
||||
f_c2.store_string(JSON.stringify({"version": 7, "meta": {"keystone_balance": 100,
|
||||
@@ -290,11 +292,9 @@ func _ready() -> void:
|
||||
_problems.append("设置面仍含退出游戏按钮(二轮 D1——只在一级菜单出现)")
|
||||
# ---- 生涯页段(入口点击链+关闭回返,真实按钮信号路径;本页只读零写,
|
||||
# 值断言归冒烟投影段与 ui_struct 结构族,此处只验开合路径与零跳转)----
|
||||
var career_btn: Button = ProbeUiUtil.find_button(main._start_overlay, "生涯", "prefix")
|
||||
if career_btn == null:
|
||||
_problems.append("生涯入口按钮缺失(开始层 careerbtn)")
|
||||
else:
|
||||
career_btn.pressed.emit() # 真实按钮信号路径 → 组合根 _open_career
|
||||
# 生涯页驱动=函数直调中间态(卡② mn10——careerbtn 已撤,卡④ 笔记本改挂前无 UI 路径)
|
||||
if true:
|
||||
main._open_career()
|
||||
await get_tree().process_frame
|
||||
if not main.career_overlay.visible or main._start_overlay.visible:
|
||||
_problems.append("生涯页未打开(点击路径)")
|
||||
@@ -316,12 +316,7 @@ func _ready() -> void:
|
||||
if main.career_overlay.visible or not main._start_overlay.visible:
|
||||
_problems.append("生涯页关闭后未恢复开始层")
|
||||
# 换回全新零档(营地购买态不泄入后续冒险段——确定性;档案残留下次段首清理兜底)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_click_probe_reset", true, false, true) # 零档换注 + 继续上局按钮重刷(原三行样板收口)
|
||||
var resume_btn0: Button = ProbeUiUtil.find_button(main._start_overlay, "▶ 继续上局", "prefix")
|
||||
if resume_btn0 == null:
|
||||
_problems.append("继续上局按钮缺失(开始层 resumebtn——装配器)")
|
||||
elif resume_btn0.visible:
|
||||
_problems.append("无断点态继续上局按钮未隐藏(卡② AC①——新档合法空态)")
|
||||
ProbeUiUtil.isolate_save(main, "smoke_click_probe_reset", true, false, true) # 零档换注(继续上局钮已随三入口化撤出——卡② mn8)
|
||||
main.debug_overlay.set_sliders(400, 200) # 高加成保 L1 可通关——L2 岔路选路段只能经冒险推进到达(单关直入口退役)
|
||||
main.debug_overlay.seed_edit.text = "42" # 种子钉死(种子框默认为空=非首局随机,行为走查确定性禁依赖默认分支)
|
||||
var t1 := Time.get_ticks_msec()
|
||||
@@ -555,73 +550,9 @@ func _ready() -> void:
|
||||
# 战败态前提失配——记录不计 problem(返回路径已实机目检)。
|
||||
if not _closed_via_abandon:
|
||||
_problems.append("断点段:终局返回未回开始菜单")
|
||||
var resume_btn: Button = ProbeUiUtil.find_button(main._start_overlay, "▶ 继续上局", "prefix")
|
||||
if resume_btn != null and resume_btn.visible:
|
||||
_problems.append("断点段:退出清断点后继续上局按钮未隐藏(卡②/T3 AC③)")
|
||||
# ② 中断→续玩:新冒险达入口停点=断点在档 → 合成回菜单(模拟关游戏重开)→ 按钮点亮 → 点击恢复至停点
|
||||
var lv_btn: Button = ProbeUiUtil.find_button(main._start_overlay, "▶ 开始冒险", "prefix")
|
||||
if lv_btn == null or resume_btn == null:
|
||||
_problems.append("断点段:开始冒险/继续上局按钮缺失")
|
||||
else:
|
||||
lv_btn.pressed.emit() # 无断点态单击直启(不触发二次确认)
|
||||
await get_tree().process_frame
|
||||
if not main.level_screen.visible:
|
||||
if not _closed_via_abandon:
|
||||
_problems.append("断点段:无断点开新冒险未达入口停点")
|
||||
else:
|
||||
iso_chk.load_from_disk()
|
||||
if not iso_chk.has_breakpoint():
|
||||
_problems.append("断点段:入口停点断点未写盘(卡①写面失守)")
|
||||
var cand_before: Array = main.run_scope.runner.next_candidate_ids()
|
||||
# 合成「关游戏重开回菜单」(探针专用——真实路径无此入口;断点已在盘)
|
||||
main._exit_level_screen()
|
||||
main._start_overlay.visible = true
|
||||
main.run_scope.adventure = null
|
||||
main._refresh_resume_button()
|
||||
await get_tree().process_frame
|
||||
if not resume_btn.visible:
|
||||
_problems.append("断点段:有断点态继续上局按钮未点亮(卡② AC②前置)")
|
||||
else:
|
||||
resume_btn.pressed.emit() # 真实按钮信号路径 → _resume_from_menu → resume_adventure
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
if main.run_scope.adventure == null or main.run_scope.runner == null or not main.level_screen.visible:
|
||||
_problems.append("断点段:续玩未恢复至停点(关卡画面未现)")
|
||||
else:
|
||||
var cand_after: Array = main.run_scope.runner.next_candidate_ids()
|
||||
if cand_after.size() != cand_before.size() or (cand_after.size() > 0 and int(cand_after[0]) != int(cand_before[0])):
|
||||
_problems.append("断点段:续玩候选与中断前不一致(停点重建失准)")
|
||||
if not iso_chk.load_from_disk() or not iso_chk.has_breakpoint():
|
||||
_problems.append("断点段:续玩误清断点(只在三结局清)")
|
||||
# ③ 互斥确认弹窗(二轮修改批 A):断点在档点开始冒险 → 弹确认框;取消=回菜单;开新冒险=提交
|
||||
main._exit_level_screen()
|
||||
main._start_overlay.visible = true
|
||||
main.run_scope.adventure = null
|
||||
main._refresh_resume_button()
|
||||
await get_tree().process_frame
|
||||
lv_btn.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
if not main.confirm_dialog.is_open() or main.run_scope.adventure != null:
|
||||
_problems.append("断点段:有断点点开始冒险未弹确认框(二轮 A 失守)")
|
||||
var cancel_btn: Button = ProbeUiUtil.find_button(main.confirm_dialog, "取消", "contains")
|
||||
if cancel_btn == null:
|
||||
_problems.append("断点段:确认框取消按钮缺失")
|
||||
else:
|
||||
cancel_btn.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
if main.confirm_dialog.is_open() or main.run_scope.adventure != null or not main._start_overlay.visible:
|
||||
_problems.append("断点段:取消未回开始菜单(二轮 A)")
|
||||
lv_btn.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
var confirm_btn: Button = ProbeUiUtil.find_button(main.confirm_dialog, "开新冒险", "contains")
|
||||
if confirm_btn == null:
|
||||
_problems.append("断点段:确认框开新冒险按钮缺失")
|
||||
else:
|
||||
confirm_btn.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
if main.run_scope.adventure == null or main._start_overlay.visible or main.confirm_dialog.is_open():
|
||||
_problems.append("断点段:确认开新冒险后未开局(二轮 A)")
|
||||
# ②③ 中断→续玩全链+互斥确认两分支:随三入口化撤出(卡② §7.2 申报——断点确认探针段移交
|
||||
# 卡④大门 T5 接收,两头登记禁静默删除;续玩钮已退役,主菜单确认链已摘 mn6)。
|
||||
# ① 战斗收口断点写盘断言保留(上方——冒险流直调中间态 mn10)。
|
||||
print("[click_probe] 循环退出(done=%s budget=%s)问题=%d" % [
|
||||
str(_done), str(action_budget), _problems.size()])
|
||||
for p in _problems:
|
||||
|
||||
@@ -23,15 +23,13 @@ func _ready() -> void:
|
||||
# ---- 营地覆盖层(主菜单入口/开合/余额文案/购买禁用态;
|
||||
# 隔离存档换注 main.meta 保确定性(禁碰真实档 user://save.json——SaveManager 路径注入纪律;
|
||||
# 营地先行段只换 meta 不换 save_manager——冒险段换注零档在前)----
|
||||
ProbeUiUtil.isolate_save(main, "smoke_ui_probe_camp", false, false, false, false)
|
||||
var campbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "营地", "prefix")
|
||||
if campbtn == null:
|
||||
problems.append("营地入口按钮缺失(开始层 campbtn)")
|
||||
ProbeUiUtil.isolate_save(main, "smoke_ui_probe_camp", false, false, false)
|
||||
if not ProbeUiUtil.open_camp_via_savesel(main, "smoke_ui_probe_camp"):
|
||||
problems.append("营地入口缺失(选档层新档钮——mn9 新路径驱动中断)")
|
||||
else:
|
||||
campbtn.pressed.emit() # 合成信号路径(真实按钮 → 组合根 _open_camp)
|
||||
await get_tree().process_frame
|
||||
if not main.camp_overlay.visible:
|
||||
problems.append("营地层未打开(campbtn 路径)")
|
||||
problems.append("营地层未打开(进档开层新路径)")
|
||||
elif main._start_overlay.visible:
|
||||
problems.append("营地层打开时开始层未隐藏(规范 2.3 遮挡纪律)")
|
||||
else:
|
||||
@@ -51,6 +49,8 @@ func _ready() -> void:
|
||||
problems.append("秘宝匣柜台行数错误(%d ≠ 12——迭代 22 秘宝批换代)" % main.camp_overlay._workshop_rows.size())
|
||||
main._on_camp_closed()
|
||||
await get_tree().process_frame
|
||||
main._on_save_select_closed() # 关闭被栈还原的选档层(动线序中间态——卡④ 换代点)
|
||||
await get_tree().process_frame
|
||||
if main.camp_overlay.visible or not main._start_overlay.visible:
|
||||
problems.append("营地关闭后未恢复开始层(开合往返失守)")
|
||||
# 换回全新零档(营地段购买态不泄入后续冒险段——确定性;先删后建防陈旧档泄入)
|
||||
|
||||
@@ -38,35 +38,32 @@ func _ready() -> void:
|
||||
main._on_settings_closed()
|
||||
_settle()
|
||||
|
||||
var campbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "营地", "prefix")
|
||||
if campbtn != null:
|
||||
campbtn.pressed.emit()
|
||||
if not ProbeUiUtil.open_camp_via_savesel(main, "smoke_ui_struct_probe_menu"):
|
||||
problems.append("[camp] 营地入口缺失(选档层新档钮——mn9 新路径驱动中断)")
|
||||
else:
|
||||
_settle()
|
||||
await _audit("camp", [main.camp_overlay])
|
||||
main._on_camp_closed()
|
||||
_settle()
|
||||
else:
|
||||
problems.append("[camp] 营地入口按钮缺失(驱动中断)")
|
||||
main._on_save_select_closed() # 关闭被栈还原的选档层(动线序中间态——卡④ 换代点)
|
||||
_settle()
|
||||
|
||||
# ---- 生涯页:入口点击链(合成点击真路径=pressed.emit→组合根 _open_career)→
|
||||
# 结构断言族→只读巡检(契约 3)+零动效契约+零跳转契约(提纲 P4 甲)→组合根真实路径关闭。
|
||||
#(登记序/树序契约统一在全模态 _modal_registry_contract——boot 段跑)----
|
||||
var careerbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "生涯", "prefix")
|
||||
if careerbtn != null:
|
||||
careerbtn.pressed.emit()
|
||||
_settle()
|
||||
if not main.career_overlay.visible or main._start_overlay.visible:
|
||||
problems.append("[career] 生涯页未打开或开始层未隐藏(入口点击链断裂)")
|
||||
await _audit("career", [main.career_overlay])
|
||||
_career_readonly_contract(main)
|
||||
_career_zero_motion_contract(main)
|
||||
_career_nojump_contract(main)
|
||||
main._on_career_closed()
|
||||
_settle()
|
||||
if main.career_overlay.visible or not main._start_overlay.visible:
|
||||
problems.append("[career] 关闭后页未隐藏或开始层未恢复(模态栈单口失守)")
|
||||
else:
|
||||
problems.append("[career] 生涯入口按钮缺失(开始层 careerbtn)")
|
||||
# 生涯页驱动=函数直调中间态(卡② mn9/mn10——careerbtn 已撤,卡④ 营地笔记本改挂前无 UI 路径)
|
||||
main._open_career()
|
||||
_settle()
|
||||
if not main.career_overlay.visible or main._start_overlay.visible:
|
||||
problems.append("[career] 生涯页未打开或开始层未隐藏(函数直调中间态断裂)")
|
||||
await _audit("career", [main.career_overlay])
|
||||
_career_readonly_contract(main)
|
||||
_career_zero_motion_contract(main)
|
||||
_career_nojump_contract(main)
|
||||
main._on_career_closed()
|
||||
_settle()
|
||||
if main.career_overlay.visible or not main._start_overlay.visible:
|
||||
problems.append("[career] 关闭后页未隐藏或开始层未恢复(模态栈单口失守)")
|
||||
|
||||
# ---- 选档界面(迭代 33 卡③):函数直调开层(「进入存档」钮归卡② mn3——点击链在卡② 承接),
|
||||
# sl1 三槽呈现/sl2 摘要三项逐槽读数/sl3 摘要禁项/sl4 操作集二分/sl9 重启链不预选。
|
||||
@@ -192,12 +189,43 @@ func _ready() -> void:
|
||||
_settle()
|
||||
await _audit("shop", [main.shop_overlay])
|
||||
|
||||
# ---- 术语传导:货架卡与三选一卡片的玩家面文案(物品名=专长获取、分类=专长凭证)
|
||||
main.shop_overlay.open_shelf([
|
||||
{"kind_id": "feat_ticket", "display_name": "专长获取", "value": 0, "price": 5},
|
||||
{"kind_id": "heal", "display_name": "应急回复", "value": 6, "price": 5},
|
||||
], 20)
|
||||
_settle()
|
||||
var ticket_row: Dictionary = main.shop_overlay._shelf_rows[0]
|
||||
if String(main.db.shop_pool_row("feat_ticket").get("display_name", "")) != "专长获取":
|
||||
problems.append("[shop_term] shop.tres 专长凭证件名未换代(现=%s)" % String(main.db.shop_pool_row("feat_ticket").get("display_name", "")))
|
||||
if ticket_row.card.name_l.text != "专长获取":
|
||||
problems.append("[shop_term] 专长凭证件名未用物品名「专长获取」(现=%s)" % ticket_row.card.name_l.text)
|
||||
if ticket_row.btn.get_parent() != ticket_row.card.body or ticket_row.btn.get_index() >= ticket_row.card.foot_l.get_index():
|
||||
problems.append("[shop_term] 购买钮未落在底注之前(add_footer 落位失败)")
|
||||
if ticket_row.card.desc_l.text != "开一次专长三选一":
|
||||
problems.append("[shop_term] 专长凭证件描述未用规范流程句(现=%s)" % ticket_row.card.desc_l.text)
|
||||
if ticket_row.card.foot_l.text != "专长凭证":
|
||||
problems.append("[shop_term] 专长凭证件分类标注未用「专长凭证」(现=%s)" % ticket_row.card.foot_l.text)
|
||||
var heal_row: Dictionary = main.shop_overlay._shelf_rows[1]
|
||||
if heal_row.card.desc_l.text != "回复 +6(本冒险)":
|
||||
problems.append("[shop_term] 回复件描述漏了 heal 词表(现=%s)" % heal_row.card.desc_l.text)
|
||||
if heal_row.card.foot_l.text != "回复":
|
||||
problems.append("[shop_term] 回复件分类标注落到英文 kind(现=%s)" % heal_row.card.foot_l.text)
|
||||
var ticket_texts: Array = main._bonus._curio_card_texts([{"kind": "feat_ticket", "tier": "excellent"}])
|
||||
var ticket_text := String((ticket_texts[0] as Dictionary).get("text", ""))
|
||||
var ticket_lines := ticket_text.replace("\r\n", "\n").split("\n")
|
||||
if ticket_lines.size() < 2 or ticket_lines[0] != "专长获取" or not ticket_lines[1].contains("专长三选一"):
|
||||
problems.append("[curio_term] 专长凭证三选一卡未用物品名/规范流程句(现=%s)" % ticket_text)
|
||||
if ticket_text.contains("门票") or ticket_text.contains("T5") or ticket_text.contains("持有集") or ticket_text.contains("奇物三选一"):
|
||||
problems.append("[curio_term] 专长凭证三选一卡残留退役词/内部任务号(现=%s)" % ticket_text)
|
||||
main.shop_overlay.visible = false
|
||||
_settle()
|
||||
|
||||
# ---- ⑦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)
|
||||
main.save_manager.set_breakpoint(_resume_bp_fixture())
|
||||
main._refresh_resume_button()
|
||||
main.run_scope.runner = null # 全新启动等价态(真机=菜单直进续玩,无前置冒险——runner 从未赋值;探针此前推流会残留旧 runner)
|
||||
main._resume_from_menu()
|
||||
_settle(8)
|
||||
|
||||
@@ -89,7 +89,7 @@ func _ready() -> void:
|
||||
# (攻击 ×2 / 生命 +50%)——旧缺陷(残留值被当基线再乘)在 encounter 参数链上同样被抓获
|
||||
# 存档隔离(停点断点写盘随 main.save_manager;探针禁碰真实档,同族探针隔离纪律;
|
||||
# isolate_save 先删后建——上次运行的残留断点会触发互斥确认早退)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_tune_probe_save", true, false, false)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_tune_probe_save", true, false, true) # 末参=swap_save(卡②签名换代——断点写盘经 autoload 落隔离档)
|
||||
main.debug_overlay.set_sliders(100, 50)
|
||||
main.debug_overlay.press_apply_for_probe()
|
||||
main.debug_overlay.seed_edit.text = "42" # 种子钉死(18卡⑦审计🔴——空框=非首局随机,显式优先经真实路径断言 master_seed)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 312 KiB After Width: | Height: | Size: 312 KiB |
+51
-32
@@ -55,8 +55,8 @@ func _smoke_scene_split() -> void:
|
||||
var menu: Node = load("res://presentation/scenes/menu_screen.tscn").instantiate()
|
||||
root.add_child(menu)
|
||||
await process_frame
|
||||
check(menu.start_overlay != null and menu.lvbtn != null and menu.resumebtn != null and menu.campbtn != null and menu.careerbtn != null and menu.settingsbtn != null and menu.quitbtn != null,
|
||||
"V2 菜单屏壳独立实例化(start_overlay+操作组六钮在位)")
|
||||
check(menu.start_overlay != null and menu.entersavebtn != null and menu.settingsbtn != null and menu.quitbtn != null,
|
||||
"V2 菜单屏壳独立实例化(start_overlay+操作组三钮在位——主菜单三入口化)〔卡② mn1〕")
|
||||
check(menu.start_overlay.visible, "V2 菜单层默认可见(非模态全屏态)")
|
||||
check(menu.mouse_filter == Control.MOUSE_FILTER_IGNORE, "V2 屏壳根零鼠标截获(IGNORE——全屏 STOP 壳吃输入病灶回归闸)")
|
||||
menu.queue_free()
|
||||
@@ -136,6 +136,15 @@ func _topmost_visible_layer(main: Node) -> Node:
|
||||
|
||||
# ---- boot 链路时序后置条件(启动态六断言;只立行为可判断言,不造假时序)----
|
||||
# (自 game/smoke/smoke_all.gd 剪切迁入——label 与 cond 逐字原样,断言迁移批 B G1)
|
||||
|
||||
func _count_visible_buttons(node: Node) -> int:
|
||||
var n := 1 if (node is Button and node.visible) else 0
|
||||
for c in node.get_children():
|
||||
n += _count_visible_buttons(c)
|
||||
return n
|
||||
|
||||
|
||||
# ---- boot 链路时序后置条件(启动态六断言;只立行为可判断言,不造假时序)----
|
||||
func _smoke_boot_chain() -> void:
|
||||
print("--- 迭代28 T2 boot 链路时序后置条件(V2:六断言)---")
|
||||
var main: Node = load("res://presentation/main.tscn").instantiate()
|
||||
@@ -163,9 +172,8 @@ func _smoke_boot_chain() -> void:
|
||||
var sm = main.get_node("/root/SaveManager")
|
||||
# ④-1 boot 路径:启动态钉死(卡① sv2)——boot 无激活态、断点在档恒否,续玩钮恒隐
|
||||
#(原「按钮态==真实档断点态」关系判据随启动态换代改写:test-conventions §9.5 申报在案,卡② mn8 再承接)
|
||||
check(not sm.has_breakpoint() and not main._resume_btn.visible,
|
||||
"V2d 续玩钮 boot 态恒隐(无激活态——启动态不隐式激活;断点在档=%s visible=%s)〔装配生命批 V2·卡① sv2 改写〕" % [
|
||||
str(sm.has_breakpoint()), str(main._resume_btn.visible)])
|
||||
check(not sm.has_breakpoint(),
|
||||
"V2d 续玩钮族退役·boot 无断点在档(启动态不隐式激活——卡① sv2 钉死;恒隐判据随钮退役由本断言+V2d 三钮在位承接)〔装配生命批 V2·卡② mn8 改写〕")
|
||||
# ④-1b 启动态三断言+旧单档迁移不变式(卡① sv2/sv12——真实 autoload boot 链)
|
||||
check(sm.active_slot() == 0 and not sm.has_write_target(),
|
||||
"V2-s1 boot 后无激活态(active_slot=0、写盘目标空)〔卡① sv2〕")
|
||||
@@ -175,24 +183,20 @@ func _smoke_boot_chain() -> void:
|
||||
"V2-s3 boot 无激活写盘拒绝(write_to_disk=false 生产入口)〔卡① sv3〕")
|
||||
check(not (FileAccess.file_exists("user://save.json") and not FileAccess.file_exists(sm.slot_path(1))),
|
||||
"V2-s4 旧单档迁移不变式(旧档在则槽 1 必在——Q1 甲一次性迁移已发生)〔卡① sv12〕")
|
||||
# ④-2 隔离新档双向(attach 原地重置——绝不碰真实档 user://save.json;刷新单口与 boot 路径同源)
|
||||
# ④-2 三钮承接(卡② mn8——V2d 续玩钮族随钮退役废止:钮可见性联动面由卡① V2-s 启动态断言与
|
||||
# sv11 attach 语义段承接;attach 原地重置语义保持——绝不碰真实档 user://save.json)
|
||||
for p in ["user://smoke_boot_chain.json", "user://smoke_boot_chain.json.tmp"]:
|
||||
if FileAccess.file_exists(p):
|
||||
DirAccess.remove_absolute(p)
|
||||
sm.attach_path("user://smoke_boot_chain.json")
|
||||
main._refresh_resume_button()
|
||||
check(not sm.has_breakpoint() and not main._resume_btn.visible,
|
||||
"V2d 续玩钮·无断点态隐藏(visible=%s has_breakpoint=%s)〔装配生命批 V2〕" % [
|
||||
str(main._resume_btn.visible), str(sm.has_breakpoint())])
|
||||
sm.set_breakpoint({"level_index": 2, "master_seed": 42})
|
||||
main._refresh_resume_button()
|
||||
check(sm.has_breakpoint() and main._resume_btn.visible,
|
||||
"V2d 续玩钮·有断点态可见(visible=%s has_breakpoint=%s)〔装配生命批 V2〕" % [
|
||||
str(main._resume_btn.visible), str(sm.has_breakpoint())])
|
||||
sm.clear_breakpoint()
|
||||
main._refresh_resume_button()
|
||||
check(not main._resume_btn.visible,
|
||||
"V2d 续玩钮·清断点后回隐藏(visible=%s)〔装配生命批 V2〕" % str(main._resume_btn.visible))
|
||||
check(main._menu_screen.entersavebtn != null and main._menu_screen.settingsbtn != null
|
||||
and main._menu_screen.quitbtn != null,
|
||||
"V2d 三钮在位·进入存档/设置/退出游戏(续玩钮族退役后主菜单操作组承接)〔卡② mn1/mn8〕")
|
||||
for old_btn in ["lvbtn", "resumebtn", "campbtn", "careerbtn"]:
|
||||
check(not (old_btn in main._menu_screen),
|
||||
"V2d 四旧钮句柄零命中·%s(彻底撤出——禁隐藏态禁置灰态残留)〔卡② mn2〕" % old_btn)
|
||||
check(_count_visible_buttons(main._start_overlay) == 3,
|
||||
"V2d 渲染面可见按钮计数==3(旧钮接回即红——渲染面锚,句柄缝盲区闭合)〔卡② mn1/mn2〕")
|
||||
# ⑤ 闲时会话(_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〕")
|
||||
@@ -209,8 +213,10 @@ func _smoke_boot_chain() -> void:
|
||||
DirAccess.remove_absolute(p)
|
||||
|
||||
|
||||
# ---- 会话物化断言(V3——两连局复位/无脏状态残留)----
|
||||
# (自 game/smoke/smoke_all.gd 剪切迁入——label 与 cond 逐字原样,断言迁移批 B G1)
|
||||
# ---- 生命周期存活性矩阵(九阶段×五引用面;驱动复用 V3 debug seed 开局路径+
|
||||
# _auto_play_round 活战斗模式+ui_struct resume 夹具模式,不另起点击链)----
|
||||
# 阶段映射说明:计划书十阶段中「开局停点」与「地图选路」在本现行流程同为关卡画面停点态
|
||||
#(level_started→choices_presented 同步到达,无可观测中间态)——合并为 V3b 一处断言。
|
||||
func _smoke_run_lifecycle() -> void:
|
||||
print("--- 迭代27 T1 会话物化(V3:两连局复位+脏状态不残留)---")
|
||||
var main: Node = load("res://presentation/main.tscn").instantiate()
|
||||
@@ -346,9 +352,6 @@ func _stage_faces(main: Node, tag: String, adv: String, run: String, set: String
|
||||
"end_open":
|
||||
if main._end_overlay.is_open() != bool(extra[k]):
|
||||
bad += " _end_overlay.is_open 应=%s" % str(extra[k])
|
||||
"resume_vis":
|
||||
if main._resume_btn.visible != bool(extra[k]):
|
||||
bad += " _resume_btn.visible 应=%s" % str(extra[k])
|
||||
"start_vis":
|
||||
if main._start_overlay.visible != bool(extra[k]):
|
||||
bad += " _start_overlay.visible 应=%s" % str(extra[k])
|
||||
@@ -380,11 +383,10 @@ func _smoke_lifecycle_matrix() -> void:
|
||||
if FileAccess.file_exists(p):
|
||||
DirAccess.remove_absolute(p)
|
||||
sm.attach_path("user://smoke_lifecycle.json")
|
||||
main._refresh_resume_button() # 隔离后重同步(boot 时按钮态反映的是真实档——T2 已断 boot 关系,此处按隔离档定基)
|
||||
main.debug_overlay.seed_edit.text = "42"
|
||||
# 阶段①闲时
|
||||
await _stage_faces(main, "V3a 闲时", "null", "null", "null",
|
||||
{"mf_start": true, "mf_inter": false, "mf_rows_empty": true, "start_vis": true, "resume_vis": false})
|
||||
{"mf_start": true, "mf_inter": false, "mf_rows_empty": true, "start_vis": true})
|
||||
# 阶段②开局停点(地图选路停点态)
|
||||
main._start_adventure_from_menu()
|
||||
for i in range(6):
|
||||
@@ -469,11 +471,18 @@ func _smoke_lifecycle_matrix() -> void:
|
||||
elif modal_name == "career":
|
||||
main._open_career()
|
||||
elif modal_name == "camp":
|
||||
var campbtn: Button = main._menu_screen.campbtn
|
||||
if campbtn == null:
|
||||
check(false, "V3g 营地入口缺失(驱动中断)〔装配生命批 V3〕")
|
||||
# 营地经进档开层(卡② mn9 新路径——campbtn 已撤);槽模板注入隔离命名空间
|
||||
#(防碰真实槽 user://save_slot_N.json——真实档红线),营地闭合后恢复生命周期 attach 写盘目标
|
||||
#(卡① sv3 无激活拒写——后续阶段断点写盘依赖)
|
||||
sm.attach_slot_template("user://smoke_lifecycle_slot_%d.json")
|
||||
main._open_save_select()
|
||||
for i in range(2):
|
||||
await process_frame
|
||||
var ssel_new: Button = main.save_select_overlay._new_btns.get(1)
|
||||
if ssel_new == null:
|
||||
check(false, "V3g 营地入口缺失(选档层新档钮驱动中断)〔装配生命批 V3〕")
|
||||
continue
|
||||
campbtn.pressed.emit()
|
||||
ssel_new.pressed.emit() # 创建=激活=暂行开营地(卡③ Q3 乙落点)
|
||||
else:
|
||||
main._show_debug_overlay()
|
||||
for i in range(4):
|
||||
@@ -494,6 +503,15 @@ func _smoke_lifecycle_matrix() -> void:
|
||||
await process_frame
|
||||
await _stage_faces(main, "V3g 模态合·%s" % modal_name, "null", "null", "null",
|
||||
{"mf_start": true, "start_vis": true})
|
||||
if modal_name == "camp":
|
||||
main._on_save_select_closed() # 关闭被栈还原的选档层(动线序中间态——卡④ 换代点)
|
||||
for i in range(2):
|
||||
await process_frame
|
||||
sm.attach_path("user://smoke_lifecycle.json") # 恢复生命周期写盘目标
|
||||
for suf in ["", ".tmp"]:
|
||||
var slot_p: String = "user://smoke_lifecycle_slot_1.json" + suf
|
||||
if FileAccess.file_exists(slot_p):
|
||||
DirAccess.remove_absolute(slot_p)
|
||||
# 阶段⑧两连局(第二局全新会话——旧局对象不复用、脏态零残留)
|
||||
var first_adv = main.run_scope.adventure
|
||||
main.debug_overlay.seed_edit.text = "43"
|
||||
@@ -528,8 +546,6 @@ func _smoke_lifecycle_matrix() -> void:
|
||||
"keystone_drops": [], "bonus_taken": {},
|
||||
"bonus_pending": {"candidates": [{"kind": "heal", "tier": "common"}], "payload": {"gp_dropped": 0}},
|
||||
})
|
||||
main._refresh_resume_button()
|
||||
check(main._resume_btn.visible, "V3i 续玩钮·断点在档可见〔装配生命批 V3〕")
|
||||
var idle_scope = main.run_scope
|
||||
main._resume_from_menu()
|
||||
check(main.run_scope != idle_scope and main.run_scope.is_inside_tree(),
|
||||
@@ -543,3 +559,6 @@ func _smoke_lifecycle_matrix() -> void:
|
||||
"user://smoke_lifecycle_resume.json", "user://smoke_lifecycle_resume.json.tmp"]:
|
||||
if FileAccess.file_exists(p):
|
||||
DirAccess.remove_absolute(p)
|
||||
|
||||
|
||||
# 引用面快照(五承载物的会话相关面+恒活面——逐个调用现值回调,与 run_scope 成员并采)
|
||||
@@ -27,7 +27,6 @@ func _init() -> void:
|
||||
var sm = main.get_node("/root/SaveManager")
|
||||
sm.attach_path("user://test_pacing_queue_save.json")
|
||||
sm.mark_first_adventure_done()
|
||||
main._refresh_resume_button()
|
||||
# 行信号计数器(真实信号路径旁挂计数——零触碰既有接线)
|
||||
var rows_seen: Array = []
|
||||
main._start_adventure_from_menu()
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
# 迭代 33 代拍板追认单(2026-10-21)
|
||||
|
||||
> 累积文档:各卡 §9 白名单内的代拍项随卡施工留痕于此;用户在会话中追认(veto 窗口开放至用户明示)。授权性质:卡片审问阶段的预授权执行,本单为备案确认,非事后授权。
|
||||
|
||||
## 卡① 存档制数据层改造批
|
||||
|
||||
| # | 代拍项(卡片 §9 条目) | 取法 | 约束核对 | veto 影响 |
|
||||
|---|---|---|---|---|
|
||||
| 1 | 槽位存储机制与文件命名(§9-1) | **三文件制** `user://save_slot_1/2/3.json` | 每槽与现行 v7 逐键同构 ✓;迁移链按槽独立成立 ✓(sv9 冒烟段);坏档兜底按槽 ✓(.corrupt.bak 按槽文件名派生);槽 1 禁复用 `user://save.json` ✓(独立派生名) | 改单文件三键=承载面重写,回炉 T1 |
|
||||
| 2 | 启动激活态机制(§9-2) | **纯内存态,不持久化**(`_active_slot` 字段) | 卡③ Q1 裁甲「每轮回选档」——裁甲则本条按卡① 契约作废持久化需求 ✓ | 若用户改裁卡③ Q1 乙,本条需重开(激活位持久化补建) |
|
||||
| 3 | 类 API 命名与文件落点(§9-3) | `slot_path`/`active_slot`/`has_write_target`/`activate_slot`/`create_slot`/`delete_slot`/`peek_slot_summary`/`peek_summary_at`/`attach_slot_template`;承载面不拆(696 行单文件) | 词族 save_slot_*/activate_*/peek_* ✓;禁裸名 slots(同调位已占)✓;测试隔离注入口镜像 attach_path 哲学 | 改名=接口面重排,牵连卡③ 消费面 |
|
||||
| 4 | 删档边界(§9-4) | 激活槽可删;删后回合法空态+指针连清除;**`.corrupt.bak` 损坏备份不追删**(用户数据留盘可考,同槽再损坏时兜底流按槽覆盖同名备份) | 禁崩禁误写 ✓;激活态生命周期终点=显式清除/进程结束/该槽被删 ✓;回主菜单不清除 ✓(内存态) | 追删备份=删档语义扩一步,改 delete_slot 一处 |
|
||||
| 5 | 提交切分与 worktree 命名(§9-5) | worktree `iter33card1-save`/分支 `iter33-card1-save`;两笔:T1+T2+T3 实现(6a7c2575)+T4 产出物 | 单 worktree 单分支 ✓;定义面(迭代行/卡片)不入本批提交 ✓ | 仅过程命名,veto 无实质影响 |
|
||||
| 6 | Q1 甲执行取法(实现取法,超出字面处陈明) | 旧档迁移取「字节级原样搬运、零解析零改造」——损坏/高版本旧档字节原样落槽 1(「原样落入槽 1」字面成立),读取时兜底/拒读链接管;未走 §8 L3 呈报(意外形态不再触发承诺失效) | 不静默丢数据 ✓;源改名 `.migrated.bak` 留痕不删 ✓;失败源保留重试 ✓ | 若用户裁「损坏旧档应 L3 停机」——则补迁移前预检解析、损坏即停的分支 |
|
||||
|
||||
## 卡③ 选档界面新建批
|
||||
|
||||
| # | 代拍项(卡片 §9 条目) | 取法 | 约束核对 | veto 影响 |
|
||||
|---|---|---|---|---|
|
||||
| 1 | 槽卡布局(§9-1) | **纵列三行**(页壳内容列内每槽一行:槽名+摘要+动作钮)——career 页行族同构,等宽纪律零豁免 | 三槽全显一屏(契约 1 禁滚动)✓;1440 宽内单行容纳 | 改横列三卡=视图布局重排(L2 域) |
|
||||
| 2 | 槽位编号呈现(§9-2) | 「存档位 1/2/3」 | 用户原话口径直用 | 改措辞=视图一处 |
|
||||
| 3 | 三钮文案(§9-3) | 「新档」/「进档」/「删档」(动词钮,对齐现役动词钮先例;进档=primary 主操作钮、删档=danger_button 危险钮 `ui_kit.gd:695`) | 裁决 3/4 语义直用 ✓ | 改文案=视图常量 |
|
||||
| 4 | 与开始层互斥方式(§9-4) | career 同款(`_start_overlay.visible=false`+模态栈单口;关闭恢复) | 仿先例域内参数选择 ✓ | — |
|
||||
| 5 | 提交切分与 worktree 命名(§9-5) | worktree `iter33card3-saveselect`/分支 `iter33-card3-saveselect`;三笔:T1+T2+T3 实现+变异伴生强化+T4 产出物 | — | — |
|
||||
| 6 | ConfirmDialog 消费方编排机制(§9-6,卡片预授权取法照录) | **open 前设消费方状态量(`_confirm_consumer`)、confirmed/cancelled 后按量分派(`_on_confirm_accepted`/`_on_confirm_declined` match 路由)**;双钮签名未动(`confirm_dialog.gd:36-38`);分派面=match 分支可扩展(卡④ 第三消费方直接加分支) | 禁双常驻静态接线 ✓(变异m4 拦截在役);本批消费方=删档确认+现役新冒险确认(随卡②撤出) | 机制重选=分派层重写 |
|
||||
| 7 | 窥视读器 has_file 位(实现期接口补全——超出 §9 清单单项,按 T0 对齐授权补记待追认) | `peek_slot_summary` 返回结构加 `has_file: bool`(空/有档操作集二分判定来处;卡③ 6.0「槽态唯一来处=卡① 窥视 API 返回值」的接口闭环——交付面缺该位则二分不可实现) | 非摘要第四项(契约 5 三项不变)✓;向后兼容(既有断言零改)✓;卡① 侧 sv7/sv8 断言复跑绿 ✓ | 若裁「二分判定改走他口」(如独立 has_slot API)——save_manager 增一访问器+组合根改一行 |
|
||||
@@ -1,23 +0,0 @@
|
||||
# 迭代 33 GDD 反哺点清单(2026-10-21)
|
||||
|
||||
> 累积文档:实现与设计权威文档的差异/缺口逐条登记于此;用户在会话中裁决后由文档批写入 `design/`(实现批禁写 design/,2026-10-10 用户立规)。每条写清:哪个文件哪一节、改成什么、依据是什么。
|
||||
|
||||
## 卡① 存档制数据层改造批
|
||||
|
||||
| # | 文档与落点 | 现行陈述 | 应改成 | 依据 |
|
||||
|---|---|---|---|---|
|
||||
| 1 | `design/gdd/systems/表现与支撑/存档序列化.md` `:61`(现行口径节) | 「存档是单文件 JSON(user://save.json)」 | 三存档位承载:`user://save_slot_1/2/3.json` 三文件制,写盘目标=当前激活槽文件;boot 启动态无激活不读写;激活态经选档界面进档/新档建立(卡③) | 卡① 完成定义 1/3+契约 1/6 实装(`save_manager.gd` SLOT_COUNT=3) |
|
||||
| 2 | 同上 `:20`/`:16`(系统范围负责表) | 「单档 JSON 存档的域划分与读写约定」 | 「3 存档位 JSON 存档的域划分与读写约定」;消费面纪律补「无激活态一切写盘路径拒绝并返回 false」 | 卡① 契约 6(sv3 断言在役) |
|
||||
| 3 | 同上 `:165`(P2 后置表「多存档槽位」行) | 「单档 MVP(2026-09-21 裁决);多档等有真实需求再立项」 | 该条注销(去向=迭代 33 卡① 已落地)——后置表此行删除或标「已实现(迭代 33)」 | 卡① F7:本批即该条预写的「真实需求」 |
|
||||
| 4 | 同上(新增条款建议) | 无旧档迁移记载 | 补一段旧单档一次性迁移口径:`user://save.json` 首次启动字节迁入槽 1、源改名 `.migrated.bak` 留痕、槽 1 已存在不重迁(幂等) | 卡① Q1 裁甲+sv12 实装(契约 4 旧档不静默丢失的机制化) |
|
||||
| 5 | `待办清单.md` 营地交互重做条目 | 状态「…已编迭代 33」 | 卡① 完工后条目状态推进(归流水线登记段/文档批按 §12.1 执行) | doc-conventions §12.1;实现批禁写两份流程清单 |
|
||||
| 6 | `roadmap.md` 迭代 33 行与顶部「当前位」 | 状态「待开工」 | 卡① 合并后行内状态换代(归文档批) | 同上 |
|
||||
|
||||
## 卡③ 选档界面新建批
|
||||
|
||||
| # | 文档与落点 | 现行陈述 | 应改成 | 依据 |
|
||||
|---|---|---|---|---|
|
||||
| 7 | `design/gdd/systems/跨局循环/生涯.md` `:11-23`(信息架构结构树) | 主菜单六钮组直达营地/生涯 | 结构树补「进入存档→选档界面→进档→营地」一级层级;生涯入口改挂营地笔记本(卡④) | 卡③ 完成定义 1+裁决 1 三入口实装 |
|
||||
| 8 | `design/gdd/08-Alpha版本标准.md` 「三 · 界面」表 | 无选档界面行 | **增行请求(须用户裁——08 头注纪律)**:新增「选档界面」行(在役,迭代 33 卡③) | 卡③ §5 统一口径 |
|
||||
| 9 | `待办清单.md`/`roadmap.md` | 迭代 33 进行中 | 卡③ 完工状态推进(归文档批) | doc-conventions §12.1 |
|
||||
| 10 | `design/gdd/systems/表现与支撑/存档序列化.md` 消费面纪律节 | 窥视读器未记载(卡① 反哺点 4 补迁移口径时顺带) | 补 `peek_slot_summary` 返回结构(readable/has_file/三值)与「has_file=占档判定、非摘要项」口径 | 卡③ T0 对齐补充(二分判定来处的文档化) |
|
||||
@@ -1,146 +0,0 @@
|
||||
# 迭代 33 实现报告(2026-10-21)
|
||||
|
||||
> 累积文档:卡①→卡③→卡② 依序施工,各卡收口时在本文追加该卡章节;随各卡合并提交进 master。三卡全部合并且总收口完成后本文即为迭代终稿。
|
||||
> 基线复读(T0,2026-10-21,master=7280070f):冒烟 **1156 项 / 0 失败**;单元 **35 套件全绿**;probe_gate `--click` **全绿**(残留 Godot=0)。
|
||||
|
||||
---
|
||||
|
||||
## 卡① 存档制数据层改造批(隐式单档 → 3 存档位)——已合并(见合并记录)
|
||||
|
||||
**状态**:T0–T4 完成;批末重闸 --code 全绿(回执见合并提交信息);独立验收审计两轮——首轮未过(sv3 拆闸实验判「拒写断言无判别力+生产链零对照面」、sv4 申报变异未执行且无判别力,两行缺漏回炉),回炉后断言强化(sv3 退化写目标锚+生产链对照面、sv4 旧内容判别锚)并补执行变异⑥⑦,复审通过(`reports/iter33-验收审计-2026-10-21.md` 卡① 节)。
|
||||
|
||||
### 一、实际改动—验收对照表(§7.1 需求侧表的执行对账,六列+结果)
|
||||
|
||||
> 断言尾缀族〔sv#〕均可 grep 定位。落点行号=合并时点实值。
|
||||
|
||||
| 需求点 | 改动实值(文件:行) | 验收测试实值(落点+尾缀) | 层级 | 真实入口 | 撤销或变异证明 | 结果 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| sv1 三槽承载+位间隔离 | `save_manager.gd:15-27` 常量与字段(SLOT_COUNT/SLOT_PATH_TEMPLATE/_slot_template);`:77` slot_path 唯一派生口;`:66` attach_slot_template 注入口 | 冒烟 `_smoke_save_slots` ①段 `smoke_all.gd:6858` 起〔sv1 往返×3+位间隔离〕+单元 `save_slot_isolation_test.gd`〔sv1〕(22 检查) | 接口 | `SaveManagerCore` 实例按槽 API 读写往返,不经 UI | 变异①=slot_path 派生写死 `% 1` → 三槽往返一致断言红(已执行,见变异表) | 通过 |
|
||||
| sv2 启动态不读盘 | `save_manager.gd:29` `_init` 默认参改 `""`+`:48-53` `_ready` 只做旧档迁移、零读槽 | 冒烟 V2-s1/V2-s2(`smoke_all.gd:273-278`)〔sv2〕真实 boot 链+单元 `save_boot_no_activate_test.gd`(12 检查)类级白盒+生产链对照 | 冒烟+单元 | 组合根 boot 链 `/root/SaveManager`(真实入口=冒烟);单元为 --script 无 autoload 环境的类级对照面+settle 生产链(**双落点对账:计划仅列单元,实测拆为冒烟真实链+单元类级/链级**) | 变异④=_ready 偷调 activate_slot(1) → V2-s1/V2-s3 红(已执行) | 通过 |
|
||||
| sv3 无激活写盘拒绝 | `save_manager.gd:354-358` `write_to_disk` 入口 `_path == ""` 判定 | 冒烟 V2-s3(`smoke_all.gd:278`)+单元〔sv3〕「拒写+返 false+三槽快照全等+**退化写目标(裸 .tmp)零新增**+**MetaProgression.settle_adventure 生产链触达后盘面零触碰**」(`save_boot_no_activate_test.gd`,12 检查) | 接口 | `MetaProgression.settle_adventure()`(`meta_progression.gd:275`,写盘 :282)无激活态触达写盘被拒——生产链对照面在单测 ③段实测(真表 db 驱动全链) | 变异⑦=闸短路(`if false and _path == ""`)→ 退化写目标两断言红(类级+链级,已执行;首轮断言无判别力经审计判缺漏后强化) | 通过(回炉后) |
|
||||
| sv4 新档原语 | `save_manager.gd:116-137` `create_slot`(创建即激活+落盘+失败回退) | 冒烟 ③段〔sv4〕非白板旧内容(999/5)覆盖为全零白板+盘面核验非旧值 | 接口 | 空槽调新档 API 后按域读回+盘面文件内容核验 | 变异⑥=create 改读旧档(`load_from_disk()` 代 `_default_data()`)→ 白板两断言红(已执行) | 通过(回炉后) |
|
||||
| sv5 进档原语 | `save_manager.gd:94-114` `activate_slot`(激活+读盘+失败恢复切换前三态) | 冒烟 ①④段〔sv5〕+单元〔sv5〕 | 接口 | 槽 N 有档 → activate_slot → 读回=该槽内容 | 变异⑤=activate 漏更新 _path → 写盘受理断言红(已执行) | 通过 |
|
||||
| sv6 删档原语 | `save_manager.gd:140-161` `delete_slot`(文件删除+.tmp 清偿+激活指针连清除+.corrupt.bak 不追删) | 冒烟 ②段〔sv6〕文件系统存在性断言 | 集成 | 激活/非激活槽调删档 API+盘面核查 | 变异②=漏删文件 → 在盘断言红(已执行) | 通过 |
|
||||
| sv7 摘要三项按槽窥视 | `save_manager.gd:163-168` `peek_slot_summary`+`:170-172` peek_summary_at 注入口+`:174-205` 只读解析 | 单元 `save_slot_summary_test.gd`〔sv7〕(12 检查:三槽异值/空槽/三不可读态)+冒烟 ⑥段 | 单元+接口 | 窥视 API 按槽调用(不激活不写盘——套件内断言 active_slot==0) | 变异③=窥视改读激活态内存 → 跨槽摘要红(已执行) | 通过 |
|
||||
| sv8 窥视三态零副作用 | 同上(窥视路径零 `_corrupt_fallback` 触达——`:616` 迁移/`:315` 正式读盘均不在窥视调用链) | 冒烟 ⑥段〔sv8〕字节+mtime 双比对+零 .corrupt.bak 改名+.tmp 按空槽 | 接口 | 盘上坏槽/高版本夹具 → 窥视 API | 变异=窥视改走正式 load 路径 → 坏槽字节/在盘断言红(.corrupt.bak 改名主文件消失——sv8 断言族覆盖) | 通过 |
|
||||
| sv9 迁移链各槽成立 | 迁移链零改动(`SAVE_FORMAT_VERSION=7`+六件自注册不动),执行面按槽独立 | 冒烟 ⑤段〔sv9〕三槽各喂 v5 旧档→各自激活读回+写盘 version=7;既有迁移段(v1/v2/v5 旧档)全数复跑绿 | 接口 | 各槽 `load_from_disk` | 变异=迁移只跑激活槽 → 他槽读回断言红(⑤段按槽独立喂档,共享化即异值不成立) | 通过 |
|
||||
| sv10 切槽同实例整体替换 | `activate_slot` 内 `_data` 与路径整体替换+失败恢复;`MetaProgression.save` 引用零触碰(meta_progression.gd 零改动) | 单元 `save_slot_isolation_test.gd` ③段〔sv10〕宿主链引用同一性+写盘落当前槽+盘面核验 | 集成 | `MetaProgression.new(null, sm)` 真实宿主链驱动切槽 | 变异=切槽新建实例 → 同一性断言红(meta.save == t 断言锚);写成落错槽 → 位间隔离红(变异⑤已证) | 通过 |
|
||||
| sv11 测试隔离面保留 | `attach_path`(`:56-64`)语义保持「注入即激活+重读」+`attach_slot_template`(`:66-75`)新增隔离注入口;既有调用面零改(见 T0 清点) | 既有冒烟/探针段全数复跑绿(冒烟 1201/0 含全部既有段;probe_gate --click 重闸复跑)〔sv11〕 | 集成 | 各探针 `isolate_save()`(`.new(path)`+`load_from_disk`)与 `attach_path` 现有 8 处直接消费 | 撤销=注入路径改成忽略 → 依赖隔离的既有断言成片红(成片红即本行证明;实测既有段全绿=语义保持) | 通过 |
|
||||
| sv12 旧档处置 Q1 甲 | `save_manager.gd:616-631` `_migrate_legacy_save(src,dst,bak)` 字节级搬运+幂等判据+源改名 `.migrated.bak` 留痕;`_ready`(`:48-53`)生产接线 | 冒烟 V2-s4 迁移不变式(真实链)+⑦段夹具断言〔sv12〕(逐域相等/留痕/幂等/他槽零触碰) | 接口 | 盘上旧档夹具跑迁移+真实 boot 链(V2-s4) | 变异=去掉幂等判据 → 预置 777 覆盖断言红(⑦段夹具:槽 1 预置异值档+二次迁移) | 通过 |
|
||||
| sv13 不升 schema 版本 | `SAVE_FORMAT_VERSION := 7`(`save_manager.gd:9`)与 `_normalize` 零改动(diff 核实) | 既有版本/高版本拒读断言复跑绿(既有段+④段高版本槽)〔sv13〕 | 单元 | 既有冒烟版本段 | 判断依据=本行不改任何行为;升版即撞既有高版本拒读断言 | 通过(零改动核实) |
|
||||
| sv14 反哺点清单 | §5 所列文档口径(存档序列化.md `:61`/`:20`/`:16`/`:165`、待办清单条目、roadmap 行)列点不落文 | 件核对表〔sv14〕落 `reports/iter33-反哺点-2026-10-21.md` | 件核 | 收口前逐条指认落点 | 判断依据=产出物件核不产码 | 通过(见反哺点清单卡① 节) |
|
||||
|
||||
### 二、变异验证记录表(注入 → 最窄闸见红 → git checkout 精确还原 → 复绿)
|
||||
|
||||
| # | 注入点 | 预期 | 实测红 | 最窄闸 | 还原后 |
|
||||
|---|---|---|---|---|---|
|
||||
| ① | `slot_path` 派生写死 `_slot_template % 1`(三槽同一文件) | 三槽往返一致断言红 | sv1 三槽往返一致·槽 1/2 红(`save_slot_isolation_test`) | 单元套件直跑 | all green (22 checks) |
|
||||
| ② | `delete_slot` 文件删除分支短路(`if false and …`,漏删文件) | 在盘断言红 | sv6 删后文件不在盘红+sv6 非激活槽红+sv7 空槽窥视连带红(冒烟) | `run_smoke.py` 全量 | 1201/0 全绿 |
|
||||
| ③ | `peek_slot_summary` 改读激活态内存 | 跨槽摘要红 | sv7 窥视三项逐槽正确·槽 1/2 红(`save_slot_summary_test`) | 单元套件直跑 | all green (12 checks) |
|
||||
| ④ | `_ready` 偷调 `activate_slot(1)`(偷复激活) | boot 断言红 | V2-s1 boot 后无激活态红+V2-s3 写盘拒绝红(冒烟) | `run_smoke.py` 全量 | 1201/0 全绿 |
|
||||
| ⑤ | `activate_slot` 漏更新 `_path`(写盘落旧目标) | 写盘落错槽红 | sv3 激活态写盘受理·槽 1/2 红(`save_slot_isolation_test`——无激活态拒写路径被触发) | 单元套件直跑 | all green (22 checks) |
|
||||
| ⑥ | `create_slot` 改读旧档(`load_from_disk()` 代 `_default_data()`,首轮审计 sv4 缺漏回炉) | 全零白板断言红 | sv4 白板态红+sv4 盘面核验红(999 旧值带入;冒烟) | `run_smoke.py` 全量 | 1201/0 全绿 |
|
||||
| ⑦ | `write_to_disk` 无激活闸短路(首轮审计 sv3 缺漏回炉——拆闸实验证实原断言无判别力) | 拒写盘面零触碰断言红 | sv3 退化写目标零触碰红+sv3 生产链盘面零触碰红(`save_boot_no_activate_test`——杂散 game/.tmp 真实落盘被两锚抓获) | 单元套件直跑 | all green (12 checks) |
|
||||
|
||||
### 三、T0 产物:隔离面全清单清点(sv11 件核)
|
||||
|
||||
逐点确认三槽化后仍可隔离到单槽(判定准则=契约 7 单路径语义「注入路径=激活槽文件,无激活态时注入即激活并重读」):
|
||||
|
||||
| 隔离面 | 位点 | 三槽化后判定 |
|
||||
|---|---|---|
|
||||
| `attach_path` 直接消费 | `ui_tune_probe.gd:167/:171`、`t17_defer_probe.gd:21`(注释引)、`probe_ui_util.gd:111`、`pacing_queue_test.gd:28`、`smoke_all.gd:276/:320/:462/:593` | 语义零变化(注入即激活+重读+写盘落注入路径)——实测既有段全绿 |
|
||||
| `isolate_save`(`.new(path)`+显式读盘) | `probe_ui_util.gd:104-106`(tag 族 10 探针 15 处间接消费) | `.new(path)` 显式传路径形态保持(默认参改 `""` 零波及——全仓无 `.new()` 零参消费) |
|
||||
| `_META_SMOKE_PATHS` 18 条 | `smoke_all.gd:5697-5704`(T0 订正值),消费=`_meta_new_save(path)` 独立实例 | 与槽位承载正交(独立实例直构),零影响 |
|
||||
| boot/lifecycle 四段 | `smoke_all.gd:276/:320/:462/:593` | 段内先 attach 后消费,V2d-2 起全部在激活态下运行,零影响 |
|
||||
| presenter lambda 注入面 | `main.gd:317`(camp ctx) | 未触碰 save 引用,零影响 |
|
||||
| 真实档红线 | 探针纪律「绝不碰 user://save.json」 | 保持:生产迁移在 autoload `_ready`(玩家 boot 语义),探针注入路径不经过 `user://save.json`;新增槽模板注入口保证测试夹具落 `user://smoke_*` 命名空间 |
|
||||
|
||||
### 四、Q1 执行留痕(sv12 生产实证)
|
||||
|
||||
- **裁定执行**:Q1 甲(迁 1 号存档位)——`_ready` 一次性 `_migrate_legacy_save(user://save.json, user://save_slot_1.json, user://save.json.migrated.bak)`。
|
||||
- **本机真实迁移已发生**(批内首次 godot boot 时):源= v7 空进度档(钥石 0、无断点),已字节迁入 `user://save_slot_1.json`,原件留痕 `user://save.json.migrated.bak`。`save.json.quarantined-20261020`(10-19 隔离件)非迁移对象,原样未动。
|
||||
- **损坏/高版本旧档路由**:实现取「字节级原样搬运、零解析零改造」——损坏/高版本旧档字节原样落槽 1,「原样落入槽 1」按字面成立;读取该槽时由正式进档路径兜底链(`.corrupt.bak` 改名留盘)/拒读链接管,数据不静默丢失。与本卡 §10 Q1「执行前置检查」的 L3 路由相比,本实现使该意外形态不再触发承诺失效(字节未变),故未走 L3 呈报;此口径已在追认单登记(§9 白名单域内的实现取法,veto 窗口开放)。
|
||||
- **幂等判据**:槽 1 已存在不重迁;迁移成功后源已改名,二次启动源不存在=天然无操作。双重保险,sv12 ⑦段夹具断言钉死。
|
||||
|
||||
### 五、已知中间态(批内事实,随卡③/卡② 合并消除)
|
||||
|
||||
1. **无激活态真空窗口**(卡① 合并后、卡③ 合并前):boot 后无激活态,主菜单「开始冒险/继续上局/营地/生涯」旧钮仍可点——冒险可玩但结算写盘被拒(`settle_adventure` 忽略返回值→进度不落盘)、营地购买写盘被拒。此为卡① Q2 裁甲明知且接受的批内中间态;卡③ 同迭代内随后合并(进档即激活),卡② 再撤旧钮,终态无此窗口。
|
||||
2. **boot 态 first_adventure_done=false**:无激活态下 `is_first_adventure_done()` 返回默认 false——窗口期内直开冒险会走首局教学脚本模式(旧档玩家的一次性观感差异);卡③ 合并后生产路径必经进档(激活后读回该槽真实值),窗口外无影响。
|
||||
3. **V2d-1 改写**(削弱申报在案):「续玩钮 boot 态==真实档断点态」关系判据 → 「boot 态恒隐(无激活态)」;卡② mn8 撤钮时整族承接。
|
||||
|
||||
### 六、读数对照
|
||||
|
||||
| 闸 | 基线(T0) | 末态(卡① 收口) |
|
||||
|---|---|---|
|
||||
| 冒烟 | 1156 / 0 | **1201 / 0**(+45:V2-s1..s4 四断言+_smoke_save_slots 段 41 断言) |
|
||||
| 单元 | 35 套件全绿 | **38 套件全绿**(+3:isolation 22 / boot 12〔回炉+4〕/ summary 12) |
|
||||
| probe --click | 全绿 | 全绿(重闸复跑) |
|
||||
| 重闸 --code | — | 全绿(回执随合并提交留痕) |
|
||||
|
||||
---
|
||||
|
||||
## 卡③ 选档界面新建批(3 存档位 · 新档/进档/删档)——已合并(见合并记录)
|
||||
|
||||
**状态**:T0–T4 完成;独立验收审计两轮——首轮未过(批末重闸回执 all_green=false:静态扫描两处卡③新增 R1 裸容器注解 `main.gd:1176`/`save_select_overlay.gd:58`,收口时点只核回执 commit 未核 verdict、报告「全绿」表述失实——回炉改推断形态+`Array[Variant]`+`assign()`、重跑重闸实测全绿);复审通过(`reports/iter33-验收审计-2026-10-21.md` 卡③ 节)。
|
||||
|
||||
### 一、实际改动—验收对照表(§7.1 需求侧表的执行对账,六列+结果)
|
||||
|
||||
> 断言尾缀族〔sl#〕均可 grep 定位(探针 problems 文本与对照表同名)。落点行号=合并时点实值。
|
||||
|
||||
| 需求点 | 改动实值(文件:行) | 验收测试实值(落点+尾缀) | 层级 | 真实入口 | 撤销或变异证明 | 结果 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| sl1 三槽呈现 | 新建 `views/save_select_overlay.gd`(`_init`:19 页壳+`open_save_select`:53 喂入重建) | `ui_struct_probe` 选档段〔sl1〕槽卡行数==3+滚动容器计数==0(`ui_struct_probe.gd:80` 起段) | 探针 | `main._open_save_select()` 真实开层子树(「进入存档」钮归卡② mn3——函数直调中间态在案) | 变异m7=套 ScrollContainer → 计数+零尺寸双红(已执行) | 通过 |
|
||||
| sl2 摘要三项逐槽读数 | 槽卡消费喂入三键(视图 `_build_slot_row`:72;组合根 `_save_select_data`:1173 经卡① 窥视 API) | struct 段〔sl2〕异值夹具(钥石 555/通关 2 局/冒险 7 局)逐字断言 | 探针 | 开层后各槽卡 label 实取值(渲染面) | 变异m2=摘要改读激活位 → 两行红(已执行) | 通过 |
|
||||
| sl3 摘要禁项 | 槽卡只消费三键,零断点字段进视图 | struct 段〔sl3〕禁词断言(断点/种子/继续/停点/「 关」零命中——label 全集枚举) | 探针 | 选档层真实 Label 文本全集 | 变异m9=断点关数拼进槽卡副标题 → sl3 红(已执行;词形表随变异补「 关」) | 通过 |
|
||||
| sl4 操作集二分 | 槽卡按 occupied 分支渲染钮集(视图 `_build_slot_row` occupied 分支) | struct 段〔sl4〕**渲染面按钮文本扫描**(空/坏槽零删档钮含置灰形态、有档槽零新档钮) | 探针 | 真实开层子树按钮枚举 | 变异m3=空槽渲染删档钮 → 红(已执行;首轮断言走簿记缝被变异暴露盲区,强化为渲染面扫描后复红) | 通过 |
|
||||
| sl5 空槽新档链 | `main.gd:1187` `_on_save_select_new`:create_slot→暂行开 CampOverlay(Q3 乙) | `ui_click_probe` 选档段〔sl5〕真实点击(pressed.emit)断言 active==1+白板落盘 | 集成 | 真实按钮信号路径 | 撤销=去掉 create_slot 调用 → 激活/落盘断言红 | 通过 |
|
||||
| sl6 有档槽进档链 | `main.gd:1193` `_on_save_select_load`:activate_slot→暂行 CampOverlay | click 段〔sl6〕 | 集成 | 真实点击进档钮 → active==2 | 变异=进档读成当前激活槽 → active 断言红 | 通过 |
|
||||
| sl7 删档二次确认链 | `main.gd:1200` `_on_save_select_delete`:open 前设消费方→弹窗;confirmed 才删、cancelled 只关窗 | click 段〔sl7〕双路径(一击只开窗/取消文件在/确认删+槽回空+就地刷新) | 集成 | 真实点删档钮 → 确认窗 → 两支(cancelled/confirmed 信号同源) | 变异m1=删档直连删除 → 「一击未只开确认窗(直删形态)」红(已执行) | 通过 |
|
||||
| sl8 消费方编排机制 | `main.gd:361-362` 单口分派接线+`:495` new_adventure 消费方设置+`:1200` delete_slot 消费方设置;双常驻静态接线撤除 | click 段〔sl8〕确认后/取消后消费方状态量清零+删档确认不误触发开局(`run_scope.is_adventure` 断言);现役断点确认段(既有 ui_click_probe 二轮 A 段)复跑绿=分派对 new_adventure 消费方行为零变化 | 集成 | 两个开窗路径共用同一弹窗实例 | 变异m4=注入双常驻静态接线(confirmed 再连 _start_adventure)→ 「删档确认误触发开局」红(已执行) | 通过 |
|
||||
| sl9 重启不预选(Q1 甲) | 视图零选中态字段+组合根零持久化(boot 无激活=卡① sv2 面承接) | struct 段〔sl9〕fresh-boot 开层前 active_slot()==0+「已选」标记文本零命中 | 探针 | 探针每 run 全新 boot main.tscn=重启链;V2-s1(卡①)钉 boot 级 | 变异m8=视图加预选标记 → 红(已执行) | 通过 |
|
||||
| sl10 返回路径与 ESC 语境 | 返回钮→closed 信号→`main.gd:1164` `_on_save_select_closed`(_close_modal+开始层恢复);视图零 ESC 处理 | `screen_flow_probe` 选档步〔sl10〕(`screen_flow_probe.gd:129` 起步函数):返回后恢复+合成 ESC 层不关 | 探针 | 真实点击返回钮+viewport.push_input 合成 ESC | 变异m5=返回钮只隐不关 → 恢复断言红;变异m-ESC=main 加 ESC 处理 → 不响应断言红(均已执行) | 通过 |
|
||||
| sl11 层序与模态纪律 | `main.gd:48` LAYER_CONTRACT 加行(生涯同档)+`:434` 层查表+`:297` 构造 | 既有 `_modal_registry_contract`(登记序=合同序逐位)+V1d(move_child 单口)复跑自动覆盖新层〔sl11〕;ui_tune_probe 树序断言复跑 | 冒烟/探针 | `smoke_all.gd:146` 起源码合同段+struct 登记契约 | 变异=视图内散落 move_child → V1d 散落判红(新层零散落=合同表行即全部落位) | 通过 |
|
||||
| sl12 动线序不回闪 | `main.gd:1187/:1193` 先落点开层(open_camp 内藏开始层)再不关选档(栈记账挂起) | click 段〔sl12〕逐帧可见性采样+**栈遮挡记账断言**(select ∈ camp._occluded——被挂起非关闭) | 探针 | 真实点击新档钮后逐帧采样 | 变异m6=改成先关后开 → 「被关闭而非栈记账挂起」红(已执行;回闪一帧前提经 ModalStack 源码核实不成立〔close 只还原登记层、start 为壳不登记〕,判别面钉在记账态) | 通过 |
|
||||
| sl13 公共件复用零新素材零新色值(非行为改动) | 视图全用 UiKit 工厂(page_shell/label/button/danger_button/primary_button/keystone_badge)+现行色 token(WARM/WARM_SOFT/CANDLE/WARM_FAINT) | struct `_audit("savesel")` 结构族+`ui_contrast_probe` 对比度全绿复跑〔sl13〕;diff 核实零新 `Color8(` 字面量/素材路径 | 件核 | 本批 diff 文件枚举 | 判断依据=不改行为;变异=引入新色值 → 对比度探针红 | 通过(diff 核实) |
|
||||
| sl14 反哺点清单(非行为改动) | §5 所列(待办清单、生涯.md 结构树、08 增行请求、roadmap)列点不落文 | 件核对表〔sl14〕落 `reports/iter33-反哺点-2026-10-21.md` 卡③ 节 | 件核 | 收口前逐条指认落点 | 判断依据=产出物件核不产码 | 通过(见反哺点清单卡③ 节) |
|
||||
|
||||
### 二、变异验证记录表(注入 → 最窄闸见红 → git checkout 精确还原 → 复绿)
|
||||
|
||||
| # | 注入点 | 实测红 | 最窄闸 | 还原后 | 伴生断言强化 |
|
||||
|---|---|---|---|---|---|
|
||||
| m1 | `_on_save_select_delete` 直连删除(跳过确认窗) | sl7 一击未只开确认窗(直删形态) | ui_click_probe | 问题=0 | — |
|
||||
| m2 | `_save_select_data` 三值改读激活位现值 | sl2 摘要读数两行红 | ui_struct_probe | 零红 | — |
|
||||
| m3 | 空槽分支渲染删档钮 | 首轮零红→**暴露断言盲区**(簿记字典缝未含该钮);sl4 改渲染面按钮文本扫描后复红 | ui_struct_probe | 零红 | sl4 渲染面化 |
|
||||
| m4 | confirmed 再连 `_start_adventure`(双常驻静态接线忠实形态) | sl8 删档确认误触发开局 | ui_click_probe | 问题=0 | — |
|
||||
| m5 | 返回钮改只隐不关不恢复 | sl10 返回后开始层未恢复 | screen_flow_probe | PASS | — |
|
||||
| m6 | 新档回调先 `_close_modal` 再开营地 | sl12 被关闭而非栈记账挂起(**首轮帧采样零红**——ModalStack 源码核实「close 恢复开始层」前提不成立,判别面改钉遮挡记账) | ui_click_probe | 问题=0 | sl12 记账判别 |
|
||||
| m7 | 槽卡容器套 ScrollContainer | sl1 滚动容器计数红+zero_size 红 | ui_struct_probe | 零红 | — |
|
||||
| m8 | 槽名拼「(已选)」预选标记 | sl9 预选标记文本命中 | ui_struct_probe | 零红 | — |
|
||||
| m9 | 槽卡副标题拼断点关数 | sl2 精确匹配红+sl3 禁词红(**首轮仅 sl2 红**——禁词表缺关数词形,补「 关」形后双红) | ui_struct_probe | 零红 | sl3 词形表 |
|
||||
| m-ESC | main 加选档语境 ESC 处理 | sl10 ESC 关闭了选档层 | screen_flow_probe | PASS | — |
|
||||
|
||||
### 三、T0 产物:confirm_dialog 断言面清点(§7.2 申报位点核对)
|
||||
|
||||
| 位点 | 卡③ 处置后实况 |
|
||||
|---|---|
|
||||
| `ui_struct_probe.gd:71`(结构采样——confirm open/audit) | 分派口变化后行为不变(open 直开保留)——采样复跑绿,零改写 |
|
||||
| `smoke_all.gd:226`(最顶层候选) | 弹窗实例数与树序未变——复跑绿,零改写 |
|
||||
| `ui_click_probe.gd:508-527`(断点确认交互段) | 分派重构初版曾红(「确认开新冒险后未开局」——`_start_adventure_from_menu` 开窗未设消费方),补设后复跑绿;该段即 sl8 的 new_adventure 侧活体回归 |
|
||||
| `ui_tune_probe.gd:52`(树序断言) | 弹窗构建位未动——复跑绿,零改写 |
|
||||
| 申报小结 | §7.2 四位点**零改写**(判据未放宽);新增断言见对照表 |
|
||||
|
||||
### 四、已知中间态(随卡②/卡④ 合并消除或换代)
|
||||
|
||||
1. **选档层无生产入口**(卡③ 合并后、卡② 合并前):「进入存档」钮属卡②——探针经 `main._open_save_select()` 函数直调(mn10 同款中间态,对照表 sl1/sl5-sl7 真实入口列在案);卡② mn3 补钮与点击链后闭环。
|
||||
2. **进档/新档暂行落点 CampOverlay**(Q3 裁乙):卡④ 重立卡后改挂场景图(其 T3 承载改挂与二次验证面)。
|
||||
3. **选档层营地段被栈挂起不关闭**(sl12 钉死态):camp 关闭时栈还原选档层(玩家回选档面)+`_on_camp_closed` 恢复开始层(被选档页遮挡不可见)——卡④ T3 同口径换代点。
|
||||
4. **窥视读器 has_file 位**(T0 对齐补充):空/有档操作集二分判定来处,非摘要第四项;已在卡① 交付面、卡③ 消费面两侧文档(卡③ §2 对齐附注)留痕。
|
||||
|
||||
### 五、读数对照
|
||||
|
||||
| 闸 | 基线(卡① 合并态) | 末态(卡③ 收口) |
|
||||
|---|---|---|
|
||||
| 冒烟 | 1201 / 0 | **1201 / 0**(卡③ 断言全在探针层,冒烟零新增) |
|
||||
| 单元 | 38 套件全绿 | **38 套件全绿** |
|
||||
| probe --click | 全绿 | 全绿(struct/click/flow 三件新段全绿+ui_contrast 等既有件零回归) |
|
||||
| 重闸 --code | — | 首轮 all_green=false(R1×2 新增)→ 回炉后**全绿**(回执随合并提交留痕——收口流程订正:回执须核 verdict 非仅 commit) |
|
||||
@@ -1,191 +0,0 @@
|
||||
# 迭代 33 独立验收审计(2026-10-21)
|
||||
|
||||
> 审计人:未参与实现的独立会话,只采信盘面证据与自跑实测,不采信任何报告的「已全绿」。
|
||||
> 被审计对象:卡① 存档制数据层改造批(worktree `D:\code\g-plan2-iter33card1-save`,分支 `iter33-card1-save`,实现提交 `6a7c2575`+`074cfe27`,基线 `7280070f`;首轮审计后回炉提交 `4a8558a0`,见文末复审小节)。卡③ 选档界面新建批审计见文末「卡③」节(worktree `D:\code\g-plan2-iter33card3-saveselect`)。
|
||||
> 审计材料:需求卡片 §7.1/§7.2、实现报告卡① 节实际对照表与变异记录表、`git diff 7280070f..HEAD`、三个新单元套件+冒烟新段+run_all 注册、闸回执。
|
||||
> 审计自跑基线(首轮,HEAD=074cfe27):冒烟 **1201 项 / 0 失败**(`python tools/run_smoke.py`,三闸全过);单元 **38 套件全绿**(`--script res://tests/run_all.gd`)——与实现报告读数一致。
|
||||
> 复审自跑基线(回炉后,HEAD=4a8558a0):冒烟 **1201 项 / 0 失败**(三闸全过);单元 **38 套件全绿**;boot 套件 **12 检查全绿**——均为审计自跑实测,见复审小节。
|
||||
|
||||
## 卡① 存档制数据层改造批
|
||||
|
||||
### ① 逐行核对表(sv1–sv14,对实现报告实际对照表逐行复核)
|
||||
|
||||
| # | 判定 | 依据(审计自查实录) |
|
||||
|---|---|---|
|
||||
| sv1 三槽承载+位间隔离 | 通过 | 两落点在盘:单元 `save_slot_isolation_test.gd` ①段+冒烟 `_smoke_save_slots` ①段;〔sv1〕尾缀 grep 命中(冒烟 4 处、单元多处)。真实入口=卡片申报面(SaveManagerCore 按槽 API 直调,不经 UI)未绕过。变异①(slot_path 写死 `% 1`)机理静态复核成立:三槽同名文件则槽 2/3 异值读回必不成立。 |
|
||||
| sv2 启动态不读盘 | 通过 | 真实入口在位:冒烟 V2-s1/V2-s2 挂真实 autoload boot 链(`main.get_node("/root/SaveManager")`,`_smoke_boot_chain` 内)。单元为类级白盒面——计划落点仅单元、实测拆双落点,报告已如实对账(非隐瞒)。变异④机理成立:`_ready` 偷激活则 V2-s1 `active_slot()==0` 直接判红。 |
|
||||
| sv3 无激活写盘拒绝 | **缺漏**(首轮判;回炉后复审通过,见文末复审小节) | 见结论缺漏 1。两点:申报真实入口(`MetaProgression.settle_adventure` 链触达写盘被拒)零对照面——单测与冒烟 V2-s3 均裸调 `write_to_disk`,无任何 MetaProgression 链在无激活态下触达写盘的断言;撤销证明经审计实测**不成立**(拆闸后全部 sv3 断言仍绿,详②-2)。报告 sv3 行「代码评审可证」的撤销主张被实验推翻。 |
|
||||
| sv4 新档原语 | **缺漏(轻)**(首轮判;回炉后复审通过,见文末复审小节) | 断言在盘(冒烟 ③段)且入口合规;但申报变异「新档写成读旧档」未执行,且经流程点推演**无判别力**:冒烟段序为②段先删槽 3、③段才 create_slot(3),此时槽 3 无文件——「读旧档」变体读不存在文件=回默认态,全零断言仍绿。报告以推理代实测(「与 sv5 读回断言同族必红」),未按 test-conventions §6 标「拦截能力未证」。见结论缺漏 2。 |
|
||||
| sv5 进档原语 | 通过 | 冒烟 ①④段+单元多落点;〔sv5〕grep 命中。变异⑤已执行且机理成立:激活不落 `_path` 则首槽写盘受理返回 false,「sv3 激活态写盘受理」判红——与报告变异表⑤一致。 |
|
||||
| sv6 删档原语 | 通过 | 冒烟 ②段直接盘面断言(文件不在盘+无 .tmp+指针清除+他槽字节不动)。变异②(短路文件删除)经审计**静态推演**成立:在盘断言直查 `FileAccess.file_exists`,短路即红;⑥段空槽窥视连带红(与报告变异表②的红集一致)。未实测(报告已申报全量冒烟实测),推演记录于②-3。 |
|
||||
| sv7 摘要三项按槽窥视 | 通过 | 单元 12 检查+冒烟 ⑥段双落点;窥视不激活不写内存有专断言(active_slot==0)。**变异③审计实测复现**:注入读激活态 → `save_slot_summary_test` 红(sv7 逐槽·槽 3+坏槽/高版本/缺版本三不可读态,详②-1)→ 还原 → 12 检查全绿。 |
|
||||
| sv8 窥视三态零副作用 | 通过 | 冒烟 ⑥段+单元 ③段字节+mtime 双比对+零 `.corrupt.bak` 改名+.tmp 按空槽。变异未实测;静态推演成立:窥视改走正式 `load_from_disk` → `_corrupt_fallback` 改名主文件消失 → 「零改名」断言红。判据面(字节+mtime)实测在案于双落点。 |
|
||||
| sv9 迁移链各槽成立 | 通过 | 冒烟 ⑤段三槽各喂 v5 旧档逐槽读回+写盘 version=7;既有迁移段(v1/v2/v5)全数复跑绿(审计自跑基线在案)。变异「迁移只跑激活槽」机理静态成立:他槽激活读回值必不成立。 |
|
||||
| sv10 切槽同实例整体替换 | 通过 | 单元 ③段宿主链:`MetaProgressionScript.new(null, t)` 真实宿主链、`meta.save == t` 引用同一、读数随槽(533→644)、写盘 650 落槽 2 并盘面核验、高版本槽激活失败恢复切换前三态。变异⑤覆盖「写盘落错槽」半面;「新建实例」半面为 API 形状所禁(方法内无从换实例),推理可证。meta_progression.gd 零改动(diff 核实)。 |
|
||||
| sv11 测试隔离面保留 | 通过(附注) | 非新断言行——卡片申报即「既有段全数复跑」,无代码尾缀可 grep 属申报内形态,非缺漏。凭据:审计自跑基线冒烟 1201/0(含全部既有段)+单元 38 套件绿+回执探针 --click/--full 绿;T0 隔离面清点在实现报告§三(18+15 条、attach_path 8 处、tag 族、boot/lifecycle 四段、presenter lambda、真实档红线逐点判定)。attach_path「注入即激活+重读」语义在代码核实保持(注入槽名记账激活号、注入任意路径写盘目标照旧)。 |
|
||||
| sv12 旧档处置 Q1 甲 | 通过(附注) | ⑦段夹具四断言钉死语义:逐域相等(1234)、源改名留痕、幂等(预置 777 零覆盖+源保留)、他槽字节不动;幂等变异静态成立(去 `dst` 存在判据 → 二次迁移覆盖 777 → 断言红)。V2-s4 挂真实 boot 链。附注:V2-s4 不变式(旧档在则槽 1 必在)在本机已迁移态下为空真——生产接线面的机检强度依赖盘面状态,但语义面已由夹具钉死,接线面拆毁在有旧档的盘面上仍会红,判可接受。⑦段直调 `_migrate_legacy_save` 为被测私有件本身,有 V2-s4 生产链对照面在,不判绕过。 |
|
||||
| sv13 不升 schema 版本 | 通过 | **diff 核实零改动**:`SAVE_FORMAT_VERSION := 7` 行基线/HEAD md5 一致(`101adcd0ebe1a18f2004b454a8c85bb8`);`_normalize` 函数体逐字节一致(diff 空输出);迁移链函数零触碰(新窥视路径只读调用二者)。既有版本/高版本拒读断言复跑绿(基线在案+冒烟 ④段高版本槽断言)。 |
|
||||
| sv14 反哺点清单 | 通过 | `reports/iter33-反哺点-2026-10-21.md` 在盘,六条全覆盖 §5:存档序列化.md :61/:20/:16/:165 四落点+新增迁移条款建议+待办清单+roadmap,各条有「现行陈述/应改成/依据」。件核不产码,合规。 |
|
||||
|
||||
### ② 撤销证明抽查记录(审计自跑实测,命令与输出摘要)
|
||||
|
||||
**②-1 变异③复现(报告变异表③,实测)**
|
||||
- 注入:`game/core/save_manager.gd` `peek_slot_summary` 函数体首行插 `return {"readable": true, "keystone": keystone_balance(), "cleared": adventure_cleared(), "total": adventure_total()}`。
|
||||
- `--headless --path . --script res://tests/unit/core/save_slot_summary_test.gd` → **FAIL**(窗内 4 条:`sv7 窥视三项逐槽正确·槽 3`+`sv7 坏槽窥视=显式损坏标记`+`sv7 高版本槽窥视=不可读标记`+`sv7 缺版本字段槽窥视=不可读标记`;更早 FAIL 行被输出窗口截断)——跨槽摘要与不可读态两面均被抓,拦截力实测成立。
|
||||
- `git checkout -- game/core/save_manager.gd` → `git status --porcelain` 空 → 复跑 **all green (12 checks)**。与报告变异表③一致。
|
||||
|
||||
**②-2 自选变异:sv3 撤销证明检验(审计设计,实测——发现缺漏)**
|
||||
- 注入:`write_to_disk` 无激活闸 `if _path == "":` 改 `if false and _path == "":`(即 sv3 行申报的撤销操作「去掉判定放行旧入口」)。
|
||||
- 跑 `save_boot_no_activate_test.gd` → **仍 all green (8 checks)——申报的红未出现**。
|
||||
- 原因查实:拒写断言锚在返回值 `false`,而空路径下游 `FileAccess.open(".tmp", WRITE)` 对 `"" + ".tmp"` 相对路径**打开成功并真实写盘**(实测运行在 worktree `game/` 落杂散文件 `.tmp`,657 字节,内容为序列化默认档 JSON),随后改名到空目标失败才返回 false——「闸拒绝」与「空路径写失败」在全部 sv3 断言(返回值+三槽存在性/字节/mtime)上不可区分;杂散 .tmp 落在项目根不在三槽扫描面内,零断言可抓。
|
||||
- 还原:`git checkout --` → 复跑 **all green (8 checks)**;杂散 `game/.tmp` 已删除(审计产物清理,git-ignored 件,删后 `git status` 干净)。
|
||||
- 判定:sv3 断言批对「拆闸」无判别力,撤销证明不成立。
|
||||
|
||||
**②-3 变异②(删档漏删)静态推演(审计设计,未实测——报告已申报全量冒烟实测)**
|
||||
- 注入设定:`delete_slot` 文件删除分支短路(`if false and FileAccess.file_exists(p) and not _remove_file(p)`),返回 true、文件留盘。
|
||||
- 推演:冒烟 ②段 `check(not FileAccess.file_exists(slot_tpl % 3) ...)` 直查文件系统 → 段内文件仍在 → 判红;`sv6 删非激活槽:文件不在盘` 同理红;⑥段 `delete_slot(3)` 后空槽窥视读到残file值 600 → `sv7 空槽窥视=零值合法态` 连带红。红集与报告变异表②一致,拦截面成立。
|
||||
|
||||
### ③ 测试削弱检查表(diff 全部删改逐处 vs 卡片 §7.2 申报)
|
||||
|
||||
| diff 改动处 | 定性 | vs §7.2 申报 |
|
||||
|---|---|---|
|
||||
| `smoke_all.gd` 删 5 行:V2d-1「boot 态==断点在档态」关系判据整块 | 既有断言改写(唯一一处) | **申报内**(§7.2 唯一允许面=boot 链 V2d-1)。判据**收紧非放宽**:原=关系判据 `visible == has_breakpoint`;新=钉死两事实 `not has_breakpoint() and not visible`。断言文本带「卡① sv2 改写」标识与「卡② mn8 再承接」注记,禁判据空转的条件满足。 |
|
||||
| `save_manager.gd` 删 8 行:6 行注释+2 处生产代码(`_init` 默认参 `"user://save.json"`→`""`、`_ready` 删 `load_from_disk()`) | 生产改动本体 | 非断言删改;两处均=卡片 §7.1 sv2 行申报的改动本体(「_init 默认参取消」+启动态钉死),非测试削弱面。 |
|
||||
| `smoke_all.gd` 其余 +176 行 | 纯新增(`_smoke_save_slots` 新段+V2-s1..s4) | 不属削弱面;既有段零触碰(game/ 删除行逐行清点:合计 13 行=上两行所列,无其他)。 |
|
||||
| `run_all.gd` +3 行 | 纯新增三套件注册 | 既有注册零删改、顺序与 expect 域未动——无削弱。 |
|
||||
|
||||
**小结**:除申报内 V2d-1 改写外,diff 中不存在任何未申报的既有断言删改、阈值放宽、扫描面缩小或入口替换。
|
||||
|
||||
### ④ 回执核验(`game/tests/.gates/receipt.json`)
|
||||
|
||||
- `commit` = `074cfe27a4b4cc6c67d359c033729243e86ce4eb` == 分支尖 HEAD —— **一致**;
|
||||
- `all_green` = **true**;`domain` = **"code"**(本批只碰 game/ 代码与断言面,选档正确);`quick_mode` = false(非快闸)。
|
||||
- 闸明细:01 冒烟全量/02 单元套件/03 探针 --click/04 探针 --full/05 渲染闸/09 静态扫描/10 熵增闸均 green;`11 回放确定性对拍` = NEED-APPROVAL 未跑(`not_run` 在案;与卡片「MC 零跑、纯承载改造」口径相容,此处只记录不另裁);`inherited_red` 注记 09 静态扫描「基线红→现绿(改善)」。
|
||||
- 审计对回执的独立支撑:冒烟 1201/0 与单元 38 套件全绿均为审计自跑复现(见文首基线)。
|
||||
|
||||
## 结论(首轮审计,盘面=074cfe27)——未通过(两缺漏已回炉,终审见文末复审小节)
|
||||
|
||||
首轮缺漏清单(保留存档,回炉事实见复审小节):
|
||||
|
||||
1. **sv3(必回炉,缺漏)**:
|
||||
- **撤销证明不成立(实测)**:拆除 `write_to_disk` 无激活闸后,单测 2 条断言+冒烟 V2-s3 全部仍绿——拒写断言锚在返回值 false,与空路径下游写失败不可区分;拆闸运行实测在项目根落杂散 `.tmp`(写盘真实发生),而「盘面零触碰」断言只扫三槽路径,抓不到该副作用通道。报告 sv3 行「撤销=去掉判定 → 拒写断言红(代码评审可证)」经实验推翻,变异记录表亦无此条实测。
|
||||
- **申报真实入口零对照面**:卡片与报告均申报真实入口=`MetaProgression.settle_adventure()`(`meta_progression.gd:275`,写盘 :282)链触达写盘被拒,但两个测试落点均裸调 `write_to_disk`(单元类级+真实 autoload 直调),无任何 MetaProgression 链在无激活态下触达写盘的断言。
|
||||
- 回炉方向(供实现段参考,非裁断):断言加掃描空路径写失败的实际副作用面(如杂散 .tmp 不在盘),并补一条 MetaProgression 链(或等价生产链)无激活触达写盘被拒的断言;补做拆闸变异实测留红。
|
||||
2. **sv4(须回炉,缺漏·轻)**:申报变异「新档写成读旧档」未执行,且在现有冒烟段序下(②段先删槽 3、③段才新档)无判别力——读旧档变体读到空档=默认态,全零断言仍绿;报告以推理代实测且未按 test-conventions §6 降格标注「已实现,拦截能力未证」。回炉方向:新档断言前预置带异值的残档夹具(或调整段序),补做该变异实测留红;或按 §6 如实降格标注。
|
||||
|
||||
其余 sv1/sv2/sv5–sv14 共 12 行逐行**通过**(其中 sv8/sv9/sv12 的变异为审计静态推演补证、sv11/sv12 附注见逐行表);测试削弱检查无未申报删改;回执三项核验全过。首轮审计未合并任何提交、未改 `game/` 下任何文件(两处变异注入均已 `git checkout` 精确还原,审计产物杂散 `.tmp` 已删,`git status` 干净)。
|
||||
|
||||
## 复审(2026-10-21,回炉提交 4a8558a0)
|
||||
|
||||
**回炉 diff 核验**(`git diff 074cfe27..4a8558a0`,仅两测试文件+实现报告对账,生产代码 `game/core/` 零触碰):
|
||||
- `save_boot_no_activate_test.gd` 8→12 检查,**纯新增**(删除行逐行清点=仅 3 行文件头注释,零既有断言删改):②段加「拒写退化写目标零触碰」锚——空 `_path` 派生的裸 `.tmp`/`.tmp.tmp` 夹具清场后断言零新增(正是首轮拆闸实验实测的杂散落点通道);新增 ③段 `_test_settle_chain_write_rejected`:真表 ConfigDB+`MetaProgression.settle_adventure` 生产链全段驱动(`mark_first_adventure_done`→`apply_adventure_summary`→`refresh_treasure_unlocks`→`write_to_disk`),断言落账内存(adventure_total=1)而写盘无目标+链触达后退化写目标零新增——首轮「生产链零对照面」缺漏的对照面成立,卡片 sv3 申报真实入口自此有机检面。
|
||||
- `smoke_all.gd` ③段**段内改写**:`create_slot` 前预置非白板 v7 旧内容(keystone 999/adventure_total 5/adventure_cleared 2);白板断言加 `adventure_total()==0` 合取项;旧「文件在位」检查升格为「盘面文件内容核验非 999」(解析落盘文件取 `keystone_balance==0`——文件缺失或不可解析时哨兵 -1 必红,存在性被其子集化)。两处被换断言均系本批新增断言(非卡片 §7.2 辖区的批前既有断言),且为升格收紧非放宽;段内检查数 3→3,冒烟总数保持 1201。
|
||||
- 实现报告 sv2/sv3/sv4 行与变异表补⑥⑦两行对账更新,sv3 行撤销主张改写为实测执行——与审计实测结果一致。
|
||||
|
||||
**复审自跑实录**(命令同首轮;每次变异后 `git checkout -- game/core/save_manager.gd` 精确还原并确认 `git status --porcelain -- game/` 为空):
|
||||
- 基线:`save_boot_no_activate_test.gd` → **all green (12 checks)**;单元全量 `run_all.gd` → **38 套件全绿**;全量冒烟 → **1201 项 / 0 失败三闸过**(回炉后基线独立复现)。
|
||||
- **变异⑦复现**(=首轮审计的拆闸实验原样重放):`write_to_disk` 闸改 `if false and _path == ""` 注入 → boot 套件**恰两锚红**——「sv3 拒写退化写目标零触碰(裸 .tmp 零新增——拒绝口可判别锚)」+「sv3 生产链盘面:结算触达后退化写目标零新增(链上真实入口的盘面核验)」,且杂散 `.tmp`(845 字节,链上结算落账数据)真实落盘被两锚抓获 → 还原清理 → 复跑 **all green (12 checks)**。首轮「拆闸不红」的缺漏自此闭合。
|
||||
- **变异⑥复现**:`create_slot` 内 `_data = _default_data()` 改 `load_from_disk()`(读旧档)注入 → 全量冒烟**恰 sv4 两行红**——「sv4 新档=全零可玩合法白板态(旧内容 999/5 零带入)」+「sv4 新档落盘=白板内容(盘面核验非 999 旧值)」,1201 项 2 失败 → 还原 → 复跑 **1201/0 全绿三闸过**。sv4 盘面核验断言「真能抓读旧档」经**实测**证实(非静态推演),与报告变异表⑥逐行一致。
|
||||
- 回执核验(复审轮,盘面刷新件):`receipt.json` `commit`==`4a8558a0`==HEAD、`all_green`=true、`domain`="code"、`quick_mode`=false;`not_run` 同首轮(11 回放确定性对拍 NEED-APPROVAL,记录不另裁)。
|
||||
|
||||
**复审削弱检查**:回炉 diff 删除行逐行清点=boot 套件 3 行文件头注释+smoke ③段 1 行注释与 2 行本批新增断言;零批前既有断言删改、零阈值放宽、零扫描面缩小、零入口替换——**未引入新的未申报削弱**。
|
||||
|
||||
**复审判定**:sv3、sv4 两缺漏回炉后断言均经实测具备判别力(变异⑦/⑥注入见红、还原复绿),sv3 申报真实入口已有生产链对照面(链级断言实测在役),处置未引入新削弱——两行改为**通过**。
|
||||
|
||||
## 卡① 结论(终审)
|
||||
|
||||
**通过**——sv1–sv14 全部 14 行通过(sv3/sv4 回炉后复审通过,凭据见复审小节;首轮未过记录保留于上,回炉事实=提交 `4a8558a0`)。独立验收审计合并前置达成。复审全程零 commit、`game/` 零残留(两处变异注入均已精确还原,杂散件已清)。
|
||||
|
||||
## 卡③ 选档界面新建批(3 存档位 · 新档/进档/删档)
|
||||
|
||||
> 审计人:同一独立协议(未参与实现、只采信盘面证据与自跑实测、不采信报告「已全绿」)。
|
||||
> 被审计对象:worktree `D:\code\g-plan2-iter33card3-saveselect`,分支 `iter33-card3-saveselect`,实现提交 `a6614a3b`+`52dd1ad2`+`54bde367`,基线 merge-base=`ebf40947`(卡① 合并态)。
|
||||
> 审计材料:卡③ 需求卡片 §7.1/§7.2/§2 T0 对齐附注、实现报告卡③ 节(对照表+变异表十条+confirm 断言面清点)、`git diff ebf40947..HEAD`、三探针新段、闸回执。
|
||||
> 审计自跑基线(HEAD=54bde367):冒烟 **1201/0 三闸过**;单元 **38 套件全绿**;探针三件 exit=0(struct **PASS 全屏结构断言零红**/click **问题=0**/flow **PASS**);ui_contrast_probe **PASS(38 对测点)**;卡① `save_slot_summary_test` **12 检查全绿**(has_file 向后兼容面)。
|
||||
|
||||
### ① 逐行核对表(sl1–sl14,对实现报告实际对照表逐行复核)
|
||||
|
||||
| # | 判定 | 依据(审计自查实录) |
|
||||
|---|---|---|
|
||||
| sl1 三槽呈现 | 通过 | `ui_struct_probe` 选档段+`_save_select_contract` 在盘:槽卡行数==3+`_count_scroll` 零滚动容器断言;〔sl1〕grep 命中。真实入口=`main._open_save_select()` 函数直调——**中间态登记核实**:实现报告「已知中间态」#1+对照表 sl1/sl5–sl7 真实入口列均在案;全仓 `_open_save_select` 调用方=探针 6 处+定义 1 处,生产零调用、无死钮预埋(「进入存档」钮属卡② mn3,本批未提前接线)——合法中间态成立。变异m7(ScrollContainer)注入点与红项(滚动计数+zero_size 结构族)桌核自洽。 |
|
||||
| sl2 摘要三项逐槽读数 | 通过 | struct 段夹具按槽直写(槽1=钥石 555/通关 2 局/冒险 7 局)逐字断言+钥石徽全树枚举;真实入口=开层后渲染面 label 实取值。变异m2(`_save_select_data` 改读激活位)桌核自洽:槽1 两断言(摘要行+钥石徽)必红。 |
|
||||
| sl3 摘要禁项 | 通过 | 禁词表=断点/种子/继续/停点/「 关」(label 全集 `contains` 扫描——「通关」无空格不误伤,词形注记在案);变异m9 双红记录(sl2 精确匹配+sl3 禁词)与词形表强化历史自洽(首轮缺「 关」被变异暴露后补齐=收紧)。 |
|
||||
| sl4 空/有档操作集二分 | 通过 | **渲染面实测**:`_collect_button_texts` 逐行枚举 visible Button 文本(行1=进档+删档零新档;行2/3=仅新档零进档删档含置灰形态)+簿记 occ 判定保留;变异m3 **审计实测复现**(详②-1)。 |
|
||||
| sl5 空槽新档链 | 通过 | click 段真实按钮信号路径(`new_btn.pressed.emit()`):active==1+槽1 白板落盘(盘面解析 keystone==0)+逐帧采样;中间态登记同 sl1。撤销机理成立(去 `create_slot` 调用→激活/落盘断言红)。 |
|
||||
| sl6 有档槽进档链 | 通过 | click 段槽2 进档→active==2+落点营地层可见+选档隐藏。变异(进档读成当前激活槽)桌核自洽:active 断言红。 |
|
||||
| sl7 删档二次确认链 | 通过 | 双路径全链:一击只开窗(`is_open`+文件在盘)→取消只关窗文件仍在(含消费方状态量清零)→再开窗确认删+槽回空+就地刷新(occupied_flags 翻转断言);变异m1 **审计实测复现**(详②-2)。 |
|
||||
| sl8 消费方编排机制 | 通过 | 分派单口三断言(取消后/确认后 `_confirm_consumer` 清零+删档确认不误触发开局 `run_scope.is_adventure`);现役断点确认段(`ui_click_probe.gd:604` 起,行号较申报漂移)零改写复跑绿=new_adventure 侧活体回归;变异m4(confirmed 再连 `_start_adventure`)桌核自洽。生产接线核验:`_start_adventure_from_menu` open 前设消费方、`_on_confirm_accepted` match 路由、旧双常驻静态接线撤除(diff 删除行=申报的生产改动本体)。 |
|
||||
| sl9 重启不预选(Q1 甲) | 通过 | struct 段开层前 `active_slot()==0` 断言+「已选」标记文本零命中+视图零选中态字段(文件核);boot 级由卡① V2-s1 承接。变异m8(预选标记)桌核自洽。 |
|
||||
| sl10 返回路径与 ESC 语境 | 通过 | `screen_flow_probe` 新步:返回钮真实信号→选档隐藏+开始层恢复断言+屏级互斥采样;合成 ESC 键(viewport.push_input)层不关断言。变异m5(只隐不关)与 m-ESC(加 ESC 处理)桌核自洽(申报已执行)。 |
|
||||
| sl11 层序与模态纪律 | 通过(无新码尾缀——申报形态=既有段复跑,同卡① sv11 先例) | 凭据:`LAYER_CONTRACT` 加行+`_layer_node` 查表+构造三处在 diff 核实;`ui_struct_probe` 全屏 PASS 含 `_modal_registry_contract`(登记序==合同序,新层在册);冒烟 1201/0(V1d 源码合同段,审计自跑);ui_tune_probe 树序断言(:52 原样在位)经回执 04 --full 绿。变异(视图散落 move_child→V1d 判红)为既有闸机理,无新断言需变异。 |
|
||||
| sl12 动线序不回闪 | 通过 | 逐帧三断言(落点帧选档隐藏/营地层可见/开始层保持隐藏)+**栈遮挡记账判别**(select ∈ `camp._occluded`);变异m6 红项与报告一致。强化历史核实:首轮帧采样对 m6 零红(close-then-open 形态在帧采样下不可判别)→52dd1ad2 **纯新增**记账断言(帧采样保留零删)——收紧非放宽。 |
|
||||
| sl13 零新素材零新色值(非行为改动) | 通过(件核+复跑) | diff 核实:新视图文件零 `Color8(`/`Color(`/`preload`/素材路径,main.gd 新增行零色值素材(grep 计数=0);ui_contrast_probe **PASS(38 对测点+裸色白名单/preload 红线静态段绿)**(审计自跑)。无新码尾缀=件核行申报形态(同卡① sv13 先例)。 |
|
||||
| sl14 反哺点清单(非行为改动) | 通过 | `reports/iter33-反哺点-2026-10-21.md` 卡③ 节 4 条(#7 生涯.md 结构树补层/#8 08 增行请求-明示须用户裁/#9 待办清单+roadmap 推进/#10 存档序列化消费面纪律补 has_file 口径)覆盖卡片 §5 全部落点。 |
|
||||
|
||||
### ② 撤销/变异证明抽查记录(审计自跑实测)
|
||||
|
||||
**②-1 变异m3 复现(空槽渲染删档钮——按簿记缝盲区形态注入:渲染但不注册簿记字典)**
|
||||
- 注入:`save_select_overlay.gd` `_build_slot_row` 空槽分支尾加 `row.add_child(UiKit.danger_button("删档", "MUTATION m3"))`(不写 `_delete_btns`)。
|
||||
- `ui_struct_probe` → **exit=1,恰两行红**:「行2 操作集失守(空/坏槽应=仅新档、零进档删档含置灰形态)〔sl4〕」+「行3 ……〔sl4〕」——首轮走簿记缝的盲区(字典未含该钮)被渲染面扫描闭合,实测证实强化有效。
|
||||
- `git checkout --` 还原 → 复跑 **PASS 全屏结构断言零红** → `git status` 干净。
|
||||
- 强化本身核查(52dd1ad2 diff 逐行):sl4 由簿记字典缝改为真实钮文本枚举(扫描面扩大、occ 簿记保留、零检查删除);sl3 词形表扩充;sl12 记账断言纯新增——**未引入未申报削弱**。
|
||||
|
||||
**②-2 变异m1 复现(删档直连删除,跳过确认窗)**
|
||||
- 注入:`main.gd` `_on_save_select_delete` 改直连 `save_manager.delete_slot(slot)`+就地刷新,原确认链 `if false` 短路。
|
||||
- `ui_click_probe` → **exit=1,sl7 面如期红**:「sl7 一击未只开确认窗(直删形态)」。同轮另现一条连带红「断点段:战败结算后断点未清」——该段在变异前基线与还原后复跑均 0 红,判为变异扰动的对局段偶发(预算帧漂移 9781→9749→6619),非基线不稳,记录备查。
|
||||
- 还原 → 复跑 **问题=0** → `git status` 干净。
|
||||
|
||||
**②-3 变异表十条逐条桌核**:m1/m3 实测如上;m2(读激活位→sl2 两断言红)、m4(双常驻接线→`run_scope.is_adventure` 红)、m5(只隐不关→恢复断言红)、m6(先关后开→记账判别红,帧采样不可判别的机理说明与 ModalStack 语义核实一致)、m7(ScrollContainer→滚动计数+zero_size 结构族双红)、m8(预选标记→文本命中红)、m9(拼关数→sl2+sl3 双红)、m-ESC(ESC 关层红)——注入点、断言面、红项记录逐条与盘面代码对得上,自洽。
|
||||
|
||||
### ③ 测试削弱检查表(diff 全部删改逐处 vs 卡片 §7.2 申报)
|
||||
|
||||
| diff 改动处 | 定性 | 判定 |
|
||||
|---|---|---|
|
||||
| `smoke_all.gd` | **零改动**(del=0/add=0) | 与对照表「卡③断言全在探针层,冒烟零新增」一致 ✓ |
|
||||
| `ui_struct_probe.gd`/`ui_click_probe.gd`/`screen_flow_probe.gd` | **纯新增**(del=0;+103/+96/+41) | 既有段零触碰 ✓;批内强化提交 52dd1ad2 为批内新断言的演进(m3/m9/m6 盲区修正),全部收紧零删(详②-1) |
|
||||
| §7.2 申报四位点(按内容定位,行号已漂移) | 逐一核实 | `ui_struct_probe` confirm 结构采样(:103-106)、`smoke_all` `_topmost_visible_layer` 候选表(:226 区)、`ui_click_probe` 断点确认交互段(:604-623)、`ui_tune_probe` 树序断言(:52)——**全部原样在位零改写**(申报允许改写而实际未改,优于申报) |
|
||||
| `main.gd` 删 9 行 | 生产改动本体 | 旧双常驻静态接线(`_on_confirm_new_adventure`/`_on_confirm_cancelled` 及两条 connect)撤除=卡片契约 3/§9 第 6 条+sl8 申报的改动本体,非断言削弱;新分派行为与旧 handler 逐句等价(new_adventure 分支对照核实) |
|
||||
| `save_manager.gd` 删 4 行 | 接口补全 | 注释 2 行+peek 返回字典字面量 2 处加 `has_file` 键——向后兼容扩展,卡① 断言零触碰(详⑤) |
|
||||
|
||||
**小结**:零未申报削弱;零批前既有断言删改;零阈值放宽;零扫描面缩小;零入口替换。
|
||||
|
||||
### ④ 回执核验(`game/tests/.gates/receipt.json`,盘面工作件)
|
||||
|
||||
- `commit` = `54bde3678ab8707872c2a117d75e7a9e8abcb91f` == HEAD ✓;`domain` = "code" ✓;`quick_mode` = false;`not_run` = 11 回放确定性对拍(NEED-APPROVAL,同卡① 口径)。
|
||||
- **`all_green` = false ✗**:`09 静态扫描` exit=1,且 `changed_vs_baseline` 记录红项清单较基线变化(基线 4354b2aa72a7 → 现 2b71884ec242;卡① 合并态该闸为绿/改善,存量基线记录的旧红清单已被卡① 清零)。其余 01 冒烟/02 单元/03 探针 --click/04 探针 --full/05 渲染闸/10 熵增闸 green(其中 01/02/03+struct/flow/contrast 探针经审计自跑复现)。
|
||||
- 审计现场复现红项:`python tools/audit_type_hints.py` → **存量 2 处 R1(裸 Dictionary/Array 注解)**——`main.gd:1176`(`var p: Dictionary`,`_save_select_data` 内)+`save_select_overlay.gd:58`(`var slots: Array`);两处均为卡③新增代码行(diff `+` 行核实),即本批新引入的类型闸红。
|
||||
- **与实现报告矛盾**:卡③ 状态行与读数对照声称「批末重闸 --code 全绿(回执见合并提交信息)」——盘面回执 `all_green=false` 且红闸为本批新引入,报告表述失实。按硬性红线「`run_all_gates.sh` 所选域全绿才合回 master」,本批当前态**不可合并**。
|
||||
|
||||
### ⑤ has_file 接口补全专项
|
||||
|
||||
- diff 核实:`save_manager.gd` 仅 4 删 6 增=窥视读器注释改写+peek 返回字典(越界分支与 `out` 初始化)加 `has_file` 键+主文件在盘置位一行——**纯返回键扩展,向后兼容**。
|
||||
- 卡① 侧断言零触碰:`save_slot_summary_test.gd` 零 diff;审计直跑 **all green (12 checks)** ✓。
|
||||
- 三处留痕一致:卡③ §2 T0 对齐附注(has_file=空/有档操作集二分判定来处、非摘要第四项、零 UI 语义)=实现报告已知中间态 #4=追认单卡③ #7(列为待追认单项、veto 影响写明)——三处口径逐字一致 ✓。
|
||||
- 消费面核验:`_save_select_data` `occupied = has_file ∧ readable`(Q2 甲坏槽按空呈现)✓;视图零自判(槽态唯一来处=喂入数据)✓。
|
||||
|
||||
### 卡③ 结论(首轮)——未通过(已回炉,终审见文末卡③复审小节)
|
||||
|
||||
**首轮缺漏清单(1 项,阻塞合并;保留存档)**:
|
||||
1. **批末重闸未全绿+报告失实**:回执 `09 静态扫描` 红(2 处 R1 类型闸存量,均在卡③新增代码行:`main.gd:1176` 裸 `Dictionary`、`save_select_overlay.gd:58` 裸 `Array`;红项清单较基线变化),`all_green=false`;实现报告「批末重闸 --code 全绿」与盘面矛盾。回炉方向(供实现段参考,非裁断):两处容器注解参数化(如 `Dictionary[String, Variant]`/`Array[Dictionary]`)或按闸机规程报用户裁;重跑批末重闸取全绿回执(回执 commit 须对新 HEAD);更正实现报告「全绿」表述按盘面实况。回炉后按本协议复审。
|
||||
|
||||
其余全部通过:sl1–sl14 逐行核对 14 行通过(含中间态登记与无死钮核实、has_file 专项、三处留痕一致);变异 m1/m3 实测复现红→还原→绿,十条变异表自洽;52dd1ad2 强化纯收紧未引入削弱;§7.2 四位点零改写;smoke_all 零改动。审计全程零 commit、`game/` 零残留(两处变异注入均已 `git checkout` 精确还原)。
|
||||
|
||||
### 卡③ 复审(2026-10-22,回炉提交 b673ced)
|
||||
|
||||
**回炉 diff 核验**(`git show b673ced`,仅两处代码修+实现报告更正,共 5 增 4 删):
|
||||
- `main.gd:1176`:`var p: Dictionary = save_manager.peek_slot_summary(i)` → `var p := save_manager.peek_slot_summary(i)`(推断形态,行内注记写明取舍依据:裸注解触 R1、参数化 `Dictionary[String, Variant]` 赋值被运行期严格类型拒——实测 SCRIPT ERROR 实证过)。变量仍持同一窥视返回 Dictionary,下游 `.get()` 消费零变化。
|
||||
- `save_select_overlay.gd:58`:`var slots: Array = ...` → `var slots: Array[Variant] = []`+`slots.assign(data.get("slots", []))`(typed 容器纪律)。`assign()` 逐元素拷贝后迭代内容不变,`for sd: Dictionary in slots` 原样——零行为改动。
|
||||
- 两处均为审计申报缺漏的定点修除,容器注解形态变化(声明面),零逻辑改动——无未申报削弱可言(行为不变佐证:sl2 摘要读数断言、sl5/sl7 数据链断言复审全绿,见下)。
|
||||
- 实现报告更正核实:卡③ 状态行改为两轮记录(首轮未过原因含「收口时点只核回执 commit 未核 verdict」的流程订正);读数表「重闸 --code」行改为「首轮 all_green=false(R1×2 新增)→ 回炉后全绿」——首轮审计指出的「报告失实」已消除。
|
||||
|
||||
**复审自跑实录**(HEAD=b673ced):
|
||||
- `python tools/audit_type_hints.py` → **PASS,产品码类型闸归零(R1/R2/R3)**,exit=0(首轮红项 `main.gd:1176`/`save_select_overlay.gd:58` 均已消)。
|
||||
- `ui_struct_probe` → **PASS 全屏结构断言零红**——含 sl2 摘要读数断言(555/2 局/7 局逐字)绿=`_save_select_data` 改推断形态后喂入数据面零行为变化的实测佐证。
|
||||
- `ui_click_probe` → **exit=0,问题=0**——sl5/sl7 数据链与 `open_save_select` 的 `Array[Variant]`+`assign()` 消费面(每次开层走该口)零行为变化的实测佐证。
|
||||
- 回执核验(复审轮):`commit`==`b673cedd…`==HEAD ✓、`all_green`=**true** ✓、`domain`="code" ✓、`quick_mode`=false;`09 静态扫描` exit=0 green(fingerprint green)——首轮红闸闭合;`not_run` 同前(11 回放确定性对拍 NEED-APPROVAL);回执时间戳(06:11:28)在回炉提交(06:04:59)之后=修后重闸实测。
|
||||
|
||||
**复审判定**:缺漏 1(批末重闸未全绿+报告失实)回炉后闭合——类型闸归零、回执全绿且对上 HEAD、报告更正为两轮实况。零未申报削弱。卡③ sl1–sl14 全部 14 行通过。
|
||||
|
||||
### 卡③ 结论(终审)
|
||||
|
||||
**通过**——卡③ 选档界面新建批 14 行(sl1–sl14)全部通过(首轮未过记录保留于上,回炉事实=提交 `b673ced`)。独立验收审计合并前置达成。复审全程零 commit、`game/` 零残留、`git status` 仅本报告工作件。
|
||||
@@ -0,0 +1,519 @@
|
||||
# 提案:营地场景图美术生成方案(渠道 · 分层 · 工作流 · 样张验收判据)
|
||||
|
||||
> 性质:设计讨论段过程稿(2026-10-22 美术方案讨论产出)。**只讨论生成方案,不出图、不写需求卡片、不改 `game/`、不编迭代**——美术线是用户自立批(铁律 2),方向稿与「过/不过」的目检结论由作者出。
|
||||
> 输入事实源:`reports/需求卡片-营地场景图新建批-2026-10-18.md`(卡④ v2.3,已退回美术设计段)、`reports/需求澄清-营地交互重做-2026-10-18.md`(目标体验原话/纵深稿/10 条交互裁决)、`design/art/art-bible.md` §6.2/§7.5/§4.1/§4.2/§8.3、`design/art/asset-path-map.md`、`design/art/art-prompts.md` §0/§4bis、`design/art/remote-gen-prompts.md`。
|
||||
> 待作者带的输入:①参照物(作者原话「后续找一下」)②渠道一句话裁定 ③每轮方向稿「过/不过」的目检结论。
|
||||
|
||||
---
|
||||
|
||||
## 0. 四问速览(只读这一段也能定)
|
||||
|
||||
| 问 | 答 |
|
||||
|---|---|
|
||||
| **① 现状差在哪** | 营地场景图**一张都不存在**(现役是四柜台覆盖层,程序化占位)。卡④ 已因美术轨凭据缺(P1–P5 未销号)退回美术设计段,卡⑤ 排在它后面,营地五卡是 Alpha 例外项——**没有图,卡④⑤ 一行代码都开不了**。 |
|
||||
| **② 建议做什么** | 走**项目既有远程生图管线(主角/八敌同条路)出图 + 既有后处理管线收口**,交付形态定为 **「1 张背景层 + 7 张物件层 + 1 份坐标表」**(不是一张整图叠七个矩形热区)。出图顺序:先 2–3 张低分辨率**方向稿**让作者选划方向,判完方向才分层精制。 |
|
||||
| **③ 为什么选它** | 七物件要**悬停/按下/禁用/已解锁四态**:整图 + 矩形热区做不出「贴合物件形状的高亮」和「单个物件灰掉」,要补就得给每个物件抠一张透明遮罩——那其实还是分层,只是遮罩不公开成素材。渠道 **B(插画级新产,✦ 渠道作者自跑远程生图管线)** 的**返工成本最低**(换提示词=换一张,八敌已量产验证);♻ CC0 凑不齐七件同套素材,且多来源像素密度不齐。**不是三选一**:A/B 是「产出什么」,远程生图管线是「怎么产出」。 |
|
||||
| **④ 怎么验证** | 机检三件:色板(`tools/palette_check.py --baseline`)、像素件(`tools/standee_asset_check.py`)、几何(七命中矩形两两不重叠 + 中心点落在物件不透明像素上,实现批写成探针断言)。风格一致、构图好看、七件一眼找得到——这三项机检判不了,**归作者目检**。 |
|
||||
|
||||
---
|
||||
|
||||
## 1. 议题 1 · 生成渠道怎么选
|
||||
|
||||
### 1.1 三条路摆开
|
||||
|
||||
> **口径更正(2026-10-22,Agent 自纠)**:草案曾把 B 误标为「人工/外包」——**错**。项目原文(卡④ `:282`)定义 **B = 插画级新产 = 按纵深稿从零新画一张**;执行方仍是**作者自跑远程生图管线**(`art-assets-checklist.md:14` 图例:✦ = 用户自跑,产出「角色、插画级素材」)。
|
||||
> 因此真实结构是:**A vs B =「产出什么」的二选一**(改现有 vs 从零画),**远程生图管线是「怎么产出」的执行通道**,不是与之并列的第三条路。下表保留三行以便对照,但裁定实质是 A / B 二选一(详见 1.3)。
|
||||
|
||||
| 案 | 怎么干活(逐天的真实动作) | 构图控制力 | 成本/周期 | 贴合已定色域的代价 | 返工风险 |
|
||||
|---|---|---|---|---|---|
|
||||
| **A · CC0 素材改色复用**(♻ 渠道) | 去 Kenney / OpenGameArt / itch.io 免费包找现成像素场景件(营火、砧台、宝箱、床、木牌、栅栏门等);选中后过「复用四道闸」(`art-assets-checklist.md:22`):① 色板量化到 §4.1 的 48 色 token、不保留原包杂色 ② 吸色检查无 HSV 300°–345° ③ 去色相仍可辨、不与语义件混 ④ 授权干净(CC0 优先,CC-BY 须署名,授权不明不用);过闸后按 v3 坐标拼上画面 | **最弱**——要凑齐八个指定物件的同一套素材几乎不可能,落点是东拼西凑 | 找素材耗时不可控(看似零绘成本,实际耗在筛选与授权核对) | **高**——多来源拼的图,像素密度、描边粗细、光照方向各不相同,改色+统一描边的工作量接近重画 | **中偏高**:发现风格不齐或构图不贴纵深稿,只能换源重找,前功尽弃 |
|
||||
| **B · 插画级新产**(✦ 渠道 · 卡④ 原案) | 以已接受的布局稿 + 纵深稿作参考锚,开远程生图对话 → 出构图候选 → 选一张 → 分层出图 → 抠底 / 降采样 / 色板量化 / 描边统一 → 合成校验 → 样张呈裁。**全链路=本提案 §3 的 S0–S7**,执行人始终是作者自己 | **最强**——七件位置与纵深完全由布局稿+提示词控制 | 重出一张很便宜(换提示词=换一张);拖周期的是反复横评,不是绘制本身 | **低**——提示词锁主色(烛光黄 `#F6C667` / 木色 `#8A5A34`)+后处理色板量化收口 | **最低**——候选多、迭代便宜 |
|
||||
| **C · 方向稿先行的混合时序**(B 的低风险写法) | 与 B 同一条管线,只是分两段:**先出 2–3 张低分辨率方向稿**给作者选划 → 判完方向才分层精制。**C 不是与 B 并列的第三条路,它就是 B 的执行时序** | 同 B | 同 B(因先用便宜稿定方向,总额外轮次更少) | 同 B | 最低 |
|
||||
|
||||
### 1.2 我的推荐:选 B(插画级新产),用 C 的时序去走(不替作者拍板,只摊代价)
|
||||
|
||||
> 原推荐写作「C 为主 + 混合收口」,口径更正后重新表述:**产出方式的裁定是 A / B 二选一,推荐 B;C 只是 B 的执行时序(先出可被否决的便宜方向稿),不构成第三选项。**
|
||||
|
||||
**推荐 B**,三条理由按权重排:
|
||||
|
||||
1. **它和本项目的具体缺口对得上**:缺口是「七个可点击物件的独立透明件 + 一张背景」,不是「一张漂亮插画」。远程生图一次出一张、想要几张出几张,天然适配分层交付;♻ 渠道卡在「找不齐一套八件的同一套 CC0 素材」。
|
||||
2. **返工风险最低是硬道理**:重出一张很便宜(换提示词=换一张),所以「先用过渡规格跑通交互、画质后升」这个口径才成立。
|
||||
3. **后处理管线已齐**:抠底→最近邻降采样→色板量化→描边,这条链在八敌批跑通过(art-prompts §0 五步第 4 步);换渠道等于这条链作废重搭。
|
||||
|
||||
**混合怎么混**(= C 时序,B 的内部工序):AI 出构图候选 → 作者选划方向 → 按定稿构图出「背景 1 张 + 物件拼表 1–2 张」→ 脚本后处理(抠底/降采样/量化/描边统一)→ 按坐标表合成校验 → 样张呈裁。**人工只出现在两处:作者选方向、作者判样张**。
|
||||
|
||||
**⚠ 选 B 时要连带处理的一件事(卡④ Q6 甲原文冲突,须作者确认)**:Q6 甲的裁定原文是「**Q1 裁 A 时**用过渡尺寸档=现役 1280 工程档+烛光黄 `#F6C667`/木色 `#8A5A34`」;**若 Q1 裁 B,按该裁定原文「过渡口径不成立」**——须走乙案「等样张批规格清单产出才开 T1」,或由作者**另行裁定一次过渡规格**。而本次讨论的输入条件里把「过渡规格=1280 工程档」列为已定硬约束,两者口径冲突,**属呈报项,不自行取一侧**:请作者确认过渡规格是否无条件适用。
|
||||
|
||||
**一句话裁定**:`A` 还是 `B`(推荐 **B · 插画级新产**,并按 C 的「方向稿先行」时序执行)。裁完即可进 §3 的 S1(S0 已销号)。
|
||||
**同时请顺便确认**:① 过渡规格是否无条件适用(见上方 ⚠ Q6 甲冲突);② 参照物是否阻塞 S1(等参照 vs 先用布局稿当锚)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 议题 2 · 要不要分层、怎么分(核心)
|
||||
|
||||
### 2.1 先判「一张整图 + 七个矩形热区」够不够
|
||||
|
||||
结论:**不够**,四态里有三态做不出来。
|
||||
|
||||
| 四态 | 整图 + 矩形热区能做到吗 | 说明 |
|
||||
|---|---|---|
|
||||
| 悬停高亮 | ❌ 只能整体提亮整图,或画一个**矩形框**——矩形框正是作者点名拒绝的「各种框框」形态;若要贴合物件形状提亮,必须有一张**该物件的透明遮罩** | 「要遮罩」就等于分层,只是遮罩不公开成素材,反而更难维护 |
|
||||
| 按下 | ❌ 同上(位移/压暗也要遮罩,否则整图一起动) | |
|
||||
| 禁用 / 未解锁 | ❌ 灰掉单个物件 → 同样要遮罩 | |
|
||||
| 已解锁 | ✅ 不需要额外素材 | |
|
||||
|
||||
**不分层还会发生什么**(逐条摊开):
|
||||
|
||||
1. **改构图 = 整图重出**:七件的相对位置被一张图锁死。分层后调位置只改坐标表(背景空档由背景层自己承担)。
|
||||
2. **物件没法复用**:图鉴提示里想放宝箱小图标、顶栏想放钥石徽 → 得另出一套小件。分层后同一张 PNG 直接缩着用。
|
||||
3. **命中区与剪影对不齐**:矩形热区必然误吞(点大门旁边的空地也进冒险),只能逐个手工调矩形,且物件形状越不规则误差越大。
|
||||
4. **遮挡关系写死在像素里**:现在篝火压在近景是画出来的,将来要在它后面加东西、或者把火焰做成动效,都得整图重出。
|
||||
5. **四态演示无法提前给作者看**:分层后可以在出图阶段就合成「常态/悬停/按下/禁用」四联图给作者判;整图方案要等代码写完才看得见反馈。
|
||||
|
||||
### 2.2 结论:分层,共 8 张 + 1 份坐标表
|
||||
|
||||
**交付形态 = 1 张背景层 + 7 张物件层 + 1 份坐标表**(8 张 PNG)。
|
||||
|
||||
| 层 | 文件名(草案) | 内容 | z 序 | 是否透明底 |
|
||||
|---|---|---|---|---|
|
||||
| L0 | `scene_camp_bg.png` | 远景天空 + 地面 + 中景围栏(**含门柱与门洞**,门洞内画通往远处的路)+ 远景植被/山;**不含七个可点物件的本体** | 0 | 否(全幅不透明) |
|
||||
| L1 | `scene_camp_board.png` | 布告板/悬赏板(挂在中景围栏上)→ 图鉴 | 1 | 是 |
|
||||
| L2 | `scene_camp_gate.png` | 大门门扇(叠在 L0 门洞上)→ 冒险 | 2 | 是 |
|
||||
| L3 | `scene_camp_dummy.png` | 木桩 → 天赋树 | 3 | 是 |
|
||||
| L4 | `scene_camp_forge.png` | 锻炉·铁砧 → 锻造工坊 | 3 | 是 |
|
||||
| L5 | `scene_camp_bed.png` | 床铺 →(承载笔记本,本体不可点) | 3 | 是 |
|
||||
| L6 | `scene_camp_chest.png` | 宝箱 → 秘宝匣 | 4 | 是 |
|
||||
| L7 | `scene_camp_notebook.png` | 床铺旁笔记本 → 生涯记录 | 4 | 是 |
|
||||
| L8 | `scene_camp_campfire.png` | 篝火 → 离开营地/回主菜单 | 5(最前) | 是 |
|
||||
|
||||
> **七个可点物件 = L1/L2/L3/L4/L6/L7/L8 七张**(床铺 L5 是承载件,不可点;笔记本挂它旁边)。
|
||||
> **四态不落素材**(2026-10-22 作者裁后改写):**悬停 = 给轮廓加亮边(描边发光)+ 浮动**,**不是整体提亮**——亮边由物件层 alpha 外扩 1px 派生,零手绘;按下 = 位移 1px(平移不是缩放,不触甲类整数倍缩放规则);**禁用/未解锁 = 变暗并调成灰度**(见 §9 ⑨,**作者特许破除 §2 明度禁令**,须登反哺点);已解锁 = 常态。
|
||||
> **若作者要「描边发光」式高亮**:不需要新出图——由物件层的透明通道自动外扩 1px 派生一张描边图(脚本生成,零生成成本)。这条正好回答「不分层就做不了描边」。
|
||||
|
||||
### 2.3 篝火与大门要不要区别对待
|
||||
|
||||
**要,两件各有各的特殊处,但都不是「不分离」的理由**:
|
||||
|
||||
- **篝火**(近景居中、可能遮挡):它是**最该分离**的一件——① 它是 z 序最前的近景件,分离后遮挡由代码 z 序管,背景不会被它烧进去;② 它绑「离开营地」这个高代价动作,命中区要单独定(建议与躯干等宽、不含火焰上部飘动区,防误点);③ 火焰是将来唯一可能带动效的件,分离后加帧只动它一张。
|
||||
- 过渡规格先出**静态一张**;若作者要火焰动效,后补 2–4 帧(同方向稿续写锁定形态),属后续画质档,本次非目标。
|
||||
- **大门**(中景、与围栏连体):**背景层画全门柱与门洞**,大门物件层只画**门扇**叠在门洞上。这样分层边界天然(门柱内框 = 对位锚),且不会出现「背景缺个洞」的空洞问题。
|
||||
- **已裁(2026-10-22):门扇=半开**,门洞内**画一条通向远处的小路**(暗示「出去即冒险」)。两扇门同属一张 `scene_camp_gate.png`,接缝一起落在同一命中矩形内。
|
||||
|
||||
### 2.4 分了层,AI 能不能保证七个物件与背景风格一致
|
||||
|
||||
**单靠「同一对话续写」不行**——项目实证:同对话续写 = 对上一张图的**编辑模式**(会被当成增量修图),变体必须各开新对话。所以续写恰恰是风格漂移的来源,不是解法。
|
||||
|
||||
**靠三道,按硬度排序**:
|
||||
|
||||
1. **硬办法 · 拼表制(首选)**:**一张图里画完全部物件**,出完按网格裁开。同一张图内不可能出现两种像素密度、两种描边——风格一致性由「同源」保证,不靠模型自觉。这是本项目瓦片批已验证的制式(2×2 拼表一张出全族)。
|
||||
- 适配到本件:七件尺寸差异大,用**不等分网格 + 每件一个标注框**的排版(提示词写明「七个独立物件,各自占据一个矩形区域,区域之间留统一浅灰间隔,物件的任何像素不得越出自己的区域,不得画任何边框/标签/文字」)。
|
||||
- 兜底:若拼表连续失败(模型坚持画框/串位),退回**一张一跑**,改靠第 2、3 道收口。
|
||||
2. **软办法 · 风格参考图**:出图时贴**已定稿的项目素材**(主角立绘/已定档敌人/瓦片纹理任择)并带既有句式「只是风格参考,只对齐像素密度、平涂、亮暖白描边与暖色限制调色板,不许抄服装道具配件」。目标是把**像素密度与描边**锚到既有世界观上。
|
||||
3. **兜底 · 后处理统一**:抠底 → 最近邻降采样到统一像素密度 → 色板量化到同一套板 → 描边统一(缺描边的件由脚本按 alpha 外扩补一圈亮暖白描边)。三道做完,风格差异被压到只剩造型差异(造型差异是好事,七个物件本来就该长得不一样)。
|
||||
|
||||
### 2.5 分层的代价:位置谁定、对位怎么保证
|
||||
|
||||
| 代价项 | 谁定 | 怎么保证 |
|
||||
|---|---|---|
|
||||
| **七件摆哪儿** | **作者定方向**(纵深稿已给:中景围栏+大门、近景中间篝火、左锻炉铁砧、右床铺与宝箱),Agent 出**灰块布局稿**(1280×800,七个编号矩形 + z 序标注)供作者调 | 布局稿 = 唯一坐标事实源,后续所有出图都贴它作参考锚 |
|
||||
| **对位精度** | 出图后由**脚本按坐标表合成** | 合成图与方向稿并排,逐件锚点误差 **≤2px**;物件层边缘**无 1px 半透明毛边**(硬边/无抗锯齿纪律) |
|
||||
| **坐标表格式** | 实现批定(建议走代码常量单点,与 `UiKit.TEX_*` 同处;或 `.tres` 落 `data/tables/`,按数值单一事实源口径) | 表必须含四列:**物件键 / 贴图锚点 (x,y) / 命中矩形 (x,y,w,h) / z 序** |
|
||||
| **背景空档** | 背景层自己承担 | 背景层画全(含门洞、地面、围栏完整),物件层只是叠上去,移走任何一件背景都不露洞 |
|
||||
|
||||
**坐标草案 v3(2026-10-22 · 作者已接受)**
|
||||
|
||||
口径(用户 2026-10-22 亲自定):**只有最左、最右两件往边上推;不靠边的那些不许贴边**——它们按「离画面中心的距离」成比例往外挪一点点(最外挪 ~80,第二圈 ~40,中轴 0)。**物件尺寸一律不变**,拉开的是它们之间的**间隔**。
|
||||
|
||||
做法:**以中心线 x=640 为原点等比外扩,k=1.20**,只改 x、不动 y 与尺寸。v2「所有物件一律贴边」的做法已被否决作废(把非边缘件也拽到边上,无故且无意义)。
|
||||
|
||||
| 物件 | 层 | v1 基线 x | **v3 命中矩形 (x, y, w, h)** | 外移量 | z 序 | 可点 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 锻炉·铁砧(最左) | L4 | 120 | **`(40, 420, 240, 240)`** | −80 | 3 | 是 → 锻造工坊 |
|
||||
| 木桩 | L3 | 380 | **`(340, 520, 120, 180)`** | −40 | 3 | 是 → 天赋树 |
|
||||
| 篝火 | L8 | 560 | **`(560, 560, 160, 160)`** | 0 | 5 | 是 → 离开营地 |
|
||||
| 大门(门扇) | L2 | 520 | **`(520, 250, 240, 220)`** | 0 | 2 | 是 → 冒险 |
|
||||
| 布告板 | L1 | 800 | **`(845, 330, 130, 140)`** | +45 | 1 | 是 → 图鉴 |
|
||||
| 笔记本 | L7 | 770 | **`(818, 690, 100, 80)`** | +48 | 4 | 是 → 生涯记录 |
|
||||
| 床铺 | L5 | 880 | **`(958, 520, 300, 170)`** | +78 | 3 | **否**(承载件) |
|
||||
| 宝箱 | L6 | 1000 | **`(1085, 700, 130, 90)`** | +85 | 4 | 是 → 秘宝匣 |
|
||||
|
||||
配套约束(2026-10-22 更新):顶栏 HUD 保留带 = **`y ≤ 48`**(§9 ⑤⑦:一行量、浮层覆盖),八矩形全部落在其下方;中景围栏横贯约 `y ≈ 500`(画在背景层);**八个命中矩形两两不相交**(已逐对校验;y 方向分离的有:大门/篝火、布告板/床铺、床铺/宝箱);间隙最小的两处 = 笔记本右缘↔床铺左缘 40px、锻炉右缘↔木桩左缘 60px。
|
||||
|
||||
**⚠ 唯一例外件(2026-10-22 作者裁)**:**篝火的「贴图矩形 ≠ 命中矩形」**——整张 `scene_camp_campfire.png` 仍画火堆+火焰,**命中矩形只取下半(火堆),上半=火焰只作特效展示、不可点**(防误点「离开营地」)。这是八个件里唯一两栏不一致的,**实现批坐标表必须用两列表达**(贴图矩形 / 命中矩形),其余七件两栏相同。具体分界数值**等成图后按实际画面切**(现在定死无意义)。火焰动效本次不做(作者令),过渡档=静态一张;将来要动效只需给这一层补帧(分层的收益)。
|
||||
|
||||
### 2.6 分层后,探针与断言怎么验「物件在正确的位置上」
|
||||
|
||||
分三层验,**前两层是机检主力,第三层是兜底**:
|
||||
|
||||
1. **几何断言(零渲染,最便宜)**——七件命中矩形两两不相交;每个矩形不越出 1280×800;不侵入顶栏 HUD 保留带(`y ≤ 48`,§9 ⑤⑦);最小命中尺寸 ≥ 64×64(小件笔记本允许 ≥48×48,并允许命中区大于贴图本身,外扩补齐);**篝火用命中矩形(火堆)判定,不用贴图矩形**。
|
||||
2. **alpha 采样断言(这一条是「位置正确」的可机检近似)**——取每个命中矩形的中心点,断言该点在**对应物件层**上是不透明像素、在**其它六个物件层**上是透明像素。物件贴图摆错位置、坐标表抄错行、z 序写反,这条都会红。
|
||||
3. **可达性断言(功能主力)**——七件逐一合成点击,断言进入对应界面(契约 2,卡④ V2);这一条验的是「点得到」,前两条验的是「图摆对了」。
|
||||
|
||||
**变异验证**(新增断言必须验证过它会红):把某个物件的坐标表改错一行 → 第 2 条断言红;把某物件的命中区删掉 → 第 3 条红。注入 → 见红 → 精确还原 → 记录。
|
||||
|
||||
### 2.7 一句话结论
|
||||
|
||||
**分层,8 张(1 背景 + 7 可点物件 + 床铺承载件共 8 张图),配一份四列坐标表;四态全部走程序化(提亮/位移/幽灵化),零四态素材;风格一致靠拼表制硬压 + 风格参考图 + 后处理统一三道。**
|
||||
|
||||
---
|
||||
|
||||
## 3. 议题 3 · 生成工作流(从空白到样张过审)
|
||||
|
||||
> 「谁做」列:作者 = 用户本人;Agent = 我(脚本/文档);管线 = 远程对话式生图(作者自跑)。
|
||||
|
||||
| 步 | 做什么 | 谁做 | 产出物 | 完成判据 |
|
||||
|---|---|---|---|---|
|
||||
| **S0 布局稿** ✅**已销号 2026-10-22** | 按纵深稿把七件摆到 1280×800 上 | Agent 出稿 → **作者已裁** | 坐标表=本文 **§2.5 坐标草案 v3** | v3 经作者目检通过;改动须显式提出 |
|
||||
| **S1 方向稿**(下一步) | 开 **3 个独立对话**,贴项目自家定稿素材作风格锚,出**整图构图候选**(背景+七件全画,不分层) | 作者出图 | `artwork/2026-10-23-营地场景/direction/v1.png v2.png v3.png` | 每张登记**模型名 + 分辨率 + seed + 对话/日期**(缺登记不入遴选);分辨率取平台**最大 16:10**(不小于 1024×640);提示词=**§13** |
|
||||
| **S2 选划方向** | 作者目检三张,选一张并点名要改什么 | **作者** | 选划记录(选了哪张 / 改什么 / 淘汰另两张的理由) | 作者一句裁定 |
|
||||
| **S3 分层出图** | 按定稿构图出:① 背景 1 张(1280×800 幅面)② 物件拼表 1–2 张(七件同图,浅灰 `#F2F2F2` 均匀底,便于抠图);每件 2–3 版候选 | 作者出图 | `.../layers/bg_v1-3.png`、`.../layers/props_v1-3.png` | 同 S1 登记义务;拼表图物件的任何像素不越出自己的区域、无边框无文字;**提示词待 S2 后另起** |
|
||||
| **S4 后处理** | 抠底转透明 → 最近邻降采样到统一像素密度 → 色板量化到既有板 → 描边统一 → 按布局尺寸裁成 8 张 | Agent(脚本管线) | `.../layers/out/*.png`(8 张透明 PNG)+ 机检读数 | `palette_check.py <目录> --baseline <基线目录>` 无新增色红灯;`standee_asset_check.py` 单张 32 色、无非整数缩放痕迹、描边亮度达标 |
|
||||
| **S5 合成校验** | 按坐标表把 8 张合到 1280×800,与 S2 选中的方向稿并排;另出**四态演示图**(常态/悬停/按下/禁用四联) | Agent | `.../composite_check.png` + `.../states_preview.png` | 逐件锚点误差 ≤2px;七命中矩形两两不重叠(脚本先跑一遍);四态四联一眼可辨 |
|
||||
| **S6 样张过审** | 作者目检合成图与四态演示 | **作者** | 一句「过/不过 + 改什么」 | 过 = 进 S7;不过 = 回 S3(改提示词重出)或回 S1(方向错了) |
|
||||
| **S7 落盘与挂链** | 终稿拷入 `game/assets/art/scene/`;代码侧先加 `UiKit.TEX_CAMP_*` 常量再接线(终稿文件名 = 代码消费名) | 实现批(**本次不做**) | 8 张终稿 + 常量 + 坐标表落码 | 反哺点中的**文档部分已于 2026-10-23 执行完毕**(见 §11:art-bible §6.2/§7.5/§2.8/§2/§4.1 改版、camp.md 整体改版、asset-path-map §3 增 `scene/`);剩余为代码侧常量与落码 |
|
||||
|
||||
**出图分辨率纪律(像素硬规则)**:源档按**终稿的整数倍**出(建议 2×:背景 2560×1600 → 降采样到 1280×800;物件件按布局尺寸 ×2 出),降采样走最近邻(放大缩小不做平滑插值,保硬像素边)。**禁止非整数倍降采样**——甲类(语义件/环境结构件)严格整数倍。
|
||||
|
||||
**参考物到位后的处置**:作者找到参照物 → 与纵深稿对表;结构性冲突(比如参照的营地根本没有围栏/大门)→ **呈报订正构图,不在批内私改**(卡④ L3 条)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 命名与消费链(先定消费名,防断链)
|
||||
|
||||
命名按 art-bible §8.3:`<域>_<对象键>_<状态|变体>.png`,全小写 snake_case。新增语义子目录 `scene/`(现有仅 board/character/fx/ui)。
|
||||
|
||||
| 消费常量(草案,实现批落 `UiKit`) | 资源路径 | 可点 |
|
||||
|---|---|---|
|
||||
| `TEX_CAMP_BG` | `res://assets/art/scene/scene_camp_bg.png` | 否 |
|
||||
| `TEX_CAMP_GATE` | `res://assets/art/scene/scene_camp_gate.png` | 是 → 冒险 |
|
||||
| `TEX_CAMP_FORGE` | `res://assets/art/scene/scene_camp_forge.png` | 是 → 锻造工坊 |
|
||||
| `TEX_CAMP_CHEST` | `res://assets/art/scene/scene_camp_chest.png` | 是 → 秘宝匣 |
|
||||
| `TEX_CAMP_NOTEBOOK` | `res://assets/art/scene/scene_camp_notebook.png` | 是 → 生涯记录 |
|
||||
| `TEX_CAMP_DUMMY` | `res://assets/art/scene/scene_camp_dummy.png` | 是 → 天赋树 |
|
||||
| `TEX_CAMP_BOARD` | `res://assets/art/scene/scene_camp_board.png` | 是 → 图鉴(占位态) |
|
||||
| `TEX_CAMP_CAMPFIRE` | `res://assets/art/scene/scene_camp_campfire.png` | 是 → 离开营地 |
|
||||
| `TEX_CAMP_BED` | `res://assets/art/scene/scene_camp_bed.png` | 否(承载件) |
|
||||
|
||||
装载一律 `UiKit.load_tex`(素材不入 git,缺位要有回退),**禁 preload**(asset-path-map §2)。
|
||||
|
||||
> **状态(2026-10-23)**:本节命名与 `game/assets/art/scene/` 子目录**已随文档批写入 `asset-path-map` §3**(commit `47907625`),本节与该文件互为一致;常量 `TEX_CAMP_*` 仍待实现批落码。
|
||||
|
||||
---
|
||||
|
||||
## 5. 样张验收判据(QA 回头照这张表判)
|
||||
|
||||
| # | 判据 | 怎么判 |
|
||||
|---|---|---|
|
||||
| **Y1 色数** | ①**单张 PNG ≤32 色**(像素域硬闸,不变);②色板按 **§9⑥ 乙口径**:语义/UI token 48 不动,**每屏一套环境子板 ≤32 色、允许跨屏不共享** | `palette_check.py <目录> --baseline <基线目录>` + `standee_asset_check.py`;超了走「换色合并」,**禁加色绕行** |
|
||||
| **Y2 色域** | 吸色全扫 **无 HSV 300°–345°**(禁紫/洋红);主色域 = 烛光黄 `#F6C667` × 木色 `#8A5A34` 暖色相,中等饱和(饱和 ≤0.55) | 脚本吸色统计;建议暖色相像素占比判据由作者定一档 |
|
||||
| **Y3 新色双门** | 新增色仍过两门:① 不占语义色段(红只说危险/金只说收益/蓝只说己方)② 与既有任一色 RGB 三通道差 ≥8/255。**注**:按乙口径,新增的**环境色**归所属屏的环境子板,**不再挤占 48 token 额度** | `palette_check.py` |
|
||||
| **Y4 明度档** | 三档带成立:信息面层(顶栏 HUD/提示名牌)> 世界中层(七物件)> 世界底层(地面/远景),层间灰度可分;**明度序在渲染合成空间(伽马)排档**——按 CIE L* 线性排会把序排反(本项目实测教训) | 截图转灰度抽测 + 作者目检 |
|
||||
| **Y5 像素纪律** | 纹理过滤 Nearest;像素网格对齐、**硬边、无渐变、无抗锯齿**(放大 4× 目检无中间过渡色);无 1px 半透明毛边 | `standee_asset_check.py` + 放大目检 |
|
||||
| **Y6 物件可辨性** | 转灰度后七件剪影**两两可辨**(不混);每件在 1280×800 上最小外接矩形 ≥64×64(笔记本可 ≥40×40,命中区外扩补到 ≥48×48);七件均带亮暖白描边(§5.1 轮廓通道,禁黑描边) | 灰度图目检 + 脚本量外接矩形 |
|
||||
| **Y7 可点区域** | 七命中矩形**两两不相交**;不越出画面;**不侵入顶栏保留带(y ≤ 48)**;最小 64×64;中心点落在对应物件的不透明像素上且**不落在其它六件上**;**篝火按「命中矩形(火堆)」而非贴图矩形判定** | 脚本几何断言(实现批落探针) |
|
||||
| **Y8 对位** | 合成图与 S2 选中方向稿逐件锚点误差 **≤2px**;移走任一物件背景不露洞 | 并排对比 + 脚本差分 |
|
||||
| **Y9 风格一致** | 八张图 1× 像素密度一致(放大后色块大小相同)、描边同色同粗、色域同源 | 八件并排目检(机检不判气质) |
|
||||
| **Y10 文字与结构** | 顶栏/HUD/提示名牌文字对直接底 **≥4.5:1**(大字 ≥3:1);围栏/门柱/石板等结构**必须是画出来的结构件**,禁以渐变/滤镜伪造(§8.5) | 对比度实测 + 放大目检 |
|
||||
|
||||
**不机检、归作者目检的三项**:构图气质(纵深稿味道对不对)、七件一眼找得到(可辨性终审)、四态反馈手感。
|
||||
|
||||
---
|
||||
|
||||
## 6. 待裁清单状态(2026-10-22 更新)
|
||||
|
||||
**已销号**:
|
||||
|
||||
1. ✅ **渠道** = B 插画级新产(§1.2)|卡④ P1 销号
|
||||
2. ✅ **规格口径** = 沿用 `art-bible` §8.1/§8.2 既有裁决,营地不单开例外(§1.2 ⚠ 条)
|
||||
3. ✅ **参照物** = 讨论阶段不需要,S1 开工前由我提醒(§9 ⑧)
|
||||
4. ✅ **门扇形态** = 半开(§9 ①)
|
||||
5. ✅ **篝火命中区** = 只含火堆不含火焰;火焰动效本次不谈(§9 ②)
|
||||
6. ✅ **顶栏** = 一行量、高 48px、浮层覆盖、素材仍 1280×800(§9 ⑤⑦)
|
||||
7. ✅ **S0 布局坐标** = v3 已目检接受(§2.5)——后续改动须显式提出,会连带改对位/命中区断言
|
||||
8. ✅ **色板口径** = 乙 · 分层(§9 ⑥)
|
||||
|
||||
**仍待裁 / 待补**:
|
||||
|
||||
1. ~~顶栏形态~~ ✅ 已定=全宽窄条 48px(§9 ⑦)
|
||||
2. ~~名牌文案七条~~ ✅ 已定(§9 ③)
|
||||
3. ~~门洞远景画不画小路~~ ✅ 已定=画(§9 ①)
|
||||
4. ~~色板加不加新色~~ ✅ 已定=允许加;额度不足时呈报作者压缩(§9 ⑩)
|
||||
5. ~~禁用态给不给~~ ✅ 已定=给,仅锻炉与宝箱,表现=变暗+灰度(§9 ⑨)
|
||||
6. **篝火「命中矩形」的具体数值** —— 规则已定(只取下半=火堆,上半=火焰只展示),**数值归实现批按成图裁切定**
|
||||
7. ✅ **P5 落文的文档部分已于 2026-10-23 执行完毕**(§11,commit `47907625`):camp.md 整份重写、art-bible §2/§2.8/§4.1/§6.2/§7.5/§7.6 改版。**剩余=代码侧**(`UiKit.TEX_CAMP_*` 常量与落码)
|
||||
8. ✅ ~~**§8 提示词草稿**~~ → **已由 §13 取代**:旧稿被删(与已定裁定冲突),**新提示词 v2 已按全部定稿裁定重新起草**。
|
||||
9. **下一步=S1 出方向稿**(作者跑生图)→ S2 作者选划 → 反馈改词 → 再出。当前等作者的预览图。
|
||||
|
||||
---
|
||||
|
||||
## 9. 讨论裁定记录(2026-10-22)
|
||||
|
||||
> **性质**:讨论段决定,尚未落实任何素材与代码。**作者 2026-10-22 令=先写进本文档、暂不提交**,待本轮议题全部结束后统一处置(会话内容不留存,只认文件)。
|
||||
> 已并入上文的:渠道=B(§1)、规格=沿用既有口径(§1.2)、坐标=v3(§2.5)、篝火贴图/命中两分(§2.5 末)。
|
||||
|
||||
| # | 裁定 | 连带影响 / 待办 |
|
||||
|---|---|---|
|
||||
| ① | **门扇=半开** | 与既有结构一致(背景画门柱+门洞、门扇叠在洞上)。**已定(2026-10-22)**:门洞=营地大门的门洞(半开门扇透出处),**画一条通向远处的小路**,暗示「出去即冒险」 |
|
||||
| ② | **篝火命中区只含火堆、不含火焰** | 篝火=唯一「贴图矩形 ≠ 命中矩形」的件,坐标表须两列表表达;**火焰动效本次不谈**(作者令),过渡档=静态一张 |
|
||||
| ③ | **悬停反馈=轮廓亮边 + 浮动 + 名牌**(2026-10-22 作者更正:**不是整体提亮**,是给轮廓加亮边) | 亮边=按物件层 alpha 外扩 1px 派生(零手绘、零新素材);**浮动⚠必须整像素吸附**(每帧 `round()`,否则 Nearest 下边缘抖/糊,须写成验收项),幅度 **±2px、周期约 0.5s**(作者认可);**名牌**=物件**下方 8px 水平居中**(作者认可),字号走 §7.4 tooltip 档 14px、对比 ≥4.5:1、不压物件本体;**文案七条**:开始冒险/锻造工坊/秘宝匣/生涯记录/天赋树/奖励格图鉴/离开营地(取自现役界面名) |
|
||||
| ⑨ | **禁用态=变暗 + 调灰度**(2026-10-22 作者裁) | ⚠ **作者特许破除 `art-bible` §2 明度禁令**(原「不动明度」、§6.2「亮起只走饱和/色相」)与 §7.6 按钮禁用态(α0.45 幽灵化)——**本项须登记为反哺点,由文档批改条款,不私下改规矩**。适用范围:**只有锻炉(锻造工坊)与宝箱(秘宝匣)两件**会进入禁用态(依据 `camp_overlay_view.gd:111`「🔒 锻造工坊未开放」、`:25-31` 两柜台锁定态行);**其余五件恒可点**;布告板(图鉴)是内容冻结未激活,**不是锁定**,不做禁用态 |
|
||||
| ⑩ | **色板:允许新增颜色**(2026-10-22 作者裁) | 过渡档**不再一律压回既有色板**;按 §9⑥ 乙口径加**环境色**(归每屏环境子板)。**额度不够时呈报作者**,由作者决定如何压缩既有色 |
|
||||
| ④ | **篝火「离开营地」必须二次确认** | ⚠ **改判**:推翻卡④ §9-4 既有代拍板(原「默认直回」),须登记为反哺点;实现复用**删档二次确认**的既有形态(澄清⑤裁决 3),零新控件 |
|
||||
|
||||
| ⑤ | **顶部信息只保留「一行的量」;顶栏高度=48px**(2026-10-22 作者裁,重要) | 内容 = 钥石图标 32px(64 源 ×0.5 显示档,asset-path-map §2)+ 余额文字一行(FS_BODY 16);**不加第二行、不放大按钮**。48 = 32 + 上下各 8,8/16 整数倍、图标在条内居中(备选 44=与现役 AP 条同高,未采用)。作废的 64/96/80/72 见本节末留痕 |
|
||||
| ⑥ | **色板=乙 · 分层口径**(2026-10-22 作者裁) | 语义/UI token 48 不动;**新增「每屏环境子板」:每屏一套 ≤32 色、允许跨屏不共享**;单张 PNG ≤32 色这条不变。落实需走文档批改 `art-bible` §4.1 措辞(反哺点) |
|
||||
| ⑦ | **顶栏=浮层覆盖在画面上层,形态=全宽窄条,高 48px,素材仍 1280×800,不挤压、不缩放、不变形**(2026-10-22 作者裁) | v3 坐标零影响(最高物件大门 y=250)。禁区判定:全宽 `y ≤ 48` |
|
||||
| ⑧ | **参照物=讨论阶段不需要**(2026-10-22 作者裁) | 由 Agent 在「开始生成美术素材(S1)」**之前**提醒作者;不是本讨论阶段的阻塞项 |
|
||||
|
||||
**待办**:~~§8 提示词草稿~~ **已整段删除**(2026-10-22 作者令:草稿与已定裁定冲突,后续专门讨论生成时重新起草)。
|
||||
|
||||
**已作废的推导(留痕)**:曾按「占屏高百分比」比照 SNES《超级马里奥世界》(40/224=17.9%)与 Deltarune 幻想主机(16/144=11.1%),推出顶栏 96px——**作者否决**:取样太古老、像素尺度不同、无参考价值。改用近代像素 Roguelike/幸存者 like 后作废该结论(详见上表 ⑤)。
|
||||
|
||||
## 11. 既有条款修订清单(2026-10-22 核定,**2026-10-23 已执行**)
|
||||
|
||||
> **执行结果**:worktree `D:/code/g-plan2-camp-art-doc`(分支 `camp-art-doc-20261023`)→ commit `569db112` → **`git merge --no-ff` 合回 master = `47907625`**;**文档域闸 `tools/run_all_gates.sh --docs` 全绿**(闸况与基线一致、无新增红;过程中修掉 1 处死链:`HUD框架` 指路 camp.md 应为 `../../ux/camp.md`)。主工作区 status CLEAN。
|
||||
>
|
||||
> 本轮讨论的裁定与 `design/` 既有条款冲突者共 **10 项**(另加 GDD 侧「柜台」用词 9 处,以及补扫出的 `元进度.md` 5 处、`HUD框架.md` 2 处)。作者令:**逐条定改法 → 随本会话文档一并修改并提交**(走 worktree,不碰主区)。下表为**改法记录**,条文已按此改完。
|
||||
|
||||
| # | 条款 | 改法(作者 2026-10-22 裁) | 状态 |
|
||||
|---|---|---|---|
|
||||
| 1 | `art-bible` §2 头注明度禁令 | **缩窄范围**:删去「状态表达」这个禁止项,只保留「情绪表达」;**不设例外条款** | ✅ 措辞已定,见下 |
|
||||
| 2 | `art-bible` §2.8 菜单与元进度 | **删旧写新**:「营地三柜台一字排开」整句换成七物件可点场景图 | ✅ 措辞已定,见下 |
|
||||
| 3 | `art-bible` §4.1 色板 | **新增一款**(原文不动):色板分层=语义/UI token 48 + 每屏环境子板 ≤32 | ✅ 措辞已定,见下 |
|
||||
| 4 | `art-bible` §6.2 营地场景 | **整条重写**:七物件场景图 + 分层 + 四态 + 顶栏 | ✅ 措辞已定,见下 |
|
||||
| 5 | `art-bible` §7.5 营地界面 | **整条重写** | ✅ 措辞已定,见下 |
|
||||
| 6 | `art-bible` §7.6(一)禁用态 | **加一句注**:本条管 UI 按钮,场景物件另按 §6.2 | ✅ 措辞已定,见下 |
|
||||
| 7 | `camp.md` | **整份重写**(场景图 + 七物件点选 + 顶栏 + 叠层) | ✅ 措辞已定,见下 |
|
||||
| 8 | `asset-path-map` §3 | **加一行**:新增 `scene/` 子目录 | ✅ 措辞已定,见下 |
|
||||
| 9 | `art-assets-checklist` §3.5(含 :175) | **整条重写**为营地场景图 | ✅ 措辞已定,见下 |
|
||||
| 10 | `art-status-checklist`:32 | 条目名改「营地场景图」,依据改指 §6.2 | ✅ 措辞已定,见下 |
|
||||
| 附 | GDD 侧「柜台」用词 9 处 | **直接更正为新的营地说法**(作者令:不必逐条裁) | ✅ 措辞已定,见下 |
|
||||
|
||||
### 第 1 条 · `art-bible` §2 头注
|
||||
|
||||
**现行**:「`禁令保留`:明度变化仍禁止用于**状态表达与情绪表达**——状态区分只允许**色相、饱和、运动、元素**四手段;roguelike 失败重开,世界无光暗记忆;Darkest Dungeon 式压暗仍在 §9.2 反面清单。」
|
||||
|
||||
**改为**:「`禁令保留(2026-10-22 缩窄至情绪域)`:明度变化禁止用于**情绪表达**——画面不得靠压暗/渐晕阴沉下来;roguelike 失败重开,世界无光暗记忆;Darkest Dungeon 式压暗仍在 §9.2 反面清单。**状态表达不受本禁令约束**:状态可用明度、色相、饱和、运动、元素任一手段承载。」
|
||||
|
||||
(同段其余不动:明度三档带分层、空间纵深/光照氛围/形体塑造允许域、§4.2 类型微光明度梯度一句,全部原样保留。)
|
||||
|
||||
**影响核查**:现有冒烟断言里编码「禁用态 α0.45」的只有 UI 按钮(`smoke_all.gd:6526/6551/6563`,归 §7.6),**没有**任何断言编码「明度禁用于状态」→ 本条改动不牵动现役断言。
|
||||
|
||||
### 第 2 条 · `art-bible` §2.8 菜单与元进度(目标措辞)
|
||||
|
||||
**现行(最后一行)**:`承载元素`:营地三柜台(属性锻造/秘宝匣/奖励格图鉴)在烛光下一字排开——场景构成、柜台亮光与钥石呈现位连同系统语义边界一并见 §6.2
|
||||
|
||||
**改为**:`承载元素`:**一张可点击的营地场景图**——远景天空与远山,中景围栏与半开的营地大门,近景中央的篝火,左侧锻炉铁砧,右侧床铺与宝箱、床边的笔记本,另有木桩与挂在围栏上的布告板;点画面里的物件进入对应界面(冒险/锻造工坊/秘宝匣/生涯记录/天赋树/图鉴/离开营地)。钥石余额常驻画面顶部的一行小 HUD 栏。场景构成、七物件绑定与呈现位见 §6.2
|
||||
|
||||
(本条其余四行——主情绪「可靠的营地感」、色彩性格「全作最暖烛光黄与木色」、氛围形容词、能量 3/10——**全部保留不动**。)
|
||||
|
||||
### 第 3 条 · `art-bible` §4.1 色板(新增一款,原文不动)
|
||||
|
||||
在 §4.1「色板增量纪律」之后**新增**一款(原文全部保留):
|
||||
|
||||
> **色板分层(2026-10-22 作者裁)**:色板分两层管理——① **语义/UI token 板**:全作共享,硬上限 **48 色**,管 UI 语义色、墨色、材质色,跨屏恒定;② **场景环境子板**:**每屏一套,≤32 色,允许跨屏不共享**(环境色=天空、地面、植被、石材、火焰等随场景走的颜色)。新增环境色仍须过两道门(§4.2 语义检查 + 与既有任一色 RGB 三通道差 ≥8/255),但**不占用 48 token 额度**;不过门照旧走「换色合并」,**禁加色绕行**。单张 PNG 的像素域色数上限 **≤32 色**另由 `standee_asset_check` 执法(像素域口径,与本表 token 口径互不干扰)。额度不足时呈报作者,由作者决定压缩或合并既有色。
|
||||
|
||||
### 第 4 条 · `art-bible` §6.2 营地场景(整条重写)
|
||||
|
||||
**现行**:三柜台一字排开 + 柜台=石板圆角容器 + 「亮起只走饱和/色相,不动明度」+ 事实源边界。
|
||||
|
||||
**改为**:
|
||||
|
||||
> ### 6.2 营地场景
|
||||
> - **情绪与色域**:承载 §2.8——全作最暖:烛光黄 `#F6C667` × 木色 `#8A5A34`(§7.2),中等饱和,无棋盘式高对比。
|
||||
> - **场景构成**:一张可点击的营地场景图(1280×800,与工程档同幅面)。远景=天空与远山;中景=木围栏与**半开的营地大门**(门洞内一条通向远处的小路);近景=中央篝火、左侧锻炉铁砧、右侧床铺与宝箱、床边的笔记本,另有木桩与挂在围栏上的布告板。七个可点物件的功能绑定归 `camp.md`,本节只定画法。
|
||||
> - **交付形态**:**背景 1 层 + 七个物件各 1 层**(床铺为承载件、不可点),共 8 张透明 PNG + 一份坐标表(贴图矩形/命中矩形/z 序)。**篝火例外**:命中矩形只取下半(火堆),上半(火焰)只作特效展示。
|
||||
> - **交互四态(零新素材,全部程序化)**:悬停=**轮廓亮边 + 浮动**(浮动须整像素吸附);按下=位移 1px;**禁用/未解锁=降明度 + 去饱和**(§2 已缩窄至情绪域,状态表达不受限),**仅锻炉(锻造工坊)与宝箱(秘宝匣)两件会有此态**;已解锁=常态。
|
||||
> - **钥石余额**:常驻画面顶部的一行小 HUD 栏(高 48px,**浮层覆盖,不挤压画面**)。
|
||||
> - **事实源边界**:解锁条件/价格/存档写入归元进度 GDD 与 `MetaProgression`;素材命名与路径归 `asset-path-map`;清单登记归 `art-assets-checklist` §3.5。
|
||||
|
||||
### 第 5 条 · `art-bible` §7.5 营地界面(整条重写)
|
||||
|
||||
> - 营地界面=**一张可点击的场景图 + 七物件点选**:点画面里的物件进入对应界面(冒险/锻造工坊/秘宝匣/生涯记录/天赋树/图鉴/离开营地)。场景图的画法、分层与四态见 §6.2;色域走 §7.2 最暖一档;钥石余额常驻顶部一行小 HUD 栏。界面视觉终稿以表现层样张过审为前置(§1.4 整屏样张闸)。
|
||||
|
||||
### 第 6 条 · `art-bible` §7.6(一)按钮禁用态(加一句注,原文不动)
|
||||
|
||||
在「禁用 = 本族底 + α0.45 幽灵化(甲案)」条目末**追加**:
|
||||
|
||||
> (注:本条管 **UI 按钮**;营地场景图里的**物件**禁用态另按 §6.2——降明度 + 去饱和,不走 α 幽灵化。)
|
||||
|
||||
### GDD 侧「柜台」用词清理(一并改,共 9 处)
|
||||
|
||||
| 文件:行 | 现行 | 改为 |
|
||||
|---|---|---|
|
||||
| `术语表.md:43` | 秘宝匣|营地**柜台之一**:… | 秘宝匣|营地**功能界面之一**(场景图里点**宝箱**进入):… |
|
||||
| `术语表.md:56` | 锻造工坊|营地**四柜台之一**:… | 锻造工坊|营地**功能界面之一**(场景图里点**锻炉·铁砧**进入):…(顺带消除 43/56 条"三柜台 vs 四柜台"自相矛盾) |
|
||||
| `02-系统清单.md:82` | camp.md|营地覆盖层 UX spec:**三柜台呈现**、钥石余额… | camp.md|营地 UX spec:**可点击场景图与七物件点选**、钥石余额、各功能界面入口… |
|
||||
| `08-Alpha版本标准.md:106` | 营地(天赋树/锻造工坊/秘宝匣/图鉴)…锻造**柜台**占位面板注已解除;**柜台贴图**占位… | 营地(**场景图** + 天赋树/锻造工坊/秘宝匣/图鉴/生涯)…**场景图与七物件点选**随营地交互重做列入 Alpha… |
|
||||
| `08-Alpha版本标准.md:200` | …**营地柜台贴图**已随营地交互重做列入 Alpha | …**营地场景图**已随营地交互重做列入 Alpha |
|
||||
| `05-不做清单.md:22` | …首批已落地(营地**三柜台**/钥石/跨局注入) | …首批已落地(**营地**/钥石/跨局注入) |
|
||||
| `01-核心循环.md:156` | …`unlock_requires` 字段 + **工坊柜台** + 里程碑分档发槽 | …`unlock_requires` 字段 + **锻造工坊界面** + 里程碑分档发槽 |
|
||||
| `03-内容规模.md:59` | 扩**柜台**或改定价结构走… | 扩**锻造路线**或改定价结构走… |
|
||||
| `ux/level-clear.md:64` | …**营地柜台全量** | …**营地界面全量**(禁入语义不变) |
|
||||
|
||||
(`architecture/code-architecture.json:122` 与 `.html:5273-5284` 的「商品卡·三柜台」是**脚本生成的架构图节点副标签**,随实现批代码变更重生成,不在本次文档批改。)
|
||||
|
||||
### 第 7 条 · `camp.md`(整份重写)
|
||||
|
||||
**现行**:通篇是「四柜台覆盖层 + 石纹全屏底 + 三柜台列 + 底栏关闭钮 + 秘宝匣柜台呈现细则」。整体作废,替换为:
|
||||
|
||||
```markdown
|
||||
# 营地场景 UX spec(camp)
|
||||
|
||||
> 状态:v2.0(2026-10-22 营地交互重做美术设计段;取代旧「四柜台覆盖层」形态)
|
||||
> 事实源:本 spec(呈现)+ [元进度](../systems/跨局循环/元进度.md)(机制)
|
||||
> 美术画法:[art-bible](../art/art-bible.md) §6.2/§7.5;素材命名与路径:[asset-path-map](../art/asset-path-map.md)
|
||||
> 相邻:[level-map.md](level-map.md)(主菜单语境)
|
||||
|
||||
## 定位
|
||||
营地=存档内的局外枢纽(存档语境可达,冒险进行中不可达)。形态=**一张可点击的营地场景图**:画面里有篝火、锻炉、床铺等物件,点物件进对应界面。**不是按钮列表式 UI。**
|
||||
|
||||
## 场景构成与七物件绑定
|
||||
| 物件 | 进入 | 备注 |
|
||||
|---|---|---|
|
||||
| 大门(半开,门洞内一条通向远处的小路) | 冒险 | 点大门永远先出确认:有未完冒险=三出口(继续上一段/开始新冒险/取消);无=是否开始新冒险 |
|
||||
| 锻炉·铁砧 | 锻造工坊 | **未解锁=禁用态**(降明度+去饱和) |
|
||||
| 宝箱 | 秘宝匣 | **未解锁=禁用态**(同上) |
|
||||
| 床铺旁笔记本 | 生涯记录 | 生涯页返回钮文案**禁含「营地」字样**(`ui_struct_probe.gd` nojump 禁词表) |
|
||||
| 木桩 | 天赋树 | |
|
||||
| 布告板 | 奖励格图鉴 | 内容冻结未激活,点进看占位——**不是禁用态** |
|
||||
| 篝火 | 离开营地回主菜单 | **必须二次确认**;命中区只含火堆、不含火焰 |
|
||||
| 床铺 | — | 承载件,**不可点** |
|
||||
|
||||
纵深=远景天空与远山/中景围栏与大门/近景篝火与左右物件(作者纵深稿)。
|
||||
|
||||
## 点选反馈(根态)
|
||||
悬停=**轮廓亮边 + 浮动**(浮动须整像素吸附)+物件**名牌**(物件下方 8px 居中,FS_HINT 14,对比 ≥4.5:1);按下=位移 1px;禁用=降明度+去饱和;已解锁=常态。**四态零新素材**(全部程序化)。
|
||||
命中区:七件两两不相交、不越出画面、**不侵入顶栏禁区(y ≤ 48)**。
|
||||
|
||||
## 顶栏
|
||||
钥石余额常驻画面顶部一行小 HUD 栏(高 48px、全宽窄条、**浮层覆盖在场景图上层,不挤压画面**)。刷新入口=营地刷新单口(卡⑤同口挂接)。
|
||||
|
||||
## 叠层与开合
|
||||
各界面开合走模态栈单口,层序入 `LAYER_CONTRACT`。**承载形态(独立全屏页 vs 单一内页切换)与叠层规则归卡④ §9 代拍板域,本 spec 不预设值**;派生规则:独立全屏页=场景根隐藏/单一内页切换=场景根留底(「缩放虚化」为第三形态,禁批内自选)。ESC 浮窗(返回主菜单/设置/退出游戏)归卡⑤。
|
||||
|
||||
## 口径
|
||||
- 呈现数据源=MetaProgression 只读投影经组合根喂入;本层不持有系统资源、不算价。
|
||||
- 「最近冒险」条带已撤下(卡④ Q4=甲),逐局历史回看归生涯。
|
||||
- 旧「秘宝匣柜台呈现细则」随形态作废;秘宝匣界面内部呈现(解锁面+同调装配段)保留原条款,迁本文件附录暂管,待该界面立独立 spec 后迁出。
|
||||
```
|
||||
|
||||
### 第 8 条 · `asset-path-map` §3(加一行)
|
||||
|
||||
| 子目录 | 内容 | 现役 |
|
||||
|---|---|---|
|
||||
| `scene/` | **场景图**(背景层 + 可点物件层;2026-10-22 新增,营地场景图首批) | `scene_camp_bg`/`_gate`/`_forge`/`_chest`/`_notebook`/`_dummy`/`_board`/`_campfire`/`_bed`(九张,床铺=承载件不可点) |
|
||||
|
||||
### 第 9 条 · `art-assets-checklist` §3.5(整条重写,含 :175 子句)
|
||||
|
||||
> ### 3.5 营地场景图(2026-10-22 重写;原「营地与元进度件·三柜台」条目作废)
|
||||
> - **要什么**:营地场景图 9 张——`scene_camp_bg`(背景)+ `scene_camp_gate / forge / chest / notebook / dummy / board / campfire`(七个可点物件)+ `scene_camp_bed`(承载件)。钥石顶栏图标沿用现役 `icon_keystone`。
|
||||
> - **来源/规格**:**✦ 插画级**(作者自跑远程生图管线);烛光黄 `#F6C667` + 木色 `#8A5A34`(art-bible §6.2);2× 源档出图、最近邻降采样到 1280×800;后处理=抠底/降采样/色板量化/描边统一。**每张出图须登记模型名+分辨率+seed+对话/日期**。
|
||||
> - **排期**:营地交互重做**美术自立批**(不占迭代位;UI 贴图重构批已搁置)。终稿落 `game/assets/art/scene/`,消费常量 `UiKit.TEX_CAMP_*`。
|
||||
|
||||
(`:175` 原句「营地件(3.5)归 UI 贴图重构批」→ 改为「营地场景图(3.5)归营地交互重做美术自立批」。)
|
||||
|
||||
### 第 10 条 · `art-status-checklist`:32
|
||||
|
||||
`| 营地与元进度件 | ◐ | art-bible §4.4 |` → `| 营地场景图 | ◐ | art-bible §6.2 |`
|
||||
|
||||
---
|
||||
|
||||
## 12. 营地场景 · 分层元素描述表(2026-10-23)
|
||||
|
||||
> 用途:跳过外部参照物后的**替代输入**——先把"脑里的画面"落成文字,既是给作者确认,也是写提示词的直接依据。远景/中景/近景三层齐全。
|
||||
|
||||
**时间**:**白天(晴朗)**——推导依据:① 美术基调「明亮轻快」;② §2 明度禁令缩窄后**情绪/氛围仍禁压暗**,夜间必然压暗即违规;③ 篝火作营地炊火,白天点着成立,不冲突「全作最暖」。
|
||||
**天空元素**:**不画太阳**(§3.4 焦点预算:首焦唯一,背景禁构成完整凸形、禁抢焦);允许 **1–2 朵极简扁平云**,低对比,只为天空留层次。
|
||||
|
||||
### A. 背景层(1 张,1280×800,不透明全幅)
|
||||
|
||||
**层次分带**:远景=画面上部;**中景自底部往上约 2/3 处起**(≈ y 267);再往下全部是近景。
|
||||
|
||||
| 层次 | 元素 | 形态描述 | 画面位置 |
|
||||
|---|---|---|---|
|
||||
| 远景 | 天空 | 平涂,暖白偏米黄,上浅下略暖;**顶部 48px 保持空旷**(顶栏覆盖);无太阳,可有 1–2 朵极简扁平云 | y 0–200 |
|
||||
| 远景 | 远山 | 2–3 层低矮起伏**剪影**,越远越淡(明度走**世界底层档**);**不画远树**——树形并入山轮廓 | y 180–260 |
|
||||
| 远景 | 远景地面 | 远山脚下延伸到围栏背后的一片草地/土坡平涂色块;**不单独画地平线**(围栏横贯后不存在可见的地平线) | y 250–480 |
|
||||
| **中景** | **木围栏** | 横贯全宽的矮木栅:等距木桩 + 两道横木;**中段留缺口**给大门 | y ≈ 480–520;缺口 x 520–760 |
|
||||
| **中景** | **大门(门柱 + 门洞)** | 缺口两侧各一根粗木柱,柱顶略高出围栏;门洞内透出远景,一条向远处收缩的土路(暗示"出去即冒险") | 门柱 x ≈ 500–520 / 760–780;门洞 y 300–500 |
|
||||
| 近景 | 地面 | 干土与踩踏过的草;硬边色块,无渐变 | y 480–800 |
|
||||
|
||||
### B. 物件层(8 张,透明 PNG)
|
||||
|
||||
| 层次 | 物件 | 形态描述(识别特征) | 位置/大小(v3 坐标) | 可点 |
|
||||
|---|---|---|---|---|
|
||||
| **中景** | 大门**门扇** | **两扇半开**的木门,向外敞开一条缝;厚木板 + 横撑 + 深色铁件(门柱与门洞在背景层) | `(520,250,240,220)` | 是 → 冒险 |
|
||||
| **中景** | 布告板 | 挂**在围栏上**的木板,钉 2–3 张**空白**纸,纸角微翘 | `(845,330,130,140)` | 是 → 图鉴 |
|
||||
| 近景 | 锻炉·铁砧 | 石砌炉体 + 短烟囱,炉口透橙光;炉前一具深色铁砧(矮墩 + 平顶 + 一角外伸);**主体落在近景地面**,顶部略高于中景分带线 | `(40,420,240,240)` | 是 → 锻造工坊(**可能禁用态**) |
|
||||
| 近景 | 木桩 | 单根木柱立在地面,中段缠草绳/布垫,顶端略圆 | `(340,520,120,180)` | 是 → 天赋树 |
|
||||
| 近景 | 篝火 | 灰石围成一圈,中间交叉架柴;上方橙黄火焰(**上半=火焰只展示,不可点**) | `(560,560,160,160)` | 是(**仅下半火堆**)→ 离开营地 |
|
||||
| 近景 | 床铺 | 矮木架床 + 草垫 + 折好的毯子,床头略高 | `(958,520,300,170)` | **否**(承载件) |
|
||||
| 近景 | 宝箱 | 闭合的木箱,深色铁箍包边,正面一个小锁扣 | `(1085,700,130,90)` | 是 → 秘宝匣(**可能禁用态**) |
|
||||
| 近景 | 笔记本 | 摊开的小册子,平放在靠床头的位置,露出纸页 | `(818,690,100,80)` | 是 → 生涯记录 |
|
||||
|
||||
> **中景只有两样东西:木围栏(背景层)+ 营地大门(门柱门洞在背景层,门扇是物件层)**,另加挂在围栏上的布告板(物件层)。其余全部属于近景。
|
||||
|
||||
### C. 全画面通用约束
|
||||
|
||||
- **视角**:正侧平视(orthographic),所有物件同一侧角,**无透视变形**
|
||||
- **光照**:均匀,无长投影;每个物件正下方**只一个小的深色接地影**(不是情绪压暗)
|
||||
- **色域骨架**:烛光黄 `#F6C667`/木色 `#8A5A34`/掩尘 `#C9AF83`/裸土 `#B39A78`;天空、草、火焰等归**营地环境子板**(§9⑥ 乙口径)
|
||||
- **禁用**:无文字/字母/数字/水印;无边框;无角色与生物;无紫或洋红;无渐变、无抗锯齿;无暗角渐晕
|
||||
|
||||
---
|
||||
|
||||
## 13. S1 方向稿 · 生图提示词 v2(2026-10-23 定稿,取代已删的旧 §8)
|
||||
|
||||
> 依据=§12 分层元素描述表(已确认)。**整段可贴,不需拼装、不需读其他文件。**
|
||||
|
||||
```
|
||||
Pixel art style. True pixel art game scene drawn with chunky square pixels, strict pixel grid alignment, hard edges, no anti-aliasing, no gradients, flat colors only, a limited warm palette of about 24 colors, retro 16-bit look, Aseprite style, bright cheerful daytime fantasy, cozy and warm, all ages, flat side view, orthographic, no perspective distortion, every object drawn from the same side angle. Wide horizontal composition, 16:10 aspect ratio, showing a small adventurer camp on a grassy plain in clear daylight. SKY (top of frame): flat warm off-white sky, slightly warmer toward the bottom; the very top strip of the frame must stay calm and empty with nothing in it; no sun anywhere; at most one or two extremely simple flat low-contrast clouds. FAR DISTANCE: two or three layers of low rolling hill silhouettes, each layer paler than the one in front, no trees, no individual foliage, no visible horizon line — below the hills a flat band of distant grass and earth continues downward and is hidden behind the fence. MIDDLE GROUND (starting about two thirds up from the bottom edge): a low wooden fence running across the whole width of the frame, made of evenly spaced wooden posts and two horizontal rails, with one wide gap in the middle; in that gap stand two thick wooden gate posts slightly taller than the fence, and between them an opening showing a dirt path running away into the distance; in that opening hang two wooden gate leaves, half open, tilted outward, each made of thick planks with a cross brace and dark iron fittings. FOREGROUND GROUND: dry dirt and trodden grass, flat color blocks, hard edges, no gradient. Seven separate objects stand on this ground, each fully inside the frame, never cut off by the edges, never touching or overlapping another object, with clear empty ground visible all around it: on the left side, a stone forge with a short chimney and a warm orange glow in its mouth, and in front of it a dark iron anvil on a low block, the largest object on the left, its left edge close to the left border; to its right and slightly lower, a single wooden training post wrapped with a straw rope pad around its middle; at the bottom center, a campfire made of a ring of grey stones around crossed stacked logs with a warm orange-yellow flame above them; on the right side, a low wooden bed frame with a straw mattress and a folded blanket, the largest object on the right, its right edge close to the right border; below and slightly in front of the bed, a small closed wooden treasure chest with dark iron bands and a small lock plate; to the left of the chest, at the foot of the bed, a small open journal lying flat on the ground, the smallest object in the scene; hung on the fence on the right, a wooden notice board with two or three blank pinned papers, no writing on them. Warm color scheme throughout: candlelight yellow #F6C667 for firelight and highlights, wood brown #8A5A34 for every wooden structure, warm tan stone #C9AF83 for the forge and stones, dry warm earth brown #B39A78 for the ground, medium saturation, low contrast, even daylight, no long shadows, and only one small dark oval contact shadow directly beneath each object. Every object has a thin warm cream outline separating it from what is behind it. Do not add any of the following: realistic, photorealistic or 3D rendering; painterly brushwork, smooth anti-aliased lines, gradient or dithered shading, glossy highlights; black or heavy dark outlines; blur or compression artifacts; a vignette, dark corners, or any mood darkening; night, dusk, moon, stars, sunset or sunrise light; a sun or any light source drawn in the sky; a visible horizon line; trees, forests or foliage in the distance; any purple or magenta anywhere; any text, letters, numbers, watermark, signature or logo on any surface or paper; any frame, border, panel, arrow or UI element; any characters, people, creatures or animals; any object not listed above; any object overlapping, touching or hiding another object.
|
||||
```
|
||||
|
||||
### 出图设置(平台侧,不在提示词里)
|
||||
|
||||
| 项 | 设什么 |
|
||||
|---|---|
|
||||
| 张数 | **3 张,各开一个独立对话**(同对话续写=修图,不是变体) |
|
||||
| 分辨率 | 平台能选的**最大 16:10**(理想 1536×960 或 1280×800;不小于 1024×640) |
|
||||
| seed | 可取则取 |
|
||||
| 参考图 | 贴**项目自己的定稿素材**(主角立绘/瓦片纹理)作风格锚 —— 见下方追加句 |
|
||||
| 登记 | 每张记 **模型名 + 分辨率 + seed + 对话/日期**,随图存 `artwork/2026-10-23-营地场景/direction/`;缺登记不入遴选 |
|
||||
|
||||
### 贴参考图时的追加句
|
||||
|
||||
```
|
||||
Style reference: the attached image is this game's own finished pixel art — match only its rendering style, the same pixel density, flat shading, thin warm cream outline and warm limited palette. It is a style reference only: do not copy its character, gear or props, and do not put any character into the scene.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 14. 本轮确立的协作纪律(2026-10-22~23,作者逐条立)
|
||||
|
||||
> 这些是**本轮会话里立下的工作方式**,此前只存在于会话与记忆中,现固化于此,供后续批与后续会话照做。
|
||||
|
||||
1. **会话不留存**:每次新会话只读得到文件。**一切决定必须落文档**,不能"说过了就算"。
|
||||
2. **无证据的推荐值不采纳**:给任何推荐值前先自检是否有项目文档/代码出处。**证据在会话里举给作者判断即可,不写进文档**(作者原话:「证据是用来干什么的?是给我判断用的…你写到文档里面给谁看」)。
|
||||
3. **布局口径(作者原话)**:说「两边太空、往两边移」=**只把最左、最右那两个组件推向边缘**;**不靠边的绝不允许贴边**,它们按离中心的距离成比例外移(最外移 80、第二圈 40、中轴 0),**组件尺寸不变**,拉开的是间隔。
|
||||
4. **作者说了算**:改既有规矩时,Agent 的义务=**指出该裁定破了哪条既有规矩 + 登记反哺点**,由文档批改条款;**不反对、也不私下改规矩**。
|
||||
5. **焦点纪律**:本次会话的目标=营地场景图「**美术素材怎么生成**」。凡**不影响出图、不影响分层、不影响提示词**的实现侧事项(如五界面承载形态、叠层规则、屏壳改造),**在文档里引用该域、不预设值**,绝不端到作者面前当"待定项"。
|
||||
6. **能推导的直接定**:能从已定设计推出来的,**直接定值、报作者同意**;只有上下文里确实没定过的才问。不要把所有未决事项一股脑端上去。
|
||||
7. **陈旧概念一律删净**:重新设计就是要替换掉旧的;凡与新设计冲突的旧说法(如「三柜台/柜台」),**全部删干净、用新设计取代**,不逐条问"删还是改"。
|
||||
8. **方向稿先行**(卡④ Q8=甲):2~3 张低成本方向稿供选划,判完方向才精制。**外部参照物非必需**——风格锚用**项目自己的定稿素材**(比任何外部图都准),构图用纵深稿 + 坐标表。
|
||||
|
||||
---
|
||||
|
||||
## 7. 本次做了什么 / 没做什么(边界留痕 · 2026-10-23 更新)
|
||||
|
||||
**做了**:
|
||||
- 出图提示词 v2(§13)与分层元素描述表(§12)
|
||||
- **文档批已执行并合回 master**:15 个文件,commit `47907625`;文档域闸 `--docs` 全绿(§11)
|
||||
- 待办清单登记「营地五界面窗口化批」(优先级=绝对)
|
||||
- 参照物(首轮 6 张)已判定不合格并整目录删除
|
||||
|
||||
**没做**:
|
||||
- 未出图、未跑生图管线(等作者跑 S1)
|
||||
- 未改 `game/` 任何文件、未写需求卡片、未编迭代号
|
||||
- 未做代码侧:`UiKit.TEX_CAMP_*` 常量与落码(归实现批)
|
||||
- 旧条「每购得一件永久强化,对应柜台亮起一格暖光」随形态失效,**已随 §6.2 重写一并删除**(不再是候选事项)
|
||||
@@ -1,239 +0,0 @@
|
||||
# 需求卡片:主菜单三入口化批(6 钮 → 3 钮)· 营地交互重做卡②
|
||||
|
||||
- 版本:**v1.3**(现行身份:零待裁点+含 §7.1 改动—验收对照表〔按 test-conventions §9.3 六列与 §9.8 旧卡开工前补表口径〕+§7.2 测试削弱申报。既有定性:契约 5 中间态因卡④回设计段延长为工程批交付后的稳态)
|
||||
- 来源:[需求澄清-营地交互重做-2026-10-18.md](需求澄清-营地交互重做-2026-10-18.md)(唯一事实源:④结构树「主菜单(需改动:6 钮 → 3 钮)」、⑤裁决 1、②反参照、⑦切批原则②)
|
||||
- 归属:呈现层/组合根(`game/presentation/`)——营地交互重做五卡之二
|
||||
- 排期:未编入(2026-10-18 用户令:需求卡片不预占迭代号,批次归属按工作量另裁)
|
||||
- 开工门:U0(用户 `/iter` 发令);**零待裁点**;硬依赖卡③、中间态依赖卡④(见 §0/契约 5)
|
||||
|
||||
## 0. 前置依赖与并行性
|
||||
|
||||
- **硬依赖卡③(选档界面)**:「进入存档」钮的落点=选档界面。**本卡与卡③必须同批交付或卡③在先**(卡内推导,防死钮——澄清⑦只定切批原则,「同批或在先」是本卡的防死钮推导,非用户裁决)——禁以死钮/占位钮形态合并(违契)。
|
||||
- **卡④(营地场景图)依赖(v1.1 补明;v1.2 注:卡④已回设计段)**:冒险入口探针段的新路径是「进入存档→选档→进档→营地→大门两分支→开局」——卡③同批到位也解决不了这批探针(卡④未到位时无路可走)。中间态处置见契约 5。**卡④ 2026-10-18 回设计段(美术设计定稿未过前置闸)**——契约 5 的中间态将从「批内临时」延长为「工程批交付后的稳态」,直至卡④重新立卡落地;实现报告「已知中间态」节按此登记。
|
||||
- 卡④(营地场景图)承接本卡撤出的「开始冒险/继续上局/营地/生涯」四功能入口;本卡只负责主菜单侧撤出与接线,不负责落点实现。
|
||||
- 卡①(存档制数据层)是卡③的前置,间接构成本批链的数据面底。
|
||||
|
||||
## 1. 目标与完成定义
|
||||
|
||||
**目标(澄清④照录)**:主菜单 6 钮 → 3 钮——**进入存档 / 设置 / 退出游戏**(裁决 1:用户原话「主菜单界面应该只有 3 个入口:①进入一个存档 ②游戏的设置 ③退出游戏。开始冒险,和营地相关的都应该是一个存档内的东西」)。
|
||||
|
||||
**相对现状,新增了什么**:
|
||||
1. 主菜单按钮组从 6 钮(继续上局/开始冒险/营地/生涯/设置/退出游戏)砍到 3 钮;
|
||||
2. 「进入存档」新钮接线到卡③选档界面;
|
||||
3. 撤出钮的功能去向显式化:开始冒险/继续上局 → 营地大门(卡④,裁决 5 两分支);营地 → 存档内场景图(卡④);生涯 → 营地床铺旁笔记本(卡④);
|
||||
4. 主菜单侧断点互斥确认路径(现居开始冒险)整体移交卡④大门,主菜单禁残留。
|
||||
|
||||
**完成定义**:
|
||||
1. 主菜单有且仅有三钮:进入存档/设置/退出游戏;四旧钮与两组组帽的处理按 §9 落定;
|
||||
2. 「进入存档」可点到选档界面(卡③交付物);
|
||||
3. 设置/退出游戏两钮行为零变化(澄清④:「设置(已实现 · 不动)」「退出游戏(已实现 · 不动)」);
|
||||
4. 冒烟/探针/golden 随批迁移完毕(§2 F10 全量位点表逐点过),批末重闸按改动域选档全绿;
|
||||
5. 三份 `reports/` 产出物写齐(T3)。
|
||||
|
||||
## 2. 现状事实(2026-10-18 实查;开工日 T0 复核行号)
|
||||
|
||||
| # | 事实 | 出处 |
|
||||
|---|---|---|
|
||||
| F1 | 开始覆盖层构建=六钮+两组组帽:「── 冒 险 ──」组(继续上局/开始冒险)、「── 营地与系统 ──」组(营地/生涯/设置/退出游戏);续玩钮初始 `visible=false`(有断点才亮,可见性与文案归组合根刷新) | `game/presentation/ui_assembler.gd:128`/:130-138/:141-153 |
|
||||
| F2 | 菜单屏壳持有六句柄(`lvbtn/resumebtn/campbtn/careerbtn/settingsbtn/quitbtn`),取值在 `_ready` | `game/presentation/scenes/menu_screen.gd:9-16`/:27-31 |
|
||||
| F3 | 组合根接线:lvbtn→`_start_adventure_from_menu`;resumebtn→`_resume_from_menu`;campbtn→`_camp_pres.open_camp`;careerbtn→`_open_career`;settingsbtn→`_open_settings`;quitbtn→`_quit_game` | `game/presentation/main.gd:307-309`/:331-334 |
|
||||
| F4 | 开始冒险的断点互斥确认:有断点先出 ConfirmDialog(「已有未完冒险(第 N 关)——开新冒险将覆盖旧断点」),确认才弃旧断点写盘开局——该路径整体移交卡④大门(澄清④:「断点弹窗保留移位」) | `main.gd:475-497` |
|
||||
| F5 | 续玩钮可见性刷新=断点在档态(`_refresh_resume_button`)。**消费面(v1.1 补全)**:main.gd:194(boot)/:319(注入 CampShopPresenter ctx)/:704/:1063/:1101;camp_shop_presenter.gd:19/36/55(ctx 字段+on_camp_closed 调用);probe_ui_util.gd:117-120(isolate_save 的 refresh_resume 参数,多探针传 true);pacing_queue_test.gd:30 及 F10 表全部探针位点 | `main.gd:507-514` 及上列各处 |
|
||||
| F6 | 冒烟 V2 断言六钮非空(`menu.start_overlay != null and menu.lvbtn != null and …`) | `game/smoke/smoke_all.gd:163` |
|
||||
| F7 | 生涯.md 信息架构记载现行六钮组(「冒险」组+「营地与系统」组)与生涯入口=开始层生涯钮 | `design/gdd/systems/跨局循环/生涯.md:9`/:11-23 |
|
||||
| F8 | camp.md 定位句载「主菜单营地独立入口进入」 | `design/gdd/ux/camp.md:10` |
|
||||
| F9 | 08「三 · 界面」表载主菜单/开始覆盖层/营地/生涯页四行(均在役);08 头注纪律=增删条目须用户裁,状态列可改 | `design/gdd/08-Alpha版本标准.md:102-105`/:5 |
|
||||
| F10 | **探针/单测/闸机影响面全量清单(v1.1 重列——初查「五探针」严重不全)**:见下表 | 全仓 grep 实证 |
|
||||
| F11 | menu golden 基线在役:`game/tests/golden/menu_boot.png`(迭代 28 新增);对比段=render_gate.sh「菜单 golden 逐像素」节;重制入口=`tools/golden_baseline_refresh.sh --menu`(该脚本守卫素材齐盘,缺位拒跑) | `game/tests/golden/` 实查;`tools/render_gate.sh`(菜单 golden 节);`tools/golden_baseline_refresh.sh` 头注 |
|
||||
| F12 | art-bible §7.4 小字号豁免为**一条合并条款**(条带内读数+装饰 caption 两类,:433),主菜单分组 overline×2(「── 冒 险 ──」「── 营地与系统 ──」)只是枚举中两个片段——禁整行删,只能 excision 片段;注销以 §9 第 1 条裁定为条件。另有两处代码注释引述组帽名(main.gd:287、career_overlay.gd:3,实施本体内可自理) | `design/art/art-bible.md:433`;`main.gd:287`;`career_overlay.gd:3` |
|
||||
| F13 | 体验验证清单有两处引述主菜单形态(:170「左操作列(冒险/营地与系统两组)」、:192「营地与系统组出现生涯钮」)——随本批入口拓扑改 | `体验验证清单.md:170`(仓库根)/:192 |
|
||||
|
||||
### F10 全量影响位点表(20+ 位点,按闸归类)
|
||||
|
||||
| 位点 | 依赖内容 | 所属闸 | 本批处置 |
|
||||
|---|---|---|---|
|
||||
| `ui_probe.gd:28-55` | 营地钮驱动+余额+秘宝匣 12 行断言 | probe_gate | 改走「进入存档→选档→进档→营地」新路径 |
|
||||
| `ui_click_probe.gd:59-127` | 营地购买合成点击全链(campbtn 驱动) | probe_gate --click | 同上 |
|
||||
| `ui_click_probe.gd:224-228`、:462-518 | resumebtn 断言+整条「断点段」(中断→续玩全链+互斥确认两分支,约 80 行) | probe_gate --click | **断点确认段随弹窗移交卡④**(契约 4);卡② T1 只摘钮后保留函数直调中间态(契约 5) |
|
||||
| `ui_struct_probe.gd:41-45` | camp 结构审计(营地钮驱动) | probe_gate 默认 | 改新路径 |
|
||||
| `ui_struct_probe.gd:54-56/:69` | careerbtn 生涯入口链 | probe_gate 默认 | 改走卡④笔记本路径 |
|
||||
| `ui_struct_probe.gd:86`、:163-183 | `_start_adventure_from_menu`+resume 专项(:168 刷钮、:170 续玩) | probe_gate 默认 | resume 专项随钮退役改写;冒险段见契约 5 |
|
||||
| `screen_flow_probe.gd:53`、:109-123 | 营地可见态+营地开合段 | probe_gate 默认 | 入口段归卡②;营地键语义/开合/篝火段归卡④(分界写入两卡 T 卡) |
|
||||
| `screen_flow_probe.gd:130-136` | ④菜单→冒险 lvbtn 步 | probe_gate 默认 | 契约 5 中间态;终态归卡④ |
|
||||
| `shot_probe.gd:103-119`、:138-145、:193 | careerbtn 生涯截图段+lvbtn 关卡截图段(render_gate 七屏链三段的入口在本批被拆) | render_gate | 生涯段归卡④;关卡段契约 5 中间态、终态归卡④ |
|
||||
| `shot_probe.gd:126-133` | camp 截图+关闭钮查找 | render_gate | 归卡④(营地键/收闭改缆) |
|
||||
| `fx_shot_probe.gd:36-40`、:47 | lvbtn 查找+点击,零命中即 `_fail` | render_gate | 契约 5 中间态 |
|
||||
| `t17_defer_probe.gd:29-33` | lvbtn 查找+点击 | probe_gate --full | 契约 5 中间态 |
|
||||
| `ui_tune_probe.gd:96` | `main._start_adventure_from_menu()` 直调 | probe_gate --full | 契约 5 中间态 |
|
||||
| `ui_input_probe.gd:35` | 同上 | probe_gate **默认必跑** | 契约 5 中间态 |
|
||||
| `layout_probe.gd:27` | 同上 | probe_gate **默认必跑** | 契约 5 中间态 |
|
||||
| `smoke_all.gd:163` | V2 六钮非空断言 | smoke_all | 改三钮断言 |
|
||||
| `smoke_all.gd:266-290` | V2d 续玩钮六断言(boot/回菜单态) | smoke_all | 随钮退役改写/注销 |
|
||||
| `smoke_all.gd:322/:326`、:411-415 | V3g campbtn 直呼驱动营地模态开合 | smoke_all | 改新路径 |
|
||||
| `smoke_all.gd:470-478`、:565-567 | V3i 生命周期阶段⑨(`_resume_from_menu` 全链)+`_stage_faces` 的 `resume_vis` 键 | smoke_all | 随续玩入口迁卡④改写 |
|
||||
| `smoke_all.gd:328/:439/:598/:628` | `_start_adventure_from_menu` 直调 ×4 | smoke_all | 契约 5 中间态 |
|
||||
| `pacing_queue_test.gd:30/:33` | `_refresh_resume_button`+`_start_adventure_from_menu` | 单测(33 套之一) | 函数去留按 §9 第 2 条 |
|
||||
| `probe_ui_util.gd:117-120` | `isolate_save` 的 `refresh_resume` 参数→`main._refresh_resume_button()`,多探针传 true | 全部探针共用 | 函数去留按 §9 第 2 条连带 |
|
||||
|
||||
**T0 清点口径(v1.1 定死)**:全仓 grep `lvbtn|campbtn|careerbtn|resumebtn|_start_adventure_from_menu|_resume_from_menu|_refresh_resume_button|start_overlay`,零意外命中才收口;清点结果写成文(T0 产物),作为 T2 迁移清单的基线。
|
||||
|
||||
## 3. 设计契约(红线,违反 = L3 停机呈报)
|
||||
|
||||
🔴 **契约 1 · 三钮且仅三钮**:进入存档/设置/退出游戏(裁决 1)。主菜单禁留任何存档内功能入口——开始冒险/继续上局/营地/生涯四钮彻底撤出(禁隐藏态残留、禁置灰态残留)。
|
||||
|
||||
🔴 **契约 2 · 设置与退出零行为变化**:两钮已实现不动(澄清④结构树原文);本批只保留其接线,禁借机改设置面或退出路径。
|
||||
|
||||
🔴 **契约 3 · 「进入存档」落点唯一**:只接卡③选档界面;禁直连营地/冒险(存档语境选择先行——澄清④结构树层级)。
|
||||
|
||||
🔴 **契约 4 · 断点确认路径整体移交**:主菜单侧禁残留「开新冒险覆盖旧断点」确认逻辑(main.gd:475-497 段随迁卡④大门,裁决 5 两分支);移交后主菜单无任何写档路径。断点确认探针段(ui_click_probe:462-518 等)随弹窗移交卡④ T5 接收,本卡 T2 明列移交项。
|
||||
|
||||
🔴 **契约 5 · 硬依赖卡③+卡④中间态条款(v1.1 补)**:本卡与卡③同批或卡③在先,禁死钮合并。**卡④未到位批内**:`_start_adventure_from_menu`/`_resume_from_menu` 两函数保留在 main.gd、仅摘菜单接线(T1 现文「只摘除主菜单侧调用」即此路),冒险段探针暂维直调旧函数、卡④到位再迁——该中间态是合法交付态,须在实现报告「已知中间态」节登记;禁为凑绿而把探针断言弱化成假路径。
|
||||
|
||||
🔴 **契约 6 · 探针/golden 契约**(属仓库既有测试纪律的卡内成文,非用户裁决):入口路径迁徒的探针段随批显式改写并留痕;menu golden 漂移按「核热区限预期面→显式重制+呈报→复闸」流程执行,超预期=L3。
|
||||
|
||||
🔴 **契约 7 · 不做形态重设计**:本卡只砍钮不重排菜单形态(双列布局/立绘看台不动——砍钮后的布局适配属 §9 代拍板微调圈)。反参照纪律(澄清②:拒「各种框框」)的兑现归卡④营地场景图,本卡不借尸还魂。
|
||||
|
||||
## 4. 范围边界
|
||||
|
||||
**做**:`build_start_overlay` 钮集砍到 3(含组帽与左列布局适配);`menu_screen` 句柄面;组合根接线(撤 4 接 1,含 camp_shop_presenter.gd 的 `_refresh_resume_button` ctx 摘除——v1.1 补列实施本体);冒烟 V2 断言改写;F10 全量位点表逐点迁移;menu golden 重制+呈报;反哺点清单。
|
||||
|
||||
**不做**(明示去向):
|
||||
- 选档界面本体 → 卡③;
|
||||
- 营地场景图/大门动线/生涯改挂 → 卡④;
|
||||
- ESC 浮窗与营地顶栏 → 卡⑤;
|
||||
- 设置面/退出路径的行为改动 → 无(契约 2);
|
||||
- 主菜单视觉形态重设计(换底/新素材/布局重构)→ 不在本批;如用户要形态级重做,另立裁点。
|
||||
|
||||
## 5. 关联文档同步面
|
||||
|
||||
> **v1.3 口径**:本批禁写 `design/` 整目录与根规则文件,唯一可写目录 = `reports/`;下表一律执行为列进反哺点清单。08 写入权限三卡统一口径(v1.1 对齐):**状态列可改;注记改写列反哺点随清单呈报;增删行须用户裁**。
|
||||
|
||||
| 文档 | 关联点 | 同步义务 |
|
||||
|---|---|---|
|
||||
| `design/gdd/systems/跨局循环/生涯.md` | :9 信息架构「现行主菜单按钮组……『冒险』组……『营地与系统』组」+:11-23 结构树——六钮组记述整体失义;生涯入口从开始层迁营地笔记本 | 反哺点 · 信息架构节改三钮组+生涯入口位改挂 |
|
||||
| `design/gdd/ux/camp.md` | :10「主菜单营地独立入口进入」——营地入口改挂存档内场景图 | 反哺点 · 定位句改挂 |
|
||||
| `design/gdd/08-Alpha版本标准.md` | :102-105 三·界面表四行——状态列可改;入口拓扑注记列反哺点 | 反哺点 · 列清单(统一口径见上) |
|
||||
| `体验验证清单.md`(仓库根) | :170/:192 两处引述主菜单形态(左操作列两组/营地与系统组生涯钮) | 反哺点 · 列清单(该件属设计文档,实现批禁写) |
|
||||
| `design/art/art-bible.md` | :433 小字号豁免合并条款中「主菜单分组 overline×2」枚举片段——组帽撤后 excision(禁整行删),以 §9 第 1 条裁定为条件 | 反哺点 · 列清单 |
|
||||
| `待办清单.md`(仓库根,流水线唯一登记处) | 本卡登记条 | 反哺点 · 列清单 |
|
||||
| `roadmap.md` | 迭代行编入/状态刷新 | 反哺点 · 列清单 |
|
||||
| `game/presentation/ui_assembler.gd`、`scenes/menu_screen.gd`、`main.gd`、`camp_shop_presenter.gd`(v1.1 补)、`game/smoke/*`、`game/tests/golden/*`、`tools/golden_baseline_refresh.sh`(重制入口,只跑不改) | 实现与断言/基线本体 | 实施本体(可写) |
|
||||
|
||||
## 6. 任务卡
|
||||
|
||||
> 估时按 Claude 工作日口径;每卡出口自跑轻闸;开工日 T0 复核全部行号。
|
||||
|
||||
### 6.0 落位与可复用性预检(req-card 必备结构第 12 项,定义 T 卡前置)
|
||||
|
||||
本卡零新增文件——改的全是既有承载面。逐件核查:
|
||||
|
||||
| 新增件/改动 | 复用面(既有实现) | 落点唯一性 | 分层与跨层出口 |
|
||||
|---|---|---|---|
|
||||
| 三钮钮集(改 `ui_assembler.gd:128-153`) | 钮全用 `UiKit` 工厂件(现役即 `primary_button`/`button`/`verb_button`),零新素材零新色值 | 主菜单钮集唯一构建口=`build_start_overlay`,盘上无第二处构建菜单钮的实现 | 装配层只产树与句柄,不持业务态 |
|
||||
| 「进入存档」句柄(改 `scenes/menu_screen.gd:9-16`/`:27-31`) | 沿用屏壳句柄暴露形态(六句柄现制),只换钮名不改形态 | 屏壳句柄唯一暴露口=menu_screen,禁在装配层与组合根各存一份 | 屏壳→组合根只经 `pressed` 信号 |
|
||||
| 组合根开层函数(新增 `_open_save_select`) | **复用同层先例 `_open_career`(`main.gd:1092-1095`:取数+开层+喂视图)**+模态栈单口 `_open_modal`/`_close_modal`(`:458-462`)+层序合同 `LAYER_CONTRACT`(`:34-53`,career 行见 `:47`) | 开层函数唯一在组合根,禁在屏壳或视图内自开层 | 呈现层禁直连数据层,取数一律在组合根完成后传入视图 |
|
||||
| 删除 `_refresh_resume_button` | 无(净删除) | 删除即清掉一处散落 helper——消费点 12 处全清单见 §2 F5 与 mn7,漏删=留下第二处刷新口 | — |
|
||||
| menu golden 重采 | **复用既有重制入口 `tools/golden_baseline_refresh.sh --menu`(F11)与 `tools/render_gate.sh` 菜单 golden 段** | 禁新写采图脚本、禁在探针里复制比对逻辑(逐像素比对唯一落点=golden 段) | 代码域闸统一入口,卡内不列闸件名单 |
|
||||
| 断言与探针位点改写 | 全部改写既有段(smoke 与 F10 表内既有探针) | 禁新建同职责探针文件——同一入口的可达性只在一处断言 | 测试执行两入口铁规 |
|
||||
|
||||
### T0 事实坐实(≈0.5–1d)
|
||||
|
||||
- 复核 §2 全部行号;按 F10 表尾清点口径全仓 grep,清点结果写成文(T0 产物);
|
||||
- 与卡③对齐:「进入存档」钮的目标句柄与选档界面开层函数名先定(跨卡接口);与卡④对齐断点确认探针段的移交/接收分界(契约 4)。
|
||||
|
||||
### T1 钮集砍伐与接线(≈0.5–1d)
|
||||
|
||||
- `build_start_overlay`:六钮→三钮;组帽去留与左列布局适配按 §9 拍板(冒险组帽必撤——组内零钮;见 §9 第 1 条);
|
||||
- `menu_screen` 句柄面随裁(撤 4 留 3+新增进入存档钮句柄);
|
||||
- 组合根:撤 lvbtn/resumebtn/campbtn/careerbtn 四线,接「进入存档」→选档界面;`_start_adventure_from_menu`/`_resume_from_menu` 按契约 5 保留(摘接线不删函数);
|
||||
- `_refresh_resume_button` 去留按 §9 第 2 条:**卡④大门不复用该函数**(卡④ T4 已明示——两分支直读 `has_breakpoint`,无钮可刷),故只剩删除一路;删函数同批清全部消费点(main.gd 五处+camp_shop_presenter.gd ctx 字段与 on_camp_closed 调用+probe_ui_util 参数+pacing_queue_test+各探针传 true 位点);
|
||||
- 断点确认段(main.gd:475-497)的移交:本批只摘除主菜单侧调用,弹窗本体与两分支逻辑落卡④大门。
|
||||
|
||||
### T2 断言、探针与 golden 迁移批(≈1.5–2d)
|
||||
|
||||
- smoke V2 六钮断言→三钮断言(进入存档/设置/退出游戏非空;四旧钮句柄零命中);
|
||||
- F10 全量位点表逐点迁移:入口路径段本卡改;断点确认段/生涯截图段按契约 4 移交卡④(本卡 T2 明列移交项,卡④ T5 接收);冒险段探针按契约 5 中间态处理(卡④到位再迁);
|
||||
- menu golden:核漂移热区限钮集区→显式重制 `menu_boot.png`+呈报→复闸;
|
||||
- **变异验证伴生**:新断言段定注入实验——例:把四旧钮之一接回(预期三钮断言红)、进入存档钮接错层(预期探针路径红);注入→最窄闸见红→精确还原→记录。
|
||||
|
||||
### T3 产出物落位卡(≈0.5d,末卡)
|
||||
|
||||
三份 `reports/` 写齐(实现报告含 golden 重制呈报记录、变异记录表、「已知中间态」节〔契约 5〕、**实际改动—验收对照表**〔§7.1 需求侧表的执行对账,另加「结果」格,F10 位点逐段指到行号〕/代拍板追认单/反哺点清单)。**合并前置**:独立验收审计(§7.1 末段声明)完成且 `reports/iter33-验收审计-<完成日>.md` 逐行「通过」;§7.2 申报外的削弱由审计判红,未过不得合并。
|
||||
|
||||
**估时合计 ≈2.5–4d**(v1.1 上调:探针面从「五探针」扩到 20+ 位点,T2 清点后重估)。切分预案:T1 出口可切(砍钮先落、断言迁移后落)——但契约 5 硬依赖卡③,实际切分价值低,建议与卡③同批单跑。
|
||||
|
||||
## 7. 验证闸(逐需求点验收清单)
|
||||
|
||||
| # | 需求点 | 测什么 | 落点/判定手段 |
|
||||
|---|---|---|---|
|
||||
| V1 | 三钮在位+既有断言族改写 | 进入存档/设置/退出游戏三钮非空且可点;四旧钮(开始冒险/继续上局/营地/生涯)在主菜单零命中;被本批废止/改写的既有断言族(smoke V2d 续玩钮态、V3g campbtn 驱动、V3i 阶段⑨续玩全链、`_stage_faces` 的 `resume_vis` 键)逐族有改写后断言承接 | 冒烟 V2 改写段+V2d/V3g/V3i 改写段+ui_struct_probe 结构断言 |
|
||||
| V2 | 设置零行为变化 | 设置钮开合路径与既有断言一致 | 冒烟 V3g settings 模态段复跑 |
|
||||
| V3 | 退出接线正确 | quitbtn → `_quit_game` 连接存在(headless 不可真退——接线断言代偿) | 源码/结构断言 |
|
||||
| V4 | 进入存档可达选档 | 点击链路通到卡③选档界面(层可见+菜单隐藏) | ui_click_probe/screen_flow_probe 新路径段(依赖卡③) |
|
||||
| V5 | 断点确认零残留 | 「开新冒险覆盖断点」确认路径仅存于卡④大门;ConfirmDialog 允许多消费方(卡③删档确认在役——切换机制见卡③ 契约 3) | 源码断言+ui_struct_probe 既有采样复跑 |
|
||||
| V6 | golden 与七屏链 | menu golden 漂移限钮集区、重制有呈报、复闸绿;shot_probe 七屏截图链存在性自检全绿(career/camp/level 三入口迁移后仍七件非空) | render_gate golden 段+shot_probe 自检段复跑 |
|
||||
| V7 | 左列布局几何不破 | 砍钮后双列不相交合同与按钮几何族(互压/等宽/出屏/零尺寸)复跑 | ui_struct_probe `_start_columns_contract`+`_audit("start")` 段复跑(v1.1 补机检项) |
|
||||
| V8 | 反哺点清单 | §5 每条有落点 | 件核对表 |
|
||||
|
||||
**测试方式两分法**:V1–V7 机检自动化;**用户目检项=主菜单三钮观感(钮集砍伐后左列布局是否失衡)**——登记 07(实机目检=生命周期最后一步统一进行,不阻塞迭代,澄清⑥口径)。
|
||||
|
||||
**闸口径**:轻闸每卡出口自跑;批末重闸按改动域选档(本批碰 `game/` 代码/断言/golden → `--code`)全绿才合并;MC 零跑(零数值零行为)。
|
||||
|
||||
### 7.1 改动—验收对照表(test-conventions §9.3 六列;§7 的 V 号在各需求点格内括注)
|
||||
|
||||
> 断言尾缀族=〔mn#〕,实现期逐条 grep 定位。落点文件为计划落点,实现期在 `reports/iter33-实现报告-<完成日>.md` 的实际对照表里按真实行号对账(§9.3 双端对上)。本卡是断言迁移卡,F10 全量位点表的每一段都必须能指到本表某一行——指不到的在实现报告标「由第 X 行覆盖」。
|
||||
|
||||
| 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 撤销或变异证明 |
|
||||
|---|---|---|---|---|---|
|
||||
| mn1 三钮在位(契约1、V1、T1) | `game/presentation/ui_assembler.gd:128-153` `build_start_overlay` 六钮+两组帽 → 三钮(进入存档/设置/退出游戏) | 冒烟 V2 三钮非空段〔mn1〕落 `game/smoke/smoke_all.gd:163` 改写 | 接口 | 真实 `MenuScreen` 经 `UiAssembler.build_start_overlay()` 构建后读句柄 | 变异=把「生涯」钮接回三钮集 → 三钮断言红(T2 变异①) |
|
||||
| mn2 四旧钮彻底撤出(契约1、V1、T1) | `game/presentation/scenes/menu_screen.gd:9-16`/`:27-31` 句柄面撤 `lvbtn`/`resumebtn`/`campbtn`/`careerbtn`、留 3+新增进入存档句柄 | 冒烟〔mn2〕四旧句柄名零命中+`ui_struct_probe` 结构断言 | 探针 | 菜单场景实例的句柄枚举(禁隐藏态、禁置灰态残留) | 撤销=恢复 `lvbtn` 字段 → 零命中断言红 |
|
||||
| mn3 进入存档可达选档(契约3、V4、T1/T2) | `game/presentation/main.gd:307-309`/`:331-334` 接线区新增进入存档 → 开卡③选档层(开层函数名 T0 与卡③对齐) | `ui_click_probe` 新路径段〔mn3〕+`screen_flow_probe` 开合段 | 探针 | 合成点击进入存档钮 → 选档层可见且开始层隐藏 | 变异=接到营地层 → 层可见断言红(T2 变异②) |
|
||||
| mn4 设置钮零行为变化(契约2、V2) | `settingsbtn` 接线保持不动(`main.gd:331-334`) | 冒烟 V3g settings 模态段复跑〔mn4〕 | 冒烟 | `settingsbtn` 句柄 `pressed` 驱动 | 撤销=断线 → V3g settings 段红 |
|
||||
| mn5 退出接线正确(V3) | `quitbtn` → `_quit_game` 连接保持(`main.gd:331-334`) | 源码/结构断言〔mn5〕 | 单元 | `MenuScreen.quitbtn.pressed` 的连接目标名 | 变异=改连空函数 → 连接目标断言红 |
|
||||
| mn6 断点确认主菜单零残留(契约4、V5、T1) | `main.gd:475-497` 摘除主菜单侧调用(弹窗本体与两分支逻辑落卡④大门) | 源码断言〔mn6〕+`ui_struct_probe` 既有 confirm 采样复跑 | 探针 | 主菜单路径上「开新冒险覆盖断点」确认链不可达 | 撤销=接线复现 → 残留断言红 |
|
||||
| mn7 `_refresh_resume_button` 删除+消费点清零(T1、§9 第2条) | 函数删除(`main.gd:507-514`)+调用五处(`:194`/`:319`/`:704`/`:1063`/`:1101`)+`camp_shop_presenter.gd:19`/`:36`/`:55` ctx 字段与 `on_camp_closed` 调用+`probe_ui_util.gd:117-120` 参数+`pacing_queue_test.gd:30` | 单元〔mn7〕+表尾清点口径全仓 grep 零命中件核(T0 产物) | 集成 | 真实消费链:探针 `isolate_save()` 与营地关层回调 | 变异=漏删一处 ctx 字段 → grep 计数断言红 |
|
||||
| mn8 废止断言族有改写承接(V1、T2) | `smoke_all.gd:266-290` V2d 续玩钮六断言、`:322`/`:326`+`:411-415` V3g campbtn 驱动营地开合、`:470-478`+`:565-567` V3i 阶段⑨续玩全链与 `_stage_faces.resume_vis` 键 | 改写后的三钮/新路径断言〔mn8〕逐族承接,同落点 | 冒烟 | boot 与回菜单生命周期段真实入口 | 撤销=只删不写承接 → 「每个废止族须有承接」计数断言红 |
|
||||
| mn9 营地/生涯入口探针段改走新路径(V1、T2) | `ui_probe.gd:28-55`、`ui_click_probe.gd:59-127`、`ui_struct_probe.gd:41-45`/`:54-56`/`:69`、`screen_flow_probe.gd:53`/`:109-123` | 各探针自身绿+新路径断言〔mn9〕 | 探针 | 探针档默认跑各件,驱动路径=进档后开营地/生涯 | 撤销=入口段留旧句柄 → 取不到钮即 `_fail` 红 |
|
||||
| mn10 冒险段探针直调中间态(契约5、V1、T2) | `_start_adventure_from_menu`/`_resume_from_menu` 保留函数仅摘接线;直调位点=`fx_shot_probe.gd:36-40`/`:47`、`t17_defer_probe.gd:29-33`、`ui_tune_probe.gd:96`、`ui_input_probe.gd:35`、`layout_probe.gd:27`、`smoke_all.gd:328`/`:439`/`:598`/`:628`、`screen_flow_probe.gd:130-136`、`shot_probe.gd:138-145`/`:193` | 各该段复跑绿〔mn10〕+实现报告「已知中间态」节逐位点登记 | 探针 | 函数直调(本行如实标为中间态入口,卡④到位后换代) | 撤销=删函数 → 直调段运行即红(红证明入口真落在该函数上) |
|
||||
| mn11 组帽撤除+左列几何不破(V7、T1、§9 第1条) | `ui_assembler.gd:128`/`:141` 两枚 overline 与左列重排(「冒 险」帽必撤,「营地与系统」帽按 §9 处置并追认单留痕) | `ui_struct_probe` `_start_columns_contract`+`_audit("start")` 段复跑〔mn11〕 | 探针 | 真实菜单构建后的按钮几何审计(互压/等宽/出屏/零尺寸) | 变异=左列改单列致两列相交 → 不相交合同断言红 |
|
||||
| mn12 menu golden 重制(V6、T2、契约6) | `game/tests/golden/menu_boot.png` 重采,走 `tools/golden_baseline_refresh.sh --menu`(脚本只跑不改) | `render_gate.sh` 菜单 golden 逐像素段〔mn12〕 | 探针/golden | render_gate 驱动 shot_probe 真机渲染出图逐像素比对 | 撤销=拿旧基线跑 → 钮集区差红;差区越出钮集区=触契约7 越界,路由 §8 L3 |
|
||||
| mn13 `pacing_queue_test` 套件连带改造(V1、T1) | `game/tests/unit/presentation/pacing_queue_test.gd:30`/`:33` 去掉 `_refresh_resume_button` 与菜单直调依赖 | 该套件自身绿〔mn13〕 | 单元 | `game/tests/run_all.gd` 真实套件入口 | 变异=改成裸调下层队列函数 → 该套件的宿主链断言红(证明入口未绕过改动点) |
|
||||
| mn14 反哺点清单(V8)——非行为改动 | §5 所列(生涯.md、camp.md、08、体验验证清单、art-bible `:433` excision、待办清单、roadmap)随批列点不落文 | 件核对表〔mn14〕落 `reports/iter33-反哺点-<完成日>.md` | 件核 | 收口前逐条指认落点 | 判断依据=产出物件核不产码;§5 任一条缺落点即 T3 收口不过 |
|
||||
|
||||
### 7.2 测试削弱申报(test-conventions §9.5)
|
||||
|
||||
本批结构性拆入口,必然动到既有断言——下列为**已申报**的改/删项,逐条写明判据去向,实现期未申报的削弱由独立验收审计判红:
|
||||
|
||||
| 旧断言位点 | 处置 | 承接判据 |
|
||||
|---|---|---|
|
||||
| `smoke_all.gd:266-290` V2d 续玩钮六断言 | 钮已撤,判据失去对象——废止 | 由〔mn8〕三钮/新路径承接断言顶上;卡① sv2 boot 态断言另钉「boot 后无激活态」 |
|
||||
| `smoke_all.gd:322`/`:326`/`:411-415` V3g campbtn 直呼驱动 | 驱动路径换代 | 〔mn8〕+〔mn9〕新路径段(营地经进档开层) |
|
||||
| `smoke_all.gd:470-478`/`:565-567` V3i 阶段⑨与 `_stage_faces.resume_vis` 键 | 键随钮退役 | 〔mn8〕承接改写;生命周期其余阶段断言不许动 |
|
||||
| `ui_click_probe.gd:224-228`/`:462-518` 断点段(约 80 行) | 随弹窗移交卡④大门 | 本卡 T2 明列移交项+卡④重立卡时的接收清单两头登记;禁静默删除 |
|
||||
| `shot_probe.gd:103-119`/`:126-133` career/camp 截图段 | 归卡④ | 七屏链存在性自检不许降档——V6 判据仍要求七件非空,缺件即红 |
|
||||
| `ui_struct_probe.gd:86`/`:163-183` resume 专项 | 随钮改写 | 〔mn2〕〔mn8〕 |
|
||||
| 冒险段探针的入口路径断言 | 降级为函数直调中间态 | 〔mn10〕逐位点登记在实现报告「已知中间态」节,卡④到位后代换——契约 5 明禁为凑绿把断言改成假路径 |
|
||||
|
||||
**独立验收审计(test-conventions §9.7)**:合并前由未参与实现的迭代 loop 内子代理(或用户点名会话)审计——只读本卡、实现报告实际对照表、diff 与测试文件,自跑最窄测试抽查,不采信「已全绿」;审计报告落 `reports/iter33-验收审计-<完成日>.md`,逐行写「通过/缺漏/例外及依据」。**审计未通过不得合并**(T3 合并前置)。
|
||||
|
||||
## 8. 异常分级
|
||||
|
||||
- **L1(自救)**:断言写法、探针路径选择、布局微调。
|
||||
- **L2(记录继续)**:组帽去留与左列布局适配(§9 域内)、`_refresh_resume_button` 删除的消费点清理顺序、探针迁移中的中间态处理(契约 5 登记)、T2 估时随清点重估。
|
||||
- **L3(停机呈报)**:卡③ 未同批到位导致「进入存档」无落点(停线等批,禁死钮合并);menu golden 漂移越出钮集区(形态面被波及=超出本批契约 7);发现设置/退出路径被意外触碰;F10 清点出现表外新位点且无法随批迁移。
|
||||
|
||||
## 9. 代拍板白名单(超清单必呈报)
|
||||
|
||||
1. 组帽与左列布局适配:**「── 冒 险 ──」帽必撤(组内零钮——退化态不留);「营地与系统」帽去留/改文案属代拍板,改名须追认单留痕**(v1.1 明写——保留原样=留一句指称不可达地点的文案,禁)。
|
||||
2. `_refresh_resume_button` 去留:卡④不复用(卡④ T4 已证),默认删;删时同批清全部消费点(T1 列明)。
|
||||
3. 「进入存档」钮的动词化命名与 tooltip 文案(对齐现役动词钮先例)。
|
||||
4. 探针迁移中的中间态写法(路径分段断言 vs 端到端)+卡④未到位批内冒险段探针维直调(契约 5)。
|
||||
5. 提交切分与 worktree 分支命名。
|
||||
|
||||
## 10. 待裁点
|
||||
|
||||
**零待裁点**(裁决 1 三钮结构、四功能去向均由澄清④结构树锁定;布局适配与组帽文案归 §9 代拍板+追认单留痕)。开工门 = U0(用户 `/iter` 发令)+ 卡③同批到位+ 契约 5 中间态条款随卡④排期一并确认。
|
||||
|
||||
---
|
||||
|
||||
**审查回写要点**: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)零改动。
|
||||
@@ -1,235 +0,0 @@
|
||||
# 需求卡片:存档制数据层改造批(隐式单档 → 3 存档位)· 营地交互重做卡①
|
||||
|
||||
- 版本:**v1.3**(现行身份:零待裁点+含 §7.1 改动—验收对照表〔按 test-conventions §9.3 六列与 §9.8 旧卡开工前补表口径〕。v1.2 裁定:Q1 旧档归属甲〔迁 1 号位,代拍板留痕〕、Q2 交付序列甲〔推荐案,用户令按推荐执行〕;卡④回设计段不影响本卡链路——卡③在工程批内)
|
||||
- 来源:[需求澄清-营地交互重做-2026-10-18.md](需求澄清-营地交互重做-2026-10-18.md)(唯一事实源:④结构树「选档界面:3 存档位,新档/进档/删档」、⑤裁决 2/3/4、⑦切批原则①)+ [存档序列化](../design/gdd/systems/表现与支撑/存档序列化.md) P2 后置条
|
||||
- 归属:数据层承载面(`game/core/save_manager.gd`)——营地交互重做五卡之一;用户可见面由卡③(选档界面)承载
|
||||
- 排期:未编入(2026-10-18 用户令:需求卡片不预占迭代号,批次归属按工作量另裁)
|
||||
- 开工门:U0(用户 `/iter` 发令)+ 待裁点已裁(Q1/Q2 均裁定,见 §10)+ grilling 复核门过
|
||||
|
||||
## 0. 前置依赖与并行性
|
||||
|
||||
- 卡③(选档界面)依赖本卡数据层;卡②(主菜单三入口化)的「进入存档」钮经卡③落到本卡的激活态。
|
||||
- **交付序列待裁(Q2)**:卡③未到位前,全游戏无任何生产激活路径(卡③ 契约 8「进档即激活」是唯一激活入口)——旧入口在无激活态下写盘全被拒,且 `settle_adventure`(meta_progression.gd:275,忽略写盘返回值的写盘在 :282)忽略写盘返回值→进度静默丢失。冒烟探针走 attach_path 隔离不会红,机检放控不住。本卡「可先行」以 Q2 裁甲(与卡③同批或卡③在先)为前提;裁乙/丙须按 Q2 表执行过渡态。
|
||||
- 与在役结构的关系:SaveManager/MetaProgression 已是 autoload(迭代 27 T1 裁点①),本批只改承载面(文件组织与激活态),不改升格结构、不改 autoload 链。
|
||||
|
||||
## 1. 目标与完成定义
|
||||
|
||||
**目标(澄清④照录)**:存档制数据层改造——隐式单档 → 3 存档位(save_manager + 存档格式)。裁决 2「多存档制,**3 个存档位**」;裁决 3「删档:**要**,且必须**二次确认**」;裁决 4「档槽摘要=**钥石余额、通关次数、冒险次数(总局数)**三项,不含未完冒险进度」。
|
||||
|
||||
**相对现状,新增了什么**:
|
||||
1. 三存档位承载与当前激活位(现=单路径单实例,`user://save.json` 一档到底);
|
||||
2. 新档/进档/删档三个数据层原语(删档=档案文件删除+盘面即时生效〔卡内工程规定,非澄清裁决语〕;二次确认弹窗归卡③承载);
|
||||
3. 档槽摘要窥视读器(三项——只读、不激活、不写盘、零副作用);
|
||||
4. 旧档 `user://save.json` 的显式处置(待裁 Q1)。
|
||||
|
||||
**完成定义**(全部满足才算本批完成):
|
||||
1. SaveManagerCore 承载 3 存档位;位间互隔离(读写/删除/坏档兜底均按位);
|
||||
2. 新档/进档/删档原语齐备且断言全绿;摘要三项读器按位正确;
|
||||
3. 启动态钉死:`_ready` 不读任何槽(内存=默认合法空态)、无激活态一切写盘路径拒绝并返回 false、`_path` 不留 `user://save.json` 为隐式写目标;
|
||||
4. 存档格式版本迁移链零破坏(v1→v7 照旧);本批不升 schema 版本——执行中确需新键时按「v6 域后扩列不升版」先例(vision_used,存档序列化.md:108)处理并登记;
|
||||
5. 探针/冒烟隔离面(`attach_path` 与 smoke 注入路径)保留且行为零变化;
|
||||
6. Q1 旧档归属按裁定执行并留痕;
|
||||
7. 批末重闸按改动域选档全绿;三份 `reports/` 产出物写齐(T4)。
|
||||
|
||||
## 2. 现状事实(2026-10-18 实查;开工日 T0 复核行号)
|
||||
|
||||
| # | 事实 | 出处 |
|
||||
|---|---|---|
|
||||
| F1 | 存档唯一实现=JSON 单档:`_path` 默认 `user://save.json`;`_init(path)` 可注入路径(冒烟隔离用);类头注自述「Core 层零 UI 零玩法依赖……禁 preload/import 任何玩法脚本」 | `game/core/save_manager.gd:15`/:21/:1-5 |
|
||||
| F2 | 读写原语齐备:`load_from_disk`(新档/损坏兜底/迁移链/高版本拒读四路)、`write_to_disk`(tmp+rename 原子写;拒读禁写态拒绝)、`_corrupt_fallback`(坏档改名 `.corrupt.bak`)、`attach_path`(换路径+回默认数据+重读盘——迭代 27 T1 探针隔离面;注释明载「对象引用恒定,MetaProgression 持有的 save 引用零失效」) | `save_manager.gd:150-183`/:188-202/:443-450/:42-46/:40-41 |
|
||||
| F3 | 版本与迁移:`SAVE_FORMAT_VERSION := 7`(v7=锻造工坊域 forge_routes);生产迁移链 v1→v7 六件自注册;`_normalize` 缺键补齐+退役域清退 | `save_manager.gd:9`/:25-30/:458-471 |
|
||||
| F4 | 摘要三项的读取源已在役(单档):`keystone_balance()`、`adventure_cleared()`(三关全通才计 1)、`adventure_total()`(开局即计含放弃与失败)——按槽窥视读器=本批 T2 交付物 | `save_manager.gd:214`/:264/:258 |
|
||||
| F5 | SaveManager 为 autoload(工程序 ConfigDB→RngService→SaveManager→MetaProgression);MetaProgression 持有 `var save: SaveManagerCore`,`_ready` 取 `/root/SaveManager` 一次——消费面对存档的引用是单实例单引用;全部访问器为 `save.xxx()` 动态分发、无缓存 | `game/project.godot:21`;`game/core/meta_progression.gd:9`/:21-25/:54 |
|
||||
| F6 | 探针/冒烟隔离机制在役且面比初查大:`_META_SMOKE_PATHS` 注入清单 **18 条**(smoke_all.gd:5697-5704);另有 `user://smoke_save_*` 15 条(:6543-6553)〔T0 行号订正 2026-10-21〕、boot/lifecycle/lifecycle_resume/run_lifecycle 段(:277/:321/:463/:594)、`test_pacing_queue_save`(pacing_queue_test.gd:28)、`smoke_tune_probe_*`(ui_tune_probe.gd:167/:171)、probe tag 族(probe_ui_util.gd:98-121,10 探针 15 处调用);`attach_path` 直接消费 8 处+isolate_save 间接 15 处 | `game/smoke/smoke_all.gd:5697-5704`/:6543-6553 等;`game/smoke/probe_ui_util.gd:98-121` |
|
||||
| F7 | 文档侧早已预写多档去向:存档序列化.md P2 后置表载「多存档槽位|单档 MVP(2026-09-21 裁决);多档等有真实需求再立项」——本批即该条预写的「真实需求」落地;同文 :61 现行口径=「存档是单文件 JSON(user://save.json)」;:20 系统范围负责表载「单档 JSON 存档的域划分与读写约定」 | `design/gdd/systems/表现与支撑/存档序列化.md:165`/:61/:20/:16 |
|
||||
| F8 | 近期闸基线:冒烟 1151/0、单测 51/51(34 套件),载于迭代 30 卡① 合并提交 `7ffd1dc0` 的回执读数(实现报告已退役,git 历史可考);T0 复测(2026-10-21):冒烟 1156/0、单测 35 套件全绿、probe --click 全绿 | git 提交 `7ffd1dc0`(迭代 30 卡① 合并) |
|
||||
|
||||
## 3. 设计契约(红线,违反 = L3 停机呈报)
|
||||
|
||||
🔴 **契约 1 · 三存档位且仅三位**:用户原话「多存档可以让它有三个存档位」——位数写死 3;批内禁以「将来扩位」名义参数化,扩位=新裁点另立。
|
||||
|
||||
🔴 **契约 2 · 位间互隔离**:任一槽位的新建/进入/删除/损坏兜底不得波及其他槽位文件字节;删档只删该槽文件;坏档 `.corrupt.bak` 按槽生成。
|
||||
|
||||
🔴 **契约 3 · 迁移链与版本号零破坏**:`SAVE_FORMAT_VERSION=7` 与 v1→v7 链不动。槽位改造是承载面(文件组织+激活态)改造,不是 schema 改造;每槽档案结构与现行 v7 逐键同构。
|
||||
|
||||
🔴 **契约 4 · 旧档不静默丢失**:现行 `user://save.json` 必须按 Q1 裁定显式处置(迁 1 号位/保留不载/废弃三选一,用户裁);禁无声忽略、禁默认行为。
|
||||
|
||||
🔴 **契约 5 · 摘要三项且仅三项**:钥石余额/通关次数/冒险总局数;禁在摘要面露出未完冒险进度(裁决 4 明示「不需要显示有无未完成的冒险;只要我提到的那三个就够了」)。
|
||||
|
||||
🔴 **契约 6 · 消费面纪律不破**:其他系统只经 SaveManager 类型化访问器操作存档(存档序列化.md 消费面纪律);切槽=**同一 autoload 实例内 `_data` 与路径整体替换**(attach_path 先例:对象引用恒定,`save_manager.gd:40-41`)——禁每槽实例化+换 `MetaProgression.save` 引用(`_ready` 一次捕获会静默过期),禁 SaveManager 回写 MetaProgression.save;写盘目标=当前激活槽文件,无激活态时一切写盘路径拒绝并返回 false;「凡钥石发生变动的时刻都要落盘」纪律按位保持(存档序列化.md:121)。
|
||||
|
||||
🔴 **契约 7 · 测试隔离面保留**:`attach_path` 与 smoke 注入路径机制原样保留——槽位化后探针仍能隔离到单槽;单路径语义定义为「注入路径=激活槽文件(无激活态时注入即激活并重读)」,既有调用面零改;测试执行两入口铁规不破。若 §9 第 1 条选定单文件三键致该语义不可守,本契约显式降格为「最小改+探针修改清单留痕」并呈报(L3)。
|
||||
|
||||
🔴 **契约 8 · 删档原语正确性**:删除后该槽回合法空态(新档合法态=全零可玩,`_default_data` 纪律)、文件不在盘、无 `.tmp` 残留;删档的玩家侧必经二次确认(裁决 3,弹窗归卡③),本卡只保证原语正确;删激活槽时激活指针连清除(该槽不再可写)。
|
||||
|
||||
🔴 **契约 9 · 窥视读器三态**:可读槽=摘要三项零副作用;**不可读槽(损坏/高版本/缺版本字段)=显式损坏标记返回,禁触发 `_corrupt_fallback` 改名副作用**(窥视只读零副作用——.corrupt.bak 改名只发生在正式进档路径);`.tmp` 残留按空槽处理。坏档/高版本槽在选档面的呈现与操作集=卡③ Q2(第三态),两卡接口在各自 T0 对齐。
|
||||
|
||||
## 4. 范围边界
|
||||
|
||||
**做**:三槽承载(路径派生/当前激活位/激活与切位 API);新档/进档/删档原语;摘要三项窥视读器;旧档按 Q1 处置;断言批(冒烟+单测);反哺点清单。
|
||||
|
||||
**不做**(明示去向):
|
||||
- 选档界面 UI、删档二次确认弹窗 → 卡③;
|
||||
- 主菜单砍钮 → 卡②;营地场景图 → 卡④;ESC 浮窗与营地顶栏 → 卡⑤;
|
||||
- 存档内容域口径(钥石怎么得、摘要记什么)→ 各 owner 文档(元进度/冒险结构/生涯),本批只承载不定义(存档序列化.md 系统范围纪律);
|
||||
- schema 升版(确需新键时按先例登记,不主动升);
|
||||
- 重裁多档策略本身(裁决 2 已裁三位)。
|
||||
|
||||
## 5. 关联文档同步面
|
||||
|
||||
> **v1.3 口径(2026-10-17 文档同步闸 v3)**:本批是代码实现批,禁写 `design/` 整目录与根规则文件,唯一可写目录 = `reports/`。下表「同步义务」一律执行为「列进 `reports/iter<N>-反哺点-<完成日>.md`:哪个文件哪一节、改成什么、依据,用户会话裁决后归文档批落文」。
|
||||
|
||||
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|
||||
|---|---|---|
|
||||
| `design/gdd/systems/表现与支撑/存档序列化.md` | :61「存档是单文件 JSON(user://save.json)」→ 三槽承载;:20/:16 系统范围「单档 JSON 存档」;:165 P2 后置「多存档槽位|单档 MVP……多档等有真实需求再立项」——本批即该真实需求 | 反哺点 · 单文件→三槽口径改写+P2 条注销(去向=本批) |
|
||||
| `待办清单.md`(仓库根,流水线唯一登记处) | 本卡登记条(卡片名/文件指针/状态) | 反哺点 · 列清单 |
|
||||
| `roadmap.md` | 迭代行编入笔与批内状态刷新 | 反哺点 · 列清单 |
|
||||
| `game/core/save_manager.gd`、`game/core/meta_progression.gd` | 承载面改造本体 | 实施本体(可写) |
|
||||
| `game/smoke/*`、`game/tests/*` | 断言与隔离面 | 实施本体(可写) |
|
||||
|
||||
## 6. 任务卡
|
||||
|
||||
> 估时按 Claude 工作日口径;每卡出口自跑轻闸;开工日 T0 复核本卡全部行号。
|
||||
|
||||
### 6.0 落位与可复用性预检(req-card 必备结构第 12 项,定义 T 卡前置)
|
||||
|
||||
盘上普查(2026-10-21 实查,开工日 T0 复核):`user://save` 全仓命中 12 处——`save_manager.gd:15`/`:21` 是默认路径与注释,其余十处全是探针隔离纪律注释(`probe_ui_util.gd:89`、`screen_flow_probe.gd:23`、`smoke_all.gd:272`/`:588`/`:5696`/`:6539`、`ui_click_probe.gd:53`、`ui_input_probe.gd:30`、`ui_probe.gd:24`、`verifier_batch.gd:19`),**盘上不存在第二处存档路径派生**;`slot` 词已被同调位占用(`attunement.gd:10 static func slots(db, save)`、`config_db.gd:273`、`treasure_items.gd:56-57`)。
|
||||
|
||||
| 新增件 | 复用面(既有实现) | 为什么不能整件复用 | 唯一落点 | 跨层出口 |
|
||||
|---|---|---|---|---|
|
||||
| 三槽路径派生与槽位枚举 | 无同类实现可复用(普查见上,现承载面只有单 `_path`) | 新内容本身 | 只落 `save_manager.gd:15`/`:21` 承载面一处;探针面禁各自拼槽文件名,仍走注入口 | Core 层零 UI,禁 preload 玩法脚本(类头注 `:1-5`) |
|
||||
| 激活位的设置/读取/清除 | `attach_path()`(`:42-46`)的「换路径+回默认数据+重读、对象引用恒定」正是切槽要复用的动作 | 该函数不带「哪一位被激活」的状态语义,需在其上加状态量而非另写一套换盘逻辑 | 激活态唯一在 SaveManagerCore 内存态;Q1 甲=不落盘,禁在 `meta_progression.gd` 或呈现层另记第二份 | 消费面经 `MetaProgression.save` 动态分发(`meta_progression.gd:21-25`/`:54`),禁回写引用(契约 6) |
|
||||
| 新档/进档/删档三原语 | 读盘迁移链 `load_from_disk`(`:150-183`)、原子写 `write_to_disk`(`:188-202`)、坏档兜底 `_corrupt_fallback`(`:443-450`)、空态 `_default_data`——三原语=按槽复用这些件 | 现件全部单路径语义,需按槽参数化,不是重写 | 文件删除只落承载面,呈现层禁 `DirAccess` 直删 | 玩家侧二次确认弹窗归卡③,本卡只出原语 |
|
||||
| 摘要三项按槽窥视读器 | 读源访问器在役:`keystone_balance()`(`:214`)、`adventure_total()`(`:258`)、`adventure_cleared()`(`:264`) | 现访问器读内存 `_data`(即激活态),窥视要按槽直读文件且零副作用(契约 9) | 三项口径唯一在本卡;卡③ 视图禁自算或加第四项(契约 5) | 只返回结构体,不带 UI 语义 |
|
||||
| 三个新单元套件(`game/tests/unit/core/save_slot_*_test.gd`) | 既有 `test_kit.gd` 断言出口与 `unit/core/` 12 套件分层;存档往返先例 `game/tests/integration/save_rng_roundtrip_test.gd` | 既有件只证单实例单路径,位间隔离/启动态/跨槽摘要无对应件 | 一职责一文件、落 `unit/core` 与既有分层一致;禁把断言散写进 `smoke_all.gd`(该文件拆分在册=待办清单工程债第 6 条) | `game/tests/run_all.gd` 真实入口 |
|
||||
| 承载面文件本体不拆 | `save_manager.gd` 现 481 行,本批改动集中于同一承载面 | — | 判据=req-card「库内大文件不擅自拆」;拆分归工程债批 | — |
|
||||
|
||||
标识符纪律:本批新增 API 词族取 `save_slot_*`/`activate_*`/`peek_*`,**禁复用裸名 `slots`**(同调位已占,`attunement.gd:10`),命名细节仍属 §9 第 3 条代拍板域。
|
||||
|
||||
### T0 事实坐实与裁点执行(≈0.5–1d)
|
||||
|
||||
- 复核 §2 全部行号与读数,漂移即订正本卡;
|
||||
- Q1 旧档归属裁定执行(迁/留/废弃的动作落地,实现报告留痕);执行前置检查逐项过(见 §10 Q1 表「执行前置」行);
|
||||
- 槽位存储机制与启动激活态按 §9 代拍板拍板(启动激活态的玩家侧行为以卡③ Q1 裁定为约束);
|
||||
- **隔离面全清单清点**(v1.1 补):`_META_SMOKE_PATHS` 18 条+`smoke_save_*` 15 条+boot/lifecycle 四段+pacing_queue/tune_probe 两条+probe tag 族 15 处+`attach_path` 8 处直接消费+presenter lambda 注入面(main.gd:317)——逐点确认三槽化后仍可隔离到单槽,判定准则=契约 7 单路径语义;清点结果写成文(T0 产物),漏口恰是卡④要迁的探针面;
|
||||
- 与卡③ T0 互列对齐:窥视读器签名/命名/返回结构/空槽与坏槽表示法(契约 9 三态)。
|
||||
|
||||
### T1 三槽位承载(≈1–1.5d)
|
||||
|
||||
- 槽位路径派生与三槽枚举(存储机制按 §9:三文件 vs 单文件三键——硬约束=每槽档案结构与现行 v7 同构、迁移链按槽独立成立、坏档兜底按槽;**槽 1 文件名禁复用 `user://save.json`**(Q1 乙案前提,防旧档被新流程误读));
|
||||
- 当前激活位:设置/读取/清除;激活切换=同一实例内 `_data` 与路径整体替换(契约 6,attach_path 先例);
|
||||
- **启动态钉死**(v1.1 补):`_ready` 不读任何槽(`_data`=默认合法空态);无激活态一切写盘路径拒绝并返回 false;`_path` 不留 `user://save.json` 为隐式写目标。启动行为「不隐式激活」的条件表述=卡③ Q1 裁甲/乙-预选时的默认实现;**裁乙-一键直入则本段随裁定改写**(卡③ Q1 连带,本卡不自定);
|
||||
- 无激活态时访问器 fail-safe(返回合法空态/拒绝写,禁崩禁误写——同未知计数键先例,meta_progression.gd:54)。
|
||||
|
||||
### T2 档操作原语(≈1d)
|
||||
|
||||
- 新档:空槽创建=合法白板态(`_default_data` 全零可玩纪律);
|
||||
- 进档:激活+读盘(复用 `load_from_disk` 迁移/兜底链,按槽成立);
|
||||
- 删档:文件删除+该槽回合法空态+无 `.tmp` 残留+激活指针连清除(契约 8);「盘面即时生效」为卡内工程规定(挪用现役断点覆盖流注释语义,非澄清裁决语);
|
||||
- 摘要三项窥视读器:钥石余额/通关次数/冒险总局数——只读、不激活、不写盘;空槽摘要=零值合法态;坏槽按契约 9 返回显式损坏标记;
|
||||
- 写盘目标=当前激活槽文件(契约 6);激活标记自身落盘时机与 §9 第 2 条同一拍板(切槽即时写 or 进档时写)。
|
||||
|
||||
### T3 断言批(≈1.5–2d)
|
||||
|
||||
- 冒烟:三槽各自写入非默认值→写盘→新实例按位读回逐域相等(往返一致×3);删档后文件不在盘+该槽空态+激活指针清除;坏档按槽兜底;高版本拒读禁写按槽;迁移链 v1→v7 **各槽**成立(三槽各喂旧版本档→各读回相等——既有段只证单实例,本批补各槽断言);窥视三态(可读/坏/高版本)零副作用(窥视前后坏槽文件字节与 mtime 不变);
|
||||
- 单测(`game/tests/`):摘要三读器跨槽读数正确;位间隔离(改 A 槽、B 槽字节不动);`attach_path` 隔离到单槽的行为保持;
|
||||
- **启动态断言**(v1.1 补,原缺):boot 后无激活态(无激活访问器返回合法空态、写盘被拒);既有 boot 链 V2d-1(续玩钮恒隐)在新启动态下的处置显式化(改写为「boot 态续玩钮恒隐」或注明由卡② V2 改写时注销——禁判据空转);
|
||||
- **旧档处置机检**(v1.1 补,原仅件核):按 Q1 裁定案补——甲=迁移前后逐域相等+槽 2/3 空+旧档处置字节留痕;乙=旧文件字节不动;丙=旧文件按定处置;
|
||||
- **变异验证伴生**(新断言段逐条定注入实验):切槽写成只换路径不换数据(预期位间串味断言红)、删档漏删文件(预期在盘断言红)、摘要读激活位代替窥视位(预期跨槽摘要红)、`_ready` 偷复激活(预期 boot 断言红)、切槽后写盘落错槽(预期位间隔离断言红);实现期逐条执行「注入→最窄闸见红→`git checkout` 精确还原→记录」,记录表进实现报告。
|
||||
|
||||
### T4 产出物落位卡(≈0.5d,末卡——三份 `reports/` 文件写齐才算收口)
|
||||
|
||||
轻闸全绿后、合并前:`reports/iter<N>-实现报告-<完成日>.md`(各卡状态+变异验证记录表+**实际改动—验收对照表**〔§7.1 需求侧表的执行对账,另加「结果」格,test-conventions §9.3〕)/`reports/iter<N>-代拍板追认单-<完成日>.md`(§9 白名单内代拍项留痕)/`reports/iter<N>-反哺点-<完成日>.md`(§5 每条一落点)。**合并前置**:独立验收审计(§7.1 末段声明)完成且 `reports/iter<N>-验收审计-<完成日>.md` 逐行「通过」——未通过不得合并,缺漏项回炉对应 T 卡。
|
||||
|
||||
**估时合计 ≈4.5–5.5d**(v1.1 上调:隔离面全清单+启动态/窥视三态断言增量)。切分预案:T1/T2 后可切(承载层先落、操作原语后落)——但本卡零用户可见面,切分价值低,建议单批跑完。
|
||||
|
||||
## 7. 验证闸(逐需求点验收清单)
|
||||
|
||||
| # | 需求点 | 测什么 | 落点/判定手段 |
|
||||
|---|---|---|---|
|
||||
| V1 | 三存档位+启动态 | 三槽独立承载、位间零串扰;boot 后无激活态、无激活写盘被拒 | 冒烟往返一致×3+启动态断言+单测位间隔离 |
|
||||
| V2 | 新档 | 空槽创建=全零可玩合法态 | 冒烟(`_default_data` 纪律同款) |
|
||||
| V3 | 进档 | 激活+读回=该槽内容 | 冒烟 |
|
||||
| V4 | 删档 | 删后文件不在盘+槽回空态+激活指针清除+他槽零影响 | 冒烟+文件系统断言 |
|
||||
| V5 | 摘要三项 | 钥石余额/通关次数/冒险总局数按位正确;空槽零值;坏槽损坏标记;窥视前后文件字节/mtime 不变 | 单测+冒烟(判定手段写死:字节+mtime 双比对) |
|
||||
| V6 | 迁移链零破坏 | v1→v7 链在各槽成立(三槽各喂旧版本档);既有断言不破 | 冒烟既有迁移段复跑+各槽新断言 |
|
||||
| V7 | 隔离面保留 | `attach_path`/注入路径机制行为不变(18+15+族清单逐点) | 既有冒烟/探针复跑+T0 清点件核 |
|
||||
| V8 | 旧档处置 | Q1 裁定执行+机检(甲=逐域相等留痕/乙=字节不动/丙=按定处置) | 冒烟/单测按裁定案+件核 |
|
||||
| V9 | 反哺点清单 | §5 每条有落点 | 件核对表 |
|
||||
|
||||
**测试方式两分法(2026-10-11 用户定)**:V1–V8 机检自动化;能力验证可经调试接口直改槽位/钥石状态(沿用现役 DebugOverlay/DS_DEBUG 门控,不走正常资源积累流程)。**本卡零用户目检项**(无用户可见面)——选档界面目检归卡③ V 表。
|
||||
|
||||
**闸口径**:轻闸每任务卡出口自跑;批末重闸 = `tools/run_all_gates.sh` 按改动域选档(本批只碰 `game/` 代码与断言面 → `--code`)全绿才合并;MC 零跑(零数值零行为——纯承载改造,同板同序列结算逐位一致由既有 parity 面承接)。
|
||||
|
||||
### 7.1 改动—验收对照表(test-conventions §9.3 六列;§7 的 V 号在各需求点格内括注)
|
||||
|
||||
> 断言尾缀族=〔sv#〕,实现期逐条 grep 定位。落点文件为计划落点,实现期在 `reports/iter33-实现报告-<完成日>.md` 的实际对照表里按真实行号对账(§9.3 双端对上:正向每需求点一行、反向每行为改动一行、测试侧每条新断言挂一行)。层级取值见 §9.2 四层。
|
||||
|
||||
| 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 撤销或变异证明 |
|
||||
|---|---|---|---|---|---|
|
||||
| sv1 三槽承载+位间隔离(契约1/2、V1、T1) | `game/core/save_manager.gd:15` `var _path` 单路径 → 三槽路径派生+当前激活位字段(机制取 §9 第 1 条) | 冒烟 `save_slot_roundtrip`〔sv1〕落 `game/smoke/smoke_all.gd` + 单元 `game/tests/unit/core/save_slot_isolation_test.gd`〔sv1〕 | 接口 | `SaveManagerCore` 实例的按槽 API 读写往返,不经 UI | 变异=三槽路径派生写成同一文件 → 三槽往返一致断言红(T3 变异①) |
|
||||
| sv2 启动态不读盘(完成定义3、V1、T1) | `save_manager.gd:21` `_init` 默认参 `"user://save.json"` 取消+初态 `_data`=`_default_data` | 单元 `game/tests/unit/core/save_boot_no_activate_test.gd` boot 三断言〔sv2〕 | 单元 | 组合根 boot 链起的 `/root/SaveManager`(`game/project.godot:21` autoload 序) | 变异=`_ready` 内偷调 `load_from_disk` → boot 断言红(T3 变异④) |
|
||||
| sv3 无激活态写盘一律拒绝并返回 false(契约6、V1、T1/T2) | `save_manager.gd:188-202` `write_to_disk` 入口加激活态判定 | 单元〔sv3〕「拒写+返 false+盘面无新文件」三断言,同上落点 | 接口 | `MetaProgression.settle_adventure()`(`meta_progression.gd:275`,写盘 :282)无激活态触达写盘 | 撤销=去掉判定放行旧入口 → 拒写断言红 |
|
||||
| sv4 新档原语(完成定义2、V2、T2) | 新增空槽创建,初值取 `_default_data` 全零可玩纪律 | 冒烟段〔sv4〕落 `smoke_all.gd` 新档子段 | 接口 | 空槽调新档 API 后按域读回 | 变异=新档写成读旧档 → 全零可玩断言红 |
|
||||
| sv5 进档原语(V3、T2) | 进档=激活+读盘,复用 `load_from_disk`(`save_manager.gd:150-183`)按槽成立 | 冒烟段〔sv5〕 | 接口 | 槽 N 有档 → 进档 API → 读回=该槽档案内容 | 变异=进档只置激活指针不读盘 → 读回断言红 |
|
||||
| sv6 删档原语(契约8、V4、T2) | 新增删除:文件删除+该槽回合法空态+激活指针连清除+无 `.tmp` 残留 | 冒烟段〔sv6〕含文件系统存在性断言 | 集成 | 激活槽调删档 API,再经访问器读该槽+盘面核查 | 变异=漏删文件 → 在盘断言红(T3 变异②) |
|
||||
| sv7 摘要三项按槽窥视(契约5、V5、T2) | 新增按槽窥视读器,读源=`keystone_balance()`/`adventure_cleared()`/`adventure_total()`(`save_manager.gd:214`/`:264`/`:258`) | 单元 `game/tests/unit/core/save_slot_summary_test.gd`〔sv7〕三槽异值+空槽零值 | 单元 | 窥视 API 按槽调用(不激活不写盘) | 变异=摘要读激活位代替窥视位 → 跨槽摘要红(T3 变异③) |
|
||||
| sv8 窥视三态零副作用(契约9、V5、T2) | 窥视对损坏/高版本槽返回显式损坏标记,禁触发 `_corrupt_fallback`(`:443-450`)改名 | 冒烟段〔sv8〕窥视前后文件字节与 mtime 双比对 | 接口 | 盘上坏槽夹具 → 窥视 API | 变异=窥视改走正式 load 路径 → 字节/mtime 断言红 |
|
||||
| sv9 迁移链各槽成立(契约3、V6、T1/T3) | v1→v7 六件迁移链(`:25-30` 自注册)不动,执行面按槽独立成立 | 冒烟段〔sv9〕三槽各喂旧版本档→各读回相等 | 接口 | 各槽 `load_from_disk` | 变异=迁移只跑激活槽 → 他槽读回断言红 |
|
||||
| sv10 切槽=同实例整体换 `_data` 与路径(契约6、V1、T1) | 激活切换取 `attach_path` 先例(`:42-46`);`MetaProgression.save` 引用(`meta_progression.gd:21-25`/`:54`)禁换实例 | 单元〔sv10〕切槽前后引用同一性+写盘落当前槽 | 集成 | `MetaProgression` 真实宿主链驱动切槽 | 变异=切槽新建实例 → 同一性断言红;写成落错槽 → 位间隔离断言红(T3 变异⑤) |
|
||||
| sv11 测试隔离面保留(契约7、V7、T0/T3) | `attach_path` 与注入路径语义钉为「注入=激活槽文件,无激活态时注入即激活并重读」——`smoke_all.gd:5697-5704` 18 条、`:6543-6553` 15 条、`probe_ui_util.gd:98-121` tag 族行为零变化 | 既有冒烟/探针段全数复跑〔sv11〕+T0 隔离面清点成文件核 | 集成 | 各探针 `isolate_save()` 与 `attach_path` 现有调用面 | 撤销=注入路径改成忽略 → 依赖隔离的既有断言成片红(成片红即本行证明) |
|
||||
| sv12 旧档处置 Q1 甲(契约4、V8、T0) | 首次启动把 `user://save.json` 原样迁入槽 1;幂等=槽 1 已存在不重迁;旧档处置按 §10 Q1「执行前置检查」列逐项 | 冒烟段〔sv12〕迁移前后逐域相等+槽 2/3 空+处置字节留痕件核 | 接口 | 盘上放旧档夹具跑启动链迁移 | 变异=去掉幂等判据 → 二次启动重复迁移断言红;损坏+高版本叠加等意外形态路由 §8 L3 呈报 |
|
||||
| sv13 不升 schema 版本(契约3、完成定义4)——非行为改动 | `SAVE_FORMAT_VERSION := 7`(`:9`)与 `_normalize`(`:458-471`)零改动;确需新键按「v6 域后扩列不升版」先例登记 | 既有版本与高版本拒读断言复跑〔sv13〕 | 单元 | 既有冒烟版本段 | 判断依据=本行不改任何行为;撤销它=升版即撞既有高版本拒读断言(该断言已由 sv9 面钉住) |
|
||||
| sv14 反哺点清单(V9)——非行为改动 | §5 所列文档陈述(存档序列化.md `:61`/`:20`/`:165` 等)随实现换代,本批只列点不落文 | 件核对表〔sv14〕落 `reports/iter33-反哺点-<完成日>.md` | 件核 | 收口前逐条指认落点 | 判断依据=产出物件核不产码;§5 任一条缺落点即 T4 收口不过 |
|
||||
|
||||
**测试削弱申报(test-conventions §9.5)**:本卡允许改写的既有断言=boot 链 V2d-1(续玩钮恒隐)——按 T3 明列处置改写为「boot 态续玩钮恒隐」或注明由卡② V2 改写承接,禁判据空转;sv11 清单内既有段只许复跑不许动。除本段申报,实现期任何删除断言、放宽阈值、缩小扫描面、换下层直调,由独立验收审计判红。
|
||||
|
||||
**独立验收审计(test-conventions §9.7)**:合并前由未参与实现的迭代 loop 内子代理(或用户点名会话)审计——只读本卡、实现报告实际对照表、diff 与测试文件,自跑最窄测试抽查,不采信「已全绿」;审计报告落 `reports/iter33-验收审计-<完成日>.md`,逐行写「通过/缺漏/例外及依据」。**审计未通过不得合并**(T4 合并前置)。
|
||||
|
||||
## 8. 异常分级
|
||||
|
||||
- **L1(自救)**:断言写法、命名、文件落点。
|
||||
- **L2(记录继续)**:存储机制细节(三文件 vs 单文件三键,§9 域内)、激活态内存换栈写法、摘要窥视读器的缓存细节、激活标记落盘时机。
|
||||
- **L3(停机呈报)**:槽位化与现行 autoload 生命周期不可兼容且修复超出承载面;Q1 执行中发现旧档结构意外(损坏+高版本叠加等)需用户裁;任何触碰 `SAVE_FORMAT_VERSION`/迁移链的诉求;§9 第 1 条选单文件三键致契约 7 不可守(隔离面须改)。
|
||||
|
||||
## 9. 代拍板白名单(超清单必呈报)
|
||||
|
||||
1. 槽位存储机制与文件命名(三文件 `user://save_slot_N.json` vs 单文件三键+激活索引)——约束:每槽结构与现行 v7 同构、迁移链按槽成立、坏档兜底按槽、**槽 1 文件名禁复用 `user://save.json`**。
|
||||
2. 启动激活态的数据层机制(激活位持久化位置)——约束:玩家侧行为以卡③ Q1 裁定为准;**仅卡③ Q1 裁乙才需持久化,裁甲则作废**(连同卡③ 契约 8 父注一并按裁定回写)。
|
||||
3. 类 API 命名(槽位/激活/窥视词族)与文件落点。
|
||||
4. 删档边界(激活态槽可删性)——约束:禁崩禁误写,删后回合法空态+激活指针连清除;激活态生命周期终点=持续至显式清除/进程结束/该槽被删,**回主菜单不清除**(卡③ Q1 乙案「记忆上次激活槽」读持久化点而非内存态)。
|
||||
5. 提交切分与 worktree 分支命名。
|
||||
|
||||
## 10. 待裁点
|
||||
|
||||
### Q1 · 旧档 `user://save.json` 的归属(必裁,未裁不开工)
|
||||
|
||||
**背景**:现行单档在开发机可能已有进度(钥石/天赋树/锻造/断点等)。槽位化后旧档必须有明确去向。三案并列,**无推荐**(用户令:不代裁):
|
||||
|
||||
| 案 | 内容 | 代价 | 执行前置检查 |
|
||||
|---|---|---|---|
|
||||
| 甲 | 迁为 1 号存档位:首次启动一次性迁移,v7 结构原样落入槽 1,槽 2/3 空 | 一次性迁移代码+迁移失败兜底面 | 旧档不存在=无操作(陈明);旧档损坏/高版本=「原样落入槽 1」承诺失效,路由 §8 L3 呈报;迁移后 `user://save.json` 处置(删/改名留痕)+幂等判据(槽 1 已存在不重迁)须在实现报告写明 |
|
||||
| 乙 | 原样保留、不自动加载:旧文件留盘但新流程不读,自行处置 | 旧档成孤儿文件——盘面出现「看得见拿不到」的档 | 槽 1 文件名禁复用 `user://save.json`(否则「不自动加载」落空);.tmp 残留清理或陈明 |
|
||||
| 丙 | 开发阶段破坏性废弃:按迭代 21 T5 树域废弃先例(禁迁移禁折算)弃旧档,从空三槽开始 | 开发机现有进度全清 | 旧文件按定处置(删/归档)写明 |
|
||||
|
||||
裁决方式:随卡片评审一并定案;裁定落 T0 执行+实现报告留痕。
|
||||
|
||||
**裁定(2026-10-18)**:**甲**——迁 1 号存档位。代拍板留痕(用户令「事项按推荐的来」,本项无推荐案,取默认甲=不丢开发机进度;追认单可 veto)。执行按「执行前置检查」列逐项过,迁移后旧档处置与幂等判据写实现报告。
|
||||
|
||||
### Q2 · 交付序列:本卡可否先于卡③落地(必裁,未裁不定排期)
|
||||
|
||||
**背景**:见 §0。卡③未到位前无生产激活入口;旧入口在无激活态下写盘全被拒且 `settle_adventure` 忽略写盘返回值(meta_progression.gd:275,写盘 :282)→进度静默丢失;冒烟探针走隔离路径不会红,机检放控不住。
|
||||
|
||||
| 案 | 内容 | 代价 |
|
||||
|---|---|---|
|
||||
| 甲(推荐) | 与卡③同批交付或卡③在先(改 §0「可先行」表述,仿卡② 契约 5 硬依赖先例) | 排期自由度下降 |
|
||||
| 乙 | 批内留临时隐式激活:旧入口首次触达存档时激活槽 1,卡③到位后摘除留痕 | 临时代码+摘除时的二次验证面 |
|
||||
| 丙 | 接受中间态:登记 L2 已知缺口(激活入口真空),合入前呈报用户知晓 | 中间态进度丢失风险靠用户知情兜底 |
|
||||
|
||||
裁决方式:随卡片评审定案;裁甲则 §0 改写,裁乙/丙则按表执行并在实现报告「已知缺口」节登记。
|
||||
|
||||
**裁定(2026-10-18)**:**甲**——与卡③同批交付或卡③在先(推荐案,用户令按推荐执行)。§0「可先行」表述按裁甲维持;卡④(2026-10-18 回设计段)不影响本链路——卡③在工程批内,激活入口不真空。
|
||||
|
||||
---
|
||||
|
||||
**审查回写要点**: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)零改动。
|
||||
@@ -0,0 +1,222 @@
|
||||
# 需求卡片:状态面板瘦身批(局内面板去跨关解锁内容、只留本局信息)
|
||||
|
||||
- 版本:**v1.1**(2026-10-23 grilling 复核后定稿;自审六查+grilling 复核结论见 §12)
|
||||
- 来源:[待办清单](../待办清单.md)「状态面板瘦身——局内面板去跨关解锁内容、只留本局信息」(2026-10-16 登记,来源=playnote,设计面=工程直入,状态=待写卡)(唯一事实源:[08-Alpha版本标准](../design/gdd/08-Alpha版本标准.md) v1.14「三 · 界面」状态面板行+工程直入证据=`game/presentation/views/status_panel.gd` 实查 file:line,见 §2)
|
||||
- 归属:`game/presentation/views/status_panel.gd`(呈现层承载)+ `game/presentation/main.gd`(快照投影)+ 两屏入口角标 tooltip(`board_zone_view.gd`/`level_map_screen.gd`)
|
||||
- 排期:未编入(卡片不预占迭代号;本卡估时 ≈1–2 工作日,低于编排硬下限 5 工作日,须与其他卡同批编入——归 iter-plan 段四查③)
|
||||
- 开工门:U0(用户 `/iter` 发令)+ grilling 复核门过(零待裁点,见 §11)
|
||||
|
||||
## 0. 前置依赖与并行性
|
||||
|
||||
- **第〇步核对(2026-10-23 写卡会话)**:工程直入条目,条目现状带代码级证据指认(`status_panel.gd` 跨局镜像三段实查,本卡 §3 F1 复核扩充到行号);范围=用户原话五件套、条目自记零待裁点;目标态权威已落文(08 状态面板行,用户 2026-10-16 令「不需要讨论的写进 08」)→ **放行写卡**。
|
||||
- 本卡**不依赖任何在途批**:与「营地五界面窗口化批」无关联(该批裁五功能页的窗口形态,本批面板形态不动——modal 直开现状维持);与「棋盘战斗键盘/手柄输入」批无关联(Esc 通道归彼批,本批零改动);与「现役 UI/文案两处自相冲突」条目无关联(HUD C 区两段同标「特性」是彼条的事,本批不碰 C 区)。
|
||||
- 排期提示(非本卡义务):跨局解锁概览的营地/生涯承载**现役已在位**(营地柜台+生涯页),本批退役面板半边后零承载缺口。
|
||||
|
||||
## 1. 目标与完成定义
|
||||
|
||||
**目标**:局内状态面板从「跨局进度镜像」(钥石余额+秘宝匣解锁态 12 行概览+天赋树已购概览)换代为「本局信息面板」——只留钥石总量+本局四件:带的秘宝、已获专长、当前属性、现有 GP;两段跨关解锁概览整段退役;面板提示行与两屏入口角标 tooltip 文案随新定位换代。
|
||||
|
||||
**相对现状,改了什么**:
|
||||
1. 面板内容换代:删「道具工坊 · 解锁态」段(12 行三列解锁态)与「天赋树 · 已购概览」段(聚合文案);新增「本局状态」行(生命 当前/上限 · 攻击 · 护甲 AC · GP)+「带的秘宝」段(逐件名,已用件带尾缀)+「已获专长」段(逐件「件名 ×N」行串);
|
||||
2. 快照投影换代:`main._status_data()` 四键(balance/workshop/tree/fork_groups)→ 八键(balance/hero_hp/max_hp/atk/ac/gp/curios/feats),秘宝与专长全部复用现役投影函数零第二实现(契约 3);
|
||||
3. 文案三处换代:面板提示行+战斗屏角标 tooltip+地图屏角标 tooltip(「永久强化进度」语义随退役失效);标题「状态」与「继续」钮不变;
|
||||
4. 断言面随动:冒烟隔离档投影一致性段换代(工坊/天赋树断言族退役——削弱申报见 §8.3)+`ui_click_probe` 真实入口补三断言(零旧段+属性行全值对 runner 现值+`_status_data()` 直调投影值对拍)——`main` 侧投影代码的值层由此进断言回路(grilling 回炉订正:v1.0 仅「零旧段」时投影值层零拦截)。
|
||||
|
||||
**完成定义**(全部满足才算本批完成):
|
||||
1. 面板五件内容在位且投影一致(冒烟隔离档断言绿:余额徽/属性行全值/秘宝行受理序与已用尾缀/专长行串/空态句×2);
|
||||
2. 跨关概览退役零残留:面板子树零「道具工坊」「天赋树」文案、`_status_data()` 零 workshop/tree/fork_groups 三旧键、真实入口(角标开层)同判据绿;
|
||||
3. 文案三处换代在位且标题「状态」/「继续」钮定位锚不变(四探针状态面板相关段零红);
|
||||
4. 只读契约与零动效契约保持全绿(`ui_struct_probe` ⑧:信号连接数=2、源码零 tween/AnimationPlayer——非新增断言,回归线);
|
||||
5. 变异验证记录表进实现报告;批末重闸按改动域选档全绿+改前改后读数对拍;三份 `reports/` 产出物写齐(T2)。
|
||||
|
||||
## 2. 设计事实源
|
||||
|
||||
| # | 出处 | 取用条款 |
|
||||
|---|---|---|
|
||||
| D1 | `design/gdd/08-Alpha版本标准.md` v1.14(2026-10-23 现行)「三 · 界面」状态面板行(:115) | 目标态权威:瘦身范围=「去跨关解锁内容〔秘宝匣解锁态 12 行概览/天赋树已购概览〕、只留本局五件〔带的秘宝/已获专长/当前属性/现有 GP/钥石总量〕」;出口判据=「只显示本局五件、两段跨关解锁退役、文案更新、界面探针或断言覆盖、用户目检通过」——用户 2026-10-16 令「不需要讨论的写进 08」落文(本卡完成定义与之一一对应) |
|
||||
| D2 | 待办清单条目(工程直入证据,2026-10-23 复核扩充到行号) | 现行实态=跨局进度镜像:钥石余额徽+「道具工坊 · 解锁态」段+「天赋树 · 已购概览」段(`status_panel.gd:9/:22/:30/:34/:37`);范围=用户原话五件套、零待裁点 |
|
||||
|
||||
闭合凭据一致性:D2 与待办清单条目现状内的实查证据一致(写卡会话复核到行号);D1 为目标态权威(与 D2 同向——用户 2026-10-16 同时发两令:范围五件套+落文 08)。
|
||||
|
||||
## 3. 现状事实(2026-10-23 主区实查;开工日 T0 复核行号)
|
||||
|
||||
| # | 事实 | 出处 |
|
||||
|---|---|---|
|
||||
| F1 | 面板构成=标题「状态」+提示行「查看本局钥石与永久强化进度(只读——购买请回营地)」+钥石余额徽+「道具工坊 · 解锁态」段(`_rebuild_workshop` 秘宝匣 12 行三列解锁态:件名/钥石价或条件进度/已解锁态)+「天赋树 · 已购概览」段(`_rebuild_tree` 单条聚合文案,零已购=空态句)+「继续」钮;成员 `_workshop_holder`/`_tree_label` | `game/presentation/views/status_panel.gd:19`/:22/:30/:34/:37/:46-49/:68-72(open_status)/:78-109/:113-132 |
|
||||
| F2 | 快照投影四键:`_status_data()` 返回 balance=`meta.keystone_balance()`+workshop=`meta.treasure_shop_status()`+tree=`meta.tree_camp_rows()`+fork_groups=`meta.tree_fork_groups()`;开层口=`_open_status_panel()`→`open_status(_status_data())`;头注锁定「快照随开随建、单次开层生命周期、零写调用」口径 | `game/presentation/main.gd:1070-1076`/:1079-1081 |
|
||||
| F3 | 入口与在役前置:战斗屏角标可见判据=`run_scope.level_active and not map_on`;地图屏角标=随屏;而地图屏仅经 `open_choices(run_scope.pending_candidates, run_scope.runner)` 开启 ⇒ **两入口任一可开层时 `run_scope.runner` 恒在役** | `main.gd:1196-1197`(可见性);:695/:1006(open_choices 两调用点) |
|
||||
| F4 | 本局五件数据源(全部现役访问器,零新增记账面):钥石总量=`meta.keystone_balance()`(:1071 现用);当前属性=`runner.effective_max_hp()`/`effective_atk()`/`effective_ac()`+当前生命=`runner.ledger["hero_hp"]`;现有 GP=`runner.ledger["gp"]`;带的秘宝=`_treasure_ui.inventory_projection()`(行含 name/used,主区持有 `_treasure_ui`);已获专长=`HudPresenter.feat_holdings_lines(db, runner.feats_held())`(static,行形态=逐件「件名 ×N」,空持有=空数组) | `adventure_runner.gd:28`(ledger 字段)/:295(effective_max_hp)/:453(feats_held);`hud_presenter.gd:91-102`(feat_holdings_lines)/:150-151(atk/AC 先例);`treasure_interact_controller.gd:102-127`(inventory_projection);`main.gd:101`(_treasure_ui 声明)/:240(实例化);:694/:1005(feat_holdings_lines 现用先例) |
|
||||
| F5 | 秘宝投影停点安全:`inventory_projection()` 的 usable 预判回调在 settlement 为空时是空 Callable,`query_inventory → _usable_now` 对 invalid Callable 回退 true ⇒ 停点(地图屏)与战斗屏两上下文复用均安全 | `treasure_items.gd:73-75`;`treasure_interact_controller.gd:108-111`(cb 装配) |
|
||||
| F6 | 既有断言面(改前基线):①冒烟隔离档 `_status_panel_projection`——余额徽读数+工坊 12 行投影逐项+天赋树聚合文案三断言族(夹具=手拼数据字典喂 `open_status`,同构口径、不依赖 runner);②`ui_struct_probe` ⑧ 只读契约(信号连接数=2,白名单=视图 `_emit_closed`/组合根 `_on_status_closed`)+零动效契约(子树零 AnimationPlayer+源码零 `create_tween`/`UiKit.motion` token);③`ui_click_probe`(角标开层+`_balance_badge` 读数+继续钮关层);④`ui_input_probe`(Esc 通道+继续钮);⑤`shot_probe`(标题「状态」几何+截图+继续钮开关) | `smoke_all.gd:5727-5779`;`ui_struct_probe.gd:295-323`/:326-340;`ui_click_probe.gd:593-621`;`ui_input_probe.gd:525-542`;`shot_probe.gd:172-188` |
|
||||
| F7 | 渲染闸零 golden 锁:`shot_checker` 对 status 屏只跑屏级骨架(存在/尺寸/灰度 std≥8/唯一色数≥64),无像素基线 ⇒ 面板内容换代**不连带 golden 基线重制** | `tools/shot_checker.py:130-140`(A 屏级骨架);`tools/render_gate.sh:65`(status 屏入参) |
|
||||
| F8 | 旧文案引用点全集=三处:面板提示行(`status_panel.gd:22`)+两角标 tooltip「查看钥石与永久强化进度(只读)」(`board_zone_view.gd:58`、`level_map_screen.gd:107`)——「永久强化进度」半句随两段退役失效;全仓无第三处(2026-10-23 实查) | 上列三 file:line |
|
||||
| F9 | 改前读数基线=开工日 T0 采集(冒烟/单测通过数对拍面)——写卡会话不跑测(测试执行两入口铁规),本卡不预写数字 | — |
|
||||
|
||||
## 4. 设计契约(红线,违反 = L3 停机呈报)
|
||||
|
||||
🔴 **契约 1 · 五件内容口径**:面板内容=钥石总量徽+「本局状态」行(`生命 %d/%d · 攻击 %d · 护甲 AC %d · GP %d`——属性四值与 GP 合一行呈现)+「带的秘宝」段+「已获专长」段,四块 UI 承载五件信息;除此外零新增段。五件取数源=F4 访问器族——属性行取 `effective_max_hp()`/`effective_atk()`/`effective_ac()`/`ledger["hero_hp"]`/`ledger["gp"]`(ledger 直取下标,键缺失=致命,禁 `.get` 缺省值留门),秘宝取 `_treasure_ui.inventory_projection()`,专长取 `HudPresenter.feat_holdings_lines()`;禁第二份投影/拼装实现。
|
||||
|
||||
🔴 **契约 2 · 跨关概览退役零残留**:`status_panel.gd` 内秘宝匣解锁态段与天赋树已购概览段**整段退役**(段头+行构建函数+数据键三层面清零):`status_panel.gd` 的 `_rebuild_workshop`/`_rebuild_tree` 与 `_workshop_holder`/`_tree_label` 删除;`_status_data()` 不再喂 workshop/tree/fork_groups 三键。`meta.treasure_shop_status()`/`tree_camp_rows()`/`tree_fork_groups()` 三投影函数本体**不动**(营地柜台仍在役消费——退役仅面板半边);`camp_overlay_view.gd` 的同名 `_rebuild_workshop`(:448)/`_rebuild_tree`(:222)/`_workshop_holder`(:32)为营地在役件,与本章零关联零改动。
|
||||
|
||||
🔴 **契约 3 · 只读快照语义不破**:快照随开随建、单次开层生命周期、跨开层零持有、零写调用(`open_status` 重建各行现状口径沿袭);新增 UI 全部经 UiKit 工厂产出、禁裸色值(`status_panel.gd:3` 头注纪律);`ui_struct_probe` ⑧ 两契约(信号连接数=2+零动效 token 扫描)保持全绿是本批回归线——面板仍只有「继续」钮一条 pressed 连接+`closed` 外发一条。
|
||||
|
||||
🔴 **契约 4 · 文案钉值**:面板提示行→「查看本局冒险进度(只读)」;战斗屏与地图屏角标 tooltip→「查看本局冒险进度(只读)」;标题「状态」与「继续」钮文案**不变**(F6 四探针定位锚);段头=「本局状态」「带的秘宝」「已获专长」(词干=用户原话);空态句=「未携带秘宝」「未获专长」(现行天赋树空态句同形制,`status_panel.gd:130` 先例);已用秘宝件行尾缀=「(已用)」。
|
||||
|
||||
🔴 **契约 5 · runner 在役前置零软回退**:两入口开启时 `run_scope.runner` 恒在役(F3 证据链);`_status_data()` 直读 `run_scope.runner`,**禁加 null 守卫软回退**(fail-fast 红线——若出现 runner 空指针属状态机缺陷,按 L3 呈报,禁以零值显示掩盖)。
|
||||
|
||||
🔴 **契约 6 · 数值单一事实源**:面板显示值全部实时读访问器现值(F4),禁数值字面量(文案固定串除外);生命上限走 `effective_max_hp()`(生效上限口径——含调试浮窗 pct,与战斗内同源,`adventure_runner.gd:123/:293-296`)。
|
||||
|
||||
## 5. 范围边界
|
||||
|
||||
**做**:`status_panel.gd` 内容换代(两段退役+三段新装+提示行);`main._status_data()` 八键投影换代;两角标 tooltip 换代;冒烟隔离档断言面换代(含 §8.3 削弱申报);`ui_click_probe` 真实入口补「零旧段+GP 读数」断言;反哺点清单。
|
||||
|
||||
**不做**(明示去向):
|
||||
- 营地侧/生涯侧任何承载面改动——跨局解锁概览的营地柜台与生涯页承载现役在位,本批零改动;
|
||||
- `meta.treasure_shop_status()`/`tree_camp_rows()`/`tree_fork_groups()` 三投影函数本体(契约 2,营地仍在役);
|
||||
- HUD C 区(`hero_info_panel_view.gd`)——含其在册的 `_curio_section`/`_feat_section` 同标「特性」文案冲突(待办清单另条,本批不碰);
|
||||
- 面板开合机制/模态栈/角标置灰逻辑/键盘 Esc 通道(零改动;Esc 通道归键盘批);
|
||||
- 面板视觉规格(窗宽 560/石板皮/零动效维持现状——呈现形态换代归「营地五界面窗口化批」口径,彼批与本批无关联,见 §0);
|
||||
- HUD C 区「特性」措辞是否随本批统一为「专长」——归文案冲突条目(待办清单在册),本批只保证自家新段头用规范名「专长」;
|
||||
- 体验验证清单 ⑳ 已核销历史条目的追溯改写与否——列反哺点由用户裁(§6 ④)。
|
||||
|
||||
## 6. 关联文档同步面
|
||||
|
||||
> 本批是代码实现批,禁写 `design/` 整目录与根规则文件,唯一可写目录=`reports/`。下表「同步义务」一律执行为:逐条列进 `reports/iter<N>-反哺点-<完成日>.md`(哪个文件哪一节、改成什么、依据),用户会话裁决后归文档批落文。
|
||||
|
||||
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|
||||
|---|---|---|
|
||||
| `design/gdd/systems/跨局循环/元进度.md` | 「### 解锁界面:双入口框架」节(:104-106)「局内状态面板……也可查看钥石余额与**已解锁清单**(只读)」——「已解锁清单」半句随两段退役失效 | 反哺点 · 列清单(①该句换代为「钥石余额与本局冒险信息」口径;依据=本卡契约 1/2) |
|
||||
| `design/gdd/systems/跨局循环/生涯.md` | :30「冒险进行中玩家只看状态面板(……局内只读查看钥石与**解锁进度**)」括注;:73 分工表行「局内只读查看这一局进行中的钥石与**解锁进度**」——「解锁进度」半句同失效 | 反哺点 · 列清单(②两处括注/表行换代;依据=契约 1/2) |
|
||||
| `design/gdd/08-Alpha版本标准.md` | :115 状态面板行现标「部分在役(在役半=面板本体……未结半=2026-10-16 用户令瘦身……)」——批完成后未结半销号 | 反哺点 · 列清单(③「部分在役」→「在役」+出口判据逐项销号记载;依据=本卡完成定义) |
|
||||
| `体验验证清单.md` | ⑳「营地统一四柜台目检」(已核销 2026-10-14)连带面句「状态面板属性锻造段已消失(钥石+工坊+天赋树概览)」——历史现状句随换代过时 | 反哺点 · 列清单(④追溯改写与否由用户裁——已核销历史记录,改否只影响史实描述精度) |
|
||||
| `待办清单.md` | 本卡登记条状态推进「已写卡」(**本会话写卡时已执行**);实现批完成后条目整条退役 | 反哺点 · 列清单(⑤批后退役归 batch-closure) |
|
||||
| `roadmap.md` | 迭代行编入笔(编入哪一迭代由 iter-plan 段发令,本卡不预占) | 反哺点 · 列清单(⑥) |
|
||||
| `game/presentation/views/status_panel.gd`、`game/presentation/main.gd`、`game/presentation/views/board_zone_view.gd`、`game/presentation/views/level_map_screen.gd` | 换代本体 | 实施本体(可写) |
|
||||
| `game/smoke/smoke_all.gd`、`game/smoke/ui_click_probe.gd` | 断言面随动(§8) | 实施本体(可写) |
|
||||
|
||||
## 7. 任务卡
|
||||
|
||||
> 估时按 Claude 工作日口径;每卡出口自跑轻闸;开工日 T0 复核本卡全部行号。回归措辞模板:里程碑步(T 段)出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试先行孤立验证再并入全套。
|
||||
|
||||
### 卡前 · 文件结构图
|
||||
|
||||
| 文件 | 职责 | 行为改动 |
|
||||
|---|---|---|
|
||||
| `game/presentation/views/status_panel.gd` | 面板内容换代:两段整段退役+三段新装+提示行文案(复用既有·修改) | 行为改动 → 对照表 sv1/sv2/sv3/sv5/sv8 |
|
||||
| `game/presentation/main.gd` | `_status_data()` 四键→八键投影换代(复用既有·修改) | 行为改动 → 对照表 sv1/sv2/sv3/sv7 |
|
||||
| `game/presentation/views/board_zone_view.gd` | 角标 tooltip 一句换代(复用既有·修改) | 行为改动 → 对照表 sv9 |
|
||||
| `game/presentation/views/level_map_screen.gd` | 角标 tooltip 一句换代(复用既有·修改) | 行为改动 → 对照表 sv9 |
|
||||
| `game/smoke/smoke_all.gd` | `_status_panel_projection` 断言面换代(复用既有·改写验收函数——变异伴生义务) | 行为改动(断言面)→ 对照表 sv1–sv5/sv8 |
|
||||
| `game/smoke/ui_click_probe.gd` | 真实入口补三断言:零旧段+属性行全值+`_status_data()` 直调对拍(复用既有·增步) | 行为改动(断言面)→ 对照表 sv6/sv7 |
|
||||
| `reports/iter<N>-实现报告/代拍板追认单/反哺点`(三份,批末写) | 产出物落位 | 非行为改动 → 对照表 sv10 |
|
||||
|
||||
本批**零新增文件、零新增数据件**;新增成员仅 `_attrs_label`/`_curios_label`/`_feats_label` 三个面板内 Label(落位唯一性见 §7 前置「落位与可复用性预检」)。
|
||||
|
||||
### 接口块(全卡共用,后卡引用以此为准)
|
||||
|
||||
- **`main._status_data() -> Dictionary`** 八键契约:`balance:int`(=`meta.keystone_balance()`)/`hero_hp:int`(=`int(run_scope.runner.ledger["hero_hp"])` 直取下标)/`max_hp:int`(=`run_scope.runner.effective_max_hp()`)/`atk:int`(=`run_scope.runner.effective_atk()`)/`ac:int`(=`run_scope.runner.effective_ac()`)/`gp:int`(=`int(run_scope.runner.ledger["gp"])` 直取下标)/`curios:Array`(行=`{String name, bool used}`,由 `_treasure_ui.inventory_projection()` 逐行映射 `name`/`used` 两键,序=库存受理序)/`feats:Array[String]`(=`HudPresenter.feat_holdings_lines(db, run_scope.runner.feats_held())` 现成行)。
|
||||
- **`StatusPanel.open_status(data: Dictionary) -> void`** 签名不变(消费键换代为八键)。
|
||||
- **面板成员替换**:删 `_workshop_holder`/`_tree_label` 与 `_rebuild_workshop()`/`_rebuild_tree()`;增 `_attrs_label`/`_curios_label`/`_feats_label` 三个 `UiKit.label`(FS_HINT 档、autowrap 同 `_tree_label` 现制,`status_panel.gd:38-40`);段头沿 `_section_head()`(FS_BODY 档)现状复用。
|
||||
|
||||
### 落位与可复用性预检(本批新增件逐条三问)
|
||||
|
||||
- **`_attrs_label`/`_curios_label`/`_feats_label`(面板内三个 Label 成员)**——复用面:面板内既有 `_tree_label` 同形制(单条聚合文案+autowrap),新三件沿其形制、不另造行构建器;为什么不复用 `_tree_label` 本身:它是「天赋树已购概览」段的载体,随段整段退役(契约 2),名字与语义均已失效。唯一面:属性行/秘宝行/专长行在全仓各只有面板这一处消费(F4 投影函数是数据面唯一落点,本卡不加第二份)。分层与交互面:面板零核心依赖——数据全部由组合根 `_status_data()` 快照喂入(既有开层生命周期口径),面板不自读 runner/meta,只读契约由 `ui_struct_probe` ⑧ 巡检兜底。
|
||||
- **秘宝投影复用 `_treasure_ui.inventory_projection()`**——为什么不自拼:`runner.treasure_inventory.query_inventory()` 的行是内部记录(item_id),件名换算(`db.treasure_item_row().display_name`)与受理序语义已在 `inventory_projection()` 收口(C 区四槽同源);自拼=第二份投影实现,违落点唯一。停点安全性已核(F5)。
|
||||
- **专长行复用 `HudPresenter.feat_holdings_lines()`**——为什么不自拼:「件名 ×N」聚合计数逻辑已在该 static 函数收口(战斗 C 区与关卡选择页两处现役共用,`hud_presenter.gd:85-88` 头注),自拼=第二份计数实现。
|
||||
- **`db` 访问**:`_status_data()` 内 `feat_holdings_lines(db, …)` 的 `db` 用组合根既有成员 `db`(`main.gd` 现役 ConfigDB 门面),零新访问器。
|
||||
|
||||
### T0 事实坐实(≈0.25–0.5d)
|
||||
|
||||
- [ ] 复核 §3 全部 file:line 与 F8 旧文案引用点全集(全仓检索「道具工坊 · 解锁态」「已购概览」「永久强化进度」仍零第三处)——可核查结果:订正记录或「零漂移」声明进实现报告素材。
|
||||
- [ ] 改前读数基线采集(冒烟/单测通过数,两入口铁规下随 T1 loop 首跑取值)——可核查结果:基线读数记录在案。
|
||||
|
||||
### T1 面板与投影换代(≈0.5–1d)
|
||||
|
||||
- [ ] 实装 `main._status_data()` 八键投影(`main.gd:1070-1076` 重写;接口块八键逐字;curios 由 `_treasure_ui.inventory_projection()` 映射;feats 走 `HudPresenter.feat_holdings_lines(db, run_scope.runner.feats_held())`)。可核查结果:八键在位、workshop/tree/fork_groups 三旧键零残留。
|
||||
- [ ] 实装 `status_panel.gd` 内容换代(:22 提示行文案;:33-40 两段定义删——`HSeparator` 两条(:33/:42)保留作分区线;:78-132 `_rebuild_workshop`/`_rebuild_tree` 与两成员删;`_init` 增三段头+三 Label;`open_status` 改喂八键——属性行串按契约 4 钉值格式、秘宝行=「件名(已用)」受理序 join「 · 」、专长行=现成行 join「 · 」、空态句两则)。可核查结果:面板子树零「道具工坊」「天赋树」文案;UiKit 工厂产出(零裸色值)。
|
||||
- [ ] 实装两角标 tooltip 换代(`board_zone_view.gd:58`、`level_map_screen.gd:107` →「查看本局冒险进度(只读)」)。可核查结果:全仓「永久强化进度」检索零命中。
|
||||
- [ ] 实装冒烟 `_status_panel_projection` 换代(`smoke_all.gd:5727-5779` 重写:夹具改八键手拼〔同构口径不变、不依赖 runner〕;断言=余额徽读数+属性行全值+秘宝行含已用尾缀+专长行串+空态句×2+面板子树零旧段文案;原工坊 12 行断言族与天赋树聚合断言按 §8.3 申报删除)。可核查结果:该段绿且含 V1/V2 全部断言。
|
||||
- [ ] 验收步骤:T 段出口跑一次全套闸(`tools/run_all_gates.sh` 按改动域选档,本批只碰 `game/` → `--code`),期望代码域全绿、`ui_struct_probe` ⑧ 两契约与 click/input/shot 三探针状态面板段零红。
|
||||
- [ ] 变异验证(注入→最窄闸见红→`git checkout` 精确还原→记录):①面板 gp 读数改硬编码 `0` → 期望属性行断言红;②「(已用)」尾缀逻辑删 → 期望秘宝行断言红;③面板重加「道具工坊 · 解锁态」段头 → 期望零旧段断言红。记录表进实现报告。
|
||||
|
||||
### T2 真实入口断言+产出物落位卡(≈0.25–0.5d,末卡)
|
||||
|
||||
- [ ] 实装 `ui_click_probe` 状态面板段补三断言(`ui_click_probe.gd:593-621` 段内,角标开层后):①面板子树零「道具工坊」「天赋树」文案;②属性行全串==契约 4 格式 % `run_scope.runner` 五现值(hero_hp/`effective_max_hp()`/`effective_atk()`/`effective_ac()`/gp——`main` 侧投影值层的真链路断言);③`main._status_data()` 直调对拍——返回键集恰为接口块八键(sv7 承载)+curios 逐行 {name, used} 对拍独立oracle(`runner.treasure_inventory.query_inventory(Callable())` 行集 × `db.treasure_item_row().display_name`)+feats 对拍 `HudPresenter.feat_holdings_lines(db, runner.feats_held())`。可核查结果:探针该段绿。
|
||||
- [ ] 验收步骤:T 段出口跑一次全套闸(`--code`),期望代码域全绿。
|
||||
- [ ] 变异验证(注入→最窄闸见红→`git checkout` 精确还原→记录):①还原面板 workshop 段(注入旧段头)→ 期望断言①红(真实入口);②`_status_data()` curios 映射漏 `used` 键 → 期望断言③红(main 侧注入);③`_status_data()` max_hp 错读 `ledger["hero_hp"]` → 期望断言②红(main 侧注入)。记录表进实现报告。
|
||||
- [ ] 轻闸全绿后、合并前写齐三份:`reports/iter<N>-实现报告-<完成日>.md`(各卡状态+变异验证记录表+实机目检总清单〔面板观感一条〕+遗留读数义务)/`reports/iter<N>-代拍板追认单-<完成日>.md`(§10 白名单内代拍项留痕)/`reports/iter<N>-反哺点-<完成日>.md`(§6 六条每条一落点+§11 四处推导定值逐条列示供否决)。可核查结果:三文件在 `reports/` 且 §6 同步面每条有落点、§11 定值全部列示。
|
||||
- [ ] 合并前置:独立验收审计(§8.2 末段声明)完成且报告 `reports/iter<N>-验收审计-<完成日>.md` 逐行「通过」——未通过不得合并,缺漏项回炉对应 T 卡。可核查结果:审计报告在 `reports/` 且逐行「通过」。
|
||||
|
||||
**估时合计 ≈1–2d**(T0 0.25–0.5+T1 0.5–1+T2 0.25–0.5)。切分预案:T1 内投影与面板可切,但中间态消费键断链(面板读旧键投影已换代),建议 T1 一轮同落;本卡无超软盒预挂面(批小)。**编排注记**:本卡估时低于 iter-plan 四查③硬下限 5 工作日,单独不成迭代——与其他卡同批编入。
|
||||
|
||||
## 8. 验证闸
|
||||
|
||||
### 8.1 逐需求点验收清单
|
||||
|
||||
| # | 需求点 | 测什么(断言/行为) | 落点/判定手段 |
|
||||
|---|---|---|---|
|
||||
| V1 | 本局五件投影一致 | 夹具八键手拼→面板读数逐项相等:余额徽「钥石 %d」;属性行「生命 %d/%d · 攻击 %d · 护甲 AC %d · GP %d」全值;秘宝行=受理序件名 join、已用件带「(已用)」尾缀;专长行=行串 join;空态句×2(curios/feats 空夹具各跑一遍) | 冒烟隔离档 `_status_panel_projection` 换代(`smoke_all.gd:5727-5779`) |
|
||||
| V2 | 跨关概览退役零残留 | ①面板子树零「道具工坊」「天赋树」文案(隔离档);②真实入口三断言:零旧段+属性行全值对 runner 五现值+`_status_data()` 直调键集恰八键与 curios/feats 对拍(对局中直调——runner 在役前置由探针对局承担) | 冒烟①+`ui_click_probe` ②(T2 新增三断言) |
|
||||
| V3 | 文案三处换代 | 面板提示行=「查看本局冒险进度(只读)」;两 tooltip 同串;标题「状态」与「继续」钮定位锚不变 | 冒烟提示行断言+四探针既有定位锚回归(零改动自证) |
|
||||
| V4 | 只读与零动效契约保持 | 信号连接数=2(白名单两连接);子树零 AnimationPlayer+源码零 `create_tween`/`UiKit.motion` token | `ui_struct_probe` ⑧ 两契约(**零改动回归线**——失效即 L3) |
|
||||
| V5 | 既有探针回归 | click/input/shot/struct 四探针状态面板相关段零红 | 全套闸探针档(改前改后读数对拍) |
|
||||
| V6 | 反哺点清单 | §6 六条每条有落点 | 件核对表(T2 出口) |
|
||||
|
||||
### 8.2 改动—验收对照表
|
||||
|
||||
> 各断言 desc 统一尾缀〔sv#〕(本表「验收测试」列可 grep 定位);变异/撤销证明逐条对应 T1/T2 变异步。
|
||||
|
||||
| 需求点 | 改动(文件:行/行为) | 验收测试(名称+文件+尾缀) | 层级 | 真实入口 | 撤销或变异证明 |
|
||||
|---|---|---|---|---|---|
|
||||
| sv1 属性行投影 | `main.gd:1070-1076` 八键投影+`status_panel.gd` 属性行串(契约 4 格式) | 属性行全值投影〔sv1〕 `smoke_all.gd` `_status_panel_projection` 换代 | 集成 | `open_status()` 直喂八键夹具(同构口径) | 变异:面板 gp 硬编码 0(T1 变异步①)→ 本断言红 |
|
||||
| sv2 秘宝行投影 | `_status_data()` curios 映射+面板秘宝行(受理序+「(已用)」尾缀) | 秘宝行受理序与已用尾缀〔sv2〕 同上 | 集成 | 同 sv1 | 变异:尾缀逻辑删(T1 变异步②)→ 本断言红 |
|
||||
| sv3 专长行投影 | `_status_data()` feats 透传+面板专长行 join | 专长行串投影〔sv3〕 同上 | 集成 | 同 sv1 | 撤销证明:回退 feats 键接线 hunk → 本断言红 |
|
||||
| sv4 余额徽回归 | `open_status` 余额徽喂值零改动(回归锚) | 余额徽读数=keystone_balance〔sv4〕 同上(沿旧断言族) | 集成 | 同 sv1 | 撤销证明:改余额徽喂值 hunk → 本断言红 |
|
||||
| sv5 零旧段(隔离档) | `status_panel.gd` 两段整段退役(契约 2) | 面板子树零「道具工坊」「天赋树」文案〔sv5〕 同上 | 集成 | 同 sv1 | 变异:重加工坊段头(T1 变异步③)→ 本断言红 |
|
||||
| sv6 零旧段+投影值真链路(真实入口) | 同 sv5 面板改动+`_status_data()` 换代+`ui_click_probe.gd:593-621` 补三断言 | 角标开层后零旧段+属性行全值对 runner 五现值+`_status_data()` 直调八键与 curios/feats 对拍〔sv6〕 `ui_click_probe.gd`(T2 新增) | 探针 | `board_zone.status_badge` pressed 真实信号路径 | 变异:旧段回插→断言①红;curios 映射漏 `used` 键→断言③红;max_hp 错读 `ledger["hero_hp"]`→断言②红(T2 变异步) |
|
||||
| sv7 投影零旧键 | `_status_data()` 三旧键清零(契约 2 数据层面) | `_status_data()` 返回键集=八键〔sv7〕 `ui_click_probe.gd`(sv6 断言③承载,对局中直调) | 探针 | `main._status_data()` 直调(探针对局中,runner 在役) | 撤销证明:回退三旧键清零 hunk → 键集断言红 |
|
||||
| sv8 提示行文案 | `status_panel.gd:22` 文案换代(契约 4) | 提示行=「查看本局冒险进度(只读)」〔sv8〕 `smoke_all.gd` | 集成 | 同 sv1 | 撤销证明:回退文案 hunk → 本断言红 |
|
||||
| sv9 角标 tooltip×2 | `board_zone_view.gd:58`/`level_map_screen.gd:107` 文案换代 | tooltip=新串且全仓「永久强化进度」零命中〔sv9〕 件核(T1 可核查结果)+四探针定位锚回归 | 件核+探针 | 角标节点实查+全套闸 | 撤销证明:回退任一 tooltip hunk → 件核红 |
|
||||
| sv10 反哺点清单(**非行为改动**——纯文档产出物) | T2 三份 `reports/` 产出物(§6 六条各一落点) | §6 六条每条有落点〔sv10〕 件核对表(T2 出口) | 非行为改动 | 反哺点清单对 §6 同步面表件核 | 撤销证明:删一落点 → T2 出口件核红 |
|
||||
|
||||
**测试方式两分法(2026-10-11 用户定)**:V1–V6 全部机检自动化(冒烟+探针);能力验证可经调试接口直改钥石/GP/库存/专长后开面板读数(沿用现役 DebugOverlay/DS_DEBUG 门控)。**用户目检项**:面板观感一条(信息层级/文案通顺/空态句得体)——观测项写进 `reports/iter<N>-实现报告-<完成日>.md` 实机目检总清单,登记不阻塞(08 出口判据「用户目检通过」由此承接)。
|
||||
|
||||
**闸口径**:轻闸每任务卡出口自跑;批末重闸=`tools/run_all_gates.sh` 按改动域选档(本批只碰 `game/` → `--code`)全绿才合并+改前改后读数对拍。回归措辞:里程碑步(T 段)出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试先行孤立验证再并入全套。
|
||||
|
||||
**变异验证伴生**(新增/改写验收函数逐条注入实验,记录表进实现报告):`_status_panel_projection` 为改写函数——三注入已挂 sv1/sv2/sv5(gp 硬编码/尾缀删除/旧段回插);`ui_click_probe` 新增断言——三注入挂 sv6(旧段回插→断言①;main 侧 curios 映射漏 `used` 键→断言③;main 侧 max_hp 错读 `ledger["hero_hp"]`→断言②)。变异不红则改判据或如实标注拦截边界。V4/V5 为既有断言回归线,零新增零改写,不设注入实验。
|
||||
|
||||
### 8.3 测试削弱申报(test-conventions §9.5)
|
||||
|
||||
允许改/删的旧断言清单及理由:`smoke_all.gd:5744-5770` 工坊 12 行投影逐项断言族与 `:5771-5777` 天赋树聚合文案断言**删除**——理由=被断言内容(跨关解锁概览的呈现)随本批需求整段退役,非规避拦截;替换判据=sv5/sv6/sv7 零残留与真链路断言。`:5741-5743` 开层可见与余额徽断言**保留**(sv4 回归锚)。除此之外的断言删除/放宽/缩小扫描面/换下层直调=未申报削弱,停卡呈报、独立审计判红。`ui_struct_probe`/`ui_input_probe`/`shot_probe` 零断言改动。
|
||||
|
||||
**独立验收审计(test-conventions §9.7)**:合并前由未参与实现的迭代 loop 内子代理(或用户点名会话)审计——只读本卡、实现报告实际对照表、diff 与测试文件,自跑最窄测试抽查,不采信「已全绿」;审计报告落 `reports/iter<N>-验收审计-<完成日>.md`(逐行「通过/缺漏/例外及依据」)。**审计未通过不得合并**(T2 合并前置)。
|
||||
|
||||
## 9. 异常分级
|
||||
|
||||
- **L1(自救)**:断言措辞、命名、注释、空态句与段头微调(用户原话词干「带的秘宝/已获专长」不变前提下的语气词级调整)、属性行分隔符形态(契约 4 钉值格式内)。
|
||||
- **L2(记录继续)**:三 Label 的呈现细节(autowrap 形态、对齐);`_status_data()` 内部拼装形态(映射写法);冒烟夹具数值取值;探针断言的子树扫描写法选择。
|
||||
- **L3(停机呈报)**:`run_scope.runner` 空指针(契约 5 前置被打破=状态机缺陷);任何保留跨关概览半段的诉求;触碰 UiKit 工厂纪律(裸色值/自建样式);发现 F8 之外的第四处旧文案引用点(证据失真——订正本卡再续);顺带改动 C 区/营地承载/面板开合机制的诉求;`ui_struct_probe` ⑧ 回归线红(只读契约破)。
|
||||
|
||||
## 10. 代拍板白名单(超清单必呈报)
|
||||
|
||||
1. 空态句与段头最终措辞——约束:词干=用户原话,空态句形制沿 `status_panel.gd:130` 先例。
|
||||
2. 属性行串接序与分隔符——约束:契约 4 钉值格式逐字。
|
||||
3. 断言名与消息措辞、断言定位写法(子树扫描式 vs 逐 label 直引)。
|
||||
4. 冒烟夹具数值取值(任意非零可辨值——禁读 `data/tables` 现值,禁与属性行断言共值致误判掩盖)。
|
||||
5. 提交切分与 worktree 分支命名。
|
||||
|
||||
## 11. 待裁点
|
||||
|
||||
**零待裁点,开工门=U0。**
|
||||
|
||||
四处灰色地带已按设计事实推导定值(用户可否决,随 T2 反哺点清单逐条列示呈报):
|
||||
- **空态呈现=显示空态句而非隐藏段**——依据=本面板是「主动打开的可读快照」(玩家按需展开阅读,明确「无」比整段消失更可读)+现行空态句先例(`status_panel.gd:130` 天赋树空态句);备选「空态隐藏段」淘汰依据=那是 HUD C 区常驻悬浮件的先例(空间稀缺语义),与按需面板不同形。
|
||||
- **提示行/tooltip 文案=「查看本局冒险进度(只读)」**——依据=新定位(本局信息为主+钥石);备选「查看本局状态(只读)」淘汰依据=与标题「状态」连读冗余。
|
||||
- **GP 并入「本局状态」行而非独立段**——依据=五件呈现的最小结构(GP 是一个读数,不构成段落级信息);备选独立「资产」段淘汰依据=单行段无信息增益、徒增段头。
|
||||
- **「带的秘宝」段含已用件(带「(已用)」尾缀)而非只列未用件**——依据=秘宝投影复用 `inventory_projection()` 全行集(C 区同源、零第二实现,契约 1);已用件仍在库存里「带着」,尾缀保真不撒谎;备选「过滤只列未用件」淘汰依据=须另加过滤语义(第二份行集语义),且已用件消失会让件数对不上库存。
|
||||
|
||||
## 12. 自审六查与 grilling 复核记录
|
||||
|
||||
**自审六查(2026-10-23 写卡会话)**:①规格覆盖——§1 四项改动/五项完成定义逐条挂 T 卡(投影=T1、面板=T1、tooltip=T1、断言面=T1/T2、产出物=T2),并各指到对照表行(sv1–sv10),无漏项;②步骤扫描——全部步骤一步一动作一可核查结果,函数体零给出(签名+断言已定);③类型一致性——接口块八键名与 T1/冒烟/探针引用逐字一致(balance/hero_hp/max_hp/atk/ac/gp/curios/feats);④审查焦点+改动覆盖——规格暗示的失败模式补挂:只读契约破(V4 回归线+L3)、停点开面板秘宝投影崩(F5 已核+V5 回归)、文案锚破导致探针失明(V3 定位锚不变判据);文件结构图六个行为改动行全部指到对照表行;⑤篇幅比例——规格≈1 屏、任务卡≈实现面 1:1,零函数体、零代码块;⑥落位与复用——零新增文件/数据件,三个新 Label 成员与两处投影复用的「为什么不能复用既有那一个/落点唯一」已在预检节答清,与文件结构图互指一致。
|
||||
|
||||
**grilling 复核记录(2026-10-23,独立子代理对抗复核,不采访用户——可推导定值写依据、真归用户列 §11)**:十审点走查——事实面(F1–F8 行号、§6 四条文档引句、旧段/旧键/旧成员消费点全集、削弱申报、机检 C1/C2)逐条实核全部成立;对照表三方闭合、落位预检互指、待裁点无泄漏均过。判回炉一处:**【阻断】`main._status_data()` 八键投影值层无验收闭合**——v1.0 的 sv1–sv3 全部直喂夹具消费侧、sv7 只断键集、sv6 断言②单盖 GP 且开局零值无判别力,投影映射写坏可全绿合入,违验收闭合红线。随同改:【应修】§11 推导定值的呈报承诺无落点(T2 反哺点产出物补「逐条列示」)、sv6 断言②无变异证明。v1.1 修订内容:①sv6 升格三断言(零旧段+属性行全值对 runner 五现值+`_status_data()` 直调八键与 curios/feats 对拍独立 oracle)——投影值层进真链路断言回路;②sv7 落点自冒烟移探针(直调 `_status_data()` 需 runner 在役,冒烟免 boot 对局);③变异表补 main 侧注入两条(curios 漏 `used` 键→断言③红、max_hp 错读 hero_hp→断言②红);④§11 增第四处推导定值(带的秘宝含已用件);⑤吹毛求疵随手带改——契约 1 加「属性与 GP 合一行」半句与 ledger 直取下标、契约 2 限定「status_panel.gd 内」并明示 camp_overlay_view 同名件零关联、F2/F3/F4/F5 行号订正(±3 行内漂移)、T1 补 HSeparator 保留句、§8.3 保留区间措辞订正。复核结论:修订后零阻断零应修,零待裁点成立。
|
||||
@@ -1,246 +0,0 @@
|
||||
# 需求卡片:选档界面新建批(3 存档位 · 新档/进档/删档)· 营地交互重做卡③
|
||||
|
||||
- 版本:**v1.3**(现行身份:零待裁点+含 §7.1 改动—验收对照表〔按 test-conventions §9.3 六列与 §9.8 旧卡开工前补表口径〕+§7.2 测试削弱申报。裁定记录:Q1 甲〔每轮回选档;本项无推荐案,取默认甲代拍板留痕、追认单可 veto〕、Q2 甲〔坏槽按空槽,推荐案〕、Q3 乙〔进档暂行接现役 CampOverlay,卡④回设计段迫使〕;契约 3 的本批形态按 §9 第 6 条钉在双钮+消费方编排上;用户面裁决照录澄清文档不变)
|
||||
- 来源:[需求澄清-营地交互重做-2026-10-18.md](需求澄清-营地交互重做-2026-10-18.md)(唯一事实源:④结构树「选档界面(完全没有 · 新建):3 存档位,新档/进档/删档」、⑤裁决 2/3/4、⑦切批原则③)
|
||||
- 归属:呈现层/组合根(`game/presentation/`)——营地交互重做五卡之三
|
||||
- 排期:未编入(2026-10-18 用户令:需求卡片不预占迭代号,批次归属按工作量另裁)
|
||||
- 开工门:U0(用户 `/iter` 发令)+ 待裁点已裁(Q1/Q2/Q3 均裁定,见 §10)+ grilling 复核门过
|
||||
|
||||
## 0. 前置依赖与并行性
|
||||
|
||||
- 前置卡①(存档制数据层改造批):三槽承载、新档/进档/删档原语、摘要三项窥视读器——本卡只做界面与接线,不碰数据层实现。
|
||||
- 后接卡④(营地场景图):进档/新档的落点。**卡④已于 2026-10-21 用户令退回美术设计段**(美术轨凭据缺 P1–P5 未销号,现卡 v2.3 非有效卡——见卡④ 卡头回退声明),故 Q3 裁定乙:本卡随①②③工程批先行时,进档/新档**暂行接现役 CampOverlay**(现役在役面,复用合法,非「发明占位」),卡④设计定稿重新立卡后改挂场景图(卡④ T3 承载)。
|
||||
- 卡②(主菜单三入口化)的「进入存档」钮以本卡为落点,两卡硬耦合(卡② 契约 5:同批或卡③在先)。
|
||||
- 卡⑤(ESC 浮窗)在本卡语境不响应(卡⑤ 契约 2:ESC 范围=营地语境)——选档语境的键盘行为零裁定、零实现。
|
||||
|
||||
## 1. 目标与完成定义
|
||||
|
||||
**目标(澄清④照录)**:新建选档界面——3 存档位,新档/进档/删档。裁决 2「多存档制,3 个存档位」;裁决 3「删档:要,且必须二次确认」;裁决 4「档槽摘要=钥石余额、通关次数、冒险次数(总局数)三项,不含未完冒险进度」。
|
||||
|
||||
**相对现状,新增了什么**:选档界面整体(澄清④判定「完全没有 · 新建」)——三槽呈现+摘要三项+空/有档操作集+删档二次确认链+进档激活接线。
|
||||
|
||||
**完成定义**:
|
||||
1. 选档界面经「进入存档」钮可达,呈现 3 个存档位;
|
||||
2. 每槽摘要=钥石余额/通关次数/冒险总局数三项;空槽=合法零值态;坏槽/高版本槽按 Q2 裁定呈现;**摘要面无未完冒险进度**(裁决 4);
|
||||
3. 空槽可新档(创建=激活=**暂行接现役 CampOverlay**——卡④回设计段,Q3 裁定乙);有档槽可进档(激活该档=暂行接现役 CampOverlay);
|
||||
4. 删档必经二次确认(裁决 3):第一次点击只出确认窗,确认才删、取消不删;删后该槽回空态;
|
||||
5. 新屏/新层入 `LAYER_CONTRACT`(层序纪律),冒烟合同断言绿;
|
||||
6. 批末重闸按改动域选档全绿;三份 `reports/` 产出物写齐(T4)。
|
||||
|
||||
## 2. 现状事实(2026-10-18 实查;开工日 T0 复核行号)
|
||||
|
||||
| # | 事实 | 出处 |
|
||||
|---|---|---|
|
||||
| F1 | 选档界面完全不存在(澄清④判定);现主菜单直接进营地/生涯/冒险,无存档语境选择面 | `需求澄清-营地交互重做-2026-10-18.md` §④ |
|
||||
| F2 | 通用确认弹窗在役:`ConfirmDialog.open(text, confirm_label, cancel_label)` 双钮外发 `confirmed/cancelled`(**信号零 payload、无调用方标识**),零业务触碰;现役唯一生产消费=组合根静态常驻接线;打开走 `confirm_dialog.open()` **直开,不经 `_open_modal`**(全仓唯一绕栈模态) | `game/presentation/views/confirm_dialog.gd:36-38`/:7-8/:55-60;`main.gd:347-348`/:480 |
|
||||
| F3 | 全屏页壳先例在役:`UiKit.page_shell`(暖亮底+石纹+暗角+56px 通栏顶条+内容列),生涯页即此形制(直开直关零动效;页壳自带「返回」钮) | `game/presentation/views/career_overlay.gd:18-31`/:62-72 |
|
||||
| F4 | 钥石徽工厂件在役:`UiKit.keystone_badge`(状态面板/生涯页/营地三处消费先例;迭代 17 卡③ Q10 甲工厂化) | `career_overlay.gd:54`;`camp_overlay_view.gd:82`;`status_panel` 同族 |
|
||||
| F5 | 层序唯一事实源=`main.gd` `LAYER_CONTRACT`(16 层+float 类),`_apply_layer_contract` 为全仓唯一落位口;冒烟 V1d 源码断言判红散落 `move_child` | `main.gd:34-53`/:430-455;`smoke_all.gd:146-154` |
|
||||
| F6 | 模态栈单口在役:`_open_modal`/`_close_modal`(登记层开合一律走栈;T3 收口批纪律) | `main.gd:458-462` |
|
||||
| F7 | 摘要三项读源:现役访问器(`keystone_balance`/`adventure_total`/`adventure_cleared`;卡① 合并后 :385/:429/:435〔T0 订正 2026-10-22,成文时 :214/258/264〕)+**按槽窥视读器=卡① 已交付**(`peek_slot_summary` :164,含 `has_file` 位——T0 对齐补充);「通关次数」口径=**通关局数 `adventure_cleared`**(同生涯页行,卡① F4 已锁——禁与「各关通关次数 clear_count」混义) | `save_manager.gd:385`/:429/:435/:164;卡① §6 T2 |
|
||||
| F8 | UI 公共件纪律先例(迭代 17 卡③):「复用现行公共件与色板,零新素材零新色值」——本卡同类批,照此执行 | `roadmap.md` 迭代 17 ③行 |
|
||||
|
||||
**T0 对齐结论(2026-10-21,卡① 实测交付形态,消契约 9 落空项)**:窥视读器=`peek_slot_summary(slot: int) -> Dictionary`(另有路径注入口 `peek_summary_at(path)` 供探针隔离,契约 7 同款);返回结构=`{"readable": bool, "keystone": int, "cleared": int, "total": int}`;返回结构另含 `has_file: bool`(主文件在盘与否——T0 对齐补充 2026-10-22:空/有档操作集二分判定来处,非摘要第四项、零 UI 语义);空槽(主文件不在盘,含仅 .tmp 残留)=`readable=true`+`has_file=false`+三项零值;不可读态(损坏/高版本/缺版本字段/越界槽号)=`readable=false`(Q2 裁甲:UI 一律按空槽呈现,禁自设第三态)。激活与档操作 API:`active_slot() -> int`(0=无激活态)、`create_slot(slot)`/`activate_slot(slot) -> bool`(失败自动恢复切换前三态)/`delete_slot(slot) -> bool`;位数常量=`SaveManagerCore.SLOT_COUNT=3`;槽路径唯一派生口=`slot_path(slot)`,视图/组合根禁自拼槽文件名;测试夹具隔离走 `attach_slot_template(template)` 注入口。
|
||||
|
||||
## 3. 设计契约(红线,违反 = L3 停机呈报)
|
||||
|
||||
🔴 **契约 1 · 三存档位且仅三位**:界面呈现 3 槽(裁决 2);禁参数化槽位列表、禁滚动长列表形态。
|
||||
|
||||
🔴 **契约 2 · 摘要三项且仅三项**:钥石余额/通关次数(=通关局数 `adventure_cleared`)/冒险总局数(裁决 4)。**禁显示有无未完冒险**(用户原话「不需要显示有无未完成的冒险;只要我提到的那三个就够了」)——断点相关读数(关数/种子/停点)零露出。
|
||||
|
||||
🔴 **契约 3 · 删档必经二次确认+ConfirmDialog 消费方编排机制**:第一次点击只出确认窗(复用 ConfirmDialog 类),确认才删、取消不删;禁长按删、禁一次点击即删、禁撤销式软删。**本批内该类的形态钉在现役双钮签名**(`confirm_dialog.gd:36-38` `open(text, confirm_label, cancel_label)`,信号零 payload 单实例)——三钮形态与第三钮语义属卡④(v2.3 非有效卡,Q5 裁定甲的落点在那张卡重立卡后的批),本批禁预支类签名变更。**编排机制取 §9 第 6 条代拍板**:组合根按「open 前设消费方状态量、confirmed/cancelled 后按该状态量分派」实现,**禁双常驻静态接线**(现役 `main.gd:347` 形态禁复制——双线必致删档确认误触发开局)。本批该类的消费方=卡③删档确认一处(现役新冒险确认入口随卡②撤出),但分派面禁写死单一目标,须让卡④到位后直接接入第三消费方而不返工。
|
||||
|
||||
🔴 **契约 4 · 空/有档操作集二分**:空槽只有「新档」;有档槽有「进档」+「删档」(澄清④语义)。**禁给空槽配删档**(含置灰残留——置灰=配删档);「想在这个位开新局」的玩家路径=先删档(二次确认)→槽回空→新档,两步即达,卡内记载备查(实现期禁自发加「覆盖」钮——覆盖式新档用户未裁);坏槽/高版本槽的操作集=Q2 裁定,不属本二分。
|
||||
|
||||
🔴 **契约 5 · 选档面零存档内功能**:选档界面只做存档语境选择——禁从此面进营地/冒险/生涯(结构树层级:选档 → 进档 → 营地);禁在选档面放任何购买/查看入口。
|
||||
|
||||
🔴 **契约 6 · 层序与模态纪律**:新层入 `LAYER_CONTRACT`(改层序只改合同表);开合走模态栈单口。**豁免(v1.1 补)**:ConfirmDialog 沿用现役直开先例(main.gd:480——登记在册:输入锁与树序顶位已由 LAYER_CONTRACT 表达),不强制改走 `_open_modal`。
|
||||
|
||||
🔴 **契约 7 · 公共件复用**:UiKit 工厂件+现行色板,零新素材零新色值(迭代 17 卡③ 先例同款);场景图归卡④,本卡不碰美术产出。
|
||||
|
||||
🔴 **契约 8 · 进档即激活**:进档/新档动作=卡①激活位设置+落点卡④营地;激活态是否持久化以 Q1 裁定为准(裁乙才需,裁甲无「当前档选择」可持久——v1.1 条件化,原「拔电源不丢当前档选择」父注删除);写盘时机由卡①在 T0 对齐时定义。
|
||||
|
||||
## 4. 范围边界
|
||||
|
||||
**做**:选档界面视图(三槽卡+摘要+操作钮+空/有档/坏槽态);组合根接线(进入存档→选档;新档/进档→激活+营地;删档→确认→卡①删除原语→刷新);层序登记;断言批;反哺点清单。
|
||||
|
||||
**不做**(明示去向):
|
||||
- 三槽承载/删档原语/摘要读器实现 → 卡①;
|
||||
- 「进入存档」钮与主菜单砍钮 → 卡②;
|
||||
- 营地场景图(进档落点) → 卡④;
|
||||
- 档位自定义命名/备注/排序 → 用户未裁,批内禁加(澄清④只给三槽+三项摘要);
|
||||
- 存档导入/导出/云同步 → 不在澄清范围,禁自扩。
|
||||
|
||||
## 5. 关联文档同步面
|
||||
|
||||
> **v1.3 口径**:本批禁写 `design/` 整目录与根规则文件,唯一可写目录 = `reports/`;下表一律执行为列进反哺点清单。08 写入权限统一口径:**状态列可改;注记改写列反哺点随清单呈报;增删行须用户裁**。
|
||||
|
||||
| 文档 | 关联点 | 同步义务 |
|
||||
|---|---|---|
|
||||
| `待办清单.md`(仓库根,流水线唯一登记处) | 本卡登记条;存档序列化 P2 多档条(卡①反哺)与本条的交叉注记 | 反哺点 · 列清单 |
|
||||
| `design/gdd/systems/跨局循环/生涯.md` | :11-23 信息架构结构树——新增「进入存档→选档界面」一级层级(生涯入口随卡④改挂笔记本) | 反哺点 · 结构树补层 |
|
||||
| `design/gdd/08-Alpha版本标准.md` | 「三 · 界面」表新增「选档界面」行(在役)——增行须用户裁(08 头注纪律) | 反哺点 · 增行请求随清单呈报 |
|
||||
| `roadmap.md` | 迭代行编入/状态刷新 | 反哺点 · 列清单 |
|
||||
| `game/presentation/views/*`(新建选档视图)、`main.gd`、`game/smoke/*` | 实现与断言本体 | 实施本体(可写) |
|
||||
|
||||
## 6. 任务卡
|
||||
|
||||
> 估时按 Claude 工作日口径;每卡出口自跑轻闸;开工日 T0 复核全部行号。
|
||||
|
||||
### 6.0 落位与可复用性预检(req-card 必备结构第 12 项,定义 T 卡前置)
|
||||
|
||||
本卡只有一个新增文件与一个新增开层函数,其余全部复用。盘上形制先例=生涯页 `CareerOverlay`(`game/presentation/views/career_overlay.gd` 全屏页壳+`open_career(data: Dictionary)` 收数据+`_emit_closed` 关闭;组合根四处登记面见 `main.gd:47` 层序合同行、`:116` 字段、`:288-290` 构造与接线、`:419` 层查找表、`:1092-1095` 开层函数)。
|
||||
|
||||
| 新增件 | 复用面(既有实现) | 为什么不能整件复用 | 唯一落点 | 分层与跨层出口 |
|
||||
|---|---|---|---|---|
|
||||
| 新文件 `game/presentation/views/save_select_overlay.gd`(`SaveSelectOverlay`) | 页壳工厂 `UiKit.page_shell`(`career_overlay.gd:18-31` 同款先例)、紧凑返回钮先例(`:26-31`)、关闭链 `signal closed`+`_emit_closed`(`:75-79`) | 生涯页是只读跨局汇总、零存档操作集——**复用它的页壳形制与工厂件,不复用它本体**(澄清④判选档面「完全没有·新建」) | 视图文件只落 `views/` 一处,禁把槽卡构建 helper 散进 `ui_assembler.gd` 或 `main.gd` | 视图零数据层依赖:槽摘要由组合根取好传入(照 `open_career(_career_data())` 先例),视图内禁出现 `load()`/`DirAccess`/存档路径 |
|
||||
| 三槽卡与槽态判定 | 钥石徽工厂件 `UiKit.keystone_badge`(F4 三处消费先例) | 现无「按槽」呈现件 | 槽数量与槽态(空/有档/坏槽)唯一来处=卡① 窥视 API 返回值,视图禁自己数文件、禁硬编码三槽判定 | 呈现层→Core 只经卡① 类型化访问器(卡① 契约 6) |
|
||||
| 开层函数(组合根) | 模态栈单口 `_open_modal`/`_close_modal`(`main.gd:458-462`)+`LAYER_CONTRACT` 登记(`:34-53`)+开始层互斥仿设置面先例 | 现无选档层可复用 | 新层只在 `LAYER_CONTRACT` 加一行(改层序只改合同表,散写 `move_child` 由冒烟 V1d 判红) | 开合走栈单口;ConfirmDialog 按契约 6 豁免沿用直开先例 |
|
||||
| 删档确认弹窗 | 复用 `ConfirmDialog` 类(F2)+现役直开先例(`main.gd:480`) | 类本体够用,缺的是多消费方分派 | 消费方状态量唯一落点在组合根,禁在视图与弹窗各存一份 | 弹窗类零业务触碰(现役纪律),禁反向依赖玩法 |
|
||||
| 探针与夹具 | 既有 `ui_struct_probe`/`ui_click_probe`/`screen_flow_probe` 各加段;隔离存档夹具 `probe_ui_util.gd:98-121 isolate_save` | 三槽异值夹具经卡① 槽位 API 直写(能力验证口径),禁在视图侧开调试口 | 同一入口的可达性断言只在一处,禁新建同职责探针文件 | 测试执行两入口铁规 |
|
||||
|
||||
零新增清单(契约 7 同源):不新增素材、不新增色值、不新增弹窗类、不新增存档路径派生、不新增槽位数量常量(位数唯一在卡① 承载面)。
|
||||
|
||||
### T0 事实坐实与接口对齐(≈0.5–1d)
|
||||
|
||||
- 复核 §2 行号;与卡①对齐窥视读器签名/命名/返回结构/空槽与坏槽表示法(卡① 契约 9 三态——对齐结论写成文附 §2,消 L3 落空项);
|
||||
- 与卡②对齐「进入存档」钮句柄;进档/新档落点=现役 CampOverlay 的开层函数(Q3 乙),其签名与本卡激活调用在 T0 与卡①的激活 API 对齐;ConfirmDialog 消费方编排机制按契约 3+§9 第 6 条实现,卡④重立卡后按同一机制接入第三消费方(本批禁与卡④对接签名——卡④ v2.3 非有效卡)。
|
||||
- 清点既有 confirm_dialog 断言面(ui_struct_probe.gd:71 结构采样、smoke_all.gd:226 最顶层候选、ui_click_probe:508-527、ui_tune_probe.gd:52 树序断言)——机制或实例数若变,这些点受影响;
|
||||
- Q1 重启初始态与 Q2 坏档第三态裁定执行。
|
||||
|
||||
### T1 选档界面视图(≈1.5–2d)
|
||||
|
||||
- 全屏页壳(`UiKit.page_shell` 先例):标题+三槽卡横列+**页壳返回钮(生涯先例)→ `_close_modal`+开始层恢复**(v1.1 补——原只写「标题+三槽卡」漏了可退路径);
|
||||
- 槽卡内容:槽位编号+摘要三项(钥石余额/通关局数/冒险总局数)+操作钮;空槽=「空存档位·新档」态;有档槽=摘要+「进档」+「删档」;坏槽/高版本槽按 Q2 裁定态;
|
||||
- 钥石徽用工厂件;零新素材零新色值(契约 7);
|
||||
- 删除钮形态:危险钮先例;**空槽禁渲染删档钮、禁置灰残留**(v1.1 订正原「禁用态纪律」——与契约 4 字面冲突);
|
||||
- Q1 裁乙时补「预选」高亮态(选中槽卡视觉态——v1.1 补,原 T1 未含)。
|
||||
|
||||
### T2 组合根接线(≈1d)
|
||||
|
||||
- 「进入存档」→开选档界面(模态栈单口;与开始层互斥仿设置面先例);
|
||||
- 新档:卡①空槽创建→激活→**暂行接现役 CampOverlay 开层**(Q3 裁定乙;卡④重新立卡后改挂场景图);
|
||||
- 进档:卡①激活→**暂行接现役 CampOverlay 开层**(同上);
|
||||
- 删档:ConfirmDialog 消费方编排(契约 3:open 前设消费方=删档、confirmed 后删、cancelled 后只关窗)→卡①删除原语→选档界面就地刷新(该槽回空态);
|
||||
- 开层时摘要三读器按槽窥视(不激活不写盘);
|
||||
- **动线序(v1.1 补)**:进档/新档时「先落点开层/开始层保持隐藏,再关选档」——禁先关后开(`_close_modal` 会恢复被遮挡的开始层=回闪一帧);营地开层后选档层被模态栈遮挡隐藏、不关闭(卡④ T3 同口径)。
|
||||
|
||||
### T3 断言批(≈1–1.5d)
|
||||
|
||||
- 探针:三槽呈现+摘要三项读数(**夹具按槽直写**——经卡①槽位 API/隔离面实现同会话三槽异值注入,v1.1 补任务落点);空/有档操作集断言(空槽零删档钮/有档槽零新档钮);坏槽按 Q2 态断言;删档确认链(第一次点击只开窗、取消后文件仍在、确认后槽回空);
|
||||
- 冒烟:层序登记(`LAYER_CONTRACT` 合同断言);选档面零存档内功能入口(结构禁词断言);选档面返回钮开合(screen_flow_probe 型);
|
||||
- **变异验证伴生**:删档钮直连删除(预期确认链断言红)、摘要读激活位(预期跨槽摘要红)、空槽渲染删档钮(预期操作集断言红)、**ConfirmDialog 双常驻接线**(注入后预期「删档确认误触发开局」断言红——新契约伴生,v1.1 补);注入→最窄闸见红→精确还原→记录。
|
||||
|
||||
### T4 产出物落位卡(≈0.5d,末卡)
|
||||
|
||||
三份 `reports/` 写齐(实现报告含**实际改动—验收对照表**〔§7.1 需求侧表的执行对账,另加「结果」格〕、变异记录表、「已知中间态」节〔Q3 乙的暂行接线与卡④改挂的二次验证面〕/代拍板追认单〔含 §9 第 6 条编排机制留痕〕/反哺点清单)。**合并前置**:独立验收审计(§7.1 末段声明)完成且 `reports/iter33-验收审计-<完成日>.md` 逐行「通过」;§7.2 申报外的削弱由审计判红,未过不得合并。
|
||||
|
||||
**估时合计 ≈4.5–5.5d**(v1.1 上调:ConfirmDialog 机制+坏槽态+返回路径+夹具注入增量)。切分预案:T1/T2 后可切(视图先落、接线后落)——切分价值低,建议与卡②同批单跑。
|
||||
|
||||
## 7. 验证闸(逐需求点验收清单)
|
||||
|
||||
| # | 需求点 | 测什么 | 落点/判定手段 |
|
||||
|---|---|---|---|
|
||||
| V1 | 三槽呈现 | 3 槽卡在位且编号稳定;无滚动长列表 | ui_struct_probe 结构断言 |
|
||||
| V2 | 摘要三项 | 钥石余额/通关局数/冒险总局数逐槽读数正确(夹具按槽直写三槽不同值);空槽零值;坏槽按 Q2 态 | ui_probe 型探针段(夹具经卡①槽位 API 直写,能力验证口径) |
|
||||
| V3 | 摘要禁项 | 摘要区无断点/未完冒险相关读数(关数/种子/「继续」字样零命中) | 探针禁词断言 |
|
||||
| V4 | 操作集二分 | 空槽零删档钮(含置灰);有档槽零新档钮 | 探针结构断言 |
|
||||
| V5 | 空槽新档 | 空槽点新档→创建+激活+落点营地 | ui_click_probe 合成点击路径 |
|
||||
| V6 | 有档槽进档 | 点进档→激活该槽(摘要=该槽值)→落点营地 | 同上 |
|
||||
| V7 | 删档二次确认 | 一击只开确认窗;取消=文件仍在;确认=删+槽回空 | ui_click_probe 双路径段 |
|
||||
| V8 | Q1 重启初始态 | 甲=重启回主菜单不预选;乙=预选/直入均可机检 | 探针重启链段(按 Q1 裁定案) |
|
||||
| V9 | 返回路径 | 页壳返回钮→选档隐藏+开始层恢复;选档语境 ESC 不响应 | screen_flow_probe 型断言 |
|
||||
| V10 | 层序纪律 | 新层入 LAYER_CONTRACT;登记序=树序=z 序 | 冒烟 V1d 合同断言 |
|
||||
| V11 | 反哺点清单 | §5 每条有落点 | 件核对表 |
|
||||
|
||||
**测试方式两分法**:V1–V10 机检自动化(能力验证经夹具直写槽位/钥石/计数状态——经卡①槽位 API 或隔离存档实例,不走正常资源积累流程);**用户目检项=三槽观感与删档确认文案**——登记 07(生命周期末步统一目检,不阻塞迭代,澄清⑥口径)。
|
||||
|
||||
**闸口径**:轻闸每卡出口自跑;批末重闸按改动域选档(本批碰 `game/` 代码与断言面 → `--code`)全绿才合并;MC 零跑。
|
||||
|
||||
### 7.1 改动—验收对照表(test-conventions §9.3 六列;§7 的 V 号在各需求点格内括注)
|
||||
|
||||
> 断言尾缀族=〔sl#〕,实现期逐条 grep 定位。落点文件为计划落点,实现期在 `reports/iter33-实现报告-<完成日>.md` 的实际对照表里按真实行号对账(§9.3 双端对上)。本卡全部取数只走卡① 交付的按槽 API,夹具按槽直写=能力验证口径(§7 两分法)。
|
||||
|
||||
| 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 撤销或变异证明 |
|
||||
|---|---|---|---|---|---|
|
||||
| sl1 三槽呈现(契约1、V1、T1) | 新建 `game/presentation/views/save_select_overlay.gd`(`SaveSelectOverlay._init` 按 `career_overlay.gd:18-31` 页壳先例)渲染三槽卡 | `ui_struct_probe` 新段〔sl1〕槽卡计数=3+零滚动容器 | 探针 | 点「进入存档」开层后的真实子树 | 变异=槽列表参数化成四槽或套 ScrollContainer → 计数与禁滚动断言红 |
|
||||
| sl2 摘要三项逐槽读数(契约2、V2、T1/T2) | 槽卡内容读卡① 按槽窥视 API(三值+零值空槽) | 探针段〔sl2〕夹具按槽直写三槽异值后逐槽断言 | 探针 | 开层后各槽卡 label 实取值 | 变异=摘要改读激活槽代替窥视槽 → 异值夹具下断言红 |
|
||||
| sl3 摘要禁项(契约2、V3、T1) | 槽卡只消费三项键,零断点字段(关数/种子/停点不进视图) | 探针禁词断言〔sl3〕 | 探针 | 选档层真实 label 文本全集枚举 | 变异=把断点关数拼进槽卡副标题 → 禁词断言红 |
|
||||
| sl4 空/有档操作集二分(契约4、V4、T1) | 槽卡按槽态分支渲染钮集;空槽禁渲染删档钮(含置灰形态) | 结构断言〔sl4〕空槽零删档钮+有档槽零新档钮 | 探针 | 真实开层子树的钮枚举 | 变异=空槽渲染删档钮(哪怕 `visible=false`)→ 操作集断言红 |
|
||||
| sl5 空槽新档链(完成定义3、V5、T2) | 组合根新档回调:卡① 空槽创建→激活→暂行开现役 CampOverlay(Q3 乙) | `ui_click_probe` 合成点击段〔sl5〕 | 集成 | 真实点击空槽「新档」钮 | 撤销=去掉激活调用 → 激活槽位断言红 |
|
||||
| sl6 有档槽进档链(契约8、V6、T2) | 组合根进档回调:卡① 激活→暂行开现役 CampOverlay | `ui_click_probe` 段〔sl6〕 | 集成 | 真实点击有档槽「进档」钮 | 变异=进档读成当前激活槽 → 该槽摘要与激活位断言红 |
|
||||
| sl7 删档二次确认链(契约3、V7、T2) | 删档回调经 ConfirmDialog 编排:`main.gd:480` 直开先例+消费方状态量,confirmed 才调卡① 删除原语,cancelled 只关窗 | `ui_click_probe` 双路径段〔sl7〕(一击只开窗/取消后文件仍在/确认后删+槽回空) | 集成 | 真实点删档钮 → 确认窗 → 确认与取消两支 | 变异=删档钮直连删除原语 → 确认链断言红(T3 变异①) |
|
||||
| sl8 消费方编排机制(契约3、V7、T2、§9 第6条) | `main.gd:347-348`/`:480` 静态常驻接线改为「open 前设消费方状态量、confirmed/cancelled 后按该量分派」,弹窗类签名不动 | 结构断言〔sl8〕单口分派+变异注入双常驻接线 | 集成 | 三个开窗路径共用同一弹窗实例(本批两个:删档确认与现役新冒险确认随卡②撤出) | 变异=保留双常驻静态接线 → 「删档确认误触发开局」断言红(T3 变异④) |
|
||||
| sl9 重启不预选(Q1 甲、V8、T1/T2) | 视图与组合根零激活位持久化(卡① §9 第 2 条随 Q1 甲作废),boot 后三槽均未选 | 探针重启链段〔sl9〕 | 集成 | 重启后走「进入存档」开层 | 变异=加一条持久化预选指针 → 不预选断言红 |
|
||||
| sl10 返回路径与 ESC 语境(V9、T1/T2) | 页壳返回钮 → `_close_modal`+开始层恢复(`career_overlay.gd:75-79` 先例);选档语境 ESC 不响应(卡⑤ 契约 2 范围外,零实现) | `screen_flow_probe` 型段〔sl10〕 | 探针 | 真实点击返回钮+选档态按 ESC 键 | 变异=返回钮改成 `queue_free` 不恢复开始层 → 恢复断言红;给 ESC 加处理 → 不响应断言红 |
|
||||
| sl11 层序与模态纪律(契约6、V10、T1/T2) | 新层入 `main.gd:34-53` `LAYER_CONTRACT`(仿 `:47` career 行)+开合走 `:458-462` 模态栈单口 | 冒烟 V1d 合同断言〔sl11〕+`ui_tune_probe.gd:52` 树序断言复跑 | 冒烟 | `smoke_all.gd:146-154` 源码合同段 | 变异=在视图内散落 `move_child` → 散落判红 |
|
||||
| sl12 动线序不回闪(T2) | 进档/新档时先落点开层(开始层保持隐藏)再关选档 | 探针段〔sl12〕逐帧可见性次序(选档隐藏时营地层已可见) | 探针 | 真实点击进档钮后的可见性采样 | 变异=改成先关后开 → 开始层恢复一帧断言红 |
|
||||
| sl13 公共件复用零新素材零新色值(契约7、V1)——非行为改动 | 只用 `UiKit.page_shell`/`UiKit.keystone_badge`/现行色板;不新增素材与色值 | 静态扫描+结构断言〔sl13〕零新 `Color(` 字面量与素材路径 | 件核 | 本批 diff 文件枚举 | 判断依据=不改行为;变异=引入新色值 → 静态扫描红 |
|
||||
| sl14 反哺点清单(V11)——非行为改动 | §5 所列(待办清单、生涯.md 结构树、08 增行请求、roadmap)列点不落文 | 件核对表〔sl14〕落 `reports/iter33-反哺点-<完成日>.md` | 件核 | 收口前逐条指认落点 | 判断依据=产出物件核不产码;08 增行须用户裁,本批禁直改 |
|
||||
|
||||
### 7.2 测试削弱申报(test-conventions §9.5)
|
||||
|
||||
本卡接线会让 ConfirmDialog 的开窗形态变化,下列四点为**已申报**的可改写位点(改写须按新形态收紧,禁放宽):`ui_struct_probe.gd:71` 结构采样、`smoke_all.gd:226` 最顶层候选、`ui_click_probe.gd:508-527` 确认弹窗交互段、`ui_tune_probe.gd:52` 树序断言。改写条件=实例数或分派口变化时同步更新判据;不许把判据放宽成「任意弹窗在顶」。其余既有断言本卡不许动,实现期未申报的删除断言、放宽阈值、缩小扫描面、换下层直调由独立验收审计判红。
|
||||
|
||||
**独立验收审计(test-conventions §9.7)**:合并前由未参与实现的迭代 loop 内子代理(或用户点名会话)审计——只读本卡、实现报告实际对照表、diff 与测试文件,自跑最窄测试抽查,不采信「已全绿」;审计报告落 `reports/iter33-验收审计-<完成日>.md`,逐行写「通过/缺漏/例外及依据」。**审计未通过不得合并**(T4 合并前置)。
|
||||
|
||||
## 8. 异常分级
|
||||
|
||||
- **L1(自救)**:断言写法、槽卡布局微调、命名。
|
||||
- **L2(记录继续)**:槽卡横列/纵列布局取舍(契约 1 内)、确认文案措辞、空态呈现细节。
|
||||
- **L3(停机呈报)**:进档落点在卡④重新立卡前被要求改挂场景图(Q3 裁定乙=暂行现役 CampOverlay,提前改挂=越批);卡① 交付签名与 T0 对齐结论不符(v1.1 订正原「与本节假设不符」——本节无签名假设);删档确认链被要求简化(触裁决 3);ConfirmDialog 编排机制在本批内出现两个分派目标互相冲突(冲突时停机呈报,禁为实现方便退回双常驻静态接线)。
|
||||
|
||||
## 9. 代拍板白名单(超清单必呈报)
|
||||
|
||||
1. 槽卡布局(横列三卡 vs 纵列三行)与尺寸档取值(UiKit 现行件域内)。
|
||||
2. 槽位编号呈现(「存档位 1/2/3」vs 其他措辞)。
|
||||
3. 新档/进档/删档三钮的文案与动词化命名(对齐现役动词钮先例)。
|
||||
4. 选档界面与开始层的互斥方式(仿设置面先例内的参数选择)。
|
||||
5. 提交切分与 worktree 分支命名。
|
||||
6. ConfirmDialog 消费方编排机制的取法:**取「open 前设消费方状态量、confirmed/cancelled 后按该量分派」**(约束:不破现役双钮签名 `confirm_dialog.gd:36-38`,禁双常驻静态接线,分派面须可容纳卡④到位后的第三消费方)——代拍板留痕,追认单可 veto。
|
||||
|
||||
## 10. 待裁点
|
||||
|
||||
### Q1 · 重启后选档界面的初始态(必裁,未裁不开工)
|
||||
|
||||
**背景**:澄清④结构树只到「选档界面 → 营地场景图」,未覆盖退出游戏再启动后的行为。两案并列,**无推荐**(用户令:不代裁):
|
||||
|
||||
| 案 | 内容 | 代价 |
|
||||
|---|---|---|
|
||||
| 甲 | 每次启动都回主菜单→进入存档→选档界面,不自动进档、不预选 | 每轮开局多两次点击;语义最简(无「上次档」隐含状态) |
|
||||
| 乙 | 记忆上次激活槽:重启后选档界面预选该槽(或一键直入) | 多一个激活位持久化状态(卡①承载);「默认进哪档」成为隐含决策;**「一键直入」变体绕选档层,与澄清④「选档=必经层」存在张力,若裁须一并确认层级关系**(v1.1 补注);「预选」需槽卡高亮态(T1 已列);持久化指针指向已删槽的重启语义须注明 |
|
||||
|
||||
连带:卡① §9 第 2 条激活位持久化仅裁乙才需;卡① T1 启动行为条件化同源。裁决方式:随卡片评审定案;裁定落 T0 执行+实现报告留痕。
|
||||
|
||||
**裁定(2026-10-18)**:**甲**——每次启动回主菜单→进入存档→选档界面,不自动进档、不预选。代拍板留痕(用户令「事项按推荐的来」,本项无推荐案,取默认甲=语义最简、无「上次档」隐含状态;追认单可 veto)。连带:卡① §9 第 2 条激活位持久化**作废**(无「当前档选择」需持久);T1 预选高亮态条目不做。
|
||||
|
||||
### Q2 · 坏档/高版本槽在选档面的呈现与操作集(必裁,未裁不开 T1 坏槽态)
|
||||
|
||||
**背景**:盘上任一槽文件可损坏或高版本;卡①窥视读器对不可读槽返回显式损坏标记(契约 9,peek 禁触发 `.corrupt.bak` 改名)——坏槽既非空亦非正常有档,契约 4 二分无第三态。两案并列:
|
||||
|
||||
| 案 | 内容 | 代价 |
|
||||
|---|---|---|
|
||||
| 甲(推荐) | 窥视对坏档/高版本槽返回零值,UI 按空槽呈现(新档/进档均经卡①兜底链接管——进档时走正式 load 触发兜底/拒读) | 坏档在选档面「看不见」,用户可能不知哪槽坏 |
|
||||
| 乙 | 显式第三态(坏档标记+仅允许删档/进档) | 多一套 UI 态与断言 |
|
||||
|
||||
裁决方式:随卡片评审定案;裁定落 T0+T1 坏槽态实现。
|
||||
|
||||
**裁定(2026-10-18)**:**甲**——窥视对坏档/高版本槽返回零值,UI 按空槽呈现(推荐案,用户令按推荐执行);新档/进档均经卡①兜底链接管(进档时走正式 load 触发兜底/拒读)。T1 坏槽态=空槽态,无独立第三态 UI。
|
||||
|
||||
### Q3 · 卡③先行交付时,进档/新档的过渡落点(必裁,未裁不定排期)
|
||||
|
||||
**背景**:v1.0「建议本卡与卡②同批、卡④随后」与完成定义 3(进档落点=卡④)+§8 L3(落点未到位停线呈报)三句互斥——按 L3,「②③先合批、④随后」这条建议路径不可合并。三案并列:
|
||||
|
||||
| 案 | 内容 | 代价 |
|
||||
|---|---|---|
|
||||
| 甲(推荐) | 卡③与卡④同批(完成定义原样成立) | 两卡合并工作量大,单批周期长 |
|
||||
| 乙 | 卡③先行,进档/新档暂行接**现役 CampOverlay**(卡④到位改挂——复用现役面,非「发明占位」) | 临时代码+卡④改挂时的二次验证面;CampOverlay 在卡④前仍是在役面,复用合法 |
|
||||
| 丙 | 进档/新档暂行置灰,完成定义 3 拆两阶段 | 交付面砍残,选档界面半成品 |
|
||||
|
||||
裁决方式:随卡片评审定案;裁定落 §0/完成定义/§8 三处同步改写。
|
||||
|
||||
**裁定(2026-10-18)**:**乙**——本卡随①②③工程批先行,进档/新档暂行接现役 CampOverlay,卡④设计定稿重新立卡后改挂。**迫使原因**:卡④于同日回设计段(美术设计定稿未过设计前置闸),甲案(③④同批)失去对象;丙案(置灰)砍残交付面不取。暂行接线与后续改挂的二次验证面在 T2 明列、实现报告「已知中间态」节登记。
|
||||
|
||||
---
|
||||
|
||||
**审查回写要点**: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)零改动。
|
||||
+3
-3
@@ -5,8 +5,8 @@
|
||||
## 当前位(只回答「现在该做什么」;三行内随批次换代,禁止在此扩写成状态快照)
|
||||
|
||||
- **阶段**:M3——Alpha 版本的完整实现(2026-10-09 立规:未明令宣布完成前停留 M3,迭代只排 M3 需求,M4 不排期;根目录 stage.txt 为旧阶段开关仅存档)。
|
||||
- **迭代位**:迭代 1–32 全部已完成或已终止;迭代 33、34、35 已编排(均待开工,卡片见迭代总表);迭代 36 起未编排——编入哪一迭代由用户经迭代编排段发令。
|
||||
- **下一步**:`/iter 33` 发令开工(实现段,由用户发令,段间不自动流转)。待编池:营地交互重做卡⑤(排卡④之后)、卡④(已退回美术设计段,美术设计闭合后重立卡)、冒险前资源配比预设(冻结备选)、迭代 30 原卡②③(2026-10-17 已剔出迭代 30 规划、退回待设计,待美术/设计定稿后重新立卡)、玩家面残留禁字清扫(待写卡)、结算明细日志行序重锚(2026-10-21 授权发起、时点另定)。
|
||||
- **迭代位**:迭代 1–33 全部已完成或已终止——迭代 33 三卡合回并于 2026-10-22 总收口+反哺落文,迭代 34 两卡已合回、批后收尾未做;迭代 35 已编排(待开工,卡片在 reports/);迭代 36 起未编排——编入哪一迭代由用户经迭代编排段发令。
|
||||
- **下一步**:迭代 34 批后收尾(收口登记与遗留读数义务清册,由用户发令)→ `/iter 35` 发令开工(实现段,段间不自动流转)。待编池:营地交互重做卡⑤(排卡④之后)、卡④(已退回美术设计段,美术设计闭合后重立卡)、冒险前资源配比预设(冻结备选)、迭代 30 原卡②③(2026-10-17 已剔出迭代 30 规划、退回待设计,待美术/设计定稿后重新立卡)、玩家面残留禁字清扫(待写卡)、结算明细日志行序重锚(2026-10-21 授权发起、时点另定)。
|
||||
|
||||
## 里程碑时间线
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
| 迭代 30 | 已完成(2026-10-17) | 已退役(git 历史可考) | 2026-10-16 | — | 已退役(git 历史可考) |
|
||||
| 迭代 31 | 已完成(2026-10-19) | 已退役(git 历史可考) | 2026-10-18 | ≈7.5 个工作日 | 已退役(git 历史可考) |
|
||||
| 迭代 32 | 已完成(2026-10-21) | 已退役(git 历史可考) | 2026-10-20 | ≈8.75 个工作日 | 已退役(git 历史可考) |
|
||||
| 迭代 33 | 待开工 | reports/需求卡片-存档制数据层改造批-2026-10-18.md<br>reports/需求卡片-选档界面新建批-2026-10-18.md<br>reports/需求卡片-主菜单三入口化批-2026-10-18.md | 2026-10-21 | ≈13.25 个工作日〔用户特批 2026-10-21 超 10 个工作日〕 | — |
|
||||
| 迭代 33 | 已完成(2026-10-22) | 已退役(git 历史可考) | 2026-10-21 | ≈13.25 个工作日〔用户特批 2026-10-21 超 10 个工作日〕 | 已退役(git 历史可考) |
|
||||
| 迭代 34 | 待开工 | reports/需求卡片-敌人表深度带换代批-2026-10-21.md<br>reports/需求卡片-信息迷雾可见性批-2026-10-21.md | 2026-10-21 | ≈11 个工作日〔用户特批 2026-10-21 超 10 个工作日〕 | — |
|
||||
| 迭代 35 | 待开工 | reports/需求卡片-节点图生成器核心批-2026-10-21.md<br>reports/需求卡片-节点图消费侧换代批-2026-10-21.md | 2026-10-21 | ≈15.25 个工作日〔用户特批 2026-10-21 超 10 个工作日〕 | — |
|
||||
|
||||
|
||||
@@ -166,8 +166,13 @@
|
||||
|
||||
### ⑯ UI 结构批复验(2026-10-05 ui-struct-probe mini-loop 顺带登记——标题屏双列修复+按钮宽度纪律,约 2 分钟)
|
||||
|
||||
<<<<<<< HEAD
|
||||
- **背景**:实机目检抓到标题屏立绘/帮助牌叠压操作行牌(M2 双列接线缺陷,ui_assembler.gd 右列误挂 MarginContainer)+全站按钮宽度无纪律(UiKit 工厂无宽度约束)。已修复:右列挂回 HBox 第二列;UiKit.button 全站最小宽度基准 216+SIZE_FILL(行板/角标/图标钮 9 处豁免);全 UI 屏结构探针入探针闸默认段。
|
||||
- **看什么(实机目检约 2 分钟)**:①标题屏应为左右双列——左操作列(冒险/营地与系统两组)与右立绘看台+玩法速览牌并排,互不遮挡,「退出游戏」按钮完整可见;②同组按钮等宽(菜单列/确认弹窗),按钮不再宽窄参差;③营地屏三柜台+底栏不出屏、不重叠。
|
||||
=======
|
||||
- **背景**:实机目检抓到标题屏立绘/帮助牌叠压操作行牌(M2 双列接线缺陷,ui_assembler.gd 右列误挂 MarginContainer)+全站按钮宽度无纪律(UiKit 工厂无宽度约束)。已修复:右列挂回 HBox 第二列;UiKit.button 全站最小宽度基准 216+SIZE_FILL(行板/角标/图标钮 9 处豁免);全 UI 屏结构探针入轻闸。
|
||||
- **看什么(实机目检约 2 分钟)**:①标题屏应为左右双列——左操作列(进入存档/设置/退出游戏三钮——迭代 33 卡② 主菜单三入口化后形态,目检按新钮组验)与右立绘看台+玩法速览牌并排,互不遮挡,「退出游戏」按钮完整可见;②同组按钮等宽(菜单列/确认弹窗),按钮不再宽窄参差;③营地屏三柜台+底栏不出屏、不重叠。
|
||||
>>>>>>> master
|
||||
- **红灯信号**:任何屏出现控件叠压/按钮宽窄不一回潮/内容超出屏幕——结构探针已拦机检面,红灯=探针盲区,报批补断言。
|
||||
|
||||
### ⑰ 奇物渠道分离与凭证目检(2026-10-05 奇物词族对齐与渠道分离批顺带登记——迭代15②号卡)
|
||||
@@ -189,7 +194,7 @@
|
||||
|
||||
### ⑲ 生涯页目检(迭代 18 卡④生涯界面实装批·期一顺带登记——主菜单新增一级只读页+存档 v6)
|
||||
|
||||
- **入口与开合**:主菜单「营地与系统」组出现「生涯」钮(营地钮与设置钮之间);点击开全屏页、点「返回」回主菜单(继续上局钮可见性随开合正确恢复)。
|
||||
- **入口与开合**:〔入口已换代——迭代 33 卡② 撤主菜单生涯钮后无玩家可见入口,待迭代 34 卡④ 营地笔记本接入;接入前本项验到页内容即可〕点开全屏页、点「返回」回上层(开始层钮可见性随开合正确恢复)。
|
||||
- **页呈现两类六项**:组一·冒险战绩(冒险总局数 / 通关局数〔括注「三关全通」〕 / 各关通关次数〔一行三关,关名带层号〕 / Boss 首杀〔X/3 关〕 / Boss 总击杀);组二·资源(钥石余额徽)——数值与存档实况一致(对照:玩几局后总局数含放弃与失败、三关全通才计通关)。〔原「属性锻造已购合计」「天赋树已购概览」两观测项随生涯页三投影删除摘除——2026-10-12 用户裁⑧,天赋树实装批顺带〕
|
||||
- **旧档载入**:v5 现役档(升级前存档)载入后生涯页正常显示,总局数/通关局数从 0 起计(终身计数域 v6 新增,缺省补零),钥石等既有进度原样。
|
||||
- **零跳转与局内零入口**:页内除「返回」外无任何前往他处的按钮;冒险进行中(战斗屏/关卡地图屏/状态面板)无生涯入口。
|
||||
@@ -332,3 +337,19 @@
|
||||
| 3 | 高光行与横幅 | 对外高光行「完美封印!清图奖励 ×2」与全屏横幅「完美封印 ×2」显示正确、零「雷」字 |
|
||||
| 4 | 天赋树锋/守限次 | 同一关内第 3 次起踩危险格不再伤害减半、第 3 次标错不再返还行动点(每战限 2 → 每关限 2 的实际手感) |
|
||||
| 5 | 旧档续玩 | 含改名前 counter 键的旧断点存档正常进入不崩(崩溃面已由 V13 自动化覆盖,此处目检手感) |
|
||||
|
||||
---
|
||||
|
||||
## ㉛ 迭代 33——主菜单三入口、选档界面与旧档迁移实机目检(2026-10-22 随反哺写入登记)
|
||||
|
||||
> 三卡换代玩家入口拓扑(主菜单 6 钮→3 钮、新增选档界面、隐式单档→3 存档位+旧档迁槽 1)。机检已覆盖钮集/读回/写盘拒绝与链路面(〔mn〕〔sl〕〔sv〕断言族),左列观感失衡、删档确认文案观感与迁移实际行为仍要人眼看。登记不阻塞(2026-10-12 真人检测立规);总收口时点=迭代 33 实现报告(已退役,git 可考)。
|
||||
|
||||
| # | 目检项 | 判据 |
|
||||
|---|---|---|
|
||||
| 1 | 主菜单三钮观感 | 左列只剩「进入存档/设置/退出游戏」三钮,布局不失衡、无旧钮残留(卡② 目检项) |
|
||||
| 2 | 选档界面三槽观感 | 从「进入存档」进入:三槽逐行呈现、槽卡只显示摘要三项(钥石/通关局数/冒险总局数),无断点/种子等第四项(卡③ 目检项) |
|
||||
| 3 | 删档确认文案 | 点「删档」先出二次确认窗,文案读顺、取消不删、确认才删且槽就地回空(卡③ 目检项) |
|
||||
| 4 | 旧档首次启动迁移(可选——开发者向) | 盘上留有旧 `save.json` 时首次启动:旧档内容出现在槽 1(摘要三项=旧档进度),源改名 `.migrated.bak` 留盘,其余两槽呈白板(卡① 附带观察项,push_warning 留痕非玩家面) |
|
||||
| 5 | 空槽新档链 | 空槽点「新档」→进入营地,槽卡就地翻为有档形态(进档+删档钮) |
|
||||
- **红灯信号**:主菜单出现旧六钮任何一枚;选档层摘要读出别槽值;删档一击直删;旧档迁移后槽 1 白板(迁移没跑)。
|
||||
- **结论回流**:观感问题归迭代 34 卡④(营地场景图重立卡顺带复核入口观感);数据层缺陷归待办清单营地交互重做条。
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
本清单是流水线的唯一登记处:要做的事先在此登记一条,随流水线段推进改状态,做完整条删除;各系统文档的「待办」节只留一行指路存根,不再自建条目。条目格式(标题=登记元数据,正文=现状/缺口/归属/状态四属性)与状态机以 [doc-conventions §12.1](design/engineering/doc-conventions.md) 为权威。
|
||||
|
||||
<<<<<<< HEAD
|
||||
#### 测试术语与层级重构批 A——测试命名+频率规则+新冒烟测试(2026-10-22 登记,来源=会话提及,设计面=工程直入)
|
||||
|
||||
**现状**:测试域名实分离(名叫冒烟的载体实为千项断言面)、每轮跑闸频率过高、测试金字塔倒挂的规则重构,合同=reports/提案-测试术语与层级重构方案-2026-10-22.md(v2,2026-10-22 用户裁决全部闭合、待裁点清零)。批 A=非迭代批(规则与闸件批),用户 2026-10-22 直接下开工令执行:待办清单登记 → 改规则(process-conventions/roadmap loop 规范/术语表退役词对照/AGENTS.md 规则行)→ 写新冒烟测试(game/tests/smoke_boot.tscn/.gd+tools/run_smoke.py 重写)与系统测试宿主(tools/run_system_test.py+game/tests/system_test.gd 薄壳)→ 改闸机键映射(新增 00 冒烟测试、01 改系统测试、02 改单元与集成测试)→ 改描述性文档与 iter 技能三副本 → 全量域闸验证。批 B(断言迁移,用户特批免卡直改 game/)停机等用户发令,不在本条执行面。
|
||||
@@ -9,6 +10,19 @@
|
||||
**归属**:tools/ 闸机与测试基建+规则文档面(工程直入证据=提案 §一 四类问题证据附行号,用户裁决录在提案 §二)
|
||||
|
||||
**状态**:待写卡
|
||||
=======
|
||||
#### 营地五界面窗口化批——营地功能页点开后的呈现形态(2026-10-22 登记,来源=会话提及,设计面=文档轨,优先级=**绝对**)
|
||||
|
||||
**现状**:营地场景图(卡④)把旧四柜台换成「一张可点击的场景图」,从场景图点进去的**五个功能界面**——锻造工坊/秘宝匣/天赋树(树淬炼)/奖励格图鉴/生涯记录——其**呈现形态尚未定稿**:是各开独立全屏页(生涯先例),还是作为**窗口**打开(场景根留底)。**作者 2026-10-22 明示意图=窗口打开,不是全屏页**。该形态原属卡④ §9 代拍板白名单第 2 条(非用户裁、且「缩放虚化」第三形态禁批内自选),故单独立批,不在美术设计段定值。
|
||||
|
||||
**依赖(单向)**:**强依赖卡④**(场景图素材定稿 + 五界面入口改挂)完成;卡④不依赖本条 ⇒ 排序在卡④之后。**与「营地美术素材怎么生成」无关联**(不影响出图/分层/提示词)。
|
||||
|
||||
**缺口**:① 窗口形态与叠层规则定稿(独立全屏页=场景根隐藏/单一内页切换=场景根留底);② **窗口化=场景根留底 ⇒ 会引出「背景要不要压暗/虚化」**,而该点撞上 art-bible §2(2026-10-22 缩窄后**仍禁情绪表达**,背景压暗属氛围表达仍在禁区)与卡④「缩放虚化禁批内自选」——**须在该批开工前一并裁掉**;③ 五界面各自的返回/关闭钮(卡④ v1.1 已承诺各带一个)。
|
||||
|
||||
**归属**:卡④ §9 代拍板域 → 独立成批(呈现层 + 文档轨);窗口形态与叠层规则写入 `LAYER_CONTRACT` 与 [camp](design/gdd/ux/camp.md)「叠层与开合」节
|
||||
|
||||
**状态**:待文档设计
|
||||
>>>>>>> master
|
||||
|
||||
#### 验收闭合规则——下一次迭代实测评估(2026-10-21 登记,来源=审计发现,设计面=工程直入)
|
||||
|
||||
@@ -60,11 +74,14 @@
|
||||
|
||||
#### 状态面板瘦身——局内面板去跨关解锁内容、只留本局信息(2026-10-16 登记,来源=playnote,设计面=工程直入)
|
||||
|
||||
**现状**:playnote 用户反馈:关卡界面中的"状态"面板不需要跨关解锁内容,只显示跟当前冒险有关的信息。现行实态(status_panel.gd 实查)=局内状态面板(2026-10-13 由「暂停层」改名)现为跨局进度镜像:钥石余额徽+「道具工坊 · 解锁态」段(实为秘宝匣 12 行解锁态概览)+「天赋树 · 已购概览」段——恰为用户要去掉的跨关解锁内容。范围=用户原话五件套,零待裁点:面板只留带的秘宝/已获专长/当前属性/现有 GP/钥石总量;秘宝匣解锁态 12 行概览与天赋树已购概览两段退役(跨局解锁概览由营地/生涯承载,局内不再镜像);面板标题与提示行文案随新定位换代(现行「查看本局钥石与永久强化进度」语义失效)。2026-10-16 用户令「不需要讨论的写进 08 并同步待办清单」——[08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「三 · 界面」状态面板行已换代(v1.8 起部分在役);元进度「解锁双入口框架」节与 camp 双入口框架句为设计权威文档反哺点待用户另批裁决。未排期,开工=用户发令或随 UI 批编入。
|
||||
**现状**:playnote 用户反馈:关卡界面中的"状态"面板不需要跨关解锁内容,只显示跟当前冒险有关的信息。现行实态(status_panel.gd 实查)=局内状态面板(2026-10-13 由「暂停层」改名)现为跨局进度镜像:钥石余额徽+「道具工坊 · 解锁态」段(实为秘宝匣 12 行解锁态概览)+「天赋树 · 已购概览」段——恰为用户要去掉的跨关解锁内容。范围=用户原话五件套,零待裁点:面板只留带的秘宝/已获专长/当前属性/现有 GP/钥石总量;秘宝匣解锁态 12 行概览与天赋树已购概览两段退役(跨局解锁概览由营地/生涯承载,局内不再镜像);面板标题与提示行文案随新定位换代(现行「查看本局钥石与永久强化进度」语义失效)。2026-10-16 用户令「不需要讨论的写进 08 并同步待办清单」——[08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「三 · 界面」状态面板行已换代(v1.8 起部分在役);元进度「解锁双入口框架」节的入口拓扑面已随迭代 33 反哺落文(2026-10-22 元进度.md/camp.md 换代为「进入存档→选档→进档/新档」),其局内只读入口语义仍随状态面板瘦身待用户另批裁决;camp 双入口框架句已同步换代。未排期,开工=用户发令或随 UI 批编入。
|
||||
|
||||
**归属**:status_panel.gd(呈现层承载)+ [元进度](design/gdd/systems/跨局循环/元进度.md)「解锁双入口框架」节与 [camp](design/gdd/ux/camp.md) 双入口框架句(局内只读入口语义随瘦身穿改——设计权威文档反哺点,待用户裁决另批)+ [08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「三 · 界面」状态面板行(v1.8 起部分在役)
|
||||
关联文档清单:
|
||||
- 需求卡片 reports/需求卡片-状态面板瘦身批-2026-10-23.md(2026-10-23,零待裁点)
|
||||
|
||||
**状态**:待写卡
|
||||
**归属**:status_panel.gd(呈现层承载)+ [元进度](design/gdd/systems/跨局循环/元进度.md)「解锁界面:双入口框架」节(局内只读入口句随瘦身穿改——设计权威反哺点,归文档批落文)+ [08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「三 · 界面」状态面板行(部分在役——批后销号归反哺点);原归属所记 camp.md 双入口框架句经 2026-10-23 写卡实查无状态面板陈述(系迭代 33 入口拓扑面、已落文结清),从归属移除;同步面全集见需求卡片 §6
|
||||
|
||||
**状态**:已写卡
|
||||
|
||||
#### 旧行为 MC 行为锚全数作废——重锚归数值批(2026-10-06 登记,来源=批次移交,设计面=文档轨)
|
||||
|
||||
@@ -346,14 +363,6 @@
|
||||
|
||||
**状态**:待写卡
|
||||
|
||||
#### 阔视野带效果表述与类型微光口径冲突(2026-10-20 登记,来源=批次移交,设计面=工程直入)
|
||||
|
||||
**现状**:迭代 30 卡①实现报告登记的存量冲突(报告已在这次收尾中退役,git 历史可考):[秘宝](design/gdd/systems/跨局循环/秘宝.md) 普通档表「阔视野带」行一句话写作「类型微光范围 8 格→12 格」,`game/data/tables/treasure_items.tres` 该行 `desc` 同口径;但 [HUD框架](design/gdd/systems/表现与支撑/HUD框架.md) 迷雾节配套拍板已定「类型微光不随视野扩大(贴身 8 格、微光锚=可挖域)」,实现面微光作用集恒为 `_diggable` 子集,该件实际效果是 `light_radius_bonus` 扩灯光区(迷雾视野 8→12),不扩类型微光。两处表述属提灯功能承接时期的遗留措辞。
|
||||
|
||||
**归属**:秘宝.md 普通档表该行 + treasure_items.tres 该行 desc(数据文本订正批;只改文字、不改机制)
|
||||
|
||||
**状态**:待写卡(备选)
|
||||
|
||||
#### 第二 / 三关棋盘观感——亮度与对比度(2026-10-13 登记,来源=playnote,设计面=双轨)
|
||||
|
||||
**现状**:来源=playnote 用户试玩记录「UI 优化,第二第三关的棋盘看着太累了;不知道是因为亮度还是对比度的原因,看着非常费劲,非常不舒服」。2026-10-13 用户裁定:**这是需要做的**,且本就属版本标准的覆盖范围——[08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「五 · 表现」已新增「棋盘观感(第二 / 三关亮度与对比度)」行,标待做。**开工前须先定性(沿用既有裁决)**:是**素材轴**问题(棋盘瓦片与格面图标本身的明度与色相),还是 **UI 轴**问题(舞台底色与叠加层的对比关系)——两轴修法完全不同,定性错了等于白改一轮;该定性要求(原备忘 (e) 项)是本条的开工前置。2026-10-16 曾编入迭代 30 卡③(UI 呈现三卡批序位③),2026-10-17 用户裁定剔除回待设计(自身挂「素材轴/UI 轴」定性人闸+甲/乙〔recolor/远程生图重产〕素材裁点;若裁乙,其瓦片规格依赖战斗一屏样张批的目标规格清单产出)。v1.4 旧卡留 reports/需求卡片-二三关棋盘观感批-2026-10-16.md 作素材,非已写卡状态。与已完成注销的「呈现层残余 <4.5:1 文字位」分工:本条管**棋盘区域整体的观感**(亮度/对比度/费劲感,体感问题),彼条管**具体文字位的对比度读数**(机检可判硬指标),两条不同面不互相替代。Alpha 出口裁决:Alpha 必须,先做素材轴/UI 轴对照定性;出口=用户实机目检不再判「看着费劲」。
|
||||
@@ -576,19 +585,16 @@
|
||||
|
||||
#### 营地交互重做·五张需求卡片(2026-10-18 登记,来源=会话提及,设计面=文档轨)
|
||||
|
||||
**现状**:2026-10-17~18 需求讨论澄清会话产出结论文档,用户令按工作内容维度拆卡、卡片不预占迭代号。五卡已写(顺序=执行顺序):①存档制数据层改造批 ②主菜单三入口化批 ③选档界面新建批 ④营地场景图新建批 ⑤Esc 浮窗与营地顶栏批(各卡估时与内容见卡片自身)。三道复核:grilling 子 Agent 对抗审查(五卡各一)→v1.1;用户裁定「事项按推荐的来」→v1.2;用户两次订正(**卡④留在批内不踢出**;前置归用户自立批,Agent 不代跑不代产——曾越权起草的点选反馈设计稿 v0.1 已撤回删除)→卡④ v2.2;**卡④ 2026-10-21 用户令退回美术设计段(v2.3,非有效卡,美术设计闭合后重立卡)**。①②③⑤ 零待裁点可编工程波次:②③ 硬耦合同波(「进入存档」钮落点=选档界面),① 是 ③ 前置;⑤ 随 ④ 代码波同行。Alpha 出口裁决(2026-10-21 用户裁):五卡整体列入 Alpha——08「三 · 界面」已开条目,Alpha 出口依赖五卡完工与卡④三个用户侧前置销号。关联文档:
|
||||
**现状**:2026-10-17~18 需求讨论澄清会话产出结论文档,用户令按工作内容维度拆卡、卡片不预占迭代号。五卡已写(顺序=执行顺序):①存档制数据层改造批 ②主菜单三入口化批 ③选档界面新建批 ④营地场景图新建批 ⑤Esc 浮窗与营地顶栏批(各卡估时与内容见卡片自身)。三道复核:grilling 子 Agent 对抗审查(五卡各一)→v1.1;用户裁定「事项按推荐的来」→v1.2;用户两次订正(**卡④留在批内不踢出**;前置归用户自立批,Agent 不代跑不代产——曾越权起草的点选反馈设计稿 v0.1 已撤回删除)→卡④ v2.2;**卡④ 2026-10-21 用户令退回美术设计段(v2.3,非有效卡,美术设计闭合后重立卡)**。①②③⑤ 零待裁点可编工程波次:②③ 硬耦合同波(「进入存档」钮落点=选档界面),① 是 ③ 前置;⑤ 随 ④ 代码波同行。Alpha 出口裁决(2026-10-21 用户裁):五卡整体列入 Alpha——08「三 · 界面」已开条目,Alpha 出口依赖五卡完工与卡④三个用户侧前置销号。**工程波次一已落地(2026-10-22)**:卡①②③ 随迭代 33 实现批合回 master(合并提交 ebf40947/5c2a7bcf/508f190b,总收口 6e8f72b2),三卡需求卡片与批次产出物已按「吸收即死」退役(设计口径已吸收进 存档序列化.md/生涯.md/camp.md/08-Alpha版本标准.md v1.13/art-bible.md v3.18,反哺落文凭据=文档批 git 提交 1864f157+9f7b3e8a);卡④(营地场景图)退回美术设计段待重立卡、卡⑤(Esc 浮窗)随卡④ 代码波同行,两卡未编排——编入哪一迭代由用户经迭代编排段发令。关联文档:
|
||||
- 设计澄清定稿:reports/需求澄清-营地交互重做-2026-10-18.md(v1.0:目标体验原话/目标结构树+纵深稿/10 条交互裁决/验收口径/切批原则/遗留待裁)
|
||||
- 卡①:reports/需求卡片-存档制数据层改造批-2026-10-18.md(v1.3)
|
||||
- 卡②:reports/需求卡片-主菜单三入口化批-2026-10-18.md(v1.3)
|
||||
- 卡③:reports/需求卡片-选档界面新建批-2026-10-18.md(v1.3)
|
||||
- 卡④:reports/需求卡片-营地场景图新建批-2026-10-18.md(v2.3,**2026-10-21 用户令退回美术设计段,非有效卡**,美术设计闭合后重立卡,见缺口)
|
||||
- 卡⑤:reports/需求卡片-ESC浮窗与营地顶栏批-2026-10-18.md
|
||||
|
||||
**缺口**:卡④(营地场景图)**已退回美术设计段**(2026-10-21 用户令)——美术轨未闭合,按 req-card 第〇步不具写卡资格,现卡 v2.3 为非有效卡,五项前置销号后方可重立卡:P1 美术渠道 A/B(**待用户裁**,推荐 A);P2 像素规格(Q6 甲过渡口径已裁,执行归用户线);P3 点选反馈设计稿(用户线,未受命开工;Agent 曾越权起草 v0.1,已按用户令撤回删除);P4 参照物(用户后续找);P5 GDD/art-bible 落文(定稿后用户发令)。销号完毕且美术定稿(样张过审+art-bible 条款版本)后卡④方可进代码实现波次。
|
||||
**缺口**:卡④(营地场景图)**已退回美术设计段**(2026-10-21 用户令)——美术轨未闭合,按 req-card 第〇步不具写卡资格,现卡 v2.3 为非有效卡,五项前置销号后方可重立卡:P1 美术渠道(**2026-10-22 已裁=B 插画级新产**,✦ 渠道作者自跑远程生图管线;规格沿用 art-bible §8.1/§8.2 既有裁决);P2 像素规格(Q6 甲过渡口径已裁,执行归用户线);P3 点选反馈设计稿(用户线,未受命开工;Agent 曾越权起草 v0.1,已按用户令撤回删除);P4 参照物(用户后续找);P5 GDD/art-bible 落文(定稿后用户发令)。销号完毕且美术定稿(样张过审+art-bible 条款版本)后卡④方可进代码实现波次。
|
||||
|
||||
**归属**:营地交互重做(数据层+呈现层+美术线;五卡路径见现状清单,批次归属与波次由用户按工作量另裁)
|
||||
|
||||
**状态**:文档设计已闭合+待美术设计+已写卡+已写卡+已写卡+已写卡+已编迭代 33
|
||||
**状态**:文档设计已闭合+待美术设计+已写卡+已写卡
|
||||
|
||||
#### 需求卡片入库纪律未登记——502 批遗留的悬空待办(2026-10-18 登记,来源=批次移交,设计面=反哺点)
|
||||
|
||||
@@ -663,41 +669,6 @@
|
||||
---
|
||||
|
||||
|
||||
#### 2026-10-19 定名传导遗留二项(2026-10-19 登记,来源=会话提及,设计面=文档轨)
|
||||
|
||||
**现状**:2026-10-19「系统资源/补给」定名批(`42d64ec2`/`17ef0180`)遗留两件文档面未结——①`design/gdd/systems/战斗循环/增益状态.md` 用「账/账本」指战斗内状态容器(:10「增益状态就是这本账」、:44「增益减益同账本」、:14「容器只记账」)。经用户确认它与「系统资源」**不是同一个东西**(前者是战斗内状态实例容器,后者是玩家可增减的数值容器),但用词冲突;是否改名(候选方向:容器/状态池)与连带指路句范围待用户裁。②`design/art/art-bible.md:198`(奖励金配色行「金币/宝箱/蜡封」)、`:211`(语义物件「金币=收益金」)与 `design/art/art-assets-checklist.md:105`(九家族图标名)应换代 GP,`design/registry/entities.yaml:623/:629/:637` 三处「金币」同批——均已在分支 `gpsweep-20261019`(`c5d50192`)改完但**未合回 master**,主区现值仍是旧文;合并动作归用户另会话,本批不代做。
|
||||
|
||||
**归属**:增益状态.md(:10/:14/:44 及连带指路句);art/ 两文件(等 `gpsweep-20261019` 合回)
|
||||
|
||||
**状态**:待裁决+待裁决
|
||||
|
||||
---
|
||||
|
||||
#### 2026-10-19 代码注释旧称二处(2026-10-19 登记,来源=会话提及,设计面=工程直入)
|
||||
|
||||
**现状**:`game/data/schemas/adventure_table.gd` 两处注释仍写「资源类」——:21「完美保险整件迁出资源类归专长」、:24「refresh=资源类成员」。奇物第三类已于 2026-10-19 改名「补给」(`奇物.md` v3.20),注释未跟随。**数据零改动**:`CURIO_KINDS` 的 kind 字面(gp/ap/heal/refresh/rap/time_sand)是账名不是分类名,只改注释两处文字。按用户令,代码侧改动等建需求卡片,本批不动。
|
||||
|
||||
**归属**:`game/data/schemas/adventure_table.gd:21/:24`(代码域,随需求卡片走)
|
||||
|
||||
**状态**:待写卡
|
||||
|
||||
---
|
||||
|
||||
#### 2026-10-18 冒记案遗留待裁两项(2026-10-18 登记,来源=审计发现,设计面=文档轨)
|
||||
|
||||
**现状**:2026-10-18 考古确认两处「判据推演被写成事实记载」,均缺用户裁断的独立记录源。
|
||||
|
||||
**①「专长凭证归专长,不归资源」——已订正并写入文档(2026-10-19,用户定性=写文档时的误记)**:已随 `奇物.md` v3.19 写入文档——§1.1/§2.2 与 `entities.yaml:629` 三处改写为「专长在非 Boss 渠道的兑付形态」,不再作归类论断;**机制零改动**(非 Boss 渠道仍只给凭证、拿到即开、不可囤积、一局限购与计步保底全部不变,交叉表专长行仍记「凭证形式」);连带改指:完美保险改归专长的依据由 §1.1 改指 §1.4(**归属结论不动**);v2.2 历史行不改写字面、行尾追加更正注记指向 v3.19。**本项已解决。**
|
||||
|
||||
**②「资源成员=转换源凭证」判据句——仍待裁,本批未动**:引入于 10-08 `6e054466`,该提交信息无「用户裁」字样,而同批头注假托的「2026-10-07 五件新凭证用户裁准写入文档」实为当日用户裁的是**池结构案D**(头注那句失实的时间-裁断陈述已于 2026-10-18 批删除;**`奇物.md` v3.2 版本行的同源失实句仍未处理**)。判据句本身未动,待心智模型对齐后再裁。甄别方法(git log -S 追引入提交 → 核对提交信息管辖范围 → 找独立第二记录源)已记入项目记忆。
|
||||
|
||||
**归属**:①`奇物.md` §1.1/§2.2/v2.2 行(已订正写入文档);②`奇物.md` §1.3(:121/:223/:229)与 `02-系统清单.md:49`(待裁)
|
||||
|
||||
**状态**:已写入+待裁决
|
||||
|
||||
---
|
||||
|
||||
|
||||
#### 效果引擎「系统无状态」原则缺架构文档条目(2026-10-20 登记,来源=会话提及,设计面=文档轨)
|
||||
|
||||
**现状**:用户 2026-10-19 会话裁定的 ECS 架构依据(系统无状态——效果引擎这类系统零运行时可变状态、数据由宿主对象持有并随宿主生灭、状态按参数传入系统、系统只做判定)是「效果引擎无状态化」重构批的立项判据(上游=迭代 31 卡② 移交的计数器寿命域判据线——该登记条目已在本条闭合时整条删除,判据现由 architecture.md v1.9 条 8 承载;提案=reports/提案-效果引擎无状态化-2026-10-19.md v1.3 §7.9 #1),但 `design/engineering/architecture/architecture.md`「架构原则」节(原 7 条)无「系统无状态」条目——立项判据暂无权威文档出处(2026-10-19 全仓检索「无状态/纯计算」零命中,提案 §10.3 实查;原 `design/registry/` 两 yaml 已随 2026-10-19 用户裁注销删除,无可迁凭据)。重构批是代码批、禁写 `design/`,文档级补条只能另立文档批。
|
||||
@@ -727,31 +698,3 @@
|
||||
**归属**:`sim-data/` 锚与 `tools/parity_anchor.py`(重锚执行归用户发令批)
|
||||
|
||||
**状态**:待裁决
|
||||
|
||||
---
|
||||
|
||||
|
||||
#### 迭代 32 移交项一——奇物门票三处玩家文案待定性后传导(2026-10-21 登记,来源=批次移交,设计面=文档轨)
|
||||
|
||||
**现状**:「门票(专长门票)→专长凭证」已在 [术语表](design/gdd/术语表.md) 「退役词对照」在册;迭代 32 卡① 清了 `game/` 注释面的 36 处,但下列三处是**数据值与玩家可见文案**、属 奇物/专长 归类表述,需文档侧先定性才动,故本批只移交不改:①`game/data/tables/shop.tres:86` `"display_name": "奇物门票"`;②③`game/presentation/curio_interact_controller.gd:165`/`:166` 交互文案「奇物门票/选定即开一次奇物三选一」。代码闸拦不到它们——S11 只取注释面(.gd 取 # 后、.tres 取 ; 后),数据值与 UI 文案不在其扫描语义内。关联文档:[奇物](design/gdd/systems/冒险循环/奇物.md)(归类口径 owner,现行版本以文首状态行为准)。用户 2026-10-21 裁=与本清单「2026-10-18 冒记案遗留待裁两项」第②项(资源成员判据句)同源,待该项裁决后走传导批。
|
||||
|
||||
**缺口**:奇物/专长 归类定性一次(随「2026-10-18 冒记案遗留待裁两项」②一并裁);裁后据结论定三处文案改法。
|
||||
|
||||
**归属**:design/gdd/systems/冒险循环/奇物.md(定性面)+ `game/data/tables/shop.tres`/`game/presentation/curio_interact_controller.gd`(传导面,代码域)
|
||||
|
||||
**状态**:待文档设计
|
||||
|
||||
---
|
||||
|
||||
#### 迭代 32 移交项二——巢穴机制表述逐处定性待裁(2026-10-21 登记,来源=批次移交,设计面=文档轨)
|
||||
|
||||
**现状**:[术语表](design/gdd/术语表.md) 「退役词对照」在册一条「巢穴(机制表述)→危险格,世界观风味层的巢穴隐喻〔00-游戏概念/美术纹样名〕除外」——口径已裁,缺的是**逐处判定**:`design/gdd/` 现仍有「巢穴」用词(00-游戏概念 8 处、01-核心循环 3 处、跨局循环/秘宝 3 处,04-美术音频方向/排雷玩法/HUD框架/设置与本地化 各 1 处,术语表自身 3 处),哪些属机制表述(须换「危险格」)、哪些属风味层(保留)未定性。代码注释面本条不清——迭代 32 卡① 的 S11 扫描显式排除「巢穴」(玩家专名+术语表自带除外注)。用户 2026-10-21 裁=待裁范围后另立批,本批只登记。关联文档:design/gdd/术语表.md(用词纪律 owner)。
|
||||
|
||||
**缺口**:一次文档设计讨论——按上列文件逐处判定机制表述与风味层的分界,产出可执行的换代清单。
|
||||
|
||||
**归属**:design/gdd/ 各件(机制表述面)+ design/gdd/术语表.md(口径与除外注)
|
||||
|
||||
**状态**:待文档设计
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user