From 8a889bfcd085a9c0b3adcbd6822e543fd06d4360 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Mon, 2 Nov 2026 02:44:33 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=99=E5=8D=A1(=E8=90=A5=E5=9C=B0=E4=BA=94?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E7=9C=9F=E7=AA=97=E5=8F=A3=E5=8C=96=E6=89=B9?= =?UTF-8?q?=C2=B7=E7=94=A8=E6=88=B7=E4=BB=A4):=20=E9=9C=80=E6=B1=82?= =?UTF-8?q?=E5=8D=A1=E7=89=87v1.0=20=E9=9B=B6=E5=BE=85=E8=A3=81=E7=82=B9+R?= =?UTF-8?q?EADME=E8=83=BD=E5=8A=9B=E8=A1=8C=E7=BB=B4=E6=8A=A4+=E5=BE=85?= =?UTF-8?q?=E5=8A=9E=E6=9D=A1=E7=9B=AE=E6=8E=A8=E8=BF=9B=E5=B7=B2=E5=86=99?= =?UTF-8?q?=E5=8D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game/tests/README.md | 1 + ...œ€求卡片-营地五界面真窗口化批-2026-11-02.md | 267 ++++++++++++++++++ 待办清单.md | 4 +- 3 files changed, 270 insertions(+), 2 deletions(-) create mode 100644 reports/需求卡片-营地五界面真窗口化批-2026-11-02.md diff --git a/game/tests/README.md b/game/tests/README.md index cf7169d1..98c50e6e 100644 --- a/game/tests/README.md +++ b/game/tests/README.md @@ -150,6 +150,7 @@ tests/ | 营地刷新单口与场景根 HUD 同步 | 营地刷新总线 | 写口尾 → `CampRefreshBus.refresh()` → 现开界面刷新+场景根 HUD 刷新 | `ui_struct_probe.gd:_ready`(顶栏位段)〔营地图批 V8〕;`ui_click_probe.gd:_ready`(写口尾刷新段) | | Esc 浮窗唤起与三出口动线 | 营地 Esc 流 | 营地场景根态合成 Esc 键事件→ `main_esc_flow.on_esc_input()` → `ui.flow.open/close`;浮窗三钮 `pressed` → 三出口 | `screen_flow_probe.gd:_ready`(Esc 唤起/子界面开态不唤起/再按关窗/非营地不唤起段)〔ESC批 V1〕;`screen_flow_probe.gd:_ready`(返回动线/设置双路径段)〔ESC批 V3/V4〕 | | 营地顶栏 HUD 钥石读数与刷新单口同步 | 营地 HUD 栏 | 隔离存档实例 `meta_state._add_keystone()`→ 显式触发 `CampRefreshBus.refresh(camp_data)` → `camp_hud_band.refresh()` → `keystone_badge` 读数 | `screen_flow_probe.gd:_ready`(HUD 余额读数/刷新段)〔ESC批 V6〕;`ui_struct_probe.gd:_ready`(顶栏位结构段) | +| 营地五窗统一窗壳形态 | 营地五界面 | 七物件命中区/笔记本 → `CampSceneView._gui_input()`(`object_pressed` 信号)→ 组合根分派开窗;窗板几何(居中定尺寸 720×640 起点)/遮罩/窗内滚动面为呈现提交面 | `screen_flow_probe.gd:_step_camp_window_shell`(窗壳形态段,计划用例——锚定 `reports/需求卡片-营地五界面真窗口化批-2026-11-02.md`)〔窗口化批 V1–V8〕 | **旅程段七:数据配置与跨系统契约** diff --git a/reports/需求卡片-营地五界面真窗口化批-2026-11-02.md b/reports/需求卡片-营地五界面真窗口化批-2026-11-02.md new file mode 100644 index 00000000..c8fe0083 --- /dev/null +++ b/reports/需求卡片-营地五界面真窗口化批-2026-11-02.md @@ -0,0 +1,267 @@ +# 需求卡片 · 营地五界面真窗口化批(v1.0) + +> **用途**:迭代实现批的实施合同。把营地五个功能界面的承载形态从「近全屏面板/全屏深色叠层」换成统一居中定尺寸窗壳;开合路由、互斥、关闭钮、ESC 序等行为面(迭代 47 已落地)零改。 +> **来源**:待办清单「营地五界面窗口化批——营地功能页点开后的呈现形态(2026-10-22 登记,来源=会话提及)」条目(状态=文档设计已闭合+已写卡)。 +> **唯一事实源**:`design/gdd/ux/camp.md` v2.5「叠层与开合」节(2026-11-01 三点裁决+2026-11-02 两点补裁全在案;美术凭据=art-bible v3.32 禁令删除批)。 +> **改动面**:游戏代码。 **估时**:≈2.75 个工作日(T0 0.5–1/T1 0.25–0.5/T2 1–1.5/T3 0.25–0.5,中值合计 2.75)。 + +--- + +## 1. 目标与完成定义 + +**做什么**:营地五界面(锻造工坊/秘宝匣/天赋树/奖励格图鉴/生涯记录)各以**功能窗口**打开—— + +| 形态项 | 定稿值(camp.md v2.5) | +|---|---| +| 窗壳 | 统一居中定尺寸窗壳,起点 **720×640**(窗明显小于屏、营地场景大面积可见;终值随样张目检校准,属普通设计决策) | +| 遮罩 | 窗之下垫半透明压暗遮罩,复用既有模态遮罩件,现值锚黑色 **0.6**(观感随样张目检校准) | +| 滚动 | 内容超高时**窗内滚动** | +| 生涯页 | 与四子界面**同壳同形态**(全屏深色叠层退役) | +| 行为面 | 五窗互斥单开(模态栈深恒 1)、各窗自带关闭钮、ESC 优先序(有窗先关最上层窗、无窗才进 ESC 浮窗)——**零改** | + +**什么状态算完**: + +1. 四子界面壳与生涯页统一为居中定尺寸窗壳:基准档 1280×800 下窗板(窗壳最外层面板容器,窗口可见外缘)实测矩形 = 左上 (280, 80)、尺寸 720×640; +2. 窗开态营地场景根留底可见(场景根 visible 且窗四周有留边); +3. 遮罩 0.6 与全屏锚回归不变; +4. 天赋树长列表内容超高时在窗内滚动(窗尺寸不随内容增长); +5. 五窗互斥单开、各窗关闭钮、ESC 优先序回归全绿(既有行为面断言+本卡新增回归钉); +6. 代码域闸全绿+产出物两份齐(实现报告/反哺点清单)+独立验收审计通过。 + +--- + +## 2. 设计事实源 + +`design/gdd/ux/camp.md` v2.5「叠层与开合」节(:43-45)——五窗统一居中定尺寸窗壳(起点 720×640)、遮罩 0.6、内容超高窗内滚动、生涯页同壳同形态、五窗互斥单开、各窗关闭钮、ESC 优先序。与待办清单条目实况凭据(camp.md v2.5+art-bible v3.32)一致。本批为**行为改动批(呈现形态换壳)**:迭代 47 落地的开合路由/互斥/关闭钮/ESC 序(行为面)不动,只换承载几何。 + +--- + +## 3. 现状事实(代码级,开工自行复核) + +| # | 事实 | 出处 | +|---|---|---| +| F1 | 四子界面共用壳 `_build_shell`:手搓全屏遮罩 dim(`Color(UiKit.DIM, 0.6)`)+ MarginContainer `PRESET_FULL_RECT`(边距 16/16/12/12)+ VBox+内容体 PanelContainer `SIZE_EXPAND_FILL`——内容撑满全屏=近全屏面板形态的成因 | camp_sub_view_base.gd:14-37(dim 在 :16) | +| F2 | 顶栏铭牌+钥石徽;`_balance_label` = 徽值标签(ui_probe 直读面) | camp_sub_view_base.gd:41-62(:62) | +| F3 | 底栏「返回营地」钮 → `closed` 信号 → presenter 关层 | camp_sub_view_base.gd:66-75、:87-88 | +| F4 | 四子界面内容根全为 ScrollContainer(横向禁滚):锻造 :46-51、秘宝 :36-48、天赋树 :18-22、图鉴 :12-16——内容超高滚动面现成 | forge_view.gd:46-51/treasure_view.gd:36-48/tree_view.gd:18-22/codex_view.gd:12-16 | +| F5 | 生涯页=`UiKit.page_shell` 全屏页壳+base 色改 `Color(UiKit.DIM, 0.6)`;顶行「生 涯」标题+「返回」钮(pressed→`_emit_closed`);内容列无滚动面 | career_overlay.gd:18-30(:20-21 页壳与遮罩色) | +| F6 | 生涯开合:组合根 `_open_career`/`_on_career_closed` 模态栈单口;入口=帐篷旁笔记本(营地语境) | main_overlay_flow.gd:40-47、:67-68;句柄 ui_modals.gd:17 | +| F7 | 四子界面开层路由:presenter `open_camp_forge/treasure/tree/codex`(`_open_modal`+投影投喂);关层单口 `on_camp_sub_closed` | camp_shop_presenter.gd:52-69、:73-75;场景点选分派 main_overlay_flow.gd:57-75 | +| F8 | 营地域句柄子容器六枚:scene/forge/treasure/tree/codex/esc_overlay | ui_camp_modals.gd:4-12 | +| F9 | ESC 优先序:`on_esc_input` ①窗开→关最上层窗(`_topmost_camp_window` 五窗集含生涯页)→②设置在浮窗上无反馈→③关浮窗→④营地语境唤起浮窗 | main_esc_flow.gd:17-30、:33-39 | +| F10 | 层序合同 LAYER_CONTRACT:camp_scene(:25)→四子界面(:26-29)→esc 浮窗(:30)→设置(:31)→状态面板(:32)→生涯页(:33);`apply_layer_contract` 是唯一层序落位点 | ui_registry.gd:15-40、:86-112 | +| F11 | 模态栈语义:open 只隐登记序在后的可见层、close 恢复——窗(低层位)开态不隐场景根(更低),生涯页(高层位)开态同此 | modal_stack.gd:21-53 | +| F12 | **既有居中定尺寸壳工厂**:`UiKit.modal_shell(parent, dim_color, min_size, separation, panel_sb)` 返回 `{dim, center, panel, box}`——全屏 dim+CenterContainer 全屏锚居中+可选 PanelContainer+VBox;窗板两条现役选型:`UiKit.panel_skinned(margin)` 石板皮(暖亮模态惯例,9 消费面含营地自家 Esc 浮窗 camp_esc_overlay.gd:19)与 `PANEL_DEFAULT` 哨兵(主题未定义 PanelContainer 默认面板=引擎灰板,仅暗语境 settlement_review 在用);min_size 定尺寸先例=settlement_review 760×560 | ui_kit.gd:501-517(哨兵 :486-498)、:596-607(panel_skinned,缺位回退 PANEL_DATA 素板);settlement_review_overlay.gd:13、legend_overlay.gd:26-27、camp_esc_overlay.gd:18-19 | +| F13 | 遮罩件 `_modal_dim`:全屏锚 ColorRect(默认 mouse_filter STOP=交互聚焦兜底);`DIM` 基色 Color(0.08, 0.06, 0.05) | ui_kit.gd:478-483、:180 | +| F14 | 探针现状五窗 rect 全为 (0,0,1280,800) 全屏(2026-11-02 主会话真渲染取证);仓库内**零**把营地域窗口几何钉成全屏的断言(grep 全探针/测试无 camp 窗 rect/margin 断言) | 本卡写卡段实测(2026-11-02) | + +## 3.1 受影响既有断言面核查(逐面实测) + +| 既有断言面 | 核查结论 | +|---|---| +| ui_struct_probe〔camp〕段(:41-86):场景审计/STONE 源扫描/点选路由/HUD 预留位 | 不受影响——审计根=场景根非子界面;源扫描按文件名(不改名) | +| ui_struct_probe〔career〕段+三契约(:89-106、:433-612):可见性/只读连接数=2/零动效/导航禁词 | 不受影响——换壳保持返回钮 pressed→`_emit_closed` 与 closed→`_on_career_closed` 两条连接、零 AnimationPlayer/零动效令牌、「返回」文案不含禁词(写进设计契约 4) | +| screen_flow_probe Esc 段(:238-294):四态路由/三出口/HUD 读数 | 不受影响——行为面零改 | +| ui_probe 营地段(:26-66):`tree._balance_label` 余额文案/秘宝 12 行 | 不受影响——顶栏钥石徽保留(设计契约 5) | +| ui_click_probe 树/秘宝/图签段:行板标签收集与写口链 | 不受影响——内容件零改 | +| shot_probe ①c 生涯段(:103-121):`_open_career` 函数直调、「返回」钮、「生 涯」meta 取样 | 入口与文案锚全保留;shot_career.png 像素面换代(全屏页→窗壳),shot_checker 通用判据(工程档尺寸/灰度 std≥8/唯一色数≥40)预期仍过——实现批窄验确认,若红按 S1 停机点呈报,禁放宽阈值 | +| shot_probe ②营地段(:122-131)+render golden 基线 | 不受影响——营地截图=根态(无窗);golden 逐像素只对 board 区三基线(tools/render_gate.sh 头注段③),战斗屏不动 | +| forge_workbench_test(直例化 ForgeView 断言行板/钮态/意图信号) | 不受影响——壳改不动内容件;`_balance_label` 与 `open_camp`/`refresh_camp` 签名不变 | +| theme_projection_test 生涯投影段(:796-874):标签投影/可见性 | 不受影响——成员标签与 `open_career` 签名不变 | +| layout_probe(战斗三区几何)/system_test.gd:122 层清单 | 不受影响——战斗屏不触;层清单只核登记在场 | + +**测试削弱申报**:本批不删不改任何既有断言、不放宽任何阈值;新增段为纯增面。shot_career.png 像素换代属设计内形态变化(无 golden 基线、通用判据不变)。 + +--- + +## 4. 设计契约(违反即返工;标 🔴 触碰=L3 停机呈报) + +1. 🔴 **窗几何起点值 720×640 单点**:生产码只落 `CampSubViewBase.WINDOW_SIZE := Vector2(720, 640)` 一个常量(camp.md v2.5 定稿值),生涯页经 `CampSubViewBase.WINDOW_SIZE` 引用,禁第二处字面值;测试断言写死规格字面值(280/80/720/640)作规格锚,双端对账由对照表承担(先例=立绘显示档批 V13 档高钉值)。 +2. 🔴 **行为面零改**:开合路由(presenter `open_camp_*`/`on_camp_sub_closed`/组合根 `_open_career` 族)、模态栈语义、关闭钮 closed 信号接线、ESC 优先序(main_esc_flow)、LAYER_CONTRACT 表序与登记——本批全部零改;diff 出现上述面逻辑改动即违约。 +3. 🔴 **遮罩现值维持**:遮罩=复用既有模态遮罩件(`UiKit.modal_shell` 内 `_modal_dim`),色值 `Color(UiKit.DIM, 0.6)`、全屏锚、STOP 兜底(camp.md v2.5 现值锚黑色 0.6)。 +4. 🔴 **生涯页文案锚不动**:返回钮文案维持「返回」(禁含「营地」——ui_struct_probe nojump 契约在闸);标题「生 涯」文案不动(shot_probe meta 锚)。 +5. 🔴 **四子界面顶底栏构件不动**:顶栏铭牌+钥石徽(`_balance_label`)与底栏「返回营地」钮维持现签名与文案(ui_probe 余额断言与关闭钮回归依赖)。 +6. 🔴 **窗内滚动**:窗体尺寸不随内容增长——内容超高由既有内容滚动面(F4)在窗内滚动承载;生涯页内容列补同款滚动面(同壳同形态)。 +7. 🔴 **零新美术素材**:窗壳程序化,全部经 UiKit 工厂既有 token;禁新色值/新贴图。 +8. 🔴 **窗板选型=石板皮**:窗板样式盒=`UiKit.panel_skinned(Vector4(14, 12, 14, 12))`(暖亮模态惯例 9 消费面、camp_esc 浮窗同款;禁 `PANEL_DEFAULT`——主题无 PanelContainer 默认面板,落引擎灰板与营地暖亮档冲突)。 +9. 🔴 **生涯页文字与底色耦合维持**:生涯页文字 token(WARM/WARM_SOFT/CANDLE/INK_L_GOLD)全部对深棕 BG_BRIGHT 调校(career_overlay.gd:38-40 对比度口径)——生涯窗内容板底色维持 BG_BRIGHT(`UiKit.panel_flat(BG_BRIGHT, PANEL_BORDER, RADIUS_OBJECT, 1, 边距)`),token 零改零重测;禁把生涯文字压上米色 PANEL_DATA 底(亮字亮底 <4.5:1 违 art-bible §7.2)。 +10. 🔴 **判据口径**:验收断言从真实入口进入(进档→场景点选真实信号路由)、判据绑窗板几何/可见性/树序/滚动实高等可观测提交面;全批无变异类测试、无撤销类取证;浮点几何判等用 `is_equal_approx`/`absf < 0.01`(禁裸 `==` 假红)。 + +--- + +## 5. 范围边界 + +**做**:`camp_sub_view_base._build_shell` 换壳(四窗同时生效);`career_overlay._init` 换壳+内容滚动面;探针新增窗壳形态段(V1–V8);`game/tests/README.md` 能力行(写卡段本卡同批);文件头注与行内注释随形态订正。 + +**不做(去向明示)**: + +- 不动开合路由/模态栈/ESC 流程/层序合同(行为面零改——设计契约 2)。 +- 不动四子界面与生涯页内容件(行板/钮/标签/投影逻辑零改)。 +- 不出任何新美术素材;窗终值(720×640 之外)与遮罩观感校准=样张目检后的普通设计决策,实现批只按起点值落码,目检意见走反哺点。 +- 不动 ESC 浮窗、设置面、选档面、确认弹窗等其他模态的形态。 +- 不做窗拖拽/缩放/位置记忆(设计未含,定尺寸窗)。 +- 不改 `design/` 任何文件与根规则文件(同步面义务全部列反哺点,见 §7)。 + +--- + +## 6. 关联文档同步面 + +| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 | +|---|---|---| +| `design/gdd/ux/camp.md`「叠层与开合」节 | 设计即本批依据(起点值已定稿 v2.5);样张目检若校准窗终值或遮罩观感 | 列反哺点清单由文档批落文 | +| `design/gdd/08-Alpha版本标准.md`「三·界面」营地行 | 在役陈述「场景图+七物件点选+Esc 浮窗与顶栏」可补窗壳形态注记 | 列反哺点清单由文档批落文 | +| `design/gdd/systems/跨局循环/生涯.md` :72 | 「营地场景图+五功能窗口形态」陈述与本批一致,无冲突 | 零义务(核查结论记实现报告) | +| `game/tests/README.md` 能力清单 | 新增能力行「营地五窗统一窗壳形态」 | **写卡段已同批补行**(本卡同一提交);实现批禁写该文件 | +| `待办清单.md` 本条 | 状态推进(文档设计已闭合→+已写卡) | 写卡段本卡同批推进;后续段由编排/收尾段推进 | +| `体验验证清单.md` | 实机目检项(窗观感/终值校准/滚动手感) | 列反哺点清单由文档批落文;目检清单先落实现报告(登记不阻塞) | + +--- + +## 7. 卡前文件结构图 + +| 文件 | 职责 | 改动性质 | 验收行 | +|---|---|---|---| +| `game/presentation/views/camp_sub_view_base.gd` | 增 `WINDOW_SIZE` 常量;`_build_shell` 原地改写为 `UiKit.modal_shell` 窗壳骨架(dim 0.6+居中窗板 720×640+内容列);顶/底栏构件调用不变 | **行为改动** | V1 V2 V3 V5 | +| `game/presentation/views/career_overlay.gd` | `_init` 原地改写为同款窗壳(引用 `WINDOW_SIZE`);顶行迁入窗内容列;内容列包滚动面+BG_BRIGHT 内容板(设计契约 9) | **行为改动** | V4 V6 V8 | +| `game/probe/screen_flow_probe.gd` | 新增 `_step_camp_window_shell` 段(V1–V8 断言,插 `_step_camp_esc_and_hud` 之后) | 新增测试 | V1–V8 | +| `game/tests/README.md` | 能力清单增行「营地五窗统一窗壳形态」 | 写卡段义务(非行为) | — | +| `game/presentation/ui_registry.gd`、`game/presentation/main_ui_build.gd` | 行内注释「独立全屏页/只读全屏页」(:26/:100/:139)随形态订正 | 非行为改动(注释零逻辑) | — | +| 两视图文件头注 | 壳形态描述随动(窗壳) | 非行为改动(注释零逻辑) | — | + +结构图与 §12 落位预检互指:本批**零新增文件**;两处壳改写=存量触面原地改写(复用既有件,见 §12)。 + +--- + +## 8. 任务卡 T0..T3 + +### 8.1 T0——四子界面窗壳改造(估时 0.5–1 个工作日) + +- [ ] 环境就绪:worktree 内拷主区 `.godot/` 导入缓存(或跑 `D:\code\godot\Godot_v4.7.2-stable_win64_console.exe --headless --editor --quit --path game` 刷);跑 `python tools/gdstyle_gate.py` 记录改前 S13 读数(camp_sub_view_base.gd/career_overlay.gd 现行零基线键),存实现报告改前基线。 +- [ ] `camp_sub_view_base.gd` 增类常量 `const WINDOW_SIZE := Vector2(720, 640)`(注释注明 camp.md v2.5 起点 定值单点)。 +- [ ] `_build_shell` 原地改写:`var shell := UiKit.modal_shell(self, Color(UiKit.DIM, 0.6), Vector2.ZERO, 8, UiKit.panel_skinned(Vector4(14, 12, 14, 12)))`,随后 `shell.panel.custom_minimum_size = WINDOW_SIZE`(窗板外缘即 720×640,`min_size` 参数保持 ZERO 使窗板尺寸精确可钉;panel_skinned 边距被 PANEL_SLICE 钳到 16——ui_kit.gd:597-598 既有工厂行为);`_build_top_bar(shell.box, title, icon_path)`、内容体 PanelContainer(PANEL_DATA 样式盒与 EXPAND_FILL 沿用)挂 `shell.box`、`_build_bottom_bar(shell.box)` 三段调用不变;删除全屏 MarginContainer 16/16/12/12 骨架;`visible = false` 初始隐维持。 +- [ ] 文件头注随动(近全屏面板形态描述→居中定尺寸窗壳)。 +- [ ] 确认 forge/treasure/tree/codex 四视图 `_init` 零 diff(壳改即四窗全换——F4 内容滚动面不动)。 +- [ ] 孤立验证:`…console.exe --headless --path game --script res://tests/unit/presentation/forge_workbench_test.gd` exit 0(行板/钮态/意图信号回归)。 +- [ ] 复跑 `python tools/gdstyle_gate.py`:camp_sub_view_base.gd 零新键(S13 只降不升达成)。 + +**取用**:无。**产出**:`CampSubViewBase.WINDOW_SIZE`(Vector2 常量)+四窗窗壳化(窗板=shell.panel、内容列=shell.box 的结构形态——T1/T2 取用)。 + +### 8.2 T1——生涯页同壳改造(估时 0.25–0.5 个工作日) + +- [ ] `career_overlay.gd` `_init` 原地改写:`UiKit.page_shell` 调用与 `page.base.color` 字面量退役;换 `var shell := UiKit.modal_shell(self, Color(UiKit.DIM, 0.6), Vector2.ZERO, 8, UiKit.panel_skinned(Vector4(14, 12, 14, 12)))`+`shell.panel.custom_minimum_size = CampSubViewBase.WINDOW_SIZE`;顶行(「生 涯」标题+spacer+「返回」钮,文案与连接零改)迁入 `shell.box`;内容列(hint+组一行板)包 ScrollContainer(`SIZE_EXPAND_FILL`、横向禁滚——同 F4 形态)进 `shell.box`;滚动面外再垫内容板 PanelContainer(样式盒=`UiKit.panel_flat(UiKit.BG_BRIGHT, UiKit.PANEL_BORDER, UiKit.RADIUS_OBJECT, 1, Vector4(12, 12, 12, 12))`——原页底色随壳迁移,文字 token 零改,设计契约 9);成员标签变量与 `open_career` 签名零改。 +- [ ] 文件头注随动(只读全屏页→只读功能窗口);头注 :3 陈旧入口陈述(「入口唯一在开始覆盖层『营地与系统』组」——卡④ T3 改挂帐篷旁笔记本后遗留)一并订正为笔记本入口。 +- [ ] 孤立验证:`…console.exe --headless --path game --script res://tests/unit/presentation/theme_projection_test.gd` 生涯投影段与全件 exit 0。 +- [ ] 复跑 `python tools/gdstyle_gate.py`:career_overlay.gd 零新键。 + +**取用**:T0 的 `CampSubViewBase.WINDOW_SIZE`。**产出**:生涯页同壳(同构窗板/内容列——T2 取用)。 + +### 8.3 T2——探针窗壳形态段(估时 1–1.5 个工作日) + +- [ ] `screen_flow_probe.gd` 新增 `func _step_camp_window_shell() -> void`,插 `_ready` 中 `_step_camp_esc_and_hud()` 之后;前置 `ProbeUiUtil.open_camp_via_savesel(main, "smoke_screen_flow_winshell")`(真实进档入口)。断言明细(新码全类型标注;每断言带〔窗口化批 Vn〕尾缀): + - **V1 四窗几何**:循环 `[&"forge", &"chest", &"dummy", &"board"]` 逐一键 `object_pressed.emit(k)`(每窗先经真实关闭钮关前窗),经视图子树取 CenterContainer 下的 PanelContainer 为窗板,断 `get_global_rect()` 位置 ≈ (280, 80)、尺寸 ≈ (720, 640)(浮点容差 0.01)。 + - **V2 场景根留底**:每窗开态断 `main.ui.modals.camp.scene.visible == true` 且窗板矩形四边距视口边 ≥80px(V1 等值蕴含,独立断言钉场景根可见)。 + - **V3 遮罩 0.6**:每窗开态断视图首个子节点 ColorRect(遮罩件)`color.a ≈ 0.6` 且 `size == 视口尺寸`。 + - **V4 关闭钮回归**:四窗经底栏「返回营地」、生涯窗经顶行「返回」真实 Button `pressed.emit()` → 断窗隐(visible==false)且场景根仍 visible。 + - **V5 互斥单开与点选遮挡**:每窗开态断五窗集(forge/treasure/tree/codex/career_overlay)visible 计数 == 1(轮转开合逐窗断);另在树窗开态取锻炉命中区中心(`camp_scene.get_hotspot_rect(&"forge")` 公开读面,camp_scene_view.gd:83——场景根全屏锚下局部==全局)`push_input` 真实鼠标点击事件 → 断无任何新窗打开、树窗仍开(窗下场景点选被遮罩挡——模态遮挡可达性探针标配)。 + - **V6 ESC 先关窗**:`object_pressed.emit(&"notebook")` 开生涯窗 → `push_input` 真实 Esc 键事件(:114-120 同款)→ 断生涯窗隐且 esc 浮窗未开。 + - **V7 内容超高窗内滚动**:`object_pressed.emit(&"dummy")` 开树窗 → `tree_view.refresh_camp()` 喂真实 `main._camp_data()` 投影追加 30 行合成行(行结构与树投影同型:vein=spine/kind=stat/node_id=probe_row_i/can_buy=false)→ 断(a)窗板 rect 仍 ≈ (280, 80, 720, 640)(窗不随内容涨)(b)树滚动容器内容实高(`_tree_holder.size.y`)> 滚动容器实高(超高实据)。 + - **V8 生涯同壳**:`object_pressed.emit(&"notebook")` 开生涯窗 → 断窗板 rect 同 V1 等值+「返回」钮在位+内容列滚动面在(窗内容子树 ScrollContainer 存在且纵向 EXPAND_FILL——同壳滚动面结构钉)。 +- [ ] 段尾收闭:关窗+`main._on_camp_closed()` 复归菜单语境(后续 `_step_save_select_open_back` 段前提不受扰)。 +- [ ] 孤立验证:`…console.exe --headless --path game res://probe/screen_flow_probe.tscn` exit 0(新段+既有段全绿)。 +- [ ] 窄验 shot_probe:窗口化跑 `…console.exe --path game res://probe/shot_probe.tscn -- <临时目录>` exit 0,确认生涯段(「返回」钮/「生 涯」meta)与七屏自检在窗壳形态下通过(shot_career.png 通用判据 std/色数读数记实现报告)。 + +**取用**:T0 窗板结构(CenterContainer→PanelContainer)与 `WINDOW_SIZE`;T1 生涯窗同构。**产出**:V1–V8 断言段+shot_probe 窄验读数。 + +### 8.4 T3——产出物落位卡(估时 0.25–0.5 个工作日) + +- [ ] 代码域闸全绿:`bash tools/run_all_gates.sh --code`(里程碑步出口跑一次全套;波内修复只做出红件最窄确认;新增测试已先行孤立验证)。 +- [ ] `reports/iter-实现报告-<日期>.md`:各卡状态+实机目检总清单(登记不阻塞:①五窗观感与场景可见度样张判定;②窗终值 720×640 与遮罩 0.6 观感校准意见;③窗内滚动手感)+遗留读数义务+实现决定记录(超白名单事项逐条记决了什么/为什么/代价/撤销方式)。 +- [ ] `reports/iter-反哺点-<日期>.md`:§6 同步面每条落点(camp.md 校准注记/08-Alpha 行注记/体验验证清单入册)。 +- [ ] 独立验收审计:`reports/iter-验收审计-<日期>.md`(没参与实现的会话或子代理执行;未过不得合并)。 + +**取用**:T0–T2 全部产出。**产出**:闸全绿回执+两份产出物+审计报告。 + +--- + +## 9. 验证闸(改动—验收对照表) + +| 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 | +|---|---|---|---|---|---|---| +| 四子界面统一窗壳 720×640 起点居中 | camp_sub_view_base.gd `_build_shell`(:14-37 原地改写)+`WINDOW_SIZE` 常量 | 「四窗窗板 global_rect 位置≈(280,80)、尺寸≈(720,640)」`screen_flow_probe.gd:_step_camp_window_shell`〔窗口化批 V1〕 | 探针 | 选档层进档(`open_camp_via_savesel` 真实钮信号)→场景点选 `object_pressed` 真实信号路由 | 窗板全局 rect 浮点等值(容差 0.01) | 新增:营地五窗统一窗壳形态 | +| 窗明显小于屏+场景根留底大面积可见 | 同上(窗居中+dim 全屏不遮场景根——F11 栈语义) | 「窗开态 camp.scene.visible==true 且窗板四边距视口边≥80px」〔V2〕 | 探针 | 同 V1 | 场景根可见性状态源+窗板 rect 边距 | 新增:营地五窗统一窗壳形态 | +| 遮罩 0.6 回归 | modal_shell dim 件(`Color(UiKit.DIM, 0.6)`) | 「五窗开态遮罩 ColorRect alpha≈0.6 且全屏」〔V3〕 | 探针 | 同 V1 | 遮罩件 color/size 状态源实读 | 新增:营地五窗统一窗壳形态 | +| 各窗关闭钮回归(行为面零改的回归钉) | 零改动行——`_build_bottom_bar`/`_emit_closed`/career「返回」钮沿用(F3/F5) | 「四窗『返回营地』/生涯『返回』真实钮 pressed→窗隐且场景根留底」〔V4〕 | 探针 | 窗内真实 Button pressed 信号 | 钮信号→窗 visible 终态 | 既有:四柜台拆解后五界面入口改挂与写口零回归 | +| 五窗互斥单开回归(行为面零改的回归钉) | 零改动行——模态栈语义+遮罩 STOP 兜底(F8/F11/F13) | 「逐窗轮转开合五窗 visible 计数恒 1+窗开态向锻炉命中区(`get_hotspot_rect` 读面)推真实鼠标点无新窗打开(点选被遮罩挡)」〔V5〕 | 探针 | 同 V1 路由+V4 关闭钮+`push_input` 真实鼠标事件 | 五窗 visible 计数+点穿零响应 | 既有:模态句柄分域寻址面 | +| ESC 优先序回归(行为面零改的回归钉) | 零改动行——`_topmost_camp_window` 五窗集含生涯页(F9) | 「生涯窗开态 Esc 先关生涯窗、浮窗不唤起」〔V6〕 | 探针 | `push_input` 真实 Esc 键事件 | 窗 visible 终态+esc 浮窗 visible | 既有:Esc 浮窗唤起与三出口动线 | +| 内容超高窗内滚动(树长列表实据) | 壳改后窗体定尺寸+F4 既有滚动面承载;生涯页补滚动面(career_overlay `_init`) | 「加长行册喂入后窗板 rect 仍等值(窗不涨)+滚动内容实高>滚动视口实高」〔V7〕 | 探针 | `object_pressed(&"dummy")` 开树窗+`refresh_camp`(presenter 同款真实数据投喂口)喂加长行册 | 窗板 rect 不变量+内容实高差 | 新增:营地五窗统一窗壳形态 | +| 生涯页同壳同形态 | career_overlay.gd `_init`(:18-58 原地改写) | 「生涯窗板 rect 同 V1 等值+『返回』钮在位+内容列滚动面在+投影标签回归(theme_projection_test 全件 exit 0)」〔V8〕 | 探针+单元 | 笔记本点选 `object_pressed(&"notebook")` 路由;单元侧 `CareerOverlay.new().open_career()` 真实数据口 | 同一几何判据+文案锚+滚动面结构+标签投影 | 新增:营地五窗统一窗壳形态 | + +**非行为改动声明(反向覆盖)**:注释随动六处(ui_registry.gd:26、main_ui_build.gd:100 与 :139、camp_sub_view_base.gd:2 头注、career_overlay.gd:2 头注与 :19 行注——「独立全屏页/全屏页壳」陈述随窗壳化订正)=非行为改动——零逻辑、零签名、零接线变化,行为判据由上表 V1–V8 行覆盖。 + +**判据口径**:全批无变异类测试、无撤销类取证;每行从真实入口进入、绑被测改动特有的可观测提交面;扫描类判据带非空前置。 +**测试削弱申报**:见 §3.1 末——零删改零放宽。 +**代码域闸命令(里程碑步出口跑一次全套,波内修复只做出红件最窄确认;新增测试先行孤立验证再并入全套)**:`bash tools/run_all_gates.sh --code`。 + +--- + +## 10. 异常分级 + +- **L1 自救**:`.godot` 缓存失配 → 重跑 `--editor --quit` 刷导入;探针隔离档陈旧 → 重跑 `isolate_save` 前置。 +- **L2 记录继续**:加长行册喂入后滚动条部件读数因主题样式偏差不可靠 → 改绑内容实高差判据(V7b)并记录读数,禁删断言;shot_probe 生涯段通用判据读数贴近带缘 → 读数记实现报告盯 CI。 +- **L3 停机写报告等用户**: + 1. V1–V8 任一断言在真实跑批中做不出(判据绑不上可观测提交面)→ 停卡呈报,禁放宽阈值、禁换下层直调; + 2. `UiKit.modal_shell` 骨架与本卡契约互斥(如窗板无法精确等值钉 720×640)→ 停卡退回写卡段,禁自造第三条路; + 3. 机检预算互斥=上游缺陷停卡退回写卡段(S13 键与卡片契约冲突时禁为过闸保留无效成员); + 4. 实现中冒出卡片未写清的形态分歧 → 停该卡退上游,禁内联求裁。 + +--- + +## 11. 代拍板白名单(超清单必呈报) + +1. 窗板样式盒微调:`panel_skinned` 边距取值(Vector4 各分量 ±8px 内)与 tint——观感随样张目检校准面;选型本身(石板皮)与生涯内容板底色(BG_BRIGHT)属设计契约 8/9 不在白名单。 +2. `WINDOW_SIZE` 常量等价命名(如 `CAMP_WINDOW_SIZE`)与生涯页引用写法——单点定义与引用关系不变。 +3. 探针段测试参数取值:加长行册行数(30)与合成行字段值——非断言值的夹具参数。 +4. 断言消息尾缀〔窗口化批 Vn〕括注用词格式。 +5. 窗内容列 separation 等间距微调(±4px 内)——观感校准面。 + +--- + +## 12. 落位与可复用性预检 + +| 新增件 | 复用面(盘上是否已有同职责件) | 唯一面 | 分层与交互面 | +|---|---|---|---| +| `CampSubViewBase.WINDOW_SIZE` 常量 | 无同类常量(现行壳无定值几何);不新增文件,落壳基类 | 窗几何值 GDScript 侧只此一处;生涯页经类常量引用不自设值 | 呈现层内部常量,不跨层 | +| `_build_shell` 窗壳骨架 | **复用 `UiKit.modal_shell`**(ui_kit.gd:501-517,现役九消费者含 settlement_review 定尺寸先例)+`_modal_dim` 遮罩件+`panel_skinned` 石板皮窗板(:596-607,9 消费面惯例)——不新造工厂、不新造遮罩、不新造窗板样式 | 居中定尺寸壳骨架全仓唯一落点=UiKit.modal_shell;本批零新工厂 | 纯呈现层;视图零核心写调用不变;开合仍走模态栈单口(presenter/组合根零改);RngService/ConfigDB 不触及 | +| 生涯页滚动面 | 复用 ScrollContainer 既有形态(F4 四子界面同款) | 生涯内容列滚动面只此一处 | 同上 | +| 探针 `_step_camp_window_shell` | 复用 screen_flow_probe 既有步骤框架与 ProbeUiUtil 隔离样板(不新增探针文件) | 窗几何断言只落此段一处(段内五窗循环) | 测试侧只读,不反向驱动呈现 | + +**为什么不能复用更多**:`_build_shell` 现行手搓的全屏 MarginContainer 骨架(F1)正是本批要退役的形态——改写为调用 modal_shell 即完成复用;生涯页 page_shell 为全屏页专用工厂(设置面/选档面仍在用),退役的是调用点不是工厂本体。 + +--- + +## 13. 拆分边界纪律适用性声明 + +本批为呈现形态换壳(行为改动批),非拆分/收敛/重构类卡——零职责重组、零成员迁移(`_build_top_bar`/`_build_bottom_bar`/成员变量原地沿用)。壳内构件沿用既有职责边界:顶栏=铭牌+余额徽、底栏=关闭钮、内容体=子类内容滚动面,单一变化原因=承载几何。若实现期为凑 S13 键而拆分或收拢成员,一律停卡呈报(L3 #3)。 + +--- + +## 14. 实现规范预算 + +- **新件三查**:本批**零新增 .gd 文件**(§12 复用面已定),接口块公开方法数与成员变量数三查不适用;新增类常量 1 个(const 非成员变量,不触 var 上限)。 +- **存量触面一查(S13 键只降不升)**:`camp_sub_view_base.gd`(在面,现行零基线键)——`_build_shell` 原地改写不增成员、不增公开方法、分支数不升(dim/center/panel/box 直列无分支);`career_overlay.gd`(在面,现行零基线键)——`_init` 原地改写同上。T0/T1 各带改前改后 `python tools/gdstyle_gate.py` 读数对账(§8.1/§8.2 末步)。 +- **测试侧纪律**:探针新段全类型标注(test-conventions §6 义务);断言内规格字面值(280/80/720/640/0.6)为规格锚非第二事实源(设计契约 1 双端对账口径)。 +- **指标例外申报**:无。 + +--- + +## 15. 待裁点 + +**零待裁点,开工门 = U0。** 三点裁决(2026-11-01:功能窗口形态/遮罩 0.6+互斥+关闭钮/ESC 优先序)与两点补裁(2026-11-02:五窗统一居中定尺寸窗壳起点 720×640+生涯页同壳同形态)全在案于 camp.md v2.5「叠层与开合」节与待办清单条目实况;窗观感终值与遮罩观感校准属样张目检后的普通设计决策(camp.md v2.5 明文),归代拍板白名单与反哺点,不构成本卡待裁点。 + +--- + +## 16. 估时与切分预案 + +≈2.75 个工作日(T0 0.5–1/T1 0.25–0.5/T2 1–1.5/T3 0.25–0.5,中值合计 2.75)。 + +切分预案:T0 与 T1 同壳同骨架、可独立验收(四窗先换、生涯页随后),若 T2 探针段压超软盒,切分点=把 T2 拆成「四窗+回归钉段」与「生涯同壳+滚动实据段」两卡同迭代合回,不拆迭代;若实机样张判窗观感不可受(终值需大调),本卡止于 L3 呈报走反哺点,校准后另立微调批。 diff --git a/待办清单.md b/待办清单.md index 16fe313c..3c2d4d0b 100644 --- a/待办清单.md +++ b/待办清单.md @@ -160,11 +160,11 @@ #### 营地五界面窗口化批——营地功能页点开后的呈现形态(2026-10-22 登记,来源=会话提及) -**实况**:营地场景图(卡④)把旧四柜台换成「一张可点击的场景图」,从场景图点进去的**五个功能界面**——锻造工坊/秘宝匣/天赋树(树淬炼)/奖励格图鉴/生涯记录——其呈现形态原属卡④ §9 代拍板白名单第 2 条,故单独立批。**2026-11-01 用户裁三点闭合**:①承载形态=功能窗口·场景根留底+半透明压暗遮罩(交互聚焦用,复用既有模态遮罩件,现值锚 0.6)+五窗互斥单开(模态栈深恒 1)+各窗自带关闭钮(卡④ v1.1 承诺面);②ESC 优先序=有功能窗口开着先关最上层窗、无窗才进卡⑤ ESC 浮窗四态;③前置冲突消解=art-bible §2「情绪明暗禁令」整块删除(用户裁:明亮基调为正向方向,压暗属普通设计决策逐案走样张目检——该禁令查无正向拦截实例,同批修 art-bible 七处引用站)。**与「营地美术素材怎么生成」无关联**(不影响出图/分层/提示词);零新美术素材。定稿凭据:[camp](design/gdd/ux/camp.md) v2.5「叠层与开合」节+[art-bible](design/art/art-bible.md) v3.32(禁令删除批)。**2026-11-02 真窗口化补裁(用户令重开设计)**:迭代 47 实装把「功能窗口」落成近全屏面板(四周约 16px 暗边、场景几乎不可见),用户裁重走窗口化设计并两点补裁——①五窗统一居中定尺寸窗壳(起点 720×640,窗明显小于屏、场景大面积可见,终值随样张目检校准,内容超高窗内滚动);②生涯页与四子界面同壳同形态(全屏深色叠层退役)。实现属后续卡(卡④已完工)。 +**实况**:营地场景图(卡④)把旧四柜台换成「一张可点击的场景图」,从场景图点进去的**五个功能界面**——锻造工坊/秘宝匣/天赋树(树淬炼)/奖励格图鉴/生涯记录——其呈现形态原属卡④ §9 代拍板白名单第 2 条,故单独立批。**2026-11-01 用户裁三点闭合**:①承载形态=功能窗口·场景根留底+半透明压暗遮罩(交互聚焦用,复用既有模态遮罩件,现值锚 0.6)+五窗互斥单开(模态栈深恒 1)+各窗自带关闭钮(卡④ v1.1 承诺面);②ESC 优先序=有功能窗口开着先关最上层窗、无窗才进卡⑤ ESC 浮窗四态;③前置冲突消解=art-bible §2「情绪明暗禁令」整块删除(用户裁:明亮基调为正向方向,压暗属普通设计决策逐案走样张目检——该禁令查无正向拦截实例,同批修 art-bible 七处引用站)。**与「营地美术素材怎么生成」无关联**(不影响出图/分层/提示词);零新美术素材。定稿凭据:[camp](design/gdd/ux/camp.md) v2.5「叠层与开合」节+[art-bible](design/art/art-bible.md) v3.32(禁令删除批)。**2026-11-02 真窗口化补裁(用户令重开设计)**:迭代 47 实装把「功能窗口」落成近全屏面板(四周约 16px 暗边、场景几乎不可见),用户裁重走窗口化设计并两点补裁——①五窗统一居中定尺寸窗壳(起点 720×640,窗明显小于屏、场景大面积可见,终值随样张目检校准,内容超高窗内滚动);②生涯页与四子界面同壳同形态(全屏深色叠层退役)。实现属后续卡(卡④已完工)。**2026-11-02 写卡**:需求卡片 reports/需求卡片-营地五界面真窗口化批-2026-11-02.md(v1.0,零待裁点,开工门=U0);能力行「营地五窗统一窗壳形态」同批入 game/tests/README.md 能力清单。 **改动面**:文档+游戏代码 -**状态**:文档设计已闭合 +**状态**:文档设计已闭合+已写卡 #### UI 贴图重构批——元进度件仍是程序化占位(2026-10-13 登记,来源=审计发现)