Compare commits

..
Author SHA1 Message Date
DKChan 6b5a96b6c7 iter45-卡②T2: 断点域拆件 breakpoint_store(R2整族归件v1.1)——六成员(save_manager/resume_bp/pending_next_level/last_level_payload/last_treasure_cleared/loadout_seeded)+BREAKPOINT_FIELDS 27键冻结+函数族九个归件:纯读侧三函数与_bp_parts/snapshot body逐字(宿主输入state/level_index/master_seed/runner/counters逐调传参——件禁反向持宿主),四_resume_*按所有权缝语句分家:件侧(主角账三件restore_fragment/curio池与特性还原/stop与bank片段回填/数值账规范化钳制)迁store五个回填函数,宿主侧(八项重绑定与_reset_curio_state/_attune_refresh_x_total调用)按原语句序吸收进resume_adventure壳,引用束九引用解包为原名成员保body逐字(6+9=15贴顶);宿主留_snapshot_breakpoint一行委托壳(CurioStop的Callable目标零改)与set_save_manager转发件,断点键面零变化,语句序逐步保形;测试:185改址BreakpointStoreScript.BREAKPOINT_FIELDS(判据零变化——第14节申报)〔补件 V2〕;验证:run_all三套件全绿+run_smoke 15项0失败 2026-10-31 00:15:43 +08:00
DKChan 96ec80aa97 iter45-卡②T1: 悬停域拆件 board_hover——11函数族+_hover/_last_click两成员迁出(函数体逐字,三处机械改写:_cell_at→_cb_cell_at.call带类型标注/hover_forbidden与chord_attempted.emit→注入Callable.call/mouse_default_cursor_shape写入→_cb_cursor.call),COL_HL_TARGET/CURSOR_DIG/CURSOR_MOVE_SEM/CHORD_WINDOW_MS随函数迁常量、COL_SEAL双侧服役各自alias UiKit单源,三入站口(_gui_input/_on_cell_input/click_cell)与hover_probe读面留宿主委托,_r0留宿主;构造=引用束字典注入(cells/minesweeper/diggable共享引用+格命中换算/光标写入/两信号发射Callable)防max-parameters新键,minesweeper重绑由rebuild同拍回写件成员〔补件 V1〕;验证:probe_gate --click --full全绿+render_gate golden 8屏OK;键账board_view类变量32→31(只降不升)/公开方法27持平 2026-10-31 00:15:42 +08:00
DKChan fe0aeb8f28 iter45-卡①T3: ui_input_probe 直读改址 u.face.*——四处断言(case①②③⑭ hl_visible/hl_color/dot_visible/mutation_mark,11处)+case④b封印纹理槽 st.tex_seal 两处(设计文档§1.4直读面清单漏计的第五处,L1就地修复)——断言条件与期望值零变化,只改读路径;T0定谳绿凭据下的改址义务落码收口〔状态件 V4〕;验证:probe_gate --click --full 全绿+render_gate golden三张0.00%复跑 2026-10-31 00:15:41 +08:00
DKChan 75780e31fa iter45-卡①T2: 站桩两状态件建件与宿主改造——_StandeeState 真实25成员沿身份命值/资产演出缝拆 standee_vitals(12成员,apply_hp=_set_hp整体搬移,hp_value setter逐字)/standee_motion(11成员,六迁入函数:set_portrait_texture(tex,flip,box)/register_hero_state/apply_hero_state(is_hero参判,三连早退序逐字)/reset_state(RESET绕同态早退两拍封装)/play_intent_motion(charge参判)/state_probe),HeroState枚举与_HS_NAME/_HS_VALUE随三态机归motion(全仓零外部消费实测);宿主10成员(五冻结var+st/mo+三演出探针计数器上收),转调壳三入口外形零变,fx_probe改读宿主计数器,tween路径串st.hp_value/mo._intent_scale/mo._glyph_rot,源码锚三函数(_draw_hp_bar/_draw_armor_name_line/set_pending)留宿主且锚行逐字(st=vitals名沿用故血条/名字行零改写)〔状态件 V3〕;battle_stage_view一行未改实测;孤立验证run_all两套件全绿+run_smoke 2026-10-31 00:15:39 +08:00
DKChan ea03765adc iter45-卡①T1: 单格两绘制域件建件与宿主瘦身——_CellPaintState 27成员沿绘制层域轴拆 cell_base_layer(12成员+九函数+九常量,draw_base入口)/cell_mark_overlay(13成员+六函数段+draw_centered_text单点化,四绘制入口),宿主退六步时序器类变量33→10(edge/cell/glow_group上收+glyph/glyph_color/plate/fog_state/_glow_layer冻结面原位+base/face两实例),board_view写入面49处改址(u.st.X→u.base./u.face./u.edge/u.glow_group,u.st.清零)〔状态件 V1/V2〕;逐字搬运+三处机械改写(st.X→裸成员/draw_X→canvas.draw_X/st.edge→rect.size.x),draw_glyph_layer增plate第5参(设计文档§2.1'plate绘制侧零消费'系413124b0恢复守卫前的过时实查——现行if plate:守卫在位,迁出即随行,保golden 0.00%零漂移);孤立验证:render_gate golden三张0.00%+run_all四套件全绿+run_smoke 15项0失败 2026-10-31 00:15:38 +08:00
105 changed files with 3856 additions and 3501 deletions

No files matched your search

+7 -15
View File
@@ -16,7 +16,7 @@
## 运行与验证(工作目录 = 含 project.godot 的切片目录)
- **合回验证 = 本地 CI(2026-10-30 用户裁)**:git merge 合回 master 落地后,post-merge 钩子(`tools/hooks/post-merge`)后台触发 `tools/ci_runner.sh` 跑一次全量域闸(调 `tools/run_all_gates.sh` 不带参数档,02 全套件),结果落 `game/tests/.gates/ci-status.json`(commit/绿红/红闸名单+关键日志行/耗时)+`ci-history.jsonl` 流水账;CI 红态下每个修复提交经 post-commit 钩子(`tools/hooks/post-commit`)自动追绿复验,绿态与无状态零触发——批内提交零钩子检查、合回只验一次,同一份字节禁止第二次人手跑。CI 红不回滚合并,红项在案、修复提交追绿;开工先读 CI 状态,红未修不开新批。跑批起手自动 `--editor --quit` 刷类名缓存(.godot 缓存不入 git,防合并后失配假红)。`tools/run_all_gates.sh` 仍是全部验证闸的**唯一入口与唯一清单,域划分与选闸算法只写在它这一个地方**,闸件增减与分域调整都只改它,文档禁另列清单;`--code`/`--docs`/`--quick` 手动档只服务开发期按域跑批(开发期窄测纪律见 process-conventions §6),不构成验收;全量回归由用户自发发起
- **合回验证 = 本地 CI(2026-10-30 用户裁)**:git merge 合回 master 落地后,post-merge 钩子(`tools/hooks/post-merge`)后台触发 `tools/ci_runner.sh` 跑一次全量域闸(调 `tools/run_all_gates.sh` 不带参数档,02 全套件),结果落 `game/tests/.gates/ci-status.json`(commit/绿红/红闸名单+关键日志行/耗时)+`ci-history.jsonl` 流水账;CI 红态下每个修复提交经 post-commit 钩子(`tools/hooks/post-commit`)自动追绿复验,绿态与无状态零触发——主区小批直提不重复跑全量,同一份字节禁止第二次人手跑。CI 红不回滚合并,红项在案、修复提交追绿;开工先读 CI 状态,红未修不开新批。跑批起手自动 `--editor --quit` 刷类名缓存(.godot 缓存不入 git,防合并后失配假红)。`tools/run_all_gates.sh` 仍是全部验证闸的**唯一入口与唯一清单,域划分与选闸算法只写在它这一个地方**,闸件增减与分域调整都只改它,文档禁另列清单;`--code`/`--docs`/`--quick` 手动档只服务开发期按域跑批(开发期窄测纪律见 process-conventions §6),不构成验收;全量回归由用户自发发起
- 单件直跑(调试期最窄确认用,**不构成验收**):冒烟测试 `python tools/run_smoke.py`(`game/tests/smoke_boot.tscn` 极小启动场景)· 系统测试 `python tools/run_system_test.py`(宿主 `game/tests/system_test.gd`)· 场景探针 `…console.exe --headless --path . res://probe/ui_probe.tscn` · 单元与集成 `… --script res://tests/run_all.gd`
- 调参批量:`--script res://sim/adventure_monte_carlo.gd`(全冒险期望)· `res://sim/reward_expectation.gd`(奖励期望);关卡完成率/难度类测量一律走全冒险
- 数值验证:`python tools/balance_verifier.py`(采集端 `res://sim/verifier_batch.gd`,报告与原始数据落 `sim-data/`)
@@ -40,7 +40,7 @@
| 时机 | 权威文档 |
|---|---|
| 批次开工 / 流程纪律 | `design/engineering/process-conventions.md`——车道铁律(一切改动走独立 worktree,主区只作合并落点)、合回后本地 CI、五段流水线、批次清单、测试两入口与 MC/闸机细则、像素纪律 |
| 批次开工 / 流程纪律 | `design/engineering/process-conventions.md`——车道铁律(主区直改+直提;大批约定走 worktree)、合回后本地 CI、五段流水线、批次清单、测试两入口与 MC/闸机细则、像素纪律 |
| 流水线段入口 | 技能对照——doc-design=文档设计(兼任反哺点落文)/asset-ingest=美术录入/req-card=写卡/iter-plan=迭代编排/iter=实现(五者均装于项目 `.zcode/skills/`);登记不立技能;批后收尾与中间文档退役=batch-closure(同一目录);格式与状态机权威=`design/engineering/doc-conventions.md` §12 |
| 定代码方案 / 写代码 / 改代码前 | `design/engineering/code-conventions.md`——结构/契约/语言/数值/流程五类硬纪律(反例库 = 同目录 code-conventions-cases.md) |
| 定测试方案 / 写测试 / 改测试前 | `design/engineering/test-conventions.md`——探针标配 / 回归断言 / 提交前验证 / 验收清单落码 |
@@ -77,15 +77,7 @@
### 格式优先级
能画图的内容一律画图说明,图是第一优先载体;枚举用列表,二维对照用表格;散文是最后手段。
### 图优先
**判据**:描述含多个实体、实体间有明确关系(先后顺序、包含、依赖、状态转移、布局对比)的内容时,直接画图说明,不写长段文字;单点事实(一句装得下)不画,纯数据对照用表格。
**载体**:用 diagram-design 技能出 HTML/SVG 内联交付(流程/状态/结构/实体关系与空间对比、像素级示意、界面草图同一通道),大图精修与导出用 archify 技能;查看端不支持内联渲染时用字符画。
**边界**:硬数值与前提条件留在文字里,图不承载唯一数值依据;图与文禁重复说同一件事,文字只留图说不清的部分。
枚举用列表,二维对照用表格,按内容形态选;散文是最后手段。
## 主动检索提醒
@@ -93,12 +85,12 @@
## 硬性红线(勿违反;操作细则在 process-conventions.md 与各规约)
- 车道铁律(2026-10-31 用户裁恢复)——主工作区只作合并落点,一切开发/设计改动走独立 worktree:`git worktree add ../g-plan2-<任务名> -b <任务分支>`(建区即跑 `tools/setup_worktree_userdir.sh`),收口=冻结→件核→并 master→重塑→主区 `git merge --no-ff`→CI 全量绿→删区,CI 红回任务 worktree 修复合回;主区唯一合法写动作=合并,agent 侧由 worktree-guard 拦主区 Edit/Write 与非 merge 提交;豁免面仅 `.zcode/`、`.qoder/`(不入 git,主区直改);commit 点零钩子检查(pre-commit 直改闸已退役),全量验证归合回后本地 CI(`tools/hooks/post-merge` 触发,见「运行与验证」首条);`--no-verify` 仅属用户,agent 禁用(细则见 process-conventions §1)
- 车道铁律(判据与改动域划分同一,按文件性质切;2026-10-30 用户裁本地 CI 化)——一切面(含代码面 `game/` 下非 `.md` 的行为载体与 `.zcode/`、`.qoder/` 等不入 git 面)主工作区直改+直提;commit 点由 git pre-commit 钩子(`tools/hooks/pre-commit`,`core.hooksPath` 挂载)现场跑文档域闸,绿落地红拦,合并收尾提交跳过(归合回后 CI);代码面全量验证归合回后本地 CI(`tools/hooks/post-merge` 触发,见「运行与验证」首条);大批次(迭代实现批等)按约定仍走独立 worktree(冻结→件核→并 master→重塑→主区合回→CI 验证),约定非强制;`--no-verify` 仅属用户,agent 禁用(细则见 process-conventions §1)
- **仓库根禁止设会话状态文件**(`active.md` 已废除)——现状看 roadmap「当前位」,待办看待办清单,过程看 git 提交信息,产出物看 `reports/`;任何文档禁止另设「当前状态快照」节,两处记同一件事必然漂移(细则见 doc-conventions 第 10 节)
- 测试执行两入口铁规——只有迭代 loop 开发与用户点名两个触发入口;其余会话零测试,需测试支撑先请示并注明未跑测
- 合回后验证 = 本地 CI 全量域闸全绿(唯一强制验证点;唯一入口、唯一闸清单、唯一域划分与选闸算法仍只在 `tools/run_all_gates.sh`,禁在文档另列;触发与追绿语义见「运行与验证」首条与 process-conventions §1)。开发期手动跑批按需选档(`--code` 关联档选测——02 跑「卡片申报 ∪ diff 推导」并集套件、三件保险恒跑、横切面回落全量——算法只在闸脚本内定义),手动跑不构成验收;全量回归由用户自发发起。文档面批与代码面批验收同走合回 CI 全量(`--docs` 仅属开发期手动档,process-conventions §1)
- **改动四类**——**需求改动**(游戏代码,含随逻辑写/改的测试代码):唯一走「写需求卡片+编入迭代批次」通道;迭代实现批禁写 `design/` 整个目录、两份根流程清单(`待办清单.md`/`体验验证清单.md`)与 `game/tests/README.md`(能力清单,归写卡段维护)(含新增/修改/删除),设计文档对它只读、是写测试与实现代码的输入依据;两份流程清单的条目状态只由流水线各段推进,实现批禁止顺手改;产出物只准写 `reports/`;合回后由本地 CI 全量验证(红项修复提交追绿,process-conventions §1)。**工程改动**(tools/、闸件、模拟测量工具、纯测试维护——不改变游戏行为的配套代码)、**文档设计改动**、**美术素材改动**:不写需求卡片、不编迭代批次,由用户发令走独立 worktree 直改+合回(车道铁律,commit 点零钩子检查);大体量改动(含触及代码面的工程改动如纯测试维护)同车道无特殊通道;文档设计类写入走 doc-design 技能(登记条目格式由流水线闸强制)
- 五段流水线铁律——**需求改动**(游戏代码)按「登记 → 文档设计/美术设计 → 写需求卡片 → 迭代编排 → 实现」五段推进,段间不自动流转、每段转进由用户发令;编入迭代的卡片必须设计闭合+零待裁点——需求卡片任何工作量皆可写、皆可编入迭代,工作量限制只属迭代层(迭代估时总量 <5 个工作日=「冻结待凑批」、不可开工);流水线闸 `tools/pipeline_gate.py` 强制(已注册进 run_all_gates.sh 文档域);实现段零裁断——卡片没写清=上游缺陷,停该卡退回上游,禁内联求裁(process-conventions §2,格式与状态机=doc-conventions §12)。工程/文档设计/美术素材三类改动不走写卡与编排段:(如需设计讨论)→ 用户发令 → 独立 worktree 直改 → 合回 CI(车道细则=process-conventions §1)
- 合回后验证 = 本地 CI 全量域闸全绿(唯一强制验证点;唯一入口、唯一闸清单、唯一域划分与选闸算法仍只在 `tools/run_all_gates.sh`,禁在文档另列;触发与追绿语义见「运行与验证」首条与 process-conventions §1)。开发期手动跑批按需选档(`--code` 关联档选测——02 跑「卡片申报 ∪ diff 推导」并集套件、三件保险恒跑、横切面回落全量——算法只在闸脚本内定义),手动跑不构成验收;全量回归由用户自发发起。文档面直改批验收=commit 点 git 钩子自动跑 `--docs`(process-conventions §1)
- **改动四类**——**需求改动**(游戏代码,含随逻辑写/改的测试代码):唯一走「写需求卡片+编入迭代批次」通道;迭代实现批禁写 `design/` 整个目录、两份根流程清单(`待办清单.md`/`体验验证清单.md`)与 `game/tests/README.md`(能力清单,归写卡段维护)(含新增/修改/删除),设计文档对它只读、是写测试与实现代码的输入依据;两份流程清单的条目状态只由流水线各段推进,实现批禁止顺手改;产出物只准写 `reports/`;合回后由本地 CI 全量验证(红项修复提交追绿,process-conventions §1)。**工程改动**(tools/、闸件、模拟测量工具、纯测试维护——不改变游戏行为的配套代码)、**文档设计改动**、**美术素材改动**:不写需求卡片、不编迭代批次,登记在案后由用户发令在主工作区直改+直提(commit 点 git 钩子自动跑文档域闸),完成即删条目;大体量改动(含触及代码面的工程改动如纯测试维护)按约定走 worktree 批(非强制);文档设计类写入走 doc-design 技能(登记条目格式由流水线闸强制)
- 五段流水线铁律——**需求改动**(游戏代码)按「登记 → 文档设计/美术设计 → 写需求卡片 → 迭代编排 → 实现」五段推进,段间不自动流转、每段转进由用户发令;编入迭代的卡片必须设计闭合+零待裁点——需求卡片任何工作量皆可写、皆可编入迭代,工作量限制只属迭代层(迭代估时总量 <5 个工作日=「冻结待凑批」、不可开工);流水线闸 `tools/pipeline_gate.py` 强制(已注册进 run_all_gates.sh 文档域);实现段零裁断——卡片没写清=上游缺陷,停该卡退回上游,禁内联求裁(process-conventions §2,格式与状态机=doc-conventions §12)。工程/文档设计/美术素材三类改动不走写卡与编排段:登记 →(如需设计讨论)→ 用户发令直改 → 主区直改+commit 点闸 → 完成删条目(车道细则=process-conventions §1)
- MC/模拟:无数值改动零跑;档位硬闸见 `sim-data/README.md`「MC 采集档位表」,一档只能由用户发起
- 闸机轮次纪律:新码先孤立验证 → 出红只跑红件最小单元 → 长批先最小参数试车 → 开工扫坑册(process-conventions §6)
- **验收闭合**——每个需求点与每个行为改动都要有从真实入口进入的验收断言,可 grep 定位、在当轮真实跑批中执行并通过,判据绑被测改动特有的可观测提交面;**禁变异类测试与撤销类取证**(2026-10-24/2026-10-28 用户裁——人为制造红属伪造证据),证明做不出=停卡呈报;禁删断言/放宽阈值换绿;合回前独立验收审计未过则禁止合并(细则=test-conventions §8+iter 技能第 5 步)
+3 -8
View File
@@ -130,7 +130,7 @@
### 3.5 营地场景图
- **要什么**:营地场景图 10 张——`scene_camp_bg`(背景层,不透明全幅=天空+远山+整片地面+门洞内一条通向远处的小路)+ `scene_camp_wall`(围墙层,透明底=横贯全宽密排木桩墙+两根门柱,门洞留透明缺口)+ `scene_camp_gate / forge / chest / notebook / dummy / board / campfire`(七个可点物件)+ `scene_camp_tent`(承载件)。钥石顶栏图标沿用现役 `icon_keystone`。
- **要什么**:营地场景图 9 张——`scene_camp_bg`(背景)+ `scene_camp_gate / forge / chest / notebook / dummy / board / campfire`(七个可点物件)+ `scene_camp_tent`(承载件)。钥石顶栏图标沿用现役 `icon_keystone`。
- **来源/规格**:**✦ 插画级**(作者自跑远程生图管线);烛光黄 `#F6C667` + 木色 `#8A5A34`(art-bible §6.2);2× 源档出图、最近邻降采样到 1280×800;后处理=抠底/降采样/色板量化/描边统一。**出图登记照 [remote-gen-prompts](remote-gen-prompts.md) 头注轻量口径执行:用途+生成时间必注,其余参数有则记。**
- **排期**:营地交互重做**美术自立批**(不占迭代位;UI 贴图重构批已搁置)。终稿落 `game/assets/art/scene/`,消费常量 `UiKit.TEX_CAMP_*`。
- **现状**:全占位。
@@ -155,18 +155,13 @@
| 资产 | 需求 | 风格/规格要点 | 来源 |
|---|---|---|---|
| 受击反馈 / 死亡表现 / 顺位标记 | 敌人系统登记的资产需求**下限三类** | 死亡=血条归零后**灰化+碎裂退场,禁止瞬间消失**;顺位标记需在敌多时可读 | ⚙/✦ 挂自产精灵——死亡灰化碎裂是语义硬规则,不可整包复用;烟尘碎屑粒子可 ♻ 改色 |
| B 区舞台背景层 `scene_stage_bg_dungeon.png` | 战斗舞台背景·dungeon 变体(art-bible §6.1 资产契约) | **✦ 插画级**;源 = 基准屏宽 × `stage_h`(读布局表 `battle_layout.tres`)、B 区全高、显示 1×;顶部空区+纵深洞厅远景(远/中/近三层;暖石棕、宽岩台/层理、地精巢穴支洞/木栈道/木桩围栏),不画近景地面;按 `board_type` 选图,不走 `wall_ambient` tint | ✦ 插画级(作者自跑远程生图管线) |
| B 区舞台背景层 `scene_stage_bg_underdark.png` | 战斗舞台背景·underdark 变体(art-bible §6.1 资产契约) | **✦ 插画级**;源 = 基准屏宽 × `stage_h`、B 区全高、显示 1×;顶部空区+纵深洞厅远景(远/中/近三层;冷蓝灰、巨柱/石笋/蛛网/螺旋塔剪影/巨菇/石桥),不画近景地面;按 `board_type` 选图,不走 `wall_ambient` tint | ✦ 插画级(作者自跑远程生图管线) |
| B 区舞台背景层 `scene_stage_bg_deep_underdark.png` | 战斗舞台背景·deep_underdark 变体(art-bible §6.1 资产契约) | **✦ 插画级**;源 = 基准屏宽 × `stage_h`、B 区全高、显示 1×;顶部空区+纵深洞厅远景(远/中/近三层;灰黑、石笋城郭/棱角石厅/石桥/矿道口/烟囱塔、冷银/铜灰矿脉),不画近景地面;按 `board_type` 选图,不走 `wall_ambient` tint | ✦ 插画级(作者自跑远程生图管线) |
| B 区连续近景地面层 `scene_stage_ground.png` | 近景泥土地面层(art-bible §6.1 图层归属) | **✦ 插画级**;源 = 基准屏宽 × `ground_h`(布局表新增字段);干净压实泥土为主、全幅只零星几颗小石、散点分布,顶缘不规则泥土边/阴影缝作分隔带;三关共用、跨三关恒定、不吃 `wall_ambient`;独立层压在 B 区底部,小石台在其上 | ✦ 插画级(作者自跑远程生图管线) |
| 站桩石板地台件 `scene_stage_plaza.png` | 近景地台独立件(art-bible §6.1/§8.2) | 源 48×12、九宫格横向拉伸、顶缘受光线 2px 不随拉伸变形;跨三关恒定,不吃 `wall_ambient` tint;连续地面层在其下方,先保留 | ⚙/✦ 自产 |
| B 区舞台背景插画 `scene_stage_bg.png` | 战斗舞台背景(art-bible §6.1 资产契约) | **✦ 插画级**;源 1280×270、B 区全高含明细带底、显示 1×;**只出远景 + 中景两带**(近景带在结算期被 84px 明细带底整条盖住);三关换挡走 §4.3 `wall_ambient` tint 槽,不按板出三张 | ✦ 插画级(作者自跑远程生图管线) |
| 站桩石板地台件 `scene_stage_plaza.png` | 近景地台独立件(art-bible §6.1/§8.2) | 源 48×12、九宫格横向拉伸、顶缘受光线 2px 不随拉伸变形;跨三关恒定,不吃 `wall_ambient` tint | ⚙/✦ 自产 |
| 特殊技动画终稿 | 并入 §2.3 三档意图动画,不另起体系 | 攻/防两型旧口径由三档替代 | ✦/⚙ 自产(同 §2.3) |
| 连锁坍塌显形演出 | 连锁展开触发时的连锁演出 | 与音频方向同批配对登记;「坍塌显形」=连锁展开的玩家可见名 | ♻ 粒子/碎块改色 + ⚙ 坍塌结构自产 |
| 封印特效 | 该动作的呈现名 = **封印**(art-bible §3.2):**施印瞬间特效 + 印记常显形态**两件 | 印记旗面走封印黑 `#000000`(现行封印色,色史归 art-bible §4.1);特效走运动+色相(§2:状态/情绪不走明度,空间光照可走);现行占位 = 封印黑「旗」字形;印记常显形态可与 §3.3 旗面像素化合并出 | ✦/⚙ 自产(精灵+粒子,烟尘光点可 ♻ 改色) |
| 弹道/退场等动画密度 | 战斗表现输入清单,方案未定 | 样张锁动画方案后启动 | ♻ 通用弹道/光点/消散粒子改色为主 |
**现状**:三关舞台背景层与连续地面层已交付(2026-10-31 入包 `game/assets/art/scene/`:dungeon v10c / underdark v10c / deep_underdark v10c,均 1280×252;共用地面 v12b,1280×100,按作者裁保留原亮度 L≈0.132);小石台件已在役。
---
## 5. 明确不在本清单
+12 -17
View File
@@ -1,6 +1,6 @@
# 美术圣经(Art Bible)— Dungeon Sweeper
> 项目:Dungeon Sweeper(扫雷 × 自动战斗 闯关 Roguelike)· 状态:**第 1–9 节定稿**;现行为 v3.30,历次修订明细见 git 提交史
> 项目:Dungeon Sweeper(扫雷 × 自动战斗 闯关 Roguelike)· 状态:**第 1–9 节定稿**;现行为 v3.23,历次修订明细见 git 提交史
>
> **Art Director Sign-Off(AD-ART-BIBLE)**:历次批均未签核——此为 Lean/Solo 模式(非 PHASE-GATE)下的现行治理状态;full 门禁签核时机待用户表态。
> 风格基调:地牢题材但**非暗黑风**——轻快明亮的幻想冒险风,全年龄;像素风;角色 2~3 头身。
@@ -212,7 +212,7 @@
- **重甲冷灰金属材质色 `#868C9A`(ARMOR_PLATE_COLD,token 名暂拟、随实装批登记)**|语义/UI token 板(**分层①**,占 1 枚额度,**余量 2→1**;用户裁):重甲档甲材质色;character-design §5.3 通道 = 甲面覆盖率 × 甲材质色,甲材质色按甲档统一,故石君王岩石板甲**同引本枚、不另计额度**;材质色跨屏恒定,落分层①不落分层②(环境色才随场景走)。过门情况:第二道门按宽松口径(禁止三通道全 <8)与在册色逐一比对,**无三通道全 <8 的对 → 过门**;§4.2 语义检查过门(色相 222°,不占红/金/蓝/紫赤/绿语义段、不在 300°–345° 禁入带;材质色不进信息层与语义物件岗)。对比实测:对深素底 `#282220` 4.65:1、对舞台底 `#3E362C` 3.52:1(图形 ≥3:1 门槛);相对亮度 L≈0.261 落 §2 世界中层 0.22–0.45 带。验收:机检〈本值入板后全板色对中三通道差全部 <8/255 的对数 = 0〉
- **卓尔浅紫灰皮 `#A79CB8`(DRIDER_SKIN,token 名暂拟、随实装批登记)**|语义/UI token 板(**分层①**,占 1 枚额度,**余量 1→0,额度用尽**;用户裁):蛛化卓尔精灵上体皮色(体块主色,L≈0.355 落 §2 世界中层带)。过门情况:第二道门同上行口径,**无三通道全 <8 的对 → 过门**;§4.2 语义检查过门(色相 264°,避开 300°–345° 禁入带,紫赤独占仍归 `#8F2F6A`;不占本节五语义段)。对比实测:对深素底 `#282220` **6.04:1**、对舞台底 `#3E362C` **4.57:1**——**两处均过图形 ≥3:1 门槛**(本轮新算)。验收:机检〈本值入板后全板色对中三通道差全部 <8/255 的对数 = 0〉
- **换色合并登记五处(用户裁,部件色落值)**|按本表「不过门即触发换色合并、禁加色绕行」执行,五处**零新增额度**(各件原拟新增候选一律不取):① 主角铲刃浅铁灰(原拟 `#A8AEB8`)→ 并入 `FOG_MEMORY_INK #C4C4C4`,**部件取值 = `#C4C4C4`**;② 主角提灯铜色(原拟 `#C08A3A`)→ 并入 `GOLD_DEEP #B07A14`,**部件取值 = `#B07A14`**;③ 食人魔酋长暖褐皮(原拟 `#B08050` / `#A97C4E`)→ 并入 `暖石 #B8A582`,**部件取值 = `#B8A582`**;④ 石君王灰皮(原拟 `#9A968C` / `#949089`,按**次级皮**口径——板甲视同体块主色、灰皮属次级皮故不受 L 0.22–0.45 约束)→ 并入 `STONE #786E62`,**部件取值 = `#786E62`**;⑤ 轻甲护甲图标木色 `#8A5A34`(深素底下 2.72:1 不过门;原拟新增木色亮档 `#C49A5E`)→ 并入 `WARM_FAINT #CDB88C`,**部件取值 = `#CDB88C`**(8.08:1)。**一色两岗代价已随裁定接受**:① 的 `#C4C4C4` 语义岗 = 迷雾记忆墨(§6.5)、② 的 `#B07A14` 属金族(§4.2 金只说收益与兑现)——两者均作角色随身件材质色用,不进信息层与语义物件岗;③④⑤ 无语义岗冲突。验收:机检〈五处部件取值点全部改指合并目标色,四枚原拟新增候选值零入板〉
- **换色合并登记三处**|按本表「不过门即触发换色合并、禁加色绕行」执行,三处零新增额度:①`#C4AC84`(地台顶缘受光线,代码 `STAND_STONE_RIM`)→ 并入 `#C9AF83`(掩尘,并与 §8.2 高墙口沿高光 `Color8(196,172,132)` 统一为同一枚);②`#5A4C3A`(地台描边,代码 `STAND_STONE_EDGE`)→ 并入 `#4C4038`;③`#3E342A`(舞台底,代码 `STAGE_BG`)→ 并入 `#3E362C`(状态槽底)。①②的绘制点全部改指合并目标色、源常量删除——程序化回退绘制与已落合并值的贴图保持一致;③随 §6.1 舞台背景插画批一并处置:背景资产接管该绘制面时本常量随绘制点退役或改指,禁单独为改值出批。验收:机检〈①②两枚源常量全仓零引用,绘制点全部改指合并目标色〉
- **换色合并登记三处**|按本表「不过门即触发换色合并、禁加色绕行」执行,三处零新增额度:`#3E342A`(舞台底,代码 `STAGE_BG`)→ 并入 `#3E362C`(状态槽底);`#C4AC84`(地台顶缘受光线,代码 `STAND_STONE_RIM`)→ 并入 `#C9AF83`(掩尘,并与 §8.2 高墙口沿高光 `Color8(196,172,132)` 统一为同一枚);`#5A4C3A`(地台描边,代码 `STAND_STONE_EDGE`)→ 并入 `#4C4038`。验收:机检〈全仓三枚源常量零引用,绘制点全部改指合并目标色〉
**对比硬指标(可测)**:数字可读性由**格底明度分档**承载——棋盘数字亮墨 **L≥0.75** 对**已开格底 L 0.08–0.14** ⇒ 直画对比 **≥4.5:1 恒成立**(WCAG AA,样张逐组合抽测冻结);**色牌后备**:色牌素色恒定 **L≥0.70**、牌上数字深墨 **L≤0.027** ⇒ 任意牌墨组合 ≥4.5:1(实测样例:#33261B/#F5EAD3 = 12.3:1)。未开格底槽(含全部图类型)相对亮度 **L≥0.30**(墙顶面受光档)、HSV 饱和 **≤0.55**、避 Boss 禁入色相带;已开格底走世界底层档(见上)。物件识别不依赖格底(§5.1 轮廓通道),旗面、金色不作识别依赖。验收:机检〈亮墨对已开格底 ≥4.5:1;未开格底 L≥0.30、饱和 ≤0.55;任意牌墨组合 ≥4.5:1〉 ←原二;地形变异 AC-9
@@ -376,21 +376,17 @@
### 6.1 战斗舞台背景(B 区环境)
- **双舞台常驻下的 B 区环境**:战斗画面区(站桩立绘所在)的背景 = 明亮地窟,与 §1 风格基调同源——暖倾向、无压抑;背景整体**低对比自然后退**(§3.4 焦点预算延伸):背景禁止构成完整凸形、禁止抢 B 区立绘与 D 区数字的焦点,识别层级恒为 立绘 > 背景。验收:目检〈背景无完整凸形、立绘最抢眼〉
- **舞台正面目标**:B 区 = **地窟看台**——立绘脚下地台/落影承载(世界中层),背景环境层低饱和后退、明度走世界底层档;角色禁止直接贴平色底。规格与终值归整屏样张闸(§1.4)冻结。**地台面上零文字**——暖白 `#F0E2C8` 对地台板身 `#968264` 实测仅 2.89:1,已越 §7.2 的 4.5:1 硬指标,落法按 §7.2「文字禁直接压纹理底」(垫容器、素牌或罩层),非新条款;站桩文字位改垫素底或落进结算明细带(实装=站桩名字行垫 `HP_BAR_BACK` 深档素底牌、文字基线上移至地台顶上方——2026-10-30 落地)。验收:目检〈立绘脚下有地台/落影,非贴平色底〉+机检〈B 区站桩文字位正下方像素非地台板身色 #968264〉
- **舞台正面目标**:B 区 = **地窟看台**——立绘脚下地台/落影承载(世界中层),背景环境层低饱和后退、明度走世界底层档,允许光源氛围(洞顶光柱/暖光晕候选);角色禁止直接贴平色底。规格与终值归整屏样张闸(§1.4)冻结。**地台面上零文字**——暖白 `#F0E2C8` 对地台板身 `#968264` 实测仅 2.89:1,已越 §7.2 的 4.5:1 硬指标,落法按 §7.2「文字禁直接压纹理底」(垫容器、素牌或罩层),非新条款;站桩文字位改垫素底或落进结算明细带(实装=站桩名字行垫 `HP_BAR_BACK` 深档素底牌、文字基线上移至地台顶上方——2026-10-30 落地)。验收:目检〈立绘脚下有地台/落影,非贴平色底〉+机检〈B 区站桩文字位正下方像素非地台板身色 #968264〉
- **明度分层适用**:背景氛围的情绪表达仍禁止以压暗/渐晕实现(§2 禁令);空间纵深与洞穴感走明度分层允许域——世界底层档、光照氛围、色相饱和与形体承载(§3.2 同款逻辑)。验收:方向性
- **图类型联动**:背景层按 `board_type` 选三张变体(`scene_stage_bg_dungeon.png` / `scene_stage_bg_underdark.png` / `scene_stage_bg_deep_underdark.png`,方向取 §6.3 三关色板候选);**背景不再走 §4.3 `wall_ambient` tint**(该槽保留给棋盘/世界的墙雾氛围,避免对三张背景二次染色)。紫赤仅 Boss 战允许短暂进入背景氛围纹样(§2.6 色相独占的舞台侧延伸,高饱和独占不变),非 Boss 战高饱和紫赤禁入。验收:机检〈背景吸色无非 Boss 高饱和紫赤;背景素材不引用 `wall_ambient` 槽〉
- **场景构成(2026-10-31 用户裁)**:B 区舞台从远到近分三段——**顶部空区**:洞顶以上的昏暗空间,只留深色空区,**不画钟乳石、吊锥、悬挂物或任何可辨形状**;**远景(纵深洞厅)**:不是贴墙的后壁,按远/中/近三层组织——远层暗剪影(远处洞口/通道、层叠岩体、洞底轮廓)、中层主要细节层(岩台、岩柱、凹壁、裂缝)、近层左右暗色岩框;剪影被中层部分遮挡、不贴顶、不孤立,**禁贴墙感、禁单件圆柱贴顶、禁砖石墙/规则砌缝/方整石块**;三关母题(地精=支洞/木栈道/木桩围栏;卓尔=巨柱/石笋/蛛网/螺旋塔剪影/巨菇/石桥;灰矮人=石笋城郭/棱角石厅/石桥/矿道口/烟囱塔)见 `battle-stage-prompts.md` §3.2;**分隔带**:远壁根部与近景地面之间一条不规则碎石带/阴影缝,边界清楚但不笔直,**禁瓷砖缝、踢脚线、规则台阶**;**近景地面**:干净压实泥土为主,全幅只零星几颗小石、散点分布,中央平缓留空给角色站位,**禁成排/成堆碎石、满铺砂砾、泥点噪声、瓷砖、规则铺装、草、木地板**。纵深与三段构图归 §1.4 样张;逐条要素、分层提示词与否定后缀 = `battle-stage-prompts.md`(本文件不重复维护)。验收:目检〈顶部无钟乳石/吊锥;远景有纵深、非贴墙;无孤立圆柱贴顶;近景为泥土碎石;分隔带不规则;中央无大障碍〉
- **图层归属(2026-10-31 用户裁)**:背景层 = 三关变体 `scene_stage_bg_dungeon/_underdark/_deep_underdark.png`(顶部空区+纵深洞厅远景,不画近景地面;按 `board_type` 选一张);近景地面 = **独立连续地面层** `scene_stage_ground.png`(泥土/砂砾/碎石地面,全宽、底边贴 B 区底、顶缘即分隔带;高度读布局表 `ground_h`,字段由地面层实装批新增并回填,本批终稿高 100、代码批落表);现有每角色小石台 `scene_stage_plaza.png` 保留,叠在连续地面之上。连续地面层与小石台**三关共用**、跨关恒定、**不吃 `wall_ambient` tint**(世界中层承载面随关卡换明度会破 §2 层间关系);背景三张变体各自带关卡色族,不再叠 tint。验收:机检〈三张背景文件名带 board_type 后缀;地面层/小石台文件名无 board_type 后缀;背景与地面层均不引用 `wall_ambient` 槽〉
- **资产渠道与契约**:✦ 插画级(演出类场景贴图,清单 §4 联动登记);战斗一屏样张(§1.4 清单 1.2)含背景出样。**背景层 = 三张按关卡变体** `scene_stage_bg_dungeon.png` / `scene_stage_bg_underdark.png` / `scene_stage_bg_deep_underdark.png`(源 = 基准屏宽 × `stage_h`,读布局表 `game/data/tables/battle_layout.tres`;显示 1×;按 `board_type` 选图;**不走 `wall_ambient` tint**);三张共用本节构图规则,仅岩体形态与色族按 §6.3 三关方向不同。**背景只画顶部空区+纵深洞厅远景,不画近景地面**:结算期明细带整条压住 B 区底带(带高 = `log_band_h_settle`,读布局表),近景地面在独立层;画进背景等于画一件永远看不见、且会随背景变体重复的东西。**连续地面层** = `scene_stage_ground.png`(源 = 基准屏宽 × `ground_h`,读布局表;显示 1×;三关共用、跨关恒定、不吃 tint);地面层是极宽薄条,出图与后处理按 `battle-stage-prompts.md` §2.2 的工艺(可平铺纹理条/最宽档裁切,禁横向拉伸)。**光柱不迁入背景**:三张背景均不画光柱/光带/光束/光晕与任何光源实体,明暗只由岩体层理与暗部承载;现行四柱程序层是临时占位,资产到位后直接退役(代码批)。资产已入包(2026-10-31),四柱程序层与平色底由代码批退役/改指;出图工单 = `battle-stage-prompts.md`,交付记录见本节「B 区舞台背景与共用地面的交付绑定」。验收:目检〈三关背景可辨为不同洞窟,非同一图换色;远景有纵深、非贴墙;无孤立圆柱贴顶;背景无地台/地面结构件、无砖石墙、无瓷砖地面、无光柱/光带;地面层为泥土/砂砾/碎石〉
- **B 区舞台背景与共用地面的交付绑定(2026-10-31 入包)**:三张背景与一张地面已按本节契约入包 `game/assets/art/scene/`——`scene_stage_bg_dungeon.png` / `scene_stage_bg_underdark.png` / `scene_stage_bg_deep_underdark.png` 均 1280×252、不透明全幅、单张 ≤32 色、按 `board_type` 选图;`scene_stage_ground.png` 1280×100、顶缘以上透明、单张 ≤32 色、三关共用。地面按作者 2026-10-31 裁保留候选 v12b 原亮度(实测不透明域 L≈0.132,低于 §2 世界中层 0.22–0.45,登记为作者例外;后续调亮归调参/替换,不重开设计);背景实测 L:dungeon 0.0148、underdark 0.0132、deep_underdark 0.0111(后两者低于世界底层下沿带下限 0.014 不超过 0.003,登记读数)。验收:机检〈四件文件名与尺寸逐位相符;地面顶缘以上 alpha=0、不透明域 ≤32 色;背景不透明全幅 ≤32 色〉+目检〈三关可辨、无光柱、地面读作泥土〉。参考指针:`asset-path-map.md` `scene/` 行、`battle-stage-prompts.md` §2/§4。
- **近景地面与地台走独立件**:连续地面层 `scene_stage_ground.png` 与角色脚下小石台 `scene_stage_plaza.png` 均为独立层,三关共用、跨关恒定。小石台源 48×12、九宫格横向拉伸、顶缘受光线 2px 不随拉伸变形(规格见 §8.2);连续地面层的顶缘即分隔带(不规则碎石/阴影缝,不是直线亮边)。独立的两条理由——① 三张背景按关卡变体,地面若画进任一背景就得三张各画一遍、且三关站位面会漂移;② 结算期明细带整条压住底带(带高读 `log_band_h_settle`),地面在独立层才能跨关恒定并保持世界中层承载面不变。小石台先保留,是否退役归实装批/后续裁决。验收:机检〈地台件按九宫格拉伸后顶缘受光线宽度恒为 2px〉+目检〈连续地面为泥土碎石、顶缘不规则〉
- **图类型联动**:背景 tint 走 §4.3 `wall_ambient` 槽,随三关换挡(方向候选见 §6.3);紫赤仅 Boss 战允许短暂进入背景氛围纹样(§2.6 色相独占的舞台侧延伸,高饱和独占不变),非 Boss 战高饱和紫赤禁入。验收:机检〈背景吸色无非 Boss 高饱和紫赤〉
- **资产渠道**:✦ 插画级(演出类场景贴图,清单 §4 联动登记);战斗一屏样张(§1.4 清单 1.2)含背景出样。**资产契约(尺寸候选,样张冻结终稿)**:基准一张 = `scene_stage_bg.png`(源 1280×270,B 区全高含明细带底;三关换挡走 §4.3 `wall_ambient` tint 槽,不按板出三张——换皮成本复用棋盘同款逻辑),显示 1×;呈现约束按本节各条(低对比后退/明度世界底层档/光柱氛围保留)。程序化平色+光柱现行使用 = 占位;插画工单归 PRD,交付后 art-status-checklist 同步 ✅。**出图只出远景 + 中景两带**:结算期明细带底 84px 会盖住 B 区 78%–100% 段(约 59px),近景带在结算期整条不可见——画进背景等于画一件永远看不见的东西。远景/中景的构图占比归整屏样张(§1.4)。验收:目检〈背景插画内零地台结构件〉
- **近景地台走独立件**:`scene_stage_plaza.png`,源 48×12、九宫格横向拉伸、顶缘受光线 2px 不随拉伸变形(规格见 §8.2)。独立的两条理由——① 上条的 84px > 59px 覆盖账;② §4.3 `wall_ambient` tint 作用于整张背景,地台若画进背景会随三关换明度,而 §6.1 舞台正面目标把地台定死为世界中层承载面,随关卡变会破 §2 明度分层的层间关系。独立件跨关恒定。验收:机检〈地台件按九宫格拉伸后顶缘受光线宽度恒为 2px〉
### 6.2 营地场景
- **情绪与色域**:承载 §2.8——全作最暖:烛光黄 `#F6C667` × 木色 `#8A5A34`(§7.2),中等饱和,无棋盘式高对比。
- **场景构成**:一张可点击的营地场景图(1280×800,与工程档同幅面)。远景=天空与远山;中景=**独立成层的木围墙**(密排竖木桩、桩顶削尖、不透缝无横木)与**半开的营地大门**;近景=中央篝火、左侧锻炉铁砧、右侧帐篷与宝箱、帐篷旁的笔记本,另有木桩与挂在围墙上的布告板。**中景带自底部往上约 2/3 处起**;**近景物件可覆盖围墙,唯一例外=中间门洞必须留空、不被任何物件遮挡**。七个可点物件的功能绑定归 `camp.md`,本节只定画法。
- **图层拆分(10 张)**:场景按「远景/中景/近景要素各自成层」拆——`scene_camp_bg` 背景层(z0,不透明全幅)=天空+远山+整片地面+门洞内一条通向远处的小路;`scene_camp_wall` 围墙层(z1,透明底)=横贯全宽密排木桩墙(左右两段)+两根略高的门柱,**门洞处留透明缺口**透出背景层的小路;`scene_camp_board` 布告板(z2)、`scene_camp_gate` 门扇(z3)、`scene_camp_dummy` 木桩/`scene_camp_forge` 锻炉/`scene_camp_tent` 帐篷(z4)、`scene_camp_chest` 宝箱/`scene_camp_notebook` 笔记本(z5)、`scene_camp_campfire` 篝火(z6,最前)=八个物件层,各透明底单件一张。**帐篷**为承载件、不可点。围墙独立成层的好处:桩高可单独锁死、门洞做透明缺口、背景层不混入暖木色。提示词与坐标 = `camp-scene-prompts.md`,消费常量 = `asset-path-map`。
- **交付形态**:**背景层 1 张(不透明全幅)+ 围墙层 1 张 + 八个物件层 = 10 张**,其中 9 张透明底、1 张不透明全幅 + 一份坐标表(贴图矩形/命中矩形/z 序)。**篝火例外**:命中矩形只取下半(火堆),上半(火焰)只作特效展示。围墙层落盘按细条 `(0, 240, 1280, 70)` 裁,不做全幅(全幅约 3.9 MB 显存,细条约 0.35 MB)。
- **场景构成**:一张可点击的营地场景图(1280×800,与工程档同幅面)。远景=天空与远山;中景=木围墙(密排竖木桩、桩顶削尖、不透缝无横木)与**半开的营地大门**(门洞内一条通向远处的小路);近景=中央篝火、左侧锻炉铁砧、右侧帐篷与宝箱、帐篷旁的笔记本,另有木桩与挂在围墙上的布告板。**中景带自底部往上约 2/3 处起**;**近景物件可覆盖围墙(围墙是纯背景板),唯一例外=中间门洞必须留空、不被任何物件遮挡**。七个可点物件的功能绑定归 `camp.md`,本节只定画法。
- **交付形态**:**背景 1 层 + 七个物件各 1 层**(**帐篷**为承载件、不可点),共 8 张透明 PNG + 一份坐标表(贴图矩形/命中矩形/z 序)。**篝火例外**:命中矩形只取下半(火堆),上半(火焰)只作特效展示。
- **色彩与氛围依据**:营地场景的冷暖分工(冷的大面积后退、暖的小面积前进)、空气透视三档与大面积用色规则 = `reports/提案-营地色彩与氛围脚本-2026-10-23.md`。本节不复述色值;新增环境色按 §4.1 场景环境子板条款登记(每屏一套、≤32 色、过 §4.2 语义检查与 RGB 三通道差 ≥8/255 两道门)。
- **交互四态(零新素材,全部程序化)**:悬停=**轮廓亮边 + 浮动**(浮动须整像素吸附);按下=位移 1px;**禁用/未解锁=降明度 + 去饱和**(§2 已缩窄至情绪域,状态表达不受限),**仅锻炉(锻造工坊)与宝箱(秘宝匣)两件会有此态**;已解锁=常态。
- **钥石余额**:常驻画面顶部的一行小 HUD 栏(高 48px,**浮层覆盖,不挤压画面**)。
@@ -400,7 +396,6 @@
### 6.3 三关图类型色板候选(board_type 换挡方向)
- **模板与不变槽**:换皮只换 §4.3 四槽(`tile_closed`/`tile_open`/`wall_ambient`/`variant_tint`),信息与语义层全图类型恒定——本节只给三关**方向性候选**,终值按 §4.3 现行规则重跑 §1.4 格子样张冻结。**终值的取值程序**:先跑「三关色相 × 五组类型微光」互辨抽测(抽测任务登记在待办清单),再按 §4.3 现行规则重跑 §1.4 格子样张冻结——本节不填终值色值,待该抽测与格子样张重跑后落本节修订。验收:机检〈本节三关行无 `tile_closed`/`wall_ambient` 终值色值字面量(终值未冻结前禁填)〉
- **三关背景变体**:§6.1 的三张背景取本节三关方向作为岩体形态、剪影语言与色族差异(dungeon 暖石棕+地精巢穴支洞/木栈道/木桩围栏;underdark 冷蓝灰+卓尔巨柱/石笋/蛛网/螺旋塔剪影/巨菇/石桥;deep_underdark 灰黑+灰矮人石笋城郭/棱角石厅/矿道口/烟囱塔);背景不复用 `wall_ambient` tint(该槽作用于棋盘/世界),背景色值归战斗屏场景环境子板。验收:目检〈三关背景可辨为不同洞窟,非同一图换色〉
- **深度轴叙事**(§2.7 下探过渡):色相层进预告「更深更险」,明度档不动——
- **dungeon 地精洞窟**(第一关):现行掩尘系暖石棕(`#C9AF83` 基)即基准档,`wall_ambient` 暖棕;
- **underdark 幽暗地域**(第二关;方向:**冷调幽暗**):主调**灰白蓝**候选(低饱和蓝灰域,`tile_closed`),少量紫黑倾向点缀——紫系取紫罗兰域(≈256°)候选,禁入带 300°–345° 不变;`wall_ambient` 冷蓝灰;
@@ -452,7 +447,7 @@
### 7.3 布局栅格
- **结构**:双舞台三区(B 战斗画面/C 数据框/D 棋盘;字母保持不重编)为结构冻结项,分区几何的唯一事实源 = `game/data/tables/battle_layout.tres`,分区尺寸与像素级裁决归 battle.md(HUD框架只载 1280×800 基座口径,不复写数值)。验收:机检〈三区结构常驻〉
- **结构**:双舞台三区(B 战斗画面/C 数据框/D 棋盘;字母保持不重编)为结构冻结项,分区尺寸与像素级裁决归 battle.md(HUD框架承载 1280×800 基座锚点值,如扫雷图区 1036×504、结算明细带展开 84px)。验收:机检〈三区结构常驻〉
- **栅格规则(候选)**:面板间距/内边距按 4px 步进档(8/12/16/24 候选),全 UI 恒定;数据区直角细线不占圆角预算。终值归样张。验收:目检〈间距落在步进档〉
### 7.4 字体与字号
@@ -460,7 +455,7 @@
- **字体**:全局一套像素字,单套即终稿——缝合像素字体 Fusion Pixel(OFL,已接入 `game/assets/fonts/ui_font_fusion_pixel_zh_hans.ttf`),拉丁字符与数字沿用其自带拉丁字形,不另设拉丁专件(现状即终稿;旧拉丁候选 Kenney Fonts 已弃;生产工单=清单 §3.6);墨色走主墨系(§7.2);换字体 = 全局决策。验收:机检〈主题字体指向 Fusion Pixel 件〉
- **字号**:像素字体**整数倍缩放,禁非整数缩放**(像素模糊);下限(1280×800 基座):棋盘数字 ≥18px(公式 = `max(18, ceil(格边长 × 0.5))`不变)、**正文/明细 ≥16px、tooltip ≥14px**(1280×800 低于 1080p 基准,同字号实际更小)。验收:机检〈静态文字位点字号 ≥ 档位表值〉
- **字号档位表(六档)**:全站 UI 文字字号只经 `UiKit.FS_*` 单点取值,裸数字字号弃用——`FS_CAPTION 12`/`FS_HINT 14`/`FS_BODY 16`/`FS_SUB 18`/`FS_TITLE 24`/`FS_H1 34`。旧实测档按就近归档收编(10/11/12→CAPTION、13/14→HINT、15/16→BODY、17/18/20→SUB、21/22/24/26→TITLE、32/40→H1;静态位点全归档,数据驱动动态字号位点除外);棋盘数字公式 `maxi(18, ceil(格边长×0.5))` 与站桩血数 11px(条带内读数豁免)不入表。注:六档相邻比 12→14→16→18 三段 <1.25×,系裁决值优先于字重纪律的档差参考线,该参考线对新层级设计仍有效。验收:机检〈全站无裸数字字号,位点走 FS_*〉
- **小字号豁免条款(合并单条不开两口子)**:下款两类**豁免于本节下限**——①**条带内读数**:压在窄条带(血条/进度条等 ≤12px 高带)内居中的数字,受条带高度物理约束,维持 11px 下限,且必须按 §7.2 垫素色牌后计对比(实装=B 区站桩血数 11px 压 HP_BAR_BACK 牌 14.3:1);②**装饰性 overline/caption**:不承载须精确读取的信息、仅作分区标题或氛围小字者,可至 **12px**。**豁免逐处清单(撤除史归 git 提交史,余清单如下)**:条带内读数=B 区站桩血数一处;装饰 caption 档(FS_CAPTION)在册面=棋盘底操作提示条/营地柜台说明文与结构位预留注记/图例 RAP 词条说明/设置警示文两处/关卡地图底栏组标(生命/属性/特性)与分隔系/站桩消散提示/B 区状态槽微计数(×N●○)/bcard 脚注/RAP 反馈行/刷新余量徽标——清单外 11-13px 文字一律按正文/tooltip 下限提档,新增 caption 位须同批增补本清单。**站桩顺位徽标 ①②③ 不增列本清单**:该处原为 13px 字形,既不在①条带内读数在册面、也不在②装饰 caption 在册面,属「清单外 11–13px 文字」,按本条纪律提档至 `FS_HINT` 14 即归六档;为它单独入册等于开第二口子,与「合并单条不开两口子」的立条理由正面相撞。**站桩名字行同理提档**:名字行(敌人名与护甲文字)承载须精确读取的信息,原取 12px 不在①②两在册面、属「清单外 11–13px 文字」,按本条纪律提档至 `FS_HINT` 14 归六档、不增列②在册面,名字行几何(素底牌矩形、文字基线、宽度测量)随档位联动。②装饰 caption 在册面逐处维持不变。验收:机检〈豁免文字位均可对上本清单,清单外无 <14px;站桩顺位徽标与站桩名字行绘制点取 UiKit.FS_HINT,且②在册面不含该两位〉
- **小字号豁免条款(合并单条不开两口子)**:下款两类**豁免于本节下限**——①**条带内读数**:压在窄条带(血条/进度条等 ≤12px 高带)内居中的数字,受条带高度物理约束,维持 11px 下限,且必须按 §7.2 垫素色牌后计对比(实装=B 区站桩血数 11px 压 HP_BAR_BACK 牌 14.3:1);②**装饰性 overline/caption**:不承载须精确读取的信息、仅作分区标题或氛围小字者,可至 **12px**。**豁免逐处清单(撤除史归 git 提交史,余清单如下)**:条带内读数=B 区站桩血数一处;装饰 caption 档(FS_CAPTION)在册面=棋盘底操作提示条/营地柜台说明文与结构位预留注记/图例 RAP 词条说明/设置警示文两处/关卡地图底栏组标(生命/属性/特性)与分隔系/站桩消散提示/B 区状态槽微计数(×N●○)/bcard 脚注/RAP 反馈行/刷新余量徽标——清单外 11-13px 文字一律按正文/tooltip 下限提档,新增 caption 位须同批增补本清单。**站桩顺位徽标 ①②③ 不增列本清单**:该处原为 13px 字形,既不在①条带内读数在册面、也不在②装饰 caption 在册面,属「清单外 11–13px 文字」,按本条纪律提档至 `FS_HINT` 14 即归六档;为它单独入册等于开第二口子,与「合并单条不开两口子」的立条理由正面相撞。②装饰 caption 在册面逐处维持不变。验收:机检〈豁免文字位均可对上本清单,清单外无 <14px;站桩顺位徽标绘制点取 UiKit.FS_HINT,且②在册面不含该位〉
- **字重纪律(字重两档不启用)**:层级手段为两件——**字号档差(相邻层级 ≥1.25×)+ 墨色深浅**;全局单字重,不上第二个字重(**重开钩子已注销**——整屏样张设计轮已重开并复核:屏内各级文字全部能归进本节六档字号,顺位徽标与站桩名字行两处按本节纪律提档即可,屏内实测对比全部达标(暖白对舞台底 9.49:1、GOLD_BRIGHT 6.47:1、血数 14.3:1),**未实证标题层级不足**,维持单字重,不另立条目);数字禁描边/阴影伪加粗不变(字形为唯一数值载体,§4.1 同源纪律)。验收:机检〈主题仅注册单字重〉/目检〈屏内标题与正文层级仅靠字号档差与墨色深浅两件即可分辨,无一处需要第二字重才读得清〉
### 7.5 营地界面
@@ -521,8 +516,8 @@
- **画布基准(暂定值)**:
- **主角人设原图 = 48×72**(1× 基准,暂定;与站姿降采样可读性验证一致);
- **棋盘小人 = 32×32 二头身派生版(暂定,允许更小)**——独立资产,自人设定稿压缩派生(character-design §5.4),不吞数字位、占位 ≤ 0.75× 格边长;板越小占比摩擦越大(13×13 / 14×14 更小,算例见 [battle.md](../gdd/ux/battle.md)「棋盘格尺寸公式」),32px 源档的去留已定终值 = **保留 32×32 源档**(沿「独立小源档」路线;N=12 板下显示占位上限 27px = 0.84 倍,正落本节乙类非整数缩放许可范围,**连豁免都不用再办**),待决标注注销;
- **站桩立绘源档 = 八敌逐键定档**:主角 48 不变;八敌源档高 = goblin 36 / giant_spider 38 / duergar 46 / hook_horror 58 / bugbear 62 / ogre_chief 74 / drider 90 / duergar_king 94,显示一律 **×2 整数档(NEAREST)** = 72–188。定档依据 = 生物体型三约束(钩爪恐魔>灰矮人、灰矮人<熊地精、食人魔>熊地精——体量=物种体型,非强度线性映射,见 character-design §5.2);可读性实测门槛 = 源高 ≥32(24 糊/32 可读/48 清楚/64 细节完整),全阶梯 36–94 达标;派生管线 = pixel-1.png 紧裁 → 等比缩至档高 → dom_block_resize 块内众数降采样(tools/pixelize_candidates.py `STANDEE_TIER_H`,`SIZES` 降格为管线上游中间分辨率表);体量存在感经整屏对比校验(B 区高读 `stage_h`/立绘显示上限 188)。验收:机检〈standee_asset_check 逐键档高校验〉
- **站桩立绘排版**:① 区高 B 区 ≈1/3 屏 / C 区 ≈2/3 屏,**扫雷盘原尺寸不缩、格子不变**(区高事实源 = 布局表 `battle_layout.tres`;压缩由 C 区面板空档吸收);② 站桩内部重排——立绘双脚落石台上缘(弃盒内居中)、**血条+状态/名字行落底排**(立绘→血条→状态 顺序,全场血条对齐一线;血条嵌石板位、台缘线留作地面线、落影保留接地感),状态空时该行退化为名字行;③ 大体档(显示 >150px 级:drider/duergar_king)**允许向上溢出盒顶 N px**(N 由实装批按实测尺寸算定,**与背景/光柱无关**——现行溢出区恰为临时光柱氛围层〔§6.1 方向稿四柱,x 基准 110/900/1055/1210@1280,`battle_stage_view.gd:47-56`〕,正式舞台背景插画(三关变体)到位后该层直接退役(背景不画光柱),**溢出判定不随之变更**;横向禁止压到顶部中央轮次·阶段指示,溢出上限由实装批用真图复算 x 区间定),血条仍落底(落底排的第二个收益=头部探顶不带出血条);意图徽标悬浮头顶上方(探顶档压胸);④ 「血条悬浮头顶+立绘盒内居中」排式已弃——盒顶固定 y 与盒内居中在高盒下拉开血条-立绘空洞。验收:目检〈血条一线对齐、大体档溢出不压轮次指示〉
- **站桩立绘源档 = 八敌逐键定档**:主角 48 不变;八敌源档高 = goblin 36 / giant_spider 38 / duergar 46 / hook_horror 58 / bugbear 62 / ogre_chief 74 / drider 90 / duergar_king 94,显示一律 **×2 整数档(NEAREST)** = 72–188。定档依据 = 生物体型三约束(钩爪恐魔>灰矮人、灰矮人<熊地精、食人魔>熊地精——体量=物种体型,非强度线性映射,见 character-design §5.2);可读性实测门槛 = 源高 ≥32(24 糊/32 可读/48 清楚/64 细节完整),全阶梯 36–94 达标;派生管线 = pixel-1.png 紧裁 → 等比缩至档高 → dom_block_resize 块内众数降采样(tools/pixelize_candidates.py `STANDEE_TIER_H`,`SIZES` 降格为管线上游中间分辨率表);体量存在感经整屏对比校验(B 区 270/立绘显示上限 188)。验收:机检〈standee_asset_check 逐键档高校验〉
- **站桩立绘排版**:① 区高 B 区 270(≈1/3)/C 区 530(≈2/3),**扫雷盘 438×438 原尺寸不缩、格子不变**(区高事实源 battle.md 区表;压缩由 C 区面板空档吸收);② 站桩内部重排——立绘双脚落石台上缘(弃盒内居中)、**血条+状态/名字行落底排**(立绘→血条→状态 顺序,全场血条对齐一线;血条嵌石板位、台缘线留作地面线、落影保留接地感),状态空时该行退化为名字行;③ 大体档(显示 >150px 级:drider/duergar_king)**允许向上溢出盒顶 N px**(N 由实装批按实测尺寸算定,**与背景/光柱无关**——现行溢出区恰为临时光柱氛围层〔§6.1 方向稿四柱,x 基准 110/900/1055/1210@1280,`battle_stage_view.gd:55-63`〕,正式舞台背景插画 `scene_stage_bg.png` 到位后该层由背景绘制吸收,**溢出判定不随之变更**;横向禁止压到顶部中央轮次·阶段指示,溢出上限由实装批用真图复算 x 区间定),血条仍落底(落底排的第二个收益=头部探顶不带出血条);意图徽标悬浮头顶上方(探顶档压胸);④ 「血条悬浮头顶+立绘盒内居中」排式已弃——盒顶固定 y 与盒内居中在高盒下拉开血条-立绘空洞。验收:目检〈血条一线对齐、大体档溢出不压轮次指示〉
- **站桩石板地台件**:`scene_stage_plaza.png`,源 48×12、九宫格横向拉伸、顶缘受光线 2px 不随拉伸变形;跨三关恒定、不吃 §4.3 `wall_ambient` tint(独立理由见 §6.1 近景地台独立件条)。验收:机检〈地台件按九宫格拉伸后顶缘受光线宽度恒为 2px〉
### 8.3 导出格式与命名规范
-293
View File
@@ -1,293 +0,0 @@
# 美术后处理与校验工具清单
> **性质**:本文件是 `tools/` 下美术资产处理与校验脚本的用法清单。回答三件事:这类资产该跑哪件工具、命令怎么敲、判据与坑在哪。
> **边界**:只管工具用法,不立美术规格。色值、画布、体量、命名与验收条款归 [art-bible](art-bible.md)(§4.1 主色板、§8 资产与技术规范)和 [art-assets-checklist](art-assets-checklist.md);命令与源码冲突时以源码现行为准,美术规格冲突时以 art-bible 为准。素材入库与代码接线归 [asset-path-map](asset-path-map.md),不在本文件。
> **分工**:[art-prompts](art-prompts.md) 管角色级提示词与五步出图流程,[camp-scene-prompts](camp-scene-prompts.md) 管营地场景分层提示词与四步流程;两卡只把「后处理」一步指到本文件。提示词怎么写出图、出完图怎么处理,是两件事。
> **命令前提**:以下命令均在仓库根执行。素材不入 git,worktree 缺件时部分脚本回退主检出 `D:/code/g-plan2`,部分直接返回错误,见各节「已知坑与适用边界」。
## 按资产类型选工具
| 资产类型 | 先跑 | 再跑或校验 | 说明 |
|---|---|---|---|
| 角色精灵(八敌、主角) | `tools/pixelize_candidates.py` | `tools/standee_asset_check.py`、`tools/palette_check.py` | 需要收网格时加 `--fixer` |
| 场景不透明全幅(营地背景层、战斗舞台背景) | 无专用工具 | `tools/palette_check.py` 只出读数 | 见「三条已知边界」第 3 条 |
| 场景透明分层(围墙层、八个物件层) | 无专用工具 | `tools/palette_check.py` 只出读数 | 现役批量处理的键表只认角色键 |
| UI 框材(面板、按钮、石框、底噪、图标) | `tools/quantize_ui_skin.py` | `tools/palette_check.py`、`tools/path_check.py` | 主题小件另跑 `tools/gen_theme_icons.py` |
| 地形瓦片 | `tools/recolor_terrain_tiles.py` | `tools/palette_check.py` | 只换色,不重绘 |
| 整屏样张 | `tools/render_sample_sheet_v3.py`、`tools/render_level_map_sheet.py` | `tools/shot_checker.py`;棋盘回归用 `tools/golden_board_crop.py` 加 `tools/golden_compare.py` | 样张脚本生成后自带机检 |
## 三条已知边界
1. **`pixelize_candidates.py` 不能处理任意资产。** `main()` 写死 `SIZES` 角色键表,只遍历这八个键的子目录;目录名不在表里就跳过,没有单文件入口,也没有通用目录模式。
2. **`palette_check.py` 不做色相禁入带检查,也没有全图明度带检查。** 它只统计单张色数,以及对基线判新增色近色;HSV 300°–345° 禁入带与 §4.1 的明度带不在它的检查范围。
3. **现存工具链没有「不透明全幅背景件」的专用入口。** 角色批量处理按角色键,UI 量化按键名,瓦片换色按 `terrain_*_dungeon` 命名,整屏样张是合成器;没有一件接受一张不透明全幅场景图并输出同尺寸成品。`camp-scene-prompts.md` 第 3 步写明背景层不去底,但这一步没有对应的仓库命令。
## tools/pixelize_candidates.py
**一句话定位**:把远程生图的角色候选批量处理成透明底像素精灵;带 `--standee48` 时按逐键档高产出站桩源档。
**归属**:仓库内 `tools/pixelize_candidates.py`。
**输入与输出**:默认批量模式读 `<批次根>/<角色键>/v*.png`,角色键取 `SIZES` 的八个键;输出 `<角色键>/pixel-<n>.png`、四联底测试条 `pixel-<n>-strip.png`,批次根再出一张 `0-像素化预览.png`。站桩模式读 `<批次根>/<角色键>/pixel-1.png` 与 `<批次根>/hero-ref/edit/normal_1x.png`,有 `attack_1x.png`、`hit_1x.png` 时一并产出;输出 `character_enemy_<键>.png`、`character_hero_portrait.png`、`character_hero_attack.png`、`character_hero_hit.png`。
**用法命令**:
```bash
python tools/pixelize_candidates.py <候选批次目录>
python tools/pixelize_candidates.py <候选批次目录> --fixer
python tools/pixelize_candidates.py <候选批次目录> --standee48
python tools/pixelize_candidates.py <候选批次目录> --standee48 --standee-out game/assets/art/character
python tools/pixelize_candidates.py <候选批次目录> --fixer --fixer-exe D:/code/pixel-art-fixer/rust/target/release/pixelfixer.exe
```
**判据或口径**:`SIZES` 是中间图最长边,不是最终体量——goblin/giant_spider/hook_horror 96,bugbear/duergar 128,ogre_chief/drider/duergar_king 192。`STANDEE_TIER_H` 是站桩档高——goblin 36、giant_spider 38、duergar 46、hook_horror 58、bugbear 62、ogre_chief 74、drider 90、duergar_king 94;主角取 `STANDEE_SLOT_H` 48。站桩源宽上限 75,脚贴画布底缘。去底走奶油描边屏障法,屏障法保留面积低于底色门路径的 60% 时自动回落;随后吃描边。像素化顺序:内容裁剪、BOX 预滤到 4 倍、中位切分量化 64 色(`QUANT_COLORS`)、NEAREST 降到目标、alpha 二值(阈值 128)、删小于 10px 的孤立不透明域、边缘色内插 2 遍。四联底测试条的四底色在 `STRIP_BGS`。正常结束退出 0;源码没有显式退出码,未捕获异常按 Python 默认非零。
**已知坑与适用边界**:键表固定,任意资产不能直接跑,见「三条已知边界」第 1 条。候选文件名须以 `v` 开头且不含 `pixel`;命名解析只取 `v` 后一位数字,`v10.png` 会与 `v1.png` 落到同一个 `pixel-1.png`。`--standee48` 分支读完 `pixel-1.png` 后直接返回,`--fixer` 在站桩分支不生效;要先跑一次带 `--fixer` 的批量模式。`--fixer` 调用失败只打印一行并回退原图,批次继续,不会以非零退出码中断。去底依赖奶油描边;描边被压暗开缺口会漏灌,脚本按 60% 面积阈值回落,但仍假定底色均匀浅色。输出是角色精灵,不处理不透明全幅件。
## 外部工具:pixel-art-fixer
**一句话定位**:检测伪像素网格并把图重建为原生分辨率的真像素图;是 `--fixer` 的收网格后端。
**归属**:仓库外 `D:/code/pixel-art-fixer`,Retro Diffusion 开源,MIT。可执行文件 `D:/code/pixel-art-fixer/rust/target/release/pixelfixer.exe`;`pixelize_candidates.py` 的默认路径同此,可用 `--fixer-exe` 覆写。
**输入与输出**:PNG 或 JPEG,最短边不小于 16px、总像素不超过 4MP。`process` 输出原生 1x PNG,并在 stdout 打一行 JSON,含 `cols`、`rows`、`step_x`、`step_y`、`consensus`、`mode` 与耗时。透明按每格多数保留。
**用法命令**:
```bash
D:/code/pixel-art-fixer/rust/target/release/pixelfixer.exe process <输入.png> <输出.png> full
D:/code/pixel-art-fixer/rust/target/release/pixelfixer.exe process <输入.png> <输出.png> fast
D:/code/pixel-art-fixer/rust/target/release/pixelfixer.exe process <输入.png> <输出.png> full legacy
D:/code/pixel-art-fixer/rust/target/release/pixelfixer.exe recon <输入.png> <step_x> <step_y> <cols> <rows> <输出.png>
D:/code/pixel-art-fixer/rust/target/release/pixelfixer.exe full <输入.png>
```
**判据或口径**:`process` 做自动检测加重建,默认重建走 `two_stage_pack`——量化只用于决定结构,颜色取原图对应像素;加 `legacy` 改走旧的 mode-vote 重建。`recon` 是已知网格参数只做重建,默认 raw 不量化,传 `palette` 才启用自动色板,另可传 `dark`。`full` 与 `fast` 只检测不写图,逐图打 JSON;`full` 跑完整仲裁,`fast` 只跑便宜检测器。退出码:成功 0;`process` 输入不合法或写图失败 1;用法错误或未知命令 2。
**已知坑与适用边界**:输出常是几十到几百像素的原生图,显示必须 NEAREST 放大。它是收网格器,不是降噪或调色器;色数与色板仍归 `palette_check.py` 与 `standee_asset_check.py`。`recon` 不检测网格,参数给错就按错的网格重建。`pixelize_candidates.py` 只在 `--fixer` 时调用 `process`,失败打印一行后回退原图。仓库内的可执行文件是本地构建产物;换机器要按 README 的 Rust 用法执行 `cargo build --release`。
## tools/standee_asset_check.py
**一句话定位**:站桩素材硬闸,逐件校验档高、宽度、底锚、色数、alpha 二值与描边亮度。
**归属**:仓库内 `tools/standee_asset_check.py`。
**输入与输出**:默认读 `game/assets/art/character/` 下固定 11 件——八敌 `character_enemy_<键>.png`,主角 `character_hero_portrait.png`、`character_hero_attack.png`、`character_hero_hit.png`。输出 PASS/FAIL 文本,或 `--json` 机器可读结果。
**用法命令**:
```bash
python tools/standee_asset_check.py
python tools/standee_asset_check.py game/assets/art/character
python tools/standee_asset_check.py game/assets/art/character --json
```
**判据或口径**:档高逐键取自 `pixelize_candidates.STANDEE_TIER_H`,主角三态 48。源宽不大于 75,即乘 2 后不超站桩盒宽 150。画布底行至少一个不透明像素,即脚贴底缘。色数不大于 32,只统计 alpha>0 的唯一 RGB。alpha 只允许 0 或 255,出现中间值即判非整数倍缩放痕迹。敌人轮廓像素中暖白描边占比不低于 40%;暖白指亮度不低于 150 且饱和不高于 0.35。主角三态豁免描边断言。全过 0,任一缺失或红灯 1。
**已知坑与适用边界**:主角三态描边实测约 0.4% 暖白,属暗边已知缺口,本闸豁免、不判红;要验主角描边得另找证据。文件名必须与固定清单完全一致,缺一件即失败;目录里多出的 PNG 不检查。它只查站桩 11 件,不覆盖棋盘小人、场景层、UI 或瓦片。色数口径必须排除全透明像素;按所有像素计会假报 33 色。
## tools/palette_check.py
**一句话定位**:扫目录内 PNG,报单张色数与新增色,并按基线色板判新增色近色。
**归属**:仓库内 `tools/palette_check.py`。
**输入与输出**:递归读目录下所有 `.png`;可选 `--baseline` 目录作为基线色板。输出逐张 PASS/WARN/FAIL、小计与累计新增色。
**用法命令**:
```bash
python tools/palette_check.py <待检目录>
python tools/palette_check.py <待检目录> --baseline <基线目录>
```
**判据或口径**:单张色数等于 alpha>0 的唯一 RGB 数,排除全透明。无 `--baseline` 时是只读模式,只出读数、不判红。有基线时,本图颜色减去基线颜色并集得到新增色;新增色与基线任一色的最大单通道差小于 8/255 即判近色红灯。48 色是设计色板 token 上限,不是单张 PNG 的色数;单张 32 色冻结由 `standee_asset_check.py` 执法,本工具的单张色数只报读数。退出码:0 通过,1 有新增色红灯,2 没给目录。
**已知坑与适用边界**:近色只判新增色对基线,不做存量色两两互查。不做色相禁入带检查,也没有全图明度带检查,见「三条已知边界」第 2 条。单张色数超过 32 只标 WARN 或读数,不进退出码;文件头写的「超单张上限判红」与现行源码不一致,按源码为准。文件头提到 `--tokens`,但现行 `main()` 没有这个参数分支,`TOKEN_MAX=48` 目前只是常量。基线目录不存在时不会返回错误:基线色集为空,新增色判据失效。只排除 alpha=0 的像素,半透明像素的 RGB 也计入色数。
## tools/quantize_ui_skin.py
**一句话定位**:把 UI 复用包里的面板、按钮、石框、底噪与图标按 token 明度带量化改色,产出 `game/assets/art/ui/` 下的终稿件。
**归属**:仓库内 `tools/quantize_ui_skin.py`。
**输入与输出**:源包固定为 `artwork/ui-reuse-2026-09-23/` 下的 Kenney 与 OGA CC0 件;当前仓缺位时回退主检出 `D:/code/g-plan2`。输出 14 件到 `game/assets/art/ui/`——5 件框材与底噪、4 枚营地图标、5 枚节点图标。
**用法命令**:
```bash
python tools/quantize_ui_skin.py
```
**判据或口径**:面板、按钮、石框与底噪按五条硬编码 ramp 做明度重映射,保留 alpha 与纹理结构;ramp 常量在脚本顶部 `RAMP_*`。图标走单色重着色:钥石取奖励金,柜台四件取暖白;节点五件取暖白并烘到 20×20。节点图标自检三项——全像素只能是 `NODE_WARM` 或透明、尺寸 20×20、两两 alpha 剪影错位率不低于 0.08;失败 `SystemExit(1)`。复用闸四道(量化、禁入带、灰度可辨、CC0 授权)的来源说明在文件头;脚本实际自检只跑节点图标这三项,框材件没有逐件断言。全过 0,失败 1,源件缺位抛 `FileNotFoundError`。
**已知坑与适用边界**:源包路径、子目录名与文件名全部硬编码;换包或改名直接 `FileNotFoundError`,不是通用量化器。源包在 `artwork/`,整目录不入 git;worktree 或新检出缺件时才会回退主检出,主检出也没有就失败。只服务这一批 UI 复用件,不处理角色、场景或瓦片。输出覆盖同名件;改色值要改脚本顶部 ramp 常量后重跑,再让 Godot 重导入。
## tools/recolor_terrain_tiles.py
**一句话定位**:把 dungeon 地形瓦片按家族与亮度秩序换色,产出 underdark 与 deep_underdark 两套。
**归属**:仓库内 `tools/recolor_terrain_tiles.py`。
**输入与输出**:默认源与输出都是 `game/assets/art/board/`;只匹配 `terrain_*_dungeon.png` 与 `terrain_*_dungeon_<数字>.png`。输出把文件名里的 `_dungeon` 换成 `_underdark` 或 `_deep_underdark`。
**用法命令**:
```bash
python tools/recolor_terrain_tiles.py
python tools/recolor_terrain_tiles.py --palettes underdark
python tools/recolor_terrain_tiles.py --src <源目录> --out <输出目录> --palettes underdark,deep_underdark
```
**判据或口径**:源图每个唯一色先按 RGB 距离归到 dungeon 锚槽的四家族——墙顶、立面、地面、雷坑;再在家族内按亮度秩序线性映射到目标色表同家族槽列。目标色表 `PALETTES` 硬编码在脚本里,槽值来源为归档包 `archive/归档-terrain-walls-2026-09-26.zip` 内的生成器。映射确定性,无随机;脚本打印每枚源图的唯一色数。成功 0;源目录没有匹配瓦片时打印「零输出」并返回 1。
**已知坑与适用边界**:只做换色,不重绘、不增删结构;结构件缺件不能用它补。家族归属靠最近锚色距离,偏离锚槽的颜色可能归错家族。只认 dungeon 命名,其他图类型或其他前缀不处理。默认输出覆盖同目录同名件;源瓦片不入 git,跑前确认盘上源件在。
## tools/gen_theme_icons.py
**一句话定位**:程序化生成 UI 主题小位图——滑轨柄三态、SpinBox 上下箭头、OptionButton 箭头、勾选框四态。
**归属**:仓库内 `tools/gen_theme_icons.py`。
**输入与输出**:无输入参数;输出 9 张 PNG 到 `game/assets/art/ui/gen/`。
**用法命令**:
```bash
python tools/gen_theme_icons.py
```
**判据或口径**:色值取 `game/presentation/views/ui_kit.gd` 的既有常量,脚本头注明溯源;不新增美术素材、不改 art-bible §7。脚本幂等,重复执行覆盖同名件。滚动条柄不走位图,由 `StyleBoxFlat` 承载,本脚本不产出。无显式退出码;正常结束 0,写入异常按 Python 默认非零。
**已知坑与适用边界**:脚本没有验收断言,生成完要目检并让 Godot 重导入。改色值只能改脚本顶部常量再重跑,脚本不读 `ui_kit.gd` 的运行时值。只出主题小件,不处理面板、图标或场景。产出在素材目录,不入 git。
## tools/shot_checker.py
**一句话定位**:整屏截图机检,判屏级骨架、文字对比、背景纹理、明度三档带与文字是否还在框内。
**归属**:仓库内 `tools/shot_checker.py`。
**输入与输出**:截图目录,默认屏清单 `shot_menu.png`、`shot_camp.png`、`shot_level.png`、`shot_battle.png`;同目录 `shot_meta.json` 提供取样框。输出逐项 PASS/FAIL 摘要。
**用法命令**:
```bash
python tools/shot_checker.py <截图目录>
python tools/shot_checker.py <截图目录> shot_menu.png shot_battle.png
```
**判据或口径**:A 屏级骨架——PNG 存在、任一边 1280、灰度 std 不低于 8、唯一色数不低于 64。B 文字对比——战斗 C 区面板与明细带提示的 WCAG 不低于 4.5:1。C 明度三档——战斗屏信息面高于世界中,世界中高于世界底。D 文字禁压纹理——文字框背景中带灰度 std 不高于 18。F 文字在——菜单标题框内与中位灰度差大于 60 的像素占比落在 2% 到 55%。B/C/D 只在清单含 `shot_battle.png` 时跑,F 只在含 `shot_menu.png` 时跑,其余屏只跑 A。全过 0,缺参数或任一失败 1。
**已知坑与适用边界**:截图必须由窗口化 `shot_probe` 产出;headless 没有渲染面,截图是空的。`shot_meta.json` 缺失时 B/C/D 直接判 meta 几何缺失,不会跳过。尺寸断言按「任一边等于 1280」放行;1920×1080 截图两边都不等于 1280,会被判非工程档,与文件头「1920 档 1.5×」说明不一致,按源码为准。焦点预算是目检项,机检不判。
## tools/golden_board_crop.py
**一句话定位**:按 `board_shot_probe` 输出的 `board_meta.json` 从整屏截图裁出棋盘区,供 golden 逐像素比对。
**归属**:仓库内 `tools/golden_board_crop.py`。
**输入与输出**:三个参数依次是 `board_meta.json`、截图目录、输出目录;读截图目录内 `board_<tag>.png`,按 meta 矩形裁剪,写输出目录同名文件。
**用法命令**:
```bash
python tools/golden_board_crop.py <board_meta.json> <截图目录> <输出目录>
```
**判据或口径**:meta 键即 tag,矩形字段为 x/y/w/h;越界按图像边界收拢。meta 缺失、空表、截图缺失、矩形字段非法或退化,均返回 1;全部裁出 0。禁硬编码像素:布局改动只重跑探针刷新 meta。
**已知坑与适用边界**:依赖 `board_shot_probe` 的 meta 与截图命名;手工截图或改名不认。只裁剪不缩放,输出尺寸随 meta 矩形。它不跑比对;比对是 `golden_compare.py`。
## tools/golden_compare.py
**一句话定位**:黄金图与实测截图逐屏灰度对比,报视觉回归。
**归属**:仓库内 `tools/golden_compare.py`。
**输入与输出**:黄金图目录、新截图目录、可选屏清单;默认四屏 `shot_menu.png`、`shot_camp.png`、`shot_level.png`、`shot_battle.png`。输出逐屏 changed 占比与 PASS/FAIL。
**用法命令**:
```bash
python tools/golden_compare.py game/tests/golden <截图目录>
python tools/golden_compare.py game/tests/golden <棋盘裁剪目录> board_L1_dungeon.png board_L2_underdark.png board_L3_deep_underdark.png
```
**判据或口径**:两图尺寸必须一致;逐像素灰度差大于 16 记为 changed。changed 占比超过 2% 判失败;尺寸不符、缺基线或缺截图也判失败。全过 0,有失败 1。
**已知坑与适用边界**:只比灰度,不比色相;纯换色但明度相同可能漏过。基线在 `game/tests/golden/`,资产换代要显式重制并按该目录 README 记录判定,不能拿重制基线掩盖回归。默认四屏不含棋盘与关卡图;比棋盘要传裁剪后的文件名,比关卡图要传 `level_map.png`。截图分辨率必须与基线一致,基线是 1280 档。
## tools/render_sample_sheet_v3.py
**一句话定位**:战斗一屏样张的当前生成器,出 1280×800 与 1920×1080 两版,并在生成过程中跑断言。
**归属**:仓库内 `tools/render_sample_sheet_v3.py`。
**输入与输出**:读 `game/assets/art/board` 的 21 枚瓦片、`game/assets/art/character` 的小人与立绘、`game/assets/ui/icons` 的状态图标;素材缺位回退主检出。输出 `artwork/mockups/sample-batch-v3-final-2026-09-30.png`、`sample_battle_screen_1280x800.png`、`sample_battle_screen_1920x1080.png`;有基线时再出 `sample_battle_screen_before_after.png`;机检报告写到 `reports/`。
**用法命令**:
```bash
python tools/render_sample_sheet_v3.py
python tools/render_sample_sheet_v3.py --save-baseline
python tools/render_sample_sheet_v3.py --gen-assets
```
**判据或口径**:生成即验。F 段管方案甲拼装、旗位、脚锚、0 格字形、微光带限、立面双明度带、悬崖同源;A 段管色板对表、禁入带、周界闭合、明度对比、混排、净空、观感密度;整屏扩展含 S1–S4、P1–P5、V1、V10、A5b。全绿 0,有红 1,报告逐项列 PASS/FAIL。分区几何不设脚本常量:B 区高 / C 区宽 / AP 条高 / 明细带两态高经 `tools/layout_config.py` 读 `game/data/tables/battle_layout.tres`,与游戏侧 `ConfigDb.presentation.battle_layout` 同源。`--gen-assets` 产四件——`scene_stage_plaza.png` 48×12 与 `ui_armor_light`、`ui_armor_ward`、`ui_armor_heavy` 三枚 24×24;尺寸或色数不过直接 `RuntimeError`。`--save-baseline` 只把当前整屏存成基线并返回 0,整屏断言不跑,板面断言即使有红也不改退出码。
**已知坑与适用边界**:固定输出文件名带 2026-09-30,重跑覆盖同名件。字体硬编码 `C:\Windows\Fonts\msyh.ttc`,非 Windows 环境起不来。第一次跑要先 `--save-baseline`,否则 V10 因缺基线判红。素材不入 git;worktree 缺件会抛 `FileNotFoundError`,回退主检出后仍缺也失败。它产的是样张与机检报告,不是游戏内资产;唯一例外是 `--gen-assets` 的四件。
## tools/render_level_map_sheet.py
**一句话定位**:关卡画面样张生成器,出岔路、入口、单链与换层示意,并跑断言。
**归属**:仓库内 `tools/render_level_map_sheet.py`。
**输入与输出**:读 `artwork/ui-reuse-2026-09-23/` 的节点图标与字体、`game/assets/art/ui/backdrop_stone.png`;画布公式、停点标题与 `HIT_PAD` 从 `game/presentation/views/level_map_screen.gd` 解析。输出 `artwork/mockups/level-map-sheet-v1-2026-09-28.png`;机检报告写到 `reports/`。
**用法命令**:
```bash
python tools/render_level_map_sheet.py
```
**判据或口径**:断言 L1 图标互辨、L2 四态与 Boss 环灰度、L3 对比不低于 4.5:1、L4 禁入带零命中、L5 画布自适应、L6 独立屏底、L7 占位区不侵入;另有 SRC 同源、ST 态齐备、S3 换层。全绿 0,有红 1,报告逐项列 PASS/FAIL。节点图标 20px、通道线宽 2/3/4px 等冻结值在脚本顶部;画布公式不自立,解析自 `level_map_screen.gd`。
**已知坑与适用边界**:依赖 `level_map_screen.gd` 存在且常量写法可解析;改常量写法会让脚本抛 `FileNotFoundError` 或解析失败。字体同样硬编码 Windows 字体。固定输出文件名带 2026-09-28,重跑覆盖。样张是验收图,不是游戏资产。
## tools/render_sample_sheet.py
**一句话定位**:战斗一屏样张 v2 生成器,现行 v3 的前一版。
**归属**:仓库内 `tools/render_sample_sheet.py`。
**输入与输出**:读同一批游戏素材,输出 `artwork/mockups/sample-batch-v2-2026-09-28.png`;机检报告写到 `reports/`。
**用法命令**:
```bash
python tools/render_sample_sheet.py
```
**判据或口径**:断言 F1–F7 与 A1–A6;全绿 0,有红 1。产物为 1280×800 单版,没有 v3 的 1920 档、整屏 S/P 段与改前改后并排。
**已知坑与适用边界**:已被 `render_sample_sheet_v3.py` 取代,只用于复现 v2 旧口径,不要拿它出新冻结。固定输出名与报告名带 2026-09-28,重跑覆盖。字体与素材依赖同 v3。
## tools/path_check.py
**一句话定位**:扫描 `asset-path-map.md` 声明的目录与现役文件,以及代码里的 `res://assets/art` 引用,报悬空与退役命名。
**归属**:仓库内 `tools/path_check.py`。
**输入与输出**:可选 `--repo` 仓库根、`--code` 代码根,默认 `.` 与 `game`。输出 L1 目录、L2 文件、L3 代码引用三段 PASS/FAIL。
**用法命令**:
```bash
python tools/path_check.py
python tools/path_check.py --repo . --code game
```
**判据或口径**:L1 查 `asset-path-map` §1 的声明目录,`design/art/candidates` 按需创建豁免。L2 查 `game/assets/art` 的四个语义子目录与现役文件清单,含主角 idle/walk/portrait、八敌、铲三帧、封印印记。L3 grep 代码里的 `res://assets/art` 引用,核对盘上存在性,并检出 `board_floor`、`board_wall`、`pillar_dungeon`、`production/mockups` 等退役命名;路径模板含 `%s` 或 `%d` 的跳过。worktree 素材未同步时,缺失项标 SKIP 不判红;主区完整素材环境才全量判。全过 0,有红灯 1。
**已知坑与适用边界**:依赖 `asset-path-map.md` 的声明清单与代码常量;新增素材目录不更新文档就不会被查。素材不入 git,worktree 空或半同步会大量 SKIP,不能据此判断主区健康。只核对路径存在与退役命名,不核对图像内容、尺寸或色板。
+44 -9
View File
@@ -1,7 +1,7 @@
# 生图提示词卡(角色级资产)v2.12
# 生图提示词卡(角色级资产)v2.11
> **性质**:美术清单生图通道(✦ 用户自跑,现走线上 API)的执行侧文件——每资产一段**自包含完整提示词**:正向 = 通用底座+主体+动作已拼妥、负向 = 通用底座+增补已并妥,整段复制直接贴进工作流即可,**不需要读其他文件、不需要拼装**。人物规格转写自 [character-design.md](character-design.md)(人物设计 v1.0,自 art-bible §5 迁出,圣经 §5 为存根),风格/色彩条款转写自 [art-bible](art-bible.md)(§4.1 主色板 / §4.2 语义色规则);冲突时人物规格以 character-design 为准、色彩以 art-bible 为准。
> **边界**:本文件只管**角色级**资产的生图通道。图标/格面/样张走脚本管线(⚙ 代理出),规格在 art-bible §4.6 与 [art-assets-checklist](art-assets-checklist.md),不需要提示词。**场景级资产(营地场景图的背景层与八个物件层)另立 [camp-scene-prompts](camp-scene-prompts.md);战斗舞台背景层与连续地面层另立 [battle-stage-prompts](battle-stage-prompts.md),本文件不覆盖**;两卡的角色/场景分工以「谁的资产谁出卡」为界,同一段提示词不两处维护。战斗舞台的小石台件与护甲类型图标三枚的**出图工单**登记在本文件 §5;§5 只把各权威节的定值收进逐件工单,不立新值。意图动画三档是动画资产,等一屏样张锁方案后另立规格卡,本文件不覆盖。
> **边界**:本文件只管**角色级**资产的生图通道。图标/格面/样张走脚本管线(⚙ 代理出),规格在 art-bible §4.6 与 [art-assets-checklist](art-assets-checklist.md),不需要提示词。**场景级资产(营地场景图的背景层与八个物件层)另立 [camp-scene-prompts](camp-scene-prompts.md),本文件不覆盖**;两卡的角色/场景分工以「谁的资产谁出卡」为界,同一段提示词不两处维护。战斗舞台的场景级两件与护甲类型图标三枚的**出图工单**登记在本文件 §5(camp-scene-prompts 只管营地场景图,战斗屏这两类无处可落);§5 只把各权威节的定值收进逐件工单,不立新值。意图动画三档是动画资产,等一屏样张锁方案后另立规格卡,本文件不覆盖。
> **状态**:提示词卡成文,出图未开始;按「美术圣经 §5 现行」重生成(正序:B 路线),继承 seed 纪律 / 色相禁入带 / `#F2F2F2` 生成底色;沿革见 git 提交史。
---
@@ -11,7 +11,7 @@
1. **出图**:按下面卡片把正向/负向提示词粘进生图渠道的提示词栏(**渠道 = 远程对话式生图为主,本地 ComfyUI 为备选**——2026-10-06 拍板;对话操作纪律见 [remote-gen-prompts](remote-gen-prompts.md)),每个资产出 **2–3 版候选**(建议固定 3 个 seed 连拍,便于横评)。
2. **入库**:候选原图(带底)放 `artwork/candidates/<资产名>/`,文件名 `v1.png / v2.png / v3.png`。这个目录只存候选,不进引擎。
3. **裁决**:你按 §4 验收速查预筛,挑出每一资产的入围候选拍板。
4. **后处理**:喊我一声,脚本管线代跑——去底转透明、最近邻降采样到目标尺寸、色板量化、四联底测试条(掩尘底/裸土底/暗底/灰度)。后处理工具清单与用法见 [art-pipeline-tools](art-pipeline-tools.md)。
4. **后处理**:喊我一声,脚本管线代跑——去底转透明、最近邻降采样到目标尺寸、色板量化、四联底测试条(掩尘底/裸土底/暗底/灰度)。
5. **转正**:终稿从 `artwork/candidates/` 转入切片资产目录,随表现层升级批接线;清单状态列改「已交付」。
**出图通道(2026-09-23 定稿)**:线上 API,用户自跑——本地 ComfyUI 生图路线已经用户拍板**彻底关闭**(母版工作流/像素 LoRA/Z-Image 模型已清退,不留复活预案,本卡不依赖任何本地管线)。
@@ -286,15 +286,50 @@ Seamless tileable pixel art texture of dry dirt ground, top-down, for a dungeon
## 5. 资产出图工单(四组九件)
> **范围注**:本文件原定位角色级(见文件头边界句),§4bis 已有「地形类同库登记」的先例,本节循同一先例补登记战斗屏的**小石台件(②)**与护甲类型图标三枚(③),两组在营地卡与清单里都无处落工单;战斗舞台背景层(①)与连续地面层的元素/提示词已另立 [battle-stage-prompts](battle-stage-prompts.md),§5.1 只留指路;角色级立绘重产(④)是本文件的本职。四组的规格定值清单 §4 已有登记,本节补的是「逐件照着就能出件」那一层。
> **范围注**:本文件原定位角色级(见文件头边界句),§4bis 已有「地形类同库登记」的先例,本节循同一先例补登记战斗屏两类——战斗舞台的场景级两件(① ②)与护甲类型图标三枚(③),两组在营地卡与清单里都无处落工单;角色级立绘重产(④)是本文件的本职。四组的规格定值清单 §4 已有登记,本节补的是「逐件照着就能出件」那一层。
> **定值纪律(§8 头注 定值单点纪律)**:本节**指路不立值**——色值 = 圣经 §4.1(含场景环境子板)、尺寸与缩放 = §8.2、明度带 = §2、甲档 = character-design §5.3、命名 = §8.3 + asset-path-map。本节新增零定值;凡圣经未定的值,一律进本节 §5.5 缺口,不在本节填空。
> **验收标注纪律**:逐条按三档标 `←机检: <断言>` / `←目检: <判据>` / `←方向性`,照圣经头注 2026-10-06 用户拍板的写法。
> **流程**:出图前后一律走 §0 五步;出图登记义务照 remote-gen-prompts 头注轻量口径(用途+生成时间必注,其余参数有则记),随候选图存 `artwork/candidates/<资产名>/`;登记不作正稿遴选前置。
> **产出状态**:组二地台件与组三护甲三枚已按各节 ⑤「程序化产出即终稿」产出入包(`scene_stage_plaza.png` 48×12、`ui_armor_light/ward/heavy.png` 24×24,路径见各组 ① 字段;登记=战斗一屏样张批,合并提交 3b66d1a6);组一背景插画已迁至 [battle-stage-prompts](battle-stage-prompts.md)(仍待出图),组四立绘重产仍待出图。
> **产出状态**:组二地台件与组三护甲三枚已按各节 ⑤「程序化产出即终稿」产出入包(`scene_stage_plaza.png` 48×12、`ui_armor_light/ward/heavy.png` 24×24,路径见各组 ① 字段;登记=战斗一屏样张批,合并提交 3b66d1a6);组一背景插画与组四立绘重产仍待出图。
### 5.1 组一 · B 区舞台背景插画(1 件)
> **本件已迁出本文件**:逐条要素、分层提示词、否定后缀与验收 = [battle-stage-prompts](battle-stage-prompts.md)(背景层 §2.1/§4);场景构成与图层归属 = [art-bible](art-bible.md) §6.1;尺寸读 `game/data/tables/battle_layout.tres`。本文件不再复写本件提示词,避免两处维护。
| 字段 | 值 |
|---|---|
| ① 路径与命名 | `game/assets/art/scene/scene_stage_bg.png`——域键 `scene`(asset-path-map §3),命名照 §8.3 `<域>_<对象键>_<状态\|变体>[_<序号>].png`。**三关不按板出三张,文件名不带 `_dungeon`/`_underdark`/`_deep_underdark` 后缀**(三关换挡走 §4.3 `wall_ambient` tint 槽,与棋盘同款换皮逻辑) |
| ② 尺寸档与像素网格 | 源 1280×270(B 区全高含明细带底),显示 1×;九宫格 = 否。甲/乙两分类不覆盖环境件(§8.2 甲类 = 文本与语义件、乙类 = 角色与单位精灵),本件在 1280×800 基座下满幅铺 1×、不缩放;1920 档口径见 §8.2「1920×1080 档策略」条,本节不另立值 |
| ③ 色板约束 | 进**战斗屏场景环境子板**(§4.1 分层②:每屏一套 ≤32 色、跨屏不共享、**不占 48 token 额度**——48 额度余量现为 0(2026-10-28 用尽),本件不动它)。**零新增**——主体三色:远景最深 `#282220`(默认;备选 `#3A2E22`,二选一,选后者则图内禁用 `#362B20`,两者三通道差 4/3/2 全部 <8,是 §4.1 欠账清单六对之一);中景洞壁 `#3E362C` 与中景受光壁面 `#453723` 交替,**两色只靠笔触与纹理分出块面,不靠第三个色**;需过渡色时只从在册的 `#362B20`/`#4C4038` 取。单张 PNG 像素域色数 ≤32。第二道门 = 与既有任一色三通道差不得全部 <8/255(§4.1 增量纪律),不过门即换色合并、禁加色绕行 |
| ④ 明度带归属 | **世界底层下沿子带 L 0.014–0.06**(§2 世界底层两子带)——全图落该子带,不得越进上沿子带 L 0.08–0.14(那是已开格底与迷雾记忆态合成底的地盘)。三色实测: `#282220` L≈0.016 / `#3E362C` L≈0.039 / `#453723` L≈0.042 |
| ⑤ 是否程序化件 | 否 → **须出图**(✦ 插画级,清单 §4 已定来源 = 作者自跑远程生图管线)。现行程序化平色 + 光柱 = 占位(◐),按 §7.1 占位完成条款须在终稿闸前换代 |
| ⑥ 验收判据 | 见下方逐条判据 |
| ⑦ 出图操作要点 | 见下方提示词与负面约束 |
**逐条判据**
- 构图只出远景 + 中景两带:远景 0–35%、中景 35–78%,78%–100% 段不画 ←机检: 画布 1280×270 逐位相符;`y ≥ 210`(78%) 段内 `#968264` 像素数 = 0 且该段与中景段无独立地台结构件
- 三关只走 tint 槽 ←机检: 仓内 `scene_stage_bg*` 文件名无 board_type 后缀变体(三关方向指路 §6.3,该节终值未冻结,属实装批,不阻塞本件出图)
- 色板零新增 ←机检: 单张像素域色数 ≤32 且逐色在 §4.1 战斗屏场景环境子板在册
- 明度带 ←机检: 全图取样点相对亮度 L 全部落 [0.014, 0.060]
- 禁入带 ←机检: 全图无 HSV 色相 300°–345° 像素(清单 §0 复用闸②吸色检查同口径)
- 临时光柱层退役 ←机检: 本件入包后 `battle_stage_view.gd` 四柱临时光柱层退役(§8.2 站桩排版③条;该条的立绘溢出判定不随之变更)
- 背景自然后退 ←目检: 立绘与 C 区数字在前,本件不构成完整凸形、无第二焦点(§3.4 焦点预算 / §6.1 低对比后退)
- 气质 ←方向性: 明亮地窟、暖倾向、无压抑(§1 风格基调;§9.2 Darkest Dungeon 式压暗在反面清单)
**出图画布**:2560×540(终稿 2×,保证整数倍降采样;平台不支持该宽高比时取可用的最宽档出图、按上下居中裁到 4.74:1,禁横向拉伸变形)。
**正向提示词(整段可贴)**:
```
Pixel art style. True pixel art game background illustration drawn with chunky square pixels, strict pixel grid alignment, hard edges, no anti-aliasing, no gradients, flat colors only, a limited palette of about eight colors, retro 16-bit look, Aseprite style, all ages, bright cheerful fantasy cavern, not dark and not grim, flat side view, orthographic, no perspective distortion, very wide horizontal band about 4.7 to 1 aspect ratio. This is the BACK WALL of a bright underground cavern arena seen straight on, and it is a BACKGROUND ONLY: it must contain no characters, no creatures, no floor platform and no props, because the standing stone platform and the characters are drawn on top of it as separate pieces. TWO BANDS ONLY, and the bottom twenty-two percent of the frame stays completely empty. FAR BAND (the top zero to thirty-five percent of the frame height): the deepest hollow of the cavern, a flat dark far wall receding into shadow, one or two rows of very simple flat stalactite silhouettes hanging from the top edge, the darkest area of the picture, its darkest value is hex color #282220, no light sources, no small detail, everything reduced to a few large flat shapes. MIDDLE BAND (thirty-five to seventy-eight percent of the frame height): the cavern wall, broad flat facets of stone alternating between hex colors #3E362C and #453723, the facets separated only by their brush texture and by a few slightly darker seam lines, with two or three soft vertical light shafts falling from the cave roof across the wall, the shafts being flat low-contrast bands of light and not beams of particles. WHOLE IMAGE: every color is very dark and low in contrast, the entire background recedes behind the characters, there are no bright highlights and no rim lights, no single element forms a complete solid shape that competes for attention, and all wall facets stay large and simple.
```
**负向提示词(整段可贴)**:
```
Do not add any of the following: realistic, photorealistic or 3D rendering; painterly brushwork, smooth anti-aliased lines, gradient or dithered shading, glossy highlights; blur or compression artifacts; a vignette, dark corners, or any mood darkening; any purple or magenta anywhere, any color with a hue between 300 and 345 degrees; any text, letters, numbers, watermark, signature or logo; any frame, border, panel, arrow or UI element; any characters, people, creatures or animals; any floor, ground plane, stone platform, pedestal, stage floor or baseboard in the lower part of the frame, because the bottom twenty-two percent of the frame must stay completely empty; any torch, brazier, lantern, candle or glowing object as an object, only the flat light shafts described above; bright or saturated colors, any area lighter than hex #453723; high contrast edges, rim lights, black outlines; rubble, chains, bones, murals, paintings, furniture or any extra prop.
```
**后处理**:§0 五步第 4 步——本件是**不透明全幅件**,去底与四联底测试条两步不适用,只走最近邻降采样到 1280×270 + 色板量化到本节 ③ 所列色;终稿入包后走 §1.4 整屏样张闸。
### 5.2 组二 · 近景地台件(1 件)
@@ -308,7 +343,7 @@ Seamless tileable pixel art texture of dry dirt ground, top-down, for a dungeon
| ⑥ 验收判据 | 见下方逐条判据 |
| ⑦ 出图操作要点 | 见下方工艺要点(手绘/程序化,无须 AI 生图) |
**独立成件的两条理由(§6.1「近景地面与地台走独立件」条,写进工单备查)**:① 背景层按关卡出三张变体,地台若画进任一张就得三张各画一遍、且三关站位面会漂移;② 结算期明细带整条压住 B 区底带(带高 = `log_band_h_settle`,读布局表),地台在独立层才能跨关恒定并保持 §6.1 定死的世界中层承载面不变。
**独立成件的两条理由(§6.1「近景地台走独立件」条,写进工单备查)**:① 结算期明细带底 84px 会盖住 B 区 78%–100% 段(约 59px),84 > 59,近景带在结算期整条不可见——画进背景等于画一件永远看不见的东西;② §4.3 `wall_ambient` tint 作用于整张背景,地台若画进背景会随三关换明度,而 §6.1 舞台正面目标把地台定死为世界中层承载面,随关卡变会破 §2 明度分层的层间关系。
**逐条判据**
@@ -344,7 +379,7 @@ Seamless tileable pixel art texture of dry dirt ground, top-down, for a dungeon
- ←机检: 源 24×24、显示 1× 整数倍(§8.2 显示档登记例外条:素材一字节禁改)
- ←机检: 文件名逐位等于 `ui_armor_light` / `ui_armor_ward` / `ui_armor_heavy`
- ←机检: 单张像素域色数 ≤32
- ←机检: 三枚对其实际挂载底色的图形对比 ≥3:1(§4.1 图标槽柔和档条的图形参考线硬约束)。**挂载底色 = 站桩名字行的素底,不是舞台底也不是地台面**——站桩名字行是文字,§7.2「一切文字(含菜单/说明/tooltip/按钮/底栏,**无区域例外**)」+「文字禁直接压纹理底——垫容器或罩层」两条覆盖它;§6.1 舞台正面目标条(2026-10-28 v3.22 定值)已就站桩文字位显式落法:「站桩文字位改垫素底或落进结算明细带」,并明写「**非新条款**」,§7.2 同批加「站桩石板地台面同理」句、两处机检断言同文。舞台背景插画(`scene_stage_bg_<board_type>` 三关变体;battle-stage-prompts §2.1)属纹理底,落法门触发。**故「站桩名字行落法 = 垫素底」是既有条款的落法,本节不立新条款**(§5 头注定值纪律:本节指路不立值)。素底明暗档 **2026-10-28 已裁 = 深档 `#282220`**(§7.4 血数垫牌 `HP_BAR_BACK` 在册同款,零新增;浅档 `#F5EAD3` 落选,两档对照与理据见 §5.5 缺口 2 已裁条)
- ←机检: 三枚对其实际挂载底色的图形对比 ≥3:1(§4.1 图标槽柔和档条的图形参考线硬约束)。**挂载底色 = 站桩名字行的素底,不是舞台底也不是地台面**——站桩名字行是文字,§7.2「一切文字(含菜单/说明/tooltip/按钮/底栏,**无区域例外**)」+「文字禁直接压纹理底——垫容器或罩层」两条覆盖它;§6.1 舞台正面目标条(2026-10-28 v3.22 定值)已就站桩文字位显式落法:「站桩文字位改垫素底或落进结算明细带」,并明写「**非新条款**」,§7.2 同批加「站桩石板地台面同理」句、两处机检断言同文。舞台背景插画 `scene_stage_bg.png` 的中景两色只靠笔触与纹理分块面(5.1 ③),属纹理底,落法门触发。**故「站桩名字行落法 = 垫素底」是既有条款的落法,本节不立新条款**(§5 头注定值纪律:本节指路不立值)。素底明暗档 **2026-10-28 已裁 = 深档 `#282220`**(§7.4 血数垫牌 `HP_BAR_BACK` 在册同款,零新增;浅档 `#F5EAD3` 落选,两档对照与理据见 §5.5 缺口 2 已裁条)
- ←机检: B 区站桩名字行与护甲图标正下方像素非地台板身色 `#968264`(§6.1 / §7.2 同文断言)
- ←目检: 灰度下按甲面覆盖率三档可辨——无甲板 → 符纹带 → 大面积甲板(character-design §5.3 灰度通道条)
- ←目检: 三枚互辨,身份只靠形状不靠色相(§4.5 ⑨ 图标键族:色相不承载身份)
@@ -456,7 +491,7 @@ Seamless tileable pixel art texture of dry dirt ground, top-down, for a dungeon
- ←机检: 本值入板后全板色对中三通道差全部 <8/255 的对数 = 0
2. **站桩名字行的落法 + 素底明暗档——已裁(2026-10-28)= 垫素底、素底取深档 `#282220`**,本节转指路(原记为「轻甲木色在深底上不过 3:1」;核出落法是它的前置,故先落这一条)。
- **推导核实 = 成立,且是既有条款的落法、非新条款**:站桩名字行是文字,§7.2「一切文字(含菜单/说明/tooltip/按钮/底栏,**无区域例外**)」+「文字禁直接压纹理底——垫容器或罩层」两条覆盖它;§6.1 舞台正面目标条(2026-10-28 v3.22 定值)已就站桩文字位显式落法——「站桩文字位改垫素底或落进结算明细带」并明写「**非新条款**」,§7.2 同批加「站桩石板地台面同理」句,两处机检断言同文。舞台背景插画(`scene_stage_bg_<board_type>` 三关变体;battle-stage-prompts §2.1)属纹理底 → 落法门触发。**已回填**:站桩名字行落法 = **垫素底**(§5.3 共用验收条 + 5.3.1 / 5.3.3 对比判据)。
- **推导核实 = 成立,且是既有条款的落法、非新条款**:站桩名字行是文字,§7.2「一切文字(含菜单/说明/tooltip/按钮/底栏,**无区域例外**)」+「文字禁直接压纹理底——垫容器或罩层」两条覆盖它;§6.1 舞台正面目标条(2026-10-28 v3.22 定值)已就站桩文字位显式落法——「站桩文字位改垫素底或落进结算明细带」并明写「**非新条款**」,§7.2 同批加「站桩石板地台面同理」句,两处机检断言同文。舞台背景插画 `scene_stage_bg.png` 中景两色只靠笔触与纹理分块面(5.1 ③),属纹理底 → 落法门触发。**已回填**:站桩名字行落法 = **垫素底**(§5.3 共用验收条 + 5.3.1 / 5.3.3 对比判据)。
- **原冲突 = 素底明暗档圣经未定死(2026-10-28 已由作者裁,本节不替裁的冲突至此闭合)**:§4.1 只在册浅档 `#F5EAD3`(数字色牌,圣经唯一素色牌值),§7.4 血数垫牌在用的深档 `HP_BAR_BACK #282220` 亦在册。两档后果**相反**(下表留作裁定依据账):
| 受影响的位 | 浅档 `#F5EAD3` | 深档 `#282220` |
-1
View File
@@ -40,7 +40,6 @@
| 连锁坍塌显形演出 | ⬜ | [art-assets-checklist](art-assets-checklist.md) §4 |
| 封印特效(动作=封印,两件:施印特效+印记常显) | ⬜ | [art-bible](art-bible.md) §3.2 + [art-assets-checklist](art-assets-checklist.md) §4 |
| 弹道 / 退场等动画密度 | ◐ 程序化弹道在役(play_projectile 0.16s+0.19s 到达拍调度;密度终稿归战斗表现) | [art-assets-checklist](art-assets-checklist.md) §4(战斗表现输入清单) |
| B 区舞台背景三关变体+共用连续地面层(场景件) | ✅ 已交付(2026-10-31 入包 `game/assets/art/scene/`:三张背景 1280×252、共用地面 1280×100;地面按作者裁保留候选 v12b 原亮度 L≈0.132) | [art-bible](art-bible.md) §6.1 · [battle-stage-prompts](battle-stage-prompts.md) §2 |
---
+1 -1
View File
@@ -27,7 +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/` | **场景图**(背景层 + 地面层 + 围墙层 + 可点物件层;营地场景图首批) | 营地 10 张:`scene_camp_bg`(背景层,不透明全幅=天空+远山+地面+门洞小路)+ `scene_camp_wall`(围墙层,透明底、门洞留透明缺口)+ `scene_camp_gate / forge / chest / notebook / dummy / board / campfire`(七个可点物件)+ `scene_camp_tent`(承载件,不可点)+ `scene_stage_bg_dungeon` / `scene_stage_bg_underdark` / `scene_stage_bg_deep_underdark`(B 区战斗舞台背景层三关变体,✦ 插画级,顶部空区+远景天然洞壁,不画近景地面,按 board_type 选图)+ `scene_stage_ground`(B 区连续近景地面层,✦ 插画级,泥土/砂砾/碎石+顶缘分隔带,跨关恒定)+ `scene_stage_plaza`(B 区角色脚下小石台,48×12 九宫格件)——B 区战斗舞台背景与连续地面 2026-10-31 已入包;登记超前:营地场景图批落地前盘上未建 |
| `scene/` | **场景图**(背景层 + 可点物件层;营地场景图首批) | `scene_camp_bg`(背景)+ `scene_camp_gate / forge / chest / notebook / dummy / board / campfire`(七个可点物件)+ `scene_camp_tent`(承载件,不可点)+ `scene_stage_bg`(B 区战斗舞台背景,✦ 插画级,只出远景+中景两带)+ `scene_stage_plaza`(B 区近景地台,48×12 九宫格件)——登记超前:营地场景图批落地前盘上未建 |
| `board/` | 砖面/封印印记(三关换皮 + 封印印记件) | terrain_floor_<board_type>_<n>.png(三关地面系)、seal_mark.png |
## 4. 坐标/朝向等工程侧约定备查
-182
View File
@@ -1,182 +0,0 @@
# 战斗舞台背景 · 分层生图提示词卡 v1.8
> **性质**:B 区战斗舞台背景(顶部空区+远景天然洞壁+近景连续泥土地面+分隔带)的出图执行侧文件。背景按三关出三张变体,地面三关共用一张;场景级资产,与角色级 [art-prompts](art-prompts.md) 并列,两文件互不覆盖。
> **依据**:场景构成与图层归属 = [art-bible](art-bible.md) §6.1;三关方向 = art-bible §6.3;色板 = art-bible §4.1(战斗屏场景环境子板);尺寸 = `game/data/tables/battle_layout.tres`(背景读 `stage_h`;地面读 `ground_h`,该字段由地面层实装批新增并回填);命名与路径 = [asset-path-map](asset-path-map.md);后处理 = [art-pipeline-tools](art-pipeline-tools.md)。
> **边界**:只管三张背景变体与一张共用地面的提示词与验收;角色、格面、图标、小石台 `scene_stage_plaza.png` 与样张走 art-prompts 与脚本管线,不在本卡。
> **建立**:2026-10-31 · 状态:三关背景变体与共用地面已按本工单出图并入包(选定=dungeon v10c/underdark v10c/deep_underdark v10c/ground v12b,落点与读数见 art-bible §6.1「B 区舞台背景与共用地面的交付绑定」);出图通道由作者自定(参考候选可用内置 ImageGen,水印可留;入包终稿须干净)。
---
## 0. 使用流程(四步)
1. **出图**:按 §2 把提示词贴进生图渠道;每次出图先放 §1 的风格参考图。**先只出 dungeon 背景 1 张**,作者确认风格前缀后,再出 underdark / deep_underdark 两张变体与连续地面层。
2. **入库**:候选原图放 `artwork/candidates/scene_stage_bg/`(三关变体用 `dungeon_*` / `underdark_*` / `deep_underdark_*` 命名)与 `artwork/candidates/scene_stage_ground/`;`_登记.txt` 记用途与生成时间。
3. **后处理**:三张背景不去底(不透明全幅);连续地面层去底转透明(顶缘以上键控)+最近邻降采样+色板量化+底测试条;工具清单与已知边界见 [art-pipeline-tools](art-pipeline-tools.md)。
4. **转正**:终稿转入 `game/assets/art/scene/`;三张背景按 `board_type` 选图、连续地面层接线与布局表 `ground_h` 字段由实装批落码。
---
## 1. 风格参考图(每次出图都要带)
| 参考图 | 作用 |
|---|---|
| `game/assets/art/character/character_hero_idle.png` | 定像素密度、平涂质感、描边与暖色族 |
| `game/assets/art/board/terrain_floor_dungeon_1.png` | 定岩面/地面的笔触与色族;只借质感,不抄瓦片形状与拼块接缝 |
| `game/assets/art/scene/scene_stage_plaza.png` | 定近景层色族与顶缘处理;只借色与像素密度,不借石板铺装 |
**禁止**拿未经验证的自造图当风格参考——风格错了整批全废。元素参考可用 D&D 洞穴/地下城的岩层、裂缝、凹壁、碎石等常见构成(见 §3),但不把外部图当风格锚。
贴参考图时,在提示词末尾接这一句:
```
Style reference: the attached images are this game's own finished pixel art — match only their rendering style, the same pixel density, flat shading, hard edges and warm limited palette. They are style references only: do not copy their subjects, characters, gear, props, tile patterns or any specific rock or ground layout, and do not put any character into the scene.
```
---
## 2. 两层提示词
### 2.1 背景层(三关变体,按 `board_type` 选一张)
**画什么**:顶部空区(深色、无物);**纵深洞厅远景**——远层暗剪影(远处洞口/通道、层叠岩体、洞底轮廓)、中层主要细节层(岩台、岩柱、凹壁、裂缝、建筑剪影)、近层左右暗色岩框;三关母题按 §3.2。
**不画什么**:近景地面、地台、平台;贴墙感、单件圆柱/贴图直接贴顶、悬挂物;砖石墙、规则砌缝、方整石块、瓷砖/铺装;钟乳石、吊锥、洞顶结构;角色、生物、道具、火把/灯/发光物;文字/UI。
**三关变体**:
| 关卡 `board_type` | 资产 | 岩体/构图 | 色族 |
|---|---|---|---|
| dungeon | `scene_stage_bg_dungeon.png` | 深远洞厅:远层支洞/通道口;中层岩台+歪斜木栈道/脚手架+削尖木桩围栏 | 暖石棕(`#282220` / `#3E362C` / `#453723`) |
| underdark | `scene_stage_bg_underdark.png` | 深远洞厅:巨型石柱、细长石笋、蛛网、螺旋塔剪影、巨菇、裂谷石桥 | 冷蓝灰+少量紫罗兰灰(约 256° 域;避 300°–345°) |
| deep_underdark | `scene_stage_bg_deep_underdark.png` | 深远洞厅:石笋城郭、棱角石厅/扶壁、跨谷石桥、矿道口、烟囱塔群 | 灰黑主调+金属质矿脉 |
**出图画布**:三张同规格——终稿 2× = (2× 基准屏宽) × (2× `stage_h`),尺寸读 `battle_layout.tres`。平台不支持该宽高比时取可用最宽档、按中央 5:1 横带裁到目标宽高比(基准屏宽 / `stage_h`),禁横向拉伸。当前内置参考通道最宽 2560×1080,按中央带裁。
**共用底座正向提示词(三张共用)**:
```
Pixel art style. True pixel art game background layer drawn with chunky square pixels, strict pixel grid alignment, hard edges, no anti-aliasing, no gradients, flat colors only, a limited palette of about eight colors, retro 16-bit look, Aseprite style, all ages, bright cheerful fantasy cavern, not grim, flat side view, orthographic, no perspective distortion. A very wide horizontal composition, about 5 to 1 aspect ratio; if the canvas is taller than that band, paint the band across the middle and fill the area above and below with flat dark continuation #282220, keeping all detail inside the band. This is the FAR BACKGROUND of an underground cavern arena: the camera stands at the arena edge and looks across a deep cave chamber, so the view must read as a distant cavern interior with real depth, NOT as a flat wall close behind the characters. BACKGROUND LAYER ONLY: no ground, no floor, no platform, no characters, no creatures, no props in the near view, no torches, no lanterns, no light sources of any kind, no light shafts, no beams of light, no glow. TOP BAND (the top fifth of the band): completely empty flat solid darkness #282220, no texture, no ceiling, no stalactites, no hanging cones, no spikes, no objects, and nothing touches the top edge. DEPTH LAYERS, from far to near: FAR LAYER: the farthest depth, simple dark silhouettes of distant rock masses and two or three dark side tunnel openings; no continuous floor line, the far depth fades into darkness; these are the darkest and simplest shapes, their edges partly hidden behind the midground, and they never form isolated cutouts against the top band. MIDGROUND: the main readable layer across the middle of the band — several enormous rock masses and broad ledges at different heights that overlap and partly hide each other, irregularly spaced, not a row of evenly spaced pillars; a few tall natural rock pillars rise from behind the ledges; the central part of the frame opens into a deeper recess with one large dark tunnel mouth far behind it; shallow alcoves and recesses, cracks and fissures; this layer carries most of the detail, low in contrast; the rock reads as huge natural cave masses, not a built wall, with only a few faint, short, broken strata hints that fade out, never continuous wavy stripes. NEAR FRAME: at the left and right edges, two dark rock masses frame the view, slightly darker than the midground; no isolated cylinder, column or prop pasted against the top; no hanging shapes. CENTER: the central half of the band stays calm and low in detail so the characters and UI can read. The overlapping ledges, pillars and far silhouettes must create several depth planes, not one flat backdrop. BOTTOM BAND (the bottom third of the band): simple flat dark rock in #282220 fading into shadow, no floor, no ground plane, no continuous horizontal ground line, no stone platform, no pedestal, no baseboard, no props — this area will be covered by a separate ground layer and UI. WHOLE IMAGE: very dark and low in contrast, no bright highlights, no rim lights, no vignette, no complete solid shape that competes for attention; no dense horizontal wavy lines, no repeated banding, no zebra stripes, no wood-grain pattern.
```
**三关变体段(接在共用底座后)**:
dungeon:
```
Use warm limestone for the far and mid rock: dark warm brown-grey, from the darkest #282220 through #3E362C to the lighter #453723; broad calm rock faces and a few wide low ledges; only a couple of faint, broken strata hints, not bands across the wall. GOBLIN LAIR DETAILS, fully built into the rock, only in the midground and far layer, small and low contrast, partly hidden: one broken crude wooden walkway anchored into a distant ledge with its posts set into the rock, its middle hidden behind a rock outcrop; one short pointed stake fence embedded along the edge of a far ledge, partly behind a rock mass; a dark side tunnel mouth with a rough timber frame built into the rock; no isolated fence segments, no floating walkway pieces, no structures sitting on top of ledges like icons; never in the near frame, never at the top, never lit.
```
underdark:
```
Use cool desaturated blue-grey rock for the far and mid rock: the rock faces are dark cool blue-grey, not warm brown; the cracks are sharper and more vertical; in the far layer add simple dark silhouettes of a few giant natural rock pillars whose tops fade into the dark top band, slender stone spires rising from distant ledges, thin muted grey web strands between rocks, a few curved spiral tower silhouettes, huge mushroom silhouettes on far ledges, and a distant chasm crossed by a thin stone bridge; add only a few thin, muted blue-violet mineral seams around 256 degrees hue, never saturated purple or magenta; no glowing fungi, no faerie fire, no bricks, no regular masonry.
```
deep_underdark:
```
Use very dark neutral grey-black rock for the far and mid rock: the rock faces are grey-black and angular, with broken, step-like ledges; in the far layer add simple dark silhouettes of a city carved into a giant stalagmite, with angular stone halls, buttresses and stepped terraces, a few stone bridges spanning a rift, several mine entrances with dark timber frames, and a row of chimney and vent stacks; a few thin cool silver and copper-grey mineral veins run through the rock as matte metal, not glowing; no forge fire, no glow, no smoke plume, no bricks, no regular masonry.
```
**共用否定后缀(三张共用)**:
```
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; any saturated purple or magenta anywhere, any color with a hue between 300 and 345 degrees (the underdark's muted 256-degree blue-violet seams are allowed and must stay desaturated); brick patterns, rectangular cut stone blocks, regular masonry joints, mortar lines, tiled surfaces, paved surfaces, a near-view carved or dressed stone wall, a flat wall close behind the characters, a single isolated column or cylinder pasted against the top band, any element touching the top edge, isolated fence segments, floating walkway pieces, structures sitting on top of ledges like icons, a continuous horizontal floor line; dense horizontal wavy lines, repetitive wavy banding, zebra stripes, wood grain, layer-cake stripes, continuous parallel strata across the whole wall; stalactites, stalagmites used as hanging shapes, hanging cones, ceiling spikes, cave curtains; any ground, floor plane, stone platform, pedestal, stage floor, baseboard, path or paving in the lower band; any character, person, creature or animal; any light source of any kind, any torch, brazier, lantern, candle, crystal, glowing object, light shaft, god ray, beam of light, glow, bloom or bright patch; any props in the near view, bones, chains, rubble pile, furniture, murals, paintings, grass, moss, plants, trees, small foreground fungi or glowing fungi (the underdark's far-layer giant mushroom silhouettes are allowed and must stay dark and unlit); bright or saturated colors, any area lighter than the variant's lightest wall color; high contrast edges, rim lights, black outlines; text, letters, numbers, watermark, signature, logo; frame, border, panel, arrow or UI element.
```
**组合方式**:每张背景 = 共用底座 + 对应关卡变体段 + 共用否定后缀,拼起来即整段可贴。三张仅岩体形态与色族不同,构图规则一致。
**后处理**:三张均不去底;最近邻降采样到终稿尺寸,色板量化到 art-bible §4.1 战斗屏场景环境子板(三张共用该子板,新增冷/灰色按 §4.1 两道门入板),单张 ≤32 色;四道机检见 §4。
### 2.2 连续地面层(`scene_stage_ground`,三关共用,顶缘以上透明)
**画什么**:全宽近景地面——**干净压实泥土为主**,整片平整、中低明度;全幅只保留**零星 3–5 颗小石**,散点分布、不成排不成堆;顶缘为不规则泥土边+阴影缝,可带 2–3 颗小石;中央平缓留空;地面跨三关恒定。
**不画什么**:瓷砖、砖缝、规则铺装、石板块、踢脚线/直亮边;草、木地板;远景/洞壁/天空;角色、生物、道具、火把/灯;中央大石或碎石堆挡站位;满铺碎石、密集砂砾、成排/成堆碎石、亮色浅棕大片、泥点噪声、垃圾杂物。
**出图画布**:终稿 = 基准屏宽 × `ground_h`(`battle_layout.tres` 新增字段,地面层实装批回填);本件是极宽薄条,平台无对应宽高比时按横向可平铺纹理条出图(左右无缝,宽度取平台方档,高度取 `ground_h` 的整数倍),终稿裁/平铺到目标宽高比,禁横向拉伸。试片阶段可按构图比例先出,终稿尺寸读表。
**正向提示词**:
```
Pixel art style. True pixel art game layer drawn with chunky square pixels, strict pixel grid alignment, hard edges, no anti-aliasing, no gradients, flat colors only, a limited palette of about eight colors, retro 16-bit look, Aseprite style, all ages, bright cheerful fantasy cavern, not grim, flat side view, orthographic, no perspective distortion. A full-width horizontal texture strip of the NEAR GROUND of a bright underground cavern arena, seen from the front, drawn on a plain flat uniform light grey #F2F2F2 background for easy keying: the ground strip occupies the lower part of the canvas and extends down to the bottom edge, and everything above its top edge is clean empty #F2F2F2 with nothing drawn in it. The ground is mostly CLEAN packed bare dirt with large calm flat areas of nearly unbroken color, medium-dark warm brown, not light tan and not bright; across the whole strip there are only THREE OR FOUR small stones in total, scattered singly and far apart, plus two or three small stones along the top edge; no rows of pebbles, no clusters, no gravel patches, no piles; the middle half of the strip is smooth and clear so characters can stand there; the surface is only slightly uneven with two or three thin cracks; no dense speckles, no heavy noise, no scattered pebbles spread everywhere, no muddy patches, no dirt clumps, no debris. The TOP EDGE of the ground is an irregular edge of packed dirt with a thin dark shadow seam, with only two or three small stones, clearly marking the boundary between the ground and the far wall behind it; the top edge must NOT be a straight tile edge, NOT a clean bright rim, NOT a masonry joint, NOT a regular curb, NOT a continuous row of stones or equal-sized pebbles. Colors: packed earth body in warm tan #968264 with large darker areas of #7A6448 and #5E4C38, darker soil patches #453723 and #3E362C, only the few small stones in #C9AF83, dark cracks and shadow seam in #4C4038 and #282220; the overall ground is medium-dark, not light tan and not bright, no large light-colored areas; matte flat colors, no gloss. No regular paving, no tiles, no bricks, no stone slabs, no grass, no plants.
```
**负向提示词**:
```
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; any purple or magenta anywhere, any color with a hue between 300 and 345 degrees; tiles, tile joints, paving, rectangular stone slabs, bricks, masonry, mortar lines, a clean straight rim, a bright curb or a regular edge along the top of the ground; grass, moss, plants, trees, fungi; any character, person, creature or animal; any prop, tool, bone, chain, furniture, torch, brazier, lantern, crystal or glowing object; any far wall, cave wall, background scenery or sky above the ground, the area above the top edge must stay plain flat uniform light grey #F2F2F2; any large boulder or rubble pile in the middle of the ground, the middle must stay clear for standing; many stones, rows of pebbles, clusters of rubble, gravel patches, stone piles, a continuous row of stones along the top edge, light tan or bright ground, large light-colored areas, dense speckles, heavy noise, scattered pebbles spread everywhere, muddy patches, dirt clumps, debris, garbage, a messy or dirty ground surface; any complete solid shape that competes for attention; bright or saturated colors, anything lighter than #C9AF83 inside the ground itself (the flat #F2F2F2 keying area above the top edge is required and allowed); high contrast edges, rim lights, black outlines; text, letters, numbers, watermark, signature, logo; frame, border, panel, arrow or UI element.
```
**后处理**:去底(`#F2F2F2` 键控,顶缘以上转透明)+ 最近邻降采样到终稿尺寸 + 色板量化;地面主体色落 art-bible §4.1 世界中层色族,单张 ≤32 色;四道机检见 §4。
---
## 3. 纵深结构与三关母题(2026-10-31 作者认可)
### 3.1 纵深结构(三关共用)
| 层次 | 放什么 | 规则 |
|---|---|---|
| 远层 | 远处洞口/通道、层叠岩体、洞底轮廓、远景建筑剪影 | 压到最深,细节最少;边缘被中层遮住,不孤立、不贴顶 |
| 中层 | 岩台、岩柱、凹壁、裂缝、主要建筑剪影 | 细节主要放这里;低对比 |
| 近层 | 左右暗色岩体作画框 | 不挡中央;禁单独圆柱/贴图贴顶 |
| 顶部/底部 | 顶部空区、底部暗部 | 顶部不挂钟乳石/吊锥;底部留给地面层 |
| 中央 | 角色站位区 | 1/2–2/3 宽保持低细节、无大障碍 |
### 3.2 三关母题(推荐项启用,可选项关闭)
| 关卡 | 推荐项(本版启用) | 可选项(本版关闭) |
|---|---|---|
| dungeon 地精 | 远处支洞/通道口、木质栈道/脚手架、削尖木桩/围栏残段 | 骨堆/头骨图腾、蘑菇丛/苔藓、暗河/细水流、丢弃箱桶/破布 |
| underdark 卓尔 | 巨型天然石柱、细长石笋群/尖塔、蛛网/蛛丝、弧形塔楼/螺旋尖塔剪影、巨型蘑菇剪影、裂谷+石桥、紫罗兰灰矿脉 | 雕刻拱门/门廊、蛛形雕刻 |
| deep_underdark 灰矮人 | 挖空石笋的城郭剪影、棱角石厅/扶壁/台阶、跨裂谷石桥、矿道口/木框矿井、烟囱/通风塔群、铜灰/银灰矿脉 | 铁箍/铁门/锁链、暗湖边缘、矮人面雕像 |
### 3.3 通用排除
钟乳石/吊锥/悬挂物、砖石墙/规则砌缝/瓷砖/铺装、贴墙感、单件圆柱贴顶、光柱/光带/光源/发光物、火把/灯、角色/生物、文字/UI、紫/洋红。
**近景地面**:独立连续地面层,画法与验收见 §2.2,不并入背景。
---
## 4. 验收(机检 + 目检)
**三张背景变体 `scene_stage_bg_<board_type>`**
- 每张画布 = (基准屏宽, `stage_h`) 逐位相符(终稿);文件名带 `_dungeon` / `_underdark` / `_deep_underdark` 后缀。
- 顶部空区无钟乳石/吊锥/悬挂物,且无任何元素触碰画面上缘;远景为天然岩体,无砖石/规则砌缝/瓷砖/方整石块。
- 纵深分层:远/中/近三层可辨;远层剪影被中层部分遮挡、不孤立、不贴顶;无贴墙感、无单件圆柱/贴图直接贴顶;无连续地平线/地面;无孤立栅栏/栈道图标。
- 背景不含近景地面、地台、平台;底带只留暗部(结算期被明细带压住)。
- 无光柱/光带/光束/光晕,无光源实体(火把/灯/发光物);明暗只由岩体层理与暗部承载。
- 明度:全图取样点 L ∈ [0.014,0.060](世界底层下沿带,art-bible §2)。
- 无 300°–345° 色相;无角色/生物/道具/文字/UI;无完整凸形焦点(立绘 > 背景)。
- 背景不引用 `wall_ambient` tint;三张按 `board_type` 选图。
- 目检:三关色族与母题——dungeon 暖石棕+支洞/木栈道/木桩围栏;underdark 冷蓝灰+巨柱/石笋/蛛网/螺旋塔/巨菇/石桥;deep_underdark 灰黑+石笋城郭/棱角石厅/石桥/矿道口/烟囱塔;可选项不出现;三张可辨为不同洞窟,不是同一张图换色。
**共用连续地面层 `scene_stage_ground`**
- 画布 = (基准屏宽, `ground_h`)(终稿;`ground_h` 读布局表);文件名无 board_type 后缀。
- 地面为干净压实泥土为主,全幅只零星几颗小石、散点分布;无瓷砖/砖缝/规则铺装/石板块/草。
- 顶缘 = 不规则泥土边/阴影缝,只带 2–3 颗小石;不是直线亮边/踢脚线,也不是一排石子;顶缘以上键控后透明、无残留底色。
- 中央 1/2–2/3 宽平缓、无大石阻挡;无成排/成堆碎石、满铺砂砾、泥点噪声、垃圾杂物。
- 地面主体色 L ∈ [0.22,0.45] 的中低段(世界中层,art-bible §2;裂缝/阴影不按明度带判定;避免浅棕/亮面)。
- 三关共用、不吃 `wall_ambient`;无角色/生物/道具/文字/UI。
- 目检:地面读作泥土/碎石,不是瓷砖或石板铺装。
**参考与入包**:参考候选可带水印;入包终稿须无水印;四件终稿均按 §0 后处理与 `art-pipeline-tools` 的判据执行。
---
## 5. 待裁与待办(不阻塞提示词成文)
1. **三张背景按 `board_type` 选图**——游戏代码改动,走需求卡片+迭代;背景 `wall_ambient` tint 退役,棋盘/世界的该槽保留。
2. **`ground_h` 字段**——布局表新增字段,地面层实装批回填;本卡试片按构图比例,终稿读表。
3. **冷/灰色入板**——underdark / deep_underdark 需要的冷蓝灰、灰黑与矿脉色按 art-bible §4.1 战斗屏场景环境子板两道门入板;三张背景共用该子板 ≤32 色。
4. **地面层出图工艺**——极宽薄条;默认横向可平铺纹理条(左右无缝);若作者要整幅不拼接,另议。
5. **小石台 `scene_stage_plaza.png`**——先保留;是否退役归实装批/后续裁决。
6. **四柱光柱程序层退役**——光柱不迁入背景;背景资产入包后该程序层退役(代码批)。
7. **风格前缀**——首张 dungeon 背景试片后由作者确认,确认后才出另外两张与地面层。
8. **可选要素池**——按 §3.2 可选项本版关闭;要加走本卡修订。
---
## 6. 不在本卡
角色与敌种立绘、棋盘格面/墙面纹理、UI 图标、护甲图标、小石台 `scene_stage_plaza.png`、整屏样张与游戏代码接线;这些各归 art-prompts、脚本管线与实装批。
+26 -50
View File
@@ -1,9 +1,9 @@
# 营地场景 · 分层生图提示词卡 v1.2
# 营地场景 · 分层生图提示词卡 v1.0
> **性质**:营地场景图(1280×800,一张可点击场景图 + 十张分层:背景层 1 + 围墙层 1 + 八个物件层)的出图执行侧文件。**场景级资产,与角色级 [art-prompts](art-prompts.md) 并列,两文件互不覆盖**。
> **性质**:营地场景图(1280×800,一张可点击场景图 + 八个物件层)的出图执行侧文件。**场景级资产,与角色级 [art-prompts](art-prompts.md) 并列,两文件互不覆盖**。
> **依据**:色彩与氛围 = `reports/提案-营地色彩与氛围脚本-2026-10-23.md`(本卡不复述色值);坐标与层序 = `artwork/2026-10-23-营地场景/布局草案-1280x800.html`;物件命名与消费链 = [asset-path-map](asset-path-map.md);画法与交付形态 = [art-bible](art-bible.md) §6.2。冲突时色彩以色彩脚本为准,画法以 art-bible 为准。
> **边界**:只管营地场景图的分层出图。角色、图标、格面走 art-prompts.md 与脚本管线,不需要提示词。
> **建立**:2026-10-25 · 状态:十条提示词成文(背景层 1 + 围墙层 1 + 八个物件层),出图通道由作者自定
> **建立**:2026-10-25 · 状态:九条提示词成文,出图未开始(出图通道由作者自定)
---
@@ -11,10 +11,10 @@
1. **出图**:按下面各条把提示词贴进生图渠道。出图前先放**风格参考图**(见 §1)。
2. **入库**:候选原图放 `artwork/candidates/<资产名>/`,文件名 `v1.png / v2.png / v3.png`。
3. **后处理**:脚本管线代跑——去底转透明、降采样到终稿尺寸(整数倍)、色板量化、四联底测试条。**背景层不去底(全幅不透明)**;围墙层与八个物件层去底转透明。后处理工具清单与用法见 [art-pipeline-tools](art-pipeline-tools.md)。
3. **后处理**:脚本管线代跑——去底转透明、降采样到终稿尺寸(整数倍)、色板量化、四联底测试条。
4. **转正**:终稿转入切片资产目录,按坐标表接线。
**出图顺序(先锁后产,不能跳)**:概念脚本 → **本卡提示词** → 贴风格参考图**先出背景层 `scene_camp_bg` 1 张** → 作者确认风格前缀 → 才扩产围墙层 `scene_camp_wall` 与八个物件层(共 9 张)。
**出图顺序(先锁后产,不能跳)**:概念脚本 → **本卡提示词** → 贴风格参考图出背景层 → 作者确认风格前缀 → 才扩产八件。
---
@@ -37,40 +37,24 @@ Style reference: the attached images are this game's own finished pixel art and
---
## 2. 背景层与围墙层(两张,不可点)
围墙从背景层拆出、独立成层:围墙层可单独锁死桩高、门洞做成透明缺口透出背景层的小路;背景层不混入暖木色、更易守住冷色占比判据(判据见 §4)。两层都不可点;按乙工序门**先只出背景层 1 张**供作者确认风格前缀,确认后才扩产围墙层与八个物件层。
### 2.1 背景层(`scene_camp_bg`,不可点,不透明全幅)
## 2. 背景层(`scene_camp_bg`,不可点,不透明全幅)
**出图画布**:2560×1600(终稿 1280×800 的 2 倍,保证整数倍降采样)
**画什么**:天空、远山、整片地面、门洞位置一条通向远处的小路
**不画什么**:木围墙、门柱、门扇、七个物件、角色、接地阴影——围墙与门柱是 §2.2 的独立层,门洞是它的透明缺口;小路在本层画好、透出来即可
**画什么**:天空、远山、地面、木围墙、门柱与门洞
**不画什么**:七个物件、门扇、角色、接地阴影——那些是上面的独立图层
```
Pixel art style. True pixel art game background layer drawn with chunky square pixels, strict pixel grid alignment, hard edges, no anti-aliasing, no gradients, flat colors only, a limited palette of about 24 colors, retro 16-bit look, Aseprite style, all ages, flat side view, orthographic, no perspective distortion. Wide horizontal composition, 16:10 aspect ratio. This is the FAR BACKGROUND LAYER ONLY of a small adventurer camp: sky, distant hills and the whole ground. It must contain no palisade wall, no gate posts, no camp objects, no gate leaves, no characters and no drop shadows, because all of those are drawn as separate transparent layers on top of this one. COLOR SCRIPT — cool recedes, warm advances: the sky, the hills and the ground are all COOL, pale, desaturated and low in contrast; there is no warm accent anywhere in this layer, warm color belongs only to the separate object layers drawn on top. ATMOSPHERIC DEPTH: every plane that is farther away is lighter, closer to the value of the sky, cooler, lower in contrast and simpler in detail, while the nearest plane is the darkest and highest in contrast. SKY (top of frame): the lightest thing in the picture, flat pale cool off-white with a faint blue-grey tint, no yellow or cream tone, no sun anywhere; the very top strip of the frame, about one sixteenth of the frame height, stays completely calm and empty, reserved as clear space with nothing in it; at most one or two extremely simple flat low-contrast clouds. FAR DISTANCE: two or three layers of low rolling hill silhouettes in pale cool blue-grey, each farther layer lighter, cooler and lower in contrast than the one in front, fading towards the value of the sky, no trees, no individual foliage. HILLS TO GROUND: the hills fade gradually and smoothly down into the ground, with NO visible horizon line and NO distant ground band — the transition must not read as a separate horizontal stripe of a different color. GATE PATH: in the middle of the frame, between x=1040 and x=1520, one clearly visible dirt path runs from the ground at two thirds of the frame height measured from the bottom edge away into the distance between the hills, narrowing as it recedes, painted in a muted desaturated grey-brown earth tone, never golden or warm yellow; this path shows through the empty gate opening of the wall layer above. FOREGROUND GROUND: the darkest area of the picture, dry packed bare earth in a neutral desaturated grey-brown, never golden, amber or warm yellow, hard flat color blocks, hard edges, no gradient, no grass, no grass tufts, no weeds and no plants of any kind. The foreground ground is completely empty apart from the dirt path: no objects, no icons, no badges, no markers, no decorations of any kind. 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; drop shadows, contact shadows or any shadow band; 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, a separate horizontal distant ground band or any distant grass strip below the hills; trees, forests or foliage in the distance; grass, grass tufts, weeds or plants in the foreground; a palisade wall, wooden fence, fence posts, gate posts or any wall structure; any warm, golden, amber or yellow cast on the sky, on the hills or on the ground; any camp object, furniture, crate, barrel, fire, tent or tool; any gate leaf, door panel or hinge; any purple or magenta anywhere; any text, letters, numbers, watermark, signature or logo; any frame, border, panel, arrow or UI element; any icon, badge, item tile, emblem, sign, marker or symbol anywhere in the frame; any characters, people, creatures or animals.
Pixel art style. True pixel art game background layer drawn with chunky square pixels, strict pixel grid alignment, hard edges, no anti-aliasing, no gradients, flat colors only, a limited palette of about 24 colors, retro 16-bit look, Aseprite style, all ages, flat side view, orthographic, no perspective distortion. Wide horizontal composition, 16:10 aspect ratio. This is the BACKGROUND LAYER ONLY of a small adventurer camp: sky, distant hills, ground and the wooden palisade wall around it. It must contain no camp objects, no gate leaves, no characters and no drop shadows, because all of those are drawn as separate transparent layers on top of this one. COLOR SCRIPT — cool recedes, warm advances: the sky, the hills, the ground and the wall are all COOL, pale, desaturated and low in contrast; there is no warm accent anywhere in this layer, warm color belongs only to the separate object layers drawn on top. ATMOSPHERIC DEPTH: every plane that is farther away is lighter, closer to the value of the sky, cooler, lower in contrast and simpler in detail, while the nearest plane is the darkest and highest in contrast. SKY (top of frame): the lightest thing in the picture, flat pale cool off-white with a faint blue-grey tint, no yellow or cream tone, no sun anywhere; the very top strip of the frame, about one sixteenth of the frame height, stays completely calm and empty because a HUD bar is drawn over it; at most one or two extremely simple flat low-contrast clouds. FAR DISTANCE: two or three layers of low rolling hill silhouettes in pale cool blue-grey, each farther layer lighter, cooler and lower in contrast than the one in front, fading towards the value of the sky, no trees, no individual foliage; the foot of the hills is cut off and hidden behind the wall, so there is no visible horizon line and no distant ground band between the hills and the wall. MIDDLE GROUND: the base line where the logs meet the ground sits at two thirds of the frame height measured from the bottom edge; at that height runs a wooden palisade wall across the whole width of the frame, built from closely spaced vertical logs standing side by side with no gaps between them, every log cut to a sharp point at the top, a solid barrier that completely blocks the view of the outside — no horizontal rails, no see-through gaps, no ranch-style post-and-rail fence; the wall is painted in a muted, greyed wood brown. In the middle of the wall one wide gap holds two thick gate posts slightly taller than the wall, and between them an opening showing a dirt path running away into the distance; the gate opening itself stays empty, because the two gate leaves are a separate layer. FOREGROUND GROUND: the darkest area of the picture, dry packed bare earth in a neutral desaturated grey-brown, never golden, amber or warm yellow, hard flat color blocks, hard edges, no gradient, no grass, no grass tufts, no weeds and no plants of any kind; the ground meets the foot of the wall cleanly with no shadow band and no gradient. 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; drop shadows, contact shadows or any shadow band; 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, a distant ground band or any distant grass strip below the hills; trees, forests or foliage in the distance; grass, grass tufts, weeds or plants in the foreground; a ranch-style post-and-rail fence, a see-through fence, flat-topped posts or horizontal rails; any warm, golden, amber or yellow cast on the sky, on the hills or on the ground; any camp object, furniture, crate, barrel, fire, tent or tool; any gate leaf, door panel or hinge; any purple or magenta anywhere; any text, letters, numbers, watermark, signature or logo; any frame, border, panel, arrow or UI element; any characters, people, creatures or animals.
```
### 2.2 围墙层(`scene_camp_wall`,不可点,透明底)
**出图画布**:2560×1600(与背景层同画布,门洞 x 坐标直接对齐);墙横贯画在出图 y480–620 这条**窄带**内,其余为纯色底 `#F2F2F2`。落盘由 S4 后处理裁成终稿外接矩形 `(0, 240, 1280, 70)` / 出图 `(0, 480, 2560, 140)` 的细条,**不做全幅 1280×800 落盘**(全幅约 3.9 MB 显存,细条约 0.35 MB)。
**画什么**:横贯全宽的密排竖木桩墙(左右两段)+ 两根略高的门柱,门洞处完全透明
**不画什么**:天空、远山、地面、小路、门扇、七个物件、角色;门洞内不画任何东西,透出背景层的小路
```
Pixel art style. True pixel art game layer drawn with chunky square pixels, strict pixel grid alignment, hard edges, no anti-aliasing, no gradients, flat colors only, a limited palette of about 24 colors, retro 16-bit look, Aseprite style, all ages, flat side view, orthographic, no perspective distortion. Wide horizontal composition, 16:10 aspect ratio. This is the PALISADE WALL LAYER ONLY of a small adventurer camp, drawn on a plain flat uniform light grey #F2F2F2 background for easy keying. A wooden palisade wall runs straight across the full width of the frame, seen from the front, built from closely spaced vertical logs standing side by side with no gaps between them, every log cut to a sharp point at the top, a solid barrier with no horizontal rails, no see-through gaps, no ranch-style post-and-rail fence. The wall is SHORT and LOW: including the pointed tips the whole band occupies only about one eighteenth of the total frame height, a thin horizontal strip, NOT a tall barrier; the logs stand only about one eighteenth of the total frame height above their base line. In the middle of the wall one wide gap holds two thick gate posts slightly taller than the wall, and the entire opening between them is completely EMPTY — plain flat uniform light grey #F2F2F2 showing through, no logs, no path, no ground, no scenery inside the opening, because the dirt path and the hills belong to the background layer below and the gate leaves are a separate object layer. The wall is painted in a muted greyed wood brown, with a thin warm cream outline around the whole silhouette, flat shading. 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; drop shadows or contact shadows; blur or compression artifacts; a vignette or dark corners; any sky, hills, ground, grass, dirt path or scenery of any kind; any gate leaf, door panel or hinge; any camp object, furniture, crate, barrel, fire, tent or tool; any characters, people, creatures or animals; any purple or magenta anywhere; any text, letters, numbers, watermark, signature or logo; any frame, border, panel, arrow or UI element.
```
### 2.3 出图画布上的坐标(终稿 ×2)
### 出图画布上的坐标(终稿 ×2)
| 元素 | 终稿 1280×800 | 出图画布 2560×1600 |
|---|---|---|
| 顶栏 HUD 保留带 | y ≤ 48 | **y ≤ 96**(保持空旷) |
| 背景层 `scene_camp_bg` | 全幅 1280×800 | 全幅 2560×1600 |
| 围墙带(wall 层桩身) | y 267–310(**高 43px**) | y 534–620(**高 86px**) |
| 门柱(wall 层,略高) | y 240–310;x 500–520 / 760–780 | y 480–620;x 1000–1040 / 1520–1560 |
| 门洞(wall 层透明缺口) | x 520–760 | x 1040–1520 |
| 门洞内小路(画在 bg 层) | x 520–760,自 y310 向上收窄至远山 | x 1040–1520,自 y620 向上收窄至远山 |
| 围墙带 | y 267–310 | **y 534–620** |
| 门洞(必须留空) | x 520–760 | **x 1040–1520** |
| 门柱 | x 500–520 / 760–780 | **x 1000–1040 / 1520–1560** |
---
@@ -78,7 +62,7 @@ Pixel art style. True pixel art game layer drawn with chunky square pixels, stri
### 组装方式(不要逐条重复前缀)
每件提示词 = **风格前缀** + **本件正文** + **否定后缀**。前缀与后缀在**本节单点定义**,**八件共用**,避免同一段话八处维护。背景层与围墙层用各自的完整提示词(§2.1/§2.2),不用本节的物件前缀。
每件提示词 = **风格前缀** + **本件正文** + **否定后缀**。前缀与后缀在**本节单点定义**,九张共用,避免同一段话九处维护。
**风格前缀**(八件共用,照抄):
@@ -94,16 +78,16 @@ Do not add any of the following: realistic, photorealistic or 3D rendering; pain
### 逐件正文(只替换这一段)
| 件 | z 序 | 终稿矩形 | 出图画布 | 正文 |
| 件 | 层 | 终稿矩形 | 出图画布 | 正文 |
|---|---|---|---|---|
| 布告板 | 2 | 130×140 | 260×280 | §3.1 |
| 门扇 | 3 | 240×220 | 480×440 | §3.2 |
| 木桩 | 4 | 120×180 | 240×360 | §3.3 |
| 锻炉·铁砧 | 4 | 240×240 | 480×480 | §3.4 |
| 帐篷 | 4(不可点) | 300×170 | 600×340 | §3.5 |
| 宝箱 | 5 | 130×90 | 260×180 | §3.6 |
| 笔记本 | 5 | 100×80 | 200×160 | §3.7 |
| 篝火 | 6 | 160×160 | 320×320 | §3.8 |
| 布告板 | L1 | 130×140 | 260×280 | §3.1 |
| 门扇 | L2 | 240×220 | 480×440 | §3.2 |
| 木桩 | L3 | 120×180 | 240×360 | §3.3 |
| 锻炉·铁砧 | L4 | 240×240 | 480×480 | §3.4 |
| 帐篷 | L5(不可点) | 300×170 | 600×340 | §3.5 |
| 宝箱 | L6 | 130×90 | 260×180 | §3.6 |
| 笔记本 | L7 | 100×80 | 200×160 | §3.7 |
| 篝火 | L8 | 160×160 | 320×320 | §3.8 |
**3.1 布告板(→ 图鉴)**
```
@@ -149,18 +133,10 @@ A campfire made of a ring of grey stones around crossed stacked logs with a warm
## 4. 验收(机检 + 目检)
**背景层 `scene_camp_bg`**
**背景层**
- 黄度 =(R+G)/2−B 分区取样:天空 ≤20、远山 ≤20、地面 ≤35
- 冷色像素占比 ≥55%;本层不应出现任何暖色高饱和像素
- 目检:顶部约 1/16 完全空旷;**无地平线、无远景地面带**(远山自然渐隐过渡到地面);不含围墙、门柱、门扇、物件、角色
- 目检/机检:门洞 x1040–1520 处**有一条清晰可辨、向远处收窄的土路**(非纯色块),透出「出去即冒险」
- 机检/目检:全幅**无任何独立物件/图标/徽章/标记**(前景地面除小路外全空);参考做法=中下方块区独立色数应≈邻区(旧口径 v1 该区仅 179 色)
**围墙层 `scene_camp_wall`**
- 透明底 `#F2F2F2` 可去底、奶油描边闭合
- **桩身高度 = 出图 y534–620(终稿 43px);门柱略高 y480–620。桩身超出围墙带下沿 y620 达 5px 以上即判红**
- 目检:密排竖木桩、桩顶削尖、不透缝、无横木;门洞 x1040–1520 **完全透明**(透出 bg 小路)、无门扇
- 单张色数 ≤32(量化后)、缩放为整数倍无拉伸痕迹
- 目检:顶部约 1/16 完全空旷;无地平线;围墙密排尖桩、桩顶削尖、不透缝;门洞空着没有门扇
**八件**
- 单件居中、四周留边、整件完整不出画
@@ -174,7 +150,7 @@ A campfire made of a ring of grey stones around crossed stacked logs with a warm
## 5. 待裁(不阻塞出图,阻塞坐标表与定稿)
1. **帐篷尺寸**:现 300×170 待重定,重定后按比例重出
2. **门扇高宽**:现 240×220,围墙带只有 43px 高;围墙独立成层后门扇叠在门洞上,两者高宽关系待裁
2. **门扇高宽**:现 240×220,围墙带只有 43px 高,比例待裁
3. **布告板位置**:现 y330 悬空在围墙下方,建议 `(845, 268, 130, 140)` 挂回围墙带
4. **描边颜色追认**:本卡按奶油色(去底技术前提);若改参照物的深灰褐,需换去底方案
5. **营地环境子板色值**:art-bible §4.1 为数值单点,色值待作者拍板,本卡不复述
+20 -19
View File
@@ -85,7 +85,7 @@
| 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API |
|---|---|---|---|---|
| **ConfigDB**(autoload,D2) | 全部玩法数值表与表现层布局配置表(`data/tables/*.tres` + `data/schemas/*.gd`);SCHEMA_VERSION;加载/校验/override/诊断状态机。**行族访问器归位各 schema 表类(表管自己的行查询),本类只留加载/校验/override/诊断门面;表持有成员按域收进四张域容器 Resource(`config_domain_combat/run/crossrun/presentation.gd`——前三件迭代 41 已建件,第四件表现层布局域 2026-10-30 建件,类型化成员 7/7/5/1);三张 resolver 表(board_gen.resolve_row/enemy.resolve_rowset/difficulty.resolve_modifiers)经 `load_tables` 装配段注入各容器,resolver 文件与键零搬移**——红线不变:本类仍是唯一加载与持有单点,"经 ConfigDB 单点读取"=经其持有的表对象 | 类型化域容器属性(每域一张容器);公开面 8(push_diag/is_fatal/reset_diagnostics/diagnostics/diagnostics_count/load_tables/set_reload_gate/reload)、类变量 10 | 无(基础层顶点) | Resource/.tres 加载、autoload 生命周期——LOW |
| **ConfigDB**(autoload,D2) | 全部玩法数值表(`data/tables/*.tres` + `data/schemas/*.gd`);SCHEMA_VERSION;加载/校验/override/诊断状态机。**行族访问器归位各 schema 表类(表管自己的行查询),本类只留加载/校验/override/诊断门面;表持有成员按域收进三张域容器 Resource(`config_domain_combat/run/crossrun.gd`——已建件(迭代 41),类型化成员 7/7/5);三张 resolver 表(board_gen.resolve_row/enemy.resolve_rowset/difficulty.resolve_modifiers)经 `load_tables` 装配段注入各容器,resolver 文件与键零搬移**——红线不变:本类仍是唯一加载与持有单点,"经 ConfigDB 单点读取"=经其持有的表对象 | 类型化域容器属性(每域一张容器);公开面 8(push_diag/is_fatal/reset_diagnostics/diagnostics/diagnostics_count/load_tables/set_reload_gate/reload)、类变量 9 | 无(基础层顶点) | Resource/.tres 加载、autoload 生命周期——LOW |
| **SlotStore**(`core/slot_store.gd`,D3 存档槽位域件,已建件——迭代 41 存量债批) | 存档三槽位文件域唯一所有者(自 save_manager 收编槽位族):槽位挂载与模板、激活与建删、槽位摘要窥视(peek 族);改名覆盖原语(_rename_overwrite)留 save_manager(IO 原语单点) | 槽位读写原语族+摘要投影(公开 10/类变量 4;SaveManager 与菜单消费方经 `save.slots.` 直连) | save_manager(注入路径与模板配置);FileAccess——LOW |
| **MetaStateStore**(`core/meta_state_store.gd`,D3 存档内元进度数据件,已建件——迭代 41 存量债批) | 存档内元进度数据的读写唯一层(自 save_manager 收编 accessor 族:钥石/道具解锁/树节点与叉侧/锻造路线/同调/真视/计数器/摘要——数据读写原语,不含业务规则);save_manager 与 meta_progression 双 God Class 的共同病根=该数据域摊在两文件,本件即其归一 | 写口原语 13+只读投影 6(tree_state/forge_state/attune_state/career_state 四投影+keystone_balance/item_unlocked)=公开 19(add_keystone 私有 `_add_keystone`),零 _data 副本零缓存;MetaProgression 业务层与营地/锻造 UI 消费方经 `save.meta_state.` 直连(meta 的纯转发读方法已退役) | save_manager(序列化接线);FileAccess——LOW |
| **RngService**(autoload,D2) | master_seed、各流 scope 计数器(封闭流词表现值以 `RngServiceCore.PURPOSE_TAGS` 为准;增流走 P1 评审) | `set_master_seed()`(唯一调用方 C2);`open_stream(stream)` 有状态门面;`derive_at(stream, scope)` 纯函数;只读计数器 | ConfigDB(无) | 无——纯逻辑 |
@@ -110,7 +110,7 @@
| **HeroLedger**(`core/hero_ledger.gd`,冒险域主角实体账,已实装(2026-10-27 迭代 39 拆件批)) | 冒险生命周期主角数值与获得记录唯一所有者:生命与 GP 钱包(gain/spend/clear 单写原语,钱包事件发射点归件)、锻造强化快照、调试百分比、攻击/甲类型轴快照、特性持有集(活引用注入——关内兑付当关生效)、本局钥石增量与逐杀明细、真视使用记录;获得记录三层结构=获得记录列表(三选一件/商店购买/战末奖励各一条)→属性增益明细(带来源指回)→四轴汇总(由明细推导);生效上限与回血封顶公式单点归件 | 构造注入;单写原语族+只读投影;断点自交片段(账本键+获得日记键) | ConfigDB(表值读取);由 AdventureRunner 冒险开始创建、注入 CurioStop/level_runner/ShopSession/战斗 encounter | 无(RefCounted 纯逻辑) |
| **AttuneLoadout**(`core/attune_loadout.gd`,同调配装件,已实装(2026-10-27 迭代 39 拆件批)) | 装备中的秘宝件对象集唯一所有者(每件内含充能单位与重置周期);同调充能的物化行为唯一事实源——种行/补行改写时同步(RunLedger 充能字典轨与差额对账函数退役);旧档 aux_items 同调行迁移归件 | 构造注入;充能查询/消耗/按周期重置原语;断点自交片段(attunement_charges 键,键名与策略不变) | ConfigDB(秘宝行集);TreasureItems(同调行投放面);注入战斗使用路径 | 无 |
| **CurioStop**(`core/curio_stop.gd`,三选一停点件,已实装(2026-10-27 迭代 39 拆件批)) | 三选一停点编排唯一所有者(架构原则 9 本域承载):停点三态(关卡完成三选一在途/已兑付待推进/奖励节点三选一在途)、刷新三源账(刷新件 X/营地池 Y/刷新券存量/付费刷新计数)、兑付方法族(pick/refresh/redeem/skip)、凭证出箱(RAP/时沙待注入);三选一信号面自带;零自动推进停点语义承载 | 对外=开停点/刷新/兑付/放行谓词/交断点片段五组入口+信号面(curio_choice_presented/curio_resolved);由 AdventureRunner 关卡完成受理时调用 | ConfigDB;注入 CurioDeck(抽签/摘牌)与 HeroLedger(落账);随机只经 CurioDeck 的 reward_pick 封闭流 | 无 |
| **breakpoint_store**(`core/breakpoint_store.gd`,冒险域·断点组装与回放件,已建件——迭代 45) | 存档断点组装与回放唯一承载(自 adventure_runner 收编 6 成员+函数族):断点快照拼盘、回放回填、读侧策略分发;`BREAKPOINT_FIELDS` 27 键登记单源随件(键名/策略标签/键序冻结) | 构造=引用束注入(九引用束成员解包为原名成员——保迁移函数体逐字);`resume_adventure` 留宿主(壳+宿主侧回填语句——R2 所有权缝分家);断点键面零变化;实测类变量 15(贴顶禁再增) | adventure_runner(宿主);注入主角账三件与 curio/stop/bank/loadout 引用 | 无(RefCounted 纯逻辑) |
| **breakpoint_store**(`core/breakpoint_store.gd`,冒险域·断点组装与回放件,2026-10-29 零豁免裁设计闭合——实现批建件) | 存档断点组装与回放唯一承载(自 adventure_runner 收编 6 成员+函数族):断点快照拼盘、回放回填、读侧策略分发;`BREAKPOINT_FIELDS` 27 键登记单源随件(键名/策略标签/键序冻结) | 构造=引用束注入;`resume_adventure` 留宿主薄壳;断点键面零变化 | adventure_runner(宿主);注入主角账三件与 curio/stop/bank/loadout 引用 | 无(RefCounted 纯逻辑) |
### 功能层
@@ -121,8 +121,8 @@
| **RewardGrant**(`core/reward_grant.gd`,B1 域·奖励授予件,2026-10-26 编排域拆件设计定稿——实现批建件) | 奖励授予唯一兑付管线(自 battle_orchestrator 收编 grant 族):极性字典路由与封印溢价兑付(_grant_routed)、三种行应用(flat/percent/gp)、伤害单据提交面(_submit 族)、清图奖励与身份授予、秘宝使用编排(use_treasure 四步)、战斗域 GP 缓冲 escrow 与授予段暂存伤害闸(_defer_board_damage/_deferred_board) | use_treasure 编排入口(treasure_interact_controller 经组合根现值回调直连);授予入口(结算段类直调);只读投影(escrow 读与 GP 掉落合计——宿主呈现快照与 _roll_gp_drop 消费) | B4 RewardEconomy(polarity_row/grant);B1 域 DamageController(开单);BattleFxHost 引用(treasure_used 事件发射与计数器消耗);A2 minesweeper(校验回调/fx_reveal/remove_mines_in);A3 action_economy(相位闸/grant_ap/queue_ap_delta);B3 status_container(apply_effect/池读);B2 unit_container(hero_unit/heal);ConfigDB;注入 emit Callable、宿主 fatal Callable(battle_result 状态机唯一写点留宿主)、宿主 attune 读投影(_attune_safe_seen)、encounter 账本引用;TreasureItems 经宿主 setter 转发注入(库存注入时序在宿主构造之后) | 无(零随机零 await——授予期零随机口径,roll 值授予前已定) |
| **damage_controller**(B1 域·伤害单据管线) | 伤害单据唯一兑现管线(单据九栏目声明→分量掷点/克制修正/伤害下限归一→明细行发射;双方同规) | 兑付入口(编排侧开单)+ fx 揭示回调注入位 | B2 单位实例(单据目标传入);B1 注入(EffectContext 引用束与编排回调) | 无 |
| **BoardInstaller**(`core/board_installer.gd`,B1 域·装板域件,2026-10-29 尾波清偿批设计闭合——实现批建件,细则见「战斗编排域拆件定稿」节轴丙) | 棋盘安装与变异布置域唯一承载(自 battle_orchestrator 收编装板族六函数):生成受理、全局作用域变异决议、资源摇号资格域组装(roll_board 恰一次)、region 变异决议与连通片布置;BoardGenerator 实例随件自建自接线(宿主成员退役)——宿主侧装板后状态复位(封印/完美计数清零、板序推进、board_changed 发射、秘宝叠加层退役)留宿主薄壳,时序逐字保持 | `install(during_round) -> bool` 单入口;构造=引用束注入(rng/db/minesweeper/reward_economy/encounter 只读引用+宿主 fatal Callable——防 _init max-parameters 新键) | A1 board_generator(件内持有);A2 install_board;B4 roll_board/board_skew 写;A4 变异决议行集经 ConfigDB;board_gen/variant_place 两封闭流随件、流名与开流时点零漂移 | 无(零 await——装板全同步) |
| **RoundCycle**(`core/round_cycle.gd`,B1 域·轮循环驱动件,已建件——迭代 44) | 轮循环驱动域唯一承载(自宿主收编 7 成员):结算五段段件持有与驱动、重入门闸、开轮摇号、踩雷账 | 三参直构(host/fx_host_ref/reward_grant_ref——五段构造透传不落成员);段驱动入口由宿主接线调用;实测类变量 8/公开方法 3 | B1 宿主;settlement/ 五段段类;A3 相位读 | 无 |
| **BattleFacts**(`core/battle_facts.gd`,B1 域·战斗事实件,已建件——迭代 44) | 战斗事实域唯一承载(自宿主收编 14 成员):受理事实(encounter)、轮 facts 缓冲(reveals/seals/path)、封印判定账、事实溯源、同调快照读面;attune 状态两成员随件(行为函数留宿主) | 零参直构;宿主与段类经注入引用读写;实测类变量 15(贴顶)/公开方法 4(reset_round+三 mark 写口) | B1 宿主;A2/A3 只读 | 无 |
| **RoundCycle**(`core/round_cycle.gd`,B1 域·轮循环驱动件,2026-10-29 设计闭合——实现批建件) | 轮循环驱动域唯一承载(自宿主收编 7 成员):结算五段段件持有与驱动、重入门闸、开轮摇号、踩雷账 | 构造=引用束注入;段驱动入口由宿主接线调用 | B1 宿主;settlement/ 五段段类;A3 相位读 | 无 |
| **BattleFacts**(`core/battle_facts.gd`,B1 域·战斗事实件,2026-10-29 设计闭合——实现批建件) | 战斗事实域唯一承载(自宿主收编 14 成员):受理事实(encounter)、轮 facts 缓冲(reveals/seals/path)、封印判定账、事实溯源、同调快照读面;attune 状态两成员随件(行为函数留宿主) | 构造=引用束注入;宿主与段类经注入引用读写 | B1 宿主;A2/A3 只读 | 无 |
| **settlement/ 五段段类**(B1 域·结算段件) | B1 每轮结算序列的五段逻辑件(授予/增益减益/战斗/衰减/判定——细则见下「战斗域装配现状」节) | 段处理入口(B1 接线调用);可直接 `new()` 单测 | B2/B3/B4 兑付面与 B1 轮 facts 缓冲(各段按职责) | 无 |
| **level_runner**(C1-lite,切片已建) | 关卡域生命周期(节点链推进、共享 B4 + HP 携带、关卡末 level_clear) | 节点推进接口;LevelTable(`level.tres`——节点 enum {battle,reward,rest,boss}、末节点必须 Boss、ConfigDB 跨表校验⑧) | B1(直构 BattleOrchestrator 接线战斗)、ConfigDB LevelTable | 无 |
| **run_structure**(C2) | 冒险/关卡序列、失败重开、**master_seed 唯一接线方** | (契约规范源:`../../gdd/systems/冒险循环/冒险结构.md`) | RngService.set_master_seed、C3/D2 | 无 |
@@ -164,15 +164,15 @@
|---|---|---|---|---|
| **D1 HUD**(呈现面拆分持续换代:组合根 main.gd + 三屏壳(MenuScreen/CampScreen/AdventureScreen)+ views/ 视图单元(现行承载面见「呈现层装配与会话生命周期」节;早期 9 单元清单与 LevelStripView 已随场景换代退役);营地覆盖层=四柜台并排〔树淬炼主界面/锻造工坊·秘宝匣钥匙门/图鉴常开——迭代 21 T6 程序占位重排〕) | 全部 Control/CanvasLayer(例外:BoardView 棋盘本体与 BattleStageView 站桩本体 = Control 壳 + SubViewportContainer + SubViewport + Node2D 世界〔BoardWorld/CellUnit;StageWorld/StandeeBody——B 区 slot_row 伴随件留壳层〕,探针契约面不变——棋盘 Node2D 迁移批 Phase A 2026-09-23 / 战斗舞台 Phase B 2026-09-26)、输入→意图翻译(**唯一提交路径 = settle_batch,不直调 A3**)、呈现义务状态记录(A2×6 / B2×4 / B3×4 / B4×5 / B1×3) | 视图单元接口(信号外发、setter 只读注入) | A2 compute_move_path / ActionOutcome;A3 ap/rap;B1 步骤流行协议(数据源);ConfigDB display_name | **MEDIUM**:Control / CanvasLayer / draw_* / InputEvent / RichTextLabel——对照 breaking-changes.md 4.5–4.7 条目(CanvasItem 线条无抗锯齿羽化、设备 ID 常量、RichTextLabel 图片参数两轮变化) |
| **组合根拆件**(呈现侧写口子件:curio_interact_controller / camp_shop_presenter / treasure_interact_controller) | 代组合根执行核心写调用(冒险节点后续推进/营地购买与刷新/道具使用——依赖与回调由 main 构造注入) | 各拆件的写入口(仅组合根装配面可达;视图零直连) | 构造注入的核心写引用(推进/商店/道具各域——详见各拆件头注) | 无 |
| **ui_registry**(`presentation/ui_registry.gd`,界面注册面,已建件——迭代 44) | 呈现层接口面唯一承载:层序合同(LAYER_CONTRACT)迁驻与合同寻址、三域句柄容器 ui_screens(9 屏壳与覆盖层句柄)/ui_battle(5 战区句柄)/ui_modals(13 模态句柄+ModalFlow);组合根经其一级寻址接线,探针挂载假设迁移为 `main.ui.<域容器>.<句柄>`;七个探针别名/转发成员随批消灭 | 三容器属性+合同寻址口(RefCounted 门面,不挂树、零会话期引用);四件(UiRegistry/UiScreens/UiBattle/UiModals)类变量 3/9/5/14,ModalFlow 随 UiModals 容器构造即建 | 构造注入:三屏壳、覆盖层、战区句柄、ModalFlow(main_ui_build 交付随之改型) | 无(RefCounted) |
| **board_hover**(`views/board_hover.gd`,悬停预承诺呈现域件,已建件——迭代 45) | 悬停反馈域唯一承载(自 board_view 收编 11 函数族+_hover/_last_click 两成员):三语义光标、目标格边框、BFS 路径预览、chord 双击首遇锚;_r0 出生展开区成员留宿主 | 构造=引用束注入实为 7 项(cells/minesweeper/diggable 引用+格命中换算/光标写入/hover_forbidden/chord_attempted 四 Callable——卡片预估 5 项,11 函数逐字迁移的最小必需面);三入站口留宿主委托;hover_probe 读面留宿主 | board_view(宿主);输入事件经宿主入站口 | 无(RefCounted) |
| **cell_base_layer/cell_mark_overlay**(`views/`,单格两绘制域件,已建件——迭代 45) | 单格绘制域拆分(自 board_cell_unit 状态件 `_CellPaintState` 收编,入参与该层绘制命令同件):基座层(底面/描边/立面/投影/接触带/倒角,12 成员)与标识叠加层(标记/字形/徽章/封印/点迹/高亮/退色,13 成员);宿主 _draw 退为六步时序器,类变量 30→10 | 构造注入;绘制命令由宿主 _draw 按层序调用 | board_cell_unit(宿主);gdstyle 键各文件独立计数(12/13 均 ≤15) | 无(RefCounted) |
| **standee_vitals/standee_motion**(`views/`,站桩两状态件,已建件——迭代 45) | 站桩状态域拆分(自 `_StandeeState` 真实 25 成员收编):身份命值(hp/atk/状态值族,12 成员)与资产演出(动作/姿态/位移演出族,11 成员);三个演出探针计数器留宿主,宿主类变量 19→10 | 构造注入;st(沿用)/mo 两实例由宿主持有 | standee_body(宿主);battle_stage_view 写入面逐字保持 | 无(RefCounted) |
| **ui_registry**(`presentation/ui_registry.gd`,界面注册面,2026-10-29 零豁免裁设计闭合——实现批建件) | 呈现层接口面唯一承载:层序合同(LAYER_CONTRACT)迁驻与合同寻址、三域句柄容器 ui_screens(9 屏壳与覆盖层句柄)/ui_battle(5 战区句柄)/ui_modals(13 模态句柄+ModalFlow);组合根经其一级寻址接线,探针挂载假设迁移为 `main.ui.<域容器>.<句柄>`;七个探针别名/转发成员随批消灭 | 三容器属性+合同寻址口(RefCounted 门面,不挂树、零会话期引用) | 构造注入:三屏壳、覆盖层、战区句柄、ModalFlow(main_ui_build 交付随之改型) | 无(RefCounted) |
| **board_hover**(`views/board_hover.gd`,悬停预承诺呈现域件,尾波清偿批 D2 设计闭合——实现批建件) | 悬停反馈域唯一承载(自 board_view 收编 11 函数族+_hover/_last_click 两成员):三语义光标、目标格边框、BFS 路径预览、chord 双击首遇锚;_r0 出生展开区成员留宿主 | 构造=引用束注入(cells/minesweeper/diggable 引用+光标写入与 hover_forbidden 注入回调);三入站口留宿主委托;hover_probe 读面留宿主 | board_view(宿主);输入事件经宿主入站口 | 无(RefCounted) |
| **cell_base_layer/cell_mark_overlay**(`views/`,单格两绘制域件,2026-10-29 设计闭合——实现批建件) | 单格绘制域拆分(自 board_cell_unit 状态件 `_CellPaintState` 收编,入参与该层绘制命令同件):基座层(底面/描边/立面/投影/接触带/倒角,12 成员)与标识叠加层(标记/字形/徽章/封印/点迹/高亮/退色,13 成员);宿主 _draw 退为六步时序器,类变量 30→10 | 构造注入;绘制命令由宿主 _draw 按层序调用 | board_cell_unit(宿主);gdstyle 键各文件独立计数(12/13 均 ≤15) | 无(RefCounted) |
| **standee_vitals/standee_motion**(`views/`,站桩两状态件,2026-10-29 设计闭合——实现批建件) | 站桩状态域拆分(自 `_StandeeState` 真实 25 成员收编):身份命值(hp/atk/状态值族,12 成员)与资产演出(动作/姿态/位移演出族,11 成员);三个演出探针计数器留宿主,宿主类变量 19→10 | 构造注入;st(沿用)/mo 两实例由宿主持有 | standee_body(宿主);battle_stage_view 写入面逐字保持 | 无(RefCounted) |
| **HudPresenter**(`presentation/hud_presenter.gd`,迭代 37 加注) | 战斗屏**数据投影+文案拼装静态族**——核心状态→呈现文案的全部翻译集中于此(B/C/D 区文案与投影),静态无状态 | `refresh(…)` 全量重查装配(组合根每次动作/结算返回后调用,漏调即陈旧呈现)+只读静态投影族 | 核心读取只走 `settlement.presentation_snapshot()` 成文快照面(禁链式穿透结算内部);ConfigDB display_name | 无(RefCounted 静态) |
| **board_resolvers**(`presentation/board_resolvers.gd`,迭代 37 拆出) | 棋盘每格渲染数据的只读解析回调四函数(奖励徽章身份——挖掘期 Active 相位内、地形变异数字遮蔽与角标、调试加成生效值)——有态绑定件,与无态静态投影族 HudPresenter 职责互斥 | 构造注入 db、调试浮窗与结算活态取值,产出绑定 Callable 供组合根接线 | ConfigDB / DebugOverlay / 结算活态取值 Callable | 无(纯投影) |
| **main_ui_build**(`presentation/main_ui_build.gd`,迭代 37 拆出) | `_build_ui` 八步拆分件——组合根 UI 装配分步承接(三屏壳实例化、视图句柄接线、覆盖层装配与模态编排注入按步拆开);main 侧留同名薄委托,装配序与 z 序零改动 | 分步静态函数(成员访问经 root 显式传入) | 层序逻辑不在此件——唯一事实源=`ui_registry.LAYER_CONTRACT`+`ui.apply_layer_contract(root)`(迭代 44 迁驻注册面) | 同 D1(Control 装配面) |
| **main_ui_build**(`presentation/main_ui_build.gd`,迭代 37 拆出) | `_build_ui` 八步拆分件——组合根 UI 装配分步承接(三屏壳实例化、视图句柄接线、覆盖层装配与模态编排注入按步拆开);main 侧留同名薄委托,装配序与 z 序零改动 | 分步静态函数(成员访问经 root 显式传入) | 层序逻辑不在此件——唯一事实源仍是 `main.LAYER_CONTRACT` + `_apply_layer_contract()` | 同 D1(Control 装配面) |
| **main_adventure_flow**(`presentation/main_adventure_flow.gd`,迭代 37 拆出) | main 冒险流程族——菜单开局/续玩后的冒险编排接线、节点事件分发、终局面与选路屏开合;逐字搬运,main 侧留同名薄委托(探针 `main.X` 路径零迁移) | 流程静态函数(root 显式) | 局态全局住 run_scope 节点——本件零成员态、零新增信号连接(连接语句随原段搬运) | 无 |
| **main_overlay_flow**(`presentation/main_overlay_flow.gd`,迭代 37 拆出) | main 浮层流程族——设置/状态面板/生涯页/选档界面/图例/钱包事件的开合与数据投喂;逐字搬运,main 侧留同名薄委托 | 流程静态函数(root 显式) | 全部开合走组合根模态编排口(`root.ui.modals.flow.open/close`)——本件零成员态 | 同 D1 |
| **main_overlay_flow**(`presentation/main_overlay_flow.gd`,迭代 37 拆出) | main 浮层流程族——设置/状态面板/生涯页/选档界面/图例/钱包事件的开合与数据投喂;逐字搬运,main 侧留同名薄委托 | 流程静态函数(root 显式) | 全部开合走组合根模态单口(`root._open_modal/_close_modal`)——本件零成员态 | 同 D1 |
| **main_debug_flow**(`presentation/main_debug_flow.gd`,迭代 37 拆出) | main 调试流程族——调试浮窗开合与上下文同步、批量模拟入口、两层调试对局起手、诊断转储;逐字搬运,main 侧留同名薄委托 | 流程静态函数(root 显式) | 调试会话状态机归 debug_session.gd——本件只接线与出 UI,零成员态 | 同 D1 |
| **TilePalette**(`presentation/views/tile_palette.gd`,迭代 37 拆出) | 瓦片排版/装载:高墙/地面瓦片整批装载与运行时镜像合成、地板明度归一、数字墨族按板自适应判据、格坐标确定性散列与十六正交情形墙瓦片查表 | 查表族(读件持棋盘引用——棋盘视图 rebuild 经 `bind_board` 同步);装载缓存七成员持于件内(同板型零重载、换板重载时序同源) | 零绘制面、零玩法数据写入(绘制调用面留棋盘视图);纹理路径单点在件内 | Resource 纹理加载——LOW |
| **HeroSprite**(`presentation/views/hero_sprite.gd`,迭代 37 拆出) | 英雄精灵四态与落位装配(落位与位移演出、撞墙帧闪、挖掘弹跳、脚底锚与持握手位出口) | 由棋盘视图 `_init` 建为子件(注入世界根与壳层容器引用)——精灵本体经世界根 ensure_hero 建于 SubViewport 世界内,本件只驱动其状态 | BoardWorld 世界根;素材缺位=零精灵(棋盘视图字形「人」回退路径在役) | Node2D / create_tween(Tween 系 Node 方法——MEDIUM 域对照 breaking-changes.md) |
@@ -190,7 +190,7 @@
### 三屏壳与组合根句柄面
- 呈现场景拆为三屏壳:MenuScreen(开始菜单屏)/CampScreen(营地屏)/AdventureScreen(冒险屏——内含关卡地图与战斗两容器)。
- 屏成员寻址自实现批起迁经界面注册面(**已建件——迭代 44**):探针挂载假设 `main.X` 迁移为 `main.ui.<域容器>.<句柄>`(ui_screens/ui_battle/ui_modals 三域容器,约 867 处探针与系统测试引用随批改址);原 S13 豁免登记〔2026-10-27「组合根类变量面即探针契约面」〕注销;main.gd 类变量 49→15,注册面形态见「模块归属·呈现层」表 ui_registry 行;ModalFlow 实例随 UiModals 容器构造建立(装配早期注入点依赖其先在座);取证探针 shot_probe/fx_shot_probe 随批改址;局态一律住 RunScope 节点,禁在屏/视图侧持有局态引用。
- 屏成员寻址自实现批起迁经界面注册面(**2026-10-29 零豁免裁+注册面设计闭合——实现批建件**):探针挂载假设 `main.X` 迁移为 `main.ui.<域容器>.<句柄>`(ui_screens/ui_battle/ui_modals 三域容器,约 867 处探针与系统测试引用随批改址);原 S13 豁免登记〔2026-10-27「组合根类变量面即探针契约面」〕注销;main.gd 类变量 49→15,注册面形态见「模块归属·呈现层」表 ui_registry 行;局态一律住 RunScope 节点,禁在屏/视图侧持有局态引用。
- **组合根拆件**=组合根构造注入、代组合根执行核心写调用的呈现侧子件(现行三件:curio_interact_controller/camp_shop_presenter/treasure_interact_controller——冒险节点后续推进、营地购买与刷新、道具使用)。视图禁直连拆件;核心写调用的可达路径仍是「视图→信号→组合根(含拆件)→核心」,依赖规则与组合根单点装配不变。成员见「模块归属·呈现层」表。
### 视觉层装配合同
@@ -249,17 +249,18 @@
| **文档域** | gdd_lint、doc_link_audit、doc_term_audit、流水线闸 | `game/` 内的 `.md` 与 `game/` 外的一切路径:`design/`、根规则文件(`AGENTS.md`/`roadmap.md`/`待办清单.md`/`体验验证清单.md`)、`tools/` 工具脚本、`.zcode/` 配置、`sim-data/`、`reports/` |
| **两域都含** | repo_structure_audit(熵增闸:顶层目录/根文件/图像白名单/退役路径/design 子目录五查——文档批新增或挪动 `.md` 同样会绊它;纯文本扫描秒级) | — |
口径三条:**域划分的唯一出处是 `tools/run_all_gates.sh`**(`--code`/`--docs`/不带参数=全量),本表是它的现状登记、不是第二份清单;改闸件本身或一次改动跨两域 → 跑全量档(§6.2 共享件例外);开发期手动档按本批改动域选 `--code`/`--docs`,合回后 CI 恒跑全量档。代码域跑前先过**素材齐盘预检**——`game/assets/art/**` 与一切 `*.import` 边车都不入 git(2026-09-29 裁定),worktree 冷检出必空盘,空盘态冒烟 V1 成片假红、渲染闸更是一段 golden 都不比。
口径三条:**域划分的唯一出处是 `tools/run_all_gates.sh`**(`--code`/`--docs`/不带参数=全量),本表是它的现状登记、不是第二份清单;改闸件本身或一次改动跨两域 → 跑全量档(§6.2 共享件例外);合回闸按 merge diff 的文件性质推出应验的域(`game/` 内 `.md` 归文档域),再校验回执的 `domain` 字段与新增红。代码域跑前先过**素材齐盘预检**——`game/assets/art/**` 与一切 `*.import` 边车都不入 git(2026-09-29 裁定),worktree 冷检出必空盘,空盘态冒烟 V1 成片假红、渲染闸更是一段 golden 都不比。
### 车道分层执法(2026-10-31 用户裁恢复「一切改动走 worktree」)
### 车道分层执法(2026-10-26 用户裁「按路径切车道,取代一切改动走 worktree」)
一切改动走独立 worktree,主工作区只作合并落点。执法全机械——判据只有 git 图与路径(豁免面 `.zcode/`、`.qoder/` 不入 git,主区直改),不含「改动大小」等语义判断。
改动车道与改动域同一判据(文件性质):代码面=worktree 批车道,文档面=主工作区直改车道。执法全机械——判据只有文件路径性质与 git 图,不含「改动大小」等语义判断;「预期大改」由用户开工点名自愿开 worktree,不进规则。
| 执法层 | 载体 | 职责 | 判据 |
|---|---|---|---|
| **worktree-guard**(ZCode PreToolUse) | `.zcode/hooks/worktree-guard.sh`(本机件,不入 git) | agent 侧车道纪律:主工作区 Edit/Write 与主区非 merge `git commit` 拦截(豁免 `.zcode/`、`.qoder/`;worktree 内目标快速放行;合并收尾提交凭 MERGE_HEAD 豁免);`git commit --no-verify` 拦截(该旗标仅属用户);iter 分支合回一卡一提交数卡校验;规则闸 | 路径性质+分支名+MERGE_HEAD+git 图 |
| **git pre-commit 钩子** | `tools/hooks/pre-commit`(版本化本体,`core.hooksPath` 挂载;在位性由 run_all_gates.sh 跑批自检——失位即红) | 直改车道闸机检:staged 不含代码面的提交,提交点现场跑 `run_all_gates.sh --docs`(秒级文本扫描),绿落地红拦;staged 含代码面时主工作区=拦(代码面唯一合法路径=worktree 批合回)、任务 worktree=跳过(归批末闸+合回闸,不打扰迭代批中间提交) | staged 文件性质+主区/worktree 判定(git-dir 与 common-dir 同一=主区) |
| **worktree-guard**(ZCode PreToolUse) | `.zcode/hooks/worktree-guard.sh`(本机件,不入 git) | agent 侧车道纪律:主工作区代码面的 Edit/Write 与 staged 含代码面的 commit 拦截;`git commit --no-verify` 拦截(该旗标仅属用户);合回闸回执六况校验 | 路径性质+分支名+回执 JSON+git 图 |
验证收拢为合回后本地 CI 全量(post-merge 触发),commit 点零执法;主工作区防污染由 ZCode 层守卫承担——只约束 agent,用户手工改动不受限。子代理覆盖面(2026-10-26 冷启动评估实测):子代理的工具调用不经过 ZCode 层守卫——ZCode 层实际只覆盖主会话工具调用;残余暴露面=子代理写主工作区与蓄意 `--no-verify`(该旗标整族跳过 git 层钩子),属故意越权而非遗忘型失误,与防遗忘的设计目标正交。
取舍依据:失败代价不对称——docs 红是死链/术语/格式,下次任何跑批对基线比对必暴露、秒级修复,故文档面轻执法(commit 点闸、无回执流程);代码面红是运行时行为坏,保留「worktree+批末域闸+回执硬绑定」全套。git 层钩子对一切提交者生效(含用户手工提交,紧急出口 `--no-verify`);ZCode 层只约束 agent。子代理覆盖面(2026-10-26 冷启动评估实测):子代理的工具调用不经过 ZCode 层守卫(代码面 Edit 未被拦、`--no-verify` 探针未被拦)——ZCode 层实际只覆盖主会话工具调用,git 层因此是唯一覆盖一切提交者的执法层;残余暴露面=蓄意 `--no-verify`(pre-commit 族钩子被该旗标整族跳过,git 层无法自防),属故意越权而非遗忘型失误,与防遗忘的设计目标正交。
### 三条判定硬闸现行状态
@@ -317,11 +318,11 @@
本节为测试域(测试载体、判定口径、静态扫描域)的事实源。新增违规案例仍须先补 static_scan 规则再修码(code-conventions 缺陷-规范对照表纪律)。
**S13 测量面豁免注销(2026-10-29 零豁免裁)**:原循环内 `await` 豁免〔2026-10-27〕注销——tune_sim_controller 改 process_frame 信号常驻连接+步进状态机(每帧一局、帧相位逐点对齐,已建件——迭代 44 卡③);运行态收尾现行形态=run() 尾每批一次执行(卡③ v1.0 申报的「每局置假还原」前提已被迭代 41 测试债批 215da315 先行消化,行为改动申报随 v1.1 停卡重裁剥离)。
**S13 测量面豁免注销(2026-10-29 零豁免裁)**:原循环内 `await` 豁免〔2026-10-27〕注销——tune_sim_controller 改 process_frame 信号常驻连接+步进状态机(每帧一局、帧相位逐点对齐,设计闭合、实现批建件);随批申报行为改动一处:运行态收尾由「每局置假」还原为「整批收尾单次置假」(消除与 wd8/ui_tune_probe 断言面的静态矛盾)。
**S13 豁免第三条注销(2026-10-29 零豁免裁)**:原 battle_orchestrator max-class-variables 豁免〔2026-10-28 迭代 40 卡①〕注销——RoundCycle/BattleFacts 两新件设计闭合(宿主实测 15,已建件——迭代 44 卡② 合回,见「战斗编排域拆件定稿」节轴丁)。
**S13 豁免第三条注销(2026-10-29 零豁免裁)**:原 battle_orchestrator max-class-variables 豁免〔2026-10-28 迭代 40 卡①〕注销——RoundCycle/BattleFacts 两新件设计闭合(宿主 38→15,实现批建件,见「战斗编排域拆件定稿」节轴丁)。
**gdstyle 计数截断缺陷登记(2026-10-29 两设计批独立实证)**:gdstyle v0.4.0 对文件内 inner class 的成员计数存在截断——内嵌类中带行尾注释的属性声明截断其后续成员计数(standee_body 实测 31 声明仅记 19、board_cell_unit 33 仅记 30)。基线登记值属欠估;闸机扫描与基线同源、判定口径自洽不误报,债的真值以实查为准——零豁免各批按真实口径设计(实数低于阈值,不依赖解析缺陷)。**清偿结果(2026-10-31)**:board_cell_unit 30→10、standee_body 19→10 已随迭代 45 真实清偿,基线 refresh 已收账(欠估口径旁证=33/31 声明与实测吻合)。登记待办:向 gdstyle 上游报 issue(仍在册)。
**gdstyle 计数截断缺陷登记(2026-10-29 两设计批独立实证)**:gdstyle v0.4.0 对文件内 inner class 的成员计数存在截断——内嵌类中带行尾注释的属性声明截断其后续成员计数(standee_body 实测 31 声明仅记 19、board_cell_unit 33 仅记 30)。基线登记值属欠估;闸机扫描与基线同源、判定口径自洽不误报,债的真值以实查为准——零豁免各批按真实口径设计(实数低于阈值,不依赖解析缺陷)。登记待办:向 gdstyle 上游报 issue。
---
+5 -5
View File
@@ -18,7 +18,7 @@
写文档像向朋友当面解释你的游戏:
1. **完整句子优先**:一段只说一件事,长句拆短句。
2. **禁止碎片笔记体**:不写压缩碎片,不把 `A→B→C` 箭头链当叙述(流程交给图,见第 3 节),不用只有作者自己懂的缩略语。
2. **禁止碎片笔记体**:不写压缩碎片,不把 `A→B→C` 箭头链当叙述(流程交给字符画,见第 3 节),不用只有作者自己懂的缩略语。
3. **每节人话开头**:每小节第一段先用白话说清"这是什么、为什么需要它";只读各节第一段就能看懂全文故事线。
4. **术语首现即解释**:专业术语或项目概念首次出现用一句话解释;玩家可见专属名词(如"显影尘")同样要说清。
5. **叙述优先于引用**:AC-x、F-x 等编号引用不进正文叙述,只出现在验收标准与附录。
@@ -30,11 +30,11 @@
|---|---|---|
| 规则的来龙去脉、行为逻辑 | 散文段 | 每段 ≤240 字,一段一件事 |
| 枚举、数值、边界、依赖 | 表格 | 表格只放可列举的事实;禁把需要解释的内容塞进单元格让读者自己拼 |
| 流程、状态流转、结构关系 | 文档内嵌 HTML/SVG(默认)· Mermaid(网页发布保底)· 字符画(无渲染环境保底) | 禁用散文逐步描述流程;默认在文档内嵌 HTML/SVG(表现力优先,本地预览即渲染,图体行数计入节点篇幅);发布到会过滤内嵌 HTML 的网页端时改 Mermaid;无渲染查看环境用字符画 |
| 流程、状态流转 | 字符画(代码块) | 禁用散文逐步描述流程 |
| 公式 | 结论先行 | 先一行加粗结论,再放公式代码块、变量表与验算表 |
| 体验锚点 | 关键词表 | 支柱/关键词/机制承诺 三列表,禁长篇情绪描述 |
节点内顺序:先人话,再表格枚举,再流程图(内嵌 HTML/SVG 或字符画),最后公式举证。**规则两段式**:先写"人话阶段"(作用于哪个系统、什么情况下、谁触发、触发后发生什么),再写"举证阶段"(逐效果给出计算方法;纯流程规则明写"无计算")。规则名禁止纯名词短语(反面例:"获取路由")。
节点内顺序:先人话,再表格枚举,再字符流程图,最后公式举证。**规则两段式**:先写"人话阶段"(作用于哪个系统、什么情况下、谁触发、触发后发生什么),再写"举证阶段"(逐效果给出计算方法;纯流程规则明写"无计算")。规则名禁止纯名词短语(反面例:"获取路由")。
## 4. 用语纪律(见名知意 · 所见即所得 · 禁自造黑话)
@@ -136,7 +136,7 @@
### 12.1 待办清单条目格式与状态机
待办清单是流水线的唯一登记处:**现在不做、以后才做的事**登记一条,随流水线段推进改状态,做完整条删除。条目记录某件事走到了哪一段,不是各段的开工前置。一条条目分两层——**标题=登记元数据**(何时登记、从哪来、紧急度,登记后不再变),**正文=四个属性**(随进程演进)。四个属性各管一件事:`实况` 管凭据,`缺口` 管这条的**输入**(还缺哪一次设计),`改动面` 管这条的**产出**(要动哪些面),`状态` 管这条走到流水线哪一段。
待办清单是流水线的唯一登记处:要做的事先登记一条,随流水线段推进改状态,做完整条删除。一条条目分两层——**标题=登记元数据**(何时登记、从哪来、紧急度,登记后不再变),**正文=四个属性**(随进程演进)。四个属性各管一件事:`实况` 管凭据,`缺口` 管这条的**输入**(还缺哪一次设计),`改动面` 管这条的**产出**(要动哪些面),`状态` 管这条走到流水线哪一段。
标题格式(尖括号处按实际填写,方括号内为可选段):
@@ -173,7 +173,7 @@
文档线:待文档设计 → 文档设计中 → 文档设计已闭合
美术线:待美术设计 → 美术设计中 → 美术设计已闭合
下游共用序列(需求改动):待写卡 → 已写卡 → 已编迭代 N → 完成即整条删除
直改序列(工程改动/文档设计改动/美术素材改动):待执行 → 完成即整条删除(经设计讨论的可前置闭合段,如「文档设计已闭合+待执行」)
直改序列(工程改动/文档设计改动/美术素材改动):登记 → 待执行 → 完成即整条删除(经设计讨论的可前置闭合段,如「文档设计已闭合+待执行」)
累积示例:文档设计已闭合+待美术设计+已写卡
```
+11 -11
View File
@@ -1,28 +1,28 @@
# 流程规范(Dungeon Sweeper)
> 约束范围:一切批次的流程纪律——车道(一切改动走独立 worktree,主区只作合并落点)、五段流水线、批次工作流、测试执行细则、像素件工作纪律。
> 约束范围:一切批次的流程纪律——车道(代码面 worktree 批/其余主区直改)、五段流水线、批次工作流、测试执行细则、像素件工作纪律。
> 分工:硬性红线的一句话索引在 AGENTS.md「硬性红线」;本文承载其操作细则;批次开工前通读本文。
**开工任何批次前必须通读本文。**
## 1. 分支纪律(worktree 铁律)
## 1. 分支纪律(车道铁律)
主工作区(master 检出)只作合并落点,一切开发/设计改动禁止直接发生在主工作区(2026-10-31 用户裁恢复;2026-10-30 的「主区直改+直提」车道与 commit 点 pre-commit 直改闸随之退役;验证模型不动——合回后本地 CI 仍是唯一强制验证点):
一切面主工作区直改+直提(2026-10-30 用户裁本地 CI 化:验证挪到合回后,主区直提不再拦任何面;判据与 §3 第 8 条改动域划分同一):
1. **worktree 车道(一切面)**:每批先建独立 worktree:`git worktree add ../g-plan2-<任务名> -b <任务分支>`;建区后立刻跑 `tools/setup_worktree_userdir.sh`——给该区独立 Godot user 目录(测试夹具、试玩日志、截图产物不与其他区共用;主区不生成,真实档保持原位)。所有改动与提交都在 worktree 内自由进行——commit 点零钩子检查(`tools/hooks/pre-commit` 已删除)。豁免面仅 `.zcode/`(钩子与配置)与 `.qoder/`(本机 harness 配置)允许主工作区直改——两份实测均不入 git(走 worktree 反而带不进去,改动只对本机生效)
2. **收口顺序(固定)**:**冻结 → 件核 → 并 master → 重塑 → 主区合回 → CI 验证 → 删区**——代码与断言改完即冻结,全仓件核 grep 查残留;master 已被别的批次推进时先在 worktree 内 `git merge master` 解冲突(必须在合回之前,合回后才并=CI 验的是中间态);**重塑**=迭代分支(iter<N> 形)合回前执行 `python tools/reshape_cards.py`,把分支线性史按卡末态快照压成一卡一笔(可选追加一笔纯文档收尾),master 台账由此每卡一行——工具自带「重塑前后树逐字节一致」断言与 backup 分支,不改任何文件内容;非迭代批免重塑;然后主工作区 `git merge --no-ff <任务分支>`——这是主区唯一合法写动作(合回守卫对迭代分支数卡校验,未归卡提交拦下)。**CI 全绿后才 `git worktree remove`+删分支;CI 红不删区——回任务 worktree 修复提交再合,追绿后删区**。游戏类测试(冒烟/单测/MC/探针)批内默认零执行(两入口铁规,见 §4),用户点名或当场问才跑
3. **合回后验证(本地 CI,2026-10-30 用户裁)**:git merge 合回 master 落地后 post-merge 钩子(`tools/hooks/post-merge`)后台触发 `tools/ci_runner.sh merge` 对 master 尖跑一次全量域闸——唯一强制全量验证点;CI 红态下每个修复提交经 post-commit 钩子(`tools/hooks/post-commit`)自动追绿复验(钩子仅主工作区生效——修复合回落地即触发),绿态与无状态零触发。重跑判据:同一份字节禁止第二次人手跑;有意义的重跑只剩「验证修复」一类。CI 红不回滚合并——红项记 `game/tests/.gates/ci-status.json`,开工先读 CI 状态,红未修不开新批。跑批起手 `--editor --quit` 刷类名缓存(在册坑:.godot 缓存不入 git,合并后失配假红假绿)。并跑语义=跑完补跑(coalesce):跑批期间新触发不中断当前轮,轮尾对最新尖端补跑,绝不逐笔各跑一轮
4. **执法分层(全机械,零自觉依赖)**:①`.zcode/hooks/worktree-guard.sh`(PreToolUse,本机件不入 git)——agent 侧:主工作区 Edit/Write 与主区非 merge `git commit` 拦截(豁免 `.zcode/`、`.qoder/`;worktree 内目标快速放行;合并收尾提交凭 MERGE_HEAD 豁免)、`git commit --no-verify` 拦截(该旗标仅属用户)、iter<N> 分支合回的一卡一提交数卡校验、规则闸(写 design//game/ 前核对会话规约读取记录)。②post-merge/post-commit 钩子——本地 CI 触发(仅主工作区;任务 worktree 内的合并不触发)。③git 层不设车道钩子(pre-commit 直改闸已退役)——用户手工改动不受限;ZCode 层只约束 agent(子代理不经守卫层)
1. **主区直改车道(一切面)**:`game/`(含代码面=`game/` 下非 `.md` 的行为载体)、`design/`、`reports/`、`tools/`、根规则与清单文件、`.zcode/`、`.qoder/`——直接改、直接提交。验收分两层:commit 点 git pre-commit 钩子(`tools/hooks/pre-commit`,经 `core.hooksPath` 挂载,在位性由 run_all_gates.sh 跑批自检)现场跑 `tools/run_all_gates.sh --docs`(秒级文本扫描)绿即落地红即拦,合并收尾提交跳过(MERGE_HEAD 在,内容归合回后 CI);代码面的全量验证归合回后本地 CI(下条)。开发期纪律不变:卡内只测自己改的东西、出红只跑红件最小单元(§6)
2. **合回后验证(本地 CI,2026-10-30 用户裁)**:git merge 合回 master 落地后 post-merge 钩子(`tools/hooks/post-merge`)后台触发 `tools/ci_runner.sh merge` 对 master 尖跑一次全量域闸——唯一强制全量验证点;CI 红态下每个修复提交经 post-commit 钩子(`tools/hooks/post-commit`)自动追绿复验,绿态与无状态零触发。重跑判据:同一份字节禁止第二次人手跑;有意义的重跑只剩「验证修复」一类。CI 红不回滚合并——红项记 `game/tests/.gates/ci-status.json`,修复提交追绿;开工先读 CI 状态,红未修不开新批。跑批起手 `--editor --quit` 刷类名缓存(在册坑:.godot 缓存不入 git,合并后失配假红假绿)——原「合并后零复跑」的秒级动作由跑批件接管。并跑语义=跑完补跑(coalesce):跑批期间新触发不中断当前轮,轮尾对最新尖端补跑,绝不逐笔各跑一轮
3. **worktree 批车道(大批约定,非强制)**:迭代实现批与大体量改动按约定仍走独立 worktree:`git worktree add ../g-plan2-<任务名> -b <任务分支>`;建区后立刻跑 `tools/setup_worktree_userdir.sh`——给该区独立 Godot user 目录(测试夹具、试玩日志、截图产物不与其他区共用;主区不生成,真实档保持原位)。收口顺序固定为**冻结 → 件核 → 并 master → 重塑 → 主区合回 → CI 验证**——代码与断言改完即冻结,全仓件核 grep 查残留;master 已被别的批次推进时先 `git merge master` 解冲突;**重塑**=迭代分支(iter<N> 形)合回前执行 `python tools/reshape_cards.py`,把分支线性史按卡末态快照压成一卡一笔(可选追加一笔纯文档收尾),master 台账由此每卡一行——工具自带「重塑前后树逐字节一致」断言与 backup 分支,不改任何文件内容;非迭代工程小批免重塑;然后主工作区 `git merge --no-ff <任务分支>`(合回守卫对迭代分支数卡校验,未归卡提交拦下),合并落地 post-merge 钩子触发 CI,红则修复提交(主区直提)追绿,全绿后 `git worktree remove`+删分支。游戏类测试(冒烟/单测/MC/探针)批内默认零执行(两入口铁规,见 §4),用户点名或当场问才跑
4. **执法分层(全机械,零自觉依赖)**:①git pre-commit 钩子——一切提交的文档域闸机检(合并收尾提交豁免)。②post-merge/post-commit 钩子——本地 CI 触发(仅主工作区;任务 worktree 内的合并不触发)。③`.zcode/hooks/worktree-guard.sh`(PreToolUse,本机件不入 git)——agent 侧:`git commit --no-verify` 拦截(该旗标仅属用户)、iter<N> 分支合回的一卡一提交数卡校验、规则闸(写 design//game/ 前核对会话规约读取记录)。git 层钩子对一切提交者生效(含用户手工提交,紧急出口 `--no-verify`);ZCode 层只约束 agent
## 2. 五段流水线
**需求改动**(游戏代码,含随逻辑写/改的测试)按五段流水线走:**登记 → 文档设计/美术设计(两条设计线)→ 写需求卡片 → 迭代编排 → 实现**;工程/文档设计/美术素材三类改动不走写卡与编排段,走「(如需设计讨论)→ 用户发令 → 独立 worktree 直改 → 合回 CI」(车道细则见 §1)。两层口径(2026-10-25 用户立):需求卡片=需求单位的实施文档,任何工作量皆可写、皆可编入迭代;工作量限制只属迭代层——迭代估时总量 <5 个工作日=「冻结待凑批」,不可开工。段间不自动流转,每段转进由用户发令;每段一个技能入口(五者均装于项目 `.zcode/skills/`:doc-design/asset-ingest/req-card/iter-plan/iter),登记不立技能(条目格式由流水线闸强制)。设计工作在会话内进行、用户主导、禁无监管自跑。
**需求改动**(游戏代码,含随逻辑写/改的测试)按五段流水线走:**登记 → 文档设计/美术设计(两条设计线)→ 写需求卡片 → 迭代编排 → 实现**;工程/文档设计/美术素材三类改动不走写卡与编排段,走「登记 →(如需设计讨论)→ 用户发令直改 → 主区直改+commit 点闸 → 完成删条目」(车道细则见 §1)。两层口径(2026-10-25 用户立):需求卡片=需求单位的实施文档,任何工作量皆可写、皆可编入迭代;工作量限制只属迭代层——迭代估时总量 <5 个工作日=「冻结待凑批」,不可开工。段间不自动流转,每段转进由用户发令;每段一个技能入口(五者均装于项目 `.zcode/skills/`:doc-design/asset-ingest/req-card/iter-plan/iter),登记不立技能(条目格式由流水线闸强制)。设计工作在会话内进行、用户主导、禁无监管自跑。
| 段 | 入口技能 | 产出 | 出入口铁律 |
|---|---|---|---|
| 一·登记 | 无(闸管格式) | 待办清单条目 | 条目=标题登记元数据(日期/来源/可选优先级)+正文四属性(实况/缺口/改动面/状态);标题登记后不再变,正文随进程演进。格式与状态机权威=doc-conventions 第 12 节 |
| 二·文档设计/美术设计 | doc-design(文档线,兼任反哺点写入)/asset-ingest(美术录入;样张素材由用户主导产出) | GDD 文档或 art-bible/过审样张素材 | 用户提起或从待办清单取出;会话内进行、用户主导、禁无监管自跑;经用户点头确认心智一致才许写入文档;完成判据=待裁点清零,带未裁点的是讨论稿;设计线闭合凭据记入待办清单实况清单(文档线=文档路径+版本号,美术线=art-bible 条款版本);缺哪条线写在缺口属性,闭合与否写在状态段 |
| 三·写需求卡片 | req-card | 需求卡片 | 设计线闭合后用户发令;新玩法/新系统/新内容必须有设计定稿前置,例外=需求性工程条目(缺陷修复/重构等改游戏行为)凭实况里的证据指认跳过设计线;配套维护类(工程债/测试基建/工具维护,不动游戏行为)=工程改动直改类,不走本段,由用户发令直改;卡片必经 grilling 多轮复核、零待裁点才成立;写完在待办清单状态记「已写卡」,卡片路径记入实况清单(防遗忘) |
| 三·写需求卡片 | req-card | 需求卡片 | 设计线闭合后用户发令;新玩法/新系统/新内容必须有设计定稿前置,例外=需求性工程条目(缺陷修复/重构等改游戏行为)凭实况里的证据指认跳过设计线;配套维护类(工程债/测试基建/工具维护,不动游戏行为)=工程改动直改类,不走本段,登记后「待执行」由用户发令直改;卡片必经 grilling 多轮复核、零待裁点才成立;写完在待办清单状态记「已写卡」,卡片路径记入实况清单(防遗忘) |
| 四·迭代编排 | iter-plan | roadmap 迭代行 | 编排四查:①每卡卡片文件存在 ②每卡设计闭合凭据齐(或需求性工程条目的证据指认)③估时与冻结线——所选卡估时按区间**中值**求和(单位工作日、写精确值不取整):**卡片任何工作量均可编入**(2026-10-25 用户立:工作量限制属迭代层、非卡片层);编入后迭代总量 <5 个工作日=迭代行状态「冻结待凑批」、不可开工,凑批 ≥5 后由编排段改「待开工」(迭代体量偏好,2026-10-21 用户立、2026-10-25 改冻结制);5–10 个工作日为常规区间;超过 10 个工作日须经用户确认(确认前呈报整批/拆批两案等裁,禁自行拆分或塞入),确认后迭代行随带日期特批标记;超过 20 个工作日禁止编(硬上限,用户确认也不放行,必须拆批)④写完 roadmap 行后跑流水线闸确认绿;编入未完成迭代,新开迭代行经用户确认 |
| 五·实现 | iter | 代码与配置,可运行的游戏 | 需求卡片永不单独施工,统一由用户指定迭代号触发(=U0 开工令),按 iter 技能与本文 §3 执行;**本段是代码实现批:禁写 `design/` 与根规则文件,产出物只落 `reports/`(见 §3 第 12 条)**;设计权威文档(GDD/art-bible)批内一律不更新;完成人闸=实机目检清单+实现决定记录写齐即完成批内义务 |
@@ -40,7 +40,7 @@
3. **用户发开工令才动手**——需求卡片经用户批准(U0)后方开工
**环境与基线**
4. **一切批独立 worktree+拷导入缓存**——按 §1 建 worktree;涉代码域跑闸或测试的批先拷主区 `.godot/` 目录与字体 `.import` 边车(纯文档批免拷),否则全量重导入资源近似卡死。检出工作区零测试,直接开工(2026-10-22 频率规则);闸壳每次跑批先自检/自愈本区 user 目录隔离(§1 第 1 条),建不起来即拒跑
4. **代码面批独立 worktree+拷导入缓存**——触及代码面的批次按 §1 建 worktree;先拷主区 `.godot/` 目录与字体 `.import` 边车再跑测试,否则全量重导入资源近似卡死。检出工作区零测试,直接开工(2026-10-22 频率规则);闸壳每次跑批先自检/自愈本区 user 目录隔离(§1 第 1 条),建不起来即拒跑;直改车道(非代码面)无此项
5. **涉数值改动先采改前读数**——与改后同随机种子配对比较并写明逐项比对口径;无数值改动禁跑模拟
**实施**
@@ -48,7 +48,7 @@
7. **验收改动先行声明**——验收变化(基线换代/探针增改/旧断言改判)预先写进需求卡片,禁事后补
**完成**
8. **合回后 CI 验证(唯一强制验证点)**——主工作区 `git merge --no-ff <任务分支>` 落地后 post-merge 钩子自动跑全量域闸(不带参数档,02 全套件),判定与红项落 `game/tests/.gates/ci-status.json`。全量是唯一强制档:跨卡触面、探针与未申报套件的消费漏网只有全量闸能抓(迭代 44 实证),关联档选测的盲区由它兜底。合回前独立验收审计通过(iter 技能第 5 步),未过不合回。该脚本是全部验证闸的**唯一入口、唯一清单与唯一域划分(含选闸算法与套件族映射表)**,闸件增减、分域调整都只改它;**本文与其他文档禁另列闸件清单**(清单散落多处正是 iter27 漏跑 `probe_gate --full` 的成因)。开发期手动跑批按需选档(按文件性质判域:代码面→`--code`,文档件→`--docs`,两类都有→全量;`--code` 关联档选测——02 只跑「需求卡片申报 ∪ diff 推导」并集套件、00 冒烟/01 系统测试/09 静态扫描三件保险恒跑、横切面回落全量——算法见闸脚本),手动跑不构成验收。闸件(`tools/` 下机检脚本与闸壳)自身的改动不占 CI 全量——其质量义务=落批时人工确认闸可跑通且判据口径未变;闸真崩溃时 CI 判红在案(跑不出回执=verdict 红,fail-closed 语义保留)
8. **合回后 CI 验证(worktree 批;主区直改小批的验收在 commit 点由 git 钩子执行,见 §1 第 1 条)**——主工作区 `git merge --no-ff <任务分支>` 落地后 post-merge 钩子自动跑全量域闸(不带参数档,02 全套件),判定与红项落 `game/tests/.gates/ci-status.json`。全量是唯一强制档:跨卡触面、探针与未申报套件的消费漏网只有全量闸能抓(迭代 44 实证),关联档选测的盲区由它兜底。合回前独立验收审计通过(iter 技能第 5 步),未过不合回。该脚本是全部验证闸的**唯一入口、唯一清单与唯一域划分(含选闸算法与套件族映射表)**,闸件增减、分域调整都只改它;**本文与其他文档禁另列闸件清单**(清单散落多处正是 iter27 漏跑 `probe_gate --full` 的成因)。开发期手动跑批按需选档(按文件性质判域:代码面→`--code`,文档件→`--docs`,两类都有→全量;`--code` 关联档选测——02 只跑「需求卡片申报 ∪ diff 推导」并集套件、00 冒烟/01 系统测试/09 静态扫描三件保险恒跑、横切面回落全量——算法见闸脚本),手动跑不构成验收。闸件(`tools/` 下机检脚本与闸壳)自身的改动不占 CI 全量——其质量义务=落批时人工确认闸可跑通且判据口径未变;闸真崩溃时 CI 判红在案(跑不出回执=verdict 红,fail-closed 语义保留)
9. **重跑语义(2026-10-30 用户裁,取代原「每批一次/合并后零复跑」口径)**——同一份字节禁止第二次人手跑;允许的重跑只剩两类:① CI 红后的修复提交(post-commit 钩子自动追绿复验,每笔修复至多触发一轮);② 用户自发发起的全量回归。「跑都跑了再跑一遍保险」「顺手改点再补一跑」都不构成重跑理由。类名缓存刷新与开机确认由 CI 跑批起手接管(§1 第 2 条),合并后无手工动作
10. **批次完成后的登记义务**——合回 master 后按 doc-conventions §12.1 推进待办清单条目状态(做完整条删除),涉及迭代编排的在 roadmap 迭代总表与顶部「当前位」节换代——执行入口=项目技能 batch-closure(批后收尾与中间文档退役),跨会话教训写记忆库。批次过程与结论由 git 提交信息承载,禁止再写会话状态文件(见 doc-conventions 第 10 节)。`design/` 与根规则文件(`AGENTS.md`/`roadmap.md`/`待办清单.md`/`体验验证清单.md`)实现批禁写,见 §12
11. **文档同步闸(实现批禁写文档)**——实现批**禁写 `design/` 整个目录与根规则文件**,**另禁写 `game/tests/README.md`(能力清单,归写卡段维护,test-conventions §8.9)**,要往外交代的东西一律落 `reports/`:实现报告 `reports/iter<N>-实现报告-<日期>.md`(各卡状态+实机目检总清单+遗留读数义务+实现决定记录——超白名单/超卡片明列范围事项逐条记「决了什么/为什么/代价/撤销方式」,全部按卡执行时只写一行「零拍板」)、GDD 反哺点清单 `reports/iter<N>-反哺点-<日期>.md`(每条写清哪个文件哪一节、改成什么、依据是什么)。设计权威文档(GDD/art-bible)**任何批都不直改**:用户在会话中逐点裁决后,由工程/文档设计改动批(直改类)写入 `design/`(执行入口=doc-design 技能),并把反哺条目从 `reports/` 清掉(吸收即死;退役执行=batch-closure 技能)。机械面文档(roadmap 行/术语表/README 工具注)同样归工程/文档设计改动批在合并前更新。反哺点未落地期间相关 GDD 节视为待反哺,读前先查 `reports/` 与待办清单;需求卡片必列「关联文档同步面」按两层标注
+1 -1
View File
@@ -27,7 +27,7 @@
## 4. 验证时机(合回后本地 CI 制,2026-10-30 换代)
开发期窄测义务不变:每批开发中,本批新增/改动的验收测试自己跑绿即收口(卡内只测自己改的东西,process-conventions §6)。全量验证归合回后的本地 CI:git merge 合回 master 触发 post-merge 钩子跑 `tools/run_all_gates.sh` 不带参数档(两域全量,02 全套件——跨卡触面与关联档选测的盲区由全量兜底),结果落 `game/tests/.gates/ci-status.json`;CI 红态下修复提交经 post-commit 钩子自动追绿。同一份字节禁止第二次人手跑。该脚本是全部验证闸的唯一入口与唯一清单,域划分与选闸算法只写在脚本里,本文禁另列闸件清单。
开发期窄测义务不变:每批开发中,本批新增/改动的验收测试自己跑绿即收口(卡内只测自己改的东西,process-conventions §6);主区小改孤跑验证后直提。全量验证归合回后的本地 CI:git merge 合回 master 触发 post-merge 钩子跑 `tools/run_all_gates.sh` 不带参数档(两域全量,02 全套件——跨卡触面与关联档选测的盲区由全量兜底),结果落 `game/tests/.gates/ci-status.json`;CI 红态下修复提交经 post-commit 钩子自动追绿。同一份字节禁止第二次人手跑。该脚本是全部验证闸的唯一入口与唯一清单,域划分与选闸算法只写在脚本里,本文禁另列闸件清单。
行为探针使用随机化玩家行为(封印/停手/刷新/无效点击)——自动玩家不做的动作就是测试盲区。
## 5. 测试函数怎么写——验收清单条目的落码规范
+3 -29
View File
@@ -11,23 +11,21 @@
>
> **兑付频率(先看这条,它是三条渠道的共同前提)**:奇物**不是打一场战斗给一份**。关内的普通战斗节点打完了什么也不给;一关之内奇物**只兑付一次**,触发点是**关底 Boss 被击败**——而按 [冒险结构](冒险结构.md) 的定义,打掉关底 Boss 恰好就等于"通过这一关",这两件事是同一个时刻,不是一条链上的两步。
>
> 状态:**已实现**(2026-10-04 双层 BD 实施批落地);现行为 v1.3。本文件是奇物的唯一定义文档。
> 状态:**已实现**(2026-10-04 双层 BD 实施批落地);现行为 v1.1。本文件是奇物的唯一定义文档。
>
> 数值纪律:本文件只写概念、取值域与指路;每件给多少、效果是什么一律不进正文,事实源是 `data/tables/feats.tres` 与 `data/tables/adventure.tres`。
## 专长(重设计·基础框架 v1)
> 本节是专长分类的现行事实源(2026-10-07 用户终审认同写入文档)。件表为设计声明——数值全 provisional 归调参批;命名全为代号,正式命名归用户。**新框架已实装:`feats.tres` 30 行=基础 27+迁入 2+规则豁免 1,行为与数据行 1:1。**
> 本节是专长分类的现行事实源(2026-10-07 用户终审认同写入文档)。件表为设计声明——数值全 provisional 归调参批;命名全为代号,正式命名归用户。**新框架已随迭代 20 专长实装批落地(2026-10-11):`feats.tres` 29 行=基础 27+迁入 2,行为与数据行 1:1。**
### 设计原则
1. **触发器句式**:每件专长的效果声明为「当 X 时 Y」(on / when / do 三字段,词表=效果引擎封闭集)。件的性格来自它挂在哪个事件上;combo 靠事件共享自然涌现——不设流派标签、不设档位机制。
2. **事件族组织**(设计侧分组工具,不上卡面):开格系 / 封印系 / 踩雷系 / 节奏系 / 战斗系 / 换图系六族。族名禁上玩家可见面(命名铁律)。
2. **事件族组织**(设计侧分组工具,不上卡面):开格系 / 封印系 / 踩雷系 / 节奏系 / 战斗系五族。族名禁上玩家可见面(命名铁律)。
3. **准入校验**:代价与收益须同账可核算——「纯代价件」禁止出生;契约件的代价必须一句话讲得清(契约不可怕,糊涂账才可怕)。
4. **信息红线**:禁止任何效果让数字说谎(信息规则不豁免);揭示类效果只揭真格。
5. **防兑换环**:互相转换的通道必须有损耗或每轮上限;单向通道优先。
6. **基座先行**:流派先确定基座专长——通过改变资源来源、动作成本或频率、动作结算、动作之间的关系,让原本偶尔用于止损的动作成为可以持续使用的主要打法。后续专长再围绕这个新行为提供输出、生存或资源收益;泛用数值增长不能代替基座。
7. **行为改变检验**:基座必须能回答「拿到前后操作有何不同、新行为靠什么资源持续、后续专长为何依附这个新行为」。只是同一操作后的结算数字变大,不算形成新流派。
> **落行注记(迭代 20 反哺写入,2026-10-12 追认⑤)**:「每第 N 次 / 积满触发」的数据行条件写 **N−1**——效果引擎分发时 when 先于 do 读计数器现值(预评估),故「满 N 触发」落行写 N−1(例:地质学家「满 4 种」写 eq 3、封印匠「每第 3 次」写 mod_eq ref 2、双管镐「每第 2 次」写 mod_eq ref 1)。行为仍为每第 N 次准点触发,单元测试钉住;新件落行照此口径。
@@ -97,28 +95,6 @@
|---|---|---|
| 血税 | 本局:踩雷 −2 最大生命;标中 +1 攻击(**均下一战起生效**——战末汇入冒险加算区) | 双向都痛都爽,一句话讲得清;双向同账、本局累积、冒险收束清零。生命上限/攻击系属战界重建属性,即时改会被重建冲掉,故滞后一战兑付(2026-10-12 追认⑨回写;卡面 desc 同步补「下一战起生效」) |
### 换图系(7 件,设计定稿,待实现)
换图系把「弃图刷新」从坏图逃生改成主动构筑行为。两件基座分别解决 RAP 的来源与价格;后续专长让成功刷新产生输出、生存或 GP 资源收益。七件不要求一次拿齐,不设强制先拿基座、集件标签或集件奖励。
| 层 | 代号 | 规则 | 行为职责 |
|---|---|---|---|
| 基座 | 矿脉储能 | 每次付费挖格被受理后,额外获得 RAP;安全格与危险格同口径 | 持续挖图也能准备刷新,不再必须少挖停手 |
| 基座 | 省力周转 | 弃图刷新的 RAP 成本减半 | 同一份储备支持更多刷新 |
| 输出 | 崩壁冲击 | 成功刷新后,在本轮战斗段末对全体存活敌人造成一次固定伤害 | 刷新成为直接进攻行为 |
| 输出 | 蓄力周转 | 成功刷新攒层,最多 3 层;本轮下一次主角攻击消费全部层数后清零,战斗结束不跨战保留 | 连续换图蓄成一次单点爆发 |
| 生存 | 石层缓冲 | 本轮至少成功刷新一次后,主角每次受到伤害固定减少 2 点;不叠加 | 刷新形成当轮全局防御姿态 |
| 生存 | 坑道小憩 | 每次成功刷新累计 1 点恢复,最多 3 点;本轮授予段合计回复生命,封顶生命上限 | 放弃当前图换取恢复 |
| 资源 | 矿道红利 | 每次成功刷新固定获得 1 GP | 刷新动作自身带少量GP收益 |
共同规则:
- **双基座叠加**:矿脉储能与省力周转可以同时持有,产 RAP 与成本减半分别生效;每轮刷新次数上限继续限频,不设互斥规则。
- **成功才触发**:后续五件只认成功换图;刷新被拒绝时不产生事实,也不给输出、生存或资源收益。同一轮多次成功刷新按发生顺序逐次登记。
- **轮末兑付**:刷新不新增结算段。崩壁冲击走本轮战斗段末结账,石层缓冲在每次主角受伤时消费,坑道小憩与矿道红利走本轮授予段兑付。
- **全局受伤面**:石层缓冲覆盖敌方攻击、危险格、错误封印资源格与地形造成的主角伤害;临时生命值不在本流派设计范围内。
- **基线不变**:没有这些专长时,RAP 来源、刷新成本、清图奖励与伤害结果保持原规则。数值与稀有度归 `feats.tres`,落表前本节只作设计声明。
### 迁入登记(秘宝域迁出件;实装批落地后并入件表)
| 代号沿用 | 目标族 | on / when / do 要点 | 备注 |
@@ -478,8 +454,6 @@
10. 一个渠道一旦确定要出某个分类,该分类的成员就都在它的池子里——"渠道出哪些分类"不受这条约束,那是渠道轴的定位。
11. 凭证拿到即开,不进持有集,玩家无法囤积——选中或买下的同一时刻就开专长三选一。
12. 凭证带有计步保底:连续 5 次三选一展示未出现则第 6 次必出;计数跨奖励节点与商店共享,刷新后的重新展示计入次数,限购用满后保底不再触发。
13. 被称为流派基座的专长必须能说明拿到前后的操作差异与新行为的持续资源来源;只有同一操作后的泛用数值增长,不得登记为基座。
14. 换图系两件基座同时持有时都生效;后续五件只在成功刷新后触发,无专长基线不变;石层缓冲覆盖所有主角受伤路径且同轮不叠加,矿道红利按成功刷新次数固定获得 GP。
> 实装批落地前,现役代码按旧 27 件专长目录与旧资源成员在同框架下运行;新成员口径(27 件基础件表 / 凭证件表)自实装批起验。
@@ -1,7 +1,7 @@
# 地图战斗资源
> 一句话:格面资源的产出、极性字典与清图奖励封装
> 状态:已定稿(自旧体系迁移);现行为 v1.3
> 状态:已定稿(自旧体系迁移);现行为 v1.1
## 设计目的
@@ -127,7 +127,7 @@
| defense 护甲 | ac_up 盾牌加护(AC 掷点阈值轴——2026-09-16 换装,不入池)——幅度/上限/权重见 `reward.tres` | off_guard 失衡(AC 掷点阈值轴负向——2026-09-18 换装,不入池、退出主角防御池)——幅度/上限见 `status_effects.tres` off_guard 行 |
| heal 回血 | heal_minor(满血零兑付照旧)——威力/权重见 `reward.tres` | heal_backlash 直伤:战斗结算直接扣血,不经增益状态——威力见 `reward.tres` |
| blast 群伤 | spark_aoe 全体存活敌各吃一笔——威力/权重见 `reward.tres` | enemy_alert 警觉:敌方全体护甲等级 +1/层(`status_effects.tres` alert 行)——见 `reward.tres` |
| weaken 削弱 | weaken(敌方输出池;同名重复授予只加时长)——幅度见 `status_effects.tres` weaken 行 | sapped(主角输出池)——幅度见 `status_effects.tres` sapped 行 |
| weaken 削弱 | weaken(敌方输出池;同名重复授予只刷新剩余次数——2026-09-18 续时定案)——幅度见 `status_effects.tres` weaken 行 | sapped(主角输出池)——幅度见 `status_effects.tres` sapped 行 |
| action 行动点 | ap_up:下轮行动点 +1——见 `reward.tres` | ap_drain 迟滞:下轮行动点 −1——见 `reward.tres` |
| gp 财货 | gp_gain GP 袋:战斗内 GP 缓冲 +power,战斗完成随 GP 掉落统一入钱包账本(兑付编排归[战斗结算](战斗结算.md)、账本归[冒险结构](../冒险循环/冒险结构.md))——威力/权重见 `reward.tres` | gp_loss 破财:战斗内 GP 缓冲 −power,weight=0 纯字典不参与摇号——见 `reward.tres` |
| pierce 穿刺 | pierce_strike 穿刺弹:单目标克制直伤(attack_type=pierce 查克制矩阵,必中全额不掷点;目标 = 固定顺位最前存活敌)——威力/权重见 `reward.tres` | pierce_snare 穿刺陷阱:主角直伤,不经增益状态——威力见 `reward.tres` |
+18 -18
View File
@@ -1,13 +1,13 @@
# 增益状态
> 一句话:增益/减益的状态池、叠层与衰减
> 状态:已定稿(自旧体系迁移);现行为 v1.3
> 状态:已定稿(自旧体系迁移);现行为 v1.2
## 设计目的
战斗里有一类效果不在当场一次性用掉,而要管上几次结算:挖开安全格拿到的主角增益、封印标中带来的怪物削弱、踩雷喂给怪物的增强(警觉——blast 型负向)、标错封印招来的负向兑付,都是这类。本文把它们统称"状态":发给主角的有益效果叫增益(失衡与乏力是例外——它们是发给主角的减益),发给敌人的负面效果叫减益;敌方侧的增强同样是状态——几个方向共用同一个状态池。
增益状态就是这一个状态池:它收下全部状态,用同一套规矩管理——发入、合并(同一种效果重复拿到时按表行策略处理:叠层加一,或把剩余次数累加上本次授予的时长——读 `status_effects.tres` 逐行 stack_policy)、衰减(每次结算后剩余次数减一,减到零效果消失)、清空(战斗结束全部清除)。没有它,几类效果得各写一套计时逻辑,结算明细也无法逐行指回"这效果是我哪步棋带来的"。状态池管机制、不管数值从哪来:某个效果该多大,由各收益系统的表去定,状态池只照章入列、按次衰减。
增益状态就是这一个状态池:它收下全部状态,用同一套规矩管理——发入、合并(同一种效果重复拿到时按表行策略处理:叠层加一,或只刷新剩余次数——读 `status_effects.tres` 逐行 stack_policy)、衰减(每次结算后剩余次数减一,减到零效果消失)、清空(战斗结束全部清除)。没有它,几类效果得各写一套计时逻辑,结算明细也无法逐行指回"这效果是我哪步棋带来的"。状态池管机制、不管数值从哪来:某个效果该多大,由各收益系统的表去定,状态池只照章入列、按次衰减。
## 系统范围
@@ -76,14 +76,14 @@
举证:本节为授予路径与登记规则,无计算。
### 同名状态再拿到:叠层、累加、并存
### 同名状态再拿到:叠层、刷新、并存
同一种状态还没消失又拿到一份,怎么合并由状态表每行的合并策略字段说了算,共三种。合并在授予那一刻由状态池完成;多个状态在结算里按什么先后起作用,是战斗结算的编排——两件事互不干扰。
| 合并策略 | 重复授予时发生什么 | 说明 |
|---|---|---|
| 叠加 | 层数加一;剩余结算次数不动——只有首次授予定钟 | 现行内容行多数用叠加(逐行合并策略读 `status_effects.tres`) |
| 累加 | 剩余结算次数加上本次授予的时长——技能施放行带覆盖时长时按覆盖值加;层数不变 | 现行内容行六行用累加(削弱行 weaken、增益技行 empower / fortify、主角增益行 attack_up / ac_up);重复拿一次就多攒一段时长,同一轮拿几份攒几段,停手后按剩余次数逐轮耗完;逐行读 `status_effects.tres` |
| 刷新 | 剩余结算次数重置为该实例首次授予时的初始值,层数不变 | 刷新类内容行已就位——削弱行 weaken(2026-09-18 续时定案)、增益技行 empower / fortify、**主角增益行 attack_up / ac_up(2026-09-20 用户拍板「只续时不叠层」,全状态表增益/减益两侧合并语义就此统一为:主角可重复获取的增益与减益一律续时、不叠层)**;逐行读 `status_effects.tres` |
| 并存 | 新建一份独立实例,两份各算各的 | 同上 |
并存分支没有满层上限,但状态池规模天然有界:实例数的上界就是受理过的授予数——多受理一份就多一份实例,多少份在授予那一刻就完全确定,不会无限膨胀。
@@ -110,7 +110,7 @@
### 剩余次数怎么倒数:按结算次数衰减
每个状态实例自带一个倒数计数——剩余结算次数(本文说的"衰减"就是它逐次递减、归零消失)。它不承诺"活几轮",而是数"经历过几次轮末结算":每轮结算先让状态起作用,随后计数减一,减到零状态即被移除。持续 1 的状态就是"一次性":在授予它的那轮结算里生效一次,轮末消失。现行累加行里主角增益两行持续 1、削弱与敌方增益技行持续 2——累加语义下重复拿一次就按本次授予时长多攒一段,同一轮拿几份攒几段;跨轮持续的状态,寿命由表行初始值表达,给几就活几次结算。
每个状态实例自带一个倒数计数——剩余结算次数(本文说的"衰减"就是它逐次递减、归零消失)。它不承诺"活几轮",而是数"经历过几次轮末结算":每轮结算先让状态起作用,随后计数减一,减到零状态即被移除。持续 1 的状态就是"一次性":在授予它的那轮结算里生效一次,轮末消失。MVP 时期六行内容均为一次性(削弱后改续时——见 git 提交史;2026-09-20 起主角增益两行也走续时、duration 表值仍为 1——重复拿等于重新获得一次当轮增益);跨轮持续的状态,寿命由表行初始值表达,给几就活几次结算。
```
一轮结算:查询生效清单 → 逐行兑付(层数 × 行值)→ 轮末衰减(全部实例剩余次数 −1)→ 归零实例移除
@@ -140,8 +140,8 @@
| 例子 | 状态池输出 | 消费侧读法 |
|---|---|---|
| 暴走叠两层 | +(2 × enrage 行幅度)(读表;越出单行取值域,原样输出) | 压在天花板 +100% 上:敌方输出乘区封顶 ×2(削弱非叠层行——"叠两层压地板 −100% 归零"的读法不成立) |
| 主角盾牌加护再拿一份 | 层数恒 1、剩余结算次数累加本次授予的时长 | 不经任何池:掷点判定阈值 = 主角基准(读 hero 表)+ 层数(现行 +1——上限 2 层叠读取法退役,局内可达 AC 上限 11) |
| 暴走叠两层 | +(2 × enrage 行幅度)(读表;越出单行取值域,原样输出) | 压在天花板 +100% 上:敌方输出乘区封顶 ×2(削弱已改续时——"叠两层压地板 −100% 归零"的读法随 2026-09-18 结构修复批退役) |
| 主角盾牌加护再拿一份 | 层数恒 1、剩余结算次数重置(refresh——2026-09-20 主角增益续时批) | 不经任何池:掷点判定阈值 = 主角基准(读 hero 表)+ 层数(现行 +1——上限 2 层叠读取法退役,局内可达 AC 上限 11) |
状态池还有一条快照纪律:实例的幅度、初始次数、量纲在授予那一刻从表行拷贝。战斗中配置表即使被重载,已授予实例不受任何影响,只影响后续授予。
@@ -162,15 +162,15 @@
| 状态 | 效果一句话 | 发给谁 | 幅度(现行值) | 时限 / 合并 | 来源类别 |
|---|---|---|---|---|---|
| attack_up 增伤 | 主角攻击提升 | 主角 | 见 `data/tables/status_effects.tres` attack_up 行 | 时限/上限读表 / 累加(层数恒 1) | 安全格 |
| ac_up 盾牌加护 | 主角护甲等级提升(掷点折扣判定阈值——AC 轴,不入池) | 主角 | 见 `status_effects.tres` ac_up 行(2026-09-16 换装,原 defense_up 行已退役) | 时限/上限读表 / 累加(层数恒 1) | 安全格 |
| attack_up 增伤 | 主角攻击提升 | 主角 | 见 `data/tables/status_effects.tres` attack_up 行 | 时限/上限读表 / 刷新(2026-09-20 续时批 stack→refresh,层数恒 1) | 安全格 |
| ac_up 盾牌加护 | 主角护甲等级提升(掷点折扣判定阈值——AC 轴,不入池) | 主角 | 见 `status_effects.tres` ac_up 行(2026-09-16 换装,原 defense_up 行已退役) | 时限/上限读表 / 刷新(2026-09-20 续时批 stack→refresh,层数恒 1) | 安全格 |
| alert 警觉 | 敌方护甲等级 +1/层 | 敌方 | 见 `status_effects.tres` alert 行 | 1 结算 / 叠加读表 | 踩雷 / 标空封印(blast 型负向) |
| weaken 削弱 | 敌方攻击被削弱(同名重复标中只加时长、层数恒 1) | 敌方 | 见 `status_effects.tres` weaken 行(取值域 [60,85],取负生效) | 时限读表 / 累加 | 封印标中 |
| weaken 削弱 | 敌方攻击被削弱(同名重复标中只刷新剩余次数、层数恒 1) | 敌方 | 见 `status_effects.tres` weaken 行(取值域 [60,85],取负生效) | 时限读表 / 刷新(2026-09-18 续时定案) | 封印标中 |
| enrage 暴走 | 敌方攻击提升 | 敌方 | 见 `status_effects.tres` enrage 行 | 时限/上限读表 / 叠加 | 标空封印反噬 / 踩雷(attack 型负向) |
| off_guard 失衡 | 主角护甲等级降低(AC 轴——掷点判定阈值下调、更易被命中;2026-09-18 换装,原百分比承伤池已退) | 主角 | 见 `status_effects.tres` off_guard 行 | 时限/上限读表 / 叠加 | 标空封印反噬 / 踩雷(defense 型负向)/ 敌方妨害技(2026-09-19 新效应词汇批——蛛网束缚载体,duration 由技能行覆盖) |
| sapped 乏力 | 主角输出降低(weaken 型负向,主角输出池) | 主角 | 见 `status_effects.tres` sapped 行 | 时限/上限读表 / 叠加 | 危险格负向 / 标空封印(2026-09-15 格面资源批)/ 敌方妨害技(大地脉动——L3 Boss 石君王独占,2026-09-20 第三关内容批) |
| empower 蓄力 | 敌方输出倍率增益(敌方输出池——蓄力技载体;幅度读表) | 敌方 | 见 `status_effects.tres` empower 行 | duration 读表 = 1 个有效增益拍 / 累加 | 敌方技能施放(2026-09-16 敌人技能池批) |
| fortify 硬化 | 敌方防御提升(**敌方防御池**——硬化技载体;负值入池 = 主角攻击折半,2026-09-18 符号纠正——旧正值实际翻倍) | 敌方 | 见 `status_effects.tres` fortify 行 | duration 读表 = 1 个有效增益拍 / 累加 | 敌方技能施放(2026-09-16 敌人技能池批) |
| empower 蓄力 | 敌方输出倍率增益(敌方输出池——蓄力技载体;幅度读表) | 敌方 | 见 `status_effects.tres` empower 行 | duration 读表 = 1 个有效增益拍 / 刷新 | 敌方技能施放(2026-09-16 敌人技能池批) |
| fortify 硬化 | 敌方防御提升(**敌方防御池**——硬化技载体;负值入池 = 主角攻击折半,2026-09-18 符号纠正——旧正值实际翻倍) | 敌方 | 见 `status_effects.tres` fortify 行 | duration 读表 = 1 个有效增益拍 / 刷新 | 敌方技能施放(2026-09-16 敌人技能池批) |
empower 与 fortify 是敌方技能池增益技在状态池侧的数据落点(技能行 buff_ref 引用,施放时长由技能行覆盖——技能冷却与增益持续是两个计时器):两行 duration 表值(读表)的口径是"先兑付后衰减含施放当轮"——施放发生在第 N 结算战斗段,存活到第 N+1 结算战斗段才兑付"下一拍",即"持续 1 个有效结算"(proposal 语义的状态池落地)。敌方防御池是第四个乘区池:敌方作为防守方的百分比修正池,消费面 = [战斗结算](战斗结算.md)主角攻击的池乘区——四池对称(敌打主角 = 主角防御池 × 敌方输出池,主角打敌 = 主角输出池 × 敌方防御池),状态池语义零延伸:仍是同构实例、side-wide 加算、不封顶不保底。
@@ -195,7 +195,7 @@ empower 与 fortify 是敌方技能池增益技在状态池侧的数据落点(
1. 战斗结算通知战斗开始:状态池初始化,空池进入可用状态。
2. 轮末结算时,战斗结算把这一轮的扫雷事实兑换成授予:挖开安全格给主角上增益、封印标中削弱敌人、踩雷给敌方上增强、标空封印触发反噬——授予入口是唯一进货口。
3. 状态池按表行合并策略受理(新建 / 叠一层 / 累加时长),实例立即生效并携带归因记录。
3. 状态池按表行合并策略受理(新建 / 叠一层 / 刷新),实例立即生效并携带归因记录。
4. 战斗结算查询生效清单,逐行兑付进结算公式(有效值 = 层数 × 行值)。
5. 兑付完做轮末衰减:全部实例剩余次数减一,归零移除——先兑付、后衰减。
6. 战斗外授予、未知状态、满层授予一律被拒且状态池不变;满层的"奖励未生效"行归战斗结算的结算明细。
@@ -207,7 +207,7 @@ empower 与 fortify 是敌方技能池增益技在状态池侧的数据落点(
| 优先级 | 内容 | 后置原因 |
|---|---|---|
| P1 | 累加、并存两类合并策略的后续内容行 | 语义已定义、状态池已承载;累加类已有内容(weaken/empower/fortify/attack_up/ac_up),并存仍空,首个并存内容行上线时顺带补验收 |
| P1 | 刷新、并存两类合并策略的后续内容行 | 语义已定义、状态池已承载;刷新类已有内容(empower/fortify 2026-09-16 敌人技能池批、weaken 2026-09-18 续时定案),并存仍空,首个并存内容行上线时顺带补验收 |
| P1 | 清图奖励含增益的授予路径 | 来源类别已预留;内容与档位归[地图战斗资源](地图战斗资源.md)定稿 |
| P1 | 单体寻址扩展位(接口已定稿——五条语义见核心规则〈单体寻址扩展位〉节) | 实现随首个单体效果的内容批进游戏,真实入口验收随该批闭合 |
| P2 | 驱散 / 延时 / 转移接口 | 状态一旦生效,玩家没有任何手段摘掉、延后或挪给别人——省掉一整类界面复杂度是明确的设计决定;要加属于新增接口的修订,不是调参 |
@@ -230,12 +230,12 @@ empower 与 fortify 是敌方技能池增益技在状态池侧的数据落点(
| sapped 幅度 | 百分比 [−100,100] 且非 0 | percent 行 magnitude | 乏力;危险格负向 weaken 型,进主角输出修正池(2026-09-15 格面资源批补登记) |
| empower 幅度 | 百分比 [−100,100] 且非 0 | percent 行 magnitude | 蓄力;敌方技能池增益技载体,进敌方输出修正池 |
| fortify 幅度 | 百分比 [−100,100] 且非 0 | percent 行 magnitude | 硬化;敌方技能池增益技载体,进**敌方防御池**(负值 = 减伤方向——2026-09-18 符号纠正) |
| 初始剩余次数 | 整数 [1,99] | duration_settlements | 累加行 = weaken(duration 2)+ empower/fortify(表值 2 = 先兑付后衰减含施放当轮的 1 个有效增益拍)+ attack_up / ac_up(duration 1);累加语义下重复拿一次就按本次授予时长加一段;拉长表值 = 每次授予攒更多段、规划变简单 |
| 叠层上限 | 整数 [1,16] | max_stack | 仅叠加策略消费;累加行层数恒 1、表值上限不消费,empower/fortify ×1(冷却闸下不可能自叠加) |
| 初始剩余次数 | 整数 [1,99] | duration_settlements | 一次性语义行逐行读表;续时行 = weaken(2026-09-18 定案,duration 2)+ empower/fortify(1 个有效增益拍——先兑付后衰减含施放当轮)+ **attack_up / ac_up(2026-09-20 主角增益续时批,duration 表值 1 维持——续时语义在 duration=1 下表现为重复拿重置当轮倒数;跨轮延续随将来 duration 拉长自然显形,数值归状态层重设计批)**;拉长 = 恢复跨轮延续、规划变简单 |
| 叠层上限 | 整数 [1,16] | max_stack | 仅叠加策略消费;刷新行层数恒 1——weaken / attack_up / ac_up 表值上限在续时语义下不消费(2026-09-18 / 2026-09-20),empower/fortify ×1(冷却闸下不可能自叠加) |
非调参的冻结项:三类合并策略语义、两种量纲语义、来源类别枚举、"先兑付后衰减"时序、拒绝原子性、零随机——改动走本文修订流程,不走调参。
联动纪律:增伤与削弱是当量锚的两端;盾牌加护与[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)的承伤预期联动(掷点折扣轴——AC 行值变更须复算生存链区间;ac_up 层数恒 1、局内可达 AC 上限 11,复算随调参批);削弱与主角增益行同名重复授予只加时长、层数恒 1,"单轮层数上限受[行动经济](../排雷循环/行动经济.md)行动点约束"的联动不成立。这些联动值禁止独立调参,修订须重跑锚对照并同步登记册。
联动纪律:增伤与削弱是当量锚的两端;盾牌加护与[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)的承伤预期联动(掷点折扣轴——AC 行值变更须复算生存链区间;2026-09-20 主角增益续时批后 ac_up 层数恒 1、局内可达 AC 上限 11,复算随调参批);削弱改续时后"单轮层数上限受[行动经济](../排雷循环/行动经济.md)行动点约束"的联动随之失效(2026-09-18 续时定案——同名重复标中只刷新剩余次数、层数恒 1;2026-09-20 起主角侧 attack_up / ac_up 同口径)。这些联动值禁止独立调参,修订须重跑锚对照并同步登记册。
## 验收标准
@@ -243,7 +243,7 @@ empower 与 fortify 是敌方技能池增益技在状态池侧的数据落点(
- 多向同构:主角侧增益与减益、敌方侧增强与削弱共用同一套受理、合并、倒数、清除语义,不存在第二套计时逻辑。
- 授予即生效:状态发入当轮结算即兑付第一次,无"待生效"中间态。
- 只登记不去重:同一事实被转化两次授予,登记两层——去重责任在战斗结算。
- 叠层不减钟:叠加策略行叠加只加层数,剩余次数保持首次授予定下的轨迹不变(累加策略行则相反——层数不变、剩余次数加上本次授予的时长;两策略逐行读表)。
- 叠层不减钟:叠加策略行叠加只加层数,剩余次数保持首次授予定下的轨迹不变(刷新策略行则相反——层数不变、只重置剩余次数;两策略逐行读表)。
- 满层拒绝原子且留痕:叠满后再授予返回失败、状态池逐字不变;结算明细多一行"奖励未生效"(含来源)。
- 先兑付后衰减:每轮结算恰做一次衰减,归零实例当轮移除;停手轮、弃图刷新轮照常衰减。
- 合成不设上下限:状态池输出的有效值恒等于层数 × 行值,越出百分比域不封顶不保底;地板在战斗结算侧。
@@ -1,7 +1,7 @@
# 战斗结算
> 一句话:轮末结算的编排与逐行兑现
> 状态:已定稿(自旧体系迁移);现行为 v1.4
> 状态:已定稿(自旧体系迁移);现行为 v1.2
## 设计目的
@@ -84,13 +84,13 @@
| 判定行 | 胜 / 负 / 继续各一行;终局判定行同时是胜负画面的数据锚 |
| 高光行 | 完美封印成立时一行,只记实际有效兑付 |
每行还携带公共字段:来源类别、来源格、轮次、显示名、数值,以及可空的高光标记(用于强调封印标中、清图奖励这类值得高亮的结果)。奖励直伤行的数值字段沿用 `effectiveness` 键名、值为整数点数——键名与量纲是数据导出与分析工具的兼容契约,改动须连动分析工具面。没生效也要留痕:两类"未生效"行如实记录合法例外,呈现时聚合计数,不逐行刷屏。
每行还携带公共字段:来源类别、来源格、轮次、显示名、数值,以及可空的高光标记(用于强调封印标中、清图奖励这类值得高亮的结果)。没生效也要留痕:两类"未生效"行如实记录合法例外,呈现时聚合计数,不逐行刷屏。
任何一行找不到来源即断言失败——宁可返回错误,也不让"合并到看不出来源"的呈现混过数据层。但有些行天然没有棋盘来源,断言为此留了两层豁免,豁免集合是封闭清单,改动同样走本文修订。
第一层按行型豁免两类:衰减行(到期移除本就是段级动作,不属于任何一格)、判定行(它是胜负出口的结论,不是棋盘事实)。这两类连来源类别都不必填。
第二层按来源类别豁免,封闭清单六类:主角攻击行(来源是主角单位本身)、敌方行动行(来源是当时动手的那个敌人单位)、清图奖励行(来源是"这张板被清掉"这一整板事实)、专长揭示掷格行(落空行没有真实棋盘格可指)、专长 GP 入账行(来源是钱包面而非棋盘面)、专长刷新效果行(来源是刷新专长与被弃旧图,不指向单一格)——它们都不指向某个棋盘格,来源格校验因此跳过。
第二层按来源类别豁免,封闭清单五类:主角攻击行(来源是主角单位本身)、敌方行动行(来源是当时动手的那个敌人单位)、清图奖励行(来源是"这张板被清掉"这一整板事实)、专长揭示掷格行(落空行没有真实棋盘格可指)、专长 GP 入账行(来源是钱包面而非棋盘面)——它们都不指向某个棋盘格,来源格校验因此跳过。
豁免不等于免检:按行型豁免的行仍要带齐公共字段、守住各自的语义约束(如衰减行的数值必须是本次移除的读数),按来源类别豁免的行仍必须写明来源类别,其余行必须指回一个真实存在的棋盘格。豁免只是免掉"来源格必须有效"这一条校验,不是免掉整份行协议。
@@ -266,24 +266,6 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值
挖掘期刷新是玩家在挖掘中途主动换图,经[行动经济](../排雷循环/行动经济.md)扣费:扣费成功后按"旧板退役、生成新板、装板、资源预分配恰一次、变异布置"编排,本轮不打断——没有结算段、没有轮次结束。储备不足被拒是玩家决策的合法结果,不是编排错误。刷新图不发清图奖励,完美封印计数随装板重置。
### 换图系专长:刷新事实与本轮兑付(设计定稿,待实现)
持有换图系后续专长时,成功刷新除执行上述换图编排外,还产生一次 `board_refreshed` 事实。事实只在新板装板成功后登记;刷新被拒绝时不产生事实,任何后续效果都不触发。同一轮多次成功刷新按发生顺序逐次登记,不合并成一次。
刷新只登记事实,不当场插入结算。各效果在既有五段与对应消费点兑付:
| 专长 | 兑付规则 |
|---|---|
| 崩壁冲击 | 每次刷新事实开一张全体敌人伤害单据,在本轮战斗段末经伤害控制器统一结账;目标按结账时的存活状态解析 |
| 蓄力周转 | 每次刷新事实累计一层,最多 3 层;本轮下一次主角攻击消费全部层数对应的攻击加成,随后清零;战斗结束不跨战保留 |
| 石层缓冲 | 每次刷新事实把当轮全局减伤状态置为生效;本轮主角每次受到伤害都固定减少 2 点,同一轮多次刷新不继续叠加 |
| 坑道小憩 | 每次刷新事实累计 1 点恢复量,最多 3 点;本轮授予段合计回复生命,封顶生命上限,随后清零;满血时记未生效行 |
| 矿道红利 | 每次刷新事实固定获得 1 GP,走战斗内 GP 缓冲并在授予段留痕;不按旧图探索进度折算,也不与清图奖励绑定 |
全局受伤事件统一:`damage_taken` 是主角受到伤害的唯一效果事件,覆盖敌方攻击、危险格、错误封印资源格与地形造成的主角伤害。石层缓冲订阅该事件并在现行伤害下限之前消费;旧有订阅同一事件的专长也按这一完整语义生效。临时生命值不在此机制内。
崩壁冲击若击杀最后敌人,仍由本轮判定段按既有顺序判胜,不新增挖掘期即时胜利出口。换图系效果使用扩展行留痕:崩壁冲击走伤害单据,石层缓冲在受伤消费行体现减免,坑道小憩与矿道红利分别走治疗与 GP 入账记录。刷新事实来源不指向单一棋盘格,使用明细流水的专长刷新效果来源豁免,不伪造来源格。
战斗开始按固定序列开张:关上配置热重载的闸门、初始化状态池、掷骰定敌方实际数量、生成敌人、装板并预分配资源恰一次、变异布置([地形变异](../排雷循环/地形变异.md)——棋盘设置顺序第 4 步:生成棋盘 → 打开状态初始化 → 战斗资源格设置 → 变异格设置,消费 `variant_place` 封闭流)、发开轮通知并执行开轮摇号(摇定首轮各敌本拍动作)。上一关的大奖励(如血上限提升)经战斗开始入参的覆盖值通道生效,内容归[冒险结构](../冒险循环/冒险结构.md)。
举证:本节为编排流程,无计算。
@@ -378,10 +360,6 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值
- 无来源即炸:每行明细都能指回一个来源事实(棋盘格、单位、清图或段级结论);找不到来源即断言失败,行型与来源类别两层豁免清单见明细流水一节,豁免行仍受其它契约约束。
- 行型封闭:流水行型只出现本文登记的基础 9 类与扩展行;行型词表改动必须走本文修订并同步呈现层行格式化,未登记行型禁止落行。
- 伤害单据管线(2026-09-24):全部伤害(主角先手、敌方伤害技、棋盘克制直伤、群伤、反噬、地形变异)经伤害控制器单据管线兑现,兑付配方封闭五种;目标在结账时刻照规则解析;死亡事件由单位自行宣布——怪死其未结单据作废(零行、不进冷却不进保底计数)、主角死兑付终止;段界结账为现行口径、开单即结为回切结构位,两模式各自同种子同输入逐位复现。
- 换图系刷新事实:成功刷新保存旧图探索进度并登记一次事实,被拒绝时不登记;同一轮多次刷新按发生顺序逐次兑付,刷新本身不新增结算段或轮次结束。
- 换图系输出:崩壁冲击在本轮战斗段末经伤害控制器结算;蓄力周转受 3 层上限约束,本轮下一次主角攻击消费全部层数,战斗结束清空;群伤致敌清空时仍由本轮判定段判胜。
- 换图系生存与资源:石层缓冲经全局 `damage_taken` 对敌方攻击、危险格、错误封印与地形伤害各减 2,同轮不叠加;坑道小憩在授予段按累计值回血并封顶;矿道红利每次成功刷新固定入账 1 GP。
- 全局受伤事件:`damage_taken` 只在主角实际承伤消费点发射一次,所有伤害路径均经同一效果引擎减免面,禁止同一张单重复发射或只让部分伤害来源订阅生效。
- 条款3 对账(2026-10-05 判式换代批 T3——与行动经济 F1 条款3 重立同步):①聚合健康式 (1−ρ̂)·E_dig(u) − ρ̂·V_mine(u) ≥ 0 与 β 比值带 [1.2, 2.5] 判读逐 u 检算(清图支配性审计为常设重跑项,读数快照登记归 clause3 重立条);②封印溢价兑付正确:封印标中正向兑付 = 同型正向 ×(1+δ)(δ 读 `settlement.tres` flag_hit_premium,100=无溢价直通零扰动),三类形态全覆盖(flat power / percent 幅度 / gp 缓冲)、标空与挖格兑付不乘溢价、危险格与安全格同池结构零触碰。
## 待办
@@ -119,7 +119,7 @@
| trigger(触发条件) | 全部,可省 | {fact, op, value, latch} 四键——fact 与 op 取「触发条件」节封闭词表,value 类型与域随 fact,出域加载期拒绝;缺省无字段=无条件技,旧行为零变化(2026-10-26 情境条件触发器批立列、2026-10-27 迭代 39 实装落地;原池条目的血量百分比字段收编为本字段闩型首用例) |
| P1 字段位 | — | 命中段数、目标数——随对应后置批加列(触发条件位已由 trigger 立列收编——2026-10-26 立列、2026-10-27 实装;原"固定值分量"位已由 rider_mult 实装收编——2026-09-19;多段命中「命中段数」保留以防复活) |
普通攻击也是一行技能行,两条域校验锁死它的特殊性:倍率恒 1、冷却恒 0——想配倍率或冷却的就不是普攻,是伤害技。技能伤害存倍率、不存固定值:伤害 = 施放者攻击基线 × 技能倍率——同一行"重击",不同敌种按各自攻击基线缩放 = 基线 A × 技能倍率 M(行值读 enemy.tres / skills.tres),深层强化行自动缩放,这是共享技能表成立的前提;**固定的绝对值伤害不满足该前提**(不随基线缩放、跨关稀释——Brotato 教训),"固定值伤害"的合法形态是**必中附加分量 rider_mult**(×攻击基线的必中小倍率,2026-09-19 实装)。增益技带效果引用与持续回合,百分比天然按施放者同池生效,无缩放问题;妨害技同构,落点由状态行 target_side 路由到主角。技能伤害基线的取整:攻击基线 × 倍率按四舍五入、正好半格时一律向上取——全伤害管线唯一不用向下取整的点(半点上取保住低攻击档特殊技的辨识度:攻击 1 配 ×1.5 的突刺落到 2 而不是 1)。
普通攻击也是一行技能行,两条域校验锁死它的特殊性:倍率恒 1、冷却恒 0——想配倍率或冷却的就不是普攻,是伤害技。技能伤害存倍率、不存固定值:伤害 = 施放者攻击基线 × 技能倍率——同一行"重击",不同敌种按各自攻击基线缩放 = 基线 A × 技能倍率 M(行值读 enemy.tres / skills.tres),深层强化行自动缩放,这是共享技能表成立的前提;**固定的绝对值伤害不满足该前提**(不随基线缩放、跨关稀释——Brotato 教训),"固定值伤害"的合法形态是**必中附加分量 rider_mult**(×攻击基线的必中小倍率,2026-09-19 实装)。增益技带效果引用与持续回合,百分比天然按施放者同池生效,无缩放问题;妨害技同构,落点由状态行 target_side 路由到主角。
池构成纪律(加载校验,违规拒绝入表):**每池恰一行普通攻击**(普攻冷却恒 0 → 可摇集合恒非空,"空池不可能"由结构保证,最坏情况怪物平砍等待——那是玩家的反打窗口而非死拍);**每池增益类技能 ≤1**(非 RPG,怪物连出不同增益显得呆);**每池妨害类技能 ≤1**(2026-09-19 新效应词汇批同构纪律);**每池至少一行不带触发条件的特殊技**(普攻不算——保底特殊技集合恒非空的结构保证,2026-10-26 触发条件批);池条目 skill_id 悬空致命;权重 > 0、冷却 ≥ 0。
@@ -1,7 +1,7 @@
# 行动经济
> 一句话:每轮行动点怎么花、停手与刷新的代价
> 状态:已定稿(自旧体系迁移);现行为 v1.3
> 状态:已定稿(自旧体系迁移);现行为 v1.1
## 设计目的
@@ -91,19 +91,6 @@
停手与刷新合起来构成这本账的基线节拍:满行动点一轮停手,正好攒够一次刷新。行动点修正队列会扰动该节拍的实际兑现(+1 轮可多挖一格),不变式本身不动;对账归曲线调参批。
### 换图系专长对储备与刷新的改写(设计定稿,待实现)
换图系两件基座分别改写 RAP 的来源与刷新价格。它们只给持有专长的玩家增加规则,不改变无专长时的基线账本。
| 专长 | 规则 | 不变边界 |
|---|---|---|
| 矿脉储能 | 每次付费挖格被受理后,额外获得表值 RAP;安全格与危险格同口径 | 连锁展开只随首格的一次付费动作结算,不逐格追加;封印、移动、刷新不产 RAP |
| 省力周转 | 弃图刷新的 RAP 成本为基线的 50% | 只改价格;AP、轮次、每轮刷新上限与换图流程不变 |
两件基座可以同时持有并叠加:付费挖格照常产 RAP,刷新同时按半价扣费。两条规则作用在不同账户入口,不互相覆盖,也不设互斥。刷新仍须储备达到折后门槛才受理;储备不足或超过每轮次数上限时拒绝,状态不变。RAP 仍在战斗结束清零,刷新本身不返 RAP。
无矿脉储能时,挖格不新增 RAP;无省力周转时,刷新成本仍读全局基值。后续输出、生存与资源专长如何使用成功刷新这个事实,归[战斗结算](../战斗循环/战斗结算.md)。
### 下轮行动点修正(格面资源八型批 2026-09-20)
格面资源八型批(2026-09-20)新增 action 型格面资源:正向行 ap_up = 下轮行动点 +1,负向行 ap_drain(迟滞)= 下轮行动点 −1。修正不在授予当轮生效:结算期经行动经济的行动点修正队列登记(同轮多笔按净值累加),下一轮开始时(开轮通知)一次性兑现——兑现值 = 基线 ap_per_round + 排队净值,下限 0,兑现后队列清零;排队净值不跨轮保留。明细在结算流水记效果行(effect_id=ap_delta)。
@@ -249,8 +236,6 @@
| move_ap_cost | int | 表值(冻结 0) | 移动免费——冻结,非调参项 |
| chain_ap_cost | int | 表值(冻结 0) | 连锁免费——冻结,非调参项 |
| refresh_cap_per_round | int | 表值(provisional,结构位预留) | 每轮刷新上限,开轮重置计数 |
| (跨表)矿脉储能产 RAP | int [1, 64] | 设计定稿,待入 `feats.tres` | 每次受理的付费挖格兑付一次;连锁不逐格追加 |
| (跨表)省力周转成本率 | percent | 50%(结构已裁,待入 `feats.tres`) | 只改持有者的刷新价格;双基座叠加时不覆盖矿脉储能 |
| (跨表)跨冒险行动点加成 | int [0,10] / int [0,99],冒险表 | adventure_table bonus_ap_flat / bonus_cap_ap(provisional) | 三选一 AP 件兑现值与全冒险次数上限;加成轴语义见「跨冒险行动点加成轴」节 |
字段名注记:2026-09-18 措辞完成批已全链对齐正式名——表字段与本文行名统一为 `refresh_cap_per_round`,刷新入口命名与表字段口径对齐(命名统一登记兑现,切片临时名零残留)。
@@ -265,8 +250,6 @@
- 仲裁唯一:最后 1 点行动点挖开最后一个安全格时,判清图(剩余清零 + 换图 + 清图奖励),不判耗尽;输出恰一条。
- 停手 1:1:剩余 3 点停手,储备池加 3,下轮同图继续。
- 刷新规则:储备不足时刷新被拒绝且状态不变;同一轮第 3 次刷新被拒绝;刷新不重置行动点、不发清图奖励、旧图上的封印印记失效。
- 矿脉储能:持有专长时,每次受理的付费挖格额外产一次 RAP,安全格与危险格同口径,连锁展开不逐格追加;无专长时挖格不新增 RAP。
- 省力周转与双基座:持有省力周转时按基线的 50% 扣费;与矿脉储能同时持有则两条规则都生效,刷新仍受储备门槛与每轮次数上限约束。
- 储备清零:战斗结束信号到达后储备池归 0,行动点进入休眠。
- 跨字段校验:任一动作成本配置超过每轮预算时,加载期致命中止。
- 零随机:同一动作序列驱动两个独立行动点实例,轮次结束记录与储备轨迹逐项相同。
@@ -55,13 +55,13 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
三区各管一块:
| 区 | 位置与几何 | 管什么 |
| 区 | 位置与尺寸 | 管什么 |
|---|---|---|
| B 战斗画面 | 全宽,高读布局表 `stage_h` | 主角站桩立绘、敌人站桩立绘 ×1–3(**全站桩形态,2026-09-20 用户拍板:无框立绘+底座、状态小图标挂血条下,英雄卡/敌人卡退役**)、轮次阶段指示、结算明细带 |
| C 角色信息 | 左下,宽读 `info_panel_w`,高 = 基准屏高 − B 区高 | 生命 / 攻击 / 储备数据框、状态效果槽、小人立绘 |
| D 扫雷图 | 中下,宽 = 基准屏宽 − C 区宽 − 列间距(原右下面板删除后横向加宽),高同 C 区 | 行动点条与按钮组、棋盘本体、toast 槽 |
| B 战斗画面 | 全宽 × 270px | 主角站桩立绘、敌人站桩立绘 ×1–3(**全站桩形态,2026-09-20 用户拍板:无框立绘+底座、状态小图标挂血条下,英雄卡/敌人卡退役**)、轮次阶段指示、结算明细带 |
| C 角色信息 | 左下 240×530 | 生命 / 攻击 / 储备数据框、状态效果槽、小人立绘 |
| D 扫雷图 | 中下约 1036×530(原右下面板删除后横向加宽) | 行动点条与按钮组、棋盘本体、toast 槽 |
分区几何的唯一事实源 = `game/data/tables/battle_layout.tres`(经 `ConfigDb.presentation.battle_layout` 读取);分区尺寸与组件落位的像素级裁决归 [battle.md](../../ux/battle.md),两份文档只写结构关系、不复写数值。三区结构与双舞台常驻是结构冻结项,修订走文档修订而非调参。节点链进度不在战斗屏呈现——它由关卡画面(选路覆盖层常驻形态)的节点态承载,见[关卡节点地图](../冒险循环/关卡节点地图.md)。
分区尺寸与组件落位的像素级裁决归 [battle.md](../../ux/battle.md);三区结构与双舞台常驻是结构冻结项,修订走文档修订而非调参。节点链进度不在战斗屏呈现——它由关卡画面(选路覆盖层常驻形态)的节点态承载,见[关卡节点地图](../冒险循环/关卡节点地图.md)。
**结论**:棋盘格边长由 [battle.md](../../ux/battle.md)「棋盘格尺寸公式」按棋盘区实测面积与板型算出;本文只判"塞不塞得进",不复制算式与算例。**分辨率档位(2026-09-30 迭代 9 三裁决案甲修订)**:两档=1280×800 基准档(本表全部定值的口径)+1920×1080 档=**全局等比**(stretch canvas_items+aspect keep——16:10 设计在 16:9 窗口为等比 1.35×+左右黑边各 ~96px);本节与各屏定值一律按 1280 基准档书写,1920 档由引擎等比承载、零重排。
@@ -74,9 +74,9 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
| 变量 | 含义 | 现行值 |
|---|---|---|
| N | 棋盘边长格数 | 读[棋盘生成](../排雷循环/棋盘生成.md)(现行四档;事实源 board_gen.tres) |
| 棋盘区宽 / 高 | 扫雷图区基准尺寸 | 由 D 区尺寸扣行动点条高(读 `ap_bar_h`)得出,本表不复制现算值 |
| 棋盘区宽 / 高 | 扫雷图区基准尺寸 | 由 D 区尺寸扣行动点条 44px 得出,本表不复制现算值 |
装板可行性由上面的不等式保证;格边长的可读下限见 [battle.md](../../ux/battle.md),算例由样张渲染脚本按布局表现算、不入文档。棋盘数字直接显示排雷玩法给的真值——呈现层禁止自己算数字,这是"数据层从不说谎"在呈现侧的镜像。
装板可行性由上面的不等式保证;格边长的现行算例与可读下限见 [battle.md](../../ux/battle.md)。棋盘数字直接显示排雷玩法给的真值——呈现层禁止自己算数字,这是"数据层从不说谎"在呈现侧的镜像。
### 提示与弹层:轻提示随起随消、重弹层排队进出
@@ -244,7 +244,7 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
## 调参表
本系统的参数全部是呈现节奏与可读性常量,不是玩法数值——玩法数值一律归[数据配置](数据配置.md)的表,与本表无关。修订本文常量走文档修订流程。**本表常量无数据表承载,为文档面唯一事实源;入驻 .tres 时本列改指路。** 布局几何(B 区高 / C 区宽 / AP 条高 / 明细带两态高)已入驻 `game/data/tables/battle_layout.tres`,不在本表重复。
本系统的参数全部是呈现节奏与可读性常量,不是玩法数值——玩法数值一律归[数据配置](数据配置.md)的表,与本表无关。修订本文常量走文档修订流程。**本表常量无数据表承载,为文档面唯一事实源;入驻 .tres 时本列改指路。**
| 参数 | 域 | 现行值(文档自持,无表承载) | 说明 |
|---|---|---|---|
@@ -254,6 +254,7 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
| clear_celebration_ms | 每次清图 | 3000–5000 | 上限约束:三五秒即收 |
| font_min_board / font_min_detail / font_min_tooltip | 1280×800 基座 | 18 / 14 / 13 px | 可访问性基线 |
| reduce_motion_scale | 每段动画 | 0.5 或跳终态 | 减动效开关系数 |
| detail_band_height | 结算明细带 | 24 / 84 px | 摘要 / 实时流两态高度 |
结构冻结(非调参项,改动走文档修订):三区布局与分区尺寸、双舞台常驻、单意图帧纪律、弹层层级纪律、图标键映射契约、程序化占位策略、订阅纪律。性能预算为引用值:同屏 draw calls < 200、进入战斗屏 500ms 内可交互。
@@ -261,7 +262,7 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
以下判据逐条可测,全部通过才算闭环达标。
- 三区无遮挡、无重叠、无内容裁切(棋盘全部格子与数字完整可见),分区几何与布局表 `battle_layout.tres` 一致;同屏 draw calls < 200;进入战斗屏 500ms 内首格可点。
- 三区无遮挡、无重叠、无内容裁切(棋盘全部格子与数字完整可见),分区尺寸与 battle.md 布局表一致;同屏 draw calls < 200;进入战斗屏 500ms 内首格可点。
- 任意板型装板后网格实高不超出棋盘区:N × 格边长 + (N−1) × 2px ≤ 棋盘区可用高;数字字号与整数倍缩放判据见 battle.md。
- 已开 / 未开格态在灰度截图下可逐格分类;已引爆危险格"可通行可读"(已开底加巢穴纹、可作移动目标)。
- 类型微光:微光只在英雄周围 8 格内的未开格显示;出圈即灭、入圈即亮;已开格与封锁格恒无微光;微光呈现不随格是雷是安变化(不泄危险格与安全格)。(迭代 30 卡①实装后转正式验收)
@@ -70,7 +70,6 @@
| 关卡表 | 逐关节点图与层名 | [冒险结构](../冒险循环/冒险结构.md) |
| 冒险表 | 关卡大奖励与钥石入账(单行全局) | [冒险结构](../冒险循环/冒险结构.md) |
| 元进度表 | 元进度字段(已建表 2026-09-21——现行五行族:属性锻造 / Boss 钥石 / 工坊阈值 / 换算率 / 同调刷新升级行族,顺带扩列) | [元进度](../跨局循环/元进度.md) |
| 战斗屏布局表(`battle_layout.tres`) | 分区几何与明细带两态高(单行;呈现层布局配置,非玩法数值——供呈现层与样张工具同源读取) | [战斗屏规格](../../ux/battle.md)(结构)/[HUD框架](HUD框架.md)(呈现常量) |
举证:本节为数据纪律约定,无计算。违规检测 = 静态扫描加人工复核,随各表回填定稿与里程碑检查执行。
+15 -11
View File
@@ -115,13 +115,13 @@
### Layout Zones
采用用户拍板的布局图(2026-09-12),按 1280×800 基座落尺寸。**分区几何的唯一事实源 = `game/data/tables/battle_layout.tres`**(经 `ConfigDb.presentation.battle_layout` 读取;字段 `stage_h` / `info_panel_w` / `ap_bar_h` / `log_band_h_dig` / `log_band_h_settle`)。本节只写结构关系与内容职责,不复写数值;任何文档与代码不另立第二份布局值。
采用用户拍板的布局图(2026-09-12),按 1280×800 基座落尺寸:
| 区 | 位置与几何 | 内容 |
| 区 | 位置与尺寸 | 内容 |
|---|---|---|
| **B 战斗画面** | 全宽,高读 `stage_h`(2026-10-06 方案二拍板:演出 ≈1/3 屏) | 主角站桩立绘(左)+ 兑现演出区(中)+ 敌人站桩立绘 ×1–3(右)——**全站桩形态(2026-09-20 用户拍板,敌人卡形态待办裁决完成):主角与敌人均为无框立绘+底座,零卡片**;主角与敌人站桩 = **HP 与状态效果的唯一展示面(2026-09-26 信息归属拍板)**;底部结算明细带(挖掘期收起高读 `log_band_h_dig`,结算期展开高读 `log_band_h_settle`);顶部中央轮次·阶段指示 |
| **C 角色信息** | 左下,宽读 `info_panel_w`,高 = 基准屏高 − B 区高 | 攻击值(含修正显示)、护甲 AC;秘宝槽、奇物列表(现行标题「特性」)——HP 条/RAP 池/状态效果槽/立绘占位/钱包行退役(2026-09-26 信息归属拍板:HP 与状态唯一展示面 = B 区站桩;RAP 迁 D 区 AP 条;GP/钥石迁出战斗屏) |
| **D 扫雷图** | 中下,宽 = 基准屏宽 − C 区宽 − 列间距,高同 C 区(2026-10-06 方案二:底行压缩全部由面板空档吸收,**棋盘原尺寸不缩、格子不变**;原右下面板删除后横向加宽,吸收其宽度) | 顶部 AP 条(高读 `ap_bar_h`:左——AP 点阵 + 停手按钮;中——RAP 点阵+数字〔自 C 区迁入,贴弃图刷新按钮,2026-09-26 拍板〕;右——图例按钮 + 弃图刷新按钮〔雷图右上角,2026-09-12 拍板〕);棋盘主体(居中,格边长见下方「棋盘格尺寸公式」);toast 槽(上缘内侧) |
| **B 战斗画面** | 全宽 × 270px(2026-10-06 方案二拍板:演出 ≈1/3 屏,原 252) | 主角站桩立绘(左)+ 兑现演出区(中)+ 敌人站桩立绘 ×1–3(右)——**全站桩形态(2026-09-20 用户拍板,敌人卡形态待办裁决完成):主角与敌人均为无框立绘+底座,零卡片**;主角与敌人站桩 = **HP 与状态效果的唯一展示面(2026-09-26 信息归属拍板)**;底部结算明细带(24px 摘要 / 结算期 84px 实时流);顶部中央轮次·阶段指示 |
| **C 角色信息** | 左下 240px × 530px(2026-10-06 方案二:548→530) | 攻击值(含修正显示)、护甲 AC;秘宝槽、奇物列表(现行标题「特性」)——HP 条/RAP 池/状态效果槽/立绘占位/钱包行退役(2026-09-26 信息归属拍板:HP 与状态唯一展示面 = B 区站桩;RAP 迁 D 区 AP 条;GP/钥石迁出战斗屏) |
| **D 扫雷图** | 中下 ~1036px × 530px(2026-10-06 方案二:548→530——压缩全部由面板空档吸收,**棋盘 438×438 原尺寸不缩、格子不变**;原右下面板删除后横向加宽,吸收其宽度) | 顶部 AP 条(44px:左——AP 点阵 + 停手按钮;中——RAP 点阵+数字〔自 C 区迁入,贴弃图刷新按钮,2026-09-26 拍板〕;右——图例按钮 + 弃图刷新按钮〔雷图右上角,2026-09-12 拍板〕);棋盘主体(居中,格边长见下方「棋盘格尺寸公式」);toast 槽(上缘内侧) |
> 布局为 B/C/D 三区——关卡进度条不在战斗屏(节点链进度常驻关卡画面,见 Navigation Position;字母不重编沿用 B/C/D)。
@@ -145,7 +145,11 @@
- N 的取值与每关板型的对应关系读[棋盘生成](../systems/排雷循环/棋盘生成.md),现行值的事实源是 `data/tables/board_gen.tres`。
- 数字字号 = max(18, ceil(格边长 × 0.5)),像素字体整数倍缩放(canvas_items stretch 保证清晰)。
算例不入文档:棋盘区可用面积随布局表与板型变化,不是契约值——现算并绘在整屏样张上,本文件不复写。
按 1280×800 基准档、棋盘区可用高 486px(D 区 530 减行动点条 44)推算的算例(随布局与板型变化,不是契约值):
| 板型 N | 10 | 12 | 13 | 14 |
|---|---|---|---|---|
| 格边长 | 43px | 36px | 33px | 30px |
### Component Inventory
@@ -192,13 +196,12 @@
### ASCII Wireframe
> **2026-09-26 信息归属拍板**:C 区 HP/RAP/状态槽/立绘占位/钱包行退役——HP 与状态唯一展示面 = B 区站桩,RAP 迁 D 区 AP 条贴弃图刷新按钮,GP/钥石迁出战斗屏;C 区改攻击数据框+两预留区。下方线框图已随拍板重绘;旧线框留档于 git 历史。
> **2026-09-23 停点前移批**:A 区关卡进度条退役,下方线框图为 B/C/D 三区(纵向空间划归 C/D 底行;关卡内节点进度常驻关卡画面,战斗屏零进度承载);旧四区线框留档于 git 历史。
> **几何标注已撤**:线框只示意结构,各区几何读 `game/data/tables/battle_layout.tres`,图中不标像素值。
> **2026-09-23 停点前移批**:A 区关卡进度条退役,下方线框图为 B/C/D 三区(28px 纵向空间划归 C/D 底行 520 → 548;关卡内节点进度常驻关卡画面,战斗屏零进度承载);旧四区线框留档于 git 历史。
> **2026-09-20 全站桩形态改版**:敌人卡形态裁决完成(卡片式退役、主角与敌人均站桩——无框立绘+底座、状态小图标挂血条下),下方线框图 B 区已随裁决重绘;旧卡片式线框留档于 git 历史。
```
1280 × 800 ────────────────────────────────────────────────────────────────────
┌─[B] 战斗画面(高读布局表) ──────────────────────────────────────────────────┐
┌─[B] 战斗画面 270px ──────────────────────────────────────────────────────────┐
│ /小人\ 第 3 轮 · 挖掘中 伏×2 伏×2 │
│ (落影) [ 兑现演出区 ] /蛆虫\ /蛆虫\ │
│ HP▓▓▓▓░ (结算期: 光带→弹道→受击) ①HP▓▓▓░ ②HP▓▓░░ │
@@ -206,7 +209,8 @@
│ ├─ 结算明细带 ────────────────────────────────────────────────────────────┤ │
│ │ ▸上轮: 主角攻击3→蛆虫-3 | 攻击+50%(1结算) | 警觉+1×2 … [展开明细▾] │ │ # 2026-09-17 数值压缩批:UI 示意文本同步(atk 7→3〔地精格数÷3 + L1 锚行;UX 示意按当前地精行值读〕、伏击 +3 → +1/层,幅度参考 data/tables/)
│ └────────────────────────────────────────────────────────────────────────┘ │
├─[C] 角色信息 ─────────┬─[D] 扫雷图 ───────────────────────────────────────────┤
├─[C] 角色信息 240px ───┬─[D] 扫雷图 ~1036px ──────────────────────────────────┤
│ 548px │ 548px │
│ ┌──────────────────┐ │ ┌─────────────────────────────────────────────────┐ │
│ │ 攻击 6 (+50%) │ │ │ AP ●●●●●○○○ 5/8 RAP ▓▓▓░ 3/8 │ │
│ │ 护甲 AC 12 │ │ │ [⏹停手] [?图例] [↻刷新 8|剩2] │ │
@@ -228,7 +232,7 @@
| State / Variant | Trigger | What Changes |
|---|---|---|
| **挖掘阶段(默认态)** | 轮次开始 / 结算完毕回 Active 相位 | B 区敌人待机(意图徽标全程可见——敌人系统 Rule 8⑤),D 区棋盘可交互,AP 条点亮;能量 2/10,唯悬停呼吸微光在动(§2.1) |
| **结算阶段** | round_end 触发(AP 尽/停手/清图) | D 区锁输入(棋盘去饱和 + 金橙色相偏移,明度不变,数字保持全对比);B 区播放五段编排演出(授予段 → 增益/减益段 → 战斗段 → 衰减段 → 判定段,战斗结算 段序冻结);明细带按结算期档展开(高读 `log_band_h_settle`)逐行滚动;阶段指示→"结算中";能量 7/10 |
| **结算阶段** | round_end 触发(AP 尽/停手/清图) | D 区锁输入(棋盘去饱和 + 金橙色相偏移,明度不变,数字保持全对比);B 区播放五段编排演出(授予段 → 增益/减益段 → 战斗段 → 衰减段 → 判定段,战斗结算 段序冻结);明细带展开 84px 逐行滚动;阶段指示→"结算中";能量 7/10 |
| **清图瞬间** | 全部安全格开完 | 金粒喷泉 + 彩纸 3–5s 即收(§2.3);清图奖励行强调呈现(H2,地图战斗资源×④——金框高亮行);随后换新图 install |
| **完美封印高光** | 战斗结算高光判定(全图标中/零误标类) | 全屏喝彩级反馈(§2.2 最高档):金光带加倍扫射 + 「完美封印 ×2」横幅——P2 爆发兑现节点(创意风险 #2 落点) |
| **封印标中高光** | 封印判定·标中 | 该印记化暴击弹道加重 + 明细行金框——chord 缺席的即时兑现补偿(创意风险 #3 落点) |
+3 -5
View File
@@ -1,6 +1,6 @@
# 营地场景 UX spec(camp)
> 状态:v2.2(现行)
> 状态:v2.1(现行)
> 事实源:本 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)(主菜单语境)
@@ -24,11 +24,9 @@
纵深=远景天空与远山/中景木围墙与营地大门/近景篝火与左右物件(作者纵深稿)。中景围墙是横贯全宽的密排竖木桩墙——木桩一根挨一根无缝、桩顶削尖、无横木,只在中段留缺口给大门。
**场景按要素分层(10 张)**:远景天空/远山/整片地面/门洞内的小路合成 `scene_camp_bg` 背景层(z0,不透明全幅);中景木围墙独立成 `scene_camp_wall` 围墙层(z1,透明底,门洞处留透明缺口);其余八个物件层各一张、由上往下叠。门洞是围墙层的透明缺口,透出背景层画的**一条通向远处的小路**,不可填死。
**中景带自画面底部往上约 2/3 处起**;近景物件允许压住围墙(围墙是纯背景板),**唯一例外=中间门洞必须留空、不被任何物件遮挡**。围墙形态、门扇比例与帐篷尺寸的现行口径归 [art-bible](../../art/art-bible.md) §6.2,本 spec 不再复述。
**中景带自画面底部往上约 2/3 处起**;近景物件允许压住围墙(围墙不可点,z 序在近景物件之下),**唯一例外=中间门洞必须留空、不被任何物件遮挡**。围墙形态、门扇比例与帐篷尺寸的现行口径归 [art-bible](../../art/art-bible.md) §6.2,本 spec 不再复述。
坐标草案与分层验收判据见 [camp-scene-prompts](../../art/camp-scene-prompts.md) §2.3/§4(10 张口径现行事实源);2026-10-22 美术方案讨论留痕见 [提案](../../../reports/提案-营地场景图美术生成方案-2026-10-22.md)。
坐标草案与验收判据见 [提案](../../../reports/提案-营地场景图美术生成方案-2026-10-22.md) §2.5/§5。
## 点选反馈(根态)
+1 -1
View File
@@ -81,7 +81,7 @@ MVP 未使用标准控件(不入库):toggle / dropdown / input field / tab
**Category**: Data Display
**Used In**: 战斗画面区底部(结算期第一注视点)
**Description**: 轮末结算逐行流水实时呈现 + 可回看——「扫雷之因逐行兑现为战果」(P2 归因)的承载面。挖掘期收起为 1 行上轮摘要;结算期展开为实时流(带高读 `log_band_h_settle`);点击开完整回看 overlay。
**Description**: 轮末结算逐行流水实时呈现 + 可回看——「扫雷之因逐行兑现为战果」(P2 归因)的承载面。挖掘期收起为 1 行上轮摘要;结算期展开 84px 实时流;点击开完整回看 overlay。
**Specification**:
- 数据源:[战斗结算](../systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)步骤流(9 类行封闭协议(现行);公共字段:来源类别 / 来源格 / 轮次 / 显示名 / 数值 / 可空高光标记);**无来源行 = 断言失败**
-6
View File
@@ -168,12 +168,6 @@ func resume_adventure(bp: Dictionary, params: Dictionary = {}) -> bool:
var bp_counters = _bp_store._bp_read("adventure_counters", bp)
if bp_counters is Dictionary:
adventure_counters = (bp_counters as Dictionary).duplicate(true)
return _resume_pending_or_start(bp)
# 续玩收束段(宿主侧——停点直回/已兑付重发/无停点续玩起步;R2 回放段的尾半,语句序与
# resume_adventure 内联时逐句相同):三选一停点态与待推进位经件读写,选路停点快照单跳传递。
func _resume_pending_or_start(bp: Dictionary) -> bool:
var bp_pending: Dictionary[Variant, Variant] = bp.get("bonus_pending", {}) as Dictionary
var bp_result: Dictionary[Variant, Variant] = bp.get("bonus_result", {}) as Dictionary
if not bp_pending.is_empty():
+5 -15
View File
@@ -1,9 +1,8 @@
## VERTICAL SLICE - NOT FOR PRODUCTION
## 数值表单点访问入口:全部 .tres 表的加载、校验诊断与门面(垂直切片验证:改表即改玩法,数值零硬编码)。
## 玩法代码禁止绕过本单点自建 load();行查询归各表类(表管自己的行),
## 表持有按域收进四容器(combat 战斗编排域/run 冒险 runner 域/crossrun 跨局元进度域/
## presentation 表现层布局域),消费面经 db.<容器>.<表> 直连。
## 「经 ConfigDB 单点读取」=经其持有的容器与表对象(架构 :88)。
## 表持有按域收进三容器(combat 战斗编排域/run 冒险 runner 域/crossrun 跨局元进度域),
## 消费面经 db.<容器>.<表> 直连。「经 ConfigDB 单点读取」=经其持有的容器与表对象(架构 :88)。
## 冒烟脚本可显式实例化本类(headless --script 亦会加载 autoload——共享 .tres 上的 resolver 归最后装载的实例);
## 加载失败 is_ready=false 加 fatal 封印,调用方须查。
class_name ConfigDb
@@ -29,13 +28,11 @@ const TABLE_MANIFEST := {
"adventure": "adventure.tres", # AdventureTable(大奖励与钥石行值单点)
"feats": "feats.tres", # FeatTable 规则改写型特性(定义表 Rule 4 豁免——TreasureItemTable 先例;空表合法态=主时间线零扰动)
"forge": "forge.tres", # ForgeTable——两根类型轴默认值+六路线行族;攻防所有权切分唯一数据面
"battle_layout": "battle_layout.tres", # BattleLayoutTable——战斗屏分区几何与明细带高度单行
}
var combat: ConfigDomainCombat # 战斗编排域七表(board_gen/variation/status_effects/enemy/skill/hero/settlement)
var run: ConfigDomainRun # 冒险 runner 域七表(level/difficulty/level_gen_params/reward/adventure/action_economy/shop)
var crossrun: ConfigDomainCrossrun # 跨局元进度域五表(meta/meta_tree/treasure_items/feats/forge)
var presentation: ConfigDomainPresentation # 表现层布局域一表(battle_layout)
var is_ready := false
var _diagnostics: Array[Dictionary] = [] # {severity, category, message}
@@ -48,7 +45,6 @@ func _init() -> void:
combat = ConfigDomainCombat.new()
run = ConfigDomainRun.new()
crossrun = ConfigDomainCrossrun.new()
presentation = ConfigDomainPresentation.new()
_resolver = ConfigDbResolver.new(push_diag,
func() -> Variant: return combat.board_gen.rows, func() -> Variant: return combat.enemy.rows, func() -> Variant: return run.difficulty) # 协作类持门面引用(诊断/致命通道回呼)
@@ -121,14 +117,7 @@ func load_tables(root: String, collect_only: bool) -> bool:
if has_errors and not collect_only:
# 游戏通道:致命(Rule 6)——is_ready 恒 false,调用方(主场景)中止构建
return false
# 容器装配(表行按域收进四容器+resolver 注入)归私有协函数——load_tables 只留加载/校验/致命门面
_assign_loaded(loaded)
is_ready = not has_errors
return not has_errors
# 容器装配协函数:20 表成员按域收进四容器(2026-10-27 全清设计定稿,2026-10-31 增表现层布局域)
func _assign_loaded(loaded: Dictionary) -> void:
# 容器装配(19 表成员按域收进三容器——2026-10-27 全清设计定稿)
combat.board_gen = loaded.get("board_gen")
combat.variation = loaded.get("variation")
combat.status_effects = loaded.get("status_effects")
@@ -148,11 +137,12 @@ func _assign_loaded(loaded: Dictionary) -> void:
crossrun.treasure_items = loaded.get("treasure_items")
crossrun.feats = loaded.get("feats")
crossrun.forge = loaded.get("forge")
presentation.battle_layout = loaded.get("battle_layout")
# resolver 协作件注入三表(resolve 委托承载——resolver 文件与键零搬移)
combat.board_gen._resolver = _resolver
combat.enemy._resolver = _resolver
run.difficulty._resolver = _resolver
is_ready = not has_errors
return not has_errors
# 跨表校验(悬空引用 / 池护栏——全部加载期致命)本体:
-6
View File
@@ -1,6 +0,0 @@
## 表现层布局域容器(D2 域容器——config_db 表持有按域收敛):战斗屏布局一表类型化持有。
## 零方法零行为——纯持有结构;「经 ConfigDB 单点读取」=经其持有的容器与表对象(架构 :88 定稿注记)。
class_name ConfigDomainPresentation
extends Resource
var battle_layout: BattleLayoutTable
@@ -1 +0,0 @@
uid://bay1b1s3lrd1e
-30
View File
@@ -1,30 +0,0 @@
## 战斗屏布局表 schema:分区几何与明细带高度的单行类型化读取(呈现层布局配置,非玩法数值)。
## 消费面 = BattleStageView / BattleLogView / HeroInfoPanelView / ApBarView(经 ConfigDb.presentation.battle_layout);
## 文档只写结构关系与表名,不复制数值。validate() 违例加载期致命(fail-fast)。
class_name BattleLayoutTable
extends Resource
@export var stage_h: int = 252 # B 区高(全宽战斗画面,含底部明细带)
@export var info_panel_w: int = 240 # C 区宽(左下角色信息列)
@export var ap_bar_h: int = 44 # D 区 AP 条高
@export var log_band_h_dig: int = 24 # 明细带挖掘期收起高(单行上轮摘要)
@export var log_band_h_settle: int = 84 # 明细带结算期展开高(实时结算流)
func validate() -> Array:
var errs: Array[Dictionary] = []
if stage_h < 120 or stage_h > 600:
errs.append({"category": "domain", "message": "stage_h 越域 [120,600]: %d" % stage_h})
if info_panel_w < 120 or info_panel_w > 480:
errs.append({"category": "domain", "message": "info_panel_w 越域 [120,480]: %d" % info_panel_w})
if ap_bar_h < 24 or ap_bar_h > 96:
errs.append({"category": "domain", "message": "ap_bar_h 越域 [24,96]: %d" % ap_bar_h})
if log_band_h_dig < 16 or log_band_h_dig > 80:
errs.append({"category": "domain", "message": "log_band_h_dig 越域 [16,80]: %d" % log_band_h_dig})
if log_band_h_settle < 24 or log_band_h_settle > 160:
errs.append({"category": "domain", "message": "log_band_h_settle 越域 [24,160]: %d" % log_band_h_settle})
if log_band_h_settle < log_band_h_dig:
errs.append({"category": "cross_field", "message": "log_band_h_settle(%d) < log_band_h_dig(%d)——展开态不得矮于收起态" % [log_band_h_settle, log_band_h_dig]})
if log_band_h_settle >= stage_h:
errs.append({"category": "cross_field", "message": "log_band_h_settle(%d) ≥ stage_h(%d)——明细带不得占满 B 区" % [log_band_h_settle, stage_h]})
return errs
@@ -1 +0,0 @@
uid://b3jh66yq4b7rp
+15
View File
@@ -11,3 +11,18 @@ rap_refresh_cost = 8
refresh_cap_per_round = 2
move_ap_cost = 0
chain_ap_cost = 0
; AP 压速批(2026-09-16 用户拍板):ap_per_round 8→6——无伤通关根因诊断(playtest_5678/1234 实录:
; 第 1 轮 8 AP 全封印 = 8 份正向兑付 + 16 魔法充能,减伤/削弱单轮堆满 → "被减伤归零"零承伤通关)
; 的主阀门:削每轮兑付吞吐(封印 rush 墙/归零轮覆盖率 ~50%→~35%)。单格兑付语义零改动(保留封印命中
; 正向兑付——危险格/安全格概率差异化设计的前提)。rap_refresh_cost 8→6 随动 = 保持 registry 登记
; "默认 = ap_per_round,满停一轮 = 恰好一刷基线节拍"耦合不变式;若有意解耦(刷新相对变贵推清图)
; 须单独立批。减伤幅度下调(-30 → 下调)为同根因配套项,待用户拍板数值后另行落表;
; 终局方案 = 减伤换装护甲等级 AC+1(随 AC 掷点定稿批 EV 中性换装)。
; 观察口径:AP 6 不够再降 4(墙覆盖率 ~19%,代价 = 12×12 板挖掘节奏拖长)。
;
; Package B 数值优化批·首版(2026-09-22——qa-data/实现计划书_PackageB.md §4.2):ap_per_round 6→8、
; rap_refresh_cost 6→8 随动(维持 registry 登记"刷新成本 = 每轮 AP,满停一轮恰一刷"不变式;schema
; 非硬约束,系设计不变式)。上批 8→6 所杀"首轮全封印→减伤削弱堆满→零承伤通关"退化,在 B1 敌人 HP
; 大幅抬升后单轮堆满已无法零承伤通关多轮整场,风险缓解;复测须盯 analyze.py 零承伤轮指标,明显回升
; 则按计划书 §6.5 AP 8→7 回调。dig/seal/move/chain cost 与 refresh_cap 未动(move/chain 结构冻结 0)。
-11
View File
@@ -1,11 +0,0 @@
[gd_resource type="Resource" script_class="BattleLayoutTable" load_steps=2 format=3]
[ext_resource type="Script" path="res://data/schemas/battle_layout_table.gd" id="1"]
[resource]
script = ExtResource("1")
stage_h = 252
info_panel_w = 240
ap_bar_h = 44
log_band_h_dig = 24
log_band_h_settle = 84
+45
View File
@@ -408,3 +408,48 @@ rows = [{
"shave_ring_radius": 1,
"r0_max_cap": 59
}]
; 切片调参登记(SLICE-TUNED provisional,调参所有权仍归 C3):
; A1 GDD 参考行(d0.10/0.12)经"先布后删"环内移除后仅幸存 2-3 雷、R0/|S|约0.97、残余挖掘 2-4 格——
; 掘近退化板(A2 反例 B 机制的低密度放大)。实验数据(8 种子均值,smoke/experiment_density.gd):
; d0.25 → L1 幸存雷 11/残余 13/inf 0.925/att 2.9 · L2 雷 19/残余 21/inf 0.908/att 7.9(seed42 实测 inf 0.889→target 定 0.88 首过),零降级告警。
; target 收窄至 0.88/0.88(不低于 0.85 绝对锚)为密度上移的对价——B1 条款③⑤对账重跑义务随调参触发。
; 2026-09-11 关卡扩展批:L1 增 D1–D4 行(Boss=Dmax=4)。
; Boss 板以 12×12 区分(d0.28/t0.87 实测达不到推理率门槛——best≈0.81 降级告警,回退 0.25/0.88;
; 密度轴上调留给 C3 与求解器能力一起解)。
;
; 分支节点图批(2026-09-17——L2 幽暗地域板行铺满,全值 provisional 归 难度曲线与Boss):
; L2 战斗/Boss 节点 (2, 0/1/4/5/6/7/8) 七行精确铺满(跨表校验强制——ConfigDB ④ level_node_dangling);
; 奖励点 (2,2)/恢复点 (2,3) 不开战斗、无板行(跨表校验只查 battle/boss 节点)。
; 板面参数与 L1 高档同值(12×12 d0.25 t0.88)——密度/推理率轴差异化留给 难度曲线与Boss 调参批;
; board_type 词表 v1.0(2026-09-19 用户拍板):L1=dungeon 地牢基线 / L2=underdark 幽暗地域(玩家侧显示名「地图类型」);域校验在 board_gen_table.gd 词表常量。
;
; 第三关内容批(2026-09-20):板面 13×13 / Boss 14×14 兑现「Boss 板 = 本关最大板形」纪律;
; 密度维持 0.25(0.28 破推理率门槛有失败先例——切片调参登记 best≈0.81 降级告警,加难主杠杆 = 板面 + 地形);
; 词表第三值 deep_underdark(灰矮人矿道方向——v1.1 2026-09-20 L3 内容批,显示名归呈现侧);
; min_safe_count 按既有 ~0.42 格占比外推(13×13 → 70 / 14×14 → 82)。
; 降档登记:Boss max_gen_attempts 批内拟值 36 越 schema 域 [1,32](config_fatal 修行值纪律——不许放宽 schema),
; 按域上限取 32(批内降档梯子「Boss 回 13×13 时 attempts 32」同款值)。行值全 provisional 归 难度曲线与Boss。
;
; 商店房批连带(2026-09-21——level.tres 商店房批 Boss 重编号 8→9):新增 (2,9)/(3,9) 精确行
; (跨表校验强制——ConfigDB ④ level_node_dangling),行值照抄原 Boss (L,8) 行;
; 商店房 (L,8) 不开战斗、无板行(跨表校验只查 battle/boss 节点)。行值 provisional 归 难度曲线与Boss。
; 陈旧行清理(GP+商店房实施批收尾 2026-09-21):并行表代理曾把 Boss 板行照抄到 (2,8)/(3,8)——节点 8 现为
; 商店房、无板行需求,原 (2,8)/(3,8) 行成陈旧冗余已删(删前核 (·,9) 行在位且内容与被删行逐字段一致);
; 本行集迁移 = Boss 重编号 8→9 的商店房批连带。
;
; Package B 迭代·第 6 轮·d3 改板试点(2026-09-22——用户提出并授权,破 §4.4 板面冻结的单行试点):
; (1,3) 第一关·节点3·熊地精双雄 板 12×12→10×10(min_safe_count 60→50、max_gen_attempts 24→16,
; 对齐 (1,0)/(1,1) 的 10×10 行)。依据:第 5 轮读数 d3 完成度 84% 中 83.2pp 系 R₀ 免费展开、实挖仅
; ~18 格/3.7 轮——总血 28-42 撑不起 121 格精英板;缩板后同战斗量读数 (68.6+18)/87≈100% 回带,
; 清图率升(打完近全翻开,清图尖峰 24-40 伤可兑现),轮数/承伤/胜率预计不动(难度刀≠设计意图修复)。
; 连带义务:board_calibration.csv 全量重跑 calibrate_boards(§4.4 预告)。provisional 未提交。
;
; 板尺寸策略改判批(2026-09-24——用户拍板「小怪板统一 10×10」原则,取代第 6 轮「板随战斗时长」原则):
; 第 6 轮单行缩板在 L1 内造出 10→10→12→10→12 锯齿——弱怪长战配大板、强怪速战配小板,节奏倒挂
; (用户实测定罪:第三场单只熊地精 50 血占 12×12、第四场三只强怪占 10×10)。本批 L1 小怪场统一 10×10:
; d2 12×12→10×10(min_safe_count 60→50、max_gen_attempts 24→16,对齐本关其余小怪行);
; **boss d4 维持 12×12 不动**(首次实施时误将 boss 板一并缩小,用户纠正后回滚——boss 场更大=
; 战斗逐渐变难的视觉收束,板序列 10/10/10/10/12 单调递增)。
; 战斗轮数由怪血量与玩家输出决定、与板大小无关=难度中性;完成度分母/清图率变化连带 board_calibration
; 全量重跑。L2 全 12×12 / L3 全 13×13(boss 14×14 单调收尾)本原则下无需动。provisional 未提交。
+2
View File
@@ -5,3 +5,5 @@
[resource]
script = ExtResource("1")
rows = []
; C3 GDD Core Rule 1:全局修饰结构位——MVP 空表(零行为)。首个修饰行 = 精英节点上线(C1 联动)。
+172
View File
@@ -754,4 +754,176 @@ rows = [{
"armor_class": 12
}]
; 切片调参登记 v3(2026-09-12 试玩批次 1 触发——F7 流程;C3 GDD F5 对照):
; 试玩反馈 = 基线满血全冒险成功(模拟 80%/真人 100%)——难度严重不足,主杠杆 = atk 曲线上调(承伤侧):
; 4/4/6/4/7 → 7/5/9/6/9(约 +50%);HP 结构调整(D0 24→20 缩短战斗、Boss 130→150 用户拍板可上调)。
; D0 注:20 HP 会被首轮盲挖粉尘秒杀(12+9)——回 24(4 轮战斗/承伤 42%,有过程有痛感)。
; DND 命名(用户指令):goblin 地精(单拍杂鱼)→ bugbear 熊地精(三拍伏击环——DND 原型即伏击手)→
; ogre_chief 食人魔酋长(经典低阶 Boss)。enemy_id 同步更名(内部键,无外部引用)。
; L2 锚行同步 v3 语义(bugbear 30/7)。
; 遭遇随机化批(2026-09-12 用户拍板):D0 [1,2]/D1 [2,3] hp13/D3 [2,3] hp18——数量区间骰(encounter 流,B1 掷骰);
; D2/Boss 固定(新敌种首遇教学位不加骰——C3 GDD Core Rule 8)。期望总量 ≈304(+8%),F6 带内。
;
; 护甲类型批(2026-09-12 用户拍板:攻击类型 × 护甲类型克制;2026-09-15 命名统一批——原位置键/位置名作废):
; armor_type ∈ {light, ward, heavy} = 轻甲 / 魔法护甲 / 重甲(缺省 = light 向后兼容;原 {none, a, b});
; 克制矩阵本体在 settlement.tres.armor_effectiveness。
; 映射(教学梯度:轻甲→魔法护甲→重甲):goblin=light · bugbear=ward · ogre_chief=heavy(L2 bugbear 同 ward)——候选方案,
; 数值与映射均 provisional 待用户调参。
; 敌方攻击区间批(2026-09-14 用户拍板②第二步——"上限掺运气"敌方侧:atk 上阶/下阶,中点恒等行值;
; roll 时机 = 遭遇骰同流〔encounter〕spawn 期整战持久,每拍抖动否决〔数字可读性锚〕;B2 零随机纪律保持
; ——收 override 即确定值。宽度 ±3 provisional 归 C3 测量迭代;验收 = 完美策略档 0 加成关卡完成 ≤40%。
; 护甲等级掷点批(2026-09-16 用户拍板):armor_class 字段入列(缺省 0 向后兼容)——防守方掷点判定阈值基数,
; 与 armor_type(克制属性轴)两概念严格分离、不做映射。首关六行暂定 0(正式行值归怪物/敌人系统设定批——
; 登记待办:第一关怪物 AC 相对较低,值待怪物设定投值;投值所有权归 难度曲线与Boss)。
; 敌人技能池批(2026-09-16 用户拍板——设计权威 docs/proposal-skill-pool.md v1.0):
; pattern 行为环数组 + heavy_multiplier 整体退役,改池模板 pool = [{skill_id, weight}](技能行本体在 skills.tres;
; 实例池快照与冷却状态在 单位容器 spawn)。建议池(全部 provisional,投值归 难度曲线与Boss;EV 锚 = proposal §2.5):
; 地精 普攻 9/突刺 1(名义 EV 1.05;**整数基线 EV 1.10**——atk1 突刺落地 2:〔9×1+1×2〕÷10;2026-10-05 技能池执行批 D4 整数口径重登记);
; 熊地精 普攻 6/蓄力 2/重击 2(EV 1.00 中性);食人魔酋长 普攻 6/重击 2/硬化 2(EV 1.00 中性;
; 硬化 = Boss 池独占增益技——增益 ≤1 纪律下旧蓄力拍退役不进 Boss 池)。;
; 酋长 EV 重锚(2026-10-05 技能池执行批 T5——震地怒击半血解锁入池:前半场池 6/2/2/3,
; 后半场 6/2/2/2+震地怒击 2=每拍 4.33;含闸长期速率抽样实测 1.1948,smoke EV 抽样带重锚 [1.10, 1.30];
; 卓尔遏毒/石君王岩崩同批入池——读数判读归 T7 节奏重测〔后置挂 07,跑批待用户批准〕)
; 含闸长期速率(冷却/保底)EV 锚按实施批 EV 抽样复核登记(proposal §2.5)。
; 地精 EV 重锚(2026-10-28——触发条件批孤注守势入池(w1,血量 ≤35% 情境入池):池 9/1/1;
; EV 抽样模拟器取无情境口径(trigger 行不过滤、每拍可摇)实测 0.9148,smoke EV 抽样带重锚 [0.82, 1.02];
; 旧带 [1.00, 1.20] 系触发器前唯一特殊技=突刺的池结构下登记,随池构成换代作废)。
;
; 分支节点图批(2026-09-17——L2 幽暗地域内容批,行值全部 provisional,投值归 难度曲线与Boss):
; 每战斗/Boss 节点 (2, node_depth) 精确行(跨表校验强制,违例加载致命——ConfigDB ④);锚行 (2,0) 保留。
; L2 熊地精 = 熊地精 bugbear 复用(幽暗地域部族设定——第二关三行):
; 池差异化改造 = 蓄力拍退役换突刺(复用共享技能行 lunge——共享技能表验证面),display_name 沿用
; 熊地精系译名(熊地精/熊地精猎群/熊地精重击手——行值与池与 L1 错开)。节点 5 重击手轮廓:普攻 5/突刺 2/重击 2(名义 EV 1.333;atk1 整数口径 1.333、atk3 每拍 ≈4.11——2026-10-05 整数口径重登记;权重期望
——冷却闸实际拉低,抽样复核归实施批口径)。
; 巨蜘蛛 giant_spider(新敌种——关间台阶纪律的"新敌种"半边):群行倾向(数量区间 [2,3],首遇位节点 4
; 固定 2 不加骰——新敌种首遇教学位纪律同 L1 D2);池 = 普攻 6/撕咬 2/蓄力 1(增益 ≤1 纪律——charge 复用
; empower;EV 名义 1.00——批注旧值 1.11 = **atk1 整数口径**〔6+2×2〕÷9=1.111,非混用(2026-10-05 T2 消歧登记);护甲 light(与 L2 熊地精 ward 错开克制面;L1 三甲 goblin=light/
; bugbear=ward/ogre_chief=heavy 全覆盖,蜘蛛取 light 与同关敌种错开)。
; 蛛化卓尔精灵 drider(Boss——用户 2026-09-17 拍板定名,蜘蛛主题呼应):
; 专属池 = 普攻 6/重击 2/毒爆 2(独占技 venom_burst 权重轮廓;EV ≈1.67 权重期望,冷却闸拉低后待抽样),
; armor heavy,血量 175 = r_boss 口径 provisional 锚(定位本关最大单场消耗)。
; L2 敌种首遇位绿档(节点 0 熊地精/节点 4 巨蜘蛛):任何掷骰结果稳过——完美策略档扫描验证,读数另批登记。
;
; 数值压缩批(2026-09-17 用户拍板暂定——整体绝对值轴 ÷3,四舍五入):
; 全部 12 行 hp/atk/atk_min/atk_max ÷3(24/7→8/2 · 13/5→4/2 · 40/9→13/3 · 18/6→6/2 · Boss 150/9→50/3 ·
; 30/7→10/2 · 15/5→5/2 · 14/5→5/2 · 38/8→13/3 · 12/4→4/1 · 13/5→4/2 · drider 175/8→58/3)。
; armor_type / armor_class / unit_count 区间 / 技能池权重不动(相对轴与概率轴不压缩)。
; 粒度告警登记:atk 1~3 域下掷点折扣 25% 档大量触 damage_floor=1,地板伤害相对权重上升——
; 属压缩的已知效应,难度复测(monte carlo 压缩前后对比)随批产出。行值 provisional 归 难度曲线与Boss。
;
; 护甲类型重配批(2026-09-18 用户拍板):关卡 1 全部轻甲(食人魔酋长 heavy→light、熊地精两行 ward→light);
; 关卡 2 除 Boss(蛛化卓尔精灵 heavy→ward 魔法甲)外全部轻甲(熊地精四行 ward→light,巨蜘蛛既有 light 不动)。
; hero 侧两轴(armor_type/attack_type)同批入列(hero.tres 批注),敌方技能攻击类型轴仍未开(全部 normal 档)。
;
; 甲效矩阵加法核换装批(2026-09-18 用户拍板——settlement.tres armor_effectiveness 量纲 percent→整数点数,
; 三档 克制 +1 / 中性 0 / 被克 −1,五档百分比词表随批退役)。
;
; 新效应词汇批(2026-09-19 用户拍板——设计权威 docs/proposal-status-vocabulary.md v1.0):卓尔池
; 6/2/2 → 6/2/2/2(+蛛网束缚 web_snare 2——妨害技,对主角施 off_guard;每池妨害 ≤1 纪律入跨表校验)。
; 主分量权重期望 1.67 → 1.25(零伤害拍占 2/12),加毒爆必中附加分量(max(1,floor(atk×0.75)),atk 区间
; 2–4 → 1–3 点)后净期望待抽样复核归 难度曲线与Boss;实装面 = 仅卓尔,其余敌种不动。
; 现行读数效果:L1/L2 小怪全 light → 穿刺类(开格充能/穿刺弹)被克 −1(穿刺弹 2→1、充能 3 点→2)、普通/魔法中性;
; L2 仅 Boss 战非中性(魔法甲)——基础攻击与穿刺弹克制 +1、魔法矢被克 −1(原威力 + delta 自行核算后落笔)。
; 原重配批注「魔法矢克 Boss ×150、穿刺弹被克 ×50」与当批矩阵正反互倒(系笔误),随本批订正为上行读数。
;
; 第三关内容批(2026-09-20):新敌种 duergar 灰矮人(单体重甲中坚——关间台阶 ≈L2 单体 ×1.5,落 [1.3,1.6] 域)
; 与 hook_horror 钩爪恐魔(群行捕食者,复用 bite 共享技能行——lunge 已有 L2 熊地精复用先例);两敌种首遇位
; (节点 0 / 节点 1)固定数量不加骰——新敌种首遇教学位纪律同 L1 D2 / L2 节点 4;克制面重轻错开
; (重甲灰矮人 = 重甲首次登台,轻甲钩爪恐魔保穿刺/普通分量有用武之地),Boss duergar_king 灰矮人石君王
; 重甲收束「轻甲→魔法甲→重甲」教学梯度;Boss 血量 75 = Σ普通战生命期望 91 × r_boss≈0.82
; (provisional 锚,域 [0.5,1.1]);Boss 专属池独占技 earth_pulse(第二妨害词汇 sapped 首发);
; armor_class 恒 0(正式投值仍归「敌方护甲等级正式行值」在案条目全表同批)。行值全 provisional
; 归 难度曲线与Boss。
;
; 商店房批连带(2026-09-21——level.tres 商店房批 Boss 重编号 8→9):新增 (2,9)/(3,9) 精确行
; (跨表校验强制——ConfigDB ④ level_node_dangling),行值照抄原 Boss (L,8) 行(drider / duergar_king);
; 商店房 (L,8) 不开战斗、无行集。行值 provisional 归 难度曲线与Boss。
; 陈旧行清理(GP+商店房实施批收尾 2026-09-21):并行表代理曾把 Boss 行照抄到 (2,8)/(3,8)——节点 8 现为
; 商店房、无战斗行需求,原 (2,8)/(3,8) 行成陈旧冗余已删(删前核 (·,9) 行在位且内容与被删行逐字段一致);
; 本行集迁移 = Boss 重编号 8→9 的商店房批连带。
;
; Package B 数值优化批·首版(2026-09-22——qa-data/实现计划书_PackageB.md §4.1,worktree
; adventure-mc-playtest,provisional 未提交):B1 敌人 HP 阶梯整体重锚(完成度主旋钮——零加成基线
; naive 完成度普遍过低,见 qa-data/分析报告_零加成全流程.md)。只改 hp 字段;atk/atk_min/atk_max/
; 池/armor_type/armor_class/unit_count 全部不动(atk 系 §6 承伤迭代旋钮,改时须三值同步保中点恒等)。
; 改动清单:L1 d2 熊地精 13→50 · d3 双雄 6→20 · d4 酋长 50→72(d0/d1 弱档不动);
; L2 d0 10→45 · d1 5→18 · d4 巨蜘蛛 5→20 · d5 13→68 · d6 巢群 4→18 · d7 巢群 4→18 · d9 卓尔 58→85;
; L3 d0 灰矮人 15→50 · d1 钩爪 5→25 · d4 钩爪 5→20 · d5 16→76 · d6 巢群 6→20 · d7 小队 8→20 ·
; d9 石君王 75→105。以 MC 复测读数为准(runbook 计划书 §5;迭代记录 qa-data/iteration_log.md)。
;
; Package B 迭代·第 3 轮(2026-09-22——计划书 §6.2 承伤带守卫,用户拍板):8 行 atk-3 精英/boss
; 三值同步 3(2/4)→2(1/3)。第 2 轮 max_hp/heal 组合拳后单场承伤% 仍 49-62%(战斗变长吃掉血池收益,
; heal 加强主导经济修复)——§6.2「AP 已到顶 → 长战斗档 atk −1」条件成立。行清单:L1 d2 熊地精 /
; d4 酋长 · L2 d5 重击手 / d9 卓尔 · L3 d0 灰矮人 / d5 重装手 / d7 小队 / d9 石君王。
; atk-1/2 行(弱怪/群怪/L1 d3 双雄)不动。预期单场承伤 ~35%(20% 带在 Package B 框架内结构性
; 不可达,带位全达标归 Package A)。provisional 未提交。
;
; Package B 迭代·第 4 轮(2026-09-22——用户拍板 A):L1 d3 熊地精双雄 hp 20→16/单位
; (总量 [32,48])。第 3 轮后唯一未回调的 L1 高压行——双单位每轮双判定,单场承伤 51%、
; 胜率 70%,拖住 L1 通过率(40.7% vs 靶 70-78%)。其余行不动。provisional 未提交。
;
; Package B 迭代·第 5 轮(2026-09-22——用户拍板「继续」,修理刀三处,胜率带优先、完成度让路):
; ① 第一关·节点3·熊地精双雄 hp 16→14/单位(冲 ≥90 胜率靶;该行胜率/完成度两靶互斥已登记);
; ② 第二关·节点9·蛛化卓尔精灵 85→80(L2 boss 胜率 59% 回 60-75 带);
; ③ 第三关·节点9·灰矮人石君王 105→92(L3 boss 胜率 38% 向 50-70 带靠;该行完成度靶未设带,让路合法)。
; 否决项登记:食人魔酋长 +10% 方案经测算否决——boss 完成度 >130 需 HP +~50-75%(98→104 买不回靶),
; 会把刚入带的 66% 胜率打回带外,纯亏。provisional 未提交。
;
; 数值设计批·关卡成长×永久成长对齿(2026-09-22——设计权威 qa-data/数值设计_关卡成长×永久成长_v1.md,
; 用户三拍板 1A/2A/3A,第 7 轮):第二/三关阶段拔高 14 行(L1 一行不动)。血轴=每关上一档;
; 伤害轴=atk 2→3 三值同步 3(2/4)【L2 d5 重击手/d9 卓尔;L3 d0 灰矮人/d1 钩爪/d4 钩爪/d5 重装手/
; d6 巢群/d7 小队/d9 石君王】。清单:L2 d0 45→50 · d1 18→22 · d4 20→24 · d5 68→88+atk3 · d6 18→22 ·
; d7 18→22 · d9 80→112+atk3;L3 d0 50→62+atk3 · d1 25→30+atk3 · d4 20→26+atk3 · d5 76→98+atk3 ·
; d6 20→26+atk3 · d7 20→26+atk3 · d9 92→140+atk3。
; 目标对齿(熟练玩家):S0 零成长 L2 达 boss ~20%/通 ~0%、L3 ~0;S1(≈5 次 L1 关卡完成锻造后,hero 快照
; 攻4/血26/甲11)L2 达 ~70%/通 ~50%;S2(攻6/血32/甲12)L3 通 ~55%。验证 = hero.tres 阶段快照 MC
; (设计文档 §6,快照后恢复基线)。验证出带微调旋钮序:L2 d1/d6/d7 血 22→20 → d4 24→22 → d9 112→108。
; provisional 未提交。
;
; 实体名修正批(2026-09-24——用户裁决,DND 阶梯对齐):(1,3) 熊地精双雄 → 大地精
; (enemy_id bugbear→hobgoblin,仅本行;L2 bugbear 三行熊地精系不动)。依据:①DND 阶梯
; 地精(goblin)→大地精(hobgoblin)→熊地精(bugbear) 与实测每只血量 4-8→14→50 严格同构——
; 单只熊地精 50 血在前、三只 14 血在后,同族每只血量倒挂的观感由阶名归位化解;
; ②「双雄」名硬编码数量、数量却是 [2,3] 变量骰——摇出 3 只即成「三个双雄」自相矛盾
; (用户截图实证),集体名(猎群/巢群/小队/大地精)为正解。hp/atk/池/数量区间零改动。
; M-3 迭代 5 判读锁值批(2026-09-28):(2,9) 卓尔 hp 130→100(杠杆扫描 C3 组合——Boss 杠杆对普通档 +4pp;
; r_boss 锚漂移加重 100/389≈0.26 低于域 [0.5,1.1] 下限,收锚裁决挂迭代 5 出口人闸;读数见
; design/qa/m3-iter5-lever-scan-2026-09-28.md)。
; M-3 迭代 5 T4 AC 投值批·终版 Boss-only(2026-09-28:v1 硬梯度普通 L2 14.3% 越带/v2 软梯度 15.7% 仍越带——杂鱼税对普通画像〔普通分量为主力输出〕系统性超压;终版=杂鱼全 0〔带 0~5 下缘,掷点戏剧性集中 Boss 战〕+Boss 台阶 8/9/12 严格递增;三版演化链读数见 design/qa/m3-iter5-t4-ac-2026-09-28.md,随出口人闸追认)。
; M-3 迭代 5 返工批·U2 裁 v1 硬梯度重投(2026-09-29 用户推翻 Boss-only:重击手 8/重装手 9〔逐行手设值,非精英编码位——解读 A 追认,精英 P2 承载〕+Boss 台阶 8/10/12;杂鱼行按 T4 报告 §一 软梯度恢复〔v1 中间态未入 git,v1↔v2 唯一差异=重击手/重装手,代拟面记台账 247〕;卓尔 hp 100→130 随 C3 回退复原;组合读数 C1+v1 无先测,全量确认归返工批——裁断全录 design/qa/m3-iter5-u2-gate-2026-09-29.md)。
;
; 数值修复批·调参二(2026-10-01 新尺 MC 驱动):L1 系八行 atk 2→1(行 15/35/54/77/99/121/144/166;
; 行 234 巨蜘蛛巢群主体=L2 域维持)——新尺读数:普通档 v3.4 死因=L1 四连战无治疗夹缝(雷伤 6/8/8
; + 杂兵垫刀双压,L1 条件关卡完成率 1-2%,0/100 出第一关);完美档战役 50%(L1 93%)。刀位语义=
; 「危险来自雷,不来自杂兵」:杂兵垫刀减半,雷直伤 6/8/8 维持痛感;L2/L3(atk 3 系)本刀不动。
; 全旧带读数随新尺作废重测归本批。
; 调参二补充:上述八行 atk 区间 1-3→0-2(中点恒等期望当量锚不变式——atk=1 需区间中点同步 1;0=掷点空刀,保随机手感)。
;
; 混编遭遇首批投放批(2026-10-07 迭代 18 卡⑤——需求卡片 v1.2 裁点全裁 P1-P4 甲;机制前置=敌人表行集多行批
; 已提交 9cc4b8b):首个混编遭遇行落表 = (2,5) 双行行集〔R6 行序契约:同坐标两行文件内相邻、
; 行序=声明序=生成序——resolver 返回序/生成序/断言面全依赖文件行序〕:
; 行 1 = 既有 熊地精重击手 (2,5,bugbear)(行值零变更);
; 行 2 = 新增 (2,5,giant_spider) 巨蜘蛛巢群——行值整行复制 (2,6) 巢群行(P4 甲零数值新增:unit_count 2/
; unit_count_max 3/hp 26/atk 1/atk [1,2]/池 普攻6·撕咬2·蓄力1/light/armor_class 2),
; 行序=重击手在前(默认目标=前排坦克 ac 8,蜘蛛后排输出——强弱搭配形态)。
; 设计意图(P1 甲单点试水):「巨蜘蛛+熊地精」同场混编——生产内容实打卡①「每行一骰数量骰」交付面
; (重击手定值不骰、蜘蛛掷 [2,3],同场两种数量语义并存);静态最坏骰和 = 1+3 = 4 ≤ ENEMY_ROWSET_INSTANCE_MAX
; (spawn 期守卫内)。
; 读数预期:(2,5) 场敌人 3-4 只(3=重击手 1+蜘蛛 2,4=蜘蛛掷 3);L2 难度带位移读数随 Alpha 收官 M4 数值批
; 统一执行(07 在册义务——MC 取证跑批届时另报批,本批零跑)。禁区排查:巨蜘蛛首遇位 (2,4)「固定 2 不加骰」
; 零触碰、Boss d9 零触碰、跨关混编禁令过(两敌种首遇关均 ≤L2)、既有 19 行现值零变更。
; 敌人表内容修批 N1(2026-10-13 用户令「按推荐方式」,迭代 24 卡①):(1,2) 熊地精降档 hp 50>>22、armor_class 3>>2——
; 2026-09-24 阶名化解方案((1,3) 改名大地精以阶名归位化解同族血量倒挂观感)实机验证未达预期,按体验反馈重裁:
; 第一关总量曲线 12/10/50/35/72 的 5 倍墙消除(22 后曲线 12/10/22/35/72 相邻比最大 2.2);敌种 bugbear/池/数量/atk 区间零改动。
; 曲线标定其余行归 M4 数值批。
; N3 敌方攻击类型轴开列(2026-10-13 迭代 24 卡①,承接锻造工坊实装批迁移面⑥):20 行全填 normal 挂敌种行——
; 不做差异化(pierce/magic 属新设计另立项)。全局平移效应=主角穿重甲受伤 −1 / 魔法护甲 +1 / 轻甲 0,
; 锻造甲路线首次具备战斗意义;克制矩阵数值零触碰(settlement.tres armor_effectiveness 不改)。
;
; 行键 = (level_index, row_kind, depth_band, enemy_id);row_kind ∈ {battle, boss}——battle=战斗节点配池,boss=终点行集;
; depth_band=节点深度所在的带键,请求落带取首个 ≥ 深度的键(偏难一侧);越顶带由 resolver clamp、跨表校验判为调参事故。
; hobgoblin 行为缺口行:无立绘、不在敌种表——留任在役,补齐三件套(立绘+语义模板+敌种表行)归敌种内容批。
+11
View File
@@ -4,6 +4,17 @@
[resource]
script = ExtResource("1")
; 迭代 20 专长实装批 T3——专长重设计 27+2 件换代(奇物.md 基础件表 27 件+迁入登记 2 件=29 行;
; 件数口径=卡文 §10.4 推荐案:29 行=基础 27+迁入 2,V2/V3 断言按落表实数)。旧 27 件随本批整体
; 退役(素材库表二);订阅行 on/when/do 词表=效果引擎封闭集;rarity 四级直映射令牌档;cap=已拿
; 上限(案②解耦——拿了才计刷出不计);数值全 provisional 归调参批;desc 禁「雷/旗」字面
; (契约 6 命名纪律:旗〔旧称〕=封印、危险格=陷阱/巢穴风味层)。dispatch 预评估口径注记:「每第 N 次/积
; 满触发」系 when 于命中前读计数器现值——行 when 按 N-1 落值(双管镐 mod_eq ref 1/地质学家 eq 3/
; 跳格 eq 2/封印匠 mod_eq ref 2/保险丝 eq 1——effect_words_t1_test mod_eq 断言钉住该口径)。
; 迭代 31 卡② 凭证件裁削批 T5——完美保险自资源类迁入专长表(第 30 行):rarity rare/cap 省略
; (承 twin_pick/seal_burst 惯例)/domain=battle 显式写出(现役 29 行全为 adventure 或不写,本行
; 系战斗域首例——豁免计数每战清零)。限次落法=单订阅行:when counter(insurance_used) lt 1 承载
; 「本场首次」,do 自带 counter_id 记账由授予段消费点落账(dispatch 不代执行计数器)。
rows = [
{
"feat_id": "twin_pick",
+11
View File
@@ -85,3 +85,14 @@ routes = [{
"prereq_route": "light",
"unlock_price": 200
}]
; 锻造工坊实装批 T1(2026-10-12——迭代 23;设计权威 design/gdd/systems/跨局循环/锻造工坊.md v0.6,
; 需求卡片=锻造工坊实装批(迭代 23,卡片已按「吸收即死」退役,git 历史可考)T1 锚表):
; 六路线 provisional 投值——cap 5/每级增量统一 +1(v1.2 用户裁:provisional 线性起步,4a 前缓后陡为
; 终值形状方向归 M4)/甲型基础 AC 10-12-9(现役结构值 settlement.tres 矩阵同行)/基础价 20/公比 150%
; (历史考古参数 meta.tres:82-84 退役批注)/各级价格 20/30/45/67/101/一次性解锁价 200(中段三级 213 九折)。
; 初始持有=长剑+轻甲(语义继承自已退役属性锻造行——迭代 21 T5 行族删除后的新建行族,非改造)。
; 并联双通道(4b-1 裁):长枪/法杖←长剑练满、重甲/魔法护甲←轻甲练满,或一次性解锁价直购,互不影响。
; 默认两轴(契约 2 所有权移交):hero.tres 静态表两轴随本批删除,默认值归本表常驻持有——normal/light
; = 裸体态类型(Q1:未解锁/未锻造=0 加值)。全部数值 provisional 终值归 M4 数值批。
; 表运行期只读(铁律):永久强化只写存档 forge_routes 域,本表零写面。
+28
View File
@@ -8,3 +8,31 @@ max_hp = 26
atk = 2
armor_class = 10
display_name = "探险者"
; 〔2026-10-12 迭代 23 锻造工坊实装批 T2——两根类型轴删除(契约 2 所有权移交):armor_type/
; attack_type 两字段随本批从静态表删除,默认值归锻造工坊配置常驻持有(forge.tres
; default_attack_type=normal/default_armor_type=light),选中态写存档域 forge_routes、冒险开始
; 经参数面注入;单位快照读取面改读注入值(缺省回退锻造配置默认值——行为连续)。原 2026-09-18
; 营地扩展前置批「两根可配置轴」登记随字段删除退役,历史记载归 git 考古。〕
; 数值压缩批(2026-09-17 用户拍板暂定——整体绝对值轴 ÷3):
; max_hp 50→17(16.67 四舍五入)、atk 6→2。armor_class 10 不动(掷点阈值轴,相对量纲不压缩——
; 用户同日裁决:本体自带 AC 不算减伤统计)。恢复奖励削弱随批在 reward.tres(概率 1/4 + 量再减半)。
; 全部行值 provisional 归 难度曲线与Boss;压缩前基线读数(N=30 normal):基线档通关率 3%。
; 护甲等级掷点批(2026-09-16 用户拍板):armor_class = 10(暂定基准,归 难度曲线与Boss;
; EV 参考数按判定式复算 = 期望减免 21.25%);ac_up 增益 +1 AC/层(×2 层 = AC+2)在其上加算。
;
; 〔营地扩展前置批(2026-09-18 用户指令)两根可配置轴 armor_type/attack_type 已于 2026-10-12
; 迭代 23 锻造工坊实装批 T2 删除——所有权移交锻造工坊配置(见顶部注记);甲型基础 AC 随甲路线
; 行承载(轻 10/重 12/魔法护甲 9),本表 armor_class=10 保留为甲路线缺失时的兜底基准。〕
;
; Package B 迭代·第 2 轮(2026-09-22——计划书 §6.2,用户拍板一B):max_hp 17→20。第 1 轮读数
; 触发 §6.2(L1 精英承伤 43-55% vs 靶 ≤20%、L1 净消耗 17.7/17=104% 破产、normal L1 通过率
; 8.3% vs 靶 70-78%)的生存侧修复。单变量归因原则:同轮第二变量(heal_minor 加强)在 reward.tres。
; 血线 17/27/37→20/30/40(关间大奖励 +10 不变)。provisional 未提交。
; 数值修复批(2026-10-01——模拟档位重构后新尺首调):max_hp 20→26(调参二再 +2:普通档 L1 7% 差 2-4 血量级,+8% 池把 b3/b4 压线死改写险胜;完美档 62% 上界余量健康)。依据=新尺 MC 读数:普通档 v3.4
; (完美+失误注入,踩雷 ~2.5/战)L1 四连战无治疗夹缝全灭(L1 条件通关 2%,0/100 出第一关);
; 完美档战役 36-41%(L2 53% 弱环)。+20% 血池抬夹缝生存;配套直伤雷当量同步上调(reward.tres
; 4/5/5→6/8/8,雷痛回归用户口径)双向对冲。全旧带读数随新尺作废重测归本批。
+4
View File
@@ -10,3 +10,7 @@ rows = [
{"level_index": 2, "display_name": "第二层 · 幽暗地域", "rest_heal_pct": 30},
{"level_index": 3, "display_name": "第三层 · 灰矮人矿城", "rest_heal_pct": 30}
]
; 节点图源已换代为参数化生成器(关卡节点图生成 v1.1)——本表逐关行只承载关卡序号/显示名/恢复比例,
; 不再携带节点数据;图 = f(参数档, 种子),参数档见 level_gen_params.tres 三行(消费侧按 level_index 解析后交 generate)。
; 旧 15 张模板池(3 关 × 5)已清出,历史查 git 提交史与 tools/t5_build_templates.py、t17_fanout2_rebuild.py 留档。
+3
View File
@@ -44,3 +44,6 @@ rows = [{
"fork_ways_min": 2,
"fork_ways_max": 3
}]
; 节点图生成器核心批 卡① §8.1 参数档 provisional 取值表逐行填列(定值批落终值,数值全 provisional)。
; 层深/出口/岔口去路数为已锁域;商店实数由摆放约束钉死=出口数(shop_ratio 为名义值,配比填余次序见卡① §8.1 注)。
+40
View File
@@ -36,3 +36,43 @@ attune_refresh_upgrade = [{
"refresh_charges": 2,
"keystone_cost": 60
}]
; 元进度实现批(2026-09-21,设计权威 design/gdd/systems/冒险循环/元进度.md 定稿 v1.2):
; 数值全 provisional 归元进度设计批配读数(骨架先行——元进度实现批 2026-09-21,先例 = GP+商店房批)。
; 〔forge_products 属性锻造行族已退役——迭代 21 T5 攻防所有权切分:生命唯一入口=树脊柱淬炼、
; 攻/AC 唯一入口=锻造工坊路线(契约 9 红线),meta_forge_row 访问器与 buy_forge 购买面随批删除;
; 历史投值记载(2026-09-22 对齿批 base 20/ratio 150、2026-09-23 标定批 6/9/1)系 conversion 行
; 与 ForgeGDD 考古用,行族本体不再在表。〕
; 〔workshop_items 道具工坊行族已退役——迭代 22 T2 秘宝实装批:解锁换代混合制(钥石购买价
; unlock_keystone_cost + 条件谓词 unlock_requires 全挂 treasure_items.tres 行内单一事实源),
; 旧「总通关次数达阈值」六行(阈值 1/1/2/2/3/3)与渠道面随批删除;历史记载归 git 考古。〕
; boss 两档 L1 5/1 · L2 8/2 · L3 12/3
; (首杀全量、重复杀固定小额恒定不递减);conversion 全 0 = 未标定占位(标定归设计批,护甲行强条目:验收读数必须按
; 解锁后参数重测)。
;
; 数值设计批·关卡成长×永久成长对齿(2026-09-22——设计权威 qa-data/数值设计_关卡成长×永久成长_v1.md,
; game-balancer 工作流,用户三拍板 1A/2A/3A):forge base_price 10→20(三行同,ratio 150% 不变,
; 效果档 血+3/攻+1/甲+1 不变)——S1 一档(攻+2/血+6/甲+1 ≈ 120 GP)对齐「≈5 次 L1 关卡完成开门」节奏
; (实测 L1 通关局收入 ≈29-35 GP)。换算率表维持全 0(墙/钥匙闭环不依赖该轴,留扩展)。
; 配套怪表改动见 enemy.tres 同日批注。provisional 未提交。
;
; 换算率标定批(2026-09-23——用户指令「现在标定」;读数报告 production/qa/conversion-calibration/
; calibration.raw.md,判定端 tools/balance_verifier.py ④ 段可复判):conversion 三行全 0 → 6/9/1 投值。
; 方法 = OFAT 冒险注入档(每属性 +1/+2 级 × 双画像 × na=100,与白板同种子流配对)逐关条件
; 通关率差实测每级带平移 生命 +6.0±0.7 / 攻击 +8.8±0.8 / 护甲 +1.2±0.4 点(配对 bootstrap SE,
; 逆方差加权合并)→ 取整投 6/9/1。测量面 = 冒险条件口径(同日单关直入口口径退役后重测——
; 首轮直入口面读数作废)+ 当日 L2 收紧/关间大奖励 10→5 后的现行数值包。
; 护甲行强条目重测义务随批履行:重测暴露并修复护甲断链(begin_battle hero_armor_class 参数此前
; 零消费——_defender_ac 主角分支本次接线,缺参/-1 = 表值兜底);修复后甲轴读数 +1.2±0.4 为
; 解锁后参数实测,非基线外推。战役轨迹三花费序(生命/攻击/护甲优先)随批采集验证。
;
; 迭代 10 奖励重构批(2026-10-01——boss_keystone 重锚,P-B 乙拍板):首杀 3 三关统一;
; 复杀按关 2/2/3 递进(**用户 2026-10-01 裁「a 用备选」**——原代拍板「复杀统一 2」被推翻;
; L3 首杀=复杀=3 系 first_kill ≥ repeat_kill 结构约束下的合法端点)。
; 钥石渠道自本批起 =
; Boss/精英击杀逐杀掉落(大奖励 keystone_per_level 渠道退役;精英掉 1 预留行随怪物批实装落)。
; 产出结构变化 → 元进度标定义务重开(06-待办清单 2026-10-01 登记条)。provisional 归曲线调参批。
;
; 迭代 11 第①批 同调实施批 T4(2026-10-03):attune_refresh_upgrade 行族 = Y 刷新升级行(需求卡片 P1 甲——
; 每冒险开局给 Y 次、冒险周期池、用完即无;等级 L → Y=L 次刷新,钥石直购)。数值全 provisional 归
; 难度曲线与Boss(需求卡片 §三 7)。
+13
View File
@@ -155,3 +155,16 @@ rows = [{
"economy_spend": 1
}
}]
; 迭代 21 天赋树实装批 T1 换代(2026-10-12,设计权威 design/gdd/systems/跨局循环/天赋树.md v0.8):
; 12 节点 = 脊柱 2(生命淬炼/命中淬炼——一线一节点 cap4,2026-10-11 用户裁,原 4 层×4 线 16 行收编;
; 攻/护淬炼线随攻防所有权切分砍除——攻唯一入口=锻造工坊武器路线、AC 唯一入口=甲路线〔契约 9 红线〕)
; + 锻造脉 2(forge_workshop 钥匙 free 无前置 + easter_ley 彩蛋——effects 只持生命/命中两键,
; :402/:405 旧攻/护分量已摘除)+ 钥石脉 2(秘宝匣 ks_workshop〔display 旧名「道具工坊」退役〕/
; 刷新升级 ks_refresh)+ 同调脉 6(同调位 1/2/3——socket1 改根节点无前置 + Fork 3 单行双态节点,
; 原 8 行 A/B 双行结构与 fg_mastery 克制专精组退役)。
; 行门槛=一线一节点主语:脊柱节点第 N 级需全树总等级 ≥4×(N−1)(SPINE_ROW_GATE=4 公式平移,
; row 字段退役);requires=点亮前置(R1 裁撤案执行,schema 无等级阈值形态)。
; 🔴 层级纪律:局外树只放全局规则件——零 archetype 键(schema 校验强制);规则改写型特性只走局内随机渠道。
; 数值全 provisional 归 M4 数值批(契约 7——价格沿旧量纲锚:脊柱 10=旧 r1 价、socket 20/40/60、
; Fork 25、刷新 30 沿旧;生命 +5/级、命中 +1/级沿旧量纲);A/B 两侧差 <~3pp 验收=V19 MC。
+59
View File
@@ -201,3 +201,62 @@ rows = [{
"pool_tag": "cell",
"tier": 1
}]
; 格面资源批(2026-09-15 用户拍板——registry reward_table 条目为现行 schema 事实源):
; 十行格面池(五型 × 正负各一行)+ 清图槽一行。安全格与危险格同池同分布(雷安同池),
; 装板期一次摇定;摇号只消费正向行权重(类型频次 = attack 20 / defense 16 / blast 16 / heal 3 / weaken 12,合计 67;
; 头段"heal 15 / weaken 12,合计 79"为历史注记——数值压缩批后 heal 3、合计 67,见本文件尾部 2026-09-17 批注);
; 负向行 weight=0 不参与摇号,纯(类型, 极性)兑付字典——heal 负向 = 主角直伤 4(不经增益状态),
; blast 负向 = 警觉(敌方 AC +1,2026-09-20 伏击退役换装)。
; 可选类三行(knife_t1/knife_adv/heal_pack)与注入池 active_inject 随可选类道具整体删除(供给控制器/保底/窗口同步下线)。
; 格面资源八型批(2026-09-20 用户拍板):① blast 负向 ambush_double 退役 → enemy_alert(警觉,effect_id=alert
; 敌方 AC +1 percent 行);② 新增第 8 型 action 两行——ap_up(正向,下轮行动点 +1)/ ap_drain(负向,下轮
; 行动点 −1),排队兑现于下一轮开始(action_economy.queue_ap_delta);③ off_guard 数值 −2→−1 归 status_effects.tres。
; 区间行(伤害量值区间批 2026-09-14):heal_minor [2,6] · clear_blast [25,55]——中点锚 power 恒等期望当量,
; roll 时机 = 身份预分配批内追加取号(既有取号序零扰动);spark_aoe 定值行无区间字段。
; 减伤墙调参批(2026-09-13):defense_up 权重 24→16——攻击成为池内最高行(历史注记)。
; 护甲等级掷点批(2026-09-16 用户拍板):defense 型正向行换装——reward_id/effect_id defense_up → ac_up
; (显示名"盾牌加护"——2026-10-12 由"护甲强化"改名;AC +1/层 ×2 层);cell_type defense / 权重 16 / tier 2 零改动(类型频次合计 79 不变——历史注记,数值压缩批后现合计 67);
; 百分比减伤行无双轨退役——status_effects.tres defense_up 行同批删除。
;
; 数值压缩批(2026-09-17 用户拍板暂定):
; ① 整体绝对值轴 ÷3:spark_aoe 4→1 · heal_backlash 4→1 · clear_blast [25,55]→[8,18](中点 power 40→13,
; 区间中点恒等期望当量的锚口径不漂移)。
; ② 恢复奖励削弱(用户拍板两条):出现概率下调到当前的 1/4——权重 15→3(当前频率 15/79≈19.0%,目标
; 4.75%,整数权重最接近 = 3/67≈4.5%);恢复量在 ÷3 后再 ÷2(现值 ×1/6)——[2,6]→定值 1
; (0.33~1 取整,区间字段保留 min=max=1 占位,量级再调时恢复区间结构)。
; ③ 雷安同池连带(结构冻结,自动同侧):heal 权重下调同比例降低踩中 heal 型雷(反噬)的频率——
; 负向侧反噬量同步 ÷3(4→1)。
; 类型频次合计 79→67(attack 20 / defense 16 / blast 16 / heal 3 / weaken 12)。行值 provisional 归 难度曲线与Boss。
;
; 伤害道具批(2026-09-18 用户指令):① 七型字典——五型增补 pierce(穿刺)/ magic(魔法)两型,各正负一行:
; 正向 = 单目标克制直伤道具(穿刺弹/魔法矢 power 2,attack_type 字段载攻击类型轴,走克制矩阵、
; 必中全额不掷点——棋盘来源伤害既有口径);负向 = 主角直伤(穿刺陷阱/魔法反噬 power 2,复用反噬通道不经增益状态)。
; ② 权重再平衡(保 spark_aoe 16 不动、总 67 不变):attack_up 20→14 · ac_up 16→11 · heal_minor 3→2 · weaken 12→8;
; 新行各 8。等比基准 = 其余四行 51→35(×0.686),整取后 14/11/2/8,微差登记已知偏差。
; 类型频次合计仍 67:attack 14 / defense 11 / blast 16 / heal 2 / weaken 8 / pierce 8 / magic 8。
;
; 九型批(2026-09-20 用户拍板——GP 进第九型,获取来源=战斗结束掉落+雷图低概率惊喜获取〔量与战斗掉落相当〕;
; GP 袋=挖开安全格入战斗内缓冲、战斗完成统一入账;破财=危险格摇到 gp 面的字典负向行〔weight 0 不入池,
; 挖危险格兑付=缓冲 -2 钱包侧 clamp ≥0〕;正向权重合计 74→76);行值 provisional 归 难度曲线与Boss。
; gp 两行 tier=1(provisional 占位);effect_id gp_gain/gp_loss = 战斗内缓冲(escrow)通道路由键
;(战斗结算 _apply_percent_row 分流,不入增益容器——ConfigDB ① status_effects 悬空豁免归 core 面)。
;
; Package B 数值优化批·首版(2026-09-22——qa-data/实现计划书_PackageB.md §4.3):clear_blast
; 区间 [8,18]→[18,35](中点 power 13→26)——清第一图回归真正伤害尖峰,撑起 boss"必清图才打得动"
; 节奏(L1 boss 清图≥1 靶 ≥80%);其余行全部不动。provisional,以 MC 复测读数为准
;(runbook 计划书 §5;迭代记录 qa-data/iteration_log.md)。
; ⚠️ 计划书笔误代拍板:原文"power 25"违反 schema 中点锚硬校验(config_fatal)——power ≡ floor((min+max)/2),
; (18+35)/2=26 故落 26(期望当量 +1 vs 计划书 25,掷点区间 18–35 与计划一致,玩法值零偏离)。
;
; Package B 迭代·第 2 轮(2026-09-22——计划书 §6.2,用户拍板一B):heal_minor 恢复量 1→2
;(区间三值同步 power/min/max = 2/2/2 过中点锚校验)+ 出现权重 2→4(正向池合计 76→78)。
; 与 hero.tres max_hp 17→20 同轮双变量(用户拍板组合拳,归因混在一起由下轮分摊)。provisional 未提交。
;
; Package B 迭代·第 4 轮(2026-09-22——计划书 §6.4,用户拍板 A):clear_blast 26→32
;(区间 [18,35]→[24,40],(24+40)/2=32 恰为整中点锚)。boss 面三缺同解(normal 胜率 62% 贴下沿 /
; 清图率 49% vs ≥80 / 完成度 99 vs >130)——清图尖峰加大让"先清一图"成为 boss 战最优路径。
; 副作用已知:perfect L1 boss 胜率 97% 越 75% 上界加剧。provisional 未提交。
; 数值修复批(2026-10-01):直伤雷三行 4/5/5→6/8/8(迭代 8 雷当量 provisional 的再抬档)——用户口径
; 「踩雷必须痛」;配套 hero max_hp 20→24 双向对冲(见 hero.tres 批注)。新尺 MC 复测归本批。
+54
View File
@@ -63,3 +63,57 @@ script = ExtResource("1")
segment_order = PackedStringArray("grant", "buff_debuff", "combat", "decay", "verdict")
core = SubResource("SettlementCoreTable_core")
damage_roll = SubResource("DamageRollTable_roll")
; 攻击类型 × 护甲克制批(2026-09-12 用户拍板结构;2026-09-15 命名统一批 + 抽象分离批,数值 provisional 待用户/C3 调参):
; 主角攻击 = 单一基础分量(2026-09-19 充能退役批·用户拍板——原三分量模型退役,克制策略归冒险前配置:
; 类型 = hero 表 attack_type,营地换型 = 改字段;局内无挖掘攒弹药的第二供给)。
; 【抽象分离纪律保留】攻击类型 {normal, pierce, magic} = 普通 / 穿刺 / 魔法 = 伤害的属性轴,
; 只决定查矩阵哪一行,定义里不含任何棋盘来源;护甲类型 {light, ward, heavy} = 轻甲 / 魔法护甲 / 重甲是敌单位属性。
; 格面资源批(2026-09-15 用户拍板):段序七段 → 五段(item_window/item 两段随可选类道具删除下线);
; source_label_map 删 item 键;effect_pool_map 增 sapped→hero_offense(weaken 型负向——乏力)。
; enrage(敌方暴走 +25%,enemy_output 池)/ off_guard(我方失衡 +25%,hero_defense 池)/
; sapped(我方乏力 -25%,hero_offense 池)= attack/defense/weaken 三型负向字典行
; (极性路由兑付:挖危险格 / 标错安全格按该格 cell_type 取负向行;heal 负向 = 主角直伤不经状态、blast 负向 = 警觉(敌方 AC +1,2026-09-20 八型批换装))。
; 减伤墙调参批(2026-09-13):pool_clamp 域 [-100,+100] 结构冻结不动;减伤杠杆走 status_effects.tres(批注在该表)。
; 护甲等级掷点批(2026-09-16 用户拍板,数字即规范——战斗结算 GDD 护甲等级掷点节定稿同批):
; roll_faces=20 / roll_tier_bounds=[3,7] / roll_tier_discounts=[75,50,25] / crit_roll=20 / crit_multiplier=200 /
; damage_floor=1 / armor_roll_stream=armor_roll;attack_bonus=0 结构位(元进度/武器附魔未来投值)。
; 判定式:掷点 ≥ 防守方 AC + attack_bonus → 全额;缺口 1-3 → ×0.75、4-7 → ×0.5、8+ → ×0.25;无 miss 无零收益档;
; nat20 = 暴击 ×2 恒全额(双方同规);任何攻击落地伤害 ≥ damage_floor(全局 max(1,·))。
; 掷点只吃基础攻击分量(主角普通分量 / 敌方攻击拍与重击拍基线);穿刺/魔法充能与棋盘来源伤害必中全额。
; EV 参考数(按判定式复算):AC10 期望减免 21.25% / AC11 25% / AC12 28.75%;微调旋钮 = bounds/discounts,不动 AC 值。
; effect_pool_map 同批删 defense_up 键(减伤百分比行整体退役、无双轨)——ac_up 是 AC 阈值轴效果,不入任何池;
; off_guard(hero_defense 池)保留不动,池结构与乘区公式零改动。
; 敌人技能池批(2026-09-16 用户拍板):effect_pool_map 增 empower→enemy_output(蓄力技载体——敌方输出 ×2
; 经既有 enemy_output 乘区兑付)与 fortify→enemy_defense(硬化技载体——敌方防御池新词汇)。
; enemy_defense 池乘区消费面 = 主角攻击落地段(Σ三分量后 ×(100+clamp(enemy_defense))/100)——
; 四池对称乘区:敌打主角 = hero_defense×enemy_output,主角打敌 = hero_offense×enemy_defense
; (hero_offense 现行走主角普通分量 attack_up 直乘、切片未改——登记遗留)。
;
; 数值压缩批(2026-09-17 用户拍板暂定):
; equivalence_ref_damage 12→4(当量参考敞口,绝对值轴 ÷3 取整);
; roll_faces/折扣档/暴击/damage_floor/克制矩阵/pool_clamp 全部不动(相对轴)。clamp 域 [-100,+100] 共用。
;
; 战斗数值结构修复批(2026-09-18 盘问会话用户拍板):
; effect_pool_map 删 off_guard 键——off_guard(失衡)换装 AC 轴(unit percent→ac、+25→−2,provisional
; 归 状态层重设计批;消费走 _defender_ac 既有 ac 型读法零代码),退离 hero_defense 池(池清空、结构保留;
; 上方 2026-09-15 attack/defense/weaken 三型负向字典行的极性路由注记不变——defense 型兑付行仍是 off_guard,
; 变的只是池归属)。hero_offense 乘区接线同步落地(battle_orchestrator 主角攻击段):Σ三分量后
; ×(100+clamp(hero_offense))/100×(100+clamp(enemy_defense))/100——attack_up 普通分量直乘旁路退役,
; 增伤/乏力覆盖面 = 普通+穿刺+魔法 合计;上方"hero_offense 现行走直乘——登记遗留"注记随之销项。
;
; 甲效矩阵用户调参批(2026-09-18 用户逐格给值,五格改值、四格不动):
; normal ward 100→120 · normal heavy 100→50 · pierce light 100→80 · pierce ward 150→120 · pierce heavy 50→80;
; magic 全行与 normal light 不动。上方「克制语义 = 克制 ×150 / 中性 ×100 / 被克 ×50(对策三角)」三档措辞退役——
; 现行五档:克制 ×150 / 弱克制 ×120 / 中性 ×100 / 弱被克 ×80 / 被克 ×50,普通行不再恒中性。
; 键集 3×3 满格结构冻结不动;矩阵消费面 = 主角侧(道具直伤 / 主角攻击三分量 / 充能分量),
; 敌打主角现行不查矩阵——主角 armor_type 轴仍休眠,轴生效待敌方技能攻击类型批。
; 实战读数(现行敌种甲配置):L1/L2 小怪全轻甲 → 穿刺类(开格充能/穿刺弹)×80 小幅折损、普通/魔法中性;
; L2 Boss 魔法甲 → 基础攻击与穿刺弹 ×120、魔法矢 ×50(不变)。重甲现行无消费敌种(零消费格)。
;
; 甲效矩阵加法核换装批(2026-09-18 用户拍板数值语言——小整数加法核,与 01-核心循环 数值语言条款同批):
; 量纲 percent→整数点数,三档 克制 +1 / 中性 0 / 被克 −1,九格 normal [0,+1,−1] / pierce [−1,+1,0] / magic [0,−1,+1];
; pierce×heavy = 0 中性为用户特别拍板(重甲挡刀刃不排斥穿刺;现行无重甲敌种,纯结构位)。
; 上方 2026-09-18 甲效矩阵用户调参批(五档 ×150/×120/×100/×80/×50)与更早三档三角批注的百分比量纲全部随批退役(历史留痕不删)。
; 键集 3×3 满格结构冻结不动;缺项回退 = 0 中性(battle_orchestrator._counter_delta);域 [−3,+3](schema 校验)。
; 奖励直伤行 payload 键 effectiveness 保留键名、值语义改点数(JSONL 契约稳定——analyze_playtest 等分析工具不破坏)。
+15
View File
@@ -94,3 +94,18 @@ price_a = 1.8
price_b = 1.1
relic_base_price = 15.0
spend_discount = 0.8
; GP+商店房实施批(2026-09-20 用户拍板,设计权威 design/research/proposal-gp-shop-room-2026-09-20.md 裁决记录):
; 掉落=均值±方差掷定(gp_drop 封闭流)+关级加值;精英行为预留行(当前无消费方,随精英节点内容批启用);
; 价格公式 = base_price + price_level_bonus(关卡) + price_increment × 该商品已购档数(已购档数在 冒险结构——
; 冒险内累计、跨冒险清零);商品三件全陈列无刷新无摇号(2026-09-20 拍板,提案 §2.4 的三选一+刷新方案退役)。
; 期望账:L2 商店前可得 GP 期望 ≈ 35–40(L1 全程 22 ± 惊喜 + L2 商店前五战 21 ± ),三件首购总价 L2 =
; (4+2)+(2+2)+(4+2)=16、全购欲望 ≈ 26–34——取舍空间成立;量级与方差全部 provisional-pending-曲线调参批
;(用户拍板骨架先行、数值整体后置,行值归 难度曲线与Boss)。
; GP 商店房重构批(M-4 迭代 11 第②批 T1,2026-10-03——需求卡片 v1.3 全裁 P1 共享池/P4 ceil/P5 甲):
; pool_shelf 行族 = 共享池货架(kind_id 词表 attack/max_hp/armor/ap/feat_ticket/heal 六行——heal 系 T6 商店补回复〔默认原则:分类内成员都要在它该出现的渠道池里,现行缺〕、GP 袋负交易切边计价物不自售、feat_ticket 系 T5 专长凭证行〔非 Boss 渠道专长入口,价与其他商品相当=契约④口径②〕、
; 规则改写型特性三轴 doctrine 切边;库存=上限即库存,账本在 冒险结构 _bonus_taken 单点共享,行族不记库存);
; 价格公式换代(pool 模式)= ceil(base_price × b^(关序−1) × A^(本次进店已购次数)),price_a=1.8/price_b=1.1
; provisional 投值(零人工令改 provisional+后置追认,原 P5 甲研究拍板后置);products 行族 + 加法定价
; 随 legacy 模式(shop=off 对照承载)保留不退役,退役归 off 锚换代批。货架行值全部 provisional 归
; 难度曲线与Boss。
+59
View File
@@ -112,3 +112,62 @@ rows = [{
"damage_mult": 1.7,
"cooldown_beats": 3
}]
; 敌人技能池批(2026-09-16 用户拍板——设计权威 docs/proposal-skill-pool.md v1.0,全值 provisional 投值归 难度曲线与Boss):
; 五行 = 普通攻击 / 突刺(新行:伤害 ×1.5 冷却 2)/ 蓄力(增益技)/ 重击 / 硬化(新行:独占增益技——Boss 专属池载体)。
; 普通攻击两条域校验锁死:倍率恒 1、冷却恒 0(schema 拒绝配置)——池恒非空的结构前提。
; 蓄力 = 纯"攻击力增加"增益技(0 伤害、施加 empower 状态),与重击无任何组合语义(纠偏二——旧"蓄力→猛击"
; 固定配对随行为环退役);增益与倍率同拍只是两层乘法共存(×2 遇 ×2 = ×4)。
; buff_duration = 2 的口径:容器时限纲 = remaining_settlements(先兑付后衰减、授予当轮衰减段即 −1)——
; 施放发生在第 N 结算战斗段,需存活到第 N+1 结算战斗段才兑付("下一拍"),故持续 1 个有效结算 ⇔ 表值 2
; (提案"攻击×2 持续 1 结算"的容器语义落地;有效增益拍恰 1 拍,归 增益状态/难度曲线 复核)。
; 硬化 = 自防增益(fortify 状态 → 敌方防御池),Boss 池独占——增益 ≤1 纪律下旧蓄力拍不进 Boss 池(proposal §2.5)。
; 保底 M = pity_threshold = 4:连续 4 拍执行普攻 → 下拍必出特殊技(特殊技内按权重、不受冷却限制)。
;
; 分支节点图批(2026-09-17——L2 幽暗地域新技能行,全值 provisional 投值归 难度曲线与Boss):
; 撕咬 bite = 伤害 ×1.5 冷却 1(高频小爆发轮廓,与突刺 ×1.5 冷却 2 同倍率错开冷却轴——巨蜘蛛池载体;
; 复用技能行纪律下 lunge 仍归 L2 熊地精,两行不共用是有意的权重/冷却独立投值位)。
; 毒爆 venom_burst = 伤害 ×2.5 冷却 4(蛛化卓尔精灵 drider 专属池独占技——"Boss=专属池独占技+权重轮廓"
; 纪律的本批兑现;池引用唯一性 = 唯一 enemy_id: drider)。
; 两行均为 damage 型(存倍率不存固定值——伤害 = 施放者攻击基线 × 技能倍率,三乘法链第一乘)。
;
; 新效应词汇批(2026-09-19 用户拍板——设计权威 docs/proposal-status-vocabulary.md v1.0,全值 provisional
; 投值归 难度曲线与Boss):三词收敛两词——多段命中退役(无防御磨损体系,无对照机制);固定值伤害改形
; 必中附加分量(rider_mult,域 (0,1]):后置加法、必中全额、不进乘区不出暴击,分量值 =
; max(damage_floor, floor(攻击基线 × rider_mult))——随基线缩放保持共享技能表前提;
; ×0.75 价位锚 = AC 折扣档最轻档"不掉档的稳定伤害"(可掷分量期望 AC10≈0.80 / AC12≈0.76 对表)。
; ① 毒爆 + rider_mult 0.75(必中毒分量:atk3 → 毒 2 点,atk 区间 2–4 → 1–3 点随开战掷定值缩放)。
; ② 蛛网束缚 web_snare(新行,妨害型 debuff——对主角施加 off_guard 失衡):0 伤害施放行(不掷不折不兑付
; 伏击),字段复用 buff_ref/buff_duration;duration 2 = 1 个有效结算(empower/fortify 先兑付后衰减含
; 施放当轮口径);冷却 4;首发载荷 = 失衡(用户拍板),乏力 sapped 为第二词汇暂不实装;
; 池纪律 +:每池妨害 ≤1(ConfigDB 跨表校验);实装面 = 仅卓尔池,其余敌种不动。
;
; 第三关内容批(2026-09-20):大地脉动 earth_pulse = 灰矮人石君王 duergar_king 专属池独占妨害技
; (0 伤害施放行,对主角施加 sapped 乏力——第二妨害词汇首发,状态行 status_effects.tres 既有);
; 字段口径同 web_snare(duration 2 = 1 个有效结算);每池妨害 ≤1 纪律由跨表校验覆盖。
; provisional 归 难度曲线与Boss。
;
; Boss 半血解锁技三行(2026-10-05 技能池执行批 T5,迭代14④——D7 用户裁案甲:每 Boss 一行新独占伤害技,
; 工作值 provisional 归调参;pool 侧 半血解锁(trigger 收编)=50 门槛随 enemy.tres 三 Boss 行):
; quake_smash 震地怒击 ×2.5/CD4(食人魔酋长)· venom_curb 遏毒 ×2.0/CD3(蛛化卓尔精灵)·
; rockslide 岩崩 ×2.5/CD4(灰矮人石君王)。解锁语义/双面过滤/一次性弹出规格 = 敌人系统.md 意图呈现节。
;
; 有效倍率表(2026-10-05 技能池执行批 T2——D4 整数基线登记:敌技基线=int(round(atk×mult)) 四舍五入半值上取,
; 全伤害管线唯一非 floor 取整点〔豁免登记见 registry skill_table〕;半点恒上取保住 atk=1 特殊技辨识度):
; atk=0(区间下界):全技塌缩下限 1(突刺==普攻==重击==1)
; atk=1(L1 全系+L2 四行):attack 1 / lunge·bite 2(实际 ×2.0 +33%)/ heavy 2(==突刺)/
; venom_burst 3(×3.0 +20%)/ venom_curb 2(×2.0 =名义)/ quake_smash 3 / rockslide 3(×3.0 +20%)
; atk=2:attack 2 / lunge·bite 3 / heavy 4 / venom_burst 5 / venom_curb 4 / quake_smash 5 / rockslide 5(全精确)
; atk=3(L2 精英/L3 全系):attack 3 / lunge·bite 5(×1.667 +11pp)/ heavy 6 / venom_burst 8(×2.667 +6.7pp)/
; venom_curb 6(=名义)/ quake_smash 8 / rockslide 8
; atk=4(区间上界):全精确(4/6/6/8/10/8/10)
;
; 敌人表内容修批 N2(2026-10-13 用户令「按推荐方式」,迭代 24 卡①)——普通敌错峰两行(12→14 行):
; venom_spit 毒吐 = 伤害 ×1.6 冷却 2(巨蜘蛛族普通敌池载体,挂 (2,5)/(2,6)/(2,7),首遇教学位 (2,4) 不投——
; 「独占技随关错峰」首轨只做在 Boss 侧的补齐;venom_spit 自 (2,5) 起投)。
; shield_bash 盾击 = 伤害 ×1.7 冷却 3(灰矮人族普通敌池载体,挂 (3,0)/(3,5)/(3,7))。
; 两行均不带 rider_mult:L2/L3 普通敌 atk 1–3,floor(atk×r) 恒被 damage_floor 兜成 1,与 0.75 档效果
; 完全相同——白占字段(毒绕开护甲由 damage 直伤表达已足够)。
; 有效倍率(int(round) 半值上取):毒吐 atk1→2/atk2→3/atk3→5;盾击 atk1→2/atk2→3/atk3→5。
; 倍率 provisional 归 M4 数值批。池权重均 2;逐池「恰一普攻/增益≤1/妨害≤1」纪律复查过
; (巨蜘蛛族增益仍仅 charge、灰矮人族 (3,0)/(3,7) 仅 charge·(3,5) 无增益、两族妨害 0)。
+44
View File
@@ -95,3 +95,47 @@ rows = [{
"stack_policy": "stack",
"max_stack": 16
}]
; 减伤墙调参批(2026-09-13,playtest-2026-09-12 报告 Q1 触发——defense_scan 实测墙轮 39%、
; 真人局 12/12 轮零承伤满血冒险成功):defense_up magnitude -50 → -30——叠满两层 = -60 减伤帽
; (原拟 pool_clamp_lo=-60 被 schema 冻结域拦截,杠杆移至本表);石肤权重 24→16 随批(reward.tres)。
; 承伤带对 C3 F4(≤20%/普通场、≤50%/Boss 场)复验责任随批;B3 GDD "-50" 文字同步随下次 B3 修订批。
; 格面资源批(2026-09-15):新增 sapped(乏力——weaken 型负向,hero_offense 池,attack_up 镜像;
; 进 effect_pool_map 同批登记)——状态表六行→七行;enrage/off_guard 语义 = attack/defense 型负向
; (标错安全格 / 踩到危险格经极性路由兑付,不再绑"标错反噬"单一来源)。
; 护甲等级掷点批(2026-09-16 用户拍板——百分比减伤增益整体换装为 AC,无双轨):
; defense_up(减伤 −30 percent ×2 层)整行退役(上方 2026-09-13 减伤墙批注随之留档)——
; "叠满池触底 ×0"免伤墙的结构面随 AC 掷点从根杜绝;新增 ac_up(盾牌加护 +1 ac ×2 层——2026-10-12 由"护甲强化"改名)——
; unit=ac 新量纲(AC 阈值轴效果,不入 effect_pool_map 任何池),消费面 = 战斗结算掷点判定
; (防守方 AC = 主角表值 armor_class + Σac 型效果层数×幅度);off_guard(失衡 +25 percent,hero_defense 池)
; 保留不动,其余六行零改动——状态表仍七行(一行换装)。
; 敌人技能池批(2026-09-16 用户拍板——增益技新状态行,七行→九行;敌方增益走既有增益状态容器):
; empower(蓄力:敌方攻击 +100 percent,enemy_output 池——蓄力技 buff_ref 载体)与
; fortify(硬化:敌方防御 +100 percent,enemy_defense 池——敌方防御池新词汇载体,Boss 池独占硬化技)。
; 两行 duration = 2 的口径:先兑付后衰减含施放当轮 → 表值 2 ⇔ 有效增益拍 1 拍(施放后下一结算兑付,
; 提案"持续 1 结算"的容器语义落地——详见 skills.tres 批注);refresh ×1 层(冷却闸下不可能自叠加)。
; enemy 侧池语义 = side-wide(registry 既有口径):蓄力 +100 入 enemy_output 与 weaken/enrage 共池 clamp;
; 硬化 +100 入 enemy_defense 新池(乘区消费面 = 战斗结算 主角攻击落地段)。值全部 provisional 归 难度曲线与Boss。
;
; 数值压缩批(2026-09-17 用户拍板暂定):ambush magnitude 3→1(伏击附加 = 层数×幅度,3 整除 ÷3)。
; percent 全族(attack_up 50 / weaken −65 / enrage 25 / off_guard 25 / sapped −25 / empower·fortify 100)
; 与 duration/max_stack 全部不动(相对轴与结构轴不压缩)。
;
; 战斗数值结构修复批(2026-09-18 盘问会话用户拍板——本批三行全部临时值,provisional 归 状态层重设计批):
; off_guard(失衡)换装 AC 轴:unit percent→ac、magnitude +25→−2(失衡 = 主角 AC −2,更易被命中;
; 消费走 _defender_ac 既有 ac 型读法零代码;settlement effect_pool_map 同批删 off_guard 键——
; hero_defense 池清空、池结构保留);fortify(硬化)符号纠正:+100→−50(乘区 = enemy_defense 池 −50
; → 主角攻击 ×0.5 折半——旧 +100 实际 ×2 翻倍,与"硬化=减伤"语义相反,用户确认系符号 bug);
; weaken(削弱)叠层改续时:stack_policy stack→refresh、duration_settlements 1→2(同名重复授予
; 只刷新剩余结算数、层数恒 1——结构性消饱和,×2 叠满池触底 ×0 免伤轮从根杜绝;refresh 实现与
; empower/fortify 同款零代码)。duration 终值、off_guard N 值、当量锚复算全部归 状态层重设计批。
;
; 格面资源八型批(2026-09-20 用户拍板):① off_guard magnitude −2→−1(护甲型奖励/惩罚数值对齐 = ±1);
; ② ambush(伏击)行整体退役——群伤负向不再放大敌方伤害;③ 新增 alert(警觉:敌方护甲等级 +1,
; target_side enemy、unit ac、1 结算、stack 上限 16)——blast 型负向新载体,消费 = _defender_ac 敌方侧
; ac 型读法(本批新接线)。状态表九行→九行(伏击出、警觉进)。数值全部 provisional 归 难度曲线与Boss。
;
; 主角增益只续时不叠层批(2026-09-20 用户拍板「主角的其实也一样,都是按照叙事的方式,不要有叠层;只续时不叠层」——
; 对齐削弱 2026-09-18 续时定案):attack_up / ac_up 两行 stack_policy stack→refresh;
; duration_settlements=1 与 max_stack=2 表值不动(refresh 下层数恒 1、max_stack 不消费——weaken 先例;
; dur=1 下续时表现为重复拿重置当轮倒数,跨轮延续随将来 duration 拉长自然显形——数值归状态层重设计批)。
+11
View File
@@ -4,6 +4,17 @@
[resource]
script = ExtResource("1")
; 迭代 22 秘宝体系实现重构落地批 T1(2026-10-12):新目录 12 行全量换代(设计权威=秘宝.md「目录(重设计 v1)」;
; 旧 12 行删除——venom_edge/seal_burst 已随迭代 20 专长批迁出删除,本批实删 12 行)。三档=普通 7/优秀 3/稀有 2
; (传说留空=空集合法,迭代 20 追认③先例)。解锁混合制(契约 8 逐件分配锁定表,2026-10-11 用户裁 C1):
; 钥石购买件 unlock_keystone_cost(provisional 占位);条件件 unlock_requires 谓词行——计数键
; adventure_cleared=生涯冒险成功局数(C6 裁:打通整局冒险)/boss_kill_count=生涯 Boss 击杀/vision_used=
; 真视类工具累计使用(本批新增计数域)。全部数值 provisional 归调参批(契约 7)。
; 常时参数面件(无订阅行——效果=开局/装板参数注入,非事件订阅):阔视野带/储备罐/远程镐/信标网络/刷新练习/
; 刷新执照六件 effect_kinds 挂参数 kind,由注入面按装配集 kind 分发读取(_attune_refresh_x_total 先例)。
; 主动件:线香(battle 级充能)/天眼(level 级充能)charge_reset 扩签;试炼镐=自动兑付(charges=0 无上限,
; ap_charge_safe 满 charge_n=8 自动当轮 grant_ap——2026-10-12 反哺批⑤用户裁:无玩家发起入口、
; 旧行 counter_spend 受理闸随裁删除;挖格扣 AP 后、轮末判定前兑付;战斗级重置=账即时清空自然无感)。
rows = [{
"item_id": "morning_order",
"display_name": "晨操令",
+31
View File
@@ -74,3 +74,34 @@ rows = [{
"board_types": ["deep_underdark"],
"counter_items": []
}]
; 地形变异 首批类型定稿批(2026-09-19 用户拍板)——四行两轴×两关:
; 第一关 dungeon(平原/密林基线):荆棘丛(伤害型:挖开扣 1 点生命,轮末结算兑现)+ 藤蔓缠绕
; (信息型:挖开且显示数字时数字被遮蔽,呈现层读取);第二关 underdark(幽暗地域):岩浆
; (伤害型 2 点,登记名沿用)+ 烬覆(信息型)。unlock_level 门控 + board_types 交集门控双闸,
; 首关候选池恒 {荆棘丛, 藤蔓缠绕},第二关候选池恒 {岩浆, 烬覆}。
; counter_items 恒空:反制道具配套义务随框架契约保留,兑现归 Alpha 反制批(2026-09-19 用户拍板
; 反制道具改排 Alpha——切片期变异暂无反制手段,纯税状态已知悉接受)。
; 全部行值 provisional 归 难度曲线与Boss 调参批(effect_value/布置参数均为加法核小整数轴)。
;
; 第三关内容批(2026-09-20):伤害型关间递进 1(荆棘)→ 2(岩浆)→ 3(落石)+ 信息型矿尘;
; counter_items 恒空(反制归 Alpha 反制批);布量走既有公式
; (5% + per_level_bonus × 2——percent_of_cells 表头字段驱动,不加新配置)。
; 行值全 provisional 归 难度曲线与Boss。
;
; 基数修正批(2026-09-21 用户拍板):数量公式百分比基数由总格数改为候选池格数
; (安全格 − 初始展开区 = 实际可挖格)——总格数基数下初始展开占全板 56–67%,
; 有效密度膨胀 4–6 倍(L1 10×10 板实测 5%→30%,极端板全池覆盖);percent 语义 =
; 占可挖格比例,关卡递增由 per_level_bonus 绝对格数承载。表值不变归 调参批 重标。
; M-3 迭代 5 判读锁值批(2026-09-28):岩浆 effect_value 2→1 · per_level_bonus 2→0 · percent_of_cells 5→4
; (杠杆扫描 C3 组合收带 L2——配对种子读数见 design/qa/m3-iter5-lever-scan-2026-09-28.md;L3 侧效应=
; 变异密度 9%→4%、完美 L3 0→34%,L3 无带记观察态;行值 provisional→正式随迭代 5 出口人闸追认)。
; M-3 迭代 5 返工批(2026-09-29 U2 推翻 C3 裁 C1 两刀):percent_of_cells 4→5 回退;岩浆 1 与 per_level_bonus 0 维持——C1 终态;
; C1+v1 AC 组合读数归返工批全量确认(裁断全录 design/qa/m3-iter5-u2-gate-2026-09-29.md)。
;
; 屏蔽记录(2026-10-16 用户令):skewed_veins 贫矿脉行已删除——用户裁「地形变异特异关卡后续重新做
; 设计,先屏蔽」。删除后 Boss/精英图全局池空 → _resolve_global_variant 空行回落 → region 布置原路
; 兜底(battle_orchestrator.gd 既有回落路径),玩家面零横幅零角标零资源偏斜。删除行内容与首发批
; 裁决依据(2026-10-04 迭代 14 ③号卡:案A 资源面微贫向偏斜、effect_value=30 provisional、域 [0,50]、
; 0=中性 off 锚)见 git 历史;resource_face 机制代码(RewardEconomy 偏斜投影/schema 互锁/负样本
; 断言)全部保留,重建设计直接加行即可。
+1 -1
View File
@@ -634,7 +634,7 @@ func _refresh_presentations() -> void:
func _sync_settlement_visuals() -> void:
# 结算阶段(round_end → 下一轮):D 区去饱和+金橙偏移锁输入(明度不变)+ 明细带展开(高度读 battle_layout)
# 结算阶段(round_end → 下一轮):D 区去饱和+金橙偏移锁输入(明度不变)+ 明细带展开 84px
var settling := _is_settling()
if settling and not run_scope.was_settling:
ui.battle.settlement_fx.play_round_sweep(ui.battle.board_zone.board_view.get_global_rect()) # 结算轮光带——时序敏感演出触发,例外留在组合根
+1 -1
View File
@@ -1,7 +1,7 @@
## VERTICAL SLICE - NOT FOR PRODUCTION
## 组合根覆盖层流程承接件:设置/状态面板/生涯页/选档界面/图例/钱包事件的开合与数据投喂。
## 本件是 main.gd 同名函数的逐字搬运(成员访问改 root 前缀)——main 侧留同名薄委托,探针 main.X 路径零改动。
## 全部开合走组合根模态编排口(root.ui.modals.flow.open/close);本件零成员态。
## 全部开合走组合根模态单口(root._open_modal/_close_modal);本件零成员态。
extends RefCounted
static func _open_settings(root: Variant) -> void:
+7 -9
View File
@@ -6,8 +6,8 @@ extends RefCounted
# 战斗屏三区(B 战斗画面 / C·D 两列——节点链
# 进度由关卡画面本体(选路覆盖层整图)承载,纵向空间归 C/D 底行;
# 无顶栏进度条、无道具面板区)。分区几何读 ConfigDb.presentation.battle_layout。
# 进度由关卡画面本体(选路覆盖层整图)承载,28px 纵向空间拨给 C/D 底行 520→548;
# 无顶栏进度条、无道具面板区)。
# + 结算演出覆盖层(A–D 之上、模态之下——跨区弹道/光带载体)。
# 返回句柄字典:{stage, log_view, info_panel, board_zone, board_view, ap_bar, settlement_fx}
# (返回句柄不含 gp_label/keystone_label——GP/钥石不在战斗屏呈现)
@@ -17,22 +17,20 @@ static func build_battle_ui(root: Control, db: ConfigDb) -> Dictionary:
root.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
root.add_theme_constant_override("separation", 0)
var layout: BattleLayoutTable = db.presentation.battle_layout
# B 区:战斗画面(全宽 × battle_layout.stage_h——常驻双舞台,布局决策 D1)
var stage := BattleStageView.new(db, layout)
# B 区:战斗画面(全宽 × 252px——常驻双舞台,布局决策 D1)
var stage := BattleStageView.new(db)
root.add_child(stage)
# C/D 两列(高度 = 基座高 − B 区高——底行承载)
# C/D 两列(548px——含顶栏让出的 28px 纵向空间)
var bottom := HBoxContainer.new()
bottom.size_flags_vertical = Control.SIZE_EXPAND_FILL
bottom.add_theme_constant_override("separation", 4)
root.add_child(bottom)
var info_panel := HeroInfoPanelView.new(layout)
var info_panel := HeroInfoPanelView.new()
bottom.add_child(info_panel)
var board_zone := BoardZoneView.new(layout)
var board_zone := BoardZoneView.new()
bottom.add_child(board_zone)
board_zone.ap_bar.set_refresh_cost(int(db.run.action_economy.rap_refresh_cost)) # RAP 读数表值驱动
+2 -2
View File
@@ -31,8 +31,8 @@ var _arm_timer := ArmedTimer.new() # 弃图刷新确认窗(T3/D3 P4 乙—
const REFRESH_CONFIRM_WINDOW_S := 4.0 # 弃图刷新确认窗(原 tween_interval 字面量升常量——语义零变化)
func _init(layout: BattleLayoutTable) -> void:
custom_minimum_size = Vector2(0, layout.ap_bar_h)
func _init() -> void:
custom_minimum_size = Vector2(0, 44)
_arm_timer.expired.connect(_disarm)
var sb := UiKit.panel_flat(UiKit.PANEL_DATA, UiKit.PANEL_BORDER, 0, 1, Vector4(8, 4, 8, 4))
add_theme_stylebox_override("panel", sb)
+7 -9
View File
@@ -4,12 +4,12 @@ class_name BattleLogView
extends PanelContainer
const BAND_H_DIG := 24
const BAND_H_SETTLE := 84
const AGG_TYPES := ["reward_ineffective"]
const COL_GOLD := UiKit.HEX_GOLD
var _db
var _band_h_dig := 0
var _band_h_settle := 0
var _log: RichTextLabel
var _summary: Label
var _hint: Label
@@ -18,11 +18,9 @@ var _round_rows: Array[String] = [] # 本结算轮行缓冲(上轮摘要
var _pending_agg := {} # 聚合计数行 pending(type+batch_key → {row, count})
func _init(db_ref, layout: BattleLayoutTable) -> void:
func _init(db_ref) -> void:
_db = db_ref
_band_h_dig = layout.log_band_h_dig
_band_h_settle = layout.log_band_h_settle
custom_minimum_size = Vector2(0, _band_h_dig)
custom_minimum_size = Vector2(0, BAND_H_DIG)
size_flags_vertical = Control.SIZE_SHRINK_END
var vb := VBoxContainer.new()
vb.add_theme_constant_override("separation", 2)
@@ -31,7 +29,7 @@ func _init(db_ref, layout: BattleLayoutTable) -> void:
vb.add_child(head)
# 明细条灰字对深灰底实测 2.63:1 → 暗底双色墨制=暖白族
_summary = UiKit.label("",UiKit.FS_BODY, false, UiKit.WARM)
_summary.custom_minimum_size = Vector2(0, _band_h_dig - 4)
_summary.custom_minimum_size = Vector2(0, BAND_H_DIG - 4)
_summary.clip_text = true
_summary.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
head.add_child(_summary)
@@ -41,7 +39,7 @@ func _init(db_ref, layout: BattleLayoutTable) -> void:
_log = RichTextLabel.new()
_log.bbcode_enabled = true
_log.scroll_following = true
_log.custom_minimum_size = Vector2(0, _band_h_settle - 26)
_log.custom_minimum_size = Vector2(0, BAND_H_SETTLE - 26)
_log.clip_contents = true
_log.scroll_active = true
vb.add_child(_log)
@@ -55,7 +53,7 @@ func set_mode(mode: String) -> void:
var settle := mode == "settle"
_log.visible = settle
_summary.visible = not settle
custom_minimum_size = Vector2(0, _band_h_settle if settle else _band_h_dig)
custom_minimum_size = Vector2(0, BAND_H_SETTLE if settle else BAND_H_DIG)
func mode() -> String:
+5 -5
View File
@@ -24,11 +24,11 @@ var _viewport: SubViewport
var world: Node2D # StageWorld(preload 脚本实例——Node2D 世界根/字体挂点)
func _init(db_ref, layout: BattleLayoutTable) -> void:
custom_minimum_size = Vector2(0, layout.stage_h)
func _init(db_ref) -> void:
custom_minimum_size = Vector2(0, 252)
_build_backdrop()
_build_world_stage()
_build_text_half(db_ref, layout)
_build_text_half(db_ref)
_build_companion_layer(db_ref)
@@ -75,7 +75,7 @@ func _build_world_stage() -> void:
## Control 文本半区域(round_label / stage_center / log_view 原样保留——C1 永久 Control)
func _build_text_half(db_ref, layout: BattleLayoutTable) -> void: # type-hint: ignore(db 鸭子型注入——单测以最小 stub 构造)
func _build_text_half(db_ref) -> void: # type-hint: ignore(db 鸭子型注入——单测以最小 stub 构造)
var vb := VBoxContainer.new()
vb.add_theme_constant_override("separation", 4)
vb.set_anchors_preset(Control.PRESET_FULL_RECT)
@@ -86,7 +86,7 @@ func _build_text_half(db_ref, layout: BattleLayoutTable) -> void: # type-hint:
add_child(vb)
_build_narr_row(vb)
_build_center_row(vb)
log_view = BattleLogView.new(db_ref, layout)
log_view = BattleLogView.new(db_ref)
vb.add_child(log_view)
+4 -4
View File
@@ -18,17 +18,17 @@ signal hover_forbidden(cell: Vector2i)
signal chord_attempted(cell: Vector2i)
func _init(layout: BattleLayoutTable) -> void:
func _init() -> void:
size_flags_horizontal = Control.SIZE_EXPAND_FILL
var vb := VBoxContainer.new()
vb.add_theme_constant_override("separation", 4)
add_child(vb)
_build_views(vb, layout)
_build_views(vb)
## 视图三件域:AP 条+棋盘区(含动效与 toast 叠层)
func _build_views(vb: VBoxContainer, layout: BattleLayoutTable) -> void:
ap_bar = ApBarView.new(layout)
func _build_views(vb: VBoxContainer) -> void:
ap_bar = ApBarView.new()
vb.add_child(ap_bar)
var board_area := Control.new()
board_area.size_flags_vertical = Control.SIZE_EXPAND_FILL
@@ -21,8 +21,8 @@ var _board_variant_section: VBoxContainer # 地形变异常驻角标(空态
var _board_variant_list: VBoxContainer
func _init(layout: BattleLayoutTable) -> void:
custom_minimum_size = Vector2(layout.info_panel_w, 0)
func _init() -> void:
custom_minimum_size = Vector2(240, 0)
clip_contents = true
# 主面板穿石板戏服(纹理本色;数据框仍素面 §7.1;缺位回退 flat)
var sb := UiKit.panel_skinned(Vector4(8, 6, 8, 6))
+1 -1
View File
@@ -136,7 +136,7 @@ func _ready() -> void:
# ---- ⑥ 主角受击/死亡路由(battle_stage 主角走完整呈现链的断言) ----
var db2 = load("res://core/config_db.gd").new()
if db2.load_tables("res://data/tables", false):
var stage2 = BattleStageView.new(db2, db2.presentation.battle_layout)
var stage2 = BattleStageView.new(db2)
add_child(stage2)
var flash_before: int = int(stage2.hero_standee.fx_probe().get("flash_count", 0))
stage2.on_step_row_fx({"type": "damage", "target": "hero", "killed": false})
+1 -1
View File
@@ -530,7 +530,7 @@ func _career_nojump_contract(main: Node) -> void:
problems.append("[career][nojump] 页内出现导航入口「%s」(零跳转违约——生涯纯只读)" % nav)
# ⑥standee 专项:B 区站桩内容矩形 ⊆ 舞台矩形(高度读布局表;内缩 8px)且不被裁切
# ⑥standee 专项:B 区站桩内容矩形 ⊆ 252px 舞台矩形(内缩 8px)且不被裁切
# (名行基线离盒底 1px 同型高危写法返修回归闸;
# 内容矩形=StandeeBody.content_rect(),最低绘制元素=底座下缘)
func _standeefit_contract(main: Node) -> void:
+3 -20
View File
@@ -112,12 +112,7 @@ tests/
| 挖/封印合法性与可辨拒绝(拒绝零副作用) | 排雷玩法 | `MinesweeperRules.settle_batch()` | `minesweeper_rules_test.gd:_test_dig_face_rules`;`minesweeper_rules_test.gd:_test_seal_place`;`minesweeper_rules_test.gd:_test_reject_out_of_catalog` |
| 封印不可逆与挖开封印格放行(兑付改判四情况) | 排雷玩法 | `MinesweeperRules.settle_batch()` | `seal_polarity_test.gd:_smoke_seal_irreversible_quadrants`;`minesweeper_rules_test.gd:_test_seal_place` |
| AP 扣费、末点耗尽即收轮与战斗收束清零 | 行动经济 | `MinesweeperRules.settle_batch()`(→`ActionEconomy.try_spend()`/`ActionEconomy.notify_combat_end()`) | `seal_polarity_test.gd:_smoke_seal_ap_exhausted`;`round_flow_skill_pool_test.gd:_smoke_full_battle`;`round_flow_skill_pool_test.gd:_smoke_active_refresh` |
| 停手转存储备与轮内刷新(上限/AP 不重置/刷新图零清图奖励) | 行动经济 | `BattleOrchestrator.player_request_refresh()`/`MinesweeperRules.settle_batch()` | `round_flow_skill_pool_test.gd:_smoke_active_refresh`;`seal_polarity_test.gd:_smoke_refresh_provenance_guard`;`refresh_feats_test.gd:test_no_feats_baseline` |
| 换图系刷新链路与效果词表接线 | 行动经济×战斗结算×奇物 | `MinesweeperRules.settle_batch()`/`BattleOrchestrator.player_request_refresh()` | `effect_words_t1_test.gd:_init`;`forge_table_test.gd:_test_effect_kinds_closed`;`refresh_feats_test.gd:test_board_refresh_fact_only_on_success` |
| 换图基座:挖格产 RAP 与刷新折扣 | 行动经济×奇物 | `MinesweeperRules.settle_batch()`/`BattleOrchestrator.player_request_refresh()` | `refresh_feats_test.gd:test_reserve_on_accepted_dig`;`refresh_feats_test.gd:test_refresh_discount_gate_and_charge`;`refresh_feats_test.gd:test_double_base_stack` |
| 换图输出:刷新群伤与蓄力攻击 | 战斗结算×奇物 | `BattleOrchestrator.player_request_refresh()`→轮末 `MinesweeperRules.settle_batch(stop)` | `refresh_feats_test.gd:test_blast_defers_to_combat_segment`;`refresh_feats_test.gd:test_charge_layers_consumed_same_round` |
| 换图生存:全局固定减伤与轮末恢复 | 战斗结算×奇物 | `BattleOrchestrator.player_request_refresh()`→敌方攻击/危险格/错误封印/地形真实受伤入口 | `refresh_feats_test.gd:test_all_hero_damage_paths_emit_once`;`refresh_feats_test.gd:test_stone_mitigation_all_damage`;`refresh_feats_test.gd:test_rest_rotation_cap_and_clear` |
| 换图资源:刷新固定 GP 收益 | 战斗结算×奇物 | `BattleOrchestrator.player_request_refresh()` | `refresh_feats_test.gd:test_mine_profit_gp` |
| 停手转存储备与轮内刷新(上限/AP 不重置/刷新图零清图奖励) | 行动经济 | `BattleOrchestrator.player_request_refresh()`/`MinesweeperRules.settle_batch()` | `round_flow_skill_pool_test.gd:_smoke_active_refresh`;`seal_polarity_test.gd:_smoke_refresh_provenance_guard` |
| 下轮行动点修正排队与兑现 | 行动经济 | `ActionEconomy.pending_ap_delta()`(排队经 `ActionEconomy.queue_ap_delta()`,写入方为效果引擎) | `seal_polarity_test.gd:_smoke_negative_dictionary`;`feat_vouchers_test.gd:_init` |
**旅程段六:表现与支撑**
@@ -133,21 +128,9 @@ tests/
| 中文字体随包与字形覆盖 | HUD框架 | `UiKit.load_font()` | `ui_font_asset_test.gd:_init`;`theme_projection_test.gd:_smoke_global_theme` |
| 地形瓦片套与格面数字可读 | HUD框架 | `TilePalette.digit_ink_mode()`/`TilePalette.normalize_floor_luma()` | `terrain_tile_sets_test.gd:_test_set_completeness`;`terrain_tile_sets_test.gd:_test_hue_domains`;`terrain_tile_sets_test.gd:_test_digit_ink_modes` |
| 站桩敌人呈现与结算演出落点 | 战斗表现 | `BattleStageView.enemy_standee_center()`/`BattleEndOverlay.open_victory()` | `standee_fx_sweep_test.gd:_init`;`pacing_queue_test.gd:_init` |
| 站桩呈现定值与素材绑定 | 战斗表现 | `UiKit.load_tex()`/`StandeeBody.name_line_probe()` | `standee_present_values_test.gd:_init` |
| B 区舞台背景三关变体与连续地面层(按 board_type 选图/地面层高度读布局表/四柱光柱退役) | HUD框架 | `BattleStageView.set_board_type()` | `stage_background_test.gd:_test_background_selection`;`stage_background_test.gd:_test_ground_layer_geometry`;`stage_background_test.gd:_test_beams_retired` |
| 战斗屏三区几何与棋盘格边长(分辨率两档×四档板型) | HUD框架 | `BoardView.set_cell_area()`(D 区可用面积 → 格边长);读面 `BoardView.cell_size` | `layout_probe.gd:_ready`;`board_gen_reward_test.gd:_smoke_layout_cell_formula` |
| 调参测速批量模拟(逐帧步进与统计读数) | 调参测量 | `TuneSimController.run()`(调试浮窗批量模拟入口) | `tune_sim_batch_parity_test.gd:_init`(配对对拍套件,随测速循环批建) |
| 战斗叙述与终局文案(数值带入/胜负互异) | HUD框架 | `BattleNarrator.battle_end_text()`/`BattleNarrator.boss_name()` | `battle_narrator_test.gd:_test_numeric_lines_carry_values`;`battle_narrator_test.gd:_test_end_text_differs_by_result`;`battle_narrator_test.gd:_test_boss_name_uses_boss_rowset` |
| 玩家面文案与危险格格面字形 | HUD框架 | `BoardView.rebuild()`/`StatusSlotRow.set_effects()` | `player_copy_sweep_test.gd:_sweep_board_glyph`;`player_copy_sweep_test.gd:_sweep_legend`;`player_copy_sweep_test.gd:_sweep_hero_panel` |
| 营地场景图十层铺底与门洞留空呈现 | 营地场景视图 | 进入存档→选档→进档→营地场景屏(`CampSceneView.setup_layers()` 驱动) | `shot_probe.gd:_ready`(camp 截图段)〔营地图批 V1〕 |
| 营地七物件命中区点选与分界面可达 | 营地场景视图 | 七物件命中区 `_gui_input()` → `CampSceneView.object_pressed()` → 组合根开界面 | `ui_click_probe.gd:_ready`(七物件合成点击段)〔营地图批 V2〕 |
| 营地大门两分支确认与断点续玩接线 | 营地交互流 | 大门命中区 → ConfirmDialog(三出口)→ `main._on_confirm_new_adventure()`/`_resume_from_menu()` | `ui_click_probe.gd:_ready`(大门两分支段/断点确认段 :500-528)〔营地图批 V3〕 |
| 四柜台拆解后五界面入口改挂与写口零回归 | 营地五界面 | 五界面意图信号 → `CampShopPresenter` → `MetaProgression.tree_buy()` 写口 | `forge_workbench_test.gd:_test_forge_rows`〔营地图批 V4〕;`ui_click_probe.gd:_ready`(写口链段) |
| 营地篝火回主菜单与笔记本改挂动线 | 营地交互流 | 笔记本命中区 → `CareerOverlay.open()`;篝火命中区 → ConfirmDialog 二次确认 → 主菜单 | `ui_struct_probe.gd:_ready`(career 段)〔营地图批 V5〕;`screen_flow_probe.gd:_ready`(篝火/开合段)〔营地图批 V7〕 |
| 营地图鉴占位挂起态与反参照结构纪律 | 营地场景视图 | 布告板命中区 → `CampSceneView.object_pressed()` → 图鉴占位视图;营地根态场景树审计 | `ui_struct_probe.gd:_ready`(占位禁词/禁行段)〔营地图批 V6〕;`ui_struct_probe.gd:_ready`(结构禁词段)〔营地图批 V9〕 |
| 营地刷新单口与场景根 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.modals.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`(顶栏位结构段) |
**旅程段七:数据配置与跨系统契约**
@@ -176,13 +159,13 @@ tests/
| 战斗循环 | 地图战斗资源.md | 清图奖励双份与零路径;GP 钱包/escrow/商店收口/共享池;封印与极性路由/不可逆 | 已覆盖 | — |
| 战斗循环 | 增益状态.md | 系统间契约词表与受理口径:五配方互异/掷点标签成员性/增益布尔受理;封印与极性路由/不可逆 | 部分覆盖 | 增益叠层/衰减/清除结算链无断言;见待办清单「能力清单覆盖缺口补齐」条 |
| 战斗循环 | 战斗结算.md | 伤害公式与掷点乘区;伤害单据编排与回放;轮内流与结算五段全序 | 已覆盖 | — |
| 战斗循环 | 战斗表现.md | 站桩敌人呈现与结算演出落点;站桩呈现定值与素材绑定 | 部分覆盖 | 死亡灰化与减动效演出档仅探针与人工目检;见待办清单「能力清单覆盖缺口补齐」条 |
| 战斗循环 | 战斗表现.md | 站桩敌人呈现与结算演出落点 | 部分覆盖 | 死亡灰化与减动效演出档仅探针与人工目检;见待办清单「能力清单覆盖缺口补齐」条 |
| 战斗循环 | 敌人系统.md | 技能池数据面与回放独立;Boss 半血解锁技门控;敌人技能池跨表链接校验 | 已覆盖 | — |
| 排雷循环 | 地形变异.md | 变异布置门控;表结构守卫:域校验/行序键/跨字段互锁/配额锚 | 已覆盖 | — |
| 排雷循环 | 排雷玩法.md | 装板与开局免费展开(封锁格无资源、计入清图);挖/封印合法性与可辨拒绝(拒绝零副作用);封印不可逆与挖开封印格放行(兑付改判四情况) | 已覆盖 | — |
| 排雷循环 | 棋盘生成.md | 棋盘按参数行出图、数字恒真;同参数同种子逐位复现、异种子不退化;可推理率与清图可达(合法性先于质量分)、重试有界、降级诚实 | 已覆盖 | — |
| 排雷循环 | 行动经济.md | AP 扣费、末点耗尽即收轮与战斗收束清零;停手转存储备与轮内刷新(上限/AP 不重置/刷新图零清图奖励);下轮行动点修正排队与兑现 | 已覆盖 | — |
| 表现与支撑 | HUD框架.md | 拒绝反馈分面可辨与未知兜底文案;结算明细带逐行呈现与排播节奏;模态覆盖层编排与输入锁;未开格类型微光(8 邻作用集/五组色相/零玩法写入);UI 全局主题与按钮五态(含对比度锚);中文字体随包与字形覆盖;地形瓦片套与格面数字可读;战斗叙述与终局文案(数值带入/胜负互异);玩家面文案与危险格格面字形;战斗屏三区几何与棋盘格边长(分辨率两档×四档板型);B 区舞台背景三关变体与连续地面层(按 board_type 选图/地面层高度读布局表/四柱光柱退役) | 已覆盖 | — |
| 表现与支撑 | HUD框架.md | 拒绝反馈分面可辨与未知兜底文案;结算明细带逐行呈现与排播节奏;模态覆盖层编排与输入锁;未开格类型微光(8 邻作用集/五组色相/零玩法写入);UI 全局主题与按钮五态(含对比度锚);中文字体随包与字形覆盖;地形瓦片套与格面数字可读;战斗叙述与终局文案(数值带入/胜负互异);玩家面文案与危险格格面字形 | 已覆盖 | — |
| 表现与支撑 | 存档序列化.md | 存档写盘⇄读回往返保真;三槽位隔离与激活失败回滚;槽位摘要窥视与坏槽三态;启动态无激活不写盘;旧档迁移链与断点续玩零跳号(集成);存档⇄RNG 快照往返保真(集成) | 已覆盖 | — |
| 表现与支撑 | 教学引导.md | — | 未覆盖 | 教学形态与首遇时机待设计;见待办清单「教学形态未定」条 |
| 表现与支撑 | 数据配置.md | 全表装载、就绪态与表清单目录对账;进度坐标查行:精确命中/向上取整/封顶/警告去重;运行期越域致命与进程非 0 退出;加载期违规表拒绝:跨表悬空/计数器前缀/真视窄域;表结构守卫:域校验/行序键/跨字段互锁/配额锚 | 已覆盖 | — |
+2 -2
View File
@@ -769,7 +769,7 @@ func _smoke_feats() -> void:
and orch0.fx_host().fx_emit("mine_hit", {"damage": 5}).is_empty()
and orch0.fx_host().fx_emit("battle_won", {"round": 1}).is_empty())
# ⑦c 特性持有呈现段(C 区「特性」节;呈现面在 06 在册)
var panel = load("res://presentation/views/hero_info_panel_view.gd").new(_db.presentation.battle_layout)
var panel = load("res://presentation/views/hero_info_panel_view.gd").new()
panel.set_feat_holdings([])
Kit.check("特性段空态隐藏(视图空态纪律同特性段)", not panel._feat_section.visible)
panel.set_feat_holdings(["疼痛记忆 ×1", "双管镐 ×1"])
@@ -788,7 +788,7 @@ func _adv_drive_to_shop(a, st: Dictionary, autoplay) -> bool:
autoplay._drive_level(a.runner(), st, null, "normal", "min")
if String(st["result"]) != "":
return false
if a._bp_store._pending_next_level:
if a._pending_next_level:
# 三选一停点确认(确定性选件后推进,与 run_adventure 自动策略同口径;TP0 令牌化)
if not a.stop()._pending.is_empty():
var bcands: Array = a.stop()._pending["candidates"]
+2 -2
View File
@@ -78,7 +78,7 @@ func _init() -> void:
# 账本保留(契约 1):主动件充能与每冒险种行入口零改动(单源化后=差额种行幂等——不吞装配)
a._attunement = ["incense_stick"]
a._loadout.set_attunement(["incense_stick"])
a._bp_store._loadout_seeded = false # 模拟首关 bind 时点(分派走 seed_for_adventure 分支——成员随断点件收编改址)
a._loadout_seeded = false # 模拟首关 bind 时点(分派走 seed_for_adventure 分支)
a._loadout_on_level_inventory() # 种行(首关 bind 时点语义)
var incense_left := 0
for r in a.runner().treasure_inventory.snapshot_inventory():
@@ -289,7 +289,7 @@ func _init() -> void:
# A12 呈现两态文案与 _format_row 一致:两态均零「雷」字面
var LogViewScript := load("res://presentation/views/battle_log_view.gd")
var lv = LogViewScript.new(db, db.presentation.battle_layout)
var lv = LogViewScript.new(db)
var broken_row := {"type": "seal_miss", "source_class": "seal_miss", "origin_cell": [0, 0],
"round_index": 1, "display_name": "封印未中", "value": 0, "highlight": "perfect_broken"}
var forgiven_row := {"type": "seal_miss", "source_class": "seal_miss", "origin_cell": [0, 0],
@@ -1477,7 +1477,7 @@ func _adv_drive_to_shop(a, st: Dictionary, autoplay) -> bool:
autoplay._drive_level(a.runner(), st, null, "normal", "min")
if String(st["result"]) != "":
return false
if a._bp_store._pending_next_level:
if a._pending_next_level:
# 三选一停点确认(确定性选件后推进,与 run_adventure 自动策略同口径;TP0 令牌化)
if not a.stop()._pending.is_empty():
var bcands: Array = a.stop()._pending["candidates"]
@@ -126,7 +126,7 @@ func _init() -> void:
UiKit.motion_scale = 1.0
# ---- 断言④:排播两处取用按行 target_id 解析站桩(d12 排播半——假 stage 记参)----
var rp = RowPacerScript.new()
var fstage := FakeStage.new(null, root.get_node("/root/ConfigDB").presentation.battle_layout)
var fstage := FakeStage.new(null)
var ffx := FakeFx.new()
rp.stage = fstage
rp.board_view = main.ui.battle.board_zone.board_view
@@ -41,7 +41,7 @@ func _init() -> void:
# ① C 区两段头(u1/u2——直建 hero 面板,adventure_feats_test ⑦c 族同构)
func _sweep_hero_panel() -> void:
var panel = load("res://presentation/views/hero_info_panel_view.gd").new(_db.presentation.battle_layout)
var panel = load("res://presentation/views/hero_info_panel_view.gd").new()
var feat_head := _first_label(panel._feat_section)
var curio_head := _first_label(panel._curio_section)
Kit.check("C 区专长段头==「专长」(u1 换代——段头文案钉值)〔wa1〕",
@@ -95,7 +95,7 @@ func _sweep_source_names() -> void:
row_view._hide_tip()
Kit.check("结算表 source_label_map[mine_hit]==「危险格」(u6 换代——ConfigDB 真装载)〔wa7〕",
String(_db.combat.settlement.core.source_label_map.get("mine_hit", "")) == "危险格")
var log_view = load("res://presentation/views/battle_log_view.gd").new(_db, _db.presentation.battle_layout)
var log_view = load("res://presentation/views/battle_log_view.gd").new(_db)
var row_txt := String(log_view._format_row({"type": "effect", "source_class": "mine_hit",
"display_name": "挖掘反噬", "value": -5, "pool_value": -5, "round_index": 1}))
Kit.check("战斗日志 mine_hit 来源行含「(危险格)」(u6 消费半——_format_row 生产路径)〔wa7〕",
@@ -72,7 +72,7 @@ func _init() -> void:
UiKit.motion_scale = 1.0
# ---- ⑤ 站桩按 id 解析(两口共用同名字敌载体)----
var stage = StageScript.new(null, load("res://data/tables/battle_layout.tres"))
var stage = StageScript.new(null)
root.add_child(stage)
var s1 = StandeeBodyScript.new("enemy")
var s2 = StandeeBodyScript.new("enemy")
@@ -383,7 +383,7 @@ func _smoke_type_glow() -> void:
# 本段把现行行形态逐型喂进真实视图:拆行残留与行字段错位在此转红)----
func _smoke_battle_log_view() -> void:
print("--- 战斗日志视图行格式化(行协议 9 类呈现层同步闸)---")
var view = load("res://presentation/views/battle_log_view.gd").new(_db, _db.presentation.battle_layout)
var view = load("res://presentation/views/battle_log_view.gd").new(_db)
# 敌方行动伤害行(现行形态:baseline 在场、attach 已出协议——修复前此行即 Invalid access)
view.append_row({"type": "damage", "display_name": "地精 撕咬", "value": 2, "target": "主角",
"baseline": 3, "roll": 15, "ac": 12, "tier": 100,
@@ -1 +0,0 @@
uid://ceh2mcde5wrtj
+26
View File
@@ -0,0 +1,26 @@
# 迭代 44 反哺点清单——2026-10-30
要写进权威文档的点逐条列落点(改哪一节、改成什么、依据);用户在会话中裁决后归文档批落文。实现批禁写 `design/` 与根规则文件,本清单是唯一移交通道。
## 架构文档(design/engineering/architecture/architecture.md)
1. **「模块归属·呈现层」ui_registry 行现状化**——现登记「实现批建件」态;实现后改现状陈述:UiRegistry/UiScreens/UiBattle/UiModals 四件已建(全 RefCounted、类变量 3/9/5/14、UiModals.flow 随容器构造即建)。
2. **同表 main_ui_build 行「层序逻辑不在此件——唯一事实源仍是 main.LAYER_CONTRACT + _apply_layer_contract()」句失效**——唯一事实源已迁 `ui_registry.LAYER_CONTRACT`+`ui.apply_layer_contract(root)`;该句改指 ui_registry(依据=设计文档 §3.3 建议句+实现实况)。
3. **「呈现层装配与会话生命周期」节屏成员寻址迁注册面句核对**——v1.25 已预写「探针挂载假设=main.ui.<域>.<句柄>」;实现实况与其一致,但需补两句实况细节:①ModalFlow 实例随 UiModals 容器构造建立(装配早期注入点依赖其先在座);②探针契约面新增两件取证探针(shot_probe/fx_shot_probe)随批改址。
4. **「战斗编排域拆件定稿」节轴丁两行「构造=引用束注入」句与实态口径差**——实态=RoundCycle 三参直构(host/fx_host_ref/reward_grant_ref,五段构造透传不落成员)、BattleFacts 零参直构;句按设计文档 §8 预判「三参直构无需束」现状化。
5. **「模块归属·功能层」RoundCycle/BattleFacts 两行实测值换代**——RoundCycle 类变量 8/公开方法 3;BattleFacts 类变量 15(贴顶)/公开方法 4(reset_round+三 mark);宿主 battle_orchestrator 实测 15 成员/811 行(文件长键 1035 已远超实况——基线 refresh 后自然消失)。
6. **「测试与质量域」S13 豁免第三条注销句现状化**——v1.25 预写「设计闭合、实现批注销」;键账已达成(宿主实测 15),注销句转已实施事实。**同节 tune_sim 测量面豁免注销句现状化随卡③ v1.1 恢复**:裸键已消除(实测命中消失、全文件零循环);注销句保持(注销对象是 await 豁免、不依赖行为改动申报),句内「随批申报行为改动一处(收尾置假还原)」半句已失效(前提被迭代 41 测试债批 215da315 消化、申报已剥离)——现状化时一并修正为收尾现行陈述(「运行态收尾在 run() 尾每批一次执行」)。
## gdstyle 基线与闸面(tools/)
7. **基线 refresh 义务(用户人工,非落文)**——`python tools/gdstyle_gate.py --refresh`:预期消失键=main.gd max-class-variables=49(实测 15)+battle_orchestrator max-class-variables=38(实测 15)+battle_orchestrator max-file-length=1035(实测 811)+轴丙遗留归绿键;合计消失 ≥2 条触发骤降守卫,须 `--force`。与待办清单「零豁免五键清偿批」批末一次人工 refresh 合并执行。
8. **S13 no-self-assign 检查的误报形态观察**(登记不阻塞)——`X.y.z = y` 形态(赋值链尾名与右侧成员同名)被判自赋值;本批以 self 前缀消解(level_runner:520)。若后续批次再现此巧合,可考虑工程批把检查器改为比较完整接收链(登记归「迭代 42 批末移交小件」同类工具小件)。
## 待办清单(根流程清单——状态回退拟稿,落笔归上游段/用户)
9. **「零豁免五键清偿批」条目测速循环批子项状态(净零处理——原回退拟稿作废)**:卡③ 停卡呈报→用户裁重裁→写卡会话重写 v1.1(零待裁点,重裁时订正 S8 十文件与两处行号注记)→本会话恢复施工收口——条目状态直推「文档设计已闭合+已写卡+已编迭代 44」无回退中间态;重裁经过实况记录于实现报告 §5/§5.1,本条不再承载状态回退义务。
10. **「零豁免五键清偿批」条目键账进度换代**——五键中两键已真实清偿(main.gd 49→15、battle_orchestrator 37→15),待基线 refresh 收账;呈现层状态件批(迭代 45 在册)两键不受影响。
## 其他
11. **main.gd 死 preload 存量**(工程小件登记建议)——拆件遗留的零使用 preload 常量 8 条(UiAssembler/TuneSimController/DebugSessionScript/TreasureInteractController/CurioInteractController/CampShopPresenter/BoardResolversScript/三场景 preload 中 main 零使用者);本批仅清理与迁移直接相关的 ModalStack/RowPacer 两条,其余属存量债不扩范围;归工程改动直改批顺路清理。
+118
View File
@@ -0,0 +1,118 @@
# 迭代 44 实现报告(组合根注册面批+战斗编排归约批+测速循环批)——2026-10-30
状态:三卡全部施工收口(卡③ 按停卡呈报建议案重裁为 v1.1 后施工);迭代总收口(批末闸/审计/合并)进行中。
## 0. 各卡状态
| 卡 | 状态 | 提交(worktree iter44,基点 c8f5091d) |
|---|---|---|
| 卡① 组合根注册面批 | **收口**——main.gd 49→15、四新件建件、全消费面改址 | bee0682f(T1 建件)/b89ee850(T2 改形)/784d581b(T3 改址)/1929516a(T4 消灭收口) |
| 卡② 战斗编排归约批 | **收口**——battle_orchestrator 38→15(实测 37 轴丙基数起算)、RoundCycle/BattleFacts 两新件 | 24f3ca51(T1 BattleFacts)/a832965a(T2 RoundCycle)/15c833e0(T3 宿主收束)/3e9d3afa(T4 键账) |
| 卡③ 测速循环批 | **收口(v1.1 重裁后施工)**——v1.0 停卡呈报→用户裁重裁→v1.1 剥离行为改动申报面后 T0–T3 全落 | c82ef23f(T1 步进状态机)/04783fae(T2 对拍套件) |
## 1. 卡① 实际对照表(卡片 §8 十一行 → 实况)
| # | 需求点 | 改动实况 | 验收测试实况 | 结果 |
|---|---|---|---|---|
| 1 | 注册面建件+合同机器迁驻 | ui_registry.gd(LAYER_CONTRACT 逐字迁入+node(key) 19 键 match+apply_layer_contract 唯一落位口)+ui_screens/ui_battle/ui_modals 三容器 | 系统测试 V1c(system_test.gd:94-106 改址 main.ui.LAYER_CONTRACT/main.ui.node,尾缀〔装配生命批 V1〕保留)——树序逐对保序 | 绿 |
| 2 | main.gd 改形回归(49→15) | 28 迁出+7 消灭+1 新增=22(T2 中间态)→15(T4 终态);六转发方法+_flush_row_queue 退役 | run_smoke 15 项 0 失败+run_system_test 69 项 0 失败;S13 静态判据=gdstyle 实测 15(基线键 49 已不命中、成死键) | 绿 |
| 3 | 装配与流程件改址 | main_ui_build 八步赋值目标 root.ui.*(八步顺序/add_child 序/连接语句逐条不变);三流程件同表映射;smoke_boot get() 4 改 2 留 | 冒烟主屏存活面六断言+系统测试 V2 句柄等价五连比(system_test.gd:108-109 改址) | 绿 |
| 4 | 探针面批量改址 | 探针九件+probe_ui_util+shot_probe/fx_shot_probe(决定记录 2)共约 460 行机械改写 | probe_gate --click --full 全段退出码 0(九件 PASS) | 绿 |
| 5 | 系统测试面改址+RunScope 生命周期 | system_test V1a/V1c/V2/V3 矩阵取址改指 | V1–V9 全绿(V3a–V3i 存活性矩阵第五引用面逐面同源) | 绿 |
| 6 | 别名/接缝成员消灭(7 个) | _seed_edit/board_view/ap_bar/_row_queue/_modals/_settlement_stop_pending/_deferred_modal 全删;消费方改址(pacing_queue 4 处+接缝探针三件+main 自身) | pacing_queue 绿+ui_struct_probe 登记序断言(改 flow.stack)+t17_defer_probe 挂起态断言(改 flow._deferred) | 绿 |
| 7 | 六转发模态方法退役 | _open_modal/_close_modal/_on_modal_closed/_input_locked/_open_modal_after_playback/_on_pump_ended 退役;调用方改指 ui.modals.flow 五真方法+pump_ended 注入改 flow 方法 | modal_flow 绿+系统测试 V3g 模态开合段+ui_click_probe 模态开合路径 | 绿 |
| 8 | V1d 源码断言重锚 | source_guard_test.gd 重锚全 presentation 目录扫描(move_child 只许 ui_registry.apply_layer_contract 体内),尾缀〔注册面 V1〕 | source_guard 绿(8 checks) | 绿 |
| 9 | V6 源码断言改串 | theme_projection_test.gd V6 改断言 ui.modals.debug_overlay.diagnose_requested.connect(_on_diagnose_pressed),尾缀〔注册面 V2〕 | theme_projection 绿(164 checks) | 绿 |
| 10 | 视觉零变化主证 | 全批呈现层改址零像素改动 | render_gate golden 零差异(shot_probe 七屏+golden 全过) | 绿 |
| 11 | 改址完整性收口 | 49 名逐名 grep 残留=0(词形态+字符串键形态两轮全量扫描,T3 提交信息留档) | 批末代码域闸归迭代总收口(待跑);grep 自检静态判据已留档 | 静态部分绿 |
静态判据申报执行实况(卡片 §8 域口径):S13 键账对账=gdstyle 实测 main.gd 15、四新件零新键(T1/T4 两轮 static_scan 确认);基线 refresh 留用户人工(见 §4 遗留义务)。
## 2. 卡② 实际对照表(卡片 §11 V0–V6 行 → 实况)
| 行 | 需求点 | 改动实况 | 验收测试实况 | 结果 |
|---|---|---|---|---|
| V0 | 行为零变化(总判据) | 成员迁移与改指;RNG 五流零触碰(behavior_roll 随件迁移取号序逐字);五信号留宿主;两快照签名载荷逐字 | 关联套件全绿零改址应红项(round_flow/settle_segments/skill_unlock/trigger_cond/seal_polarity/feat_vouchers/variant_placement/meta_forge/adventure_feats/treasure_effects/roll_multiplier/breakpoint_resume/level_shop_economy/table_structure_guard) | 绿 |
| V1 | 两新件建件接线 | battle_facts.gd(15 成员贴顶+reset_round 逐字+三 mark 写口)+round_cycle.gd(8 成员+三参直构+五段构造逐字迁入) | settle_segments_test V1 断言(_rounds 在座且 oc 回指+_facts 在座+五段段件齐 _rounds)〔编排归约 V1〕 | 绿 |
| V2 | reset_round 复位边界 | reset_round 只清 reveals/seals/path 三项 | round_flow_skill_pool_test 内嵌断言:终局后 presentation_snapshot()["refresh_used"] == 末轮结算快照 economy.refresh_used〔编排归约 V2〕 | 绿 |
| V3 | 段驱动与摇号迁移 | 三函数迁出;宿主调用点五处改址;trigger_cond 3 处改指 | round_flow 全套+settle_segments V4-3+skill_unlock+trigger_cond(改指后绿)——同种子回放断言零改址钉住 | 绿 |
| V4 | _hero_atk 派生读 | 成员删→私有函数;combat_segment :56 改调 | roll_multiplier_test 内嵌:override 贯通 spawn+缺省回退表值〔编排归约 V4〕;攻击单 base_value 贯通由既有 hero_atk_val=100 全链路夹具承载 | 绿 |
| V5 | treasure_inventory 注入改址 | 宿主成员与 setter 删、五处读改指、level_runner:520 改经 reward_grant() 出口直注 | treasure_effects_test 内嵌引用同一性断言〔编排归约 V5〕+ob8/ob11/ob13 既有 use_treasure 受理链改址后全绿 | 绿 |
| V6 | 封印判定账/装板溯源/受理事实迁移 | 事实族改指(grant_segment 18 处+宿主全量);三 mark 写口升级;attune 读源改 _facts | seal_polarity/feat_vouchers(契约 2 计数纯净 R2)/variant_placement/meta_forge/adventure_feats/table_structure_guard(attune 外部面零改址应绿——最硬的外部面零变化证)全绿 | 绿 |
行为改动申报核对:diff 中行为改动零条(全部非行为改动——成员迁移与改指;完美写口升级=同一时点同一增量改经方法单点)。测试削弱申报:零申报兑现(测试改指只动成员寻址;新增断言 V1/V2/V4/V5 四条+V1d/V6 重锚两条=卡片 §8 申报全集)。
## 3. 实现决定记录(代拍板白名单外事项备案)
卡①:
1. **ModalFlow 实例随 UiModals 容器构造即建**(ui_modals._init)——装配第二步 row_pacer.pump_ended 注入早于第八步 flow 建立,转发壳退役后需 flow 先行在座;查询/钩子 Callable 注入时点不变(_build_modal_flow 内语句序不变),八步顺序零变化。
2. **shot_probe/fx_shot_probe 纳入改址**——两件是 render_gate 取证探针、不在卡片「探针九件」清单(probe_gate 段构成),但同为 main.X 一级地址消费方;T3 改址完整性 grep 自检抓漏后纳入(render_gate 对照表行 10 的承载件,属消费面全量改址义务)。
3. **ui_tune_probe 零连接巡检白名单登记 flow.close**——表 D 申报「closed bind 目标改 flow.close.bind」的机检联动:巡检白名单原钉 main._on_modal_closed(组合根转发壳),改钉 main.ui.modals.flow.close(同一连接的新宿主);判据面「closed 外发消费目标是模态编排口」语义不变,conn_count=11 断言零变化。
4. **layout_probe 三区 get() 字符串键改容器字段键**——卡片表 D 字符串键清单只列 smoke_boot 6 处;layout_probe:60 `main.get(key)`(key="stage"/"info_panel"/"board_zone")为漏网字符串键,改 `main.get("ui").battle.get(key)`(战区域容器字段名与三区合同键同名)。
5. **curio_overlay/confirm_dialog 两词在装配/流程件替换表漏列**——main.gd 表有、main_ui_build 与三流程件表漏,冒烟(Invalid assignment on main.gd)与 ui_click_probe sl7(开窗调用静默失效)抓漏后补改;教训=机械改写必须逐词对照 T0 名单全量扫描(T3 终检已按 49 名逐词复查全域归零)。
卡②:
1. **grant_segment._seal_preview_area 的 oc.treasure_inventory 读为 T3 盘点漏项第五处**(卡片 T3 列宿主四处读)——SCRIPT ERROR 抓漏后改指 reward_grant.treasure_inventory。
2. **treasure_effects_test 五处直构注入 obX.treasure_inventory**(ob8/ob11/ob13 注入与读、ob14 段)——设计文档 §11 盘点「1 处」漏项;同属「成员寻址改指、断言零变化」改经 reward_grant() 出口。
3. **level_runner 注入行加 self 前缀**消 S13 no-self-assign 文本巧合(`X.treasure_inventory = treasure_inventory` 左侧链尾名与右侧成员同名);语义零变化。
4. **_hero_atk 派生读落位**:受理段写点删除、spawn 读点改调、combat_segment 消费改调——「读面即引用、无第二账」先例同款。
5. 宿主内 encounter/attunement 词替换以占位符保护三处字符串键(behavior_roll 前置流名 "encounter"/BoardInstaller bundle 键 "encounter"/enc.get("attunement") 键)——键字面零变化。
## 4. 遗留读数义务与登记项
- **gdstyle 基线 refresh(用户人工,批末总收口后)**:`python tools/gdstyle_gate.py --refresh`——卡① 死键 1 条(main.gd max-class-variables=49)+卡② 预期死键 1 条(battle_orchestrator max-class-variables=38;文件长键 1035 已由轴丙归绿基线在册需一并核对)+轴丙遗留归绿键,合计消失 ≥2 条触发骤降守卫须 `--force`(与待办清单「零豁免五键清偿批」批末一次人工 refresh 合并执行口径一致)。
- **实机目检总清单(登记不阻塞)**:①三屏切换与模态开合实机过一遍(卡① T4 义务——冒烟/探针/golden 已机检承载,真人观感复核登记);②战斗一局全流程观感(卡② 结构迁移零行为变化的一般性目检)。
- **能力清单核对(收尾核对义务)**:本批卡① 零新增能力(改址只换地址)、卡② 零新增能力(新增断言全部内嵌既有函数)——game/tests/README.md 零增删改,批末核对表上代表用例名与实际落地一致(未改名,核对通过)。
- **批末代码域闸**(run_all_gates.sh --code)归迭代总收口——卡③ 裁决后与 reshape 串联执行。
## 5. 卡③ 停卡呈报(缺陷移交——按卡片 §13 L3 条款①预设停机点)
**分歧点**:卡③ §3 断言「`_run_one_level` 尾部两行 :67 `panel.set_sim_running(false)`/:68 `_running = false` 每局执行一次(潜伏红本体)」与现行代码不符——实测两行在 `run()` 尾 :53-54(for 循环外、每批恰一次),`_run_one_level` 尾部 :67-68 实为败局节点记账。
**定谳证据**(三重):
1. git 历史:迭代 41 测试债批提交 215da315(2026-10-29 合回)提交信息明载「两个产品回归随批修(……**tune_sim 运行态收尾归还 run**)」——潜伏红已由该批先修复。
2. T0 实跑面一:`--only=standee_fx_sweep` 全绿(18 checks)——wd8 三断言(`drv.seen == [true, true]`/收尾双运行态假/报告非空,现位 :145-147)现行全 PASS。
3. T0 实跑面二:ui_tune_probe 全链路 PASS——⑤ 守卫环 1800 帧预算内退出、输出四串在(模拟 N=10 完整输出)。
**两种读法**:
- 读法 A(证据支持):卡片成文(2026-10-29 v1.0 定稿)时点潜伏红确实在(u23 卷入形态),同日合回的迭代 41 测试债批把收尾归还 run() 尾——卡片「现状考证」被上游批施工消化变质。215da315 提交信息与代码现状一致。
- 读法 B:卡片考证当时即误读(:67-68 为败局记账非置假)。与 215da315 提交信息矛盾,不采。
**影响面**:
- 已申报行为改动 V3(收尾置假还原)**无对象**——还原动作已由迭代 41 测试债批完成并申报。
- 目标 2「wd8 三断言与 ui_tune_probe ⑤ 零改动**转绿**」变「零改动**保持绿**」。
- 核心义务仍有效:S13 await-in-loop 裸键消除(tools/gdstyle_baseline.txt:15 在册、基线 16 键之一)与双实现对拍套件(帧相位等价执行化证据)——对拍夹具与产品码的申报差异由两处减为一处(收尾还原差异消失,仅余 stats 暴露成员)。
- T0「实跑定谳」义务已完成(上列三重证据),实现段零施工(停摆卡不提交)。
**建议案**(供写卡段/用户裁决):
1. 卡③ 退回写卡段重裁:剥离行为改动申报(对照表 V3 行删、§1 目标 2/3 措辞改「保持绿」)、T0 判读出口改「两面全绿=前提已由迭代 41 测试债批消化,直接按无行为改动形态开工」;保留裸键消除+双实现对拍义务(夹具=现行产品码 await 形态逐字副本——收尾在 run() 尾形态——与产品码唯一申报差异=夹具暴露 stats 供对拍)。
2. 若用户不愿重写卡:裁「卡③ 剥离出迭代 44」(roadmap 行拆批),裸键消除与对拍随下一迭代重编。
**待办清单条目状态回退拟稿**(落笔归上游段/用户,本批禁写根流程清单):「零豁免五键清偿批」条目的测速循环批子项状态由「文档设计已闭合+已写卡+已编迭代 44」回退为「文档设计已闭合+待写卡(现状考证已被迭代 41 测试债批消化——行为改动申报面失效,卡片重裁后重编)」。
## 6. 批末全量域闸与闸红修复(收口实况)
**闸况**:reshape 后第三次全量域闸(--code)全绿——00 冒烟/01 系统测试/03 场景探针/05 渲染闸/10 熵增闸绿;**02 单元与集成、09 静态扫描从基线红改善归绿**(基线记的迭代 41 时代存量红指纹已在册待换代——现真绿);回执 commit 对齐分支尖(b27db010)。
**闸红修复三笔(新红必修,均孤跑复绿)**:
1. S9 R1:tune_sim_controller `_sim_stats` 裸 Dictionary 注解改 `Dictionary[Variant, Variant]`(Variant 参数化现行口径)——本批新码写法违规。
2. ui_input_probe :482/:488 case⑮ 装配直构注入 `settlement.attunement` → `_facts.attunement`——卡② 成员迁移的探针消费漏网(T0 映射谱系只扫 main./root./self. 前缀,直构注入形态不在谱系);SCRIPT ERROR 中断 _ready 致探针挂死超时。
3. run_time_fatal_test :75 BoardInstaller 束键值 `oc.encounter` → `oc._facts.encounter`+meta_progression_forge_test 三处编排器 encounter 直读改指(:340/:749/:758)——同型漏网(负面套件名与触面无字面关联=关联档选测盲区;meta_forge 分片复现、单进程未现的夹具路径差异)。
**实现决定记录补(白名单外备案)**:跨卡触面(卡② 迁移成员被卡① 已改址的探针/未申报套件消费)只有全量闸能抓——关联档选测的盲区实证;全域终扫(encounter/attunement 直读形态)后同类漏网清零。
## 7. 独立验收审计结论与记录级缺漏补记
审计报告:reports/iter44-验收审计-2026-10-30.md——**结论=通过(可合并)**。21 行对照表逐行通过、判据绑定面自跑全绿、测试削弱零发现(37 条被删断言逐条有配对新行)、非行为改动成立、证据链在案。
记录级缺漏三项(不阻塞,随本节补记):
1. 卡③ 对拍串行驱动为白名单外决定——已在 §5.1 卡③ 实现决定记录 1 备案(审计方读的是早期版本);提交 04783fae 信息同载。
2. main_overlay_flow.gd:4 头注仍写已退役的 root._open_modal/_close_modal 转发方法名——词面遗留(卡面头注义务只列 main.gd 与 main_ui_build 两处);闸后代码面禁改(改则回执作废),留反哺点通道随文档批或下一代码批顺路改写。
3. 卡② grant_segment 事实族改指实测 18 处 vs 卡面「约 23」估计偏差——记录偏轻,本节补记(T0 点名清单实数为准)。
例外备案:V1d 扫描面为 presentation 平铺 27 文件口径(与卡面 glob 一致、只扩不缩;递归口径下批前既有 ui_kit.gd:819 即红——非本批引入)。
## 8. 停机状态与收口(进行中)
- 迭代总收口(冻结→并 master→reshape→批末全量域闸→独立验收审计→合并)**未启动**——按停机规则「迭代收口合并须等停摆卡闭合、或用户裁拆批后整体进行」。
- 卡① 卡② 全部收口提交在 worktree iter44 分支(9 笔提交),冻结待收口。
+99
View File
@@ -0,0 +1,99 @@
# 迭代 44 独立验收审计报告——2026-10-30
审计方:未参与实现的独立会话(只读审计+自跑最窄抽查)。对象=worktree D:\code\g-plan2-iter44 分支 iter44 尖 9f1dda40,对照基线 master 尖 ab3b4a9d;材料=三张需求卡片(组合根注册面批/战斗编排归约批/测速循环批 v1.1)+实现报告+闸回执与日志。本报告不修改任何代码与测试,缺漏如实记录不代修。
**结论行:通过(可合并)**——三卡 21 行对照表逐行核到落点、判据绑定面自跑全绿、测试削弱零发现(断言计数 22 文件零减少)、非行为改动判定成立、证据链在案;2 项记录级缺漏+1 处注释级陈旧指址+4 项例外备案,均不动行为、判据与验收闭合(见 §6),不构成合并阻塞。
## 1. 逐行核对——卡①(§8 十一行)
| # | 判定 | 凭据(文件:行/自跑) |
|---|---|---|
| 1 | 通过 | V1c 改址 `main.ui.LAYER_CONTRACT`/`main.ui.node`(system_test.gd:90/:94,尾缀〔装配生命批 V1〕保留);自跑 run_system_test 69 项 0 失败;LAYER_CONTRACT 与基线逐字一致(git show ab3b4a9d 对读,唯一差异=注释指址 `_apply_layer_contract`→`apply_layer_contract`,白名单 3) |
| 2 | 通过 | main.gd `^var` 计数 49(基线)→15(尖);自跑 run_smoke 15 项 0 失败+run_system_test 69 项 0 失败;gdstyle 零基线外新键 |
| 3 | 通过 | main_ui_build.gd `build()` 八步名序与基线逐字同;`_build_screens` 赋值序/add_child 序不变;42 条 connect 一一对应(仅 :97/:206 两处 closed bind 改 `flow.close.bind`=表 D 申报);smoke_boot get() 4 改 2 留(settings_store/run_scope 留);冒烟六断言+V2 五连比(system_test.gd:108-109)自跑绿 |
| 4 | 通过 | 探针面 diff 归一化对账 88 处非平凡行全部落表 A/C/D+实现决定 2/3/4;probe_gate 日志全绿(.gates/probe.log 06:53,全段);ui_tune_probe 审计自跑 PASS |
| 5 | 通过 | system_test 改址全对账(V1a/V1b/V1c/V2/V3 矩阵 `_face_snapshot` mf→`main.ui.modals.flow`、rp→`main.ui.screens.row_pacer`);V3a–V3i 存活性矩阵自跑全绿(69 项含) |
| 6 | 通过 | 七别名消费方改址逐处对上(pacing_queue 4 处、ui_struct_probe `flow.stack`、t17_defer_probe `flow._deferred`、ui_click_probe `settlement_stop_timer.is_armed()`);自跑 `--only=pacing_queue --only=modal_flow` 双绿;改后断言判据零变化(归一化对账) |
| 7 | 通过 | 六转发方法+_flush_row_queue 全库零残留(grep 只余 1 处陈旧头注,见 §6 缺漏 2);modal_flow 24 checks 绿+系统测试 V3g 段绿 |
| 8 | 通过 | source_guard_test.gd:69-92 重锚——尾缀〔注册面 V1〕;自跑输出「V1d 层序落位单口(presentation 27 文件——apply_layer_contract 之外 move_child 调用点=0)」;扫描面较改前(单文件)只扩不缩;口径例外见 §6 例外 1 |
| 9 | 通过 | theme_projection_test.gd:725-726 改断言新串 `ui.modals.debug_overlay.diagnose_requested.connect(_on_diagnose_pressed)`,尾缀〔注册面 V2〕;自跑 164 checks 绿 |
| 10 | 通过 | render_gate 日志全绿(.gates/render.log 06:54,shot_probe 七屏+golden);diff 零像素面改动(改址只动地址词) |
| 11 | 通过 | 审计独立 grep:49 名旧一级地址 `main./root./self.` 代码级残留=0(仅 3 处注释级命中);代码域闸日志六件全绿(§5);留档偏薄见 §6 例外 5 |
## 2. 逐行核对——卡②(§11 V0–V6)
| 行 | 判定 | 凭据 |
|---|---|---|
| V0 | 通过 | 关联套件全绿:审计自跑 8 套件(settle_segments/round_flow_skill_pool/roll_multiplier/treasure_effects/pacing_queue/modal_flow/source_guard/theme_projection)+批末闸 unit.log 分片全绿(15 suites shard 4/4);behavior_roll 随件迁移取号序逐字(§4 核对);五信号留宿主(battle_orchestrator.gd:12-16);两快照出口在宿主(:677/:739) |
| V1 | 通过 | settle_segments_test.gd:28-29 两断言〔编排归约 V1〕:`oc._rounds != null and oc._rounds.oc == oc`+`oc._facts != null`(check_quiet 静默通过=套件 18 checks 零失败);五段段件齐在 _rounds 由 :30-34 五条既有接线断言改指 `oc._rounds._X_seg` 承载(尾缀〔迭代27 T2〕保留,纯改址) |
| V2 | 通过 | round_flow_skill_pool_test.gd:112-115〔编排归约 V2〕:终局后 `presentation_snapshot()["refresh_used"]` == 末轮结算快照 `economy.refresh_used`(经 settlement_snapshot 末次发射承接);自跑实跑输出 5 实例(L1·D0×3+L2·D0×2)全 PASS;reset_round 只清三项(battle_facts.gd:32-35) |
| V3 | 通过 | roll_round_actions 与基线 `_roll_round_actions` 逐行对读一致(仅成员改指;`oc.rng.open_stream("behavior_roll")` 流名与开流时点不变,round_cycle.gd:102);settle_if_due 闸序 settling→battle_result→phase 逐字、终局早退不回置;trigger_cond_test 3 处改指(:119/:126/:131);自跑 round_flow 134 checks+settle_segments+trigger_cond 全绿 |
| V4 | 通过 | roll_multiplier_test.gd:45-59 四断言〔编排归约 V4〕:override 100→spawn hero_unit atk==100;缺省→hero 表值(check_quiet 静默通过);攻击单 base_value 贯通由既有 `_hero_attack_row_with`(:343,hero_atk_val=100 全链路停手结算行)承载——两消费点(spawn+base_value)闭合;combat_segment.gd:56 改调 `oc._hero_atk()`,宿主派生读 :69/:282 |
| V5 | 通过 | treasure_effects_test.gd:311-315〔编排归约 V5〕:`ob14.reward_grant().treasure_inventory == adr14.runner().treasure_inventory` 引用同一性;use_treasure 受理链由 ob8/ob11/ob13 既有段承载(:311 ob8 直写改指后绿);level_runner.gd:520 注入改经 `reward_grant()` 出口(`self.` 前缀=实现决定 3) |
| V6 | 通过 | seal_polarity(_perfect 直写→_facts 8 处对读)/feat_vouchers(契约 2 计数纯净段改指后全绿)/variant_placement/meta_forge/adventure_feats/table_structure_guard——批末闸 unit 分片全绿;三 mark 写口(grant_segment.gd:311/:379/:394 与基线直写同点同增量);attune 三外部消费面零改址(main.gd/treasure_interact_controller/table_structure_guard 均不在改址 diff) |
## 3. 逐行核对——卡③ v1.1(§12 V1–V3)
| 行 | 判定 | 凭据 |
|---|---|---|
| V1 | 通过 | tune_sim_batch_parity_test.gd 五面断言〔测速 V4/V5〕自跑绿(n=3 stats 六键逐键重算+报告逐字含四关键串;n=0 六键零计);run 可等待契约由 wd8 `await ctrl.run(2)`(standee_fx_sweep_test.gd:144,零改动)承载;全文件零循环(grep -c "for \|while " = 0)、代码 await 仅 :69 一处 `await _batch_finished` |
| V2 | 通过 | 五面对拍断言〔测速 V1–V3〕自跑绿:帧序列相对偏移逐位+相邻差恒一(每步恰一帧)、运行态序列逐位+收尾双假、进度串逐位;n=3+n=0 两案各 5 断言全 PASS;manifest 增行(run_all.gd:189);拓扑例外见 §6 缺漏 1 |
| V3 | 通过 | wd8 三断言〔wd8〕自跑 PASS(18 checks:`drv.seen == [true, true]`/收尾双运行态假/报告非空——standee_fx_sweep_test.gd 不在本批 diff=零改动);ui_tune_probe 审计自跑 PASS(⑤ 守卫环 1800 帧预算内退出+输出四串);收尾四语句迁入 `_finish_batch()`(:87-92)与基线 run() 尾次序逐句同(close→报告→置假→_running),`_run_one_level` 零触碰(不在 diff) |
| 静态 | 通过 | gdstyle_gate.py 审计自跑 exit 0:命中 7 全基线内、基线外新违规 0;基线 :15 `tune_sim await-in-loop` 裸键不命中=死键(消失键不参与红判定) |
## 4. 测试削弱检查(对照三卡申报全集)
- **断言计数对账**:22 个改动测试/探针文件 `Kit.check|check(|check_quiet` 计数基线→尖逐一比较——零文件减少;仅 5 增(roll_multiplier 36→40=V4 四断言、round_flow 100→101=V2、settle_segments 16→18=V1 两条、treasure_effects 58→59=V5、tune_sim_batch_parity 0→10=新套件)。与申报新增面(卡② V1/V2/V4/V5 四条+卡① V1d/V6 重锚+卡③对拍五断言)完全一致。
- **删除断言逐条对账**:全 diff 被删 check/断言行 37 条逐条找到配对新行——语义不变只换地址(含 smoke_boot 三 get、system_test V2 五连比、pacing 四断言、V1d/V6 两条);无任何断言删除后无配对。
- **阈值/扫描面**:零阈值放宽;扫描面唯一改动=V1d 单文件→27 文件(申报为强化,成立);static_scan.sh S8/S7 两清单增行 round_cycle.gd(卡② T2 申报;battle_facts.gd 未增行=卡片明示「零协作调用不入清单」,成立)。
- **换下层直调**:零发现——探针仍走真实按钮/输入路径(pressed.emit/push_input 等既有形态未动)。
- **wd8 三断言**:文件不在 diff=零改动,自跑保持绿。**ui_tune_probe 巡检白名单**(实现决定 3):`host == main and m == "_on_modal_closed"` → `host == flow_host and m == "close"`(ui_tune_probe.gd:214-216)——属卡①表 D「closed bind 目标改 flow.close.bind」的机检联动,同一连接新宿主登记;conn_count=11 断言与消息逐字不变(:223-224 与基线 :221-222 对读);判据面「closed 外发消费目标=模态编排口」语义保持。**判定:不属削弱**。
- 卡② §15 零申报、卡③ §16 零申报——兑现成立(超出申报的删改零处)。
## 5. 非行为改动判定与证据链
**卡①**:装配序(八步名序、add_child 序、赋值序)逐字不变;42 条连接语句一一对应;LAYER_CONTRACT 19 项逐字迁驻;move_child 单口由 V1d 27 文件扫描绿+grep 复证(全 presentation 仅 ui_registry :84/:98 两处调用,views/ui_kit.gd:819 为批前既有、不在 diff);main._ready 仅插入 `ui = UiRegistry.new()` 一行于 _build_ui 之前;`_build_modal_flow` 注入语句序与基线逐字同(flow 实例改随 UiModals._init 构造=实现决定 1,注入时点不变)。
**卡②**:成员迁移与改指——roll_round_actions/settle_if_due 逐字迁移对读成立;grant_segment 三 mark=同点同增量;encounter/attunement 词替换的三处字符串键保护(实现决定 5)grep 复证(behavior_roll 前置流名 "encounter" 字面在位);treasure_inventory 注入时序(宿主构造后 :520)不变。
**卡③**:收尾四语句迁移=同帧同相位(对拍 V2 运行态序列+V5 报告逐字承载,自跑绿);`_run_one_level` 零触碰。
**证据链**:
1. 卡③ T0 三重证据在实现报告 §5 在案:215da315 提交信息明载「tune_sim 运行态收尾归还 run」(审计直读提交信息复证)+两面实跑读数;审计自跑两面(wd8 套件+ui_tune_probe)复证现行全绿——前提消化链条完整。
2. 卡③ v1.1 重裁凭据:卡 v1.1 状态行+§15 裁决记录(2026-10-30 停卡重裁三点)在案。
3. 卡①卡②实现决定记录(报告 §3 共 5+5 条)对照卡① §10 七条、卡② §17 五条白名单——白名单外事项(shot/fx_shot 纳入、layout_probe get 键、curio/confirm 漏列补改、flow 随容器构造、grant 第五处读、treasure_effects 五处直构、self 前缀、占位符保护)均有备案,无遗漏。
4. 闸凭据:receipt.json 现为 docs 域回执(9f1dda40 提交时 pre-commit 钩子生成,b27db010 时代,全绿);代码域末跑凭据=.gates 六件日志(smoke 15/0、system_test 69/0、static_scan ok、probe_gate 全绿、render_gate 全绿、unit 分片全绿),时间戳 06:49–06:54 恰落 b27db010(06:49:41 提交)与 9f1dda40(06:57:19 提交)之间——绑定终态代码(9f1dda40 只含报告文件)。
5. 红线:diff 只触 `game/`+`reports/` 两目录;零 `randomize()`/自建 RandomNumberGenerator;零触及 `design/`、`game/tests/README.md`、两份根流程清单。
## 6. 缺漏与例外(如实记录,不修)
**缺漏(记录级,不动判据)**:
1. **卡③实现决定记录缺位**:对拍驱动由卡 T2 的「先启动两形态、后分别 await」并行拓扑改为**串行驱动+相对帧偏移归一**(tune_sim_batch_parity_test.gd:145-162)——卡 §14 白名单六条不覆盖,应在实现报告「实现决定记录」节备案;实际只在提交 04783fae 信息中有案(理由=GDScript 协程动态调用强制 await、无并行启动形态+_init 时点 root 未挂树实测)。报告 §3 无卡③条目。实质判据未损(相对偏移+相邻差恒一仍承载「每步恰一帧+相位同点」,审计自跑绿)。
2. **main_overlay_flow.gd:4 头注陈旧指址**:注释仍写「全部开合走组合根模态单口(root._open_modal/_close_modal)」,两转发方法已退役、实际调用全改 `root.ui.modals.flow.open/close`——「指址须真」词面违例,行为无涉,批内漏改。
3. **卡②改指处数偏差记录偏轻**:grant_segment 实改 18 处与卡片「约 23」的 L2 偏差,实况数在报告 §2 V6 行在案但未入「实现决定记录」节(卡 §14 L2 要求记入该节)。
**例外(依据在案,不判红)**:
1. **V1d 扫描面口径**:实现为 DirAccess 平铺(res://presentation 顶层 27 个 .gd),不含 views/、scenes/ 子目录——与卡片字面 glob(`game/presentation/*.gd`)一致、较改前单文件只扩不缩;但「全 presentation 目录零第二落位点」按递归读法不成立:批前既有 `views/ui_kit.gd:819` 有一处 `body.move_child(...)`(视图内行排序、非层序落位;ui_kit.gd 不在本批 diff、归迭代 42 尾波清偿批在册债)。ui_registry.gd:3 头注「全仓唯一 move_child 点」沿袭旧 main.gd 注释口径、与该既有事实并存。若日后递归化扫描面,须先处置该行。
2. **回执被覆盖**:receipt.json 为 docs 域回执(报告提交钩子生成);代码域末跑以六件日志为凭(§5 第 4 条),与报告 §6「第三次全量域闸全绿、02/05/09 从基线红改善归绿」叙述吻合。
3. **`_finished` 成员写而不读仍保留**(tune_sim_controller.gd:26/:64/:88)——卡 §14 白名单 3 明示「零读者确认后可删」,保留属白名单内两可选择,键账只升 1(11/15 在阈内)。
4. **报告 row4 计数口径差**:「约 460 行机械改写」(报告 §1)与 784d581b「422 行」——统计口径差,不影响判据。
## 7. 审计自跑记录(独立复证清单)
| 项 | 结果 |
|---|---|
| `python tools/run_smoke.py` | PASS——15 项 0 失败 |
| `python tools/run_system_test.py` | PASS——69 项 0 失败(V1a/V1c/V2/V3a–V3i 全过) |
| `--only=source_guard --only=theme_projection` | 绿——V1d「presentation 27 文件…调用点=0」〔注册面 V1〕+V6 新串〔注册面 V2〕+theme 164 checks |
| `--only=settle_segments --only=round_flow_skill_pool --only=roll_multiplier --only=treasure_effects` | 4 套件绿——V1 两断言、V2 五实例、V4 四断言、V5 一断言(check_quiet 静默通过=零失败) |
| `--only=pacing_queue --only=modal_flow` | 双绿 |
| `--only=tune_sim_batch_parity --only=standee_fx_sweep` | 双绿——对拍 10 断言〔测速 V1–V5〕+wd8 三断言 |
| `res://probe/ui_tune_probe.tscn`(headless) | PASS——⑤ 守卫环预算内退出+输出四串+全链路通过 |
| `python tools/gdstyle_gate.py` | exit 0——命中 7 全基线内、零新违规;tune_sim 裸键不命中 |
| grep:tune_sim 循环/await | 循环 0;代码 await 仅 run() :69 一处 |
| grep:49 名旧一级地址残留 | 代码级 0(仅注释级 3 处) |
| 成员数 | main.gd 49→15;battle_orchestrator 37→15;容器 3/9/5/14 |
| 断言计数对账 | 22 文件零减少、5 增(+4/+1/+2/+1/+10) |
| diff 归一化对账 | 88 处非平凡行对全部落表 A/C/D+已记录决定 |
## 8. 总结论
**通过(可合并)。** 三卡对照表 21 行全部核到落点且判据绑定面当轮实跑成立;测试削弱零发现;三卡「非行为改动」判定在代码级对读与实跑两面成立;证据链(卡③ T0 三重证据、v1.1 重裁、卡①卡②决定记录、闸日志)在案。缺漏三项(卡③决定记录缺位、main_overlay_flow.gd:4 陈旧头注、卡②计数记录偏轻)与例外四项均属记录/注释级,不触行为零变化、判据绑定与验收闭合;建议随批末收口由实现侧补记(补记动作归收口段,不由本审计代作)。gdstyle 基线 refresh(--force)仍属用户人工遗留义务(反哺点 7 在案)。
@@ -1,55 +0,0 @@
# 停机呈报:棋盘格边长口径收口批(迭代 46 卡C)——L3 #2 实板可读面不达标
> 日期:2026-10-31 · 呈报人:迭代 46 实现会话(iter 技能执行中)
> 接收方:待办清单条目「棋盘格边长三方取值不一致——待扩板定档处置(2026-10-06 登记)」
> 性质:实现段零裁断——需求卡片预设停机点触发(需求卡片-棋盘格边长口径收口批-2026-10-30.md §9 异常分级 L3 第 2 条),停该卡呈报退回上游,等用户裁决。
## 一、触发了什么
需求卡片 §7.3 T2 规定探针新增「实板可用面积下 13/14 板格边长推定」断言:以探针实读 `board_view.size` 代入算式单点 `BoardView._cell_for(n, size)`,`< 30px`(battle.md 可读下限)即记问题。§9 L3 第 2 条预设:实板可用面积代入 13/14 后 < 30 = 产品面问题,**停卡呈报,禁调低下限、禁换样本凑绿**。
当轮真实跑批实测(worktree iter46,种子 42,两档视口):
| 视口档 | board_view.size(实板可用面积) | L1 实测格边 | 13×13 推定 | 14×14 推定 |
|---|---|---|---|---|
| 基座 1280×800 | (1022.0, 454.0) | 40px ✓ | 30px(恰达标) | **28px < 30 ✗** |
| 16:9 1920×1080 | (1662.0, 734.0) | 46px(钳制顶格) | 46px ✓ | 46px ✓ |
代入算式复核(1280 档):`min(1022−12−8, 454−32) = 422`;`(422 − 13×2) / 14 = 28.28 → floor 28` → 钳制 [26,46] 内 → 28px。**14×14 板在基座档的实板格边长低于 battle.md「可读下限 30px」**。
## 二、事实定性(这不是本批制造的回归)
1. 算式逐位未动(卡C 行为零变化,单元四档冒烟 74 checks 全绿——结构钳制 [26,46] 面全过)。
2. 28px 是**存量事实**:现行生产公式对 14×14 板(board_gen.tres:L3 depth 9–13)在基座档一向算出 28px;本批新增的推定断言只是首次把它量出来。
3. battle.md 算例表的「14×14 → 30px」按「可用高 486px」推算,而实机 D 列结构给出 454px——卡片 §2.8 已登记该偏差(「实机可用面积与算例不同源」),本读数即该偏差的实测落点。
4. 同样数据下 13×13=30 恰好达标,仅 14×14 一档越线下。
## 三、分歧点与两种以上读法
**分歧点**:battle.md「可读下限 30px」(:144)的适用域——是否按视口档/板型分级适用。
- **读法甲(全域硬下限)**:30px 对一切视口档×板型组合生效 → 14×14 板在基座档不达标=产品缺陷,需要设计动作(改布局可用面积/改板型表/缩 14×14 适用域)。
- **读法乙(按档分级)**:30px 下限以 1920 档为守卫面(推定断言只判 1080 档),基座档按实测算例记录(battle.md 算例本标注「随布局与板型变化,不是契约值」)→ 推定断言判据域改判 1080 档,基座档记录实测 28px 不下断言。
- 两读法都属设计裁决(owner 文档 battle.md 的判据域修订),**实现段无权自裁**——读法乙虽不是「调低下限」(30 数值不动),但改变断言的适用域,同样超出卡片明列范围。
## 四、建议案(供裁决,禁代裁)
1. **建议主案=拆批**:迭代 46 以卡A(换图系七件批)+卡B(名字行提档与地台色合并批)先行合回——两卡已收口、代码域闸全绿(回执 45b53d68,commit 45b53d68 后另有 S9/S7 修正与卡B 提交);卡C 停摆退回写卡段,待 30px 下限适用域裁决后重立卡编入后续迭代。拆批合回前置=roadmap 迭代 46 行与待办清单条目状态换代(归文档批,本批禁写)。
2. **裁决后的卡C 重写方向**(按所选读法):
- 读法甲:重写卡范围收窄为「算式单点+门槛 36→30+四档冒烟+13 板推定」,14×14 不达标另立缺陷条目走设计段(布局或板型表动作)。
- 读法乙:卡C 原范围保留,推定断言判据域改「1080 档 ≥30」+基座档实测记录句;battle.md 反哺点补「下限适用域分级」条。
3. **卡C 已完成的可保留面**(worktree iter46 未提交改动,停摆卡不提交——随裁决处置):`board_view.gd` 算式单点提取 `_cell_for`(等价性已证:board_gen_reward_test 62→74 checks 全绿)、`layout_probe.gd` 门槛 36→30 与推定断言、`board_gen_reward_test.gd` 四档扩样。三件改动行为零变化,裁决后可直接复用。
## 五、待办清单条目状态回退+缺口补记(拟稿——落笔归上游段/用户)
条目「棋盘格边长三方取值不一致——待扩板定档处置(2026-10-06 登记,来源=批次移交)」:
- **状态**(现「已写卡+已编迭代 46」)→ 回退拟稿:`已写卡(卡C 停摆退回——L3 #2 实板可读面不达标)`。
- **缺口补记拟稿**:`缺口:14×14 板基座档(1280×800)实板格边 28px 低于 battle.md 可读下限 30px 的适用域待设计裁决——1280 档实板可用面积 (1022,454)→28px、1080 档 (1662,734)→46px;13×13 两档均达标(30/46)。裁决点=读法甲(全域硬下限→产品缺陷走设计动作)vs 读法乙(下限按视口档分级→断言判据域改 1080 档)。裁决后重写卡C(算式单点/门槛对齐/四档冒烟三件已验可复用)。`
## 六、本批实况速览
- 卡A 换图系双基座七件批:**收口**(T0–T8 全落,--code 闸 7 闸全绿)。
- 卡B 站桩名字行提档与地台色合并批:**收口**(26 checks 绿,golden 三张 0.00% 留痕)。
- 卡C 棋盘格边长口径收口批:**停摆**(T0 完成、T1–T3 改动已验未提交、T4 未走)——本呈报。
- 迭代合并:**阻塞**,等本呈报裁决(拆批合回 A+B,或卡C 闭合后整体合回)。
@@ -1,21 +0,0 @@
# grilling 复核——站桩名字行提档与地台色合并批需求卡片(2026-10-31)
> 接收方:reports/需求卡片-站桩名字行提档与地台色合并批-2026-10-31.md(v1.0→v1.1)。复核方=独立子代理对抗审查(未参与写卡;Godot 4.7.2 console 版实测断言写法)。本件属中间文档,随批退役。
## Findings 与处置(五条全落 v1.1)
| # | 级别 | 发现 | 处置(落卡位置) |
|---|---|---|---|
| 1 | 阻断 | V11 断言 `UiKit.get_script().get_script_constant_map()` 实测 parse error(类引用直调非静态函数不合法);机制本身可靠(实测枚举 186 键含目标常量) | T2 断言载体改 `load("res://presentation/views/ui_kit.gd").get_script_constant_map()`,依据随句注明(§7.3) |
| 2 | 阻断 | 五取值点中三处宽度测量点零断言——漏改测量点时牌宽按 12px 计、文字溢素底牌,全断言仍绿 | V10 增第三断言=计数锚 `body_src.count("UiKit.FS_CAPTION") == 1`(改后仅剩 :114 消散提示一处),三测量点强制换代(§7.2/§8 行 1) |
| 3 | 阻断 | 绘制点改指只有 grep 反证(旧名消失)无正证(落成错值也绿,golden 重锚还会冻结错值) | V11/V12 补三处绘制点源码锚正证:顶缘线 `ped.size.x, 2.0), UiKit.BRICK, true`、口沿 `FACADE_HIGHLIGHT_PX), UiKit.BRICK, true`、描边 `UiKit.PLAZA_EDGE`(§7.3/§8 行 3/4);grep 降为反证补充 |
| 4 | 建议 | §8 首句「6 行对应完成定义第 1–6 条」对应关系不成立(第 5 条无行) | 首句改「第 1–4、6 条;第 5 条经 T3 核对步承载」(§8 首句) |
| 5 | 建议 | `run_all.gd:191` 套件注释「V5–V9」增 V10–V12 后成死注,但该文件不在结构图 | §6 文件结构图补 run_all.gd 行(注释换代,非行为改动)+T2 增注释换代步(§7.3) |
## 无发现审点
步骤扫描(每步一动作一可核查结果)/名字一致性(PLAZA_EDGE、name_font_size、V10–V12 逐字一致且与盘面无冲突;V10 锚串与顺位徽标行无碰撞)/落位与复用(`Color8(76` 全仓零命中、`#4C4038` 仅探针注释非 token——新常量论证成立)/预算与契约(probe 增字典键非成员,gdstyle 三触面零基线键,S13 零新增预期成立;golden 重锚工具缺省只动板面三张,与禁触清单兼容)/估时(0.5 天与触面相称)。
## 结论
三阻断两建议全部落卡后 **PASS**——卡片 v1.1 成立,可交迭代编排段。
@@ -0,0 +1,85 @@
# grilling 复核报告——零豁免五卡(2026-10-29,主会话委派)
状态行:对抗式复核完成。方法=逐卡过审点 A–J(验收三问/对照表两端/静态判据形态/能力行锚定/预算实数/拆分纪律/编队碰撞/行为改动完备性/裁决一致性/可施工性),判据=req-card 必备结构 15 节+code-conventions §1.1+test-conventions §8;证据=五卡 file:line 抽验约 90 处(命中率高,个别 1 行漂移属 T0 兜住范围)+五份设计文档口径核对+architecture v1.25+能力清单逐行核对+gdstyle_baseline.txt 键账清点+迭代 42 在飞两卡触面比对+pipeline_gate 全绿。只读复核,未改任何卡与既有文件。
## 卡一:gdstyle 尾波补件批(board_hover+breakpoint_store)
**裁决:有条件成立**(四项编入前须补,均为编辑级补丁,不动拆件方案本身)。
逐条发现:
1. 【应修】卡面 §7 编队注记——「与呈现层状态件批同代时**推荐**其先行」,而呈现层状态件批 §3 已把同一约束写死为「已裁……本批先于其 board_hover 半边合回」的硬义务。同一约束两卡一软一硬,编排段按弱措辞排卡会让 hover 拆件落在旧 u.st 写入面上、board_view 改址对账表(单格篇 §5.1)随之失配。改法:board_hover 半边改成硬前置句「呈现层状态件批合回后施工」;breakpoint_store 半边明示不受此限、可独立先行。
2. 【应修】§8 V1 判据绑定面写「格件 **st** 边框/点迹字段」——本卡自认编排在状态件批之后,届时该读面已改 u.face.*(ui_input_probe 四处改址为状态件批 V4 行),判据面描述按施工时点必陈旧。改法:改写为「格件状态件边框/点迹字段(状态件批合回后=u.face.*)」。
3. 【应修】§3 现状事实「公开入口 `resume_adventure`(:94)」行号错——实查 :94 是 start_adventure,resume_adventure 在 adventure_runner.gd:141。改法:改 :141(T0 重锚虽会兜住,现状事实按规约须代码级准确)。
4. 【应修】§13 预算节「预算 2(_hover/_last_click)**+引用束成员**」「预算 6……**+引用束**」未给引用束成员数,复核门无法对账 ≤15。按 §7/T2 构造面推算 board_hover 约 7(2+cells/minesweeper/diggable+2 Callable)、breakpoint_store 约 14(6+db/rng/主角账三件/curio/stop/bank/loadout)——均达标但后者贴顶。改法:把引用束成员逐一列名计数写进预算表。
5. 【可接受申报】V1 零漂移证明全压既有断言面;悬停 11 函数族中 chord 双击首遇锚(board_view.gd:475 _detect_chord)在「棋盘悬停反馈」三语义行与 ui_click_probe 之外无显式断言,属既有覆盖缺口。零行为改动批不为既有缺口补测不违规,实现报告宜记一句该缺口。
6. 核验通过项:A 两行对照表三问可答(真实入口/判据面/能力行齐);C 对照表零静态行;E 键账全对(board_view 32 实数清点吻合、−2=约30;adventure_runner 28 清点吻合、−6=约22;断点域 6 成员与 9 函数族 file:line 全命中;BREAKPOINT_FIELDS :539 起、breakpoint_resume_test.gd:185 命中);F 拆分职责语句在位、_r0 留宿主防凑计数袋论证成立(board_view.gd:238/:296/:563 三消费方实查);G 与迭代 42 的 board_view 触面已声明、编入待其合回;I 与裁决①②⑤一致(D5 留债、禁落豁免登记、_r0 留宿主);J 一步一动作、无 TBD 类句式。
## 卡二:组合根注册面批(main 49→15)
**裁决:有条件成立**(一项 blocker 级必改+两项应修;机检与数字面全过,方案本身成立)。
逐条发现:
1. 【blocker】§1 编队注记「与迭代 42……**无文件交叠(main.gd 与探针不在其触面)**」与盘面矛盾——在飞并排卡 `reports/需求卡片-level_runner商店委托层拆除-2026-10-29.md` 文件清单明确含 game/presentation/main.gd(改址 1 处)、main_adventure_flow.gd(6 处)、main_overlay_flow.gd(2 处),三者全在本卡触面集(main.gd+三流程件)。用户裁决④要求五卡编队碰撞约束与迭代 42 自洽,此句是失实声明,编排段靠它排卡。改法:改为「与迭代 42 商店委托层拆除卡在 main.gd/main_adventure_flow/main_overlay_flow 三文件有改址点交叠——待其合回后开工,T0 映射表生成时并核其改址点」;T0 步骤同步补一句。
2. 【应修】§8 对照表第 2 行与第 11 行内含静态判据(S13 键账对账「main.gd 实测 15」、grep 残留=0)——姊妹卡三/四/五均已把静态键账判据按 test-conventions §8.4 出口移出对照表(在域口径段申报),本卡两行在表内带静态成分,形态不一致。改法:静态部分移入 §8 域口径静态申报段,行内只留行为主证(双宿主摘要/全量闸回执)。
3. 【应修】转发壳清点漏一件:main.gd:516 `main._flush_row_queue()`(纯转发 `_row_pacer.flush()`,消费方 pacing_queue_test.gd:103+main 内部两处注记)不在「七别名+六转发方法」清单——_row_pacer 迁 ui.screens 后该 Middle Man 壳归宿未声明,与本批净消灭转发壳的方向不一致。改法:表 C/表 D 补一行(退役并改址消费方,或写明保留理由)。
4. 【可接受申报】V4(探针批量改址)与 V10(render_gate)的能力行锚取九探针中单点代表行(棋盘悬停反馈/站桩敌人呈现),语义为最小可得锚且未逐行披露该局限。建议 §8 域口径补一句「探针/渲染行能力锚取代表行」。
5. 核验通过项:A 十一行全齐;E 数字全对平——main.gd 49 个 var 实数清点吻合(grep ^var 恰 49)、49=28 迁(表 A 9+5+14)+14 留(表 B)+7 消灭(表 C)+1 新增=15;四新件预算(2/0/0/1 公开方法、3/9/5/14 成员)与 §7.2 接口块逐名一致;LAYER_CONTRACT :39 起、六转发方法 :156/:161/:282/:285/:288/:292、别名七件行号全命中;smoke_boot 六处 get()=4 改 2 留逐字吻合;pacing_queue_test :108/:132/:147/:149、source_guard V1d :69-77、theme_projection V6 :724-725、system_test V1c/V2 :94-109 全命中;D 能力行六名全在 game/tests/README.md 且受影响行核对成立;F §12 复用排除论证(ModalFlow/ModalStack/ui_assembler/run_scope 逐一否决+ConfigDB 三容器先例)充分;唯一面实查成立(game/presentation/ 下四名未建、仅 ui_assembler 在册);I 与裁决①③一致(零豁免、注销句、净消灭);J 估时 3–4 日在冻结线内、步骤全部可核查。pipeline_gate 机检 13 卡全过。
## 卡三:战斗编排归约批(RoundCycle+BattleFacts,38→15)
**裁决:有条件成立**(一项应修算术错;其余全过,是五卡中证据密度最高的一张)。
逐条发现:
1. 【应修】§4 红线句内部算术矛盾:「已迁 **22** 成员声明随迁即删(**21** 迁两件+treasure_inventory 退役+_hero_atk 退役)」——21+2=23≠22。实数=迁两件 22(BattleFacts 15+RoundCycle 7)+退役 2=删声明 24 项;轴丙后宿主 37→13 旧留+2 新=15,账平。architecture v1.25 两行写「收编 7+14=21」与本卡 BattleFacts 15 名单的 1 名口径差,已由 §6 反哺点通道(「批末成员数实测值与在册数字出入」)覆盖,但本句数字须改正以免实现期对账混乱。改法:改「22 迁两件+2 退役」。
2. 【可接受申报】encounter 归 BattleFacts 最弱格标注诚实:设计文档 §6 白纸黑字「它也是本方案最弱的一格」+两条备选砍路(nest_preview_count 解冻/_reward_economy 经授予件中转)均判更差;卡内 L3② 给出实现期证伪的停卡出口、§4 给出 15/15 贴顶与 SealLedger 扩容阀、设计 §8 险点 8 处理了 BoardInstaller bundle 键 encounter 传 _facts.encounter 的同引用零冲突——无隐瞒。
3. 核验通过项:A V0–V6 七行齐(V2 复位边界险点单独配断言、判据绑两快照同键值恒等);E 类变量 38 实数清点吻合(:37-85+:223-227 逐名)、基线两条类级键与「零函数级键」实查一致、保留 15 名单/两新件 8+15 成员账全平;file:line 抽验约 20 处全命中(treasure_inventory setter :48-52、外部注入 level_runner.gd:520、宿主四读 :111/:203/:450/:858、grant_segment :370-371、combat_segment :56、settle_segments_test :27 接线断言原文、static_scan S8 :317/S7 :359 九文件清单、run_all_gates PARITY 清量 battle_orchestrator :169、五段构造/三闸/摇号/复位块/完美谓词行号);C 静态判据(键账收敛、S7/S8 增行)已按 §8.4 出口移出对照表在域口径段申报;D 十三处能力行全部在 README 在场且语义对题(V0 锚「回放确定性」为精确锚);F 两新件职责语句+集体身份在位(「持段件者不能是被持者」「事实账不是授予物」)、已否决切法留档;G 编队前置「迭代 42 合回之前禁开工」覆盖与在飞两卡在 battle_orchestrator/level_runner/static_scan.sh/treasure_effects_test 等的全部触面交叠;I 与裁决①③⑤一致;J 估时 2.5–3.75 对设计 §12 的 2–3 日给了上探理由,PARITY 批内实跑须用户点头不占估时。
## 卡四:呈现层状态件批(单格两域件+站桩两件,30→10/19→10)
**裁决:有条件成立**(一项应修编队漏声明;潜伏红处置路径成立,成员拆分账五卡中最难算、已全对平)。
逐条发现:
1. 【应修】与卡二在 game/probe/ui_input_probe.gd 的**同文件交叠两卡均未声明**:组合根注册面批改该探针的 main.X 地址面(:34-43 等约 867 处散布之一),本批改四处 u.face.* 直读(:234-235/:243-244/:250/:374-379)——行位不相交但同文件,两卡又是同一条目(零豁免五键清偿批四卡)的同代候选,编排段靠编队声明排卡,此漏会制造二次 T0 重锚。改法:两卡编队注记互写一句(本卡补「与组合根注册面批在 ui_input_probe.gd 有触面交叠,先后施工各自 T0 重锚」,卡二同步)。
2. 【可接受申报】潜伏红 T0 定谳路径诚实:四处直读实查确在探针源码、迭代 41 已把 hl_visible/hl_color/dot_visible/mutation_mark 迁入内嵌类 _CellPaintState(board_cell_unit.gd:27 起),宿主 Node2D 无同名属性,「Invalid get index」推演成立;卡内预设 L3③「实跑全绿=证伪设计前提=停卡」的出口——未把推断当已证事实写死,定谳义务落在 T0 实跑。
3. 【可接受申报】V4 能力行锚「棋盘悬停反馈」含 case⑭ 变异角标(非悬停三语义)的最小拉伸;同一探针同一入口,可接受。
4. 核验通过项:A 四行齐(V1/V2 golden 主证、V3 演出链、V4 悬停金框/禁入红框/路径点迹/变异角标四处断言面);E 成员账全对平——内嵌类 27 名实数清点吻合、基座 12(11+_owner)+叠加 13(12+_owner)+宿主上收 edge/cell/glow_group+原位 glyph/glyph_color/plate/fog_state/_glow_layer+base/face=宿主 10;站桩真实 25=vitals 11 名+motion 10 名+原 _owner+3 计数器、宿主 10=5 冻结 var+st+mo+3 计数器;31/33 全文件声明数与 :26-122/:125-143、:23-59/:62-68 分区实查一致;九常量 :12-23 逐字命中;C 静态键账判据已按出口移出对照表(§9 域口径段申报,五卡中形态最规范);D 六处能力行全在场且语义对题;F 四新件职责语句+逐件排除论证(TilePalette/HeroSprite/BoardWorld/battle_stage_view/StatusSlotRow)在位,迷雾留宿主的「唯一不产生跨件回引」论证成立;G 与迭代 42 的 board_view 五段改型耦合声明完整(T0 前置+「先于尾波补件批 board_hover 半边合回」反向义务);gdstyle 截断缺陷红线(禁利用截断口径降数、禁把 _portrait_tex 当削减目标)与裁决一致;golden 三张禁换锚禁重制。
## 卡五:测速循环批(信号步进状态机+双实现对拍)
**裁决:有条件成立**(一项应修能力行悬置;对拍方案与申报形态是五卡中最完整的)。
逐条发现:
1. 【应修】能力行锚语义错位且专属行悬置无主:三行对照表能力列锚「站桩敌人呈现与结算演出落点」,该行语义是站桩呈现与终局演出(README 旅程段六,系统列=战斗表现),与本批测量面(批量模拟逐帧步进/运行态贯穿/报告注入)不同域;卡内自承「测量面专属能力行=写卡段后续处理」——但写本卡的会话**就是**写卡段,2026-10-29「当场入表」规则下该行应随本卡增行(真实入口=debug_overlay press_simulate_for_probe() 按钮 pressed 信号链→run(n);代表用例=standee_fx_sweep_test.gd:_init〔wd8〕+tune_sim_batch_parity_test.gd:_init),增行后本列改锚。悬置写法让义务无承载主体、批末无人对账。
2. 【可接受申报】行为改动申报完备性成立:全件 68 行实读核对——:67-68 确为每局置假(潜伏红本体),静态矛盾推演(drv.seen=[true,false]、探针守卫环同段退出四串全红)与源码逐句吻合;改形其余面(常驻连接/is_connected 守卫/首步同步/n=0 同步收尾/_step_frame else 先断连)核为非行为改动;「_finished 若零读者可删」方向是删不是留,不违禁为机检保留成员条款。
3. 【可接受申报】脚本错误中断路径差异按 §8.4 出口声明缺口(协程死亡静默停摆 vs 确定性错误逐帧重试),T3 文档化义务在位,未伪装成可证判据;两形态测量批遇错都整批作废、同级不同形的论证成立。
4. 核验通过项:A 三行齐且真实入口真实(wd8 假驱动回调内读 is_running()、探针真实按钮信号链);E 键账预算表逐规则落卡、成员 5+6=11(信号计入则 12)账与 T1 名单吻合、_run_one_level 5 参临界持平声明在位、改造后全文件零循环键消除逻辑成立(结构性免疫);file:line 全量命中(run :36-52、循环 await :50、FakePanel/FakeDriver、wd8 三断言与〔wd8〕尾缀、ui_tune_probe SIM_GUARD_FRAMES=1800 :16 与 :63-83 四串断言、debug_overlay is_running :77/set_sim_running :81/_sync_sim_button :107、main_debug_flow :72-77 不 await 形态与 :84 互查守卫、hud_presenter 空守卫与 maxi(1,n));C 静态判据与声明缺口均不入对照表;F 零拆出单元的「不拆理由」在位(步进机是私有运行机制、拆出命不出职责语句=凑计数袋,§8 引 code-conventions ②④);遗留 await 形态副本全仓唯一性+夹具不入四扫描面的声明经实查成立(基线 :15 唯一键、S8 九文件不含本件);G 与其余四卡及迭代 42 无产品码触面交集声明成立(run_all.gd manifest 潜在交叠已交编排段);I 与裁决③④⑤逐条一致(双实现对拍入批、收尾还原作为已申报行为改动、错误路径接受并文档化);J 估时 1–1.5 日合理,T0 定谳证据列为审计第③项必查项。
## 总表
| 卡 | 裁决 | blocker | 应修 | 可接受申报 |
|---|---|---|---|---|
| 卡一 尾波补件批 | 有条件成立 | 0 | 4 | 1 |
| 卡二 组合根注册面批 | 有条件成立 | 1 | 2 | 1 |
| 卡三 战斗编排归约批 | 有条件成立 | 0 | 1 | 1 |
| 卡四 呈现层状态件批 | 有条件成立 | 0 | 1(与卡二共担) | 2 |
| 卡五 测速循环批 | 有条件成立 | 0 | 1 | 2 |
全库 blocker 与应修清单(编排段放行前置):
- **blocker(卡二 §1)**:编队声明失实——「与迭代 42 无文件交叠(main.gd 不在其触面)」被在飞商店委托层拆除卡的文件清单(main.gd/main_adventure_flow/main_overlay_flow)直接证伪,须改写为如实交叠声明+开工前置。
- **应修(卡二+卡四,跨卡)**:ui_input_probe.gd 同文件触面交叠两卡编队注记均未声明,互写一句补齐。
- **应修(卡一 §7)**:board_hover 半边的状态件批先行约束从「推荐」升为硬前置,与卡四侧已裁义务对齐;breakpoint_store 半边明示可独立先行。
- **应修(卡一 §8)**:V1 判据绑定面「格件 st 边框/点迹字段」按施工时点改 u.face.* 口径。
- **应修(卡一 §3)**:resume_adventure 行号 :94 改 :141。
- **应修(卡一 §13)**:预算节引用束成员列名计数(board_hover 约 7、breakpoint_store 约 14)。
- **应修(卡二 §8)**:对照表第 2/11 行静态判据移入域口径申报段,与卡三/四/五形态统一。
- **应修(卡二 表 C/D)**:main._flush_row_queue(:516)转发壳归宿补声明(退役改址或保留理由)。
- **应修(卡三 §4)**:「已迁 22 成员(21 迁两件+2 退役)」算术改正为「22 迁两件+2 退役」。
- **应修(卡五 §6/§12)**:测量面专属能力行随本卡当场增入 game/tests/README.md 并改锚三行能力列,废「写卡段后续处理」悬置表述。
总体判断:五卡可以进编排段,但须先落上表一项 blocker 与九项应修——全部是编辑级补丁与声明修正,无一张需要推翻拆件方案或重做设计。证据面结论:五卡 file:line 抽验约 90 处命中(唯一硬伤=卡一处行号),键账与成员迁移账全部数平(含卡四最难的 27/25 内嵌类双 _owner 拆分),两处静态矛盾推演(卡四潜伏红、卡五每局置假)经源码逐句复核成立,与五项用户裁决无一冲突,机检 pipeline_gate 全绿。最大的真实风险不在卡内而在编队声明层:卡二对迭代 42 的无交叠声明失实、卡二与卡四未声明探针同文件交叠——这两处修正后,编排段才有可信的排卡依据。
@@ -1,208 +0,0 @@
# 审计:全库架构审查(2026-10-29)
> **性质**:设计讨论段过程稿(审计读数)。`game/` 全目录只读架构审查的发现清单与证据,作为写卡段、工程改动批与文档设计批的输入材料;结论被吸收进权威文档与修复批后按「吸收即死」退役。
> **范围**:core 44 件、presentation 71 件、data 24 schema + 19 表、sim 15 件、probe 19 件、tests 69 件、`tools/` 闸件。判据双轨=项目自有规范(`design/engineering/architecture/architecture.md` v1.24 + 五份工程规约)+ Godot 4.7 最佳实践。
> **方式**:分层依赖方向/数据管线/测试覆盖三路并行静态取证+机械 grep 复核。**零测试执行、零引擎运行、零闸执行**(测试两入口铁规),全部结论来自静态读盘;下文每条命中均给 文件:行号,抽查原文已核。
---
## 一、总评
分层骨架是健康的:core 纯逻辑(44 件里 37 件 `RefCounted`、3 件 `Resource`,`extends Node` 仅 4 个 Autoload)、Core 零 UI 八项判据全零命中、core 内 RNG 单点 100% 成立、字符串式信号连接全库 0 处、core 层函数体超 120 行零命中、19 表 ↔ 19 schema 一一对应零孤儿、无循环 preload。
**真正的风险不在分层,在三条写了却没闸守的纪律被实际破坏,外加三处守卫面缺口。**
1. 「玩法数值只存 `data/tables/`」被 18 处硬编码击穿,其中两处是玩家可见的提示文案数字。
2. `game/sim/` 与 `game/core/` 存在四组平行实现,直接威胁「模拟读数 = 游戏真实数值」这一前提。
3. RNG 单点、类型闸、质量闸、结算禁 await 的扫描面都止步于 core/presentation(部分只扫 9 文件显式清单),sim / probe / tests 三层几乎不受约束。
另有封装面(结算段类直取编排器私有成员)与文档漂移(架构文档登记件与盘上实件不一致)两类低危问题。
---
## 二、健康面(已逐条核,零问题)
| 判据 | 结果 | 证据口径 |
|---|---|---|
| Core 零 UI | 零命中 | `res://presentation`、`Control`/`Node2D` 系、`.tscn`、`$` 节点语法、`get_parent()` 在 core 全域零命中;core 内 `get_node` 仅 2 处且均为 Autoload 取依赖 |
| RNG 单点(core 内) | 100% 合规 | 15 处 `open_stream` + 1 处 `pure_stream` 全经 RngService;`RandomNumberGenerator.new()` 在 core 内仅出现在 `rng_service.gd` 自身 |
| 字符串式信号连接 | 全库 0 处 | 正则 `\.connect\(\s*"` 全 `game/` 零命中 |
| core 层 await | 零命中 | 4 处匹配全在文件头注释里自述「零 await」 |
| core 超长函数 | 零命中 | 函数体 >120 行只在 presentation(`board_view._paint_cell` 142 行、`ui_kit.danger_button` 122 行) |
| 表 ↔ schema | 一一对应 | 19 `.tres` ↔ 19 顶层 schema,零孤儿表、零缺 schema;24 schema 全被消费 |
| resolver / cross_validator | 非测试专用 | 二者都在 `ConfigDb._ready → load_tables()` 产品路径真实运行 |
| 循环 preload | 零命中 | 全仓依赖图 DFS 仅 2 个自环,均在注释文本里 |
| 静态闸防空转自检 | 已内置 | S1–S13 各规则自带扫描面文件数为零即判红 |
---
## 三、P0 — 破坏既有纪律,已有实证
### 3.1 数值单一事实源被击穿(架构原则 2:代码零玩法数值字面量)
判据来自 `design/engineering/architecture/architecture.md` 架构原则 2 与 `code-conventions.md` 数值类硬纪律。下表分两类:**A 类=用户可观测的玩法数值写死在代码,直接违规**;**B 类=自标「机制结构常量/产出约束」,是否该入表属待裁,不计违规**。
#### A 类(18 处,直接违规)
| # | 位置 | 写死的值 | 表内真值 / 影响 |
|---|---|---|---|
| 1 | `game/presentation/main.gd:787` | 提示文案「弃图刷新需 8」 | `action_economy.tres` 的 `rap_refresh_cost`。紧邻 783 行是正确读表的,文案另写一份 |
| 2 | `game/presentation/main.gd:790` | 提示文案「每轮 2 次」 | 同表 `refresh_cap_per_round`。表改了玩家看到的数字不改 |
| 3 | `game/core/battle_orchestrator.gd:883` | GP 掉落乘数 `1.5` | 表内无此项;代码注释自认「乘数 provisional 150%」 |
| 4 | `game/core/node_map_generator.gd:380` | 岔口分支概率 `0.35` | `level_gen_params` 表内无此项 |
| 5 | `game/core/node_map_generator.gd:455` | rest/reward 排列起始骰 `0.5` | 表内无此项 |
| 6 | `game/core/node_map_generator.gd:361` | 岔口目标数上限 `24` | 表内无此项 |
| 7 | `game/core/effect_engine.gd:146` | 天赋「守」盾值 `1` | 表内无此项 |
| 8 | `game/core/effect_engine.gd:152` | 天赋「锋」伤害减半 `50` | 表内无此项 |
| 9 | `game/core/effect_engine.gd:151/154/161/164` | 天赋每关限次 `2` | 表内无此项 |
| 10 | `game/core/damage_controller.gd:435` | 直伤分量默认 `50`(百分比) | 表内无此项,`h.get("value", 50)` 兜底 |
| 11 | `game/core/battle_orchestrator.gd:507` | 变体成包大小下界 `2` | 只有上界读表 `variation.pack_max` |
| 12 | `game/core/settlement/combat_segment.gd:64` | 连击分段默认 `cap=2` / `divisor=3` | 表内无此项 |
| 13 | `game/presentation/playtest_logger.gd:16` | `ap_per_round := 8` | 与 `action_economy.tres` 同名值逐字重复 |
| 14 | `game/core/config_db_resolver.gd:118-119` | clamp 域 `0.1` / `10.0` | 与 `difficulty_table.gd` 的 `MULT_MIN`/`MULT_MAX` 重复但另写一份字面量 |
| 15 | `game/core/curio_deck.gd:98` | 令牌 cap 兜底 `99` | `config_db_cross_validator.gd:91` 注释写 cap ∈ [1,99],schema 无定义 |
| 16 | `game/core/shop_session.gd:155` | 货架位 `3` | 表内无此项 |
| 17 | `game/sim/level_autoplay.gd:29-34` | 失误三概率 `0.10` / `0.05` / `0.10` | 直接决定 MC 读数,属模拟口径的一部分 |
| 18 | `game/sim/level_autoplay.gd:410-428` | 选路评分 `30/5/10/80/20` | 同上 |
**最危险的是 #1 #2**:玩家会直接看到错误数字,且没有任何闸能发现「表值与文案数字不一致」。
**同族不一致(顺带查出)**:同调位上限在 `core/attunement.gd:14` 与 `core/meta_progression.gd:476` 写 `range(1, 4)`(上限 3),而 `presentation/views/hero_info_panel_view.gd:61/175` 写 `for i in 4`(4 槽)——两处口径已不一致。
#### B 类(自标结构常量,是否入表待裁,不计违规)
| 位置 | 常量 | 代码自述 |
|---|---|---|
| `game/core/node_map_generator.gd:12` | `MAX_WIDTH := 4` | 注释自标「产出约束·宽度=分叉生长」 |
| `game/core/action_economy.gd:14` | `CHARGE_LAYER_CAP := 3` | 注释自标「机制结构常量,非玩法表值」 |
| `game/core/board_data.gd:9` | `SPAWN_AREA_CELLS := 9` | 被 `data/schemas/board_gen_table.gd:77/106/107` 反向引用参与表校验——core 常量成了 data 侧校验的输入 |
| `game/core/node_map_generator.gd:83-94` | 层深下限 6、出口数域 [1,3]、岔口去路域 2/3 | 与 `level_gen_params.gd` 的域校验平行,两份域定义 |
---
### 3.2 sim 与 core 平行实现(四组)
`game/sim/` 15 件里 10 件是纯驱动器/采集器(调用 core,不重算规则),但有四组平行实现,其中两组直接导致「模拟读数 ≠ 游戏真实数值」。
| 组 | core 侧 | sim 侧 | 后果 |
|---|---|---|---|
| ① 扫雷推理引擎 | `board_generator.gd:175/204/217/234/249/265/286`(`measure_inferability` 族,输入含 `safe_set` oracle) | `auto_player.gd:114/154/181/188`(`_deduce` 族,输入 no-peek,且不做 0 格连锁算子) | 两边可推理率/卡死率不可直接换算。`auto_player.gd:80-83` 注释自认口径差异 |
| ② 伤害掷点期望 | `damage_math.gd` + `damage_controller.gd` 兑付管线 | `damage_probe.gd:196-201` 自建 `base_factor`/`rolled_base`/`floor` 取整顺序,只在末步复用 `pool_damage` | 探针的 ✓/✗ 比对基于自行重建的中间量 |
| ③ 档位排序与驱动循环 | `treasure_item_table.gd:44` 的 `TIER_RANK`;`sim/battle_driver.gd:17` 自称「驱动循环单点」 | `level_autoplay.gd:300-311` 另写一份档位排序;`level_autoplay.gd:521-575` 另写一份驱动循环(守卫阈值还不同:多出 `round_guard=60`、`rejects<3`) | 被声明为单点的东西存在第二份实现 |
| ④ 伪造表喂 core | 数值单一事实源 = `data/tables/*.tres` | `calibrate_boards.gd:14-19` 与 `experiment_density.gd:61-66` 用 `FakeDB` 伪造 `board_gen` 行喂 core 生成器 | 校准类读数绕开 SSOT(实验用途可理解,但无闸约束其扩散) |
---
## 四、P1 — 守卫覆盖缺口
### 4.1 RNG 单点纪律在 core 之外失守,且无闸
core 内干净,绕过点全在 core 之外:
| 层 | 位置 | 形态 | 是否被闸扫到 |
|---|---|---|---|
| presentation | `main.gd:914` | `randi()` 建种子,行内标 `rng-seed-exempt` | 扫到但被豁免标记排除 |
| probe | `ui_click_probe.gd:20` 等 8 处 | `RandomNumberGenerator.new()` | **不扫** |
| sim | `calibrate_boards.gd:54`、`experiment_density.gd:27`、`damage_probe.gd:274`、`level_autoplay.gd:388` | 自建 RNG + 显式定种 | **不扫** |
| tests | 3 处测试夹具 | 自建 RNG | **不扫** |
全部绕过点均显式定种、无 `randomize()`(全库零命中),确定性尚存;问题在于**没有任何闸防它扩散**——S1/S2 扫描面只有 `DIR_CORE` + `DIR_PRES`(`static_scan.sh:20-21, 88-91`)。
### 4.2 静态闸扫描面结构性缺口
`game/tests/static_scan.sh` 的 S1–S13 扫描面实况:
| 闸 | 扫描面 | 缺口 |
|---|---|---|
| S1/S2(RNG 单点) | core + presentation | sim / probe / tests 不扫 |
| S3(core 表加载单点) | core | — |
| S4(core 零引擎 UI 依赖) | core | — |
| S5(core 禁裸引 Autoload) | core | — |
| S6(core 信号禁内联 lambda) | core | — |
| S7(B1 编排唯一性) | core | 不管私有成员直取面(见 5.1) |
| S8(结算路径禁 await) | 9 文件显式清单 | 新增结算文件忘登记=静默不扫;缺位自检只防删改不防增 |
| S9(类型闸) | core + data + presentation | sim / probe / tests 不扫 |
| S13(gdstyle 质量闸) | core + data + presentation | 同上 |
| S11(术语禁用词)/S12(旧件残留) | game/ 全域 | 无缺口 |
净效果:**sim / probe / tests 三层除 S11/S12 外,零类型闸、零质量闸、零 RNG 闸、零 await 闸。**
### 4.3 S13 豁免常态化
三处豁免全落在体量最大、风险最高的文件上:
| 豁免对象 | 豁免内容 | 后果 |
|---|---|---|
| `core/battle_orchestrator.gd` | S13 全库单文件最大户,成员数阈值 15 豁免(实测键账 50→38 仍豁免) | 豁免后 S13 对它恒不约束,成员数再涨无感知 |
| `presentation/main.gd` | 46 个句柄成员 | 同上 |
| `presentation/tune_sim_controller.gd` | await 使用 | 同上 |
### 4.4 四个 core 文件零测试点名
判定口径:文件名与 `class_name` 在 `game/tests/` 全域 grep 均零命中。
| 文件 | 行数 | 职责 | 风险 |
|---|---|---|---|
| `core/attune_loadout.gd` | 117 | 同调配装件:装备中秘宝件对象集唯一所有者 | 有状态 |
| `core/battle_fx_host.gd` | 179 | 效果引擎宿主:fx 事件发射面、事实判定、AC/bonus 累积 | **有状态且在结算路径上** |
| `core/meta_state_store.gd` | 176 | 存档内元进度数据件(13 写口 + 6 只读投影) | **有状态且在存档路径上** |
| `core/slot_store.gd` | 189 | 存档槽位文件域件(挂载/激活/建删/摘要窥视) | 同上 |
`config_domain_combat` / `config_domain_run` / `config_domain_crossrun` 三个纯持有容器(零方法)零覆盖属可接受。
低覆盖(仅 1 个测试文件点名)另计:`hero_stats`、`skill_lottery`、`shop_session`、`curio_deck`。
---
## 五、P2 — 封装与漂移
### 5.1 settlement 五段类直读写编排器私有成员
`core/settlement/` 五段类作为「提取的方法对象」,直接读写主编排器的下划线私有成员 20+ 处:
- `combat_segment.gd:34/37` 写 `oc._damage.inject[...]`;`:52/53/58/77/78/80/89/91` 读 `oc._enemy_system.*`;`:123` 调 `oc._damage.flush()`
- `grant_segment.gd:96/121/151/178/229/289/333` 调 `oc._damage.open_ticket(...)`
- `aura_segment.gd:15/16` 调 `oc._emit_composition_effects(...)`;`decay_segment.gd:15` 调 `oc._status_effects.decay_round()`
GDScript 无编译期访问检查,私有成员改名不会有任何闸报错,只会静默断裂。S7 只管 B2/B3/B4 对外 API 符号收敛面,不管这个。
### 5.2 架构文档与代码漂移
| 文档位置 | 文档写的 | 盘上实况 |
|---|---|---|
| `architecture.md:110` | `core/hero_ledger.gd`「已实装」 | 该文件不存在;已拆为 `hero_stats.gd` / `gain_journal.gd` / `gp_wallet.gd` / `refresh_bank.gd` 四件。`tests/unit/core/hero_ledger_test.gd:171` 显式断言 `not FileAccess.file_exists("res://core/hero_ledger.gd")`,即代码层已把它当回归禁区 |
| `architecture.md:135` | `battle_orchestrator` 1313 行 / 50 成员 | 实际 1034 行(拆件后未回写) |
| `architecture.md` EC8 节 | 数据配置热重载能力(`set_reload_gate` 保护 `reload()`) | `ConfigDb.reload()` 全仓零调用方;且因走 `load()` 命中引擎资源缓存,即便调用也拿不到磁盘新值。门被 `battle_orchestrator.gd:295/861` 真实开合,但门后入口是死的 |
### 5.3 class_name 级双向依赖
`core/config_db.gd` → `data/schemas/board_gen_table.gd`(持有 `BoardGenTable` 实例)→ `core/board_data.gd:9`(取 `SPAWN_AREA_CELLS`)形成跨目录回边。双方均走 `class_name` 全局引用、未走 preload,不产生解析期死锁,但构成架构层面双向耦合。
同族:`core/node_map_generator.gd:10` 与 `data/schemas/level_table.gd` 各持一份 `NODE_TYPES` 词表(内容同、顺序不同)。
### 5.4 Autoload 形态不一致
四个 Autoload 里 `MetaProgression` 是唯一用 `get_node("/root/...")` 取依赖(`meta_progression.gd:26/28`)、唯一跨 Autoload 直调、唯一持 Node 引用的;另三个零交叉引用。注释说明是为绕 `--script` 模式 parse error,但与另外三个的构造注入形态不一致,且隐含 Autoload 加载顺序依赖(ConfigDB 须先 ready)。
---
## 六、待裁点
以下均需用户裁定,Agent 不代裁:
1. **A 类硬编码 18 处怎么修**——按改动四类归属,其中 `core/` 与 `presentation/` 的玩法数值入表属**需求改动**(写卡 + 编排),`sim/` 两处模拟口径常量属**工程改动**。两类不能混一批。
2. **B 类结构常量要不要入表**——`MAX_WIDTH` / `CHARGE_LAYER_CAP` / `SPAWN_AREA_CELLS` / `node_map_generator` 的域字面量四组,代码自标「非玩法表值」,但 `SPAWN_AREA_CELLS` 已被 data 侧校验反向引用,是否算玩法数值需裁。
3. **sim 平行实现的处置口径**——是收敛(sim 调 core 的推理与掷点)还是承认双口径并显式登记(避免读数混用)。四组里①②影响数值验证可信度,③④影响可维护性。
4. **闸面缺口补不补**——S1/S2/S9/S13 是否把 sim 纳入扫描面;S8 是否改成目录域而非 9 文件显式清单。
5. **S13 三处豁免的存废**——豁免已常态化到最大户文件上,是收回还是登记为长期例外。
6. **零测试点名的 4 个 core 文件**——补测试,还是登记豁免在册。
7. **文档漂移三处**——`architecture.md` 的 HeroLedger 登记行、battle_orchestrator 行数、EC8 热重载门表述,是否现在就按 doc-design 落回(纯文档面,主区直改)。
---
## 七、取证口径备注
- 全程只读,未跑测试、未跑引擎、未跑闸(测试两入口铁规)。
- 3.1 表 A 类 18 处中,#1 #2 #3 #4 #5 #6 #7 #8 #9 #10 #13 #14 #15 #17 逐条 `sed` 取原文核过;其余按同一 grep 口径判定。
- 「零测试点名」判定词 = 文件 basename 与 `class_name` 全称,检索面 `game/tests/**/*.gd`;被当作类型间接引用与有针对性断言已分开计数。
- `static_scan.sh` 扫描面结论来自脚本自身变量定义(`DIR_CORE` / `DIR_PRES` / `SCAN_DIRS`)与 S8 的 `S8_FILES` 显式清单,非推测。
@@ -1,126 +0,0 @@
# 工程改动报告——存量断言精简 C 档(2026-10-28)
**批性质**:工程改动(纯测试维护),代码面独立 worktree 批(`assert-slim-b2-20261028`)。验证项目覆盖逐条不变,断言静态站点收敛。
**输入合同**:待办清单「存量断言精简——验证内容不变下的断言收敛」余账②(C 档手写族改表驱动循环)+用户 2026-10-28 会话裁决「六组全批(推荐)」。
**对账基准**:`game/tests/验证集清单.md` 冻结册(基点 `b9260138`,1587 条静态调用点;本批只比对不改写)。
## 1. 判据线
沿用 A+B 批判据线:**同一读数面 + 同一输入集 + 谓词字面等价**(C 档是同一族的逐例手写断言改为表驱动循环,每旧例成为循环表的一行数据,标签串保留在数据里可 grep)。
与 A+B 的区别:A+B 是删并(旧站点消失、判据由承接者承担);C 档是**形态改造**——旧例全部保留为循环的一行,执行条数不变,只有静态 `check(` 调用点下降。失败定位由「独立断言行」改为「违例明细串」(表内每行仍输出自己的标签,附带期望/实际)。
## 2. 删并申报表(33 旧站点 → 7 新站点)
「旧序号」=冻结册序号;「旧站点」=冻结册行号(`file:line` 省略相同路径前缀)。六组逐一列出,处置列写明合并形态。
### C1 关卡生成参数负向族(11 → 1)· `game/tests/unit/data_config/level_gen_params_test.gd`
| 旧序号 | 旧站点 | 旧标签 | 新站点 | 处置 |
|---|---|---|---|---|
| #1221 | `_test_negative:72` | 合法三行域校验零错误(夹具自证)〔fv2〕 | `:107` | 表行 `cases[0]`(夹具自证行保留在表首) |
| #1222 | `_test_negative:75` | L1 出口=2 被拒(出口 L1 恒 1 已锁)〔fv2〕 | `:107` | 表行 `cases[1]` |
| #1223 | `_test_negative:78` | 配比合计 0.5 被拒(四类合计 1 已锁)〔fv2〕 | `:107` | 表行 `cases[2]` |
| #1224 | `_test_negative:81` | 层深 5<6 被拒(层深下限已锁)〔fv2〕 | `:107` | 表行 `cases[3]` |
| #1225 | `_test_negative:85` | 层深增幅倒挂被拒(递增且增幅变大)〔fv2〕 | `:107` | 表行 `cases[4]` |
| #1226 | `_test_negative:88` | 出口 4 越域 [1,3] 被拒〔fv2〕 | `:107` | 表行 `cases[5]` |
| #1227 | `_test_negative:92` | 岔口去路数 (2,4) 被拒(恒 2/3 已锁)〔fv2〕 | `:107` | 表行 `cases[6]` |
| #1228 | `_test_negative:97` | 字段键集非 ROW_KEYS 闭集被拒〔fv2〕 | `:107` | 表行 `cases[7]` |
| #1229 | `_test_negative:100` | 键重复行被拒〔fv2〕 | `:107` | 表行 `cases[8]` |
| #1230 | `_test_negative:102` | 战斗保底 -1 被拒(≥0)〔fv2〕 | `:107` | 表行 `cases[9]` |
| #1231 | `_test_negative:105` | 空表域校验零错误(合法态)〔fv2〕 | `:107` | 表行 `cases[10]` |
新站点标签模板 `域校验:%s(期望%s,实际%s)〔fv2〕`:`%s` 即旧标签原文(表内逐字保留),`期望/实际` 附违例明细串。
### C2 RNG 黄金向量族(8 → 1)· `game/tests/unit/data_config/rng_stream_boot_test.gd`
| 旧序号 | 旧站点 | 旧标签 | 新站点 | 处置 |
|---|---|---|---|---|
| #1239 | `_smoke_initialize:37` | 统一流向量 m=42 scope=0(=旧 board_gen scope0 连续性锚) | `:40` | `golden[0]`(循环标签补注 scope0 锚语义) |
| #1240 | `:38` | 统一流向量 m=42 scope=1 | `:40` | `golden[1]` |
| #1241 | `:39` | 统一流向量 m=42 scope=2 | `:40` | `golden[2]` |
| #1242 | `:40` | 统一流向量 m=42 scope=3 | `:40` | `golden[3]` |
| #1243 | `:41` | 统一流向量 m=42 scope=4 | `:40` | `golden[4]` |
| #1244 | `:42` | 统一流向量 m=42 scope=5 | `:40` | `golden[5]` |
| #1245 | `:43` | 统一流向量 m=42 scope=6 | `:40` | `golden[6]` |
| #1246 | `:44` | 统一流向量 m=42 scope=7 | `:40` | `golden[7]` |
黄金向量八值逐字不变;标签由逐行写死改为 `scope=%d` 循环变量,grep 锚 `统一流向量 m=42 scope=` 保留。
### C3a 奖励点头部禁词族(3 → 1)· `game/tests/unit/presentation/player_copy_sweep_test.gd`
| 旧序号 | 旧站点 | 旧标签 | 新站点 | 处置 |
|---|---|---|---|---|
| #1383 | `_sweep_narrator:59` | 奖励点头部零「同权重」旧话(u3 清零)〔wa4〕 | `:60` | 禁词表行「同权重」 |
| #1384 | `:60` | 奖励点头部零「同上限」旧话(u3 清零)〔wa4〕 | `:60` | 禁词表行「同上限」 |
| #1385 | `:61` | 奖励点头部零「提升池」旧话(u3 清零)〔wa4〕 | `:60` | 禁词表行「提升池」 |
标签模板 `奖励点头部零「%s」旧话(u3 清零)〔wa4〕`,禁词作参数,与旧标签逐字同形。
### C3b 图例封印行禁词族(2 → 1)· 同文件
| 旧序号 | 旧站点 | 旧标签 | 新站点 | 处置 |
|---|---|---|---|---|
| #1389 | `_sweep_legend:76` | 图例封印行零「插错」(u4 旗族遗留词干清零)〔wa5〕 | `:76` | 禁词表行「插错」 |
| #1390 | `:77` | 图例封印行零「挖雷」(u4 雷字清零)〔wa5〕 | `:76` | 禁词表行「挖雷」 |
标签模板 `图例封印行零「%s」〔wa5〕`;`seal_row` 取值表达式(`size > 2` 守卫)逐字保留在循环体内。
### C4 站桩蓄力置位四入参(4 → 1)· `game/tests/unit/presentation/standee_fx_sweep_test.gd`
| 旧序号 | 旧站点 | 旧标签 | 新站点 | 处置 |
|---|---|---|---|---|
| #1407 | `_init:95` | 蓄力技能(heavy)置 `_intent_charge=true`〔wd2〕 | `:103` | 入参表行 `["damage","heavy",true,…]` |
| #1408 | `:97` | 非蓄力攻击技(goblin_slash)零置位〔wd2〕 | `:103` | 入参表行 `["damage","goblin_slash",false,…]` |
| #1409 | `:99` | 增益系零置位〔wd2〕 | `:103` | 入参表行 `["buff","goblin_rage",false,…]` |
| #1410 | `:101` | 普攻零表示路径复位 `_intent_charge`〔wd2〕 | `:103` | 入参表行 `["damage","basic",false,…]` |
判定式 `s1._intent_charge == 期望` 与四旧例同谓词;`set_pending` 入参与旧例逐项相同。
### C5 字体字形集三组(3 → 1)· `game/tests/unit/presentation/ui_font_asset_test.gd`
| 旧序号 | 旧站点 | 旧标签 | 新站点 | 处置 |
|---|---|---|---|---|
| #1583 | `_init:18` | 中文字形在集(攻/雷/旗/封) | `:30` | 字形组「攻雷旗封」 |
| #1584 | `:20` | 中文字形在集(危——已开危险格字形换代前置,迭代36 u12/wa9) | `:30` | 字形组「危」 |
| #1585 | `:21` | ASCII/数字字形在集(A/0/%) | `:30` | 字形组「A0%」 |
判定由逐字 `has_char` 合取改为组内逐字扫描,标签附缺字明细(缺字集为空即绿)。
### C6 锻造工作间长剑/轻甲双行(2 → 1)· `game/tests/unit/presentation/forge_workbench_test.gd`
| 旧序号 | 旧站点 | 旧标签 | 新站点 | 处置 |
|---|---|---|---|---|
| #1336 | `_run:63` | 长剑行:购买钮「锻造 20」(0 级位几何价)+选中钮「当前」禁用〔锻造工坊批 V13〕 | `:64` | 行表 `["sword","长剑"]` |
| #1337 | `:66` | 轻甲行:购买钮「锻造 20」+选中钮「当前」禁用〔锻造工坊批 V13〕 | `:64` | 行表 `["light","轻甲"]` |
**谓词取并集申报**:旧 #1336 含 `not buy_btn.disabled` 与 `select_btn != null` 两子句、#1337 缺这两子句。合并后统一用 #1336 全谓词(**只增不减**,轻甲行增补 `select_btn != null` 与 `not buy_btn.disabled` 两子句)——已在用户裁决时呈报并随「六组全批」批准。标签统一为 `%s行:…(0 级位几何价)…`,两种行名均保留可 grep。
## 3. 件核
| 项 | 改前 | 改后 | 判据 |
|---|---|---|---|
| 六套件静态站点 | 33 | 7 | 冻结册逐行比对 |
| 全清单静态条数(`--diff`) | 1587 | **1561** | `python tools/extract_checks.py --diff game/tests/验证集清单.md`:消失 33/新增 7,与上表逐条对应 |
| 运行期条数(六套件) | 17/13/22/18/5/12 | 17/13/22/18/5/12 | 合并前后同值;`ui_font 5<6`、`forge 12<13` 的静态差为失败分支站点(装载失败/字体缺失 `Kit.check(…, false)`),绿跑不执行,改前即如此 |
| 套件全量回归 | — | 65 套件全绿 | `unit.log`:`[run_all] all green (65 suites)` |
| 全码域闸 | — | all_green | 回执 commit `fd6cf968`:domain=code、dirty_game=false;01/02/10 绿;09 存量红指纹 `8467b4588a20` 零新增;00/03/04/05/11 影响面选闸 SKIP(diff 全在 `game/tests/` 测量面) |
| 合并 | — | `87d241c1` | 合并后主区 `--editor --quit` 退出 0;`python tools/run_smoke.py` PASS(15 项检查,三硬闸全过) |
运行期条数不变+每个旧标签都在循环数据里逐字保留=**验证项目覆盖逐条不变**的直接证据;静态条数降 26=本批唯一预期变化。
## 4. 余账与去向
| 余账 | 处置 |
|---|---|
| 类别②(内部面断言被入口严格承载) | A+B 批实测 0 条,不再找 |
| C 档候选 | 六组全数执行,C 档本波清零;无剩余候选 |
| D 档四处(theme:215/217 × type_glow:148/150、level_shop_economy 现行图 vs 扩面段) | 2026-10-28 用户裁全保留,不属精简账 |
| 恒真与名实不符断言五条 | 判据缺陷另账 → 待办清单新登记「恒真与名实不符断言五条——判据缺陷修正」(`feat_vouchers:51`/`treasure_effects:263`/`level_shop_economy:593`/`:696`/`system_contracts:66-67`) |
| `Kit.check_quiet` 静态站点 407 个在提取器口径外 | → 待办清单新登记「断言提取器改版——覆盖 Kit.check_quiet 静默通道」 |
## 5. 纪律自检
- 无删断言、无放宽阈值、无缩小扫描面、无下层直调替换:33 条判据全部保留为循环表行,输入集与判定式逐条对应(C6 为谓词并集,已申报)。
- 无变异法、无撤销类取证;绿由保持断言复跑取得(整套件全绿)。
- 冻结册未动一字,`--diff` 差异面与申报表逐条对齐。
@@ -1,145 +0,0 @@
# 提案:弃图刷新系专长流派(双基座七件)——预案 v0.5(2026-10-31)
> **性质**:换图系设计提案与 GDD 修改清单。双基座七件结构已经用户终审;本文保留为后续实现与验收的参考件,不随 GDD 落文退役。
>
> **核心裁定**:流派先由基座专长改变资源来源与刷新价格,再由后续专长让成功刷新直接形成输出、生存与 GP 资源收益。所有效果都改变玩家的刷新决策,不把旧图探索进度折算成清图奖励。
>
> **结论行**:矿脉储能让付费挖格产 RAP,省力周转把刷新成本减半;两件基座允许叠加。崩壁冲击与蓄力周转把刷新变成输出,石层缓冲把刷新变成当轮全局受伤减免,坑道小憩把多次刷新累计成当轮恢复,矿道红利每次成功刷新固定给 1 GP。
---
## 0. 七件总表
| 层 | 显示名 | 效果 | 行为职责 |
|---|---|---|---|
| 基座 | 矿脉储能 | 每次受理的付费挖格额外获得 RAP | 持续挖图也能为刷新蓄能 |
| 基座 | 省力周转 | 弃图刷新的 RAP 成本减半 | 同一份 RAP 支撑更多刷新 |
| 输出 | 崩壁冲击 | 成功刷新后,本轮战斗段末对全体存活敌造成固定伤害 | 刷新成为进攻动作 |
| 输出 | 蓄力周转 | 每次成功刷新叠层,上限 3;本轮下一次主角攻击消费全部层数 | 连续刷新汇成单点爆发 |
| 生存 | 石层缓冲 | 本轮只要成功刷新过,主角每次受到伤害固定减少 2 点;不叠加 | 刷新成为当轮防御姿态 |
| 生存 | 坑道小憩 | 每次成功刷新累计 1 点恢复,上限 3;本轮授予段合计回血 | 用刷新换取恢复空间 |
| 资源 | 矿道红利 | 每次成功刷新固定获得 1 GP | 刷新动作自身带少量金币收益 |
---
## 1. 设计原则
1. **基座先改行为**:必须改变资源来源、动作成本、动作结算或动作关系,使偶尔止损的刷新成为可持续打法。
2. **后续收益围绕新行为**:输出、生存、资源件只在成功刷新后兑现,不做放进任何构筑都成立的泛用增益。
3. **双基座可叠加**:一件改 RAP 收入,一件改 RAP 支出;每轮刷新上限继续负责限频。
4. **无专长基线不变**:七件只给持有者增加规则;全局经济、清图奖励与刷新基础语义不改。
5. **临时生命值不做**:现有体系没有独立血量护盾,本流派不使用该概念;石层缓冲直接减少最终承伤。
---
## 2. 行为循环
无专长时:
```mermaid
flowchart LR
A[正常挖图] --> B[遇到坏图]
B --> C[停手攒 RAP]
C --> D[必要时刷新]
D --> A
```
拿到两件基座后:
```mermaid
flowchart LR
A[付费挖格] -->|矿脉储能| B[RAP 增长]
B -->|省力周转半价| C[成功刷新]
C --> D[崩壁冲击]
C --> E[蓄力周转]
C --> F[石层缓冲]
C --> G[坑道小憩]
C --> H[矿道红利]
C --> I[新图继续挖格]
```
玩家会同时比较:
- 还要不要继续挖旧图,还是现在刷新兑现崩壁冲击或矿道红利;
- 本轮承伤压力大时,是否用石层缓冲换一次全局减伤;
- 生命偏低时,是否通过多次刷新累计坑道小憩的恢复;
- 是否蓄满 3 层蓄力周转,把多次刷新集中成一次攻击;
- 刷新次数与 RAP 价格如何影响后续图推进。
---
## 3. 七件效果结构
### 3.1 矿脉储能
每次付费挖格被受理后,额外获得 1 RAP。连锁展开不逐格追加;封印、移动、刷新不产 RAP。
### 3.2 省力周转
刷新 RAP 成本固定为基线的 50%。它只改持有者的价格,不改全局基值,也不返 RAP。
### 3.3 崩壁冲击
每次成功刷新记录一次当轮事实。本轮战斗段末,所有存活敌人各受 2 点固定伤害;刷新瞬间不当场插入战斗结算。
### 3.4 蓄力周转
每次成功刷新叠 1 层,最多 3 层。本轮下一次主角攻击附加全部层数对应的攻击加成,消费后清零;战斗结束不跨战保留。
### 3.5 石层缓冲
每次成功刷新把当轮减伤状态置为生效。本轮主角每次受到伤害,在现行伤害下限之前固定减少 2 点;同一轮多次刷新不继续叠加。覆盖敌方攻击、危险格、错误封印资源格与地形造成的主角伤害。
### 3.6 坑道小憩
每次成功刷新累计 1 点恢复量,最多累计 3 点。本轮授予段一次性合计回复生命,不超过生命上限,随后清零。
### 3.7 矿道红利
每次成功刷新固定获得 1 GP。不按旧图探索进度折算,也不与清图奖励绑定。每轮刷新上限限制触发次数。
---
## 4. 与现行结算时序的衔接
- 刷新只结束挖掘动作的资源支出,不结束当前轮次,也不新增第六个结算段。
- 成功刷新后产生 `board_refreshed` 事实;刷新被拒绝时不产生事实。
- 崩壁冲击只先开伤害单,沿用现行案 C,在战斗段末结账。
- 石层缓冲订阅全局 `damage_taken`;该事件统一覆盖所有主角受伤路径。
- 坑道小憩和矿道红利用现有 GP/治疗兑付通道留痕。
- 刷新图仍不发清图奖励;正常清图支配性不变。
---
## 5. 防退化边界
- RAP 仍来自有限 AP,不能无限刷新。
- 刷新本身不返 RAP。
- 每轮刷新上限继续生效。
- 石层缓冲是固定减伤,不堆层、不产生零伤害。
- 坑道小憩恢复上限 3,不能靠无限刷新稳定续命。
- 矿道红利每次仅 1 GP,量级明显低于正常战斗掉落,不足以替代清图与探索收益。
- 不引入临时生命值,不改变棋盘信息规则。
---
## 6. 最终裁定记录
- D1:双基座允许叠加。
- D2:资源件改为每次成功刷新固定 1 GP,不采用探索进度回收清图奖励。
- D3:生存件改为全局固定减伤,不使用护盾或临时生命。
- D4:恢复量按当轮成功刷新次数累计,上限 3。
- D5:所有主角伤害统一经过 `damage_taken`,允许现有订阅该事件的专长覆盖面按字面扩展。
- D6:七件显示名采用矿脉储能/省力周转/崩壁冲击/蓄力周转/石层缓冲/坑道小憩/矿道红利。
- D7:其余数值与稀有度先按需求卡片 provisional 投值,出口人闸追认。
---
## 7. 后续参考
本文保留供需求卡片、实现验收与后续调参比对。换图系现行权威规则仍以四份 GDD为准:
- `design/gdd/systems/冒险循环/奇物.md`
- `design/gdd/systems/排雷循环/行动经济.md`
- `design/gdd/systems/战斗循环/战斗结算.md`
- `design/gdd/systems/战斗循环/地图战斗资源.md`
@@ -1,7 +1,6 @@
# 提案:营地场景图美术生成方案(渠道 · 分层 · 工作流 · 样张验收判据)
> 性质:设计讨论段过程稿(2026-10-22 美术方案讨论产出)。**只讨论生成方案,不出图、不写需求卡片、不改 `game/`、不编迭代**——美术线是用户自立批(铁律 2),方向稿与「过/不过」的目检结论由作者出。
> **现行口径指针(2026-10-30 作者裁定)**:分层张数与围墙归属已有新裁定——营地场景图 **10 张** = 背景层 `scene_camp_bg`(z0,不透明全幅:天空+远山+整片地面+门洞小路)+ 围墙层 `scene_camp_wall`(z1,透明底:横贯密排木桩墙+两根门柱,门洞留透明缺口)+ 八个物件层(布告板 z2/门扇 z3/木桩·锻炉·帐篷 z4/宝箱·笔记本 z5/篝火 z6)。**围墙已从背景层拆出、独立成层**;门洞小路画在背景层、由围墙门洞透明缺口透出。**现行坐标、提示词、验收与消费名的单一事实源 = `design/art/camp-scene-prompts.md` §2/§4、`art-bible.md` §6.2、`asset-path-map.md` §3、`art-assets-checklist.md` §3.5、`camp.md`**;本稿 §2.2 层表、§2.5 坐标草案、§4 消费常量表、§5 验收、§12 分层元素表所记的「8 张/背景层含围墙/门柱门洞画在背景层」为 2026-10-22 讨论当时口径,其推理留痕保留不改,执行以上列五份现行文档为准。
> 输入事实源:`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`。
> 待作者带的输入:①参照物(作者原话「后续找一下」)②渠道一句话裁定 ③每轮方向稿「过/不过」的目检结论。
@@ -1,46 +0,0 @@
# 盘点:验证与清单体系(阶段 0)
> 2026-10-28 · 服务待办清单「验证与清单体系整改——四方向分阶段推进」条
> 性质:过程件(吸收即死)——结论吸收进待办条目与阶段 1 设计文档后删除。
## 1. 结论
1. **验证集清单零机器闸依赖**:`tools/run_all_gates.sh`、hooks、五个项目技能均不引用它;规范性锚点只有 `design/engineering/test-conventions.md` §8.3 一处。退役不需要改闸、改钩子、改技能。
2. **测试名尾缀不是全量追溯键**:47 个有断言的文件中 19 个零尾缀(含三条 35 条以上断言的大套件)。能力清单只能按「能力→代表用例」建,不能要求逐断言尾缀。
3. **对照表与待办清单都有机器闸**:前者的列结构、后者的条目格式均由 `tools/pipeline_gate.py` 强制;这两处瘦身要动闸,属阶段 3/4,不是阶段 1 的顺手活。
4. **能力清单已有现成形态**:`game/tests/README.md` 的「集成旅程清单」5 行,扩面成本低;`repo_structure_audit.py` 不限制 `game/tests/` 下的 .md 文件名。
## 2. 依赖面盘点
| 件 | 消费方 | 机器闸依赖 | 退役/改动成本 |
|---|---|---|---|
| `game/tests/验证集清单.md` | test-conventions §8.3、待办清单 1 条、2 份过程报告、`tools/extract_checks.py` | 无 | 低:改 1 条规约+删文件 |
| `tools/extract_checks.py` | 无自动调用;手工生成/对账 | 无 | 可保留为审计工具,或随清单退役 |
| 改动—验收对照表 | req-card 技能、iter 技能、`pipeline_gate.check_ledger`(强制 5 列) | 有 | 中:规约+两技能+闸三处 |
| 待办清单 | `pipeline_gate`(格式全套)、`doc_ref_audit`、`doc_term_audit`、`repo_structure_audit`、各技能 | 有 | 低:正文压缩不触机检;新增「≤5 行」规则才动闸 |
| 独立验收审计 | iter 技能、req-card 技能、`pipeline_gate`(只查「验收审计」字样) | 有(字样) | 中:改抽样规则要动两技能+规约 |
| 集成旅程清单 | 无机器消费 | 无 | 低:直接扩面 |
## 3. 覆盖数据
- `game/tests/**/*.gd` 共 70 个文件;静态 `check(` 粗口径 1607 处(含 `test_kit` 定义行与 `smoke_boot` 等提取器口径外宿主),清单口径 1587 处。
- 标签尾缀〔…〕756 个(上限口径,一条标签一个)。
- 有断言的文件 47 个:28 个有尾缀,19 个零尾缀。
- 零尾缀大套件:`seal_polarity` 69、`variant_placement` 42、`roll_multiplier` 35、`cross_system_flow` 22、`damage_math` 21、`skill_unlock` 20、`type_glow` 20、`minesweeper_rules` 16、`system_contracts` 15。
- 静默收集通道 `check_quiet` 约 407 站点在提取口径外(既有备案,test-conventions §5 工具局限)。
## 4. 对四阶段的影响
| 阶段 | 盘点结论对它的约束 |
|---|---|
| 1 换尺子(A) | 先扩「集成旅程清单」到核心域;每行=能力|真实入口|代表用例|最后验证批次|缺口。退役验证集清单;`extract_checks.py` 去留在设计讨论裁 |
| 2 按新尺子精简(B) | 删并对象改为能力项;每项能力保留至少一个代表用例;不要求逐断言尾缀 |
| 3 调验收强度(C) | 对照表列与审计抽样一起改,触 `pipeline_gate`、req-card、iter 三处;不要与阶段 1 同批 |
| 4 文档减肥(D) | 待办正文压缩可直接做;「≤5 行」入闸需改 `pipeline_gate` |
## 5. 未决点(阶段 1 设计讨论)
1. 能力清单落点:`game/tests/README.md` 扩面,还是独立文件?
2. 能力项粒度与覆盖面:按哪些域切、预计多少行?
3. `tools/extract_checks.py` 去留:随清单退役,还是保留为审计工具?
4. 验证集清单退役时点:立即冻结,还是阶段 1 设计定稿后一并退役?
@@ -0,0 +1,322 @@
# 设计——单格绘制状态件拆分(board_cell_unit 类变量键真实清偿)
设计讨论段过程稿 v1.0——待主会话汇总裁决。
结论行:推荐「绘制层域两件案」——状态件按 _draw 既有的层域轴拆成两个独立文件的绘制域件(格面基座层件 12 成员/格面标识与叠加层件 13 成员),几何与微光子件面留宿主(10 成员),绘制命令随入参同件迁移,宿主 _draw 退为六步时序器;三文件各自类变量 10/12/13,全部低于阈值 15 且不依赖任何闸机口径漏洞。
---
## 1. 现状与两项关键发现
### 1.1 键账现状
- 涉案键:`game/presentation/views/board_cell_unit.gd|quality/max-class-variables = 30`(tools/gdstyle_baseline.txt,2026-10-29 重锚版)。阈值 15(gdstyle 默认值,tools/gdstyle.toml 不设数值阈值)。
- 源码实查(2026-10-29):全文件 33 个类级 var 声明=宿主 6+inner 状态件 `_CellPaintState` 27。闸实测 30(本会话对单文件实跑 gdstyle v0.4.0 复核)。
- 文件头注在案:状态件职责语句「单格绘制输入集」;探针直读冻结成员(glyph/fog_state/plate/glyph_color)与 `_glow_layer` 住宿主。
- 迭代 41 已把 `_draw` 拆成约 20 个分层私有函数——函数级键已清零,本设计只解决类变量 30 这一个键。
### 1.2 发现一:gdstyle 对 inner class 的计数不是均匀展平,是「首个 setter 截断」
主会话给的事实是「inner class 成员按宿主展平计数」。本会话实测修正:截断点在 inner class 内**第一个带 setter 的属性**。
| 文件 | 声明数(宿主+inner) | 闸实测 | 归因 |
|---|---|---|---|
| board_cell_unit.gd | 6+27=33 | 30 | 宿主 6+inner 第一个 setter(edge,30–35 行)之后的 24 个=30;setter 声明本身及其之前的 3 个(_owner/cell/edge)留在 inner 类一侧不进宿主账 |
| standee_body.gd | 6+25=31 | 19 | 宿主 6+inner 第一个 setter(_intent_scale,37–40 行)之后的 13 个=19 |
| board_view.gd(无 inner class) | 32 | 32 | 平面文件=声明数逐一全计 |
| main.gd(无 inner class) | 49 | 49 | 同上 |
四点全部精确吻合。推论三条:
1. 现行登记值 30 是截断口径的**欠估**——若 gdstyle 升级修掉该解析行为,同文件键跳到 33=恶化红。任何「调整 inner class 内成员顺序/把 setter 挪位置」的降数手法都是在利用解析缺陷,工具一升级即翻车,且属「为迎合机检保留无效形态」,禁。
2. 主会话「任何 inner class 重新分组都降不了数」的结论在截断口径下依然成立(重排不改总量级),且存在更深的坑——重排确实能改数(把首个 setter 挪到类尾=宿主账只剩 6),但那正是第 1 条禁的手法。
3. **唯一稳健出路=拆成独立文件**:平面文件口径=声明数逐一全计(board_view/main 两点实证),预测值即实数,不依赖闸机任何解析行为。
### 1.3 发现二:ui_input_probe 疑似潜伏红(迭代 41 合并遗留,须 T0 先证)
ui_input_probe.gd 有四处**绕过 st 直接读格件成员**的断言:case① `u1.hl_visible`/`u1.hl_color`(234–235 行)、case② `.hl_color`(243–244 行)、case③ `.dot_visible`(250 行)、case⑭ `.mutation_mark`(374–379 行)。这四个成员迭代 41 已随状态件迁入 `_CellPaintState`,而 GDScript 外部实例读不到 inner class 的成员(取索引=运行时脚本错误)。
时间线:探针末次全绿 2026-10-28 05:03(game/tests/.gates/probe_full.log)早于状态件合入 2026-10-29 01:37(三文件同秒 mtime=合并检出);基线注记「迭代 41 两卡特许直接合回未重跑代码域闸」。合入后探针未跑过,潜伏红未经证实也未经证伪。同批 standee(u4)作者对同类问题做了宿主侧出口(fx_sweep_counters 方法返回计数器字典),u3 未处理这四处直读。
处置(本设计的立场):**无论潜伏红真假,本设计的拆分都把探针直读面显式化**——hl_color/hl_visible/dot_visible/mutation_mark 落入格面标识与叠加层件,探针四处断言改址 `u.face.*`(对照表申报的探针改址,断言条件与期望值零变化);四个头注冻结成员(glyph/fog_state/plate/glyph_color)留宿主不动。T0 用一次 ui_input_probe 实跑证实或证伪潜伏红,结果记实现报告。
### 1.4 探针/测试直读面全清单(改址与保留的依据)
| 消费方 | 读什么 | 现路径 | 设计后路径 |
|---|---|---|---|
| ui_input_probe case④b⑪ | glyph | u.glyph | u.glyph(宿主冻结,不变) |
| ui_input_probe case⑮ | fog_state | u.fog_state | u.fog_state(宿主冻结,不变) |
| player_copy_sweep_test wa8 | plate/glyph_color | u.plate/u.glyph_color | 不变(宿主冻结) |
| ui_input_probe case①②③⑭ | hl_visible/hl_color/dot_visible/mutation_mark | u.X(已断——潜伏红) | u.face.X(探针改址四处) |
| board_view.cell_rect_probe:891 | edge | u.st.edge | u.edge(board_view 内部改址) |
| board_shot_probe/type_glow_shot_probe | 格矩形 | 经 cell_rect_probe | 不变(间接) |
其余状态件成员全仓零外部读方(本会话 grep 全量复核)。
---
## 2. 现状成员全列(33 个)
写入方全部在 board_view.gd(唯一写方文件);行号为 2026-10-29 实查,实现批 T0 重核。setter→重绘语义列=该成员 setter 的现行副作用(无 setter=普通赋值不重绘)。
### 2.1 宿主 6 个
| 成员 | 类型 | 重绘语义 | 写入方 | 读取方 | 绘制消费层 |
|---|---|---|---|---|---|
| st | _CellPaintState 聚合 | — | 宿主 _init:147 | 全部绘制函数经 st.X | 载体 |
| glyph | String | setter→queue_redraw | _paint_cell:667 | _draw_glyph_layer:200/205、_draw_fog_memory:344 | 字形层+迷雾记忆态(探针冻结) |
| glyph_color | Color(UiKit.INK) | setter→queue_redraw | _paint_cell:668/674 | _draw_glyph_layer:205 | 字形层(探针冻结) |
| plate | bool | 无 setter | _paint_cell:675 | **绘制侧零消费**(_draw_digit_plate 由 glyph 非空无条件触发,plate 不参与判据);读方仅 player_copy_sweep_test:138 | 无(探针冻结成员,禁删禁接线——接线即行为变化) |
| fog_state | int | 守卫 setter→queue_redraw | _paint_cell:734/736 | _draw_fog_layer:247 | 迷雾层(探针冻结) |
| _glow_layer | Node2D 子件 | — | _sync_glow_layer:407–412 | edge/badge_glyph 两 setter、_sync_glow_layer | 微光子件(头注在案住宿主) |
### 2.2 状态件 27 个
| 成员 | 类型 | 重绘语义 | 写入方(board_view) | 读取方 | 绘制消费层 |
|---|---|---|---|---|---|
| _owner | Node2D 回引 | — | 宿主 _init:147 | 各 setter 内部 | — |
| cell | Vector2i | 无 setter | rebuild:250 | **全仓零读方** | 无(诊断观测面,待裁点 3) |
| edge | float | setter→glow setup+queue_redraw | set_cell_area:204、rebuild:251;读 _paint_cell:704、cell_rect_probe:891 | 全部层 | 全层(rect 尺寸基准) |
| bg_sb | StyleBoxFlat | 无 setter | _paint_cell:666 | _draw_base_layer:174、_draw_contact_or_fallback:187、_draw_bevel:314 | 基座层 |
| contact_bands | Array[int] | 无 setter | _apply_contact_bands:804 | _draw_contact_bands:271 | 接触带 |
| contact_corners | Array[int] | 无 setter | :805 | :279 | 接触带 |
| contact_col | Color | 无 setter | _process 呼吸:780/787、_apply_contact_bands:810/816 | _draw_contact_or_fallback:183、_draw_contact_bands:278、_draw_contact_corner:293–305 | 接触带 |
| outline_sides | Array[int] | 无 setter | _paint_cell:676(assign)/:700(append) | _draw_base_layer:166、_draw_outline_sides:257 | 描边 |
| facade_south | bool | setter→queue_redraw | _paint_cell:677/690;读 :696 | _draw_south_facade:352 | 南立面 |
| proj_band | float | setter→queue_redraw | _paint_cell:678/704 | _draw_north_projection:367 | 地面投影 |
| badge_glyph | String | setter→glow mask+queue_redraw | _paint_cell:719/726 | _draw_glyph_layer:206–210、_sync_glow_layer:413 | 徽章 |
| dot_visible | bool | setter→queue_redraw | 路径预览:549/554 | _draw_overlay_layers:230 | 叠加层(探针直读 case③) |
| hl_visible | bool | setter→queue_redraw | 悬停:512/517/521/525/534 | :233 | 叠加层(探针直读 case①) |
| hl_color | Color | setter→queue_redraw | :513/518/522/526 | :235 | 叠加层(探针直读 case①②) |
| font | Font | 无 setter | set_world_font:185、rebuild:260 | _draw_glyph:392、_draw_badge:418 | 字形/徽章/迷雾记忆 |
| bevel | float | setter→queue_redraw | rebuild:253 | _draw_bevel:312–321 | 倒角 |
| tex_base | Texture2D | 无 setter | _paint_cell:665 | _draw_base_layer:161、_draw_fog_memory:341 | 基座+迷雾记忆 |
| tex_mutation | Texture2D | 无 setter | 无(素材槽位恒 null) | _draw_glyph_layer:197 | 纹带槽 |
| tex_glyph | Texture2D | 无 setter | 无(槽位) | :202 | 数字槽 |
| tex_badge | Texture2D | 无 setter | 无(槽位) | :207 | 徽章槽 |
| tex_seal | Texture2D | 守卫 setter→queue_redraw | _paint_cell:614/618 | :212 | 封印槽 |
| tex_facade | Texture2D | 无 setter | _paint_cell:679/709 | _draw_e_facade:380–386 | E 格墙面 |
| facade_strip | bool | setter→queue_redraw | _paint_cell:680/708 | :380 | E 格墙面 |
| treasure_mark | String | 守卫 setter→queue_redraw | _paint_cell:713 | _draw_mutation_marks:326 | 变异标记 |
| mutation_mark | String | 守卫 setter→queue_redraw | _paint_cell:723/725 | :330 | 变异标记(探针直读 case⑭) |
| glow_group | int | 守卫 setter→_owner._sync_glow_layer() | _paint_cell:727、_sync_glow_to_units:768 | _sync_glow_layer:404/412 | 微光子件 |
| removed_dim | bool | setter→queue_redraw | _paint_cell:737 | _draw_overlay_layers:239 | 退色层 |
---
## 3. 方案形态——三条路的评估
### 3.1 路 A:状态件升格独立文件×N(推荐,取「绘制域件」形态)
按 _draw 已有的层域轴切。迭代 41 拆函数时已经沿这条轴走了(基座/字形/叠加/迷雾/描边/接触带/倒角……),本设计把同一条轴从函数级升到类级:**每个件=一个绘制层的入参+该层的绘制命令**。件有行为(draw 方法族+setter 重绘语义)、有职责语句、单一变化原因=该层的视觉规格(art-bible 对应条款族),满足 code-conventions §1.1 全部五条拆分判据与 §1.2「功能=类」。这是对迭代 41「被动数据袋」否决的正面回答:成员不再是「剩下的装一起」,而是「这一层画什么、怎么画」的完整领域单元。
细化两个子形态:
- **A2 绘制命令随迁(推荐)**:件的 draw 方法持有绘制命令本体,宿主 _draw 退为时序器。真内聚(状态+行为同件);宿主从 423 行缩到约 150 行,退离 §1.1 的 400 行审视线。
- **A1 纯入参件(淘汰)**:件只装数据,绘制函数留宿主。宿主仍有约 20 个绘制函数经 st 间接取值,件本质=把一个被动数据袋拆成两个被动数据袋,迭代 41 的否决理由原样复活;§1.1-① 立不住。
### 3.2 路 B:成员真实削减(淘汰为主出路,保留两处微收割)
要降到 15 需削 18 个成员,而可削的只有:
- `cell`:全仓零读方(写入仅 rebuild 一处)。可删,零行为变化(待裁点 3)。
- `plate`:绘制侧零消费,**但**是探针冻结成员(player_copy_sweep_test wa8 直读)——禁删;给它接上绘制判据反而改变 golden 现状(「人」回退格会少画牌),禁。
- tex_mutation/tex_glyph/tex_badge 三槽位:从未被写入但被 _draw 消费(elif 程序化回退路径),是 art-bible §8.2 在册素材槽位——结构承载,非无效成员,留。
削减上限 1–2 个,差 16 个以上,**单独不可达**。上移 board_view 方向被堵死:board_view 类变量 32 已按尾波卡 D5 裁豁免终局(键永久基线内、禁再恶化),上移任何成员都构成禁再恶化的恶化。
### 3.3 路 A3:整体搬成一个大状态件文件(淘汰)
状态件 24–27 个成员整体独立成文件,新文件自身 24–27>15=基线外新键——任务简报预警的陷阱,实测确认。拆是必须的,问题只是切几刀、沿什么轴。
### 3.4 路 C:重绘回引形态三选(随 A2 定案)
| 形态 | 判定 |
|---|---|
| **_owner 直引(推荐,现状形态)** | Node 持 RefCounted 成员、RefCounted 持 Node 回引——Node 引用不参与引用计数,**无环无泄漏**(现行 inner class 同款,先例在役)。setter 语句逐字保形,零新契约。Godot 官方判据下 RefCounted 值对象持宿主回引是常规形态。 |
| Callable 注入 | 淘汰。edge/badge_glyph/glow_group 三个 setter 的副作用不止 queue_redraw(glow 层 setup/badge mask/子件同步),一个 Callable 表达不了,得注两三个=每件多 1–2 成员+setter 体改写=语义面重写而非迁移。 |
| 信号 | 淘汰。Godot 信号同步派发、时序等价,但守卫式 setter(tex_seal/treasure_mark/mutation_mark/fog_state 的判重)与 glow 副作用都得改写成发射+宿主分发,新增每信号一行的 §2.1 成文义务,换不来任何行为收益。 |
| 弱引用 | 淘汰。解的是不存在的环引用问题,白白加 is_instance_valid 守卫复杂度。 |
---
## 4. 拆分定案(推荐案 A2 两件案)
### 4.1 总账
| 文件 | 类变量(全计) | 构成 |
|---|---|---|
| board_cell_unit.gd(宿主) | **10** | edge/cell/glow_group/glyph/glyph_color/plate/fog_state/_glow_layer/base/face |
| cell_base_layer.gd(新) | **12** | _owner/bg_sb/contact_bands/contact_corners/contact_col/outline_sides/facade_south/proj_band/bevel/tex_base/tex_facade/facade_strip |
| cell_mark_overlay.gd(新) | **13** | _owner/badge_glyph/dot_visible/hl_visible/hl_color/font/tex_mutation/tex_glyph/tex_badge/tex_seal/treasure_mark/mutation_mark/removed_dim |
对账:原 33 声明=新 10+12+13=35;差额 2=每件各持一个 _owner(原仅一个)。edge/cell/glow_group 上收宿主的理由:edge 是格件自身几何且其 setter 驱动宿主自有 _glow_layer(收编后 setter 体少两处跨对象回引);glow_group 驱动微光子件生命周期(加/撤子节点是 Node 职责,RefCounted 件做不了);cell 是格件身份。三者上收后,跨对象回引只剩「件→宿主 queue_redraw/glow mask」这一类,与头注「setter 触发宿主重绘语义经 _owner 回引保持逐字」完全同形。
### 4.2 件 A:cell_base_layer.gd(格面基座层绘制件)
- 落点:`game/presentation/views/cell_base_layer.gd`;extends **RefCounted**(godot-master 判据:瞬态逻辑/数据容器用 RefCounted,Resource 是给可序列化、要进 Inspector 的数据——绘制入参每拍重写、永不落盘,Resource 只带来共享默认值陷阱与序列化包袱);无 class_name(类名缓存面纪律,同宿主与 cell_type_glow_layer 先例),经宿主 preload 引用。
- 职责语句:格面基座层绘制域——底面/描边/高墙立面/地面投影/接触带微光/顶面倒角的全部绘制入参与绘制命令。
- 单一变化原因:art-bible 基座层视觉规格(§1.2 叠层序/§3.2 接触带/§8.5 结构归程序/v3.5 冻结①立面条款族)——瓦片、立面、投影、微光的画法变了改本件,不触字形与迷雾。
- 成员:上表 4.1 行所列 12 个;类型与默认值逐字继承,四个 setter(facade_south/proj_band/bevel/facade_strip)体逐字(_owner.queue_redraw())。
- 绘制命令:现宿主九个私有函数随迁——_draw_base_layer/_draw_outline_sides/_draw_south_facade/_draw_north_projection/_draw_e_facade/_draw_contact_or_fallback/_draw_contact_bands/_draw_contact_corner/_draw_bevel——逐字搬运,三处机械改写:`st.X`→裸成员名、`draw_X(...)`→`canvas.draw_X(...)`、`st.edge`→`rect.size.x`;公开入口一个 `draw_base(canvas: CanvasItem, rect: Rect2)`,其余私有。九函数现役零超标键(基线无其函数级键),搬运不改行数与分支=零新函数级键。
- 常量随迁:FACADE_HIGHLIGHT_PX/FACADE_NEAR_FRAC/FACADE_FAR_FRAC/FACADE_NEAR_COL/FACADE_FAR_COL/PROJECTION_NEAR_COL/PROJECTION_MID_COL/PROJECTION_EDGE_COL/E_FACADE_FRAC 九个 D/E 档常量(本会话 grep 实查全仓零外部引用,宿主头注「绘制侧单点」句随迁改写)。UiKit.E_FACADE_FOOT_COL 是 UiKit 自己的成员,不动。
- 素材槽位 tex_base 例外消费:迷雾记忆态画底纹(宿主 _draw_fog_memory)读 base.tex_base——公开成员读,单向、成文于宿主头注。
### 4.3 件 B:cell_mark_overlay.gd(格面标识与顶层叠加绘制件)
- 落点:`game/presentation/views/cell_mark_overlay.gd`;extends RefCounted;无 class_name。
- 职责语句:格面标识与顶层叠加绘制域——变异标记/数字色牌与字形/奖励徽章/封印/路径点迹/焦点高亮/中立移除退色的全部绘制入参与绘制命令。
- 单一变化原因:art-bible 标识与叠加层视觉规格(冻结④色牌/徽章金字/真视红框/悬停高亮/退色降档条款族)——「格面上标什么记号」变了改本件,不触底面与迷雾。
- 成员:上表 4.1 行所列 13 个;八个守卫/非守卫 setter 体逐字(含 badge_glyph 的 glow mask 回引 `_owner._glow_layer`——头注在案的回引语义原样保留)。
- 绘制命令:现宿主六个私有函数随迁——_draw_mutation_marks/_draw_glyph_layer/_draw_digit_plate/_draw_glyph/_draw_badge+_draw_overlay_layers 的 dot/hl/removed 三段。字形文字与色(glyph/glyph_color)是宿主冻结成员,作**参数**传入(`draw_glyph_layer(canvas, rect, glyph, glyph_color)`,4 参≤5);文字渲染单点化为本件公开方法 `draw_centered_text(canvas, rect, text, color, font_size)`(5 参合规),宿主迷雾记忆态复用它画记忆墨数字——零复制。
- 拆出两个绘制入口的原因:迷雾(fog_state 宿主冻结成员)在原 _draw_overlay_layers 内部夹在 hl 与 removed 之间,宿主时序器在两入口之间插雾层——见 §6。
### 4.4 宿主保留面(10 成员)
- 职责语句:被动绘制壳——绘制时序器+视野迷雾域(fog_state 冻结成员+记忆态换装)+微光子件生命周期(_glow_layer/glow_group/_sync_glow_layer)+格件几何(edge/cell)+探针冻结面(glyph/glyph_color/plate)。
- 单一变化原因:迷雾规格(art-bible §6.5)与格件节点生命周期。迷雾居基座与标识两件之上、又读件 A 的 tex_base 与件 B 的字体渲染——把它留在宿主是三域中唯一不产生跨件回引的落点。
- 头注改写要点(S10 口径 ≤8 行、无日期、无链接):状态件句改为两件句;「探针直读冻结成员」清单照旧(glyph/fog_state/plate/glyph_color+_glow_layer);新增一句「hl_color/hl_visible/dot_visible/mutation_mark 探针读 u.face.*」。
### 4.5 宿主 _init 与建件
```
const _BASE_LAYER := preload("res://presentation/views/cell_base_layer.gd")
const _MARK_OVERLAY := preload("res://presentation/views/cell_mark_overlay.gd")
func _init() -> void:
base = _BASE_LAYER.new(self)
face = _MARK_OVERLAY.new(self)
```
件侧 `func _init(owner: Node2D) -> void: _owner = owner`(S9 R3 对 _init 参数豁免——构造注入面形态自由)。每格三对象(Node2D+两 RefCounted)与现状每格两对象同量级;尾波卡 T1 的 `_build_cell_unit` 构建器里仍只有一处 `_CELL_UNIT.new()`,件在宿主 _init 内自建,不触发 allocation-in-loop 新键(该规则扫循环体内的 .new() 文本,构建器函数体不在循环体内)。
### 4.6 类型闸与头注义务
两个新件全量类型标注(S9 R1/R2/R3 同尺度);文件头 `##` 注释 ≤8 行、零日期、零链接、零变更叙事(S10);每件头注写职责语句与 _owner 回引语义(§2.1 精神——回引不是跨类信号,无信号成文义务)。
---
## 5. setter→重绘语义零变化论证(写入路径逐点对账)
原则:全部 setter 体逐字搬家或原位不动;改址只改 board_view 侧赋值表达式的路径段。queue_redraw 本身合帧(同帧多次申请一次重绘),时序逐字=写入点顺序不变。
### 5.1 board_view 写入面改址对照(行号 2026-10-29,T0 重核)
| 现写点 | 新写点 | 语义 |
|---|---|---|
| u.st.edge(:204/:251 写;:704/:891 读) | u.edge | 宿主 setter 体:原 `_owner._glow_layer`→`_glow_layer`、`_owner.queue_redraw()`→`queue_redraw()`——glow setup+重绘的执行序逐字等价(语句同、对象同、时机同) |
| u.st.glow_group(:727/:768) | u.glow_group | 守卫 setter 调 _sync_glow_layer()(原经 _owner 转发,现直调——同一函数同一时机) |
| u.st.cell(:250) | u.cell(或随待裁点 3 删除) | 无 setter,纯数据 |
| u.st.bg_sb(:666) | u.base.bg_sb | 无 setter |
| u.st.tex_base(:665) | u.base.tex_base | 无 setter |
| u.st.outline_sides(:676 assign/:700 append) | u.base.outline_sides | 无 setter;**assign 保持数组引用语义**——件内成员同为一处 Array[int],引用不变 |
| u.st.facade_south(:677/:690 写;:696 读) | u.base.facade_south | setter→queue_redraw 逐字;双写触发两次申请=现状同形 |
| u.st.proj_band(:678/:704) | u.base.proj_band | 同上 |
| u.st.tex_facade(:679/:709) | u.base.tex_facade | 无 setter |
| u.st.facade_strip(:680/:708) | u.base.facade_strip | setter→queue_redraw 逐字 |
| u.st.contact_bands/corners(:804/:805) | u.base.contact_* | 无 setter(整组引用换新) |
| u.st.contact_col(:780/:787/:810/:816) | u.base.contact_col | 无 setter(_process 逐拍呼吸色) |
| u.st.bevel(:253) | u.base.bevel | setter→queue_redraw 逐字 |
| u.st.badge_glyph(:719/:726) | u.face.badge_glyph | setter:`_owner._glow_layer` mask+queue_redraw 逐字(回引体原样) |
| u.st.dot_visible(:549/:554) | u.face.dot_visible | setter→queue_redraw 逐字 |
| u.st.hl_visible/hl_color(:512–526/:534) | u.face.hl_* | setter→queue_redraw 逐字 |
| u.st.tex_mutation/tex_glyph/tex_badge | u.face.tex_* | 无 setter |
| u.st.tex_seal(:614/:618) | u.face.tex_seal | 守卫 setter 逐字(判重防覆盖语义是 case④b 回归断言的守护对象,禁动) |
| u.st.treasure_mark/mutation_mark(:713/:723/:725) | u.face.*_mark | 守卫 setter 逐字 |
| u.st.removed_dim(:737) | u.face.removed_dim | setter→queue_redraw 逐字 |
| u.st.font(:185/:260) | u.face.font | 无 setter |
| u.glyph/u.glyph_color/u.plate/u.fog_state | 不变 | 宿主冻结面 |
| u.queue_redraw()(:738 终写) | 不变 | paint 尾部全格重绘申请原样 |
### 5.2 宿主内消费改址
- _sync_glow_layer:st.glow_group→glow_group、st.edge→edge、st.badge_glyph→face.badge_glyph(公开成员读);setup/set_badge_mask 调用序逐字。
- _draw_fog_memory:st.tex_base→base.tex_base;字形重画改调 face.draw_centered_text(self, rect, glyph, UiKit.FOG_MEMORY_INK, maxi(18, int(ceil(edge * 0.5))))——同公式同字号(§7.4 冻结式)。
- cell_rect_probe:u.st.edge→u.edge。
---
## 6. 绘制命令序零变化论证(golden 判据本体)
新宿主 _draw=六步时序器,命令序与现行四函数调用树**逐命令等价**:
```
func _draw() -> void:
var rect := Rect2(Vector2.ZERO, Vector2(edge, edge))
base.draw_base(self, rect) # 原青 _draw_base_layer 整树(含描边/立面/投影/接触带/倒角与其补画序)
face.draw_marks(self, rect) # 原青 _draw_mutation_marks
face.draw_glyph_layer(self, rect, glyph, glyph_color) # 原青 _draw_glyph_layer+_draw_digit_plate+_draw_glyph+_draw_badge
face.draw_overlay_under(self, rect) # 原青 _draw_overlay_layers 前两段(点迹+高亮)
_draw_fog_layer(rect) # 宿主(原位不变——雾夹在 hl 与 removed 之间)
face.draw_removed_dim(self, rect) # 原青 _draw_overlay_layers 末段(退色)
```
等价性来源:①层间顺序=原 _draw 的四调用序+_draw_overlay_layers 内部序,一步未动;②件内顺序=九+六函数逐字搬运,`draw_*` 引擎调用全部经 canvas 参数落到同一 CanvasItem(宿主 self),命令流与命令参数逐位相同;③接触带回退路径(contact_col.a>0 时补画投影/E 墙面/接触带;elif bg_sb 路径补画立面/投影/倒角)整体在件 A 内部,补画序逐字;④浮点面:rect.size.x 与 st.edge 同值同源,推导式零改动。结论:绘制命令流逐位一致 ⇒ golden 三张差异 0.00% 可预期。
---
## 7. gdstyle 键账预期(逐文件,平面口径=声明数全计)
| 文件 | 类变量(阈值 15) | 公开方法(阈值 20) | 函数级键预测 |
|---|---|---|---|
| board_cell_unit.gd | 10(余量 5) | 6(5 setter+_draw) | 无——_draw 时序器约 10 行;_draw_fog_layer/_draw_fog_memory/_sync_glow_layer 原体(现役零键) |
| cell_base_layer.gd | 12(余量 3) | 5(draw_base+4 setter) | 无——九函数逐字搬运,行数/分支/局部/返回不变,现役零键 |
| cell_mark_overlay.gd | 13(余量 2) | 13(5 绘制入口+8 setter) | 无——同上;draw_glyph_layer 4 参、draw_centered_text 5 参(max-parameters 5=合规上限内) |
三件全无 inner class ⇒ 不受 §1.2 截断口径影响,预测值即闸实测值。余量最小 2(件 B)——后续 art-bible 加标记类成员的余量,恶化守卫(WORSENED)在位兜底。
---
## 8. 行为零变化风险点
1. **golden 三张(L1 dungeon/L2 underdark/L3 deep_underdark)**:判据=§6 命令流逐位一致;差异非零即停机呈报,禁换锚。最大实操风险=搬运时手误(常量值、rect 推导式)——对照表逐函数「逐字搬运」核对。
2. **探针冻结成员**:glyph/fog_state/plate/glyph_color 宿主保留、名称路径零变化(ui_input case④b⑪⑮+player_copy wa8 断言零改动);hl_*/dot_visible/mutation_mark 探针改址四处(断言条件与期望值零变化,只改路径段——对照表申报行)。
3. **绘制调用序**:见 §6——含「平色回退+微光并发的英雄格补画」这种跨层重复绘制路径,必须原样保形(重复无害是现行为的一部分)。
4. **setter 双写时序**:_paint_cell 内 facade_south(:677/:690)、badge_glyph(:719/:726)、mutation_mark(:723/:725)的多写多触发序不变。
5. **`_glow_layer` 生命周期**:宿主成员不动;glow_group/edge 上收后其 setter 直调宿主自有面——子件 add/free 时机零漂移(type_glow_shot_probe/type_glow_probe 断言面)。
6. **潜伏红变量**:T0 先跑 ui_input_probe——若现状已红(§1.3 判定),红因与本设计无关但同批修复(改址四处);若绿(本会话对 GDScript 取索引语义判断有误),改址四处照做(新路径本就不同),结论记实现报告。
---
## 9. 验收载体建议(全部既有载体,零新增断言面)
| 载体 | 钉什么 |
|---|---|
| render_gate 棋盘 golden 三张 | 绘制命令流逐位一致(本批主判据;对拍差异 0.00%) |
| ui_input_probe(probe_gate 默认段) | case①②③④b⑪⑭⑮——悬停/禁入/点迹/封印槽/字形回退/变异角标/迷雾直读面全链路 |
| probe_gate --click(ui_click_probe) | dig/seal/chord 输入路径(hl 状态写入面的行为侧) |
| probe_gate --full(type_glow_shot_probe/board_shot_probe/fx_probe) | 微光子件与格矩形取证面 |
| run_all --only=player_copy,theme_projection,type_glow | u.plate/u.glyph_color 直读面+字形墨族+微光派生 |
| run_smoke+run_system_test+static_scan(三件保险恒跑) | 启活面+真实玩法路径+S9/S10/S13 键账对账 |
批末跑 `tools/run_all_gates.sh --code`(改动全为代码面);改址探针断言与对应表申报同批落地。
---
## 10. 估时
| 段 | 内容 | 估时 |
|---|---|---|
| T0 | 读数复核(33 声明/30 闸账对账)+ui_input_probe 潜伏红一跑定谳 | 0.25–0.5 日 |
| T1 | 建 cell_base_layer.gd(成员+九函数+九常量随迁) | 0.5–0.75 日 |
| T2 | 建 cell_mark_overlay.gd(成员+六函数随迁+draw_centered_text 单点化) | 0.5–0.75 日 |
| T3 | 宿主瘦身(时序器/雾/glow/edge/glow_group setter 上收)+board_view 写入面约 40 处改址 | 0.5 日 |
| T4 | 探针改址四处+孤立验证(run_all 选档+probe_gate --click) | 0.25–0.5 日 |
| T5 | 批末代码域全量闸+键账对账(10/12/13 实测核对) | 0.25–0.5 日 |
合计 2.25–3.5 工作日。出红只跑红件最小单元(闸机轮次纪律)。
---
## 11. 待裁点清单(呈主会话)
1. **潜伏红处置**:ui_input_probe 四处直读疑似已被迭代 41 打断(§1.3)。方案=本设计批内改址 u.face.* 并 T0 实跑定谳;若用户希望不等本批,可先走最小工程批把四处改 u.st.* 恢复(后续本批再改一次)。取哪个时序,裁。
2. **与尾波清偿卡的编排关系**:尾波卡 T1 把 _paint_cell 拆五段(传值句写明「经 u.st/glyph/digit_col」)。本设计改变状态件路径名——同批编队时 T1 段函数传值句改指 u.base./u.face.(T0 对账自然兜住);先后皆可,同批省一次 golden 全套。取哪个编队,裁。
3. **cell 成员去留**:全仓零读方(写入仅 rebuild:250)。删除=真实削减+§1.1-⑤ 无效成员归零;保留=「诊断观测面」注释语义。本设计倾向删(宿主降为 9),删/留,裁。
4. **gdstyle 截断口径的登记**:§1.2 发现属工具行为事实(基线欠估、工具升级可能翻键),建议经反哺点通道在 gdstyle_gate 头注或审计报告补一句注记(工程改动,防后人按「均匀展平」误判键账)。落不落、落哪里,裁。
---
## 12. 把握度声明
把握最低的一点:**潜伏红判定**——它建立在「GDScript 外部实例读不到 inner class 成员」这一语义判断与时间线推断上,本会话禁跑测试无法实证,T0 一次 ui_input_probe 即可证实或证伪;即便误判(现状可读),设计本身不受影响(改址四处照做,冻结四面照留)。次低:gdstyle 截断口径系两点反推(30=6+24、19=6+13 双双精确吻合),未读工具源码;设计不依赖该口径——三文件平面化后预测=实数。
@@ -0,0 +1,183 @@
# 设计——战斗编排类变量归约(S13 真修复方案)
> 设计讨论段过程稿 v1.0——待主会话汇总裁决(2026-10-29)。输入=用户裁定「不允许任何豁免:battle_orchestrator.gd 的 max-class-variables 必须真实修复到阈值 15 内,architecture S13 豁免登记第三条注销」。读者=主会话(裁决)与后续写卡段(转需求卡片)。
## 结论
宿主 38 个类变量经「BoardInstaller 已定稿退役 1 + 两枚新件收编 19 + 库存注入改址 1 + 攻基线快照转派生读 1」收敛到 **15(=阈值,合规)**。两枚新件:RoundCycle(轮循环驱动件——五段段件持有、段序执行、结算重入门闸、开轮摇号、踩雷计数账)与 BattleFacts(战斗事实件——受理事实、轮 facts 缓冲、封印判定账、装板溯源、条件计数、同调装配快照)。已实装两拆件 BattleFxHost/RewardGrant 与五段段类构造、呈现层、A2 订阅面、封闭流全部零触碰或仅改指。
---
## 1. 目标形态——battle_orchestrator 改后保留什么
宿主保留的是「编排」本身,全部在 architecture「战斗编排域拆件定稿」第 1 款的在册职责面内(attune 一款按本文件第 5 节重裁决为「状态归事实件、行为留宿主」):
1. **状态机与生命周期**:`begin_battle` 受理四段序列(受理/装板/运行态/预告经济)、`_exit_distribution` 轮间转移、`_battle_over` 终局序列、`battle_result` 与 `_fatal` 唯一写点、`round_index` 轮时钟。
2. **A2 三事件订阅与事件处理**:三条 connect 留 `_init`(订阅面逐字);`_on_cell_revealed`(旁路守卫→积点自动兑付触发→身份快照捕获→缓冲追加)、`_on_seal_judged`、`_on_round_end` 三个处理器留宿主——它们是多件协作的编排判断点,不是纯缓冲。
3. **行发射基建**:`_emit_row`/`_assert_row_source`/`_fatal`+SOURCE_EXEMPT 两常量词表——协议面单点,零迁移。
4. **呈现投影**:`presentation_snapshot`/`diagnostic_snapshot`/`_emit_settlement_snapshot` 三出口——签名与载荷逐字不变,内部读数改指两件投影。
5. **刷新面**:`can_refresh`/`player_request_refresh`。
6. **attune 编排读数与触发面**(重裁决后):`attune_has`/`attune_param_sum`/`attune_convert_state`/`_attune_charge_safe_row`/`_reseed_attune_charges`/`_hook_attune_consume`/`_attune_safe_seen_read`/积点自动兑付体——读数出口与外部面零改址(见第 5 节)。
7. **账本读面**:`_journal`/`_attune_loadout`/`_battle_hooks` 三派生读与回调束。
8. **装板薄壳**:`_install_and_reset`(轴丙定稿形态——五处计数清零、板序推进、board_changed 发射、叠加层退役,时序逐字)。
9. **B2/B3/B4 协作者持有**:S7「唯一调用方=B1 域文件集」的承载面。
搬出去的只有两类东西:**轮结算周期的推进机构**(谁持有段件、按什么顺序跑、开轮怎么摇号、重入怎么挡——归 RoundCycle)与**发生过什么与本战是什么的记录**(事实账——归 BattleFacts)。两件的职责语句与单一变化原因见第 3、4 节。
## 2. 逐成员去向对账表(38 项)
| # | 成员 | 去向 | 依据(一句话) |
|---|---|---|---|
| 1 | db | 留宿主 | B1 跨系统调用权的表读取面,宿主级协作者 |
| 2 | rng | 留宿主 | encounter/gp_drop 两封闭流在宿主函数体内,behavior_roll 随摇号件经 oc 取用 |
| 3 | _board_generator | **随 BoardInstaller 退役** | 轴丙已定稿(v1.24):实例随件自建自接线 |
| 4 | minesweeper | 留宿主 | A2 订阅面+HUD 公有消费面(API Boundaries 在册)双锁定 |
| 5 | action_economy | 留宿主 | A3 回发面+HUD 公有消费面双锁定 |
| 6 | _enemy_system | 留宿主 | B2 生命周期(spawn/despawn)与三快照读源 |
| 7 | _status_effects | 留宿主 | B3 开域/闭域与三快照读源 |
| 8 | _reward_economy | 留宿主 | B4 恰一次 roll/retire 编排+set_treasure_unlocked/query_reward_identity 两外部代理 |
| 9 | treasure_inventory | **退役改址** | 唯一外部注入点 level_runner:520 改经 `reward_grant()` 出口直注(RewardGrant 在册成员);宿主与授予段读面改指 grant |
| 10 | _damage | 留宿主 | 单据管线接线(fx_calls/inject)与 AC 基线注入时序锁定在受理段内 |
| 11 | _fx_host | 留宿主 | 组件出口 `fx_host()`——定稿在册取件面 |
| 12 | _reward_grant | 留宿主 | 组件出口 `reward_grant()`+库存持有者+escrow 读源 |
| 13 | encounter | **BattleFacts** | 本战受理事实(打什么、带什么进来)——与过程事实同一记录口径 |
| 14 | round_index | 留宿主 | 轮时钟;system_test 等四套件约 15 处 `settlement.round_index` 公有直读面,零改址 |
| 15 | battle_result | 留宿主 | 状态机终局态;_fatal/_battle_over 唯一写点归属不变 |
| 16 | _facts_reveals | **BattleFacts.reveals** | 轮 facts 缓冲 |
| 17 | _facts_seals | **BattleFacts.seals** | 封印判定批缓冲 |
| 18 | _facts_path | **BattleFacts.path** | 轮末路径事实 |
| 19 | _settling | **RoundCycle._settling** | 结算重入门闸——与段序执行同一单元 |
| 20 | _grant_seg | **RoundCycle** | 五段段件持有归驱动件(定稿「段序编排+接线」的代码承载) |
| 21 | _aura_seg | **RoundCycle** | 同上 |
| 22 | _combat_seg | **RoundCycle** | 同上 |
| 23 | _decay_seg | **RoundCycle** | 同上 |
| 24 | _verdict_seg | **RoundCycle** | 同上 |
| 25 | _refresh_used_this_round | **BattleFacts.refresh_used** | 本轮刷新计数=过程事实(复位点=出口分发,语句随迁) |
| 26 | _board_seq | **BattleFacts.board_seq** | 装板溯源事实 |
| 27 | _board_from_midround_refresh | **BattleFacts.board_from_midround** | 装板 provenance(清图奖励守卫读源) |
| 28 | _seal_consumed | **BattleFacts.seal_consumed** | 封印兑付资格账(install 重置) |
| 29 | attunement | **BattleFacts.attunement** | 本战装配集快照=受理事实(enc.attunement 携带) |
| 30 | _mines_hits | **RoundCycle.mines_hits** | 摇号条件账——转存语句本就在 `_roll_round_actions` 轮末,随摇号件走 |
| 31 | _attune_safe_seen | **BattleFacts.attune_safe_seen** | 积点计数=过程事实 |
| 32 | nest_preview_count | 留宿主 | 冻结外部直读面(main.gd×2+treasure_effects_test×1)零变化 |
| 33 | _feat_first_dig_used | **BattleFacts.feat_first_dig_used** | 条件事实计数(魔矢每战首次) |
| 34 | _seal_miss_seen | **BattleFacts.seal_miss_seen** | 标错去重账 |
| 35 | _perfect_hit_true | **BattleFacts.perfect_hit_true** | 完美封印三账(契约 2 写口归件,见第 4 节) |
| 36 | _perfect_hit_false | **BattleFacts.perfect_hit_false** | 同上 |
| 37 | _perfect_forgiven | **BattleFacts.perfect_forgiven** | 同上 |
| 38 | _hero_atk | **退役→派生读函数** | `_hero_atk()` 派生读(`encounter.get("hero_atk", 表值)`)——`_journal()`「读面即引用、无第二账」同款先例;E4 收口语义不变(encounter 受理后只读,派生值恒等) |
**宿主改后 15 项**:db、rng、minesweeper、action_economy、_enemy_system、_status_effects、_reward_economy、_damage、_fx_host、_reward_grant、round_index、battle_result、nest_preview_count、_rounds、_facts。
## 3. 新件一:RoundCycle(轮循环驱动件)
- **文件落点**:`game/core/settlement/round_cycle.gd`(与五段段件同目录——它是段件的序主人)。
- **extends**:RefCounted(fx_host/reward_grant/段类同款;随编排器每战新建同灭)。
- **职责语句**:每轮结算周期的唯一驱动——结算重入门闸(settling)、五段段序执行(段序骨架冻结于 SettlementTable.segment_order)、开轮摇号(共识点 B:技能选择前置到轮次开始,摇定即本拍结算的选技)、踩雷计数账(转存时点=摇号轮末)。
- **单一变化原因**:轮结算周期的推进结构(段序、重入闸、摇号时序)。
- **类变量(8 ≤ 15)**:`oc`(宿主,段类同款直调形态)、`_grant_seg`、`_aura_seg`、`_combat_seg`、`_decay_seg`、`_verdict_seg`、`_settling`、`mines_hits`({"total","last","round"} 三读数合一账)。
- **公开方法(3 ≤ 20)**:`settle_if_due()`(=原 `_maybe_settle` 三闸+`_settle` 段序体合体)、`roll_round_actions()`(原函数逐字迁入)、`is_settling()`(diagnostic_snapshot 读投影)。
- **行数估算**:约 120 行(头注+成员+四函数)。
- **耦合边界**:
- `_init(host, fx_host, reward_grant)`——3 参不触发 max-parameters,无需引用束;五段构造五行从宿主 `_init` 逐字搬入。
- 段类对宿主的直调形态不变(定稿在册:「段类经宿主引用直调,现状形态」);驱动件经 `oc` 取 facts/协作件/行发射/出口分发,与段类同款。
- **VerdictSegment 零改动**:`_exit_distribution` 留宿主(轮间转移=宿主生命周期域:换图编排、notify、轮始发射),判定段仍直调 `oc._exit_distribution()`——不产生段类对驱动件的新引用,不新增 RefCounted 引用环。
- 随机只经 `oc.rng` 的 behavior_roll 封闭流(流名、开流时点、取号序逐字);零 await。
- **宿主侧变化**:`_on_round_end` 末行改调 `_rounds.settle_if_due()`;`begin_battle` 与 `_exit_distribution` 的 `_roll_round_actions()` 改调 `_rounds.roll_round_actions()`;`_maybe_settle`/`_settle`/`_roll_round_actions` 三函数从宿主删除。
## 4. 新件二:BattleFacts(战斗事实件)
- **文件落点**:`game/core/battle_facts.gd`。
- **extends**:RefCounted。
- **职责语句**:战斗事实的唯一记录面——本战受理事实(encounter:打什么、带什么进来)、同调装配事实(attunement)、轮 facts 缓冲(reveals/seals/path)、封印判定账(去重两集+完美三账)、装板溯源(seq/provenance)、条件事实计数(refresh_used、feat_first_dig_used);自带轮复位与完美账写口。
- **单一变化原因**:战斗事实的记录与查询口径——内容批新增触发条件事实/判定账只落此一处。实证:`_feat_first_dig_used`(魔能共鸣)、`_seal_miss_seen`(危险直觉)、`_mines_hits`(触发条件面)、enc 的 feats/tree_rules/voucher 携带键,全部由内容批按同一节奏累加。
- **类变量(15 ≤ 15,贴顶)**:`encounter`、`reveals`、`seals`、`path`、`refresh_used`、`board_seq`、`board_from_midround`、`seal_consumed`、`seal_miss_seen`、`perfect_hit_true`、`perfect_hit_false`、`perfect_forgiven`、`feat_first_dig_used`、`attunement`、`attune_safe_seen`。
- **公开方法(5 ≤ 20)**:`reset_round()`(原 `_reset_round_facts` 逐字——只清 reveals/seals/path 三项,**不碰 refresh_used**:_battle_over 后快照读到的 refresh_used 必须保持末轮值)、`mark_perfect_hit()`/`mark_perfect_miss()`/`mark_perfect_forgiven()`(契约 2 写口:`_perfect_hit_false` 纯净禁回退改写的执行点从段类纪律升级为账本单点)。其余一律公有成员直读写(段类/快照/宿主经 `oc._facts.X` 改指——fx_host._fx_bonus_delta 跨件直读写同款现状形态)。
- **行数估算**:约 80 行。
- **耦合边界**:**零注入引用、零信号、零协作对象调用**——纯数据+谓词+写口;缓冲写入点在宿主 A2 处理器(订阅面锁宿主),身份快照捕获(query_full_snapshot)留宿主 `_on_cell_revealed`(fact 件不持 B4 引用,防它变成第二编排面)。
- **成员冻结义务**:15/15 贴顶——实现期禁增员,增员即停卡。预留扩容阀:下一张要加事实成员的卡,先把封印判定账五成员二次拆出(SealLedger,−5)再落新账,禁硬挤。
## 5. attune 族重新裁决(architecture「原位保留」句的废止建议)
**建议:部分改裁——状态两成员归 BattleFacts,行为函数留宿主。** 理由四条:
1. **原位裁的前提已消失**:该句是迭代 39/40 两批的防冲突临时裁,原文自认「本波残留债归尾波」;两批均已合回,本波即尾波,且用户已裁「不允许任何豁免」打开重裁通道。
2. **状态是事实,行为是编排**:`attunement`=本战装配了什么(enc.attunement 受理携带的快照,受理后只读)、`attune_safe_seen`=本战安全开格积点——两者都是战斗事实,归账本件名正言顺。而参数合计(装配集行扫描)、积点自动兑付(何时 grant_ap=编排决策)、充能重置触发、呈现进度读数——这些是 B1 编排面的读数与触发,与 `_fx_host_fact` 同位的宿主读数形态,留在宿主不违职责语句。
3. **外部面零改址**:`attune_has`(断点续玩测试×2+表结构守卫×2)、`attune_param_sum`(main.gd 授予段两处+treasure_effects_test)、`attune_convert_state`(treasure_interact_controller 取值回调)全部留宿主公有面——main.gd 与 treasure_interact_controller 本批零改动。若整体拆成 BattleAttune 新件,这三面约 10 处消费点全要改址(组件出口或转发壳),收益只是把 8 个读数函数换个文件——判据③(阈值动机)嫌疑大于内聚收益。
4. **不并进 AttuneLoadout**:那是营地/冒险域的充能与装备集物化单源(迭代 39 已闭合契约);把战斗域读数插进去会重开已闭合边界。BattleFacts 持有的只是快照与计数,充能物化仍全归 AttuneLoadout(`_reseed_attune_charges`/`_hook_attune_consume` 经调用点传 loadout/treasure 委派,宿主侧单点不变)。
## 6. 已否决的方向(为什么不是别的切法)
1. **协作者引用束归袋**(任务提示①的直译形态):db/rng/units/statuses/reward_economy 等 11 个协作者句柄若收进一个「引用束」对象,宿主 150+ 处 `db.`/`oc._enemy_system.` 全部换名——零内聚收益的纯改名,命不出领域名字=凑计数袋(拆分判据②红)。引用束先例只用于新件 `_init` 防参(本批两新件参数均 ≤3,未触发)。
2. **attune 整体拆件(BattleAttune)**:宿主 14 基数+3 句柄=16 不可达;且如第 5 节理由 3,外部三面 10 处改址换不来职责改善。
3. **encounter 留宿主**:宿主 16 超阈。备选砍口只剩两处——nest_preview_count 解冻迁 facts(违背任务给定冻结面)或 _reward_economy 经 RewardGrant 中转(B4 mapping 生命周期与代理面挂到授予件名下=所有权失真)。encounter 归事实件是唯一不破冻结面、不失真的砍口;它也是本方案最弱的一格,见待裁点 1。
4. **四件以上碎片化**:每多一件付一个宿主句柄;封印判定账、装板溯源单独成件都撑不起独立变化原因,且把宿主推向 16+。
5. **_exit_distribution 迁入驱动件**:判定段须改持驱动件引用(RefCounted 环+段类构造变化),换图编排又是宿主生命周期语义——收益不抵风险,否。
## 7. 随迁键收敛义务
**基线实证**:`tools/gdstyle_baseline.txt` 中 battle_orchestrator.gd 现仅两条类级键(max-class-variables=38、max-file-length=1035),**零函数级键**——59 个函数全部在默认阈值内(长度≤50/分支≤8/局部≤10/返回≤6/参数≤5)。函数级指标是函数体内在属性,逐字迁移(仅引用改指)不产生新键。据此:
- **随迁键清单:预计零条**。义务改为「迁移函数逐字纪律」:`roll_round_actions`(45 行/分支≈8 贴线)、`settle_if_due`、`reset_round`、三个 mark 方法——迁移与改指**禁顺手增分支/局部**;确需增条件即停手核对 gdstyle,超线在卡内拆助手函数收敛(先例=迭代 40 卡①的 12 随迁键收敛)。
- 新增小函数全部远在阈值内(最长 `roll_round_actions` 45 行;新件 `_init` 参≤3)。
- 两新件与改址后的宿主、段类落地后跑 `python tools/gdstyle_gate.py` 预检一次再进批末闸。
## 8. 行为零变化风险点与对策
1. **RNG 取号序**:宿主三封闭流——encounter(`_begin_battle_dice`,留宿主)、gp_drop(`_roll_gp_drop`,留宿主)、behavior_roll(随 `roll_round_actions` 迁 RoundCycle——流名与开流时点逐字,只经 `oc.rng`)。fx_reveal(fx_host 内零触碰)、board_gen/variant_place(BoardInstaller 已定稿随件)。对策=同种子完整局对拍(见第 9 节 PARITY)。
2. **信号契约**:五信号(step_row/battle_finished/round_started/board_changed/settlement_snapshot)全留宿主;发射语句零迁移——`round_started.emit` 在 begin_battle/`_exit_distribution` 内原位,仅 round_index 读源不变;A2 三 connect 逐字。发射时序零变化。
3. **段类接线**:五段构造参数与持有形态不变(grant/combat 三引用、aura/decay/verdict 单引用);verdict 段零改动(`_exit_distribution` 留宿主)。段内约 25 处 `oc._X` 改指 `oc._facts.X`/`reward_grant.treasure_inventory`——调用点改指、禁转发壳(定稿同款纪律)。
4. **_fatal 与 battle_result 唯一写点**:留宿主;BoardInstaller(已定稿 fatal Callable)、RoundCycle/段类(经 oc 直调)零改形。
5. **结算时序**:`settle_if_due` 三闸顺序(settling→battle_result→phase)与「终局不回置 _settling、_battle_over 接管」早退语义逐字;判定段内 `_exit_distribution`→回置 `_settling` 的先后不变(出口留宿主保证);`reset_round` 不碰 refresh_used(_battle_over 后快照的 refresh_used 必须保持末轮值——这是本轮盘点抓出的一处险点)。
6. **重入语义**:`_on_cell_revealed` 不设 settling 守卫(现状——flush_pending_reveals 的 fx_reveal 事件依赖 reveal_busy 旁路闸而非 settling),处理器体零改形;install 初始展开事件「先缓冲后清除」路径(begin/exit 两处 reset_round)保持。
7. **快照逐字**:三快照字段名、嵌套结构、值口径逐字——读数改指投影后值恒等(round_index/attune_safe_seen/perfect 三账/hero_atk 派生读均受理后不变量)。
8. **装板薄壳时序**:轴丙定稿五处清零→板序推进→board_changed 发射→叠加层退役的顺序逐字(成员改指 facts 不改序);BoardInstaller 闭合设计的 bundle 键「encounter」传 `_facts.encounter`——同一字典引用,零冲突。
## 9. 验收载体与判据
改动—验收对照表(卡内落六列)建议主行:
| 需求点 | 真实入口 | 载体 | 判据绑定面 |
|---|---|---|---|
| 行为零变化(本批总判据) | 真实局 begin_battle→挖掘→结算→终局 | **PARITY 同种子完整局对拍**(parity_anchor/parity_compare) | step_row/settlement_snapshot 逐位一致;**实跑须用户批准、禁重锚**(battle_orchestrator.gd 触 PARITY_TOUCH_FACES) |
| 段序与重入门 | stop→WAITING→settle_if_due | round_flow_skill_pool_test、settle_segments_test(真实一轮走段序,零改址应绿) | 五段裁定行序、settling 闸、终局早退 |
| 开轮摇号迁移 | begin_battle/出口分发→roll_round_actions | round_flow_skill_pool_test(技能池/保底/冷却)+trigger_cond_test(mines_hits 账——3 处读改指 _rounds) | 同种子摇定结果逐位、转存读数 |
| 封印判定账迁移 | 封印动作→结算 | seal_polarity_test(4 处 perfect 直写改指)、feat_vouchers_test(8 处+_grant_seg 改指)、meta_progression_forge_test(契约 12 守侧) | 完美三账读数、去重闸、契约 2 计数纯净 |
| 装板 shell/溯源 | begin/refresh/exit 装板 | variant_placement_test(零改址应绿)+seal_polarity_test provenance 守卫 | 刷新图不发清图奖励、board_seq |
| attune 面零改址 | 装配起战→读数/兑付 | treasure_effects_test、breakpoint_resume_test、table_structure_guard_test(**应零改址全绿**——本批最硬的「外部面零变化」证) | attune_has/param_sum/convert_state/积点兑付 |
| 受理事实迁移 | begin_battle(enc) | adventure_feats_test、meta_progression_forge_test(encounter 4 处改指) | enc 携带键贯通 |
| 快照逐字 | presentation/diagnostic 出口 | system_test+对拍 | 载荷 schema 与值逐字 |
| 库存注入改址 | level_runner 建战注入 | treasure_effects_test 秘宝使用链 | use_treasure 受理面 |
配套义务:①三件保险恒跑(冒烟/系统测试/静态扫描)+上表关联套件(02 关联档);②静态扫描随批增行——RoundCycle 进 S7 B1 域文件集与 S8 await 文件集(经 oc 调 B2/B3/B4 符号落在该文件),BattleFacts 零协作调用不入两清单;③新文件全类型标注(S9)、头注按 §1.4.1;④本批零数值改动,MC 零跑。
## 10. gdstyle 键账预期
| 文件 | 类变量 | 公开方法 | 长度 | 预期键 |
|---|---|---|---|---|
| battle_orchestrator.gd | **15**(38→15) | 14 | ~830 | **两条基线键全消失**(类变量/文件长双双回落阈值内),零新键 |
| settlement/round_cycle.gd | 8 | 3 | ~120 | 零键 |
| battle_facts.gd | 15(贴顶) | 5 | ~80 | 零键(15=阈值内合法,fx_host「14≤15」同口径) |
| settlement/grant_segment.gd | 3(不变) | — | +~2 行改指 | 零键 |
| 其余段类/fx_host/reward_grant | 不变 | 不变 | 不变 | 零键、零 diff |
基线处理:`--refresh` 人工重生成;全基线 16 条消失 2 条(−12.5%>10% 骤降守卫)→ 须 `--force` 显式确认,属正常还债缩基线。architecture S13 豁免登记第三条随批注销(反哺点,实现批禁写 design/)。
## 11. 改址盘点(触面清单)
- **产品码**:battle_orchestrator.gd(主改——成员改指+三函数迁出+hero_atk 派生化+头注指址改写);settlement/round_cycle.gd、battle_facts.gd(新建);grant_segment.gd(~25 处改指);combat_segment.gd(2 处);level_runner.gd(1 行——库存注入改经 `reward_grant()` 出口);aura/decay/verdict、battle_fx_host、reward_grant、damage_controller、main.gd、treasure_interact_controller、board_installer(**零改动**)。
- **测试**:feat_vouchers_test(~13)、meta_progression_forge_test(~8)、seal_polarity_test(~8)、trigger_cond_test(3)、round_flow_skill_pool_test(1)、adventure_feats_test(1)、treasure_effects_test(1——`ob14.attunement` 改指);settle_segments_test、roll_multiplier_test、system_test、breakpoint_resume_test、table_structure_guard_test(零改址——attune 面与 round_index 面不动的直接受益者)。
- **probes/sim**:零触碰(盘点无命中)。
- **闸件数据**:gdstyle_baseline.txt(--refresh --force)。
## 12. 估时
**2–3 个工作日**:实现(两新件+宿主改址+段类改址+测试改址)1.5–2 日;验收(关联档回归+PARITY 批跑+对照表与审计配合)0.5–1 日。PARITY 实跑须用户在场批准(不占卡估时);基线 refresh 属批内闸步骤。
## 13. 待裁点清单
1. **encounter 归战斗事实件**(本方案最弱一格):受理参数与过程记录同件,变化理由按「战斗事实面扩展」归一(第 4 节实证),但确与事实缓冲不同复位节奏(encounter 随战、facts 随轮)。若否决:宿主 16,只剩两条砍路——nest_preview_count 冻结面解锁(外部读面 3 处改址)或 _reward_economy 经授予件中转(所有权失真),两者都更差,届时按判据④停卡呈报。
2. **treasure_inventory 注入面改址**:唯一外部产品码触面(level_runner 一行改经组件出口直注),拆件定稿「外部赋值路径零改址」句随本批失效,需追认。
3. **attune 重裁决幅度**:推荐「状态归 facts、行为留宿主」(第 5 节);备选「整体拆 BattleAttune」因宿主 16 不可达已被排除——即本条实际是确认推荐案或否决整个方向。
4. **完美账写口升级**:grant_segment 三处直写改经 facts 三方法(契约 2 单点执行)——推荐采纳;若求最小 diff 可退直写(现状纪律同款),卡内裁量。
5. **PARITY 对拍批准**:battle_orchestrator.gd 触 PARITY_TOUCH_FACES,实跑对拍须用户点头、不重锚。
@@ -0,0 +1,210 @@
# 设计——测速循环去 await(S13 `tune_sim_controller` await-in-loop 键真实消除)
状态行:设计讨论段过程稿 v1.0——待主会话汇总裁决(2026-10-29)。
## 1. 背景与目标
用户 2026-10-29 裁定「不允许任何豁免」:S13 静态质量闸(gdstyle)的裸键 `game/presentation/tune_sim_controller.gd|quality/await-in-loop|'await' used inside a loop` 必须真实消除;architecture「测试与质量域」S13 测量面豁免登记(2026-10-27,理由=「循环内 await 是调参测量的 wall-clock 步进承载语义——重构即测量口径漂移」)随之注销(注销落文走反哺点通道,实现批禁直改 architecture)。
本设计回答一件事:**把「循环内 await 逐帧让出」换成信号驱动形态后,测量语义是否逐点等价**——每步恰占一帧、每步执行相位不变、终止与读数不变、输出逐字不变。结论先行:**可行,推荐 process_frame 信号连接+步进状态机形态**;等价性四判据三条可严格证明并可用双实现对拍执行化验证,一条(脚本错误中断路径)无法严格证明、列为已声明缺口。
## 2. 现状全解
### 2.1 测速循环逐句流程
现码 `run(n)`(`game/presentation/tune_sim_controller.gd:36-52`):
| 步 | 语句 | 做什么 |
|---|---|---|
| 1 | `_running = true` | 控制器运行态(组合根 `_start_debug_levels` 互查守卫的判据) |
| 2 | `PlaytestLogger.new()`+`start_session(SEED_BASE)` | 开共享 JSONL 会话(一文件多局,`log_run` 行带种子切分局次) |
| 3 | `panel.set_sim_running(true)` | 浮窗运行态(`DebugOverlay.st._sim_running`——模拟钮置灰+探针守卫环判据) |
| 4 | `set_sim_progress("模拟中:0/n …")` | 进度串 |
| 5 | 建 `stats` 六键束、取 autoplay 驱动 | 测量桶与策略驱动 |
| 6 | 循环体:`_run_one_level(...)` | 单局全量模拟(`level_autoplay.run_level` 静态同步函数——自建 RngService、种子=SEED_BASE+i,逐局确定可回放)→ 四桶记账 |
| 7 | `set_sim_progress("i+1/n")` | 进度串 |
| 8 | `await panel.get_tree().process_frame` | 每局恰让出一帧(命中键的语句) |
| 9 | 循环尽:`close_session()`+`set_sim_report(...)` | JSONL 收口+报告注入(文案归 `HudPresenter.tune_sim_report`,零触碰) |
读数本质:`stats` 六键与报告是 **(种子, atk_pct, hp_pct) 的纯函数**——帧时点不进测量值(`run_level` 不读 wall-clock)。豁免登记所保护的「测量语义」是运行姿态:每局之间恰隔一帧 process_frame 发射(进度可见、窗口不僵死),以及 run 全程的运行态语义。本设计保的就是这个姿态。
### 2.2 读数消费链
- 报告文案:`tune_sim_report(stats)` → 浮窗 RichTextLabel(`set_sim_report`);探针 ⑤ 断言「关卡完成率/关卡完成剩余 HP 均/败北节点/N=10」四串。
- JSONL:`user://logs/playtest_*.jsonl`,由未触碰的 `level_autoplay` 逐行写;`close_session` 时点随收尾帧。
- 运行态:`panel.set_sim_running` → 浮窗模拟钮置灰;`_running` → 组合根两层调试入口守卫。
### 2.3 断言面盘点与一处静态矛盾(潜伏红——本设计的关键发现)
两个在库断言面钉死了 run 生命周期的语义:
1. **单元套件 `standee_fx_sweep_test.gd`〔wd8〕**(`game/tests/unit/presentation/standee_fx_sweep_test.gd:126-134`):假驱动在**每一局** `run_level` 回调内读 `ctrl.is_running()`,断言 `drv.seen == [true, true]`(两局读数都真);收尾断言 `is_running()` 假+`panel.running` 假+报告非空;且用 `await ctrl.run(2)` 驱动——**run 必须保持可等待(协程),await 它须挂起到整批完成**。
2. **探针 `ui_tune_probe.gd` ⑤**(`game/probe/ui_tune_probe.gd:67-83`):按下模拟钮后以 `while debug_overlay.is_running()` 守卫环逐帧等——**语义=浮窗运行态贯穿整批**,环退出后断言输出含报告四串。
静态推演现码:`_run_one_level` 尾部两行(`panel.set_sim_running(false)`/`_running = false`,:67-68)**每局执行一次**——首局完成即把两个运行态置假。后果:
- wd8 首断言实测必得 `[true, false]` → 红;
- 探针 ⑤ 守卫环在按下返回后立即退出(首局在按下同一同步段内已跑完)→ 输出停在进度串 → 四条输出断言全红。
推断:这两行原本在循环**之后**(run 收尾单次执行),是「循环体提函数」(run() 局部变量 11→10 清偿批,2026-10-26 审计在案该键)搬运时被卷入提取体——wd8 写于 d8 批且当时必绿,可反证。两断言面均不在近期批次的关联档选测覆盖内(套件名与文件名无字面关联、probe_gate --full 非恒跑三保险),潜伏红未暴露。**T0 义务:实跑 standee_fx_sweep 单套件+probe_gate --full 复核现状**(本设计零测试执行,此判断待实跑确认)。
推论:本批若逐字保留现行为,wd8 与探针 ⑤ 必红、批不可绿。**本设计按「run 收尾单次置 false」的还原语义设计**(两断言面共同钉住的语义),该还原作为已申报行为改动进卡(待裁点 1)。
## 3. 方案形态评估
判定轴:帧相位(步进体在帧循环中的执行时点是否与 await 恢复点相同)、步进节律(相邻两步之间是否恰隔一次 process_frame 发射)、run 可等待性(wd8 契约)、键风险(S13 新键)。
Godot 4 帧循环 process 段的迭代序(engine-reference 口径):**① `emit process_frame`**(所有连接的 Callable 同步依次调用;`await process_frame` 的恢复点=此刻挂在信号上的临时连接被调用)→ **② 节点 `_process`**(Timer 节点在此段)→ **③ 帧末**(SceneTreeTimer 超时、延迟删除等)。官方文档:process_frame「Emitted immediately before Node._process is called on every node」。await 恢复点与显式 connect 回调**同处①、同一相位**——这是全部等价性论证的支点。
| 形态 | 帧相位 | 步进节律 | run 可等待 | 键风险 | 裁决 |
|---|---|---|---|---|---|
| **process_frame 信号连接+步进状态机** | 与 await 恢复点同相位(同一 emit 内) | 恒等(常驻连接,每发射恰走一步) | 保留(函数级单次 await 完成信号,见 §4) | 零新键 | **采纳** |
| SceneTreeTimer 链 | timeout 在③帧末——相位不同 | `create_timer(0)` 同帧即燃→节律塌缩;加时长→漂移 | 须循环内 await→键不消 | await-in-loop 残留+每步分配 | 否 |
| Timer 节点 | timeout 在②节点 process 段——相位不同 | wait_time 按秒计,一帧节律不精确 | 须 await timeout 链→键不消 | 键残留+须建 Node 入树(RefCounted 控制器破形、生命周期管理新增) | 否 |
| 递归协程代循环 | 同相位(恢复点内即调下一步) | 恒等 | 天然(await 协程链) | 零键 | 备选否决——n 个并发函数状态链、错误中断语义更浑、可读性差 |
| 线程 / WorkerThreadPool | 脱离主循环 | — | — | 测量确定性破坏+面板 setter 跨线程 | 否(一句话排除) |
godot-master 惯用法对齐:异步操作移出循环、改由信号触发的独立方法承载(其 NEVER-list 第 7 条同款);动态连接用毕即断(第 27 条);逻辑件保持 RefCounted 不引入 Node(When-NOT-to-use-Node);连接前 `is_connected` 守卫(迭代 39「恰好连接一次」先例)。
## 4. 推荐案:process_frame 信号步进状态机
### 4.1 代码结构草图(伪代码级)
```gdscript
signal _batch_finished ## 批量模拟整批收尾完成(无参数;发射时点=报告注入与运行态复位之后;
## 消费方=run() 自身收尾放行——外部 `await 控制器.run(n)` 经此放行)
# run 期活成员(批末失效,下次 run 重写——非无效成员)
var _sim_n := 0
var _sim_i := 0
var _sim_stats := {}
var _sim_autoplay = null
var _sim_logger = null
var _finished := false
func run(n: int) -> void:
_running = true
# …logger 建会话/set_sim_running(true)/进度 0/n/stats 六键束/_autoplay()——逐字保持现码…
_sim_n = n; _sim_i = 0; _sim_stats = …; _sim_autoplay = …; _sim_logger = logger
_finished = false
if n > 0:
var tree: SceneTree = panel.get_tree()
if not tree.process_frame.is_connected(_step_frame):
tree.process_frame.connect(_step_frame) # 恰连接一次守卫(迭代 39 先例)
_step_frame() # 首步同步执行——与 await 形态「第 0 局在调用栈内跑完」对齐
await _batch_finished # 函数级单次 await——不在任何循环体内(键消除的落点)
else:
_finish_batch() # n=0:与 await 形态一致——循环零进,同步收尾零帧
# 每帧恰执行一步(process_frame 发射点回调);步尽次帧收尾
func _step_frame() -> void:
if _sim_i < _sim_n:
_run_one_level(_sim_autoplay, _sim_stats, _sim_i, panel, _sim_logger) # 逐字保持
panel.set_sim_progress("模拟中:%d/%d …" % [_sim_i + 1, _sim_n]) # 逐字保持
_sim_i += 1
else:
panel.get_tree().process_frame.disconnect(_step_frame) # 先断连(防再入)
_finish_batch()
_batch_finished.emit() # 放行 run() 的 await 与外部 await run(n) 的调用方
# 收尾单点(运行态复位还原为「run 收尾单次执行」——待裁点 1 的申报改动落点)
func _finish_batch() -> void:
_finished = true
_sim_logger.close_session()
panel.set_sim_running(false)
_running = false
panel.set_sim_report(HudPresenter.tune_sim_report(_sim_n, panel.atk_pct(), panel.hp_pct(), _sim_stats, _base_hp))
```
要点:
- **await 只剩一处、在函数级**(`await _batch_finished`),文件内不再有任何 for/while——await-in-loop 键从文本形态上根除,且该文件此后对键**结构性免疫**(无循环即无循环内 await)。
- **run 保持协程身份**:含 await 即仍是协程——`_on_tune_simulate` 不 await 调用(返回函数态、丢弃,与现行为逐字一致);wd8 的 `await ctrl.run(2)` 挂起到 `_batch_finished` 发射、恢复时整批已完成——**契约零变化、wd8 断言零改动**。
- `_run_one_level` 除删去尾部两行(回归还原,见 §2.3)外逐字保持(含 5 参签名,参数≤5 临界不恶化)。
- 头注按 code-conventions §2.1 增 `_batch_finished` 契约一行(现 4 行→5 行,S10 ≤8 行内)。
- 收尾段内四语句的相对次序(close/两运行态复位/报告)对两个断言面均不可观测(wd8 在整批完成后检查、探针在帧边界检查)——按草图次序落码即可,实现期查 git 历史原序可进一步对齐。
### 4.2 帧相位等价性论证(逐步对齐表)
以 n=3 为例,旧(await)新(状态机)两形态逐帧对齐:
| 时点 | 旧形态 | 新形态 | 等价 |
|---|---|---|---|
| 调用点同步段(按钮信号链内) | setup→第 0 局→进度 1/n→await 挂起 | setup→connect→`_step_frame()` 跑第 0 局→进度 1/n→`await _batch_finished` 挂起 | 同一调用栈、同一同步段、语句同序 |
| 第 1 帧 ①(emit process_frame) | 恢复→第 1 局→进度 2/n→再 await | `_step_frame` 回调→第 1 局→进度 2/n | **同一 emit、同一相位**(帧首、节点 _process 之前) |
| 第 k 帧(1≤k≤n−1) | 第 k 局 | 第 k 局 | 步进体=同一函数 `_run_one_level`+同一进度语句 |
| 第 n 帧 ① | 恢复(循环自然尽)→close→报告→返回 | `_step_frame` else 分支→断连→close→复位→报告→emit→run 返回 | 终止语句同帧同相位,恰多等的一帧来自旧形态末次 await——草图 else 分支精确复刻 |
| n=0 | 循环零进,同步收尾,不挂起 | else 直调 `_finish_batch`,同步收尾,不挂起 | 一致(含 run 返回形态:均非挂起返回) |
连接次序论证(与同信号其他订阅者的相对序):产品码内 process_frame 订阅面仅两处——本件与 `settlement_fx_view.gd:94` 的一次性 await(等文本度量,战斗结算呈现期,与模拟批不并存;T0 实查复核)。探针 ⑤ 守卫环的 await 连接时点恒晚于本件(按下返回后才首轮 await)→ 每帧步进先于探针复查,两种形态一致。旧形态每次恢复后重新挂尾连接、新形态常驻连接——对「连接时点早于 run()」的订阅者,两形态中本件都排其后;差异仅在「run 途中新增订阅者」的假想场景,现库为零(已列风险 3)。
## 5. 等价性证明清单(四判据)
| 判据 | 结论 | 依据 |
|---|---|---|
| ① 步数与帧数一一对应不变 | **严格成立** | §4.2 对齐表:第 i 局恒在(调用点 i=0/第 i 帧发射点 i≥1),收尾恒在第 n 帧发射点,n=0 退化路径一致 |
| ② 每步工作量与执行时点不变(同相位) | **严格成立** | 步进体逐字同一函数;执行点同为 emit process_frame(①段,帧首)——await 恢复点与信号回调在引擎内同处一列连接、同一 emit 内被同步调用 |
| ③ 终止条件与终止时读数不变 | **严格成立** | 终止=i 走满 n(else 分支↔循环自然尽);终止时语句(close/复位/报告)同帧执行 |
| ④ 输出逐字不变 | **成立+执行化验证** | 报告=未触碰的 `tune_sim_report(stats)`;stats 为种子纯函数(帧时点不进值);JSONL 由未触碰的 autoplay 写、close 时点同帧——逐位一致由双实现对拍执行证明(见下) |
执行化验证=**双实现对拍**(test-conventions §5.3「重放:改前改后配对」词汇,非变异类):新增配对套件——`game/tests/` 面置**遗留形态夹具**(现 run() 的 await 形态逐字副本,尾部两行按还原语义置收尾;tests/ 不在 S13/S8 扫描面,夹具内循环 await 合法在册);同一假面板+确定性假驱动分别驱动两形态,断言五行全等:每局调用时记录的**帧索引序列**(直接证明「每步恰一帧、相位同点」——把 §4.2 的论证变成当轮真实执行证据)、驱动读到的运行态序列、进度串序列、stats 六键逐位、报告全文逐字。
**已声明缺口(不能严格证明的点)**:
1. **脚本错误中断路径**:GDScript 无错误陷阱 API。旧形态:步进体内脚本错误→协程死亡→静默停摆(运行态永真、报告永不落)。新形态:错误中断 `_step_frame`→计数未推进→次帧重试同一步(确定性错误→逐帧重试,探针 1800 帧守卫可抓;生产态=持续重试的可见坏,与旧「静默卡死」同级不同形)。此差异不可消除,接受并文档化(待裁点 3);测量批遇错本就整批作废,两形态都不产出可用读数。
2. **微观连接序对未来订阅者**:若未来有人在 run 途中向 process_frame 新增连接,常驻连接与挂尾连接的相对序会分叉——现库零此场景,登记为实现期 T0 实查项+代码评审注记。
## 6. gdstyle 键账预期(逐规则核对)
| 规则 | 预期 | 依据 |
|---|---|---|
| quality/await-in-loop(裸键,本案标的) | **消除** | 全文件零 for/while,await 仅函数级一处 |
| quality/allocation-in-loop | 不命中 | 文件零循环;`PlaytestLogger.new()` 在 run 顶层(现状即如此,非循环内) |
| max-function-length ≤50 | 达标 | run 约 22 行、`_step_frame` 约 12 行、`_run_one_level` 删两行后约 10 行 |
| max-branches ≤8 | 达标 | `_step_frame` 一个 if/else;run 一个 if/else |
| max-local-variables ≤10 | 达标 | run 局部 3(logger/stats/autoplay——余者转成员);`_step_frame` 局部 1 |
| max-returns ≤6 | 达标 | 全 void |
| max-parameters ≤5 | 达标(临界持平) | `_run_one_level` 5 参逐字保持;新函数 0 参 |
| max-class-variables ≤15 | 达标 | 现 5+新增 6 成员=11(`_batch_finished` 信号若计入则 12)——成员皆 run 期活承载,非凑数袋 |
键账流程:键消失后闸判定即绿(消失键不参与红判定);基线死键由批末用户人工 `--refresh` 自然清去(16→15,降幅 <10%,不需 `--force`)。
## 7. 行为零变化风险点
1. **测量读数分布**:stats/JSONL/报告是 (种子, atk, hp) 纯函数、帧时点不进值——结构上零漂移;执行证据=双实现对拍逐位+探针 ⑤ 输出四串断言。
2. **探针断言面**:⑤ 守卫环语义依赖浮窗运行态贯穿整批——本设计还原该语义(§2.3)→ 探针由「静态推演红」转绿;探针其余段(①–④、⑥–⑩)零触碰。
3. **发布态零影响**:浮窗角标 `_debug_entry` 门控(`main.gd:200`,发布态恒隐、浮窗无 UI 开启口——系统测试与冒烟既有断言面在役);tune_sim 全链路发布态不可达,本改动不触任何发布路径。
4. **生命周期**:控制器由 `main._tune_sim` 应用期持有(RefCounted 不因帧回调悬挂);`is_connected` 守卫防信号绕过 disabled 的二次 run 造成双连接双步进;收尾先断连防再入;`_batch_finished` 发射时 run 自身的 await 连接恒在位(不存在零听众发射——n=0 路径不经 emit)。
5. **并发暴露面**:`_on_tune_simulate` 无 is_running 早退(现状即无,本设计不新增——守卫=按钮置灰〔还原后贯穿整批〕+两层调试入口 is_running 互查);与还原前相比,运行态中途置假的再入洞被顺手封死(还原语义的附带收益,申报面见待裁点 1)。
## 8. 验收载体
| # | 载体 | 判什么 | 入闸 |
|---|---|---|---|
| 1 | T0 实跑复核:standee_fx_sweep 单套件+probe_gate --full | 确认 §2.3 潜伏红现状(改动前读数) | 开工首步 |
| 2 | wd8 三断言〔wd8〕(既有,零改动) | 每局运行态真/收尾运行态假+报告注入/run 可等待——**卡内须显式申报该套件**(套件名与涉案文件无字面关联,diff 推导可能漏选) | run_all 关联档 |
| 3 | 双实现对拍配对套件(新增,§5) | 帧索引序列/运行态序列/进度串/stats 逐位/报告逐字——五面对拍 | run_all 关联档 |
| 4 | ui_tune_probe ⑤(既有,零改动) | 真实 UI 全链路 N=10:守卫环完成+报告四串+运行期钮禁用 | probe_gate --full |
| 5 | 批末 `run_all_gates.sh --code` | 所选域全绿;static_scan S13 对账确认 await 键消失、无新键 | 批末 |
## 9. 估时
| 项 | 估时 |
|---|---|
| T0 现状复核(两断言面实跑) | 0.25 工作日 |
| 控制器重构(§4.1 草图落码+头注契约行) | 0.25–0.5 工作日 |
| 双实现对拍(夹具+配对套件) | 0.25–0.5 工作日 |
| 孤立验证+批末代码域闸+键账对账 | 0.25 工作日 |
| **合计** | **1–1.5 工作日** |
## 10. 待裁点清单
1. **潜伏红处置(必裁)**:现码 `_run_one_level` 尾部两行与 wd8/探针 ⑤ 静态矛盾(§2.3)。推荐:随批还原「run 收尾单次置 false」,作为已申报行为改动进卡(T0 实跑确认现状后施工);该还原同时封死运行中途的模拟再入洞。若用户掌握「每局置 false 系有意行为」的背景,请指出——但该选择下 wd8 与探针 ⑤ 必红、批不可绿,需另行裁决断言面处置。
2. **双实现对拍是否入批**:推荐入(把帧相位等价从纸面论证变成当轮执行证据;tests/ 面不入 S13 扫描面、夹具内循环 await 合法)。备选:仅靠 wd8+探针 ⑤(省一测试件,相位等价无执行化证据)。
3. **错误路径差异接受度**:脚本错误下「逐帧重试」对「静默停摆」的差异(§5 缺口 1)不可消除。推荐:接受并文档化。备选:`_on_tune_simulate` 加 is_running 早退守卫兜底——+1 行为面、system_test〔wd7〕前置断言随之需复核,代价大于收益。
## 11. 关联文档同步面(随批义务备查,经反哺点通道落文)
- `design/engineering/architecture/architecture.md`「测试与质量域」:S13 测量面豁免登记首条(2026-10-27 tune_sim await)**注销**;同段其余条目(battle_orchestrator 第三条等)不在本案范围。
- `tools/gdstyle_baseline.txt`:await 裸键随批末人工 `--refresh` 消失(禁实现批中途 refresh)。
- `game/tests/README.md` 能力清单:配对套件入表归写卡段(实现批禁写该文件)。
@@ -0,0 +1,171 @@
# 设计——站桩状态件拆分(S13 max-class-variables 键清偿)
设计讨论段过程稿 v1.0——待主会话汇总裁决。
## 0. 一句话结论
把 `_StandeeState` 沿「身份命值 / 资产演出」职责缝拆成两个独立文件类(12 + 11 成员),三个演出探针计数器移到宿主;宿主类变量 19 → 10,两新文件各自 ≤15,站桩外部契约与呈现时序零变化。
**先纠一个前提**:主会话实测的「_StandeeState 成员 13 个、独立成文件即 13≤15 合规」不成立。实测(gdstyle v0.4.0 二进制逐案验证):该文件 `_StandeeState` 真实成员是 **25 个**;基线键账 19 是 gdstyle 一个解析缺陷造出的截断读数——内嵌类里**带行尾注释的属性声明**(`var _intent_scale := 1.0: # 注释`)会把该内嵌类的成员计数截断,其后的成员全部漏记进宿主。把 `_StandeeState` 原样拆成独立文件,键账是 25 不是 13,照样红。
## 1. 机检事实(gdstyle v0.4.0 计数语义,实测五案)
| 案 | 内容 | gdstyle 读数 | 结论 |
|---|---|---|---|
| 1 | standee_body.gd 原文件 | 外层类 19(1:1),内嵌类零命中 | 19 = 顶层 6 + 漏记内嵌 13 |
| 2 | 内嵌 25 成员抽成独立文件 | 该类 25 | **拆出即 25 > 15,方案①不成立** |
| 3 | 内嵌类全普通 var(无属性) | 内嵌类单独报 25,宿主 6 不报 | 无属性时内嵌类独立计数,正常 |
| 4 | 内嵌类 12 普通 var + 带行尾注释属性 + 12 普通 var + 宿主 6 | 宿主 18(6+12 漏记) | 属性行尾注释 = 截断点 |
| 5 | board_cell_unit.gd(旁证) | 基线 30 = 顶层 6 + 漏记 24 | 同一规则,账目吻合 |
有效规则:**类各自计数;内嵌类遇到「属性声明 + 行尾注释」即成员计到该属性为止,其后成员漏进宿主**。standee_body.gd 的截断点 = `_intent_scale`(37 行),其后 13 个成员(`_glyph_rot` 起到 `_flash_count`)漏进宿主:6 + 13 = 19。board_cell_unit.gd 截断点 = `edge`(30 行),6 + 24 = 30,同款吻合。
含义:不动内嵌形态,把三行属性声明移到内嵌类末尾(或删其行尾注释)就能让账变回「宿主 6 / 内嵌 25」——但内嵌 25 仍超阈。**真正的债是状态件 25 个成员本身**,任何合规解都必须把它拆成 ≥2 个类或砍到 ≤15。
## 2. 现状成员全列(31 个:宿主 6 + 状态件 25)
### 2.1 宿主顶层(6 个——全部有外部冻结契约)
| 成员 | 类型 | 写入方 | 读取方 |
|---|---|---|---|
| `st` | _StandeeState | 成员初始化器;`_init` 灌 _owner/_hero_state/_kind | 宿主全部内部函数经 `st.X` 读写;**外部零直访**(全仓 grep 证实) |
| `box` | Vector2(150,176) | battle_stage_view `_sync_layout`(198/208 行);fx_probe 三处 | `_place_portrait`/`_portrait_rect`/`_pedestal_rect`/`content_rect`/`_draw_*` 五域;battle_stage_view 两个 center 出口读 |
| `font` | Font | battle_stage_view `set_world_font`(232/235 行) | `_efont` |
| `slot_row` | StatusSlotRow | battle_stage_view(140/265 行) | `set_effects`/`set_effects_cleared_feedback`/`mark_dead`/`_revive`;battle_stage_view `_sync_companions`;ui_probe/ui_click_probe |
| `_intent_charge` | bool | `set_pending`(源码锚行 194)、`mark_dead` | `_play_intent_motion`;standee_fx_sweep_test 直读(103 行) |
| `has_world_hp_bar` | true 常量 | 无(声明即终值) | ui_probe 141 行 |
### 2.2 _StandeeState(25 个)
| # | 成员 | 类型 | 写入方 | 读取方 |
|---|---|---|---|---|
| 1 | `_owner` | Node2D | `_init` | 三个属性 setter(queue_redraw) |
| 2 | `_kind` | String | `_init` | `set_hero_state`/`_revive`/`_portrait_glyph`/`_draw`/`_draw_hp_bar`/`_portrait_color` |
| 3 | `_portrait_sprite` | Sprite2D | `set_portrait_texture`/`_place_portrait` | 同函数 + `_draw_portrait`/`set_hero_state`/`_settle_hero_idle`/`portrait_probe` |
| 4 | `_portrait_tex` | Texture2D | `set_portrait_texture` | 仅 `_place_portrait` 判空(与 sprite.texture 冗余) |
| 5 | `_hero_tex` | Dictionary | `register_hero_state` | `set_hero_state`/`_settle_hero_idle`/`hero_state_probe` |
| 6 | `_hero_state` | int | `_init`/`set_hero_state`/`_settle_hero_idle`/`_revive` | `set_hero_state`/`hero_state_probe` |
| 7 | `_state_revert_tw` | Tween | `set_hero_state` | 同函数(重启先杀) |
| 8 | `_order` | int | `_set_order` | `_draw_hp_bar`(顺位徽标) |
| 9 | `_intent_glyph` | String | `set_pending` | `intent_probe`/`_draw_intent_badge` |
| 10 | `_intent_col` | Color | `set_pending` | `_draw_intent_badge` |
| 11 | `_intent_visible` | bool | `set_pending`×3/`mark_dead` | `intent_probe`/`_draw_intent_badge` |
| 12 | `_intent_scale` | float(属性→重绘) | `_play_intent_motion` 的 tween | `_draw_intent_badge` |
| 13 | `_glyph_rot` | float(属性→重绘) | `_play_intent_motion` 的 tween | `_draw_portrait` |
| 14 | `_display_name` | String | `set_data` | `display_name`/`name_line_probe`/`_draw_armor_name_line` |
| 15 | `_enemy_id` | String | `set_data` | `enemy_id`(d12 解析主键) |
| 16 | `_armor` | String | `set_data` | `name_line_probe`/`_draw_armor_name_line` |
| 17 | `_dead` | bool | `mark_dead`/`_revive` | `set_data`/`set_hero`/`is_dead`/`flash_hit`/`_portrait_glyph`/`set_pending`/`mark_dead` |
| 18 | `_hp_max` | float | `set_data`/`set_hero` | `_set_hp`/`_draw_hp_bar` |
| 19 | `_hp_cur` | int | `_set_hp` | `_draw_hp_bar`(数字即时值) |
| 20 | `hp_value` | float(属性→重绘+clamp) | `_set_hp` 的 tween | `_draw_hp_bar`(条宽) |
| 21 | `_hp_tween` | Tween | `_set_hp` | 同函数(重启先杀) |
| 22 | `_hp_flash_tw` | Tween | `flash_hit` | 同函数(重启先杀;回色读 `_dead`) |
| 23 | `_death_shards` | int | `_spawn_death_shards` | `fx_probe` |
| 24 | `_hit_sparks` | int | `_spawn_hit_spark` | `fx_probe` |
| 25 | `_flash_count` | int | `flash_hit` | `fx_probe` |
### 2.3 外部触面(拆分边界 = 全部保持)
写状态的外部方只有 battle_stage_view(box/font/slot_row 三 var + 全部经方法)与 fx_probe(box 三处);读面 = 两个 center 出口、六个 probe 出口、`_intent_charge` 测试直读、theme_projection_test 三条源码锚断言(679–683 行:`GOLD_BRIGHT` 顺位墨、`HERO_BLUE_BRIGHT`/`GOLD_BRIGHT` 护甲墨、`_intent_charge = pid in CHARGE_SKILL_IDS`)——三条锚所在函数(`_draw_hp_bar`/`_draw_armor_name_line`/`set_pending`)**全部留在宿主且锚行逐字不动**。
## 3. 方案形态评估
### 方案 A(主会话原①):_StandeeState 升格独立文件
**淘汰。** 实测拆出即 25 > 15(机检事实案 2),不削成员不合规;而削到 15 需砍 10 个,全是承重成员(见方案 B 的砍不动论证),等于把 A 逼成 B+拆分。
### 方案 B(主会话原②):原地真实削减 4 个(19→15)
**淘汰。** 被计入 19 的是宿主 6(全部外部冻结:box/font/slot_row/has_world_hp_bar 探针契约面、_intent_charge 源码锚成员、st 本体)+ 漏记的 13(`_glyph_rot`/身份三元组/`_armor`/`_dead`/`_hp_max`/`_hp_cur`/`hp_value`/两条 tween 槽/三个探针计数)。逐个过堂:身份三元组合一个字典 = 丢类型的凑计数袋(违反 code-conventions §1.1①⑤);三个探针计数合一个字典同理且键变字符串;`_hp_cur` 与 `hp_value` 一个是即时目标一个是 tween 滞后值,不可互推;两条 tween 槽的重启语义各自独立;`_glyph_rot` 是 tween 目标属性。**诚实削减余额 ≈ 0(顶多 `_portrait_tex` 一个冗余成员)**,−4 凑不出来。
### 方案 C(推荐):沿职责缝拆两个独立文件类 + 三个演出探针计数器移宿主
25 个成员按领域分三堆,各自命得出名字:
**新件一 `game/presentation/views/standee_vitals.gd`「站桩身份与命值态」(12 成员)**
- 成员:`_owner`、`_kind`、`_display_name`、`_enemy_id`、`_armor`、`_order`、`_dead`、`_hp_max`、`_hp_cur`、`hp_value`(属性→重绘+clamp)、`_hp_tween`、`_hp_flash_tw`。
- 职责语句:站桩是谁、活没活、血量几何的唯一账面——身份五元组(种类/名/id/护甲/顺位)+ 存活位 + 血量账与两条血量系 tween 槽。
- 单一变化原因:战斗结算快照投影的字段形态(set_data/set_hero 投影什么它记什么)。
- 迁入行为(防纯数据袋):`apply_hp(hp)`=原 `_set_hp` 整体搬移(clamp、重启 `_hp_tween`、tween 写 `hp_value`);`hp_value` 属性 setter 逐字。`_hp_flash_tw` 归此件:`flash_hit` 的回色分支读 `_dead`,与存活位同域。
- extends **RefCounted**(godot-master 判据:瞬态逻辑数据包、随宿主生灭、零序列化零 Inspector——Resource 的共享/.tres 语义此处零收益)。
**新件二 `game/presentation/views/standee_motion.gd`「站桩资产与演出态」(11 成员)**
- 成员:`_owner`、`_portrait_sprite`、`_portrait_tex`、`_hero_tex`、`_hero_state`、`_state_revert_tw`、`_intent_glyph`、`_intent_col`、`_intent_visible`、`_intent_scale`(属性→重绘)、`_glyph_rot`(属性→重绘)。
- 职责语句:站桩的资产挂点与一次性演出——立绘精灵落位与换装、主角三态注册与 0.35s 短驻回归、意图徽标弹入动画。
- 单一变化原因:美术素材落位规则与演出编排设计(立绘 48px 档、三态帧档、§4.6.4 三档运动签名)。
- 迁入行为:`set_portrait_texture(tex, flip, box)`(原函数整体搬移,box 由宿主传入——box 是宿主冻结 var);`register_hero_state`;`apply_hero_state(state, is_hero)`(原 `set_hero_state`,唯一改形 = `st._kind != "hero"` 早退改参判 `is_hero`——早退序逐字);`reset_state()`(原 `_revive` 内「`_hero_state = RESET` 强制绕同态早退」两拍的 encapsulation);`play_intent_motion(charge)`(原 `_play_intent_motion`,`_intent_charge` 改参传入);`state_probe()`。
**宿主 standee_body.gd 保留(类变量 10)**
- 五个冻结 var 原位 + `st`(vitals 实例,**名字保留**——约 40 处引用与 tween 路径串 `"st.hp_value"` 零改)+ `mo`(motion 实例,命名待裁)+ 三个演出探针计数器 `_death_shards`/`_hit_sparks`/`_flash_count`。
- 计数器归宿主的内聚依据:唯一写入方 = 宿主演出函数(`_spawn_death_shards`/`_spawn_hit_spark`/`flash_hit`),唯一读取方 = 宿主 `fx_probe()` 出口——仪器跟着驱动它的函数走;同时给 vitals 让出余量(15 满额 → 12)。
- 保留函数:`_init`、`set_data`/`set_hero`(跨两域编排)、`set_effects`/`set_effects_cleared_feedback`(slot_row 域)、`set_pending`(分档计算 + 源码锚行,字段写改指 mo)、`mark_dead`/`flash_hit`/`play_hit_impact`/`_spawn_*`/`_revive`(跨域演出编排)、`_draw` 全族与几何函数(绘制是宿主 CanvasItem 职责)、六个 probe/display_name/enemy_id/is_dead 出口(外形零变,体内前缀改指)。
接线形态:**保持 `_owner: Node2D` 直回引,不改 Callable 注入、不改信号**。依据:①现状形态,setter 体逐字(`_owner.queue_redraw()`)即重绘时序零漂移——tween 每帧写属性 → setter 同步触发,正是「弹入动画逐帧重绘」的承载;②Node 非 RefCounted,state→宿主回引无环引用泄漏(与 BattleFxHost 场景不同——那边是两 RefCounted 互持才禁双向);③queue_redraw 是 CanvasItem 公开 API,不属「件回调宿主私有族」禁令射程。
淘汰的变形:**两内类同居主文件**(diff 更小)——依赖成员排序躲解析缺陷(属性须排各类末尾),未来任何人往类中部加一个带注释属性就静默漏账(基线恶化闸要到 19→29 才红,9→15 区间六格漂移无感知);两新件独立文件则完全脱离该缺陷的作用面。**改属性行注释形态躲缺陷**同理淘汰——赌解析器怪癖不如离开怪癖作用面。
## 4. 写入路径对账(外部写入方零改动清单)
| 外部触点 | 现状 | 改后 |
|---|---|---|
| battle_stage_view 140/265 行 `slot_row =` | 宿主 var 直写 | 不变(var 原位) |
| battle_stage_view 198/208 行 `box =` | 宿主 var 直写 | 不变;box 仍是无 setter 普通 var,**不触发重绘是现状语义**(重排后的呈现由后续 set_data/字体注入等 queue_redraw 承载),设计不补挂不拆挂 |
| battle_stage_view 232/235 行 `font =` + `queue_redraw` | var 直写 | 不变 |
| battle_stage_view 132–138/267 行 set_portrait_texture/register_hero_state | 宿主方法 | 同名宿主方法保留(1–2 行转调 mo,box 作参),battle_stage_view 一行不改 |
| battle_stage_view 313/316/388 行 set_hero_state | 宿主方法 | 同名保留,转调 `mo.apply_hero_state(state, st._kind == "hero")` |
| battle_stage_view 333–335 行 play_hit_impact/flash_hit/mark_dead | 宿主方法 | 不变(宿主保留) |
| hud_presenter 77/78/137/162/163 行 set_hero/set_effects | 宿主方法 | 不变 |
| fx_probe/ui_probe/ui_struct_probe/ui_click_probe 全部读数 | 六 probe 出口 + box/has_world_hp_bar/slot_row | 出口外形零变(fx_probe 改读宿主计数器、intent_probe/portrait_probe 前缀改指 mo) |
| standee_fx_sweep_test 103 行 `s1._intent_charge` | 宿主 var 直读 | 不变(成员原位) |
| 内部 tween 路径串 | `"st.hp_value"`(vitals 成员名保留 → 零改);`"st._intent_scale"`/`"st._glyph_rot"` | 改 `"mo._intent_scale"`/`"mo._glyph_rot"`(搬进 mo 的同一函数体内) |
重绘/重排时序零变化论证:三个属性 setter 体逐字(`_owner.queue_redraw()`);tween 目标路径只换持有者前缀、写序不变;box/font/slot_row 写入面与现状同拍同序(battle_stage_view 一行不改 = 接线时序恒等)。
## 5. gdstyle 键账预期(逐文件 ≤15)
| 文件 | 类变量实数 | 基线对账 |
|---|---|---|
| standee_body.gd | **10**(5 冻结 + st + mo + 3 计数器) | 基线登记 19,实数 10 < 19 = 改小不红 |
| standee_vitals.gd | **12** | 无基线键,12 ≤ 15 = 零命中 |
| standee_motion.gd | **11** | 无基线键,11 ≤ 15 = 零命中 |
函数级键:**零函数迁入新键**——六个搬移函数逐字搬运(仅前缀与两处改参),长度/分支/局部/返回/参数全在原值内(最大者 `apply_hero_state` 4 参数 4 分支);宿主新增转调壳 1–2 行零键。基线不随批刷新(改小即绿;收账归后续全清批人工 `--refresh`,须用户批准——与 battle_orchestrator 50→38 先例同口径)。
## 6. 行为零变化风险点
1. **tween 属性路径串**:`"st.hp_value"`/`"mo._intent_scale"`/`"mo._glyph_rot"` 拼错 = 运行时属性找不到、动画静默失效。兜底:fx_probe 段的意图弹入断言、hero_state_probe 三态断言、fx_shot_probe 帧取证都在闸内。
2. **hero 三态机改形两处**(`is_hero` 参数化、`reset_state` 封装):早退序与 RESET 哨兵语义必须逐拍对齐——`set_hero_state` 的三连早退(非主角/同态/未注册)条件序不变;`_revive` 强制回 idle 两拍改两调用、顺序不变。
3. **`_hp_flash_tw` 回色读 `_dead`**:flash_hit 留宿主、跨读 `st._dead`,与现状同一拍。
4. **源码锚三条**(theme_projection 679–683):锚行所在函数留宿主且锚行逐字,改造只动同函数其他行的 `st.` 前缀。
5. **成员初始化时序**:st/mo 于成员初始化器构造、`_init` 灰 `_owner`/`_kind`——与现状同形,构造期零属性写早于 `_owner` 赋值。
6. **counters 迁移**:三个计数器无 setter 无重绘语义,纯读写易位;`fx_probe()` 返回键名逐字。
## 7. 验收载体建议(真实入口)
| 载体 | 断言面 | 绑定 |
|---|---|---|
| static_scan S13(gdstyle_gate 回执) | 「基线外新违规 0、恶化 0」+ standee_body 键账 10 | 被测改动本身的直接判据(键清偿),grep 回执可定位 |
| run_all 关联套件 | standee_fx_sweep_test(_intent_charge 直读、fx_probe().flash_count、enemy_id 解析);theme_projection_test(三条源码锚) | 拆分后宿主成员与源码锚零变 |
| probe_gate --full | fx_probe 段(碎裂 5/火花 6/闪白计数/三态切换/死亡残位 idle);ui_probe(intent_probe 三档、name_line_probe、portrait_probe、has_world_hp_bar、slot_row);ui_struct_probe ⑥standee 出框断言;ui_click_probe slot_row tooltip | 外部契约面逐一可达 |
| render_gate | fx_shot_probe 取证 + 战斗舞台 golden | 站桩呈现像素级零变化 |
| run_smoke / run_system_test | 恒跑保险 | 活性 |
对照表口径:本批为非行为改动(结构重组)逐行申报 + 既有断言面全绿作呈现零变化证明;S13 键账数字即键清偿判据,无需新增断言。
## 8. 估时
写卡段不计。实现批(worktree):宿主改造与函数搬移 ≈2h;两新件与头注(≤8 行、无反向链接)≈0.5h;闸跑(S13 + run_all 关联 + probe_gate --full + render_gate + 冒烟/系统)与取证 ≈1.5h;对照表与实现报告 ≈0.5h——**合计 ≈0.5 工作日**。
## 9. 反哺点(预登记)
1. architecture.md「模块归属·呈现层」表登记两新件(standee_vitals/standee_motion,各一句职责)。
2. 相邻发现(不属本批):board_cell_unit.gd 内嵌类 `_CellPaintState` 27 成员受同一 gdstyle 解析缺陷截断(基线 30 = 6 + 24 漏记),属 gdstyle 存量债同族,是否立卡清偿待裁。
3. `_portrait_tex` 与 `_portrait_sprite.texture` 冗余(单一事实源可归一)——本批不动(零变化优先),留债册。
## 10. 待裁点
1. **方案形态确认**:推荐案 C(两独立文件 + 计数器归宿主)vs 淘汰案 B(原地 −4,凑不出)与两内类变形(赌解析缺陷)。前提修正:原①「拆出即合规」实测不成立。
2. **探针计数器落点**:宿主(推荐——写入方/读取方同在宿主,vitals 让出余量)vs vitals 内(15 满额零余量,快照投影类加一个字段即红)。
3. **motion 实例成员命名**:`mo`(推荐,短、域对)vs 其他;vitals 实例沿用 `st`(引用面与 `"st.hp_value"` 路径串零改)。
4. **基线收账时点**:本批不刷新(改小即绿,先例口径)vs 随批人工 `--refresh`(须用户批准)。
@@ -0,0 +1,236 @@
# 设计——组合根注册面(S13 真修复:main.gd 类变量归 15)
状态行:设计讨论段过程稿 v1.0——待主会话汇总裁决(2026-10-29)
## 0. 背景与判据来源
用户 2026-10-29 裁「不允许任何豁免」:main.gd 的 S13 键(`game/presentation/main.gd|quality/max-class-variables = 49`,阈值 15)必须真实修复,architecture 在册的 S13 豁免登记(「组合根类变量面即探针契约面」)随批注销。主会话已点头的主方向:把屏壳+覆盖层一级句柄收进一个「注册面/接口层门面」件,探针从 `main.X` 改走注册面地址。
本设计的判据来源:
- code-conventions §1.1 拆分边界纪律五条(职责轴拆分、集体身份、过阈值只作发现信号、拆不出即停卡、禁无效成员别名)与 §1.3 依赖单向(组合根=main.gd+其构造注入的组合根拆件)。
- architecture「呈现层装配与会话生命周期」「模块归属·呈现层」「测试与质量域」三节。
- godot-master 的 Node 取舍判据("Use RefCounted for logic objects and data containers. Reserve Node for things that must exist in the scene tree")与信号卫生条款;本仓既有先例:ConfigDB 迭代 41 用「三张域容器」解决同构的成员数超标问题,ModalFlow/各交互控制器均为持引用的 RefCounted。
- 源码实查:main.gd 915 行 49 var(实数复核);探针+system_test 的 `main.X` 成员引用 867 处(机械统计,扣除 main.tscn/get_node/get_viewport 等非成员形态);四个流程承接件 `root.X` 引用约 350 处。
## 1. 注册件形态
### 1.1 推荐形态:一个门面+三个域容器(四文件,全 RefCounted,不挂树)
| 新件 | 文件 | extends | 类变量数 | 职责一句话 |
|---|---|---|---|---|
| **界面注册面** | `game/presentation/ui_registry.gd` | RefCounted | **3** | 呈现层界面元素清单:持有三域容器、LAYER_CONTRACT 合同表、`node(key)` 合同寻址、`apply_layer_contract(root)` 唯一落位口 |
| **屏壳与全屏容器域** | `game/presentation/ui_screens.gd` | RefCounted | **9** | 三屏壳、屏内一级子层、全屏态、浮层角标、排播泵节点的句柄册 |
| **战区视图域** | `game/presentation/ui_battle.gd` | RefCounted | **5** | 战斗屏 A–D 区视图与结算演出句柄册 |
| **模态层域** | `game/presentation/ui_modals.gd` | RefCounted | **14** | 十三个模态覆盖层句柄+ModalFlow 栈编排(登记、开合、锁谓词) |
main.gd 新增一个成员 `ui`(类型 UiRegistry),探针与流程件的新地址形如 `main.ui.modals.level_screen`、`main.ui.battle.board_zone`、`main.ui.screens.menu_screen`。
**为什么是三容器而不是一件**: gdstyle 阈值 15 是按文件的,句柄 27 个+flow/row_pacer 共 29 个进一个文件必然超阈、又要开新基线键=留债,违用户裁决出口。 分组轴不是拍脑袋切的——它就是 LAYER_CONTRACT 的 kind 轴(modal/shell/state/float/node)加上 battle.md 的战区轴,三组身份先于本批存在(详见 §2),是「按既有领域轴收拢」,不是「为凑 15 而切」。
**为什么是 RefCounted 不是 Node**: 注册面是纯句柄容器+合同数据,零 `_process`、零绘制、零树位需求——按 godot-master 判据「Node 只留给必须在场景树里存在的东西」应取 RefCounted。 它持有的节点(屏壳/覆盖层/视图)都是 `_build_ui` 一次装配、随 main 同生死的常驻件,不含任何会话期 `queue_free` 对象(局态在 run_scope,留 main),RefCounted 持 Node 引用无悬挂风险;本仓先例充分:ModalFlow、TreasureInteractController、CampShopPresenter、DebugSession、SettingsStore 全是持引用 RefCounted。 若做成 Node 挂树,反而要回答「它占哪个树位」「进不进 LAYER_CONTRACT」「冒烟 V1d 怎么看它」三个新问题,纯增噪声。
**class_name**: 四件均给 class_name(UiRegistry/UiScreens/UiBattle/UiModals),main 里 `var ui: UiRegistry` 类型化;随批跑一次编辑器扫描刷新全局类缓存+同步 .uid(code-conventions 语言纪律 5)。
### 1.2 逐成员去向对账表(main.gd 现有 49 var,三档:进注册面/留 main/消灭)
**进注册面(28)**——成员名在容器内去下划线(变为公共地址面,与 LAYER_CONTRACT 键名对齐):
| # | 现 main 成员 | 去向 | 依据 |
|---|---|---|---|
| 1 | `_menu_screen` | `ui.screens.menu_screen` | 屏壳(kind=shell) |
| 2 | `_camp_screen` | `ui.screens.camp_screen` | 屏壳 |
| 3 | `_adventure_screen` | `ui.screens.adventure_screen` | 屏壳 |
| 4 | `_start_overlay` | `ui.screens.start_overlay` | 菜单屏内一级子层 |
| 5 | `_battle_root` | `ui.screens.battle_root` | 冒险屏内一级子层 |
| 6 | `_inter_overlay` | `ui.screens.inter_overlay` | 全屏态(kind=state) |
| 7 | `_inter_label` | `ui.screens.inter_label` | 过场层附随标签 |
| 8 | `debug_badge` | `ui.screens.debug_badge` | 全局浮层(kind=float) |
| 9 | `_row_pacer` | `ui.screens.row_pacer` | LAYER_CONTRACT kind=node 注册层(节点本体仍 add_child 到 main,注册面只持引用,树位零变化) |
| 10 | `stage` | `ui.battle.stage` | 战斗屏 B 区 |
| 11 | `log_view` | `ui.battle.log_view` | B 区明细带 |
| 12 | `info_panel` | `ui.battle.info_panel` | C 区 |
| 13 | `board_zone` | `ui.battle.board_zone` | D 区(含 toast/fx/board_view/ap_bar) |
| 14 | `settlement_fx` | `ui.battle.settlement_fx` | 结算演出覆盖层 |
| 15 | `legend_overlay` | `ui.modals.legend_overlay` | 模态层(kind=modal,13 件全集) |
| 16 | `node_overlay` | `ui.modals.node_overlay` | 模态层 |
| 17 | `level_screen` | `ui.modals.level_screen` | 模态层(host=adventure_screen,TAG_SCREEN_STATE) |
| 18 | `curio_overlay` | `ui.modals.curio_overlay` | 模态层 |
| 19 | `_end_overlay` | `ui.modals.end_overlay` | 模态层 |
| 20 | `shop_overlay` | `ui.modals.shop_overlay` | 模态层 |
| 21 | `camp_overlay` | `ui.modals.camp_overlay` | 模态层(shell=camp_screen) |
| 22 | `settings_overlay` | `ui.modals.settings_overlay` | 模态层 |
| 23 | `status_panel` | `ui.modals.status_panel` | 模态层 |
| 24 | `career_overlay` | `ui.modals.career_overlay` | 模态层 |
| 25 | `save_select_overlay` | `ui.modals.save_select_overlay` | 模态层 |
| 26 | `confirm_dialog` | `ui.modals.confirm_dialog` | 模态层 |
| 27 | `debug_overlay` | `ui.modals.debug_overlay` | 模态层(TAG_NON_LOCKING) |
| 28 | `_modal_flow` | `ui.modals.flow` | 模态编排与模态层同域(登记/开合/锁谓词的宿主) |
**留 main(14)+新增(1)=改后 15**:
| # | 成员 | 保留理由 |
|---|---|---|
| 1 | `db` | 核心配置读视图——组合根唯一加载单点读取入口(`_ready` 装配) |
| 2 | `run_scope` | 会话承载节点——架构在册「局态一律住 RunScope,组合根经 run_scope.X 读写」;173 处探针引用零迁移 |
| 3 | `save_manager` | autoload 读视图——architecture 在册「main.save_manager 语义零迁移」 |
| 4 | `meta` | autoload 读视图(同上) |
| 5 | `settings_store` | 系统级设置存储——非界面元素(无视觉面),`_ready` 装配、`_quit_game` 落盘、SettingsOverlay 构造注入 |
| 6 | `logger` | 试玩日志器——组合根埋点面(非界面元素) |
| 7 | `_debug_entry` | 调试会话门控(组合根启动态布尔) |
| 8 | `_confirm_consumer` | 确认弹窗分派状态量(组合根自身状态) |
| 9 | `_confirm_consumer_slot` | 分派附随槽号(与 8 同一关注点成对读写) |
| 10 | `_debug` | DebugSession——调试会话状态机持有(逻辑件非界面件) |
| 11 | `_treasure_ui` | TreasureInteractController——组合根拆件(核心写调用代执行) |
| 12 | `_bonus` | CurioInteractController——组合根拆件 |
| 13 | `_camp_pres` | CampShopPresenter——组合根拆件 |
| 14 | `_tune_sim` | TuneSimController——调参测量控制器(逻辑件) |
| 15 | `ui`(新增) | 界面注册面——本设计的唯一新成员 |
这 14+1 全部是「组合根自身状态+拆件引用+autoload 读视图」,正是 §1.1 拆分纪律下组合根该留的最小内聚面;没有一件是因为「计数不够了才留下」的。
**消灭(7)**——全部是别名或一行转发,属拆分纪律⑤明令禁止保留的无效成员:
| # | 成员 | 本体 | 消灭后地址 |
|---|---|---|---|
| 1 | `board_view` | = board_zone.board_view | `ui.battle.board_zone.board_view`(探针惯用 `var bv = ...` 局部承接,每文件 1–2 处) |
| 2 | `ap_bar` | = board_zone.ap_bar | `ui.battle.board_zone.ap_bar` |
| 3 | `_modals` | = _modal_flow.stack | `ui.modals.flow.stack`(ui_struct 登记序断言) |
| 4 | `_row_queue` | 委托属性 = _row_pacer.pending_rows() | `ui.screens.row_pacer.pending_rows()`(main 自身 3 处+pacing_queue_test 1 处;同一 Array 引用,语义不变) |
| 5 | `_seed_edit` | = debug_overlay.seed_edit | `ui.modals.debug_overlay.seed_edit.text`(仅 main._seed_value 内部消费,探针零引用) |
| 6 | `_settlement_stop_pending` | 委托属性(读=timer.is_armed(),写=arm()/disarm()) | `run_scope.settlement_stop_timer` 直呼(ui_click_probe 2 处读+main_adventure_flow 3 处写) |
| 7 | `_deferred_modal` | 委托属性 = _modal_flow._deferred | `ui.modals.flow._deferred`(t17_defer_probe 1 处) |
对账:14(留)+28(进注册面)+7(消灭)=49 ✓;main 改后 = 14+1(ui)=**15,恰在阈值内**。
### 1.3 main.gd 改后类变量实数
**15**(14 留+ui)。gdstyle 的 max-class-variables 语义是「超过 15 才红」,15=绿。此后 main 每想加成员就是过阈红——这正是拆分纪律③的合规用法:过阈值作发现信号,新句柄该进注册面、新职责该拆新件。
## 2. 职责语句+单一变化原因
| 件 | 职责语句 | 单一变化原因 | 集体身份判据 |
|---|---|---|---|
| ui_registry | 「呈现层界面元素清单的唯一事实源——哪些层、什么序、地址在哪」 | 界面元素集合或层序变化(加屏/加覆盖层/改层序) | 它就是今天散在 main 的 LAYER_CONTRACT+_layer_node+一级句柄三样东西的合体;合同键、登记序、句柄址本是同一份清单的三个投影 |
| ui_screens | 「不进模态栈的树位层册——三屏壳与其一级子层、全屏态、浮层角标、排播泵节点」 | 屏壳/全屏态/浮层集合变化 | 集体身份=LAYER_CONTRACT 里 kind≠modal 的项(shell/state/float/node)+屏内一级子层句柄 |
| ui_battle | 「战斗屏四区(A 状态/B 明细/C 数据/D 棋盘)视图与结算演出句柄册」 | 战斗区视图构成变化(battle.md 三区面) | battle.md 三区+演出,是架构文档反复引用的既有概念,非本批发明 |
| ui_modals | 「模态层域——十三个模态覆盖层句柄+模态栈编排(登记/开合/输入锁谓词)」 | 模态层集合或模态编排语义变化 | 集体身份=「被 ModalStack 登记的层」——遮挡互斥、开合同步、锁谓词是这 13 件共享的行为面 |
**禁凑计数袋自检(拆分判据①–⑤逐条)**:
1. 拆分沿职责轴:三容器的轴=LAYER_CONTRACT kind 轴+战区轴,两者都是本批之前就存在的领域轴;过阈值(49→15)只是**发现信号**,不是切分依据。
2. 集体身份:每件命得出名字、说得清「共同表达什么」(见上表),没有一个容器是「剩下的成员」。
3. 过阈值只作动机=违规:本设计若只把 30 个句柄原样搬进一件,那才是凑计数;按领域轴分三域+把合同机器(今天在 main 里同样占职责面的 LAYER_CONTRACT/_layer_node)一并归位,是职责收拢。
4. 拆不出内聚单元须停卡:本设计拆得出(见上),不停卡。
5. 禁无效成员/别名:本批**净消灭 7 个别名/转发成员**(§1.2 第三表)+退役 main 侧六个纯转发方法(§4.2),方向是减不是留。
依赖方向自检(§1.3):注册面只持视图引用、零核心写调用、零信号连接——它不是新的写调用出口,组合根单点装配不变;视图仍经信号到 main(或 main 拆件)再到 core,依赖单向零触碰。
## 3. 探针契约迁移
### 3.1 新地址形态
**推荐**:`main.ui.<域>.<句柄>`(例:`main.ui.modals.level_screen`、`main.ui.battle.board_zone`、`main.ui.screens.menu_screen`)。三段式地址每段都有领域含义(组合根→注册面→域→元素),与 ConfigDB 的 `db.<域容器>.<成员>` 两段式同构——本仓已验证的容器寻址形态。
**备选一(双容器直挂,`main.modals.X` 两段式)**:少一跳,但 main 要放 3 个容器成员,改后 main=16 过阈,只能再靠合并 `_confirm_consumer_slot` 之类凑减员——凑计数味,淘汰。
**备选二(单件+字典存储+方法访问器 `main.ui.layer("legend_overlay")`)**:丢了类型化字段,且约 30 个访问器方法有撞 max-public-methods 默认阈值的风险(board_view 现值 27 已在基线,默认阈值必然更低)=新基线键=留债,淘汰。
### 3.2 改址策略(约 867 处探针/系统测试引用+约 200 处流程件 root.X 引用+main 自身)
**机械映射表**(实现批以脚本生成+对账,人工复核语义位):映射表条目形如 `旧路径 → 新路径`,来源即 §1.2 对账表。三类引用分别处理:
1. **属性读/写(约 750 处)**:`main.<名>` → `main.ui.<域>.<名′>`(`名′`=去下划线后的名)。前缀链式读写在 GDScript 天然支持(`main.ui.modals.debug_overlay.seed_edit.text = "42"` 与现形态同构);探针里 `var bv = main.board_view` 的局部承接习惯使别名消灭的实际改动收敛到每文件 1–2 处。
2. **方法调用(约 110 处,其中绝大多数零迁移)**:组合根流程方法(`_start_adventure_from_menu` 16、`_open_save_select` 7、`_on_save_select_closed` 9、`_on_camp_closed` 6、`_on_battle_end_continue` 4、`_show_debug_overlay` 4、`_resume_from_menu` 3、`_flush_row_queue` 3、`_seed_value` 3 等)**留 main,零迁移**——它们是模式流转与流程入口,本就是组合根职责。真正改址的方法引用只有四条:`main._input_locked()`(18 处)→ `main.ui.modals.flow.locks_input()`;`main._layer_node(key)`(3 处,system_test)→ `main.ui.node(key)`;`main._open_modal/_close_modal`(探针各 1 处+流程件 root. 共约 23 处)→ `main.ui.modals.flow.open/close`;`root._open_modal_after_playback`(2 处)→ `root.ui.modals.flow.open_after_playback`。
3. **字符串键取值(smoke_boot 的 `main.get("<名>")` 6 处)**:`main.get("run_scope")`/`main.get("settings_store")` 零迁移(留 main);其余改 `main.get("ui").<域>.<名′>`(get 只解析一层,后续走公共字段)。
**流程承接件随批同规改址**:main_ui_build 的赋值目标改 `root.ui.<域>.<名′> = ...`;main_adventure_flow/main_overlay_flow/main_debug_flow 的 `root.<名>` 同表映射。构造注入的 context 束(CurioFlowContext/CampFlowContext 的 overlay/toast/start_overlay 等键值)改址取值,注入时点与值不变。
**源码级断言随批重锚(易漏项,实查全量在案)**:
- `source_guard_test.gd` V1d「层序落位单口」:现扫描 main.gd 源码中 `_apply_layer_contract` 之外零 `move_child(`。合同机器迁入 ui_registry 后,重锚为「扫全 `game/presentation/*.gd`:`move_child(` 只允许出现在 ui_registry.gd 的 `apply_layer_contract` 函数体内」(判据同步强化:从扫单文件变扫全目录,比原判据更严)。
- `theme_projection_test.gd` V6:`main_src.contains("debug_overlay.diagnose_requested.connect(_on_diagnose_pressed)")` 字符串断言 → 改为 ui.modals.debug_overlay 新串。
- 其余 main.gd 源码断言(V8 GP 影子账残留检查)为「禁止出现」型,不受影响;`meta_progression_forge_test` 经 `load("res://presentation/main.gd")` 直呼 static `build_adventure_params`——留 main,零迁移。
**改址完整性自检**(验收辅证):映射表驱动的全仓 grep——`game/` 下(探针/tests/flow 四件/main 自身)旧一级路径 `main.<旧名>`/`root.<旧名>`/`self.<旧名>` 残留必须为 0(按 49 名逐名 grep,报告留档)。
### 3.3 architecture 登记句改写建议
「呈现层装配与会话生命周期 §三屏壳与组合根句柄面」现句(含 S13 豁免登记)整句退役,建议改写为:
> 屏成员与覆盖层句柄经**界面注册面**(main.ui,`ui_registry.gd`+三域容器 ui_screens/ui_battle/ui_modals,全 RefCounted)统一暴露;探针挂载假设=`main.ui.<域>.<句柄>` 路径(2026-10-29 用户裁「不允许任何豁免」——原「组合根 main.gd 一级句柄(main.X 路径零迁移)」挂载假设与 S13 豁免登记同批注销,探针面全量改址,行为零变化由 probe_gate/render_gate/冒烟/系统测试四闸主证)。组合根 main.gd 成员面收口为组合根自身状态+拆件引用+autoload 读视图(类变量 15,阈内)。层序唯一事实源=`ui_registry.LAYER_CONTRACT`+`ui.apply_layer_contract()`;模态登记/开合/锁谓词单口=`ui.modals`(ModalFlow 语义零变化)。
「模块归属·呈现层」表同步增四行(四新件),main_ui_build 行的「层序逻辑不在此件——唯一事实源仍是 main.LAYER_CONTRACT」句改指 ui_registry。
## 4. main.gd 改后形态
### 4.1 剩余成员清单
见 §1.2 第二表(14 留+ui,逐个理由在表内,不重复)。文件头注同步改写:组合根职责语句追加一句「界面句柄与层清单在 ui 注册面(ui_registry.gd)」。
### 4.2 接线流程变化
1. **装配入口**:`_ready` 在 `_build_ui()` 之前 `ui = UiRegistry.new()`(容器随门面构造);`MainUiBuild.build(self)` 八步内部赋值目标全部改 `root.ui.<域>.<名′>`,八步顺序、add_child 顺序、连接语句逐条不变。
2. **MainUiBuild 交付物改型**:build 签名不变(仍 `build(root)`),改的是写入目标——从「给 root 造 30 个一级成员」变「往 root.ui 三容器登记」。装配序与 z 序零改动(合同落位仍最后一步)。
3. **合同机器搬家**:`LAYER_CONTRACT` 常量(内容逐字不动)、`_apply_layer_contract()`(root 作参传入)、`_layer_node(key)`(改为 ui_registry.`node(key)` 的 19 键 match)、`_register_modal`(改入 ui_modals 为 `register_layer(m, tags)`,anchors preset+flow.register 语义逐字)四样整体迁入注册面;main 侧不留转发壳。
4. **模态口收口**:main 的六个纯转发方法退役——`_open_modal`/`_close_modal`/`_on_modal_closed`/`_input_locked`/`_open_modal_after_playback`/`_on_pump_ended`。调用方(三个流程件、context 注入束、row_pacer.pump_ended 注入点、信号 connect 的 bind 目标、探针)一律改指 `ui.modals.flow` 真方法;`_replay_locked_click` **留 main**(读 run_scope.locked_click+调 _on_board_action,是组合根行为,作为回调注入 flow 不变)。
5. **`_seed_value()`**:种子框读取改 `ui.modals.debug_overlay.seed_edit.text`(全工程唯一种子框读取处纪律不变)。
### 4.3 LAYER_CONTRACT 与 _apply_layer_contract
合同表条目、顺序、tags、host/shell 标注**逐字零变化**,只换宿主文件;落位算法逐字搬运(move_child 单口语义不变,冒烟 V1d 判据按 §3.2 重锚后仍覆盖「全 presentation 无第二落位点」)。改层序仍只改合同表。
### 4.4 RunScope 生命周期零变化声明
`_begin_session`/闲时会话/整节点 `queue_free` 机制**一字不动**;run_scope 留 main,注册面与三容器**零会话期引用**(不持 adventure/runner/settlement,控制器仍走现值回调),会话更替对注册面完全透明。存活性矩阵第五引用面的四持句柄件+_row_pacer 逐面同源比对断言(system_test V3a–V3i)逻辑零变化,仅 `_modal_flow`→`main.ui.modals.flow`、`_row_pacer`→`main.ui.screens.row_pacer` 两处取址随批改。
## 5. 行为零变化风险点
1. **装配与接线时序**:容器在 `_ready` 建闲时会话之前创建并装配完毕,八步 build 顺序、`_apply_layer_contract` 末位调用点、信号连接顺序逐条不变。风险形态=漏改一处地址→运行期 null 实例 SCRIPT ERROR→被冒烟闸③与探针 error_scan 抓住(不静默)。
2. **模态开合**:ModalFlow 的八个查询/钩子 Callable(start_visible_get/inter_visible_get/settlement_get/rows_empty_get/flush_rows/on_open_sync/on_close_sync/replay_click)注入值不变,仅 `root._start_overlay.visible` 这类 lambda 体内取址改 `root.ui.screens.start_overlay.visible`;开合编排、挂起兜底、点击重放语义零触碰。
3. **会话更替**:注册面零局态引用(§4.4),queue_free 不触及;row_pacer 节点本体仍 add_child 到 main、树位由合同落位,注册面只持引用——第五引用面断言改址后逐面同源比对仍成立。
4. **别名消灭的断言等价性**:board_view/ap_bar/_modals/_row_queue 四件消灭后,探针断言经多一跳取到**同一对象引用**(属性链与别名同指),断言语义逐条等价;system_test V1 的句柄等价断言(`main.board_view == main._adventure_screen.board_view` 型)改址为 `ui.battle.board_zone.board_view == ui.screens.adventure_screen.board_view` 后仍是有效的装配结构断言。
5. **接缝属性消灭的读/写映射**:`_settlement_stop_pending` 读=armed→`is_armed()`、写=arm/disarm→同名方法直呼,映射一一对应且 run_scope 在探针用时点恒非空(_ready 即建,永非 null 契约);`_deferred_modal`→`flow._deferred` 同字段直读。
6. **演出链**:settlement_fx/row_pacer 的 play/enqueue 调用点改址不改序——结算行排播、轮横幅、锁期点击重放的时序敏感面(T17)零触碰;t17_defer_probe 挂起态断言改读 `flow._deferred`,判据不变。
7. **源码级断言漏改**:V1d/V6 两处实查在案(§3.2),随批重锚;若存在未登记的字符串匹配型断言,run_all 关联档跑批暴露——本设计已全量 grep `presentation/main.gd` 引用面确认只有上列两件。
RNG 消费序零触碰(本批不涉任何随机面);PARITY 触面(battle_orchestrator.gd)不在 diff;呈现层订阅禁令、核心写调用唯一出口纪律零触碰。
## 6. 验收载体建议
| 闸 | 载体与判据 |
|---|---|
| probe_gate | **默认段+`--click`+`--full` 全跑**——探针是本批改址的第一消费方(ui_click_probe 1079 行是最大户),只跑默认段会漏最深的改址面;判据=全段退出码 0 |
| render_gate | golden 零差异(shot_probe 七屏+菜单 golden+棋盘 golden)——视觉零变化的主证 |
| run_smoke | V1 装配句柄在位(get() 键改址后)+V2 启动态六条——boot 侧证明注册面装配完整 |
| run_system_test | V1–V9 全绿:LAYER_CONTRACT 寻址(改 ui.LAYER_CONTRACT/ui.node)、句柄等价、存活性矩阵、模态互斥、两连局+续玩 |
| run_all(关联档) | 申报套件:source_guard_test(V1d 重锚)、theme_projection_test(V6 字符串)、pacing_queue_test(_row_queue 改址)、meta_progression_forge_test(static 入口零变化);main.gd 是否按横切面回落全量套件见 §8 待裁点 |
| static_scan | S9 过(四新文件全类型标注);S13 键账:main.gd 键从基线消失、四新文件零新键(§7) |
| 改址完整性自检 | §3.2 的 49 名逐名 grep 残留=0,报告留档(实现报告对照表挂行) |
验收闭合口径(test-conventions §8):判据绑定面=「探针经新地址取到同一节点并驱动真实输入路径」——probe_gate 全绿+系统测试全绿+golden 零差异三件齐,即「改址不改变行为」的真实入口主证;grep 自检只作完整性辅证,不作行为判据。
## 7. gdstyle 键账预期
| 文件 | 改后类变量 | 键账 |
|---|---|---|
| main.gd | **15**(14+ui) | 基线键 `main.gd|quality/max-class-variables = 49` 消失——还债方向下降,注销合法 |
| ui_registry.gd | 3 | 零新键 |
| ui_screens.gd | 9 | 零新键 |
| ui_battle.gd | 5 | 零新键 |
| ui_modals.gd | 14 | 零新键(阈内,余量 1) |
基线 refresh 人工跑(`--refresh`):净减 1 键(约 15 键的 6.7%),低于 10% 骤降守卫,无需 `--force`。四新文件其余质量键(max-public-methods/max-file-length 等)预期零命中——容器纯字段无长函数,match 键数(19)在 max-branches 默认内,若实现批实测出新键按基线外 NEW 红处理、不得开豁免(用户裁决口径统一适用)。
§3.3 的登记句改写即豁免注销文案;「S13 豁免登记第二/三条」(tune_sim_controller、battle_orchestrator)不在本批范围、原文不动。
## 8. 估时与待裁点
**估时:3–4 个工作日**。构成:映射表脚本生成+四文件建件+main/流程件改址 1–1.5 天;探针/系统测试/冒烟改址+源码级断言重锚 1 天;闸循环(probe_gate --click --full/render golden/smoke/system_test/run_all 关联档/static_scan)修复余量 0.5–1 天;architecture 登记句+模块归属表+卡片改动—验收对照表 0.5 天。低于迭代冻结线(5 工作日),可编批。
**待裁点(呈用户裁决)**:
1. **注册面拓扑**:推荐「一门面+三域容器」(§1.1,main=15);备选「双容器直挂」因 main 会过阈 16、需再凑减员而淘汰。是否照推荐案执行。
2. **合同机器是否随批迁入注册面**:推荐迁(LAYER_CONTRACT+_apply_layer_contract+_layer_node+_register_modal → ui_registry/ui_modals,职责闭合);不迁则注册面只管址不管序,main 留合同——两案都可达 15,迁是内聚更优解但多动 V1d/system_test 约 8 处。
3. **消灭与改名清单**:七个别名/转发成员消灭+六个 main 纯转发模态方法退役+容器内成员去下划线(对齐合同键名)——涉及探针断言面写法(`main._input_locked()`→`ui.modals.flow.locks_input()` 等),请整体确认或逐项裁。
4. **run_all 关联档口径**:main.gd 是全探针宿主,保守口径=按横切面回落全量套件;精确口径=只跑 §6 申报四件。请裁跑批档位。
5. **编批**:估时 3–4 天在冻结线内,编入哪个迭代由迭代编排段定。
@@ -1,193 +0,0 @@
# 评估:Dungeon Sweeper 美术资产清单与性能预算
> 版本 v1 | 2026-10-30 | 目标引擎 Godot 4.7.2-stable(`gl_compatibility` / 纯 2D)| 平台 PC Windows 先行 | 设计分辨率 1280×800 基座 + 1920×1080(全局 1.35× 等比)
> 性质:评估过程件,对应美术师交付物「美术资产清单」+「美术规格与预算」两章合并(一次问三事,不拆两份重复)。**未改任何权威文档与 `game/` 文件**;结论若要进 `design/` 走 doc-design 登记 + 用户发令。
> 事实源:`design/art/art-assets-checklist.md`(需求)· `art-status-checklist.md`(现状)· `art-bible.md` §8(尺寸定值单点)· `asset-path-map.md`(路径)· `game/assets/` 实扫 · `game/project.godot` 与 117 份 `.import`(引擎现状)· `design/gdd/ux/battle.md` 板形表 · `game/data/tables/enemy.tres`。
> 显存口径:`art-engine-handoff/scripts/asset_budget.py` 实算;格式按项目真实导入(`compress/mode=0` Lossless → 运行时解码为 RGBA8 = 4 B/px,关 mipmap)。Draw Call 与峰值显存**未真机实测**,只给内控线与估算口径。
## 0. 结论先行
1. **纹理显存不是瓶颈**:现状 126 张 PNG 解码后合计 **0.82 MB**,占项目内控线 96 MB 的 0.85%。
2. **满配试算 39.95 MB**,占内控线 41.6%,余量 56.05 MB(≥20% 达标);前三项占 96.9%,压显存只需盯营地场景图。(营地由 9 张拆为 10 张:新增 `scene_camp_wall` 围墙层,按细条 `(0,240,1280,70)`=0.34 MB 计,不做全幅;较原口径净增 0.34 MB。)
3. **真瓶颈在 Draw Call 与包体结构**:196 格棋盘 + 碎图各自独立纹理,最重一屏粗估 400–600 次;磁盘 6.87 MB 中字体独占 6.68 MB(97%)。
4. **导入设置现状正确,无需改**:117 张全 Lossless + mipmap 全关 + 全局 Nearest,与像素风四纪律一致;非 2 幂尺寸在当前 PC Lossless 下不产生补齐,脚本 warn 可忽略。
5. **1920×1080 档不新增纹理**:全局等比缩放复用同一份资源,显存与档位无关。
## 1. 目标引擎与导入基线
### 1.1 工程侧已核事实(实测,非文档推断)
| 项 | 值 | 来源 |
|---|---|---|
| 引擎 | 4.7.2-stable,`config/features=PackedStringArray("4.7")` | `project.godot` |
| 渲染方法 | `gl_compatibility`(PC OpenGL Compatibility) | `project.godot` |
| Stretch | `canvas_items`,1280×800 视口;1920 档 aspect keep | §8.1/§8.2 |
| 默认过滤 | `default_texture_filter=0`(Nearest) | §8.2,全局像素风基线 |
| 导入类型 | `CompressedTexture2D`,`vram_texture: false`,117/117 | `.import` 全量 |
| 压缩 | `compress/mode=0`(Lossless),117/117 | `.import` 全量 |
| Mipmap | `mipmaps/generate=false`,117/117 | `.import` 全量 |
| 3D 检测 | `detect_3d/compress_to=1`(2D 项目不触发) | `.import` 全量 |
| 透明边 | `process/fix_alpha_border=true`,117/117 | `.import` 全量 |
| 字体 | `theme/custom_font` = Fusion Pixel 单套 TTF | §3.6 清单已定稿 |
**Lossless 的显存真相**:`compress/mode=0` 只压缩磁盘上的 `.ctex`,运行时仍解码成 RGBA8 上传显存(`vram_texture: false` 佐证),故显存一律按 **4 B/px** 计,不按 PNG 文件大小计。这是本次全部试算的口径。
**非 2 幂 warn 的边界**:实扫 126 张中大量 20×20 / 46×48 / 66×94 等非 2 幂尺寸。在当前 **PC + Lossless** 下不补齐、不影响压缩,脚本提示可忽略;若日后转 VRAM 压缩或上移动端/小游戏,该项即变为硬约束(无法压缩或图集补齐),属「待实测项」。
### 1.2 Godot 4.7 导入设置对照表
按 `engine-import.md` 逐项填,只列目标引擎列与项目现状;3D 相关项因纯 2D 标不适用。
| 项 | 通用要求 | Godot 4.7 项目现状 | 判定 |
|---|---|---|---|
| 纹理类型 | 2D 项目用 Sprite2D / TextureRect | `CompressedTexture2D` | ✅ |
| 压缩 | 像素风 = 关闭压缩或无损 | Lossless(117/117) | ✅ 正确;插画级大图是否转 VRAM 压缩待裁 |
| sRGB | 颜色图勾 sRGB | 走 PNG 色彩空间默认,`hdr_as_srgb=false` | ⚠ 建议显式逐张标注色彩空间(待核,无风险) |
| Mipmap | UI / 精灵 / 特效关闭 | 全关 | ✅ |
| 过滤 | Point(像素风) | 全局 Nearest;显式 LINEAR 豁免仅 vignette / gradient_base / beams 三件,已入册 | ✅ |
| 九宫格 | StyleBoxTexture 设边距 | `scene_stage_plaza` 48×12 横向拉伸、顶缘 2px 不随拉伸变形;UI 面板走主题样式盒 | ✅ 边距需随件填,不靠记忆 |
| 图集 | 同屏资产归同组 | **现无图集**,126 张独立纹理 | ⚠ Draw Call 处置方向,待工程评估 |
| 字体 | 动态字体优先,授权干净 | Fusion Pixel 单套,SIL OFL 1.1 在册 | ✅ |
| 序列帧 | 播放器关插值、行列写进规格 | 帧级素材未产;帧数已冻结(待机 4 / 攻击 6 / 受击 2,§8.4) | ⏸ 待产 |
| 3D 模型 / 法线 / PBR / LOD | 单位轴向、OpenGL 法线 | **不适用**(纯 2D,`mdl` / `tex` 类为空) | — |
## 2. 资产清单(运行时资源,十类逐一过)
### 2.1 十类现状总表
优先级沿用 `art-assets-checklist.md` 的 P0–P3 口径(玩法依赖,非排期);状态取自 `art-status-checklist.md`。前缀为美术师通用分类,项目文件命名以 §8.3 为准(见 2.3)。
| 类 | 前缀 | 项目对应资产 | 在盘件数 | 状态 | 优先级 |
|---|---|---|---|---|---|
| 角色 | `char` | 主角 B 区三态立绘 + 棋盘小人 32×32 四向 | 13(`art/character`) | ✅ 三态已接 | P1 |
| 怪物 | `mon` | 八敌站桩立绘(36–94 逐键定档) | 13(同上,含敌) | ✅ 已服役 | P1 |
| 场景 | `env` | 砖面/地形 `terrain_*` 三关换皮、封印印记、舞台地台 | 64(`art/board`)+1(`art/scene`) | ◐ 砖面程序化观感待升级 | P2 |
| UI | `ui` | 面板/按钮/进度条/节点图容器 | 33(`art/ui`) | ◐ 面板与节点图占位 | P2 |
| 图标 | `icon` | 状态九枚、格面徽章 19、护甲三枚、柜台四枚、节点四类 | 12(`assets/ui/icons`)+19 待产 | ◐ 部分在役 | P2 |
| 特效 | `fx` | 挥铲三帧、打击火花、烟尘碎屑、封印特效 | 3(`art/fx`) | ◐ 程序化在役 | P3 |
| 动画 | `anim` | 意图准备三档、死亡灰化碎裂、弹道密度 | 0(帧级未产) | ◐ 占位符号在役 | P1/P3 |
| 3D 资产 | `mdl` | — | 0 | **不适用** | — |
| 字体 | `font` | Fusion Pixel 单套单字重 | 1 TTF(6.68 MB) | ✅ 已定稿 | P2 |
| 插画 | `img` | 营地场景图 10 张(9 全幅+1 围墙细条)、B 区舞台背景 1280×270 | 0(全占位) | ⬜ 未开始 | P2/P3 |
在盘合计:PNG 126 张(`art/` 114 + `ui/icons/` 12)+ TTF 1 件;磁盘 6.87 MB。**纯 2D,零 3D 资产,无法线/PBR/LOD 需求。**
### 2.2 缺口清单(未 ✅ 项,P0 写清阻塞什么)
| # | 资产 | 类 | 规格(§8.2 定值) | 用途 | 优先级 | 状态 | 阻塞什么 |
|---|---|---|---|---|---|---|---|
| 1 | 战斗一屏样张 | 插画/样张 | 1280×800 双舞台整屏 | 锁剪影/动画/战斗空间/敌人层 | **P0** | ⬜ | 角色终稿、意图动画、演出类全部不得开工(清单 §1.2 硬前置) |
| 2 | 意图准备动画三档 | 动画 | 待机 4 / 攻击 6 / 受击 2 帧,灰度剪影可辨 | 敌方下一拍预告 | P1 | ◐ | 预告从占位符号退场;文字/技能名退出徽标后的唯一承载 |
| 3 | 格面资源徽章 19 枚 | 图标 | 32×32 级,极性=金满框/红缺框 | 九家族正负 + 清图槽 | P2 | ◐ | 无(占位够试玩,观感不达标) |
| 4 | 雷/封印/数字砖面全套 | 场景 | 32×32 瓦片随格边长整格铺满 | 扫雷核心读盘 | P2 | ◐ | 前置格子样张已 ✅,无硬阻塞;观感升级 |
| 5 | 关卡节点图图标组 | 图标 | 四类节点 + 行进器 | 节点图 UI | P2 | ◐ | 正式节点图 UI 设计未成文 |
| 6 | 营地场景图 10 张(9 全幅+1 围墙细条) | 插画 | 2× 源出图 → 降采样 1280×800 | 营地交互重做 | P2 | ◐ | 营地交互重做美术自立批(不占迭代位) |
| 7 | 护甲类型图标三枚 | 图标 | 24×24,显示 1× | 站桩名字行 | P2 | ⬜ | 名字行 ◇/◆ 字形占位退役 |
| 8 | B 区舞台背景 | 插画 | 1280×270,远景+中景两带 | 战斗舞台 | P3 | ⬜ | 临时光柱氛围层由背景吸收 |
| 9 | 受击/死亡/顺位、连锁坍塌、封印特效、弹道密度 | 特效/动画 | 灰化+碎裂退场(禁瞬消) | 战斗打磨 | P3 | ◐/⬜ | 无硬阻塞,样张后排期 |
| 10 | 状态九枚 / 字体 / 主角三态 / 八敌立绘 / 地台 | — | — | — | — | ✅ | 已交付,不列为缺口 |
格子样张 ✅ v3 冻结(2026-09-30 机检 17/17);收益/秘宝图标、封面宣传图、地形变异专属纹理按清单 §5 **明确不在本清单**,不计入预算。
### 2.3 命名口径冲突(呈报)
美术师通用规范为四段式 `<类别>_<对象>_<状态>_v<N>.png`(旧版改名 `_deprecated` 不删);项目 §8.3 已定案为**域键式** `<域>_<对象键>_<状态|变体>[_<序号>].png`,对象键 = 数据表主键(`effect_id`/`reward_id`/`cell_type`/`enemy_id`),文件名键全局恒定禁运行时换图,且素材不入 git、候选与终稿分目录、版本号走归档纪律。
**处置:以项目 §8.3 为准**,通用四段式不覆盖。依据:项目规范已定稿且有代码闸(`standee_asset_check`、图标键契约)依赖该命名;本条仅呈报差异,不擅自改。
### 2.4 产出批次
沿用清单 §6 依赖链,不重排:格子样张(✅)→ 砖面全套;战斗一屏样张(⬜)→ 角色终稿(✅)→ 意图动画 → 演出类;徽章/节点图/效果图标/复用件为独立线可插队;营地场景图归营地美术自立批。**第 1 批基准图未定稿前不排后续批次规格。**
## 3. 性能预算(六项,先预算后规格)
### 3.1 倒推起点:同屏对象数(已核)
| 对象 | 上限 | 来源 |
|---|---|---|
| 棋盘格 | 14×14 = **196 格**(格边长 30px) | `battle.md` 板形表 N=14 |
| B 区单位 | 主角 1 + 敌最多 **3** | `enemy.tres` `unit_count_max` 全表最大 = 3 |
| HUD / C 区 | 数据框、状态槽、按钮组约 60 件 | 现役 UI 结构 |
| 营地 | 背景 1 + 可点物件 7 + 承载件 1 = 9 | 清单 §3.5 |
### 3.2 六项预算表
内控线 = 本项目自定(通用 PC 档为起步值,需实测校准);均留 ≥20% 余量;实测日期栏为「未实测」的项不得当验收结论。
| 维度 | PC 档参考 | 项目内控线 | 现状/试算 | 判定 | 备注 |
|---|---|---|---|---|---|
| 纹理内存 | ≤ 1.5 GB | **96 MB** | 现状 0.82 / 满配 39.95 MB | ✅ | 余量 56.05 MB;可用线(20% 余量)76.8 MB |
| Draw Call | ≤ 800 | **600** | 估 400–600,**未实测** | ⚠ | 留 25% 余量;真机跑最重一屏取峰值 |
| 同屏三角面 | ≤ 100 万 | 不构成约束 | 约 0.14 万(2D quad 2 三角) | ✅ | 远低于档位,仅记录 |
| 同屏粒子 | ≤ 1000 | **450** | 程序化火花/碎屑,未实测 | ⚠ | 建议单次特效峰值 ≤150、同屏 ≤3 |
| 单角色骨骼 | ≤ 150 | **不适用** | 0(无骨骼,序列帧+程序化) | — | 纯 2D |
| 包体(磁盘) | PC 首包不适用 | 记录值 | **6.87 MB**(PNG 0.19 + 字体 6.68) | ✅ | 字体占 97%,压包体先做字体子集化而非压图 |
**内控线 96 MB 的依据**:通用 PC 档 1.5 GB 面向 3D/4K,本项目 2D 单场景全驻留最坏试算 39.95 MB;取 ~2.4× 作内控线,给三关场景、秘宝图标与后续插画留扩展空间,并满足 ≥20% 余量。
### 3.3 纹理内存试算(脚本实算,非估)
| 版本 | 项数 | 合计 | 占内控线 | 余量 | 前三名占比 |
|---|---|---|---|---|---|
| 现状版 | 20 种尺寸 / 126 张 | **0.82 MB** | 0.85% | 95.18 MB | 75.3%(32×32×78 = 0.30 MB、256×256×1 = 0.25 MB、64×64×4 = 0.06 MB) |
| 满配版 | 26 项 / 189 件 | **39.95 MB** | 41.6% | 56.05 MB | 96.9% |
满配增量清单口径(全部 RGBA32、mipmap 关):
| 增量项 | 规格 | 件数 | MB | 占满配 |
|---|---|---|---|---|
| 营地场景图 | 1280×800 ×9 + 围墙细条 1280×70 ×1 | 10 | **35.50** | 88.9% |
| 敌人动画图集 | sheet:64×64 帧、12 帧、6 列、pad 2 → 408×136 | 9 套 | 1.91 | 4.8% |
| B 区舞台背景 | 1280×270 | 1 | 1.32 | 3.3% |
| 徽章/节点/护甲等图标 | 32×32 | 36 | 0.14 | 0.4% |
| 特效帧/粒子贴图 | 64×64 | 6 | 0.09 | 0.2% |
| 主角动画图集 | sheet:48×72 帧、12 帧、6 列、pad 2 → 312×152 | 1 套 | 0.18 | 0.5% |
| 现状存量 | 实扫聚合 | 126 | 0.82 | 2.1% |
按格式聚合:RGBA32 100%(项目全 Lossless)。**现状与满配差 39.13 MB,其中营地 10 张独占 90.7% 的增量。**(围墙层落盘按细条 `(0,240,1280,70)`=0.34 MB,不占 1280×800 全幅大图名额。)
### 3.4 由预算倒推单件规格(≥20% 余量)
1. **大图是唯一约束面**:可用线 76.8 MB 减去非大图 4.45 MB = 72.35 MB;1280×800 @ RGBA32 单价 3.906 MB → **同档大图总量 ≤ 18 张**(18 张 = 70.31 MB,合计 74.76 MB ✅;19 张即 78.67 MB ❌)。营地首批 9 张全幅大图(另加 1 张围墙细条 0.34 MB,不占大图名额)安全,但「三关各 9 张全幅大图 = 27 张」必然触发超线。
2. **触发后的处置优先级**:① 大图换 VRAM 压缩(BC3 = 1 B/px,单价降至 0.977 MB,27 张仅 26.4 MB);② 或降入包分辨率至 960×600。**像素小图不动**——BC 块状伪影会毁像素边缘,且它们只占 0.82 MB。
3. **动画图集省的是 Draw Call,不是显存**:9 套图集 1.91 MB,同帧数逐帧独立 PNG 反而只需 1.69 MB(图集 padding 与补齐多出 0.2 MB)。进图集的收益在合批,别拿它当省显存的理由。
4. **小图/图标无需限规格**:32×32 级 78 张仅 0.30 MB,继续按 §8.2 甲类整数倍纪律产出即可。
5. **1920×1080 档零增量**:全局 1.35× 等比缩放复用同一份资源,不产生第二套纹理,显存与档位无关(§8.2 已裁)。
### 3.5 Draw Call 控制(美术能做的部分)
现状 126 张独立纹理、零图集,是 Draw Call 的结构性来源。最重一屏估算口径(**非实测**):196 格 ×(瓦片纹理 + 程序化覆盖层)≈ 390,B 区 4 单位 × 4 件 ≈ 16,HUD/C 区 ≈ 60 → **400–600 区间**,逼近内控线 600。
| 风险 | 处置方向 | 归属 |
|---|---|---|
| 三关瓦片 64 张交替绘制打断合批 | 同关同族瓦片合并为 `AtlasTexture` | 工程面改动,待裁/工程评估 |
| UI 切图过碎、每图标一材质 | 战斗页 / 营地页 / 节点图分页分图集 | 同上 |
| 特效贴图各自独立 | 特效帧进同一图集,粒子用同材质染色 | 同上 |
| 程序化 `_draw` 覆盖层 | 与纹理绘制混排会断批,排绘制顺序时可收敛 | 同上 |
| 动态字体 | Fusion Pixel 单套已合批,保持 | ✅ 无需动 |
**本报告只列处置方向,不新增需求、不改工程面**;任何一条落地须由用户发令走对应通道。
### 3.6 待实测项(未跑,发起权归用户)
| 项 | 方法 | 输出 | 状态 |
|---|---|---|---|
| 最重一屏峰值 Draw Call | 真机跑 14×14 满敌战斗场景 | 峰值次数 vs 内控 600 | **未实测** |
| 峰值显存 | 真机含营地切场景往返 | vs 96 MB 内控线 | **未实测** |
| 粒子峰值 | 同屏 3 特效叠加 | vs 450 内控线 | **未实测** |
| VRAM 压缩可用性 | GL Compatibility 下试导 BC3 大图 | 画质目检 + 显存实测 | **未实测** |
| 1920 档观感 | 1.35× 非整数缩放目检 | 甲类件宽窄不均是否可感 | 未目检 |
**禁止**用编辑器或模拟器数据当验收结论(实测差 2–3 倍);上表机型与实测日期留空待填。
## 4. 假设与待确认
1. 假设:目标平台 = PC Windows 先行(AGENTS.md),暂不上移动端/小游戏 → 无首包硬限、压缩不走 ASTC/ETC2。
2. 假设:满配 = 营地 10 张(9 全幅+1 围墙细条) + 舞台背景 1 + 9 敌动画 12 帧/套 + 主角 1 套 + 图标 36 + 特效 6;秘宝图标/封面宣传图按清单 §5 排除。
3. 假设:同屏敌人上限 3(`enemy.tres` `unit_count_max` 全表最大=3,已核)、棋盘 N=14(`battle.md` 板形表,已核)。
4. 假设:动画帧尺寸按 64×64 源档均值估(实际立绘逐键 36–94),帧数按 §8.4(4+6+2=12/套);量级不受影响。
5. 待确认:营地 10 张是否同屏常驻(Godot 引用计数不自动卸载,本报告按最坏全驻留计);动画是否走 `SpriteFrames` 图集(影响 Draw Call 估算,不影响显存量级)。
## 5. 不改动声明
未改 `design/art/` 任何权威清单与圣经、未改 `game/` 任何文件;未生成图、未跑测试、未跑 MC(无数值改动)。本报告为过程件,按 `reports/README.md`「吸收即死」:结论若被权威文档吸收即可删,若需落设计文档则走 doc-design 登记 + 用户发令。
@@ -1,19 +1,18 @@
# 需求卡片:Esc 浮窗与营地顶栏批(营地顶部小 HUD 栏 · Esc 三钮浮窗)· 营地交互重做卡⑤
- 版本:**v1.3(现行有效卡)**。留痕:Q1/Q2/Q3 均于 2026-10-18 裁定(甲/甲/甲,见 §10,已裁非待裁);契约 2 随 Q3 升格;卡④ 2026-10-31 已重立为 v3.0 现行有效卡,本卡随卡④ 代码波同行(改动沿革只进 git commit log)。
- 版本:**v1.2**(2026-10-18 grilling 轮次裁定回写——Q1 裁定甲(只营地根态响应,代拍板留痕)、Q2 裁定甲(再按 Esc 关浮窗,推荐案)、Q3 裁定甲(确认 Esc 只在营地语境,推荐案,用户的从严收窄升格为已确认);契约 2 随 Q3 升格;卡④回设计段→本卡排期随④重新立卡后,卡片保留有效)
- 来源:[需求澄清-营地交互重做-2026-10-18.md](需求澄清-营地交互重做-2026-10-18.md)(唯一事实源:⑤裁决 9/10、④结构树语境、⑦切批原则⑤)
- 归属:呈现层/组合根(`game/presentation/`)——营地交互重做五卡之五
- 排期:未编入(2026-10-18 用户令:需求卡片不预占迭代号,批次归属按工作量另裁)
- 开工门:U0(用户 `/iter` 发令)+ 零待裁点(Q1/Q2/Q3 已裁,见 §10)+ grilling 复核门过+ **卡④ 代码波落地后**(卡④ 2026-10-31 已重立为 v3.0 现行有效卡、设计线闭合;本卡浮窗与 HUD 落在卡④ 新建的场景屏上,排期随卡④ 代码波之后,卡片本身有效)
- 开工门:U0(用户 `/iter` 发令)+ 待裁点已裁(Q1/Q2/Q3 均裁定,见 §10)+ grilling 复核门过+ **卡④重新立卡并落地后**(本卡浮窗与 HUD 落在卡④新建的场景屏上——卡④ 2026-10-18 回设计段,本卡排期随④之后,卡片本身有效)
## 0. 前置依赖与并行性
- 前置卡④(营地场景图,2026-10-31 已重立为 v3.0 现行有效卡):Esc 浮窗的「返回主菜单」与顶栏 HUD 都落在卡④ 新建的营地场景屏上;卡④ 设计线已闭合(样张过审 2026-10-31+art-bible v3.24 §6.2)——本卡不可先于卡④ 代码波落地,排期随④ 之后;本卡自身零美术依赖(零新素材、裁决 9/10 已给全),设计前置检查通过,卡片有效。
- **跨卡接口(保持既有名,不改名)**:①场景屏顶栏位(卡④ T2 预留;卡④ v3.0 挂接签名=`camp_scene_view.gd set_hud_band()`,「卡⑤ 填值」);②**营地刷新单口**(卡④ T3 定义;卡④ v3.0 定名 `camp_refresh_bus.gd` 的 `CampRefreshBus.refresh(camp_data: Dictionary) -> void`)——本卡 HUD 刷新挂该单口,**非已退役的 `refresh_camp`**;③子界面返回钮承诺(卡④ T3——Q1 甲案前提:五界面各带返回/关闭钮);④卡④终局落点不变量(T0 互证:现役=终局 continue 回主菜单,`main_adventure_flow.gd:124-143` 终局出口 `_begin_session(false)`,行号 T0 复核;若后续改落点为营地则本卡「返回主菜单」动线须补会话收束)。卡④ v3.0 已原样承接上述四项,接口名无改动。
- 前置卡④(营地场景图):Esc 浮窗的「返回主菜单」与顶栏 HUD 都落在营地场景屏上;**卡④ 2026-10-18 已回设计段**(美术设计定稿未过设计前置闸)——本卡不可先于卡④重新立卡落地,排期随④之后;本卡自身零美术依赖(零新素材、裁决 9/10 已给全),设计前置检查通过,卡片有效。
- **跨卡接口(v1.1 补全)**:①场景屏顶栏位(卡④ T2 预留);②**营地刷新单口**(卡④ T3 定义:各写口尾→现开界面刷新+场景根 HUD 刷新一闸完成)——本卡 HUD 刷新挂该单口,**非已退役的 `refresh_camp`**;③子界面返回钮承诺(卡④ T3——Q1 甲案前提);④卡④终局落点不变量(T0 互证)。
- 卡②的退出游戏钮、现役设置面——本批只复用不重做(契约 3)。
- 与卡④同批或随后(两卡触碰同一新屏)。**探针入口路径依赖卡②③链**:营地交互重做后营地只能经「菜单三钮→进入存档→选档→进档」到达——本卡 V1/V3 探针段隐含依赖该全链在位;卡②③ 工程波已随迭代 33 合回(待办清单 2026-10-18 条实况),探针段全链在位,无挂起前提。
- **多卡共改文件分界(`screen_flow_probe.gd`)**:卡④ T5 改该文件营地键语义(:53→新场景根句柄)与回退段(:119-125);本卡 T3 扩展该文件 Esc 合成段(现 :153-165 已有「选档语境 Esc 零响应」断言)为营地语境 Esc 浮窗断言段。两段按行域分界,各自改各自段,禁互相覆盖;T0 与卡④ 对齐行域。
- **camp 截图/golden 联动**:HUD 栏落营地场景屏会改 camp 截图内容——若本批晚于卡④单跑,卡④ 刚重制的 camp 断言基线必再漂移;若同批,卡④ T5 迁移时点须晚于本卡 T2 HUD 落位(排序约束)。本卡 T2 含「HUD 落位后核漂移热区→限 HUD 区显式更新+呈报」条;现无 camp 逐像素 golden(卡④ 契约 10)。
- 与卡④同批或随后(两卡触碰同一新屏)。**探针入口路径还依赖卡②③链**(v1.1 补明): restructuring 后营地只能经「菜单三钮→进入存档→选档→进档」到达——本卡 V1/V3 探针段隐含依赖该全链在位;若本卡先于卡②③合入,探针段挂起或走中间态断言(仿卡② §9 第 4 条先例)。
- **camp 截图/golden 联动(v1.1 补)**:HUD 栏落营地场景屏会改 camp 截图内容——若本批晚于卡④单跑,卡④ 刚重制的 camp 断言基线必再漂移;若同批,卡④ T5 迁移时点须晚于本卡 T2 HUD 落位(排序约束)。本卡 T2 含「HUD 落位后核漂移热区→限 HUD 区显式更新+呈报」条。
## 1. 目标与完成定义
@@ -22,50 +21,48 @@
- 裁决 10「钥石余额:场景**顶部小 HUD 栏**」(用户原话「先按顶部小HUD栏设计」——provisional 措辞留痕)。
**相对现状,新增了什么**:
1. Esc 浮窗(产品码现无任何键盘快捷键处理——从零新建);
2. 营地场景顶部小 HUD 栏(钥石余额常驻——现营地钥石徽在 CampOverlay 顶栏 `camp_overlay_view.gd:125`,随卡④拆解后由新 HUD 栏承接,落卡④ T2 顶栏预留位)。
1. Esc 浮窗(全仓现无任何键盘快捷键处理——从零新建);
2. 营地场景顶部小 HUD 栏(钥石余额常驻——现营地钥石徽在 CampOverlay 顶栏,随卡④拆解后由新 HUD 栏承接)。
**完成定义**:
1. 营地语境按 Esc 唤起浮窗,浮窗有且仅有返回主菜单/设置/退出游戏三项;浮窗的关闭/取消路径按 Q2 裁定落地;
2. 「返回主菜单」回主菜单(营地场景屏隐藏+选档层同收+主菜单可见);「设置」开现役设置面(语境分支见契约 3);「退出游戏」接现役退出路径;
3. 营地场景顶部小 HUD 栏在位,钥石余额读数=存档单口现值,刷新时机=购买后(挂卡④ `CampRefreshBus.refresh()` 单口)/进档或回营地进入时重读/夹具直写后探针显式触发;
3. 营地场景顶部小 HUD 栏在位,钥石余额读数=存档单口现值,刷新时机=购买后(挂卡④营地刷新单口)/进档或回营地进入时重读/夹具直写后探针显式触发(v1.1 清单化);
4. 浮窗零动效直开直关(生涯页同款契约);新层入 `LAYER_CONTRACT`;
5. 批末重闸按改动域选档全绿;三份 `reports/` 产出物写齐(T4)。
## 2. 现状事实(2026-10-18 实查;2026-10-31 复核行号,开工日 T0 再核)
## 2. 现状事实(2026-10-18 实查;开工日 T0 复核行号)
| # | 事实 | 出处 |
|---|---|---|
| F1 | **产品码零键盘快捷键处理**:`KEY_ESCAPE`/`ui_cancel`/`ui_accept` 在 `game/core/`+`game/presentation/` grep 零命中——Esc 浮窗产品码从零新建,无旧路径可迁。**但探针侧已有键盘合成先例**:`screen_flow_probe.gd:156-160` 用 `InputEventKey`(keycode=`KEY_ESCAPE`)经 `Viewport.push_input(ev, true)` 合成,断言「选档语境 Esc 零响应」(:153-165,卡⑤ 范围外的零实现断言)——键盘事件合成机制已实证,T0 由「从零 spike」改为「复核该先例并迁移到营地语境」。鼠标 `push_input` 先例=`ui_input_probe.gd:84-116`(`InputEventMouseMotion`/`InputEventMouseButton`;原 `game/smoke/` 目录已不存在,全部探针在 `game/probe/`) | `game/probe/screen_flow_probe.gd:153-165`;`game/probe/ui_input_probe.gd:84-116` |
| F2 | 设置面在役:开=`_open_settings()`(`main.gd:444` 薄委托→`main_overlay_flow.gd:7-9`:`start_overlay.visible=false`+`ui.modals.flow.open(settings_overlay)`);关=`_on_settings_closed()`(`main.gd:448`→`main_overlay_flow.gd:11-13`:`ui.modals.flow.close`+**`start_overlay.visible = true` 硬副作用**——营地语境照抄会在关设置后弹主菜单,须语境分支,契约 3)。开合走组合根模态编排口 `ui.modals.flow.open/close`;静态承接件是 main 同名函数逐字搬运、main 侧留薄委托,探针 `main.X` 路径零改动。`_open_settings`/`_quit_game` 菜单钮调用点见装配段(T0 复核行号) | `main.gd:444`/:448;`game/presentation/main_overlay_flow.gd:7-13` |
| F3 | 退出游戏在役:`_quit_game()`(`settings_store.save_settings()` 后 `get_tree().quit()`;无语义副作用,可原样复用) | `main.gd:143-146` |
| F4 | 钥石徽工厂件在役:`UiKit.keystone_badge` 定义 `ui_kit.gd:633`;消费点四处产品码——营地顶栏 `camp_overlay_view.gd:125`/生涯页 `career_overlay.gd:54`/状态面板 `status_panel.gd:32`/选档界面 `save_select_overlay.gd:86`(卡③ 新增),+ `theme_projection_test.gd:853-854` 单测投影断言。HUD 栏复用该件,零新素材 | `game/presentation/views/ui_kit.gd:633`;`camp_overlay_view.gd:125`;`career_overlay.gd:54`;`status_panel.gd:32`;`save_select_overlay.gd:86` |
| F5 | art-bible **v3.24** §6.2 现载「钥石余额:常驻画面顶部的一行小 HUD 栏(高 48px,浮层覆盖,不挤压画面)」(:396);camp.md v2.2 §顶栏(:39-41)同述+「刷新入口=营地刷新单口(卡⑤同口挂接)」——与裁决 10 同向,本批把呈现位从 CampOverlay 顶栏迁场景屏 HUD | `design/art/art-bible.md:396`;`design/gdd/ux/camp.md:39-41` |
| F6 | 层序唯一事实源=`ui_registry.gd:15-35 LAYER_CONTRACT`(`UiRegistry`;`main.gd:5` 头注自陈界面句柄与层清单归 ui 注册面);全仓唯一落位口=`ui_registry.gd:76 apply_layer_contract(root)`(唯一 `move_child` 点);模态登记册序/树序断言=`system_test.gd:94-106`(V1c 合同树序链)。浮窗新槽入该合同表,禁散落 `move_child` | `game/presentation/ui_registry.gd:15-35`/:76;`game/tests/system_test.gd:94-106` |
| F7 | 零动效契约先例:生涯页/状态面板「直开直关」——`ui_struct_probe.gd:379-391 _career_zero_motion_contract`(子树 AnimationPlayer 零命中+视图源码 `create_tween`/`UiKit.motion` 令牌扫描)、:334-341 `_status_zero_motion_contract` 同形 | `game/probe/ui_struct_probe.gd:334-341`/:379-391 |
| F8 | 08「六 · Alpha 不含」载「键盘 / 手柄输入(排 Beta)」行(**:193**——:192 是反雪球机制行)——Esc 属用户明示裁决(澄清⑤裁决 9),与该行的关系须同步注记(反哺点),本批不自扩其余键盘面 | `design/gdd/08-Alpha版本标准.md:193` |
| F9 | **刷新链路实况**:营地侧刷新腿=`camp_overlay.refresh_camp(camp_data())`(`camp_shop_presenter.gd:82/90/102/114/126/139/151/165` 各写口尾,与 `_refresh_presentations.call()` 成对,实数 T0 复核)——`refresh_camp` 是 CampOverlay 方法,**随卡④拆解退役**;`_refresh_presentations`(`main.gd:628-633`)刷 `HudPresenter.refresh(ui.battle.*)`+`_treasure_ui.refresh_slots()`+`_sync_settlement_visuals()`,仍战斗侧、不刷营地视图(营地购买口尾成对调用它属既有行为,卡④ 契约 4 明令「禁顺手统一」);`camp_shop_presenter.gd:50-53 on_camp_closed()` 关营地亦 `_refresh_presentations.call()`;钥石读数单点=`camp_shop_presenter.gd:62 camp_data()` 的 `meta.meta_state.keystone_balance()`;钥石入账在冒险收束、不在营地(`存档序列化.md`)——营地语境无现行入账触发源 | `game/presentation/camp_shop_presenter.gd:50-53`/:62/:82-83;`main.gd:628-633`;`存档序列化.md` |
| F10 | 调试角标:`ui_registry.gd:33-34` 载 `debug_badge` 为 `LAYER_CONTRACT` 末位 `float` 类、不注册 ModalStack;`modal_stack.gd:21-41 open()` 只遍历登记层 `_list` 隐藏上方可见层、不触及 float 类 ⇒ 浮窗开不波及角标节点(结构语义)。**但角标发布态恒隐**:`main.gd:98` `ui.screens.debug_badge.visible = _debug_entry`(缺省 false,迭代 38 卡⑦ 发布态换代),`ui_click_probe.gd:330-333` 断言「设置面开中调试角标不可见(发布态恒隐)」——v1.2「角标恒压浮窗且保持可点/可见」是换代前旧结论,已失实;本批删该运行期断言面(契约 7/T3/V8 同步订正),改以「浮窗登记序+open 只动登记层」结构断言承载;开发期临时启用角标(本地改 `_debug_entry`、不提交)后的浮窗不遮角标观感归用户目检 | `game/presentation/ui_registry.gd:33-34`;`game/presentation/modal_stack.gd:21-41`;`main.gd:98`;`game/probe/ui_click_probe.gd:330-333` |
| F1 | **全仓零键盘快捷键处理**:`KEY_ESCAPE`/`ui_cancel`/`ui_accept` 在 `game/` 全目录 grep 零命中(2026-10-18 实查)——Esc 浮窗是从零新建,无旧路径可迁;现成输入合成先例只有鼠标 `Viewport.push_input`(ui_input_probe.gd:51-63/:657-680,headless 实证),键盘合成须 T0 spike | 全仓 grep 实证;`game/smoke/ui_input_probe.gd:51-63` |
| F2 | 设置面在役:`settings_overlay` 构建+`closed` 接线;开=`_open_settings`(:1055-1057),关=`_on_settings_closed`(:1060-1063,关后**带 `_start_overlay.visible = true` 硬副作用**——营地语境照抄会在关设置后弹主菜单,须语境分支,见契约 3);`_open_settings`/`_quit_game` 现唯二调用点都是菜单钮 | `main.gd:277-279`/:1055-1057/:1060-1063/:333-334(v1.1 行号订正) |
| F3 | 退出游戏在役:`_quit_game`(设置即时落盘后 `get_tree().quit()`;无语义副作用,可原样复用) | `main.gd:500-503` |
| F4 | 钥石徽工厂件在役:`UiKit.keystone_badge`(三处消费先例——营地顶栏/生涯页/状态面板;迭代 17 卡③ Q10 甲工厂化)——HUD 栏复用该件,零新素材 | `camp_overlay_view.gd:82`;`career_overlay.gd:54` |
| F5 | art-bible §6.2 现载「钥石余额常驻顶栏」——与裁决 10 同向,本批是把该呈现位从 CampOverlay 顶栏迁场景屏 HUD | `design/art/art-bible.md:369` |
| F6 | 层序唯一事实源=`main.gd` `LAYER_CONTRACT`;`_apply_layer_contract` 全仓唯一落位口;冒烟 V1d 源码断言判红散落 `move_child` | `main.gd:34-53`/:430-455 |
| F7 | 零动效契约先例:生涯页/状态面板「直开直关」——ui_struct_probe 载 `_career_zero_motion_contract`(子树 AnimationPlayer 零命中+视图源码禁动效令牌扫描) | `game/smoke/ui_struct_probe.gd:313-328` |
| F8 | 08「六 · Alpha 不含」载「键盘 / 手柄输入(排 Beta)」行(**:192**——:191 是反雪球机制行)——Esc 属用户明示裁决(澄清⑤裁决 9),与该行的关系须同步注记(反哺点),本批不自扩其余键盘面 | `design/gdd/08-Alpha版本标准.md:192`(v1.1 行号订正) |
| F9 | **刷新链路实况(v1.1 订正,原结论失实)**:营地侧刷新腿=`camp_overlay.refresh_camp(camp_data())`(CampShopPresenter 各购买口尾与 `_refresh_presentations` 成对调用)——`refresh_camp` 是 CampOverlay 方法,**随卡④拆解退役**;`_refresh_presentations`(main.gd:1293-1298)刷的是战斗侧 HudPresenter+秘宝槽+结算视觉,**营地语境零营地视图触碰**;钥石入账发生在冒险收束、不在营地(存档序列化.md:116)——营地语境无现行入账触发源 | `camp_shop_presenter.gd:85-86`/:93-94 等;`main.gd:1293-1298`;`存档序列化.md:116` |
| F10 | 调试入口全局浮层角标在役(LAYER_CONTRACT 末位 float 类,不注册 ModalStack,任何 UI 不遮挡);ModalStack.open 只隐藏登记层 | `main.gd:51-53`/:312-314;`modal_stack.gd:21-30` |
## 3. 设计契约(红线,违反 = L3 停机呈报)
🔴 **契约 1 · 浮窗三项且仅三项**:返回主菜单/设置/退出游戏(裁决 9)。禁加项(禁「继续冒险」类——营地无冒险可继续)、禁减项。浮窗的关闭路径=Q2 裁定项(再按 Esc 关),不属「加项」争议。
🔴 **契约 1 · 浮窗三项且仅三项**:返回主菜单/设置/退出游戏(裁决 9)。禁加项(禁「继续冒险」类——营地无冒险可继续)、禁减项。浮窗的关闭路径=Q2 裁定项(再按 Esc 关/关闭钮/无关闭三选一),不属「加项」争议。
🔴 **契约 2 · Esc 范围=营地语境(Q3 已确认,2026-10-18)**:浮窗只在营地场景图语境唤起(含其子界面开态——行为按 Q1 裁定的甲案:只根态响应)。**禁扩展到战斗/地图/其他屏**(用户 2026-10-18 确认「只在营地语境」;08:193 键盘面仍排 Beta,本批只落 Esc 一项)。
🔴 **契约 2 · Esc 范围=营地语境(Q3 已确认,2026-10-18)**:浮窗只在营地场景图语境唤起(含其子界面开态——行为按 Q1 裁定的甲案:只根态响应)。**禁扩展到战斗/地图/其他屏**(用户 2026-10-18 确认「只在营地语境」;08:192 键盘面仍排 Beta,本批只落 Esc 一项)。
🔴 **契约 3 · 设置与退出本体零重做、接线允许语境分支**:设置面本体与退出行为零改(F2/F3);**开合接线允许按语境分支**——现役 `main_overlay_flow.gd:11-13 _on_settings_closed` 带「回开始层」硬副作用(`start_overlay.visible = true`),营地语境须分支为「关设置回浮窗不回主菜单」。栈语义正解(F6/modal_stack.gd:21-41):浮窗登记于设置层**之下**(合同表槽位在营地层与 `settings_overlay` 之间,T0 与卡④ 对齐最终槽名),`ui.modals.flow.open(settings_overlay)` 时设置层绘制在浮窗之上遮挡之(open 只隐藏登记序在设置层**之上**的层,浮窗在下不被隐藏),`close` 后遮挡解除、浮窗自然重现——「关设置回浮窗」由栈语义保证;**语境分支点=`_on_settings_closed` 的 `start_overlay.visible = true` 硬副作用**(菜单路径保留、营地浮窗路径跳过),落 `main_overlay_flow.gd._on_settings_closed`(改)。`_quit_game`(`main.gd:143`)无语义副作用,原样复用。
🔴 **契约 3 · 设置与退出本体零重做、接线允许语境分支(v1.1 放宽)**:设置面本体与退出行为零改(F2/F3);**开合接线允许按语境分支**——现役 `_on_settings_closed` 带「回开始层」硬副作用,营地语境须分支为「关设置回浮窗不回主菜单」;正解=浮窗登记于设置层之下,`_open_modal(settings_overlay)` 自动隐藏浮窗、关闭自动恢复(既有栈语义);`_quit_game` 无语义副作用,原样复用。
🔴 **契约 4 · 返回主菜单动线**:营地场景屏隐藏+**选档层同收**(卡④ T3 口径)+开始层恢复;营地语境⇔闲时会话(无冒险会话——卡④ 契约 6「冒险进行中不开营地」+现役终局回菜单并 `_begin_session(false)` 收束推得),故动线本身不含会话收束;**回主菜单后菜单=卡②三钮、断点在档不在菜单露面**(禁实现者自作主张加「继续冒险」钮——那正是契约 1 在浮窗侧禁的);营地每笔消费即时写盘(`存档序列化.md`,行号 T0 复核),回主菜单不写档也无损。
🔴 **契约 4 · 返回主菜单动线**:营地场景屏隐藏+**选档层同收**(卡④ T3 口径)+开始层恢复;营地语境⇔闲时会话(无冒险会话——卡④ 契约 6「冒险进行中不开营地」+现役终局回菜单并 `_begin_session(false)` 收束推得,v1.1 前提成文),故动线本身不含会话收束;**回主菜单后菜单=卡②三钮、断点在档不在菜单露面**(禁实现者自作主张加「继续冒险」钮——那正是契约 1 在浮窗侧禁的);营地每笔消费即时写盘(存档序列化.md:121),回主菜单不写档也无损。
🔴 **契约 5 · 顶栏 HUD 单口读数+刷新挂卡④单口**:钥石余额只经 MetaProgression/SaveManager 访问器单口读(`camp_shop_presenter.gd:62 camp_data()` 的 `keystone_balance()`;禁第二账本、禁视图自算);**刷新挂卡④定义的营地刷新单口**(卡④ v3.0 定名 `CampRefreshBus.refresh(camp_data: Dictionary) -> void`,非已退役 `refresh_camp`——F9);刷新时机清单=购买后(挂单口)/进档或回营地进入时重读/夹具直写后探针显式触发(T2 落定)。
🔴 **契约 5 · 顶栏 HUD 单口读数+刷新挂卡④单口(v1.1 订正)**:钥石余额只经 MetaProgression/SaveManager 访问器单口读(禁第二账本、禁视图自算);**刷新挂卡④定义的营地刷新单口**(非已退役 `refresh_camp`——F9);刷新时机清单=购买后/进档或回营地进入时重读/夹具直写后探针显式触发(T2 落定)。
🔴 **契约 6 · 零动效**:浮窗直开直关,子树零 AnimationPlayer、源码禁 `create_tween`/`UiKit.motion` 令牌(生涯页同款契约,F7);减动效设置项不新增(在役项沿用)。
🔴 **契约 6 · 零动效**:浮窗直开直关,子树零 AnimationPlayer、源码禁动效令牌(生涯页同款契约,F7);减动效设置项不新增(在役项沿用)。
🔴 **契约 7 · 层序纪律+遮挡结论(订正)**:浮窗入 `ui_registry.gd LAYER_CONTRACT`(改层序只改合同表;唯一落位口 `apply_layer_contract()`——F6);禁散落 `move_child`。**与调试角标遮挡的结论**:`debug_badge` 是末位 `float` 类、不注册 ModalStack,`ModalStack.open` 只隐藏登记层 ⇒ 浮窗开不波及角标节点(结构语义);但角标**发布态恒隐**(F10,`main.gd:98` `_debug_entry` 缺省 false),故「角标恒压浮窗且保持可点/可见」不是本批可跑断言面——删该运行期断言,以「浮窗登记序+open 只动登记层」结构断言承载,开发期临时启用角标后的浮窗不遮角标观感归用户目检。另写明一条栈语义防误触 L3:浮窗开会隐藏登记序在其上的已开层(如 debug_overlay),关闭恢复——属既有栈语义非新决策。
🔴 **契约 7 · 层序纪律+遮挡结论(v1.1 落结论)**:浮窗入 `LAYER_CONTRACT`(改层序只改合同表);禁散落 `move_child`。**与调试角标遮挡的结论(v1.1 补,既有纪律已定论、无需用户裁)**:debug_badge 是末位 float 类不注册 ModalStack,ModalStack.open 只隐藏登记层⇒角标**恒压浮窗且保持可点**(树序末位=最顶绘制序,全仓无 `debug_badge.disabled` 赋值)——合同内照此表达。另写明一条栈语义防误触 L3:浮窗开会隐藏登记序在其上的已开层(如调试浮窗体 debug_overlay),关闭恢复——属既有栈语义非新决策。
🔴 **契约 8 · provisional 口径留痕**:裁决 10「先按顶部小HUD栏设计」的「先」字留痕——HUD 栏形态按最小集落地(只承载钥石余额),扩项=新裁点。
**拆分边界纪律适用性判定(req-card 第 15 节/code-conventions §1.1)**:本卡=**新增功能批**——新增 Esc 浮窗视图、营地顶栏 HUD 栏、Esc 键盘输入接线三类件,其余为存量文件接线改造;无「拆分存量单元/收敛/重构」动作,`camp_overlay_view.gd` 四柜台拆解退役属卡④ 职责(本卡不改该文件)。按 code-conventions §1.1 拆分判据五条,本卡不触发拆分/收敛/重构类,故不在设计契约区写拆分红线条款,仅在此写明判定理由。同理 req-card 第 13 节「禁为机检文本保留无效成员」(重构类卡必填)不适用;新增件类的「机检预算互斥=上游缺陷停卡退回写卡段」(第 9/14 节)已写入 §8 L3 与「实现规范预算」节。
🔴 **契约 8 · provisional 口径留痕**:裁决 10「先按顶部小HUD栏设计」的「先」字留痕——HUD 栏形态按最小集落地(只承载钥石余额),扩项=新裁点。
## 4. 范围边界
@@ -73,222 +70,116 @@
**不做**(明示去向):
- 营地场景图本体 → 卡④(本批只在其顶栏位落 HUD+挂刷新单口);
- 选档界面/主菜单/数据层 → 卡③/卡②/卡①(工程波已随迭代 33 合回);
- 选档界面/主菜单/数据层 → 卡③/卡②/卡①;
- 其余键盘快捷键(任意键关闭浮窗/手柄/战斗内 Esc) → 用户未裁,禁自扩(契约 2);
- 设置面/退出路径本体改动 → 无(契约 3);
- HUD 栏扩项(冒险天数/种子等) → 契约 8,扩项另裁;
- 不新建 camp golden(卡④ 契约 10:现无 camp 逐像素 golden,camp 验收=shot_probe 出图+shot_checker 语义断言)。
- HUD 栏扩项(冒险天数/种子等) → 契约 8,扩项另裁。
## 5. 关联文档同步面
> **现行口径**:实现批禁写 `design/` 整目录与根规则文件、两份根流程清单与 `game/tests/README.md`,唯一可写目录=`reports/`(+`game/` 实施本体);下表一律执行为列进 `reports/iter<N>-反哺点-<日期>.md` 反哺点清单(义务格全为「反哺点 · 列清单」类,禁旧「随批」措辞)。待办清单与体验验证清单已迁仓库根(原 `design/gdd/06-*`、`07-*` 路径已不存在)。
> **v1.3 口径**:本批禁写 `design/` 整目录与根规则文件,唯一可写目录 = `reports/`;下表一律执行为列进反哺点清单。
| 文档 | 关联点 | 同步义务 |
|---|---|---|
| `design/gdd/08-Alpha版本标准.md`(v1.13) | :193「键盘 / 手柄输入(排 Beta)」行——Esc 营地浮窗已落地(用户明示裁决,澄清⑤裁决 9),须加注防「Beta 行=本批违例」误读 | 反哺点 · 列清单(行内加注) |
| `design/art/art-bible.md`(v3.24) | §6.2「钥石余额:常驻画面顶部的一行小 HUD 栏」(:396)呈现位从 CampOverlay 顶栏迁场景屏 HUD | 反哺点 · 列清单(权威面零直改,过用户裁决后归文档批) |
| `design/gdd/ux/camp.md`(v2.2) | §顶栏(:39-41)「钥石余额常驻顶部小 HUD 栏、刷新入口=营地刷新单口(卡⑤同口挂接)」实装状态回填 | 反哺点 · 列清单 |
| `待办清单.md`(仓库根) | 本卡登记条(五卡总条第 438-449 行)状态推进 | 反哺点 · 列清单(实现批禁写待办清单) |
| `体验验证清单.md`(仓库根) | 新增目检条(Esc 浮窗三动线/HUD 余额观感/浮窗视觉面)——登记不阻塞 | 反哺点 · 列清单(实现批禁写体验验证清单,入册条目由文档批落) |
| `roadmap.md`(仓库根) | 迭代行编入/状态刷新 | 反哺点 · 列清单(实现批禁写 roadmap) |
| `game/tests/README.md` | 能力行入表(§7 对照表「能力行」列定名) | 写卡段定名(本卡只写卡内能力行文字,README 由主 Agent 统一收口);实现批只核对名实一致,禁写 |
| `game/presentation/*`(浮窗视图/HUD 栏/接线/注册面)、`game/probe/*` | 实现与断言本体 | 实施本体(可写) |
## 卡前·文件结构与职责(T0 前)
定义 T 卡前先列全本批新建/修改文件,一文件一职责。**每个文件行标「行为改动/非行为改动」并指向 §7 对照表行号;「落位」列与「落位与可复用性预检」节互指**(标「新建」的必须能在预检节指到不能复用的理由与唯一落点核查)。行号为开工日 T0 复核对象。
| 文件 | 职责 | 改动类型 | 落位 | 对照表行 |
|---|---|---|---|---|
| `game/presentation/views/camp_esc_overlay.gd` | Esc 浮窗视图:`UiKit.modal_shell` 模态壳+三钮(返回主菜单/设置/退出游戏,退出用 `UiKit.danger_button`)+Q2 再按 Esc 关窗;零新素材 | 行为改动 | 新建 | V1/V2/V5/B1 |
| `game/presentation/views/camp_hud_band.gd` | 营地顶栏小 HUD 栏:承载 `UiKit.keystone_badge`(钥石余额单口读数);订阅卡④ `CampRefreshBus.refresh()` 刷新 | 行为改动 | 新建 | V6/B2 |
| `game/presentation/main_esc_flow.gd` | 组合根 Esc 流程承接件:键盘输入路由+营地语境判据+Q2 再按关窗+三出口动线(返回主菜单/设置/退出);静态承接件,main 侧留同名薄委托 | 行为改动 | 新建 | V1/V3/B1/B3 |
| `game/presentation/main.gd` | 组合根:Esc 输入入口+`main_esc_flow.gd` 同名薄委托+返回主菜单动线接线 | 行为改动 | 复用既有(改) | V1/V3/B3 |
| `game/presentation/ui_registry.gd` | `LAYER_CONTRACT` 加 `camp_esc_overlay` 槽(登记于营地层与 `settings_overlay` 之间,契约 3 正解)+`node()` 寻址 | 行为改动 | 复用既有(改) | V8/B1 |
| `game/presentation/main_overlay_flow.gd` | `_on_settings_closed` 语境分支:营地浮窗路径关设置回浮窗、不回主菜单(契约 3) | 行为改动 | 复用既有(改) | V4/B3 |
| `game/presentation/views/camp_scene_view.gd`(卡④ 新建) | 顶栏预留位 `set_hud_band()` 填 `CampHudBand` 实例(卡④ T2 跨卡接口①「卡⑤ 填值」);本卡只填值、不改场景图铺底/命中区逻辑 | 行为改动 | 卡④ 新建(跨卡共改,仅顶栏填值) | V6/B2 |
| `game/probe/screen_flow_probe.gd` | 探针宿主:扩展现 :153-165 Esc 合成段为营地语境浮窗断言+三动线+Q2 关窗+HUD 余额读数;与卡④ T5 营地键段按行域分界(§0) | 非行为改动(测试面) | 复用既有(改) | V1/V3/V4/V6 |
| `game/probe/ui_struct_probe.gd` | 浮窗三钮结构断言+零动效契约段(仿 career :379-391)+顶栏位/登记序结构断言 | 非行为改动(测试面) | 复用既有(改) | V2/V7/V8 |
| `game/tests/README.md` | 能力行入表(四列:能力|系统|真实入口|代表用例) | 非行为改动(文档,写卡段) | 主 Agent 统一收口 | 全表能力行 |
| `reports/iter<N>-实现报告-<日期>.md`/`reports/iter<N>-反哺点-<日期>.md`/`reports/iter<N>-验收审计-<日期>.md` | T4 三份产出物 | 非行为改动(过程件) | 新建 | T4 |
## 落位与可复用性预检
定义 T 卡前,对本批每个**新增文件/新增函数/新增数据件**过三问(复用面/唯一面/分层与交互面),与「卡前·文件结构与职责」互指。生效=2026-10-21 用户立规;本卡虽文件名日期 2026-10-18,经 2026-10-31 用户明令补充为现行有效卡,按现行规则补齐。
### 新增件三问
| 新件 | 复用面(grep 同职责实现) | 唯一面(grep 同名同义标识符) | 分层与交互面(调用路径+跨层出口) |
|---|---|---|---|
| `camp_esc_overlay.gd` | 盘上视图件=`camp_overlay_view.gd`(CampOverlay 四柜台,随卡④ 形态退役、反参照禁复用)、`settings_overlay.gd`/`career_overlay.gd`(各有专职、无三钮 Esc 浮窗同职责实现)、`ui_kit.gd modal_shell`(工厂只产 dim+center+panel+VBox、不产完整浮窗)。grep `camp_esc`/`esc_overlay` 盘上无同职责实现 → 不能复用,须新建视图件;模态壳/按钮复用 `UiKit.modal_shell`(`ui_kit.gd:487`)/`UiKit.danger_button`(:700),零新素材零新色值 | grep `camp_esc_overlay`/`EscOverlay` 盘上无第二处;三钮文案「返回主菜单/设置/退出游戏」只此一处定义,禁在探针/T 卡各写一份 | 呈现层视图,零 Core 写调用;三钮 `pressed` → 组合根 `main_esc_flow.gd` → 现役动线(`_quit_game`/`ui.modals.flow.open(settings_overlay)`/返回主菜单);Q2 再按 Esc 关窗由组合根路由,视图只发 `closed` 信号 |
| `camp_hud_band.gd` | 盘上钥石徽消费面四处(F4),但**无「顶栏 HUD 栏」独立视图件**——现钥石徽直接挂 CampOverlay 顶栏(`camp_overlay_view.gd:125`),随卡④ 拆解退役;新 HUD 栏须独立承载读数+订阅刷新单口,职责不同 → 不能复用,须新建 | grep `camp_hud_band`/`CampHudBand`/`hud_band` 盘上无第二处;余额读数只经 `camp_data()` 单口(F9),禁视图自算 | 呈现层视图;`UiKit.keystone_badge`(`ui_kit.gd:633`)承载显示;订阅卡④ `CampRefreshBus.refresh(camp_data)` 单口刷新(跨卡接口②);经卡④ `camp_scene_view.gd set_hud_band()` 顶栏预留位挂入(跨卡接口①);零 Core 写调用 |
| `main_esc_flow.gd` | 盘上组合根承接件=`main_overlay_flow.gd`(设置/状态/生涯/选档/图例/钱包六类覆盖层开合与数据投喂)、`main_adventure_flow.gd`、`main_debug_flow.gd`。**无「键盘输入路由+Esc 三出口动线」同职责实现**;并入 `main_overlay_flow.gd` 会使其承载第二变化原因(开合数据投喂 vs 键盘输入交互),且该文件已 6 类开合 → 不能复用,须新建单一职责承接件;`main.gd` 留同名薄委托(与现行拆件模式一致,探针 `main.X` 路径零改动) | grep `main_esc_flow`/`_on_esc`/`EscFlow` 盘上无第二处;营地语境判据只此一处定义(营地场景屏 visible 且无营地子模态开态),禁散落 | 组合根拆件(静态、零成员态,仿 `main_overlay_flow.gd`);键盘输入 → 营地语境判据 → 浮窗 `ui.modals.flow.open/close`(模态栈单口);三出口 → 现役动线;返回主菜单 → 营地隐+选档层同收+开始层恢复(卡④ T3 同口径);Core 零 UI 不破 |
### 非新增件说明
- `main.gd`/`ui_registry.gd`/`main_overlay_flow.gd`/`camp_scene_view.gd`(卡④ 新建):存量或邻卡文件改造,不新增本卡文件;公开方法/成员预算见「实现规范预算」存量触面一查。
- `game/probe/screen_flow_probe.gd`/`ui_struct_probe.gd`:复用既有探针宿主(`screen_flow_probe` 已在 `tools/probe_gate.sh:142-146` 登记、零登记成本;本卡 T3 不另起新文件),只加断言段。
- **数据件/RNG/Core**:本卡纯呈现层+输入接线,零玩法数值、无新增 `data/tables/` 表(钥石余额读数经既有 `camp_data()` 单口);数值单一事实源 `data/tables/` 不被触碰;RNG 零新增(RNG 单点 RngService 不被触碰);Core 零 UI 依赖不因新增浮窗/输入接线绕过。
- **浮窗新槽落点唯一**:`camp_esc_overlay` 只在 `ui_registry.gd LAYER_CONTRACT` 登记一次、`node()` 寻址一次;禁在探针/T 卡另写层序字面量。
## 实现规范预算
定义接口块/文件结构图前,对本批每个**新增文件**对照 gdstyle 默认阈值做预算,与接口块及「卡前·文件结构与职责」互指。**生效说明**:规范写「生效=文件名日期 ≥2026-10-27,此前卡片属历史留档不回头改」——本卡经 2026-10-31 用户明令补充为现行有效卡,按现行规则补齐,不援引「不回头改」跳过。gdstyle v0.4.0 默认阈值:**公开方法 ≤20、类变量 ≤15、单函数分支 ≤8、返回 ≤6**(阈值取工具默认,改阈值=基线口径变须在本批重生成)。
### 新件三查
| 触面 | ①公开方法数 | ②成员变量数 | ③迁移函数对账 | 结论 |
|---|---|---|---|---|
| `camp_esc_overlay.gd` | 预期 ≤6:`setup_buttons()`/`set_close_path()`/`bind_signals()`/`_on_pressed(key: String)` 等,远低 ≤20 | 预期 ≤8:三钮句柄+modal_shell 句柄+`closed` 信号,低 ≤15 | 无自存量文件迁入函数 | 三查通过;T0 实测实数回填,超阈值即拆件或砍面(砍面=退设计段裁职责) |
| `camp_hud_band.gd` | 预期 ≤4:`bind_refresh_bus()`/`set_balance()`/`refresh()`,远低 ≤20 | 预期 ≤4:`keystone_badge` 句柄+刷新单口句柄,低 ≤15 | 无迁入函数 | 三查通过;T0 实测实数回填 |
| `main_esc_flow.gd` | 预期 ≤7:`on_esc_input()`/`is_camp_context()`/`open_overlay()`/`close_overlay()`/`_on_return_to_menu()`/`_on_settings()`/`_on_quit()`,远低 ≤20 | 预期 0(静态承接件、零成员态,仿 `main_overlay_flow.gd`) | 无迁入函数(新写,不搬存量函数) | 三查通过;T0 实测实数回填 |
### 存量触面一查
本卡触碰存量文件:`main.gd`/`ui_registry.gd`/`main_overlay_flow.gd`/`camp_scene_view.gd`(卡④ 新建)/`screen_flow_probe.gd`/`ui_struct_probe.gd`。**T0 读数步骤写明「S13 键较 `tools/gdstyle_baseline.txt` 登记值只降不升」的预期与达成手段**:`main.gd` 组合根新增 Esc 输入入口与薄委托(不引入重复 load/循环内 await/循环内分配等 S13 违规类型,键只降不升);`ui_registry.gd` 合同表加一槽、`node()` 加一寻址分支(不新增公开方法面);`main_overlay_flow.gd` `_on_settings_closed` 加语境分支(单函数分支数仍 ≤8、返回 ≤6);`camp_scene_view.gd` 只填 `set_hud_band()` 顶栏位;探针改接=加断言段、不新增扫描面键。任何 S13 键被迫上升=§8 L3 停卡。**`main.gd` 为组合根架构先例,其公开方法基数不在本卡新件三查面内**(第 14 节三查只对新增文件)。
### 指标例外通道
现预算内,无需例外。若三新件实测超默认阈值,或组合根薄委托致 S13 键上升,设「指标例外申报」节——键名+理由+用户特批落基线;未申报的超预算面进实现段=停卡退回写卡段(写进 §8 L3)。
| `design/gdd/08-Alpha版本标准.md` | :192「键盘 / 手柄输入(排 Beta)」行——Esc 营地浮窗已落地(用户明示裁决,澄清⑤裁决 9),须加注防「Beta 行=本批违例」误读 | 反哺点 · 行内加注(v1.1 行号订正 :192) |
| `design/art/art-bible.md` | §6.2「钥石余额常驻顶栏」呈现位从 CampOverlay 顶栏迁场景屏 HUD(:369 述) | 反哺点 · 随卡④ §6.2 改版一并落 |
| `design/gdd/ux/camp.md` | 顶栏铭牌/钥石徽记述(:14-20)随 HUD 栏改挂 | 反哺点 · 随 camp.md 改版落 |
| `design/gdd/06-待办清单.md` | 本卡登记条 | 反哺点 · 列清单 |
| `design/gdd/07-体验验证清单.md` | 新增目检条(Esc 浮窗三动线/HUD 余额观感)——登记不阻塞 | 反哺点 · 列清单 |
| `roadmap.md` | 迭代行编入/状态刷新 | 反哺点 · 列清单 |
| `game/presentation/*`(浮窗视图+接线)、`game/smoke/*` | 实现与断言本体 | 实施本体(可写) |
## 6. 任务卡
> 估时按 Claude 工作日口径;每卡出口自跑轻闸;开工日 T0 复核全部行号。步骤用 `- [ ]` 复选框记步,一步=一个动作+一个可核查结果;每卡声明「取用/产出」接口块,后卡引用的名字与早卡定义逐字一致;禁占位待定句式(不决定任何事的行不留)。
> 估时按 Claude 工作日口径;每卡出口自跑轻闸;开工日 T0 复核全部行号。
### T0 事实坐实与跨卡对齐(≈0.5–1d)
- 取用:待办清单五卡总条实况(卡④ 已重立 v3.0、卡②③ 迭代 33 合回)、§0 跨卡接口、卡④ v3.0 §0.5/T2/T3、`game/tests/README.md` 能力表。
- [ ] 复核 §2 F1–F10 全部 `file:line` 行号;漂移就地订正、订正不了的写明「开工日 T0 复核」,不硬编旧行号。
- [ ] 与卡④ 对齐三项接口:①顶栏预留位 `camp_scene_view.gd set_hud_band()` 填值签名;②营地刷新单口 `CampRefreshBus.refresh(camp_data: Dictionary) -> void`;③终局落点不变量(现役=终局 continue 回主菜单,若改落点为营地则本卡返回动线补 `_begin_session(false)`)——接口名保持既有,不改名;与卡④ 确认 `screen_flow_probe.gd` 行域分界(§0)。
- [ ] **Esc 输入合成先例复核**:读 `game/probe/screen_flow_probe.gd:153-165`(`InputEventKey`+`Viewport.push_input` 合成 Esc、断言选档语境零响应),确认该机制可迁移到营地语境;与 §9 第 1 条接线方式选型联动,T0 定选型并回写文件结构图接线落点。
- [ ] Q1/Q2/Q3 裁定执行确认(甲/甲/甲,见 §10);开工门核:U0 发令、grilling 复核门过、卡④ 代码波状态。
- [ ] 跑 `bash tools/gdstyle.sh game` 开发期局部读数,记录三新件预算实数与存量触面 S13 基线键(预期只降不升);本步最窄确认,不构成验收。
- 产出:基线 commit、三新件接口块定稿(签名/取值)、S13 读数、跨卡接口核对表、Esc 合成先例复核结论;后续卡只按本卡契约施工。
- 复核 §2 行号;确认卡④场景屏顶栏预留位接口+营地刷新单口签名(跨卡);
- **Esc 输入合成 spike**(v1.1 补):headless 下键盘事件合成机制验证(现成先例只有鼠标 `Viewport.push_input`——F1);与 §9 第 1 条接线方式选型联动(InputMap action+轮询路线与合成探针不兼容,选型时一并定);
- Q1 子界面行为、Q2 关闭路径、Q3 范围确认裁定执行;
- 与卡④ T0 互证终局落点不变量(契约 4 前提);探针入口路径依赖卡②③链的时点确认(§0)。
### T1 Esc 浮窗视图与键盘接线(≈1–1.5d)
### T1 Esc 浮窗(≈1–1.5d)
- 取用:T0 三新件接口块、Esc 合成先例复核结论、`ui_kit.gd:487 modal_shell`/:700 `danger_button`/:633 `keystone_badge`、`ui_registry.gd:15-35 LAYER_CONTRACT`。
- [ ] 在 `camp_esc_overlay.gd` 实现 `setup_buttons()`:`UiKit.modal_shell`(`ui_kit.gd:487`,只产 dim+center+panel+VBox、无内置关闭件)+三钮(返回主菜单/设置/退出游戏,退出用 `UiKit.danger_button` :700);零新素材零新色值。
- [ ] 在 `camp_esc_overlay.gd` 实现 `set_close_path()`/`bind_signals()`:Q2 裁甲=再按 Esc 关窗(同键唤起/关闭单义切换),关闭由组合根路由、视图只发 `closed` 信号;三钮 `pressed` 外发不内含动线。
- [ ] 在 `main_esc_flow.gd` 实现 `is_camp_context() -> bool`:判据=营地场景屏 visible(根态与子界面开态下皆真——子界面是模态叠加非熄屏;复用 `screen_flow_probe.gd:54` 营地旗标先例,卡④ T5 改指新场景根句柄后对齐)且无营地子模态开态(Q1 裁甲);调试浮窗开态不影响判据(全局浮层、营地屏仍可见)。
- [ ] 在 `main_esc_flow.gd` 实现 `on_esc_input(ev: InputEvent) -> void`/`open_overlay() -> void`/`close_overlay() -> void`:营地语境 Esc → `ui.modals.flow.open(camp_esc_overlay)`;再按 Esc → `close`;非营地语境(boot 菜单)不唤起(契约 2)。接线方式按 T0 选型,禁吞他处输入。
- [ ] 在 `ui_registry.gd` `LAYER_CONTRACT` 加 `camp_esc_overlay` 槽(位于营地层与 `settings_overlay` 之间,契约 3 登记序正解)+`node()` 寻址;禁散落 `move_child`(F6)。
- [ ] 在 `main.gd` 加 Esc 输入入口与 `main_esc_flow.gd` 同名薄委托(探针 `main.X` 路径零改动)。
- [ ] 零动效(契约 6):浮窗子树零 AnimationPlayer、源码禁 `create_tween`/`UiKit.motion` 令牌(仿 `ui_struct_probe.gd:379-391`)。
- 产出:`CampEscOverlay.setup_buttons()`/`set_close_path()`/`bind_signals()`、`closed` 信号;`MainEscFlow.on_esc_input()`/`is_camp_context()`/`open_overlay()`/`close_overlay()`;`LAYER_CONTRACT` 新槽键 `camp_esc_overlay`;T2 按接口块接线。
- 浮窗视图:模态壳(`UiKit.modal_shell` 先例——该工厂只产 dim+center+panel+VBox、无内置关闭件,关闭件按 Q2 裁定)+三钮(返回主菜单/设置/退出游戏);危险钮形制用于退出(`UiKit.danger_button` 先例);零新素材零新色值;
- 接线:返回主菜单→营地场景屏隐藏+选档层同收+开始层恢复(卡④动线同口);设置→`_open_settings`(**语境分支**:浮窗登记于设置层之下,关设置回浮窗——契约 3);退出→`_quit_game`;
- **营地语境判据(v1.1 补)**:判据=营地场景屏 visible(根态与子界面开态下皆真——子界面是模态叠加非熄屏;screen_flow_probe 营地旗标先例 :53 可迁移复用);Q1 裁甲则判据加「无营地子模态开态」;调试浮窗开态不影响判据(全局浮层、营地屏仍可见);Q1 裁后回写契约 2 消歧;
- 层序入 `LAYER_CONTRACT`(与调试角标遮挡按契约 7 结论表达);零动效(契约 6);
- Q2 关闭路径接线(再按 Esc 关/关闭钮/无关闭,按裁定)。
### T2 营地顶栏小 HUD 栏(≈0.5–1d)
- 取用:T1 `MainEscFlow`、`camp_hud_band.gd` 接口块、卡④ `CampRefreshBus.refresh(camp_data)` 单口、`camp_scene_view.gd set_hud_band()` 顶栏预留位、`camp_shop_presenter.gd:62 camp_data()` 读数单点。
- [ ] 在 `camp_hud_band.gd` 实现 `set_balance(v: int) -> void`/`bind_refresh_bus(bus: Object) -> void`/`refresh(camp_data: Dictionary) -> void`:`UiKit.keystone_badge`(`ui_kit.gd:633`)承载,读数只经 `camp_data()` 单口(F9/契约 5,禁第二账本、禁视图自算);订阅卡④ `CampRefreshBus.refresh(camp_data)`。
- [ ] 在卡④ `camp_scene_view.gd` 的 `set_hud_band()` 顶栏预留位填 `CampHudBand` 实例(高 48px 浮层覆盖、不挤压画面;卡④ T2 跨卡接口①);`camp_scene_view.gd` 场景图铺底/命中区逻辑零改(卡④ 职责)。
- [ ] 刷新时机清单落定(契约 5):①购买后(挂单口)②进档/回营地进入时重读③夹具直写后探针显式触发——断言前须显式触发,禁依赖「自动重读」假设。
- [ ] HUD 栏形态按最小集(契约 8):只承载钥石余额;扩项=新裁点。
- [ ] camp 截图/golden 联动:HUD 落位后核 camp 截图漂移热区→限 HUD 区显式更新+呈报;现无 camp 逐像素 golden(卡④ 契约 10),camp 验收=shot_probe 出图+shot_checker 语义断言。
- 产出:`CampHudBand.set_balance()`/`bind_refresh_bus()`/`refresh()`、顶栏填值、刷新时机清单;T3 按接口块验收。
- 顶栏位落 `UiKit.keystone_badge` 工厂件(余额单口读数,契约 5);
- **刷新挂卡④营地刷新单口**(契约 5);**刷新时机清单落定(v1.1 补)**:①购买后(挂单口)②进档/回营地进入时重读③夹具直写后由探针显式触发——断言前须显式触发,禁依赖「自动重读」假设;
- HUD 栏形态按最小集(契约 8):只承载钥石余额;
- **camp 截图/golden 联动条(v1.1 补)**:HUD 落位后核 camp 截图漂移热区→限 HUD 区显式更新+呈报(仿卡④ T5/卡② 契约 6 口径;现无 camp 逐像素 golden——卡④ 契约 10)。
### T3 三出口动线、设置语境分支与断言批(≈1–1.5d)
### T3 断言批(≈0.5–1d)
- 取用:T1/T2 产物、`main_overlay_flow.gd:11-13 _on_settings_closed`、`main.gd:143 _quit_game`、`camp_shop_presenter.gd:50-53 on_camp_closed`、`screen_flow_probe.gd:153-165` Esc 合成段、`ui_struct_probe.gd:379-391` 零动效段。
- [ ] 在 `main_esc_flow.gd` 实现 `_on_return_to_menu() -> void`:营地场景屏隐藏+选档层同收+开始层恢复(卡④ T3 动线同口);营地语境⇔闲时会话(契约 4 前提),动线不含会话收束;回主菜单后菜单=卡②三钮、禁加「继续冒险」钮。
- [ ] 在 `main_esc_flow.gd` 实现 `_on_settings() -> void`/`_on_quit() -> void`:设置→`ui.modals.flow.open(settings_overlay)`(浮窗登记于其下、关后遮挡解除重现);退出→`_quit_game`(`main.gd:143`,原样复用)。
- [ ] 在 `main_overlay_flow.gd` `_on_settings_closed` 加语境分支:营地浮窗路径关设置回浮窗、不回主菜单(契约 3;现役 :13 `start_overlay.visible = true` 硬副作用仅菜单路径保留)。
- [ ] 探针(宿主 `screen_flow_probe.gd`,已在 `tools/probe_gate.sh:142-146` 登记、零登记成本;不另起新文件):扩展 :153-165 Esc 合成段——营地根态合成 Esc→浮窗可见+三项在位;营地子界面开态合成 Esc→浮窗不唤起(Q1 甲案判据);再按 Esc 关窗;非营地语境(boot 菜单)不唤起(契约 2);返回主菜单动线(营地隐+选档层收+菜单显);设置项开合(含营地浮窗→设置→关闭回浮窗高危路径+「关闭设置后禁弹主菜单」反向断言);退出项接线断言(headless 不可真退)。
- [ ] HUD 余额断言:读数=存档单口(夹具经**隔离存档实例直写** `meta_state._add_keystone(9999)` 先例 `game/probe/ui_click_probe.gd:74`;**不经 DebugOverlay 界面——其钥石项是只读投影** `debug_overlay.gd:194-205`);直写后显式触发刷新断言。
- [ ] 结构断言(`ui_struct_probe.gd`):浮窗三钮在位且仅三;零动效(仿 career :379-391);`LAYER_CONTRACT` 登记序(浮窗入合同表、`system_test.gd:94-106` V1c 树序链复跑);**浮窗开不波及 `debug_badge` 节点**(F10:发布态恒隐,改结构断言替代 v1.2 `visible==true` 断言)。
- [ ] 正向验收断言(v1.2 计划的人工制造红取证条目整条已删,替换为 §7 上表正向断言):每条从真实入口进入、判据绑被测改动特有的可观测提交面(信号/入参/状态源取值/可见性/树序),在当轮真实跑批执行并通过;**禁把生产码改成错值看断言抓不抓得到、禁回退 hunk 看断言红不红**(人为制造红属伪造证据);判据绑不上=静态判据+评审注记申报观测面局限,证明做不出=停卡呈报。
- 产出:三出口动线接线、设置语境分支、探针断言段(V1–V8 落点)、能力行名实核对表;T4 收口。
- 探针(**宿主选 screen_flow_probe——v1.1 定:轻闸默认段且「菜单⇄营地屏壳切换」正是其职域,零闸登记成本;若另起新文件须改 tools/probe_gate.sh 登记=§5 可写面外,禁**):合成 Esc 键事件→浮窗可见+三项在位;非营地语境(boot 菜单)不唤起;返回主菜单动线(营地隐+选档层收+菜单显);设置项开合(**含营地浮窗→设置→关闭回浮窗高危路径+「关闭设置后禁弹主菜单」反向断言——v1.1 补**);退出项接线断言(headless 不可真退);
- HUD:余额读数=存档单口(夹具经**隔离存档实例直写** `add_keystone` 或等效写口——smoke 既有先例 smoke_all.gd:5440;**不经 DebugOverlay 界面——其钥石项是只读投影,debug_overlay.gd:173-189,v1.1 订正**);直写后显式触发刷新断言;
- 契约断言:浮窗零动效(career 同款段复用/仿写);层序登记(冒烟 V1d);**浮窗开态 `debug_badge.visible==true`**(仿 ui_click_probe.gd:174-177 设置面开中角标可见先例——v1.1 补);
- **变异验证伴生**:Esc 接线漏营地隐(预期动线断言红)、HUD 读缓存旧值(预期刷新断言红)、浮窗加第四钮(预期三项断言红)、**设置关闭后误回主菜单**(预期语境断言红——v1.1 补)、**Esc 再按不关窗**(预期关窗断言红,若 Q2 裁甲——v1.1 补);注入→最窄闸见红→精确还原→记录。
### T4 产出物落位卡(≈0.5d,末卡)
- 取用:T0–T3 全部产物。
- [ ] 里程碑步(T 段)出口跑一次代码域全套闸:`bash tools/run_all_gates.sh --code`;回执 `all_green=true`;任何新增红停卡,不得带红合回。波内修复只做出红最小单元的最窄确认;新增测试先行孤立验证再并入全套。
- [ ] 独立验收审计由未参与实现的会话/子代理执行,产出 `reports/iter<N>-验收审计-<日期>.md`;未过禁合并(审计入口见 §7)。
- [ ] 轻闸全绿、合并前写齐三份 `reports/`:
- [ ] `reports/iter<N>-实现报告-<日期>.md`(各卡状态+实机目检总清单+遗留读数义务+实现决定记录/代拍板追认单);
- [ ] `reports/iter<N>-反哺点-<日期>.md`(§5 每条有落点:文件/节/原句/拟改句/依据,明确「实现批未写 design/」);
- [ ] `reports/iter<N>-验收审计-<日期>.md`(独立审计逐行「通过/缺漏/例外及依据」)。
- [ ] 用户目检项登记 `体验验证清单.md`(仓库根,反哺点列清单:Esc 三动线+HUD 余额观感+浮窗视觉面),登记完成即卡内义务了结,不阻塞批末收尾/合并/下一迭代开工。
- 产出:三份 `reports/` 齐全+代码域闸全绿+验收审计通过,方算收口;合回后由本地 CI 跑不带参数的 `tools/run_all_gates.sh`(两域全量)复验。
三份 `reports/` 写齐。
**估时合计 ≈3–4.5d**。切分预案:T1/T2 后可切(浮窗先落、HUD 后落)——切分价值低,建议与卡④同批单跑。
**估时合计 ≈3–4.5d**(v1.1 订正:分项和=3.0–4.5d,原「2.5–3.5d」算术少算)。切分预案:T1/T2 后可切(浮窗先落、HUD 后落)——切分价值低,建议与卡④同批单跑。
## 7. 验证闸:改动—验收对照表
## 7. 验证闸(逐需求点验收清单)
七格表:需求点|改动(文件:行/行为)|验收测试(名称+落点+尾缀)|层级(单元/接口/集成/探针)|真实入口|判据绑定面|能力行。**每个需求点至少一行;每个行为改动至少一行(V1–V10 需求点行+B1–B3 行为改动专行);每行必须有真实入口和判据绑定面——缺任一项=该需求点未验收,卡片不成立。** 断言尾缀〔ESC批 Vn〕/〔ESC批 Bn〕,与卡片清单互相 grep。能力行格式 `既有:<能力名>;新增:<能力名>`(中文分号分隔,对齐机检与卡④ v3.0 先例),两形态名称都须在 `game/tests/README.md` 能力表在场(既有=现役在场名,新增=本卡定名、由主 Agent 统一收口入表;本卡只写卡内能力行文字,README 由主 Agent 收口)。
| # | 需求点 | 测什么 | 落点/判定手段 |
|---|---|---|---|
| V1 | Esc 唤起(按 Q1 分拆) | **根态**合成 Esc→浮窗可见;**子界面开态按 Q1 案**(甲=不现/乙=先关子界面再现);boot 菜单语境不唤起(其余非营地语境由契约 2 红线+源码断言兜底——可达性单一,登记原因) | screen_flow_probe 合成键盘事件段(T0 spike 机制) |
| V2 | 浮窗三项 | 返回主菜单/设置/退出游戏三钮在位且仅三 | ui_struct_probe 结构断言 |
| V3 | 返回主菜单 | 营地场景屏隐藏+选档层同收+主菜单可见 | screen_flow_probe 型断言 |
| V4 | 设置项(双路径) | 菜单路径(冒烟 V3g settings 段复跑)+**营地浮窗→设置→关闭回浮窗**(含禁弹主菜单反向断言) | 冒烟复跑+探针新路径段 |
| V5 | 退出项 | 接线到 `_quit_game`(headless 不可真退——接线断言代偿) | 源码/结构断言 |
| V6 | HUD 余额 | 读数=存档单口(隔离实例直写);直写后显式触发刷新;购买后刷新(挂卡④单口——跨卡联验) | 探针数据断言(smoke_all.gd:5440 同型先例) |
| V7 | 零动效 | 浮窗子树零 AnimationPlayer+源码禁动效令牌 | ui_struct_probe 零动效契约段(career 同款) |
| V8 | 层序与遮挡 | 浮窗入 LAYER_CONTRACT(冒烟 V1d);浮窗开态 debug_badge 可见 | 冒烟 V1d+探针 badge 断言 |
| V9 | 目检项登记 | Esc 三动线+HUD 观感+浮窗视觉面(文字 WCAG 若入 shot_checker 取样,否则显式登记归目检并写明理由)入 07 | 件核(登记不阻塞) |
| V10 | 反哺点清单 | §5 每条有落点 | 件核对表 |
| 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|
| V1 Esc 唤起(根态/子界面/关窗/非营地) | `camp_esc_overlay.gd` 浮窗视图;`main_esc_flow.gd on_esc_input()`/`is_camp_context()`/`open_overlay()`/`close_overlay()`;`main.gd` 输入入口 | `screen_flow_probe.gd:_ready`(Esc 唤起/子界面开态不唤起/再按关窗/非营地不唤起段)〔ESC批 V1〕 | 探针 | 营地场景根态合成 Esc 键事件(`InputEventKey`+`Viewport.push_input`,先例 :156-160)→ `main_esc_flow.on_esc_input()` → `ui.modals.flow.open/close` | 根态 Esc→浮窗 `visible=true`;再按→`visible=false`(绑 open/close 调用记录+浮窗可见性);营地子界面开态合成 Esc→浮窗 `visible=false`(Q1 甲案,绑 `is_camp_context()` 无子模态开态判据);boot 菜单合成 Esc→浮窗 `visible=false`(契约 2,绑语境判据返回值) | 新增:Esc 浮窗唤起与三出口动线 |
| V2 浮窗三项 | `camp_esc_overlay.gd setup_buttons()` 三钮(modal_shell+danger_button) | `ui_struct_probe.gd:_ready`(浮窗三钮结构段)〔ESC批 V2〕 | 探针 | 浮窗视图实例化 → 三钮节点树 | 三钮节点存在且仅三(绑按钮名与数量;禁第四钮) | 既有:UI 全局主题与按钮五态(含对比度锚);新增:Esc 浮窗唤起与三出口动线 |
| V3 返回主菜单 | `main_esc_flow.gd _on_return_to_menu()`(营地隐+选档层同收+开始层恢复) | `screen_flow_probe.gd:_ready`(返回动线段)〔ESC批 V3〕 | 探针 | 浮窗「返回主菜单」钮 `pressed` → `main_esc_flow._on_return_to_menu()` → 屏显编排 | 营地场景屏 `visible=false`+选档层 `visible=false`+`start_overlay.visible=true`(绑三处可见性;`_screen_seals()` :51-57 互斥复跑) | 新增:Esc 浮窗唤起与三出口动线 |
| V4 设置项(双路径) | `main_esc_flow.gd _on_settings()`;`main_overlay_flow.gd _on_settings_closed` 语境分支 | `screen_flow_probe.gd:_ready`(营地浮窗→设置→关闭回浮窗段)〔ESC批 V4〕+菜单路径冒烟 V3g settings 段复跑 | 探针(+冒烟复跑) | 浮窗「设置」钮 → `ui.modals.flow.open(settings_overlay)` → 关闭 → `_on_settings_closed` 语境分支 | 设置开→浮窗被遮挡不可见(绑 ModalStack 遮挡记账);关闭→浮窗 `visible=true`+`start_overlay.visible=false`(绑语境分支;反向断言「关闭设置后禁弹主菜单」) | 既有:模态覆盖层编排与输入锁;新增:Esc 浮窗唤起与三出口动线 |
| V5 退出项 | `main_esc_flow.gd _on_quit()` → `main.gd:143 _quit_game()`(原样复用) | `ui_struct_probe.gd:_ready`(退出钮接线结构断言)〔ESC批 V5〕 | 探针(源码/结构,headless 不可真退) | 浮窗「退出游戏」钮 `pressed` → `_on_quit()` → `_quit_game()`(`settings_store.save_settings()`+`get_tree().quit()`) | 钮 `pressed` 连接目标=`_on_quit`→`_quit_game`(绑信号连接与调用链;headless 不真退=静态判据+评审注记申报观测面局限) | 新增:Esc 浮窗唤起与三出口动线 |
| V6 HUD 余额 | `camp_hud_band.gd set_balance()`/`bind_refresh_bus()`/`refresh()`;`camp_scene_view.gd set_hud_band()` 填值;订阅卡④ `CampRefreshBus.refresh()` | `screen_flow_probe.gd:_ready`(HUD 余额读数/刷新段)〔ESC批 V6〕+`ui_struct_probe.gd:_ready`(顶栏位结构段) | 探针(跨卡联验:购买后刷新挂卡④单口) | 隔离存档实例 `meta_state._add_keystone(9999)`(`ui_click_probe.gd:74` 先例)→ 显式触发 `CampRefreshBus.refresh(camp_data)` → `camp_hud_band.refresh()` → `keystone_badge` 读数 | `keystone_badge.value_label.text`=`camp_data()["balance"]`(`keystone_balance()` 单口取值);直写后显式触发刷新才变(绑单口调用记录+badge 文本状态源) | 既有:元进度入账与锻造两轴;新增:营地顶栏 HUD 钥石读数与刷新单口同步 |
| V7 零动效 | `camp_esc_overlay.gd` 直开直关(零 AnimationPlayer、源码禁 `create_tween`/`UiKit.motion`) | `ui_struct_probe.gd:_ready`(浮窗零动效契约段,仿 career :379-391)〔ESC批 V7〕 | 探针(结构/源码扫描) | 浮窗视图子树+`camp_esc_overlay.gd` 源码 | 子树零 AnimationPlayer+源码零 `create_tween`/`UiKit.motion` 令牌(扫描面 >0 非空前置) | 既有:模态覆盖层编排与输入锁;新增:Esc 浮窗唤起与三出口动线 |
| V8 层序与遮挡 | `ui_registry.gd` `LAYER_CONTRACT` 加 `camp_esc_overlay` 槽(营地层与 `settings_overlay` 之间)+`node()` 寻址 | `ui_struct_probe.gd:_ready`(浮窗登记序/遮挡段)〔ESC批 V8〕+`system_test.gd:_ready`(V1c 合同树序链 :94-106 复跑) | 探针(+系统测试复跑) | `main.ui.LAYER_CONTRACT` 单一事实源;`ui.modals.flow.open()` 遮挡记账 | 登记册序=合同模态序、直接子层树序=合同序逐对相等;`debug_badge` 末位 float 类不注册(open 只动登记层,绑登记册成员性;F10 发布态恒隐,不绑 `visible==true`) | 既有:模态覆盖层编排与输入锁;新增:Esc 浮窗唤起与三出口动线 |
| V9 目检项登记 | `reports/iter<N>-实现报告-<日期>.md` 实机目检总清单 | 件核对(`体验验证清单.md` 登记,登记不阻塞)〔ESC批 V9〕 | 用户目检(非自动化) | 用户实机(生命周期末步统一进行,不阻塞迭代) | Esc 三动线+HUD 余额观感+浮窗视觉面(文字 WCAG 若入 shot_checker 取样,否则显式登记归目检并写明理由)入 `体验验证清单.md`=登记即义务了结 | 既有:模态覆盖层编排与输入锁 |
| V10 反哺点清单 | §5 每条有落点 | 件核对表〔ESC批 V10〕 | 件核对(非自动化) | §5 同步面逐条对账 | §5 每条有 `reports/iter<N>-反哺点-<日期>.md` 落点 | 既有:模态覆盖层编排与输入锁 |
| B1 Esc 输入接线与浮窗视图(行为改动专行) | `main.gd` 输入入口/薄委托;`main_esc_flow.gd on_esc_input()`/`is_camp_context()`/`open_overlay()`/`close_overlay()`;`camp_esc_overlay.gd` 新建;`ui_registry.gd` 新槽 | `screen_flow_probe.gd:_ready`(Esc 唤起/关窗/非营地段)+`ui_struct_probe.gd:_ready`(三钮/零动效/登记序段)〔ESC批 B1〕 | 集成 | 营地场景根态合成 Esc 键 → `main_esc_flow` → `ui.modals.flow.open/close(camp_esc_overlay)` | Esc 输入→浮窗 visible 两态(绑 open/close 调用记录);语境判据返回值(绑 `is_camp_context()`);浮窗三钮数量+登记序(绑节点树与合同表) | 既有:模态覆盖层编排与输入锁;新增:Esc 浮窗唤起与三出口动线 |
| B2 HUD 栏落位与刷新挂单口(行为改动专行) | `camp_hud_band.gd` 新建;`camp_scene_view.gd set_hud_band()` 填值;订阅卡④ `CampRefreshBus.refresh()` | `screen_flow_probe.gd:_ready`(HUD 读数/刷新段)+`ui_struct_probe.gd:_ready`(顶栏位结构段)〔ESC批 B2〕 | 集成 | `CampRefreshBus.refresh(camp_data)` → `camp_hud_band.refresh()` → `keystone_badge` | badge 文本=`camp_data()["balance"]` 单口取值;顶栏位存在(结构断言,高 48px 浮层);刷新单口调用记录(跨卡联验) | 既有:元进度入账与锻造两轴;新增:营地顶栏 HUD 钥石读数与刷新单口同步 |
| B3 设置语境分支与返回主动线接线(行为改动专行) | `main_esc_flow.gd _on_return_to_menu()`/`_on_settings()`/`_on_quit()`;`main_overlay_flow.gd _on_settings_closed` 语境分支 | `screen_flow_probe.gd:_ready`(返回动线/设置双路径段)+`ui_struct_probe.gd:_ready`(退出钮接线断言)〔ESC批 B3〕 | 集成 | 浮窗三钮 `pressed` → `main_esc_flow` 三出口 → 现役动线/`_quit_game`;设置关闭 → `_on_settings_closed` 语境分支 | 返回动线三处可见性(绑屏显编排);设置关闭后浮窗 `visible=true`+`start_overlay.visible=false`(绑语境分支);退出钮连接链(绑信号连接) | 既有:模态覆盖层编排与输入锁;新增:Esc 浮窗唤起与三出口动线 |
**测试方式两分法**:V1–V8 机检自动化(能力验证经隔离存档实例直写钥石/开态——v1.1 订正:不经 DebugOverlay 界面);V9 归用户目检(生命周期末步统一进行,不阻塞迭代,澄清⑥口径)。
**落点集中**:V1/B1 → T1/T3;V2/V7/V8 → T1/T3;V3/V4/V5/B3 → T3;V6/B2 → T2/T3;V9/V10 → T4。全表名实核对归 T4。
**测试方式两分法**:V1–V8、B1–B3 机检自动化(能力验证经隔离存档实例直写钥石 `meta_state._add_keystone()`,`ui_click_probe.gd:74` 先例;不经 DebugOverlay 界面——其钥石项只读投影 `debug_overlay.gd:194-205`);V9 归用户目检(生命周期末步统一进行,不阻塞迭代,澄清⑥口径);V10 为件核对表。**用户目检一律「登记不阻塞」**:登记完成即卡内义务了结,不得作为批末收尾、合并或下一迭代开工的前置条件。
**判据绑定面口径**:每个需求点与每个行为改动的验收=一条从真实入口进入的断言,可 grep 定位、在当轮真实跑批中执行并通过,判据绑被测改动特有的可观测提交面(信号/事件/入参/状态源取值/绘制记录/可见性/树序)(2026-10-24/10-28 用户两裁)。**禁把生产码改成错值看断言抓不抓得到、禁回退 hunk 看断言红不红——人为制造红属伪造证据,一律禁止**;v1.2 计划的人工制造红取证条目整条已删,替换为上表正向验收断言。判据绑不上(纯防御分支、headless 不可真退)=静态判据+评审注记申报观测面局限,证明做不出=停卡呈报。配判据按强弱分层配齐:运行期断言(可见性/树序/状态源取值)抓状态类缺陷,golden 逐像素抓内容观感类缺陷(本卡无 camp golden,用 shot_checker 语义断言段+目检),占比/统计类判据只兜「整框空白/整框糊」、是补充不是主力(细则=test-conventions §8.4)。
**测试削弱申报(零削弱)**:**本卡零削弱申报**——本批只新增断言,不删除/放宽任何在役旧断言、不缩小扫描面、不把真实入口换成下层直调。v1.2 计划断言「浮窗开态 `debug_badge.visible==true`」因调试角标发布态恒隐换代(迭代 38 卡⑦,`main.gd:98`)与现行事实冲突,属**计划期订正**(该断言从未落地、非在役旧断言),改写为「浮窗登记序+open 不波及 float 类 `debug_badge` 节点」结构断言(V8),不计削弱。除此外实现期不得删除断言、放宽阈值、缩小扫描面、换下层直调;未申报的削弱由独立验收审计判红。
**独立验收审计**:合并前由未参与实现的会话/子代理执行,入口=审计只读本卡、实际对照表、diff、测试文件与实现报告,自跑最窄测试抽查、不采信报告「已全绿」;至少四件事——①逐行核对照表(测试存在、真的执行、尾缀能 grep 到、真实入口没有绕过改动点)②抽查判据绑定面(绑被测改动特有可观测提交面、当轮真实跑批执行过)③检查测试削弱(删除断言/放宽阈值/缩小扫描面/换下层直调逐处要本卡申报或用户批准)④核内部字段直查的受控例外(该行为无公开可观测面可钉时已在对照表注明理由)。报告落 **`reports/iter<N>-验收审计-<日期>.md`**,逐行「通过/缺漏/例外及依据」,未通过不得合并。测试执行两入口铁规不变:审计在迭代 loop 内启动的子代理算 loop,另开会话须用户点名。
**闸口径**:轻闸每卡出口自跑;批末重闸按改动域选档(本批碰 `game/` 代码/断言面 → `--code`)全绿才合并;MC 零跑(零数值零行为)。**卡内不写死闸件名单与域划分**,唯一出处在 `tools/run_all_gates.sh`。合回验证=主区直改+直提后由本地 CI 跑不带参数的 `tools/run_all_gates.sh`(两域全量)复验,代码面全量验证归合回后本地 CI,主区小批直提不重复跑全量。回归措辞按模板:里程碑步(波/T 段)出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试/工具先行孤立验证再并入全套。
**闸口径**:轻闸每卡出口自跑;批末重闸按改动域选档(本批碰 `game/` 代码与断言面 → `--code`)全绿才合并;MC 零跑(零数值零行为)。
## 8. 异常分级
- **L1(自救一次)**:断言写法、探针合成键事件写法、命名、编译错误、签名拼写、测试套件 manifest 登记遗漏。
- **L2(记录继续;同一红连续三次升 L3)**:Esc 接线方式选型(§9 第 1 条域内)、浮窗壳尺寸/位次(UiKit 现行件域内)、HUD 栏位微调(顶栏域内)、行数较 T0 预期漂移但 S13 键不升。
- **L3(立即停卡写报告等用户)**:
- 卡④ 代码波未到位又需合并;
- Q1/Q2/Q3 裁定被执行期擅自改值(已裁=甲/甲/甲,见 §10);
- 发现需扩展到非营地语境才能成立(触契约 2=用户裁面);
- Esc 键盘合成先例(`screen_flow_probe.gd:153-165`)复核失败且无替代真实入口验收手段(真实路径纪律不让直呼处理函数代偿);
- 浮窗开会隐藏其上登记层的栈语义被误判为缺陷(契约 7 已写明,勿误停机);
- 任何验收行无法从真实入口绑定特有可观测提交面(证明做不出=停卡呈报);
- **机检预算互斥=上游缺陷停卡退回写卡段**:实现规范预算三新件超默认未走指标例外申报、或存量触面 S13 键较登记值上升、或机检键/计数与卡片契约互斥——一律停该卡呈报退回写卡段,禁为凑绿保留无效成员、造第三条路或内联求裁(req-card 第 9/14 节合流)。
- **L1(自救)**:断言写法、探针合成键事件写法、命名。
- **L2(记录继续)**:Esc 接线方式选型(§9 域内)、浮窗壳尺寸/位次(UiKit 现行件域内)、HUD 栏位微调。
- **L3(停机呈报)**:卡④ 场景屏未到位又需合并;Q1/Q2/Q3 未裁即开工;发现需扩展到非营地语境才能成立(触契约 2=用户裁面);Esc 键盘合成 spike 失败且无替代验收手段(真实路径纪律不让直呼处理函数代偿);浮窗开会隐藏其上登记层的栈语义被误判为缺陷(契约 7 已写明,勿误停机)。
## 9. 代拍板白名单(超清单必呈报)
1. Esc 输入接线方式(`_unhandled_input` vs InputMap 新 action vs 专用控制器)——约束:不吞他处输入、探针可合成;现 `screen_flow_probe.gd:156-160` 已有 `Viewport.push_input(InputEventKey)` 合成先例,T0 复核该先例与所选路线的兼容性(InputMap action+轮询路线与合成探针的兼容性不预断,T0 定稿)。
2. 浮窗模态壳尺寸与位次(UiKit `modal_shell` 现行件域内,`ui_kit.gd:487`)。
1. Esc 输入接线方式(`_unhandled_input` vs InputMap 新 action vs 专用控制器)——约束:不吞他处输入、探针可合成(与 T0 spike 结论兼容;InputMap action+轮Polling 路线禁——与合成探针不兼容)。
2. 浮窗模态壳尺寸与位次(UiKit `modal_shell` 现行件域内)。
3. HUD 栏在顶栏的左右位次与间距(卡④场景屏顶栏域内)。
4. 「返回主菜单」复用卡④篝火同一处理函数(建议复用——动线同口;实现期定)。
5. 浮窗视觉面是否入 shot_checker 取样(T3 定:入=补截图段;不入=显式登记归目检并写明理由)。
6. 提交切分与 worktree 分支命名(车道铁律:主区直改+直提;大批按约定 worktree 非强制)。
5. 浮窗视觉面是否入 shot_checker 取样(T3 定:入=补截图段;不入=显式登记归目检并写明理由)。
6. 提交切分与 worktree 分支命名。
超出必须呈报:任何数值、事件名、接口名、文件职责、T 卡验收落点、三钮文案、Q1/Q2/Q3 裁定值。
## 10. 待裁点
## 10. 待裁点:零待裁点,开工门=U0
**本卡设计待裁点清零,开工门=U0。** Q1/Q2/Q3 均于 2026-10-18 裁定(下列为现行裁定留痕,非待裁点,实现期禁自行改值):
### Q1 · Esc 在子界面开态下的行为(已裁定 甲)
### Q1 · Esc 在子界面开态下的行为(必裁,未裁不开 T1)
**背景**:营地语境含「场景根态」与「子界面开态」(锻造/秘宝/生涯/天赋树/图鉴开着时)。澄清⑤裁决 9 未覆盖此分支。两案并列,**无推荐(用户令:不代裁)**:
| 案 | 内容 | 代价 |
|---|---|---|
| 甲 | 只营地根态响应 Esc;子界面开着时 Esc 不唤浮窗(前提=各子界面自带返回钮闭环——待卡④ T3 承诺) | 语义最简;子界面里按 Esc 无反馈 |
| 甲 | 只营地根态响应 Esc;子界面开着时 Esc 不唤浮窗(**前提=各子界面自带返回钮闭环——待卡④ T3 承诺,v1.1 括注**) | 语义最简;子界面里按 Esc 无反馈 |
| 乙 | 营地语境任意态响应 Esc:子界面开着时先关子界面回根态,再按才唤浮窗(单义化) | 多一层输入编排;与既有「子界面返回钮」形成双关闭路径 |
连带:判据形态随案(T1 已列);V1 按案分拆断言;契约 2 措辞裁后回写。
连带:判据形态随案(T1 已列);V1 按案分拆断言;契约 2 措辞裁后回写。裁决方式:随卡片评审定案;裁定落 T0 执行+实现报告留痕。
**裁定(2026-10-18)**:**甲**——只营地根态响应 Esc;子界面开着时 Esc 不唤浮窗。代拍板留痕(用户令「事项按推荐的来」,本项无推荐案,取默认甲=语义最简;前提=卡④ T3 承诺各子界面自带返回钮闭环,卡④ v3.0 已在内;追认单可 veto)。T1 判据=营地场景屏 visible 且无营地子模态开态。裁定落 T0 执行+实现报告留痕。
**裁定(2026-10-18)**:**甲**——只营地根态响应 Esc;子界面开着时 Esc 不唤浮窗。代拍板留痕(用户令「事项按推荐的来」,本项无推荐案,取默认甲=语义最简;前提=卡④ T3 承诺各子界面自带返回钮闭环,卡④重新立卡时该承诺已在内;追认单可 veto)。T1 判据=营地场景屏 visible 且无营地子模态开态。
### Q2 · 浮窗的关闭/取消路径(已裁定 甲)
### Q2 · 浮窗的关闭/取消路径(必裁,未裁 T1 视图定不了稿——v1.1 新增)
**背景**:`UiKit.modal_shell`(`ui_kit.gd:487`)只产 dim+center+panel+VBox、**无内置关闭件**;契约 1 禁加项⇒浮窗只有三钮,无一「关闭」。而 §4 不做清单把「任意键关闭浮窗」划为用户未裁禁自扩——Esc 自身再按的行为恰好落在被 punt 的缝隙里:Q1 两案都不覆盖「浮窗已开时按 Esc」。若不裁且无关闭钮,玩家误开浮窗后离开营地只有「回主菜单/开设置/退游戏」三条路——体感陷阱,且与卡④子界面(生涯有返回钮)的可用性水准倒挂。
**背景**:`UiKit.modal_shell`(ui_kit.gd:456-475)只产 dim+center+panel+VBox、**无内置关闭件**;契约 1 禁加项⇒浮窗只有三钮,无一「关闭」。而 §4 不做清单把「任意键关闭浮窗」划为用户未裁禁自扩——**Esc 自身再按的行为恰好落在被 punt 的缝隙里**:Q1 两案都不覆盖「浮窗已开时按 Esc」。若不裁且无关闭钮,玩家误开浮窗后离开营地只有「回主菜单/开设置/退游戏」三条路——体感陷阱,且与卡④子界面(生涯有返回钮)的可用性水准倒挂。
| 案 | 内容 | 代价 |
|---|---|---|
@@ -296,15 +187,23 @@
| 乙 | 浮窗加关闭钮 | 触契约 1「禁加项」——须重新解释「三项」仅指功能项 |
| 丙 | 维持无关闭(三钮即全部出口,「返回主菜单」充当默认离开) | 误开浮窗后成本高;与子界面可用性水准倒挂 |
**裁定(2026-10-18)**:**甲**——再按 Esc 关浮窗(同键唤起/关闭单义切换)。推荐案,用户令按推荐执行。T1 接线含「浮窗已开时再按 Esc=关浮窗」;V1 断言按「根态唤起/再按关闭」两态分拆。裁定落 T1 视图与接线+V 表。
裁决方式:随卡片评审定案;裁定落 T1 视图与接线+V 表。
### Q3 · Esc 范围确认(已裁定 甲)
**裁定(2026-10-18)**:**甲**——再按 Esc 关浮窗(同键唤起/关闭单义切换)。推荐案,用户令按推荐执行。T1 接线含「浮窗已开时再按 Esc=关浮窗」;V1 断言按「根态唤起/再按关闭」两态分拆。
### Q3 · Esc 范围确认(顺带确认项,低成本高保险——v1.1 新增)
**背景**:契约 2「Esc 只在营地语境」是卡的从严收窄(澄清文档只裁「Esc 唤浮窗三项」、未裁范围——S1)。收窄方向保守且已自标「用户未裁」,但若用户本意是全局 Esc 菜单,范围锁死即返工。
| 案 | 内容 | 代价 |
|---|---|---|
| 甲(推荐) | 确认「Esc 浮窗只在营地语境」——契约 2 现文成立 | 无(一句话确认) |
| 乙 | 用户本意为全局(或更宽范围) | 本卡范围重开=契约 2/T1/V1 大改,且触 08:193 Beta 行口径 |
| 乙 | 用户本意为全局(或更宽范围) | 本卡范围重开=契约 2/T1/V1 大改,且触 08:192 Beta 行口径 |
裁决方式:随卡片评审顺带确认。
**裁定(2026-10-18)**:**甲**——确认「Esc 浮窗只在营地语境」(推荐案,用户令按推荐执行)。契约 2 从「卡的从严收窄」升格为已确认口径;S1 保留意见关闭。
---
**审查回写要点**:v1.0→v1.1(2026-10-18 grilling 子 Agent 对抗审查回写)——事实订正 5 处:F9 刷新链路失实(营地刷新腿随 CampOverlay 退役、`_refresh_presentations` 是战斗侧腿)→契约 5 改挂卡④营地刷新单口+T2 刷新时机清单;E2「调试接口直改钥石」能力不存在(DebugOverlay 钥石只读)→改隔离存档实例直写(smoke 先例);F2 行号拆分(_open_settings :1055-1057);F8 :191→:192;估时算术 2.5–3.5d→3–4.5d。自扩订正:契约 2 标卡的从严收窄+Q3 请用户确认。卡内可收 8 项:契约 3 放宽语境分支、契约 7 遮挡结论+栈语义、契约 4 前提成文、T1 语境判据、T2 刷新时机+golden 联动、T3 探针宿主定 screen_flow_probe+badge 断言+变异补二条、V1 按 Q1 分拆、V4/V6/V8/V9 订补。跨卡对齐:HUD 刷新单口(§0 接口+卡④ T3 定义)、子界面返回钮承诺(Q1 甲案前提=卡④ T3)、终局落点不变量(T0 互证)、探针路径依赖卡②③链(§0)。新增待裁点 Q2 浮窗关闭路径、Q3 Esc 范围确认。用户面裁决(裁决 9/10)零改动。
@@ -0,0 +1,134 @@
# 需求卡片——gdstyle 尾波补件批
> **版本状态**:v1.1——2026-10-30 用户裁 T2 机制=R2 整族归件(实现段停卡呈报 `reports/iter45-停机呈报-断点域拆件规格缺口-2026-10-30.md` 裁决),第 7 节 T2 条款改述、其余条款沿 v1.0 定稿——零待裁点(2026-10-29 用户裁:恢复尾波卡 v2.0 裁去的 D2/D4 两拆件项;D5 五降值键=留债、零豁免延伸)。
> **接收方**:待办清单条目「gdstyle 尾波补件批——悬停域与断点域拆件(2026-10-29 登记)」。
> **来源**:尾波清偿批设计闭合后的用户再裁(D2/D4 改判拆件)。**唯一事实源**:`design/engineering/architecture/architecture.md` v1.25(「模块归属·呈现层」表 board_hover 行、「核心层」表 breakpoint_store 行、「冒险域拆分」节断点随动句、「呈现层装配」节屏成员寻址句)。
## 1. 目标与完成定义
这批做什么:把尾波卡 v2.0 裁去的两个拆件项恢复执行——board_view 悬停域拆出 board_hover、adventure_runner 断点域拆出 breakpoint_store。三个 gdstyle 键随之降值(board_view 类变量 32→约30、adventure_runner 类变量 28→约22;board_view 公开方法 27 持平——全为契约面)。
什么状态算完:
1. 两新件在库、宿主成员迁出、键账达第 3 节预期(降值口径,不承诺清零)。
2. 行为零变化:同种子下事件流、断点快照、棋盘渲染逐位一致。
3. 批末代码域闸全绿;三键终值按留债口径记入实现报告(禁落 architecture 豁免登记)。
## 2. 设计事实源
architecture.md v1.25 三处在册设计(2026-10-29 零豁免裁设计闭合):board_hover 行(职责语句「悬停预承诺呈现域」、拟收 11 函数族+2 成员、耦合边界)、breakpoint_store 行(职责语句「存档断点组装与回放唯一承载」、拟收 6 成员+函数族、27 键冻结)、「冒险域拆分」节随动句(拼盘与读侧策略机组拆出、应用层落盘口不变)。
## 3. 现状事实(2026-10-29 实查;行号为迭代 42 合回前基线——T0 必须按当轮 master 重测重锚,board_view 的 `_paint_cell` 届时已由迭代 42 拆为五段、行号必漂移)
- board_view.gd:悬停域成员 `_hover`(:70)、`_last_click`(:71);函数族 11 个=`_hover_at`(:442)、`_on_shell_mouse_exited`(:453)、`_detect_chord`(:475)、`_on_cell_hover`(:486)、`_on_cell_unhover`(:491)、`_refresh_hover_after_paint`(:497)、`_apply_hover_visuals`(:503)、`_clear_hover_visuals`(:531)、`_set_cursor_shape`(:538)、`_show_path_preview`(:542)、`_hide_path_preview`(:552)。`_r0`(:72)是出生展开区资格域成员(:238/:296/:563 三消费方),**不随迁**——划入悬停件即凑计数袋。
- adventure_runner.gd:断点域成员 6 个=`_save_manager`(:35)、`_resume_bp`(:36)、`_pending_next_level`(:30)、`_last_level_payload`(:31)、`_last_treasure_cleared`(:32)、`_loadout_seeded`(:37);常量 `BREAKPOINT_FIELDS`(:539-568,27 键);函数族=`_snapshot_breakpoint`(:571)、`_bp_parts`(:583)、`_bp_read`(:636)、`_bp_strategy`(:646)、`_bp_read_int`(:651)、`_resume_ledger`(:182)、`_resume_curio_state`(:193)、`_resume_params`(:218)、`_resume_counters`(:237);公开入口 `resume_adventure`(:141;:94 为 start_adventure)留宿主薄壳。
- 测试触面:`game/tests/unit/core/breakpoint_resume_test.gd:185` 直读 `AdventureRunnerScript.BREAKPOINT_FIELDS`——随件迁改址(判据零变化)。
- 键账:board_view 类变量 32(键留债目标约 30)、公开方法 27(持平——27 个逐类核对全为探针契约面与依赖单向纪律承载面);adventure_runner 类变量 28(留债目标约 22)。
## 4. 设计契约(违反即返工的红线条款)
- 🔴 **行为零变化**:同种子下事件流/断点快照/存档往返/棋盘渲染逐位一致;玩家可见面零变化。
- 🔴 **断点键集冻结**:`BREAKPOINT_FIELDS` 27 键逐键冻结(键名、策略标签、键序零变化);随件迁移只换承载文件,不换键面。
- 🔴 **RNG 零触碰**:本批零新流、零消费序变化(断点回放 restore 同序取号;悬停域无随机)。
- 🔴 **呈现零变化**:悬停反馈三语义(光标/边框/路径预览)行为逐点保持;棋盘 golden 三张对拍差异非零即红。
- 🔴 **拆分边界纪律**(判据权威=code-conventions §1.1,卡内执行条款):①拆出单元须有职责语句与单一变化原因(实现报告逐件一行);②集体身份——命不出名字的打包=凑计数袋,禁;③「过阈值」只作发现信号;④拆不出内聚单元→停卡呈报;⑤禁沿阈值轴拆。
- 🔴 **禁为机检文本保留无效成员**:禁止为迎合机检消息文本保留或新增无效成员/别名;机检键与卡片契约互斥=停卡呈报。
- 🔴 **残留键留债(D5 零豁免裁)**:三键降值后留基线冻结禁恶化;**禁落 architecture 豁免登记**;禁为凑阈值硬拆。
## 5. 范围边界
做什么:第 3 节两拆件项(board_hover、breakpoint_store)。
不做什么:迭代 42 在飞范围零触碰(_paint_cell 拆五段、循环内 new、_enter_node、商店委托壳——并排卡承接);单格/站桩状态件(呈现层状态件批承接);main.gd/battle_orchestrator/tune_sim 五键(零豁免五键各批承接);三残留键的终局清偿(留债,后续窗口再议)。
## 6. 关联文档同步面
| 文档 | 关联点 | 同步义务 |
|---|---|---|
| design/engineering/architecture/architecture.md | 两新件登记行(建件后「实现批建件」改现状);「冒险域拆分」节随动句核对 | 设计权威文档——实现批禁直改;逐条列进 `reports/iter<N>-反哺点-<日期>.md`,用户裁决后归文档批落文 |
| game/tests/README.md | 「棋盘悬停反馈」行代表用例列(本批复用既有探针、零新增断言——预计零改动);断点行入口句核对 | 机械面文档——实现批禁写;如需更新由写卡段后续卡修订版同批处理 |
| design/gdd/systems/ | 无关联文档——结构整改不改游戏规则与玩家可见行为 | 无修订预期;契约句被触碰=停卡呈报走反哺点通道 |
## 7. 任务卡 T0..T3
**T0 读数重锚与对账(0.25–0.5 工作日)**
- [ ] 以当轮 master 重测 board_view/adventure_runner 三键实测值与第 3 节全部 file:line;漂移处就地改卡并记录;对不上即停卡呈报
- [ ] 复核 11+9 函数族现行键面(`tools/gdstyle_baseline.txt` 无其函数级键——逐字搬运零新键;实查确认)
**T1 board_hover 拆件(0.75–1 工作日)**
- [ ] 建 `game/presentation/views/board_hover.gd`(RefCounted;构造=引用束注入:cells 容器引用、minesweeper 只读引用、diggable 集合引用+壳层光标写入与 hover_forbidden 注入 Callable)
- [ ] 悬停函数族 11 个+成员 `_hover`/`_last_click` 迁出(函数体逐字搬运);三入站口(`_gui_input`/`_on_cell_input`/`click_cell`)留宿主委托;`hover_probe()` 留宿主读件投影(返回语义零变化);`_r0` 留宿主
- [ ] 孤立验证:`tools/probe_gate.sh --click`+`--full` 全绿;`tools/render_gate.sh` 棋盘 golden 三张差异 0.00%(非零即停机呈报)
**T2 breakpoint_store 拆件(1–1.5 工作日)**
- [ ] 建 `game/core/breakpoint_store.gd`(RefCounted;构造=引用束注入:db、rng、主角账三件、curio/stop/bank/loadout 引用——防 max-parameters 新键)
- [ ] 断点域 6 成员+`BREAKPOINT_FIELDS`+函数族 9 个归件(v1.1 R2 整族归件,机制=所有权缝语句分家):纯读侧三函数(`_bp_read`/`_bp_strategy`/`_bp_read_int`)逐字;`_bp_parts`/`_snapshot_breakpoint` body 逐字(宿主输入 state/level_index/master_seed/runner/adventure_counters 逐调传参——件不反向持宿主);四 `_resume_*` 按所有权缝语句分家——件侧语句(主角账三件片段回填、curio 池与特性持有集还原、stop/bank 片段回填、六成员改写)迁入 store,宿主侧语句(summary/levels_total/level_index/_shop_mode/_treasure_unlocked/_attunement/_tree_rules/adventure_counters 重绑定与 `_reset_curio_state`/`_attune_refresh_x_total` 宿主调用)按原语句序吸收进 `resume_adventure` 壳,语句序逐步保形、27 键冻结;宿主保留 `_snapshot_breakpoint` 一行委托壳(CurioStop 的 Callable 目标零改)与 `set_save_manager` 转发件;宿主对六成员的其余读写点改址经件
- [ ] `breakpoint_resume_test.gd:185` 改址为 breakpoint_store 常量(判据零变化——第 14 节申报)
- [ ] 孤立验证:`--script res://tests/run_all.gd -- --only=breakpoint_resume,save_rng_roundtrip,cross_system_flow` 全绿+`python tools/run_smoke.py`
**T3 键账对账与收口(0.5 工作日)**
- [ ] 批末代码域闸全绿(`tools/run_all_gates.sh --code`)
- [ ] 三键终值对账(board_view 约30/27、adventure_runner 约22)——留债口径记入实现报告
- [ ] 产出物落位卡:实现报告与反哺点清单写齐方算收口
合计估时约 2.5–3.5 工作日。编队注记:编入待迭代 42 合回;**board_hover 半边硬前置=呈现层状态件批先合回**(该批改型 u.st 写入面后,hover 拆件在新写入面上施工——grilling 复核定级,原「推荐先行」升格);breakpoint_store 半边无此依赖,可独立先行。另:本卡与组合根注册面批共享 ui_input_probe.gd 触面(该批改 main.X 地址面、本批不改探针内 u.face 读面)——同代编排时先后皆可。
## 8. 验证闸——改动—验收对照表
域口径:本批改动全为 `game/` 下非 .md 行为载体——批末跑代码域闸;里程碑步(T 段)出口跑一次全套闸,波内修复只做出红最小单元的最窄确认,新增测试先行孤立验证再并入全套。总判据=每行改动以「既有断言面全绿+golden 零差异」证明零行为漂移;全量闸电池=冒烟+系统测试+run_all 全量+probe_gate --click --full+render_gate+static_scan(含 S13 对账)。
| 行 | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|---|
| V1 | 悬停域拆件 | board_hover.gd 新建;board_view.gd 函数族与 :70-71 成员迁出 | 复用 ui_input_probe 悬停三语义断言(case①到达/②禁入/③路径预览)+ui_click_probe+type_glow_shot_probe;新增断言零条 | 探针 | 合成 InputEventMouseMotion/MouseButton 经 `_gui_input` 入站口;`hover_probe()` 读面 | 探针可见性断言面(hover_probe 返回值、光标形状、格件状态面边框/点迹字段——施工时点在呈现层状态件批合回后,按其改型后投影面口径核对,判据语义零变化)+golden 三张零差异 | 既有:棋盘悬停反馈(三语义光标/目标格边框/路径预览点迹) |
| V2 | 断点域拆件 | breakpoint_store.gd 新建;adventure_runner 断点函数族与 6 成员迁出 | 复用 breakpoint_resume_test 全套+save_rng_roundtrip_test+cross_system_flow_test:_feats_breakpoint_roundtrip;新增断言零条;:185 改址(第 14 节申报) | 单元+集成 | AdventureRunner.resume_adventure()/start_adventure() × SaveManagerCore 断点域 | 断点快照往返逐键断言面(27 键冻结——键名/策略/键序零变化) | 既有:断点片段往返与续玩幂等;既有:旧档迁移链与断点续玩零跳号(集成) |
反向核对:diff 中每个行为改动均有行——本批申报行为改动为零(全部非行为改动=结构整改,判据=零漂移证明)。孤儿断言:无(零新增断言)。
## 9. 异常分级
- **L1 自救**:迁移函数编译错、探针调用面改址漏改——就地修复重跑最窄确认。
- **L2 记录继续**:实测值与预期区间偏离但同档位——记入实现报告「实现决定记录」。
- **L3 停机写报告等用户**:①拆分边界纪律④触发(含 `_r0` 归属认定被实现期证伪);②机检预算互斥——新件实数超第 12 节预算或迁移函数现出超标键=停卡退回写卡段;③golden 对拍差异非零;④S13 键恶化或基线外新键;⑤断言面被下游兜底吸收致判据绑不上。
## 10. 代拍板白名单
1. 迁移函数头注指址微调(词表与语义不动)。
2. 新件私有 helper 命名微调(职责语义不变)。
3. 断言失败消息尾缀〔补件 Vn〕分配与措辞。
4. 改址机械改写(preload 顺序、空行排版)。
## 11. 待裁点
零待裁点,开工门=U0。(裁决记录:2026-10-29 用户裁——恢复 D2/D4 拆件;D5 五降值键留债、零豁免延伸;`_r0` 留宿主;断点域六成员全迁。2026-10-30 用户裁——T2 机制=R2 整族归件、四 `_resume_*` 所有权缝语句分家、宿主侧语句吸收进壳;呈报=reports/iter45-停机呈报-断点域拆件规格缺口-2026-10-30.md。)
## 12. 落位与可复用性预检
- **board_hover.gd(新增)**:复用面核查——悬停预承诺逻辑现行全在 board_view(11 函数族全仓无第二实现,无既有件可复用);不能并入 TilePalette(瓦片装载)、HeroSprite(英雄演出)、CellUnit(格件绘制)——悬停预承诺与三者是不同变化原因。落点唯一:`game/presentation/views/` 新件,board_view `_init` 建为子件(HeroSprite 挂载先例)。调用路径:只被 board_view 持有与调用,输入经宿主入站口委托,禁反向持宿主引用(注入回调单向)。
- **breakpoint_store.gd(新增)**:复用面核查——断点拼盘与读侧策略现行在 adventure_runner(`BREAKPOINT_FIELDS` 登记单源唯一);不能并入 save_manager(存档 IO 原语与冒险断点语义是两个变化原因——SlotStore 拆分已立界)、不能并入 MetaStateStore(元进度数据件)。落点唯一:`game/core/` 新件。调用路径:只被 adventure_runner 调用;宿主经件组装快照后写盘,应用层落盘口不变。
- **新增函数**:零——全部为既有函数体逐字搬运。零新增数据件、零新增常量表(`BREAKPOINT_FIELDS` 为迁移非新增)。
## 13. 实现规范预算(gdstyle 默认阈值对账)
| 新件 | 公开方法 ≤20 | 类变量 ≤15 | 迁移函数对账 |
|---|---|---|---|
| board_hover.gd | 预算 6(悬停驱动入口) | 预算 2(`_hover`/`_last_click`)+引用束约 7(cells/minesweeper/diggable 引用+光标写入与 hover_forbidden 注入 Callable)=合计约 9 | 11 函数现行均无超标键(基线无其函数级键);`_apply_hover_visuals` 分支 5 |
| breakpoint_store.gd | 预算 8(快照/回填/读侧入口族) | 预算 6(拟拆成员)+引用束约 14(db/rng/主角账三件/curio/stop/bank/loadout)=合计约 20?否——引用束为单成员字典注入,实计=6+1 束+件内散标 ≤15(T0 按实数对账,贴顶禁再增) | `_bp_parts` 现行 49 行/9 局部(:583-630 实测)均在默认阈值内;`_resume_*` 四函数无超标键 |
存量触面一查:board_view 6 键与 adventure_runner 1 键 T0 读数写明「S13 键较登记值只降不升」预期;`_init` 一律引用束注入防 max-parameters 新键。
## 14. 测试削弱申报
1. `breakpoint_resume_test.gd:185`——`AdventureRunnerScript.BREAKPOINT_FIELDS` 直读随件迁改址为 breakpoint_store 常量;判据零变化,仅常量承载文件换代。
2. 除此之外禁删断言、禁放宽阈值、禁缩小扫描面、禁把真实入口换成下层直调;未申报的削弱由独立验收审计判红。
## 15. 独立验收审计
合并前由未参与实现的会话或子代理执行;报告落 `reports/iter<N>-验收审计-<日期>.md`。审计至少做四件事:逐行核对第 8 节对照表(测试存在、真执行、尾缀可 grep、真实入口未绕过改动点);抽查判据绑定面;检查测试削弱(对照第 14 节申报);核对两行「非行为改动」判定的零漂移证明是否在当轮真实跑批中成立。未过不得合并。
## 16. MC/数值与 RNG 零触碰声明
本批零数值改动、零数据表改动、零 RNG 流词表改动——断点回放 restore 同序取号、悬停域无随机。MC 对拍不跑。
@@ -0,0 +1,172 @@
# 需求卡片——呈现层状态件批
> **版本状态**:v1.0 定稿——零待裁点(2026-10-29 用户裁:单格两文件案、站桩两文件案、探针计数器留宿主、st/mo 命名、潜伏红随批修复)。
> **接收方**:待办清单条目「零豁免五键清偿批——S13 余量五键真修四卡(2026-10-29 登记)」(本卡=四卡中的「呈现层状态件批」一卡,承接 board_cell_unit 类变量 30→10 与 standee_body 类变量 19→10 两键)。
> **来源**:两份设计定稿全文。**唯一事实源**:`reports/设计-单格绘制状态件-2026-10-29.md`+`reports/设计-站桩状态件-2026-10-29.md`;`design/engineering/architecture/architecture.md` v1.25「模块归属·呈现层」表 cell_base_layer/cell_mark_overlay 行(:169)与 standee_vitals/standee_motion 行(:170)。
## 1. 目标与完成定义
这批做什么:把两个呈现层宿主的内部状态件沿职责缝拆成四个独立文件类——单格 `board_cell_unit.gd` 的 `_CellPaintState`(27 成员)按绘制层域轴拆 `cell_base_layer.gd`(12 成员)+`cell_mark_overlay.gd`(13 成员),宿主 `_draw` 退六步时序器、类变量 30→10;站桩 `standee_body.gd` 的 `_StandeeState`(真实 25 成员——基线 19 是 gdstyle 计数截断的欠估读数)按「身份命值/资产演出」缝拆 `standee_vitals.gd`(12 成员)+`standee_motion.gd`(11 成员),三个演出探针计数器留宿主、类变量 19→10。宿主实例命名:单格两件 `base`/`face`;站桩沿用 `st`(指 vitals)+新增 `mo`。附带处置一处潜伏红:ui_input_probe 四处绕过状态件直读格件成员的断言疑似已被迭代 41 状态件化打断,T0 实跑定谳,确红则随批修复。
什么状态算完:
1. 四新件在库、两宿主瘦身到位、六个 gdstyle 键账达预期(board_cell_unit 10/standee_body 10——较登记值 30/19 只降不升;四新件 12/13/12/11 全部阈值内零新键)。
2. 行为零变化:棋盘 golden 三张(L1 dungeon/L2 underdark/L3 deep_underdark)对拍差异 0.00%;探针冻结成员(glyph/fog_state/plate/glyph_color)与站桩演出时序、三条源码锚逐字不动。
3. 潜伏红定谳结论记实现报告;确红则四处改址落地、probe_gate 全绿闭环。
4. 批末代码域闸全绿;实现报告与反哺点清单写齐方算收口。
## 2. 设计事实源
两份设计定稿(2026-10-29 设计闭合,待办清单条目凭据与本节一致):单格篇 §4 拆分定案(两件案 A2、成员总账 10/12/13、写入路径对账表 §5.1、六步时序器 §6、键账预期 §7)、§1.2 gdstyle 截断缺陷与 §1.3 潜伏红发现、§1.4 探针直读面全清单;站桩篇 §3 方案 C(两独立文件+计数器留宿主)、§4 外部写入方零改动清单、§5 键账预期、§6 行为零变化六点。architecture.md v1.25 两行在册(呈现层表 :169-:170——职责语句、成员数、宿主 30→10/19→10)与「gdstyle 计数截断缺陷登记」节。
## 3. 现状事实(2026-10-29 主区实查;行号为迭代 42 合回前盘面——T0 必须在迭代 42 合回后按当轮 master 重锚)
**编队注记**:本卡与迭代 42 有 board_view 触面耦合——迭代 42(在飞,roadmap 迭代 42 行「进行中」)尾波清偿批 T1 把 `_paint_cell` 拆五段(`_paint_cell_base/_ink/_facade/_overlays/_fog`,段间只经 u.st/glyph/digit_col 传值)并抽 `_build_cell_unit`(:246-262),改变 u.st 写入面的函数分布结构(写入语句从单函数分散进段函数),写入路径形态 u.st.X 本身不变。**本卡 T0 必须在迭代 42 合回后执行**;本节行号按当前盘面实查,届时 board_view 全部写入点行号漂移、以 T0 重锚为准。反向编队义务:尾波补件批(board_hover)已裁「u.st 写入面改型后 hover 拆件在新面上施工」——本批先于其 board_hover 半边合回。另:本卡与组合根注册面批共享 ui_input_probe.gd 触面(该批改 main.X 地址面、本批改四处 u.face.* 读面,互不覆盖但同文件)——同代编排时禁并行、先后皆可,编入前置声明互指。
- **键账**:`tools/gdstyle_baseline.txt` :16 `board_cell_unit.gd|quality/max-class-variables = 30`、:23 `standee_body.gd|quality/max-class-variables = 19`。源码实查:board_cell_unit.gd 全文件 33 个类级 var(宿主 6+`_CellPaintState` 27,:26-122 内嵌类/:125-143 宿主);standee_body.gd 全文件 31 个(宿主 6+`_StandeeState` 25,:23-59 内嵌类/:62-68 宿主)。登记值 30/19 均为 gdstyle 对 inner class「首个带行尾注释属性截断」的欠估(architecture v1.25 已登记该工具缺陷;board_view.gd 无内嵌类、32 逐一全计——平面口径预测即实测)。
- **单格写入方**:唯一写方文件 board_view.gd。写入点实查——set_world_font:185(font)、set_cell_area:204(edge)、rebuild:250/251/253/260(cell/edge/bevel/font)、悬停面 :512-534(hl_visible/hl_color 五组写+一清)、路径预览 :549/:554(dot_visible)、`_paint_cell` :601-738(tex_seal:614/618、tex_base:665、bg_sb:666、glyph:667、glyph_color:668/674、plate:675、outline_sides:676/700、facade_south:677/690、proj_band:678/704、tex_facade:679/709、facade_strip:680/708、treasure_mark:713、badge_glyph:719/726、mutation_mark:723/725、glow_group:727、fog_state:734/736、removed_dim:737、终写 queue_redraw:738)、接触带 :780/:787/:804/:805/:810/:816、glow 同步 :768、cell_rect_probe 读 :891(u.st.edge)。
- **站桩外部触面**:唯一写状态的外部方 battle_stage_view——slot_row :140/:265、box :198/:208、font :232/:235、set_portrait_texture/register_hero_state :132-138、set_hero_state :313/:316/:388、演出三方法 :333-336;hud_presenter :77/:78/:137/:162/:163(set_hero/set_effects/set_effects_cleared_feedback);fx_probe 对 box 直写三处。测试直读 standee_fx_sweep_test.gd:103(`s1._intent_charge`);源码锚 theme_projection_test.gd:678-683(GOLD_BRIGHT 顺位墨/HERO_BLUE_BRIGHT 与 GOLD_BRIGHT 护甲墨/`_intent_charge = pid in CHARGE_SKILL_IDS` 三条 contains 断言)。
- **潜伏红(T0 定谳)**:ui_input_probe.gd 四处绕过 st 直读格件成员——:234-235(case① `u1.hl_visible`/`u1.hl_color`)、:243-244(case② `.hl_color`)、:250(case③ `.dot_visible`)、:374-379(case⑭ `.mutation_mark`)。这四个成员迭代 41 已迁入内嵌类 `_CellPaintState`,宿主 Node2D 上不存在同名属性,外部读预期运行时「Invalid get index」错误。时间线:探针末次全绿 2026-10-28 05:03 早于状态件合入 2026-10-29 01:37,合入后未跑过。设计文档同篇已含改址方案(u.face.*)。
- **探针冻结面(零改动义务)**:ui_input_probe.gd:271/:363(u.glyph)、:400-:492(u.fog_state case⑮族);player_copy_sweep_test.gd:138-140(u.plate/u.glyph_color wa8)。plate 绘制侧零消费(禁删禁接线——接线即行为变化)。
- **演出探针计数器**:standee_body.gd:57-59(_death_shards/_hit_sparks/_flash_count);唯一写入方宿主函数 :275/:315/:336,唯一读方 fx_probe() :301。
- **文件体量**:board_cell_unit.gd 423 行(迭代 41 已拆函数级键、本设计只解决类变量键;拆后宿主约 150 行);standee_body.gd 531 行。
## 4. 设计契约(违反即返工的红线条款)
- 🔴 **行为零变化**:绘制调用序与层序零变化——宿主 `_draw` 六步时序器与现行四函数调用树逐命令等价(设计文档单格篇 §6 四点论证:层间序/件内逐字搬运/接触带回退补画序整体保形/浮点推导式零改动);接触带「平色回退+微光并发的英雄格补画」重复绘制路径原样保形;setter 多写多触发序不变(facade_south/badge_glyph/mutation_mark 双写点);站桩六点(tween 路径串、三态机早退序、`_hp_flash_tw` 回色读 `_dead` 同拍、源码锚逐字、成员初始化时序、计数器纯易位)=站桩篇 §6。
- 🔴 **golden 三张零差异**:render_gate 棋盘 golden(L1 dungeon/L2 underdark/L3 deep_underdark)对拍差异 0.00%;非零即停机呈报,禁换锚、禁重制基线。
- 🔴 **冻结面逐字**:探针冻结成员 glyph/fog_state/plate/glyph_color 宿主保留、名称路径零变化;站桩三条源码锚所在函数留宿主且锚行逐字;battle_stage_view 一行不改(写入面零改动清单=站桩篇 §4)。
- 🔴 **拆分边界纪律**(判据权威=code-conventions §1.1,卡内执行条款;实现报告逐件一行职责语句):①拆出单元须有可陈述职责语句与单一变化原因——四件职责语句与宿主保留面语句照设计文档 §4.2/§4.3/§4.4 与站桩篇 §3 逐字承载(基座层绘制域/标识叠加绘制域/身份命值唯一账面/资产挂点与一次性演出;单格宿主=被动绘制壳+迷雾域+微光子件生命周期);②集体身份——命不出名字的打包=凑计数袋,禁;③「过阈值」只作发现信号,拆分动机是职责轴(迭代 41 函数级已沿同一条绘制层域轴,本批升到类级);④拆不出内聚单元→停卡呈报;⑤禁沿阈值轴拆。
- 🔴 **禁为机检文本保留无效成员**:禁止为迎合机检消息文本(含计数)保留或新增无效成员/别名;机检键与卡片契约互斥=实现段停卡呈报,不自造第三条路。
- 🔴 **gdstyle 截断缺陷声明**:本卡不依赖任何解析行为——四新文件与两宿主全部平面口径(无内嵌类),实数即闸读数;基线登记 30/19 属截断欠估,禁任何利用截断口径的降数手法(重排成员顺序/挪 setter 位置/删行尾注释),禁把 `_portrait_tex` 这类承重槽位当削减目标凑数。
- 🔴 **潜伏红处置纪律**:T0 一次 ui_input_probe 实跑定谳——确红=已申报的存量红承接,随批修复(T3 四处改址 u.face.*,断言条件与期望值零变化);禁静默放过、禁在实现报告外私记了结。
## 5. 范围边界
做什么:第 3 节两拆件项(单格两域件+宿主上收+board_view 写入面改址;站桩两状态件+宿主转调壳)、潜伏红定谳与四处改址、键账对账收口。
不做什么:迭代 42 在飞范围零触碰(_paint_cell 拆五段、_build_cell_unit、BoardInstaller、商店委托壳);board_hover/breakpoint_store(尾波补件批承接,且其 board_hover 半边待本批合回后施工);main.gd/battle_orchestrator/tune_sim 其余三键(零豁免五键各卡承接);`_portrait_tex` 冗余归一(站桩篇 §9-3 留债册);基线收账(各批合回后用户发令一次人工 `--refresh --force`,本批不刷新基线)。
## 6. 关联文档同步面
| 文档 | 关联点 | 同步义务 |
|---|---|---|
| design/engineering/architecture/architecture.md | 呈现层表 cell_base_layer/cell_mark_overlay 行与 standee_vitals/standee_motion 行(建件后「实现批建件」改现状登记);「gdstyle 计数截断缺陷登记」节的欠估数字(30/33、19/31——收账归后续人工 refresh 批) | 设计权威文档——实现批禁直改;逐条列进 `reports/iter<N>-反哺点-<日期>.md`,用户裁决后归文档批落文 |
| game/tests/README.md | 「棋盘悬停反馈(三语义光标/目标格边框/路径预览点迹)」行——真实入口(ui_input_probe 合成鼠标事件→BoardView._gui_input();读面 hover_probe())与代表用例(ui_input_probe.gd:_ready)预计零变化,批末核对;「地形瓦片套与格面数字可读」「站桩敌人呈现与结算演出落点」「未开格类型微光」「玩家面文案与危险格格面字形」各行代表用例列核对(本批零新增能力、复用既有载体,预计零改动) | 机械面文档——实现批禁写;批末收尾核对表上名字与实际落地一致(改名则回表) |
| design/gdd/ | 无关联文档——结构整改不改游戏规则与玩家可见行为 | 无修订预期;契约句被触碰=停卡呈报走反哺点通道 |
## 7. 文件结构图(卡前)
| 文件 | 新增/修改 | 职责 | 行为属性 |
|---|---|---|---|
| game/presentation/views/cell_base_layer.gd | 新增 | 单格基座层绘制域件:12 成员+九绘制函数逐字搬运+九个 D/E 档常量随迁+公开入口 draw_base | 非行为改动(V1) |
| game/presentation/views/cell_mark_overlay.gd | 新增 | 单格标识与叠加层绘制域件:13 成员+六函数段随迁+draw_centered_text 单点化+两绘制入口 | 非行为改动(V2) |
| game/presentation/views/standee_vitals.gd | 新增 | 站桩身份与命值态件:12 成员+apply_hp(原 _set_hp 整体搬移)+hp_value setter 逐字 | 非行为改动(V3) |
| game/presentation/views/standee_motion.gd | 新增 | 站桩资产与演出态件:11 成员+六迁入函数(两处改形点见 T2) | 非行为改动(V3) |
| game/presentation/views/board_cell_unit.gd | 修改 | 宿主瘦身:类变量 33→10(edge/cell/glow_group 上收+base/face 两实例)、_draw 退六步时序器、雾/glow/记忆态留宿主、头注改写(≤8 行) | 非行为改动(V1/V2) |
| game/presentation/views/board_view.gd | 修改 | 写入面改址约 40 处(u.st.X→u.base./u.face./u.edge/u.glow_group/u.cell,全清单=设计文档单格篇 §5.1/§5.2 对账表;行号 T0 重锚)+cell_rect_probe 一处 | 非行为改动(V1/V2) |
| game/presentation/views/standee_body.gd | 修改 | 宿主改造:类变量 31→10(五冻结 var+st+mo+三计数器)、同名转调壳、tween 路径串改指、源码锚行逐字不动 | 非行为改动(V3) |
| game/probe/ui_input_probe.gd | 修改 | 四处直读改址 u.face.*(T3,:234-235/:243-244/:250/:374-379) | 非行为改动(V4——判据零变化;T0 确红时兼具存量红修复身份) |
零新增数据件、零新增常量表(九常量为迁移非新增)、零新增测试件(全部复用既有断言面)。行为改动核对:本批申报行为改动为零——全部改动为逐字搬运、换参形与读路径改址;判据=零漂移证明(golden 零差异+既有断言面全绿+源码锚逐字)。
## 8. 任务卡 T0..T4
**T0 重锚与潜伏红定谳(0.25–0.5 工作日)**
- [ ] 前置确认:迭代 42 已合回 master(`_paint_cell` 五段在盘)——未合回即停,T0 不开工(编队注记)
- [ ] 以当轮 master 重测六个键账读数(board_cell_unit 33 声明/30 闸账、standee_body 31 声明/19 闸账——截断口径双读数对照)与第 3 节全部 file:line;board_view 写入点按五段新分布逐点重锚(路径形态核对仍为 u.st.X)、漂移处就地改卡并记录;对不上即停卡呈报
- [ ] ui_input_probe 一次实跑定谳潜伏红:红=确证设计文档单格篇 §1.3;绿=证伪设计前提(L3 停机呈报,见第 10 节)——定谳结果记实现报告
- [ ] 复核迁移函数零超标键:`tools/gdstyle_baseline.txt` 无 board_cell_unit/standee_body 任何函数级键(实查确认)——九+六函数与六搬移函数逐字/换参搬运零新键
**T1 单格两域件建件与迁移(1.5–2.5 工作日)**
- [ ] 建 `game/presentation/views/cell_base_layer.gd`:extends RefCounted、无 class_name、`_init(owner: Node2D)`;12 成员+四 setter 体逐字;九函数(_draw_base_layer/_draw_outline_sides/_draw_south_facade/_draw_north_projection/_draw_e_facade/_draw_contact_or_fallback/_draw_contact_bands/_draw_contact_corner/_draw_bevel)逐字搬运,三处机械改写=`st.X`→裸成员名、`draw_X(...)`→`canvas.draw_X(...)`、`st.edge`→`rect.size.x`;公开入口 `draw_base(canvas: CanvasItem, rect: Rect2)`;九常量随迁(FACADE_HIGHLIGHT_PX/FACADE_NEAR_FRAC/FACADE_FAR_FRAC/FACADE_NEAR_COL/FACADE_FAR_COL/PROJECTION_NEAR_COL/PROJECTION_MID_COL/PROJECTION_EDGE_COL/E_FACADE_FRAC——board_cell_unit.gd:12-23,UiKit.E_FACADE_FOOT_COL 不动)
- [ ] 建 `game/presentation/views/cell_mark_overlay.gd`:同形态;13 成员+八 setter 体逐字(含 badge_glyph 的 `_owner._glow_layer` mask 回引);六函数段随迁(_draw_mutation_marks/_draw_glyph_layer/_draw_digit_plate/_draw_glyph/_draw_badge+_draw_overlay_layers 的 dot/hl/removed 三段);公开入口 `draw_marks`/`draw_glyph_layer(canvas, rect, glyph, glyph_color)`(4 参)/`draw_overlay_under`/`draw_removed_dim`/`draw_centered_text(canvas, rect, text, color, font_size)`(5 参,文字渲染单点化)
- [ ] 宿主瘦身:board_cell_unit.gd——`base`/`face` 两实例于 `_init` 自建(preload 常量 `_BASE_LAYER`/`_MARK_OVERLAY`,设计文档 §4.5);edge/cell/glow_group 上收宿主(setter 体改直调自有面:edge 的 glow setup+queue_redraw、glow_group 守卫调 `_sync_glow_layer()`);glyph/glyph_color/plate/fog_state/_glow_layer 原位;`_draw` 改六步时序器(base.draw_base→face.draw_marks→face.draw_glyph_layer→face.draw_overlay_under→`_draw_fog_layer` 原位→face.draw_removed_dim,设计文档 §6 逐字);`_sync_glow_layer`/`_draw_fog_memory` 改址(§5.2——记忆态墨数字改调 face.draw_centered_text,同公式同字号);头注改写(两件句+冻结清单+「hl_color/hl_visible/dot_visible/mutation_mark 探针读 u.face.*」句,≤8 行)
- [ ] board_view 写入面逐点对账改址:按设计文档单格篇 §5.1 对账表每处核对改后形态(T0 重锚行号为准,约 40 处)——u.base.bg_sb/tex_base/outline_sides(assign 保引用语义)/facade_south/proj_band/tex_facade/facade_strip/contact_bands/contact_corners/contact_col/bevel;u.face.badge_glyph/dot_visible/hl_visible/hl_color/tex_seal/treasure_mark/mutation_mark/removed_dim/font/tex_mutation/tex_glyph/tex_badge;u.edge/u.cell/u.glow_group;u.glyph/u.glyph_color/u.plate/u.fog_state 与终写 u.queue_redraw() 不动;cell_rect_probe `u.st.edge`→`u.edge`
- [ ] 孤立验证:`tools/render_gate.sh` golden 三张差异 0.00%(非零即 L3 停机);`--script res://tests/run_all.gd -- --only=player_copy,theme_projection,type_glow,terrain` 全绿;`python tools/run_smoke.py`。probe_gate 各段本卡内暂不计绿——ui_input_probe 段在 T3 改址前处于 T0 已定谳态(存量红或改址等待),T3 闭环
**T2 站桩两状态件建件与迁移(0.5–1 工作日)**
- [ ] 建 `game/presentation/views/standee_vitals.gd`:RefCounted、无 class_name;12 成员(_owner/_kind/_display_name/_enemy_id/_armor/_order/_dead/_hp_max/_hp_cur/hp_value/_hp_tween/_hp_flash_tw);`apply_hp(hp)`=原 `_set_hp` 整体搬移(clamp、重启 `_hp_tween`、tween 写 hp_value——路径串 `"st.hp_value"` 零改);`hp_value` setter 逐字(clamp+`_owner.queue_redraw()`);`_hp_flash_tw` 归此件(flash_hit 回色分支读 `_dead` 同域)
- [ ] 建 `game/presentation/views/standee_motion.gd`:RefCounted、无 class_name;11 成员(_owner/_portrait_sprite/_portrait_tex/_hero_tex/_hero_state/_state_revert_tw/_intent_glyph/_intent_col/_intent_visible/_intent_scale/_glyph_rot);六迁入函数——`set_portrait_texture(tex, flip, box)`(box 由宿主传入)、`register_hero_state`、`apply_hero_state(state, is_hero)`(原 set_hero_state,唯一改形=`st._kind != "hero"` 早退改参判 `is_hero`,三连早退条件序逐字)、`reset_state()`(原 `_revive` 内「置 RESET 强制绕同态早退」两拍封装)、`play_intent_motion(charge)`(`_intent_charge` 改参传入;tween 路径串改 `"mo._intent_scale"`/`"mo._glyph_rot"`)、`state_probe()`
- [ ] 宿主改造:standee_body.gd——`st` 名保留改指 vitals、新增 `mo`;三计数器留宿主(:57-59 原位);同名转调壳(set_portrait_texture/register_hero_state/set_hero_state 三入口 1–2 行转调,签名外形零变);`_draw` 全族与几何函数留宿主、成员前缀改指(st.→mo. 仅资产演出域成员);六个 probe/display_name/enemy_id/is_dead 出口外形零变体内改指(fx_probe 改读宿主计数器);源码锚所在三函数(_draw_hp_bar/_draw_armor_name_line/set_pending)留宿主且 :678-683 锚行逐字不动;`_intent_charge` 与五冻结 var 原位
- [ ] battle_stage_view 写入面对账(站桩篇 §4 清单逐点):结论=零改动——slot_row/box/font 直写原位、三同名转调入口承接、演出三方法原位;hud_presenter :77/:78/:137/:162/:163 零改动;实机核对一遍
- [ ] 孤立验证:`--script res://tests/run_all.gd -- --only=standee_fx_sweep,theme_projection` 全绿;孤立验证同 T1 口径(probe_gate 推迟 T3 闭环)
**T3 潜伏红处置(0.25–0.5 工作日)**
- [ ] ui_input_probe.gd 四处改址::234-235→`u1.face.hl_visible`/`u1.face.hl_color`、:243-244→`.face.hl_color`、:250→`.face.dot_visible`、:374-379→`.face.mutation_mark`——断言条件与期望值零变化,只改读路径
- [ ] 孤立验证(本卡闭环点):`tools/probe_gate.sh --click --full` 全绿——ui_input_probe 恢复绿;若 T0 定谳为红,本步同时即存量红修复闭环;`tools/render_gate.sh` golden 三张复跑一次仍 0.00%
**T4 键账对账与收口(0.5 工作日)**
- [ ] 批末代码域闸全绿(`tools/run_all_gates.sh --code`——三件保险恒跑+本卡申报套件族+探针+渲染+静态)
- [ ] 六文件键账对账:board_cell_unit 10/cell_base_layer 12/cell_mark_overlay 13/standee_body 10/standee_vitals 12/standee_motion 11(平面口径实测);两存量键 30→10、19→10「较登记值只降不升」达成;基线不随批刷新(收账归用户发令人工 refresh)
- [ ] 产出物落位卡:`reports/iter<N>-实现报告-<日期>.md`(各卡状态+潜伏红定谳结论+实现决定记录)与 `reports/iter<N>-反哺点-<日期>.md`(第 6 节所列每条有落点)写齐方算收口
合计约 3–5 工作日。切分预案:T1 超软盒时拆 T1a(基座件+宿主上收)/T1b(叠加件+board_view 改址)各 0.75–1.25 工作日。回归措辞:里程碑步(T 段)出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试先行孤立验证再并入全套(本批零新增测试)。
## 9. 验证闸——改动—验收对照表
域口径:本批改动全为 `game/` 下非 .md 行为载体——批末跑代码域闸(重闸按域选档);总判据=每行改动以「既有断言面全绿+golden 零差异」证明零行为漂移。**静态键账判据按 test-conventions §8.4 出口在本段申报观测面局限、不入对照表**:S13 六文件键账(10/12/13/10/12/11)与两存量键只降不升(30→10、19→10)以 static_scan S13 回执为判据(可 grep 定位)——键清偿是结构判据非运行期断言,故不出现在下表。
| 行 | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|---|
| V1 | 单格基座层域件 | cell_base_layer.gd 新建(12 成员+九函数+九常量);board_cell_unit.gd 宿主上收 edge/cell/glow_group+六步时序器;board_view.gd 基座域写入点改址(对账表 §5.1 基座行) | render_gate 棋盘 golden 三张(board_L1/L2/L3)+board_shot_probe/type_glow_shot_probe 取证;新增断言零条 | 探针+golden | BoardView.rebuild()→refresh() 真实场景帧(board_shot_probe) | golden 逐像素容差比对(差 ≤16/changed ≤2%)差异 0.00%=绘制命令流逐位;微光子件生命周期取证(glow_group setter 直调时序零漂移) | 既有:地形瓦片套与格面数字可读;既有:未开格类型微光(8 邻作用集/五组色相/零玩法写入) |
| V2 | 单格标识叠加域件+冻结面保留 | cell_mark_overlay.gd 新建(13 成员+六函数段+draw_centered_text);board_cell_unit.gd 四冻结成员原位;board_view.gd 标识域写入点改址+cell_rect_probe 一处 | 复用 player_copy_sweep_test.gd:_sweep_board_glyph+wa8(:138-140 plate/glyph_color 直读零改动);ui_input_probe case④b/⑪/⑮(glyph/fog_state 冻结读面);run_all 02 闸选跑+render_gate golden;新增断言零条 | 单元+探针+golden | BoardView.rebuild()→refresh()(player_copy 夹具真实构建);ui_input_probe 合成鼠标事件 | u.plate/u.glyph_color/u.glyph/u.fog_state 直读断言零改动全绿;golden 三张零差异(雾层原位夹在 hl 与 removed 之间) | 既有:玩家面文案与危险格格面字形;既有:地形瓦片套与格面数字可读 |
| V3 | 站桩两状态件 | standee_vitals.gd/standee_motion.gd 新建;standee_body.gd 宿主 10 成员+转调壳+tween 路径串改指;battle_stage_view 写入面零改动 | 复用 standee_fx_sweep_test 全套(:103 `_intent_charge` 直读、fx_probe().flash_count、enemy_id 解析)+theme_projection_test 三条源码锚(:678-683 逐字)+probe_gate --full 段(fx_probe/ui_probe:碎裂 5/火花 6/闪白计数/三态切换/意图三档/name_line/portrait/has_world_hp_bar/slot_row)+ui_click_probe tooltip;新增断言零条 | 单元+探针 | StandeeBody 公开方法面(set_data/set_hero/set_pending/mark_dead/flash_hit)与 battle_stage_view.on_step_row_fx 演出链;探针场景真实实例化 | fx_probe()/intent_probe()/hero_state_probe() 出口返回逐键;源码锚 contains 断言逐字命中;tween 属性路径串("st.hp_value"/"mo._intent_scale"/"mo._glyph_rot")由意图弹入与三态断言兜底 | 既有:站桩敌人呈现与结算演出落点;既有:UI 全局主题与按钮五态(含对比度锚) |
| V4 | 潜伏红处置与探针改址 | ui_input_probe.gd:234-235/:243-244/:250/:374-379 四处直读改址 u.face.*(判据零变化;T0 确红时兼具存量红修复) | ui_input_probe 全套断言改址后执行且绿(case①②③⑭);probe_gate --click --full 全绿 | 探针 | ui_input_probe 合成鼠标事件→BoardView._gui_input() | 四处断言执行且绿(悬停金框/禁入红框/路径点迹/变异角标,读路径 u.face.*);probe_gate 三硬闸全过=存量红闭环 | 既有:棋盘悬停反馈(三语义光标/目标格边框/路径预览点迹) |
反向核对:diff 中每个改动均有行——本批申报行为改动为零(结构整改,判据=零漂移证明),V1–V4 四行覆盖全部八个文件行。孤儿断言:无(零新增断言)。
## 10. 异常分级
- **L1 自救**:迁移函数编译错、改址漏改、preload 常量名笔误——就地修复重跑最窄确认。
- **L2 记录继续**:实测行号与第 3 节偏离但路径形态一致(T0 重锚记录);探针段实测时长同量级漂移。
- **L3 停机写报告等用户**:①机检预算互斥——新件实数超第 14 节预算或迁移函数现出超标键=上游缺陷停卡退回写卡段;②golden 对拍差异非零(禁换锚禁重制基线);③潜伏红证伪设计前提——T0 实跑 ui_input_probe 现状绿,即设计文档单格篇 §1.3 的 GDScript 取索引语义判断被证伪(改址四处义务不变,等用户裁决后继续);④S13 键恶化或基线外新键;⑤拆分边界纪律④触发(按职责轴拆不出内聚单元);⑥断言面被下游兜底吸收致判据绑不上(test-conventions §8.4 出口呈报)。
## 11. 代拍板白名单
1. 迁移函数与新件头注指址微调(职责语句、冻结清单句与语义不动)。
2. 新件私有 helper 命名微调(职责语义不变;公开入口名按第 8 节逐字)。
3. 改址机械改写(preload 常量顺序、空行排版、注释随迁改写)。
4. 断言失败消息尾缀〔状态件 Vn〕分配与措辞。
5. T0 重锚产生的行号漂移卡面注记更新(不改判据与改后形态)。
## 12. 待裁点
零待裁点,开工门=U0。(裁决记录:2026-10-29 用户裁——单格两文件案〔淘汰整体一件 A3 与成员削减路 B〕;站桩两文件案+三个演出探针计数器留宿主〔淘汰原地 −4 案〕;实例命名 st 沿用/mo;潜伏红随批修复〔弃「先最小工程批改 u.st.* 再二次改址」时序〕;cell 成员保留〔宿主 10 含 cell——弃删除倾向〕;gdstyle 截断口径登记已由 architecture v1.25 落文收口。)
## 13. 落位与可复用性预检
- **cell_base_layer.gd(新增)**:复用面核查——基座层绘制现行全在 board_cell_unit 内嵌类+宿主九函数(全仓唯一实现,无既有件可复用);不能并入 TilePalette(瓦片装载与查表件、架构表明载零绘制面——职责互斥)、不能并入 BoardWorld(世界根/材质挂点)、不能并入 CellUnit 本体的字形迷雾域(变化原因不同)。落点唯一:`game/presentation/views/` 新件,board_cell_unit `_init` 自建持有(每格 Node2D+两 RefCounted,与现状同量级;件内自建不触发 allocation-in-loop 新键——构建器函数体不在循环体内)。交互路径:宿主持有两件引用;件→宿主仅 `_owner.queue_redraw()`/glow mask 回引(与现状 inner class 同形);宿主迷雾记忆态读 `base.tex_base` 公开成员单向(成文于宿主头注)。
- **cell_mark_overlay.gd(新增)**:同上排除;迷雾留宿主是三域中唯一不产生跨件回引的落点(设计文档 §4.4——雾夹在两件入口之间、读件 A 纹理与件 B 字体渲染);`draw_centered_text` 单点化供宿主复用(零复制)。
- **standee_vitals.gd/standee_motion.gd(新增)**:复用面核查——25 成员现行全在 `_StandeeState`(全仓唯一);不能并入 battle_stage_view(壳层视图,站桩本体是世界件)、不能并入 StatusSlotRow(壳层伴随件)。落点唯一:`game/presentation/views/` 新件,standee_body 持有 st/mo;外部仍只经宿主方法与五冻结 var(box/font/slot_row/has_world_hp_bar/_intent_charge 原位),零新增外部直访面;`_owner` 回引同形、禁反向引用。
- **四新件对既有周边件逐一排除**(TilePalette/HeroSprite/CellUnit/BoardWorld,架构文档呈现层表在册件):TilePalette=瓦片装载与查表件、架构表明载零绘制面——四件都不并入;HeroSprite=英雄精灵演出件(落位/位移/帧闪)——与四件变化原因不同;CellUnit 本体(board_cell_unit 宿主)=两格件的持有壳而非合并对象(拆分方向是自宿主出、非并入宿主);BoardWorld=棋盘 Node2D 世界根(材质挂点)——零绘制入参承载。站桩两件另排除 battle_stage_view(壳层视图)与 StatusSlotRow(壳层伴随件)。
- **新增函数清单**:apply_hp/set_portrait_texture(3 参形)/apply_hero_state(is_hero 参形)/reset_state/play_intent_motion(charge 参形)/state_probe/draw_base/draw_marks/draw_glyph_layer/draw_overlay_under/draw_removed_dim/draw_centered_text——全部为既有函数体整体搬移或既有函数换参形与改名入口,无新逻辑。新增前已 grep 同名标识符:`apply_hero_state`/`reset_state`/`state_probe`/`draw_base` 等盘上无第二处。
## 14. 实现规范预算(gdstyle 默认阈值对账)
| 新件 | 公开方法 ≤20 | 类变量 ≤15 | 迁移函数对账 |
|---|---|---|---|
| cell_base_layer.gd | 预算 5(draw_base+4 setter) | 12(设计文档 §4.1 实数) | 九函数逐字搬运——基线无其函数级键(T0 实查)、行数/分支/局部/返回不变=零新键 |
| cell_mark_overlay.gd | 预算 13(5 绘制入口+8 setter) | 13(同上) | 六函数段同上;draw_glyph_layer 4 参、draw_centered_text 5 参(max-parameters 默认 5=合规上限内) |
| standee_vitals.gd | 预算 1(apply_hp)+hp_value setter | 12(设计文档 §5 实数) | apply_hp 整体搬移零键(原 _set_hp 现役无超标键) |
| standee_motion.gd | 预算 6(六迁入函数)+2 属性 setter | 11(同上) | 六搬移函数逐字/换参——最大者 apply_hero_state 4 参数 4 分支全在原值内;宿主转调壳 1–2 行零键 |
存量触面一查:board_cell_unit 键 30→10、standee_body 键 19→10——T0 写明「S13 键较登记值只降不升」预期与达成手段(成员迁出后实数即证);board_view 六键零触碰(改址不动成员数与函数面,32 留债冻结)。宿主 `_init` 一律单参构造注入,防 max-parameters 新键。
## 15. 测试削弱申报
1. ui_input_probe.gd 四处直读改址(T3/V4)——断言条件与期望值零变化,仅读路径 u.X→u.face.X;若 T0 确红,同处兼具存量红修复(恢复断言效力)。
2. 除此之外禁删断言、禁放宽阈值、禁缩小扫描面、禁把真实入口换成下层直调;golden 三张基线禁重制;未申报的削弱由独立验收审计判红。
## 16. 独立验收审计
合并前由未参与实现的会话或子代理执行;报告落 `reports/iter<N>-验收审计-<日期>.md`。审计至少做四件事:逐行核对第 9 节对照表(测试存在、真执行、尾缀可 grep、真实入口未绕过改动点);抽查判据绑定面(golden 零差异在当轮真实跑批成立、源码锚逐字);检查测试削弱(对照第 15 节申报);核对全部行「非行为改动」的零漂移证明。未过不得合并。
## 17. MC/数值与 RNG 零触碰声明
本批零数值改动、零数据表改动、零 RNG 流词表改动;站桩演出与呼吸微光时长全经 UiKit.motion 现值、零漂移。MC 对拍不跑。
@@ -1,453 +0,0 @@
# 需求卡片:战斗区背景替换——B 区舞台插画与连续地面层
> 日期:2026-10-31
> 性质:需求改动实现批卡片;零待裁点,开工门=U0。
> 来源:待办清单「战斗区背景图替换——B 区舞台插画 + 临时光柱退役」条(唯一事实源:[art-bible](../design/art/art-bible.md) §6.1 v3.28 与 [battle-stage-prompts](../design/art/battle-stage-prompts.md) v1.7;候选样张过审 2026-10-31,候选与推荐套见 `artwork/2026-10-30-战斗区背景/候选保存清单-2026-10-31.md`)。
> 估时:T0–T5 ≈ **3.75~4.5 个工作日**;切分预案见第十三节。
## 一、设计事实源
1. [art-bible](../design/art/art-bible.md) §6.1 v3.28:B 区舞台场景构成、图层归属与资产契约——背景层三关变体(按 `board_type` 选图、不画光柱、不走 tint)、独立连续地面层(三关共用、不吃 tint、高度读 `ground_h`)、小石台保留并叠在连续地面之上;`ground_h` 字段由本实装批新增并回填。
2. [art-bible](../design/art/art-bible.md) §4.1 换色合并登记③(现行工作区 v3.29 行):`STAGE_BG`(原舞台底)随 §6.1 舞台背景插画批一并处置——背景资产接管绘制面时源常量退役或改指,禁单独为改值出批。本卡按其口径退役源常量,平色缺图回退改指 `UiKit.SLOT_BACKDROP`(#3E362C,合并目标)。
3. [battle-stage-prompts](../design/art/battle-stage-prompts.md) v1.7:三张背景与一张共用地面的画布尺寸、分层要求、否定后缀与验收;终稿尺寸 = 基准屏宽 × `stage_h`/基准屏宽 × `ground_h`。
4. 候选过审:2026-10-31 用户确认三关背景各 3 张全部可用、共用地面前后两轮修正后 v12 系列可用;遴选与后续替换/编辑由作者另行安排,不阻塞本卡。
本卡只实现上述设计,不改设计。艺术资产的最终遴选、编辑与入包走美术素材直改通道(asset-ingest),不属本卡写面。
## 二、目标与完成定义
本批把 B 区舞台从「程序化平色底+四柱光柱层」临时占位,换成「三关背景变体+共用连续地面层+保留小石台」的正式呈现,并把选图接到真实装板链上。
完成定义:
1. B 区背景按 `board_type` 选图:`dungeon` / `underdark` / `deep_underdark` 三值分别命中 `scene_stage_bg_<board_type>.png`;空串与未知值回落 `dungeon`;目标变体缺图时先回落 `dungeon`,仍缺则保留平色底 `UiKit.SLOT_BACKDROP`(#3E362C,原舞台底合并目标)。
2. B 区底部新增共用连续地面层 `scene_stage_ground.png`,底边贴 B 区底、全宽、高度读布局表 `ground_h`;三关共用,不按 `board_type` 换图。
3. 布局表新增 `ground_h` 字段(本卡回填 100)并带加载期校验;`tools/layout_config.py` 同步读取该字段。
4. 四柱光柱程序层退役:删除光柱绘制层与 `UiKit.BEAM_LIGHT`,任何缺图态也不出现光柱;舞台底源常量 `UiKit.STAGE_BG` 随背景接管退役,平色回退改指 `UiKit.SLOT_BACKDROP`(#3E362C,换色合并③目标);背景与地面均不引用 `wall_ambient` tint(现行代码本就无该路径)。
5. 现有小石台 `scene_stage_plaza.png` 原样保留,叠在连续地面之上;不改地台件与 `standee_body` 的地台绘制。
6. 装板真实链路(`board_changed` 与调试对局就绪)把当前板 `board_type` 同步到舞台;连续一层未知或空串时不崩、不刷错误。
7. 既有战斗屏呈现回归全绿:站桩、排播、明细带、三区几何、文字对比、明度三档带、棋盘/菜单/关卡 golden 零变化;渲染闸全绿。
8. 独立验收审计通过;反哺点清单覆盖第六节全部目标;本批不写 `design/` 与根规则文件。
## 三、现状事实
1. `BattleStageView._init(db_ref, layout)` 以 `layout.stage_h` 设置 B 区最小高度,随后建背景、世界、文本半区、伴随件层:[battle_stage_view.gd:27](../game/presentation/views/battle_stage_view.gd#L27)。
2. 背景现行=`Panel` 平色底 `UiKit.panel_flat(UiKit.STAGE_BG, UiKit.PANEL_BORDER, 0, 1)`,随后调用光柱层:[battle_stage_view.gd:37](../game/presentation/views/battle_stage_view.gd#L37)、[:44](../game/presentation/views/battle_stage_view.gd#L44)。
3. 光柱层为全幅 `Control`,绘制四柱(x 基准 110/900/1055/1210@1280,60 段,α26→0):[battle_stage_view.gd:50](../game/presentation/views/battle_stage_view.gd#L50)、[:145](../game/presentation/views/battle_stage_view.gd#L145)。
4. `UiKit.STAGE_BG = Color8(62,52,42)`、`UiKit.BEAM_LIGHT = Color8(255,236,200)`:[ui_kit.gd:185](../game/presentation/views/ui_kit.gd#L185)、[:186](../game/presentation/views/ui_kit.gd#L186)。
5. `UiKit.TEX_STAGE_PLAZA` 是现有唯一场景件常量;`UiKit.load_tex()` 以 `ResourceLoader.exists` 守卫缺图:[ui_kit.gd:250](../game/presentation/views/ui_kit.gd#L250)、[:290](../game/presentation/views/ui_kit.gd#L290)。
6. `game/assets/art/scene/` 现只有 `scene_stage_plaza.png`;三张背景与地面尚未入包(素材目录不入 git,工作区需同步素材)。
7. 布局表 schema 现五字段:`stage_h` / `info_panel_w` / `ap_bar_h` / `log_band_h_dig` / `log_band_h_settle`;`validate()` 已检查域与两处跨字段:[battle_layout_table.gd:7](../game/data/schemas/battle_layout_table.gd#L7)、[:14](../game/data/schemas/battle_layout_table.gd#L14)。无 `ground_h`。
8. 布局表值:`stage_h=252`、`info_panel_w=240`、`ap_bar_h=44`、`log_band_h_dig=24`、`log_band_h_settle=84`:[battle_layout.tres:7](../game/data/tables/battle_layout.tres#L7)。
9. `ConfigDB` 的 manifest 已登记 `battle_layout`,加载后装配到 `presentation.battle_layout`:[config_db.gd:32](../game/core/config_db.gd#L32)、[:151](../game/core/config_db.gd#L151)。
10. `BoardData.board_type` 为图类型标签(`dungeon` / `underdark` / `deep_underdark`):[board_data.gd:19](../game/core/board_data.gd#L19)。
11. 棋盘视图 `rebuild()` 已按 `board_type` 装载瓦片套,空串回落 `dungeon`:[board_view.gd:257](../game/presentation/views/board_view.gd#L257)。
12. 装板成功即发 `board_changed`:[battle_orchestrator.gd:406](../game/core/battle_orchestrator.gd#L406);主场景处理点重建棋盘视图:[main.gd:361](../game/presentation/main.gd#L361)、[:367](../game/presentation/main.gd#L367)。
13. 调试对局就绪路径直接重建棋盘视图,不经过主场景处理点:[main_debug_flow.gd:101](../game/presentation/main_debug_flow.gd#L101)、[:103](../game/presentation/main_debug_flow.gd#L103)。
14. 舞台当前没有任何接收 `board_type` 的入口,也没有背景/地面纹理常量(全仓 grep 零命中)。
15. 舞台世界为透明 SubViewport;站桩、地台、落影都在世界内绘制:[battle_stage_view.gd:60](../game/presentation/views/battle_stage_view.gd#L60)、[:71](../game/presentation/views/battle_stage_view.gd#L71);小石台绘制在站桩底:[standee_body.gd:367](../game/presentation/views/standee_body.gd#L367),台面矩形 `_pedestal_rect()` 在 [standee_body.gd:312](../game/presentation/views/standee_body.gd#L312)。
16. 舞台由装配器一次性构造(冒险屏 `_ready` 时):[ui_assembler.gd:27](../game/presentation/ui_assembler.gd#L27)、[adventure_screen.gd:28](../game/presentation/scenes/adventure_screen.gd#L28);背景/地面只能在建件后按板同步,不能重建整屏。
17. 布局表读取工具 `FIELDS` 现五字段,无 `ground_h`:[layout_config.py:12](../tools/layout_config.py#L12)。
18. 渲染闸 `shot_checker` 对战斗屏判 C 区文字、明细带提示、明度三档带(信息面 > 世界中 > 世界底):[shot_checker.py:143](../tools/shot_checker.py#L143);golden 仅棋盘三张+菜单+关卡,不覆盖 B 区舞台。
19. `theme_projection_test` 的光柱断言对象是 `UiKit._beams_rect()`(菜单斜光带),不是舞台四柱层:[theme_projection_test.gd:628](../game/tests/unit/presentation/theme_projection_test.gd#L628);本批退役舞台层不影响该断言。
20. 全仓代码无 `wall_ambient` 标识符;仅 `ui_kit.gd:249` 有注释说明小石台不吃该 tint,内容不构成本批改动。
21. 现有地台件入包与尺寸断言:[standee_present_values_test.gd:76](../game/tests/unit/presentation/standee_present_values_test.gd#L76)。
22. 布局探针已从真实选路入口进战斗屏并逐档检查三区几何:[layout_probe.gd:31](../game/probe/layout_probe.gd#L31)、[:55](../game/probe/layout_probe.gd#L55)。
23. `STAGE_BG` 现行四处引用:`ui_kit.gd:185` 常量、`battle_stage_view.gd:39` 绘制点、`theme_projection_test.gd:669`、`ui_contrast_probe.gd:30`;art-bible §4.1 换色合并③(工作区 v3.29 行)要求随本批退役或改指,禁单独改值出批。
## 四、设计契约
- 🔴 **C1 选图口径**:背景只按 `board_type` 三值选图;空串与未知值回落 `dungeon`;不得按关卡序号、节点深度或 `board_variants` 另造第二套选择逻辑。
- 🔴 **C2 背景尺寸**:背景纹理源 = 1280 × `stage_h`,基准档显示 1×;三张文件名必须带 `_dungeon` / `_underdark` / `_deep_underdark` 后缀,禁止同一张图换色或换 tint。
- 🔴 **C3 地面层**:连续地面层源 = 1280 × `ground_h`,三关共用、文件名不带 `board_type` 后缀;底边贴 B 区底、全宽;顶缘即与远景的分隔带;禁横向拉伸(基准档 1×)。
- 🔴 **C4 图层序**:背景 < 连续地面 < 世界站桩/小石台 < 文本半区 < 壳层伴随件。小石台必须在连续地面之上;禁把地面画进背景、禁把地台并进地面件。
- 🔴 **C5 光柱退役**:四柱程序层与 `UiKit.BEAM_LIGHT` 全删;任何缺图态、任何 `board_type` 下都不得再出现光柱/光带/光晕;菜单斜光带 `UiKit._beams_rect()` 不在退役面。
- 🔴 **C6 `ground_h` 单源**:`ground_h` 只存布局表,经 `ConfigDb.presentation.battle_layout` 读取;视图层零 `ground_h` 数值字面量。schema 校验不得放行「地面层被收起态明细带整条盖住」与「地面层超过 B 区一半」。
- 🔴 **C7 缺图回退**:目标背景缺图 → 回 `dungeon` 背景 → 再缺 → 保留平色底 `UiKit.SLOT_BACKDROP`(#3E362C,原舞台底合并目标);地面缺图 → 地面层隐藏、背景仍显示。任何回退都不得崩溃、不得刷脚本错误、不得出现光柱。
- 🔴 **C8 接板真实入口**:`board_changed` 与调试就绪两条现有入口都在重建棋盘后同步舞台 `board_type`;禁另立轮询、定时器或第二套装板通知。
- 🔴 **C9 tint 口径**:背景三张各自带关卡色族、连续地面三关恒定,二者均不引用 `wall_ambient` 槽;不得给舞台加第二层 tint 或乘色。
- 🔴 **C10 呈现回归**:渲染闸全绿——B 区文字对比、明细带纹理幅度、明度三档带(信息面 > 世界中 > 世界底)判据不变;棋盘三张、菜单、关卡 golden 零改动。判据若需改动=停卡呈报,禁调阈值换绿。
- 🔴 **C11 结构预算**:`battle_stage_view.gd` 类变量 ≤15、公开方法 ≤20、函数长 ≤50 行、单函数分支 ≤8;`battle_layout_table.gd` 的 `validate()` 不新增分支(地面校验拆私有辅助);S13 基线外零新增、存量键只降不升。
- 🔴 **C12 写面**:实现批只写 `game/` 与 `reports/`;禁写 `design/`、`roadmap.md`、`待办清单.md`、`体验验证清单.md`、`game/tests/README.md`;文档同步只列反哺点。
- 🔴 **C13 禁凑计数袋**:不得为凑「类变量数」把背景/地面状态塞进无关容器;不得为凑「方法数」把选图与地面几何强行合并成一个无职责函数;拆分单元须有可陈述职责。
- 🔴 **C14 舞台底换色合并**:`UiKit.STAGE_BG` 源常量随本批退役;平色缺图回退改指 `UiKit.SLOT_BACKDROP`(#3E362C,art-bible §4.1 换色合并③目标);`theme_projection_test` 与 `ui_contrast_probe` 的舞台底对比锚同步改读合并目标,阈值、判据与覆盖不变。
## 五、范围边界
做:
1. `UiKit` 增三关背景路径格式常量与共用地贴路径常量。
2. `BattleStageView` 增背景纹理层、连续地面层、`set_board_type()`、缺图回退与测试用取纹理单点。
3. 布局表增 `ground_h=100`、schema 校验与 `tools/layout_config.py` 读取字段。
4. `main.gd` 与 `main_debug_flow.gd` 在既有棋盘重建点同步舞台 `board_type`。
5. 删四柱光柱层、`_draw_light_beams` 与 `UiKit.BEAM_LIGHT`;退役 `UiKit.STAGE_BG` 源常量,平色回退改指 `UiKit.SLOT_BACKDROP`;同步改读两处对比锚。
6. 新增单元套件、扩充布局探针断言、登记 `run_all.gd`。
7. 实现报告、代拍板追认单、反哺点清单与独立验收审计。
不做:
1. 不选图、不修图、不生成新图、不入包素材——本卡开工前置是四件终稿已在 `game/assets/art/scene/`;遴选与编辑归作者/asset-ingest。
2. 不改 `scene_stage_plaza.png`、不改 `standee_body` 的地台绘制与落影。
3. 不改棋盘瓦片、数字、图标、文字排版、明细带内容。
4. 不改样张工具 `render_sample_sheet*.py` 的光柱绘制与注释;不更新任何 golden。
5. 不跑 MC;不做数值调参。
6. 不新增 UI 组件、不新增场景文件、不新增 ConfigDB 容器。
7. 不把「背景/地面」做成可按 `wall_ambient` 换色的通用槽。
## 六、关联文档同步面
| 文档 | 关联点 | 同步义务 |
|---|---|---|
| [art-bible](../design/art/art-bible.md) §6.1 | 「程序化平色+光柱现行使用=占位」「`ground_h` 由实装批新增并回填」「资产到位后四柱直接退役」三句改为实装事实;回填 `ground_h=100` | 实现批禁写;逐条落 `reports/iter<N>-反哺点-<日期>.md`,用户裁决后文档批落文 |
| [art-bible](../design/art/art-bible.md) §4.1 换色合并登记③ | `STAGE_BG` 由「随舞台背景插画批处置」改为已退役、平色回退改指 `SLOT_BACKDROP`(#3E362C) | 同上 |
| [art-assets-checklist](../design/art/art-assets-checklist.md) §4 | 三张背景与地面「已出候选 v10」状态句——更新为候选 v12 过审、终稿入包状态;小石台保留句核对 | 同上 |
| [battle-stage-prompts](../design/art/battle-stage-prompts.md) §4/§5 | `ground_h` 由「待实装批回填」改为已回填 100;档 6「四柱退役(代码批)」改为已退役 | 同上 |
| [battle.md](../design/gdd/ux/battle.md) :118、:155 | 布局字段清单补 `ground_h`;「现行溢出区为临时光柱氛围层,正式背景到位后该层退役」改为已退役、判定不变 | 同上 |
| [HUD框架.md](../design/gdd/systems/表现与支撑/HUD框架.md) :60、:247 | B 区内容补「三关背景+连续地面层」;布局几何清单补地面层高 | 同上 |
| [数据配置.md](../design/gdd/systems/表现与支撑/数据配置.md) :73 | 布局表用途句补「地面层高度」 | 同上 |
| [体验验证清单.md](../体验验证清单.md) | 三关背景可辨、无光柱、地面非瓷砖/非亮面、结算带压底带等目检项如要转正式条目 | 实现批禁写;实现报告登记,转条目走反哺点 |
| [game/tests/README.md](../game/tests/README.md) | 新增「B 区舞台背景三关变体与连续地面层」能力行与覆盖域表 | 写卡段已入表;实现批只核对名实,不再修改 |
| [architecture.md](../design/engineering/architecture/architecture.md) | 无字段级陈述需要改;本批不新增容器/类,仅舞台视图内部图层 | 无同步义务 |
## 七、落位与可复用性预检
### 7.1 新增件与新增成员
| 新增件/成员 | 复用面查询结论 | 唯一面 | 分层与交互路径 |
|---|---|---|---|
| `UiKit.TEX_STAGE_BG_FMT` | 全仓无背景路径常量;`UiKit` 已是场景件/角色件/图标路径的唯一装载单点(`TEX_STAGE_PLAZA` 先例),不新建路径件 | 背景路径格式只在 `ui_kit.gd` 一处 | 舞台视图经 `UiKit.load_tex` 装载;不直连 ResourceLoader |
| `UiKit.TEX_STAGE_GROUND` | 同上;地面是唯一共用场景件 | 地面路径只此一处 | 同上 |
| `BattleStageView.set_board_type()` | 舞台无任何板类型入口;棋盘视图的 `tile_palette.load_board_tiles` 只管瓦片,不复用其选择逻辑(职责不同) | 舞台选图只在这一方法 | 组合根在 `board_changed` 后调用;舞台不反向读结算内部 |
| `BattleStageView.bg_texture` / `ground_layer` | 舞台现无背景纹理层与地面层;不复用 `Panel` 平色底(平色底保留为回退) | 两层各一枚,几何只由布局表与舞台锚点决定 | 都是舞台子 Control,位于世界 SubViewport 之下 |
| `BattleStageView._load_stage_texture()` | 现有 `UiKit.load_tex` 是公共单点;此私有薄封装只服务缺图回退的可测性,不复制资源路径 | 背景与地面装载都经此一处 | 只被本件 `set_board_type`/`_build_ground` 调用 |
| `BattleLayoutTable.ground_h` + `_ground_field_errors()` | 布局表是分区几何唯一事实源;不把地面高塞进 `BattleStageView` 常量 | `ground_h` 只在布局表;校验只在此 schema | ConfigDB 加载期 `validate()` 调用;视图经容器读取 |
| `tools/layout_config.py` FIELDS 补 `ground_h` | 工具读取单点已存在;只补字段,不新建读取器 | 工具侧字段清单只此一处 | 样张工具与游戏侧同源读表 |
| `stage_background_test.gd` | 现有 `standee_present_values_test` 是「战斗一屏样张批 V5–V9」专用套件;`layout_probe` 是场景探针。两者职责都不覆盖「背景选图/地面几何/缺图回退」单元面 | 舞台背景与地面层单元断言唯一落点 | `run_all.gd` 单元入口;舞台直建,不起完整存档 |
| `layout_probe.gd` 追加断言 | 已有真实选路进战斗屏的探针,不新建第二探针 | 真实入口接线断言唯一落点 | `probe_gate.sh` 默认段;读 `main.ui.battle.stage` |
### 7.2 唯一性核查
- 背景路径、地面路径、`ground_h`、`board_type` 归一化规则各只有一处定义:`ui_kit.gd` 两常量、`battle_layout_table.gd` 一字段、`BattleStageView.set_board_type()` 一方法。
- 舞台接板同步只在 `main.gd:_on_board_changed` 与 `main_debug_flow.gd:_on_debug_battle_ready` 两个既有重建点各加一行;不新增第三通知源。
- 小石台绘制保持 `standee_body.gd` 唯一落点;地面层不重画地台,不复制 `_pedestal_rect`。
- 缺图回退只走 `_load_stage_texture` → `UiKit.load_tex` 一条链,不另建资源检查器。
### 7.3 分层与跨层出口
- Core 零改动:`BoardData.board_type` 只读;舞台不导入 core 内部,只接组合根传入的字符串。
- 呈现层内部:布局值经 `ConfigDb.presentation.battle_layout` 单点;纹理装载经 `UiKit.load_tex`;世界内站桩/地台不动。
- 测试面:单元套件直建 `BattleStageView`(与 `pacing_queue_test` 的 `FakeStage` 同型手法);真实入口由 `layout_probe` 从选路按钮进入。
## 八、实现规范预算
| 触面 | 预算 | 结论 |
|---|---|---|
| [battle_stage_view.gd](../game/presentation/views/battle_stage_view.gd) | 类变量 11→14(+`bg_texture`/`ground_layer`/`_bg_board_type`,≤15);公开方法 12→13(+`set_board_type`,≤20);新增私有 `_build_ground`、`_load_stage_texture`;函数长 ≤50、分支 ≤8;文件长 394→目标 ≤470(gdstyle 现无该件基线键) | 通过;T4 后光柱删除会回收约 15 行 |
| [ui_kit.gd](../game/presentation/views/ui_kit.gd) | 加 2 条 const、删 `BEAM_LIGHT` 与 `STAGE_BG`(净 0);不新增变量/方法 | 通过 |
| [battle_layout_table.gd](../game/data/schemas/battle_layout_table.gd) | 类变量 5→6;公开方法仍 1(`validate`);`validate` 现有 7 个 if 不再增分支,地面校验拆 `_ground_field_errors()`(2 个 if、返回 2 次) | 通过;避免 `validate` 9 分支越默认 8 |
| [main.gd](../game/presentation/main.gd) | 既有 `_on_board_changed` 内加局部变量与 2 行守卫同步;不增成员 | 通过;文件无 S13 基线键 |
| [main_debug_flow.gd](../game/presentation/main_debug_flow.gd) | 既有就绪函数内加局部变量与 2 行守卫同步;不增成员 | 通过 |
| [layout_config.py](../tools/layout_config.py) | `FIELDS` +1 字符串 | 通过 |
| [stage_background_test.gd](../game/tests/unit/presentation/stage_background_test.gd) | 新件;公开函数 0(仅 `_init` 与私有测试函数)、类变量 0;预计 ≤220 行 | 通过 |
| 迁移函数 | 本批无函数自存量文件迁入;无 `gdstyle_baseline.txt` 同名函数键 | 通过 |
| 存量触面 | 所有被改 `.gd` 的 S13 键只降不升;超出即停卡 | 通过 |
## 九、文件结构图
| 文件 | 职责 | 改动类型 | 验收行 |
|---|---|---|---|
| [ui_kit.gd](../game/presentation/views/ui_kit.gd) | 背景路径格式常量、共用地贴常量;退役 `BEAM_LIGHT` 与 `STAGE_BG` | 行为改动 | V2/V3/V5 |
| [battle_stage_view.gd](../game/presentation/views/battle_stage_view.gd) | 背景纹理层、连续地面层、`set_board_type()`、缺图回退;平色回退改指 `SLOT_BACKDROP`;退役四柱层 | 行为改动 | V2/V3/V4/V5 |
| [battle_layout_table.gd](../game/data/schemas/battle_layout_table.gd) | 新增 `ground_h` 字段与地面校验辅助 | 行为改动(加载期校验) | V1 |
| [battle_layout.tres](../game/data/tables/battle_layout.tres) | 回填 `ground_h = 100` | 行为改动(数据表) | V1/V4 |
| [layout_config.py](../tools/layout_config.py) | 工具读取字段补 `ground_h` | 非游戏行为(工具维护) | V1 |
| [main.gd](../game/presentation/main.gd) | `_on_board_changed` 重建棋盘后同步舞台板型 | 行为改动 | V6 |
| [main_debug_flow.gd](../game/presentation/main_debug_flow.gd) | 调试对局就绪同步舞台板型 | 行为改动 | V6 |
| [layout_probe.gd](../game/probe/layout_probe.gd) | 真实入口追加背景/地面装载断言 | 非行为改动(探针断言) | V6/V7 |
| [theme_projection_test.gd](../game/tests/unit/presentation/theme_projection_test.gd) | `STAGE_BG` 对比锚改读 `SLOT_BACKDROP`(合并目标,阈值不变) | 非行为改动(测试改读) | V5 |
| [ui_contrast_probe.gd](../game/probe/ui_contrast_probe.gd) | 舞台底对比锚改读 `SLOT_BACKDROP`(合并目标,阈值不变) | 非行为改动(探针改读) | V5/V7 |
| [stage_background_test.gd](../game/tests/unit/presentation/stage_background_test.gd) | 新建单元套件:字段/选图/回退/地面几何/光柱退役 | 非行为改动 | V1–V5/V8 |
| [run_all.gd](../game/tests/run_all.gd) | 登记新套件 | 非行为改动 | V8 |
| [README.md](../game/tests/README.md) | 能力行与覆盖域表 | 非行为改动;**写卡段已入表** | V8 |
| `game/assets/art/scene/scene_stage_bg_*.png` ×3、`scene_stage_ground.png` | 开工前置资产,非本批写面;实现期只读装载 | 输入件 | V2/V3/V4 |
## 十、任务卡
### T0 开工基线与资产前置(0.25d)
取用:
- 待办清单条目状态=美术设计已闭合+已写卡;本卡路径。
- 候选过审记录:`artwork/2026-10-30-战斗区背景/候选保存清单-2026-10-31.md`(工作区文件,不入 git)。
步骤:
- [ ] 读 `game/tests/.gates/ci-status.json`;CI 红未修复即停本卡,禁开新批。
- [ ] 核对四件终稿已在包:`game/assets/art/scene/scene_stage_bg_dungeon.png`、`scene_stage_bg_underdark.png`、`scene_stage_bg_deep_underdark.png`、`scene_stage_ground.png`;用 PIL 读数:三张背景恰为 `(1280, stage_h)`、地面恰为 `(1280, ground_h=100)`。缺位或尺寸不符=L3 停卡,退回 asset-ingest;禁在实现期自行裁图/缩图。
- [ ] 复核第三节 1–22 行的 file:line 与实数;漂移先停卡核对,不靠猜行号施工。
- [ ] 跑 `python tools/gdstyle_gate.py` 记录本批触面当前读数;另记录 `battle_stage_view.gd` 行数/类变量/公开方法数、`battle_layout_table.validate()` 分支数。
- [ ] `grep -rn "STAGE_BG" game` 记录四处现行引用:`ui_kit.gd` 常量、`battle_stage_view.gd` 绘制点、`theme_projection_test.gd:669`、`ui_contrast_probe.gd:30`;T4 收口时四处全部处置。
- [ ] 写开工闸记录:基线 commit、既有红项、资产四件尺寸读数、S13 读数。
产出:资产齐盘、代码事实无漂移、预算基线可对账。
### T1 布局字段 `ground_h` 与读表口径(0.5d)
取用:T0 确认的表结构;`ConfigDb` manifest 已登记 `battle_layout`。
接口块:
```gdscript
@export var ground_h: int = 100
func validate() -> Array
func _ground_field_errors() -> Array
```
步骤:
- [ ] 在 [battle_layout_table.gd:7](../game/data/schemas/battle_layout_table.gd#L7) 的 `stage_h` 后新增 `@export var ground_h: int = 100`,注释写「B 区连续地面层高(源 = 基准屏宽 × 本值)」。
- [ ] 在 [battle_layout_table.gd:14](../game/data/schemas/battle_layout_table.gd#L14) 的 `validate()` 末尾追加 `errs.append_array(_ground_field_errors())`;不把两个新 if 直接塞进 `validate()`(保持分支 ≤8)。
- [ ] 新增私有 `_ground_field_errors() -> Array`:`ground_h < 16 or ground_h > stage_h / 2` 报 `domain`;`ground_h <= log_band_h_dig` 报 `cross_field`(地面层不得被收起态明细带整条盖住)。消息含字段名与实际值。
- [ ] 在 [battle_layout.tres:7](../game/data/tables/battle_layout.tres#L7) 的 `stage_h = 252` 后写 `ground_h = 100`;其余五值不动。
- [ ] 在 [layout_config.py:12](../tools/layout_config.py#L12) 的 `FIELDS` 元组中 `stage_h` 后加 `"ground_h"`。
- [ ] 新建 [stage_background_test.gd](../game/tests/unit/presentation/stage_background_test.gd),先写 `_test_layout_ground_field()`:
1. `load("res://data/tables/battle_layout.tres")`,断言 `ground_h == 100` 且 `validate()` 为空。
2. 用 `BattleLayoutTable.new()` 三态:`ground_h=20`(≤log_band_h_dig=24)、`ground_h=200`(>252/2)、`ground_h=100`;断言前两态各返回一条含 `ground_h` 的错误,第三态无 ground 相关错误。
- [ ] 在 [run_all.gd:191](../game/tests/run_all.gd#L191) 邻近 presentation 区追加:
`{"path": "res://tests/unit/presentation/stage_background_test.gd", "expect": 0}`
- [ ] 验证步骤:
`D:/code/godot/Godot_v4.7.2-stable_win64_console.exe --headless --path game --script res://tests/unit/presentation/stage_background_test.gd`
`python -c "from tools.layout_config import load; print(load()['ground_h'])"` → 必须输出 `100`。
`D:/code/godot/Godot_v4.7.2-stable_win64_console.exe --headless --path game --script res://tests/unit/data_config/config_db_test.gd` → 绿。
验收:布局表单源有 `ground_h`,校验拒绝越域与「被收起带整条盖住」,游戏侧与工具侧读同值。
产出:`ground_h` 字段、schema 校验、工具读取与 `_test_layout_ground_field`。
### T2 背景层与 `board_type` 选图(1.0d)
取用:T1 的布局表;`UiKit.load_tex`;`BoardData.board_type`;`board_changed` 信号。
接口块:
```gdscript
const TEX_STAGE_BG_FMT := "res://assets/art/scene/scene_stage_bg_%s.png"
var bg_texture: TextureRect
func set_board_type(board_type: String) -> void
func _load_stage_texture(path: String) -> Texture2D
```
步骤:
- [ ] 在 [ui_kit.gd:250](../game/presentation/views/ui_kit.gd#L250) 邻近 `TEX_STAGE_PLAZA` 新增 `TEX_STAGE_BG_FMT`;注释写「三关背景按 board_type 选图,不走 tint」。
- [ ] 在 [battle_stage_view.gd:14](../game/presentation/views/battle_stage_view.gd#L14) 成员区新增 `var bg_texture: TextureRect` 与 `var _bg_board_type := ""`。
- [ ] 在 [battle_stage_view.gd:37](../game/presentation/views/battle_stage_view.gd#L37) 的 `_build_backdrop()` 中,平色 Panel 之后新增全幅 `TextureRect`:`set_anchors_preset(PRESET_FULL_RECT)`、`expand_mode=EXPAND_IGNORE_SIZE`、`stretch_mode=STRETCH_SCALE`、`mouse_filter=IGNORE`、初始 `visible=false`;随后调用 `set_board_type("dungeon")`。
- [ ] 新增 `set_board_type(board_type: String) -> void`:
- 空串归一为 `"dungeon"`;与 `_bg_board_type` 相同则直接返回。
- 先取 `UiKit.TEX_STAGE_BG_FMT % bt`;为目标缺图且 `bt != "dungeon"` 时再取 `dungeon` 路径;两取都经 `_load_stage_texture`。
- 写入 `bg_texture.texture`;`visible = texture != null`;不得在缺图时抛错或打印产品日志。
- [ ] 新增私有 `_load_stage_texture(path: String) -> Texture2D`,只返回 `UiKit.load_tex(path)`;作为缺图回退的可测单点。
- [ ] 在 [main.gd:367](../game/presentation/main.gd#L367) 前后:把 `current_board()` 存局部变量,`board_view.rebuild(board, ...)` 后加 `if board != null: ui.battle.stage.set_board_type(String(board.board_type))`;不改信号连接与重建顺序。
- [ ] 在 [main_debug_flow.gd:103](../game/presentation/main_debug_flow.gd#L103) 同型:存局部变量、重建后同两行同步;不新增第三个通知源。
- [ ] 在 `stage_background_test.gd` 写 `_test_background_selection()`:
1. 直建 `BattleStageView.new(null, load("res://data/tables/battle_layout.tres"))`;默认应已装载 dungeon 背景,纹理非空且尺寸 1280×`stage_h`。
2. 依次 `set_board_type("underdark")`、`"deep_underdark"`、`"dungeon"`;每次断言 `bg_texture.texture.resource_path` 以对应 `_<board_type>.png` 结尾,且尺寸不变。
3. 断言 `bg_texture.get_index()` 小于 `world.get_parent().get_parent().get_index()`(背景在世界之下)。
- [ ] 写 `_test_background_fallback()`:用 `class MissingUnderdarkStage extends BattleStageView` 覆写 `_load_stage_texture`——`underdark` 路径返回 null、其余走 `UiKit.load_tex`;断言 `set_board_type("underdark")` 后纹理路径为 dungeon。再用全 null 子类断言 `set_board_type("dungeon")` 后 `bg_texture.texture == null` 且 `visible == false`,无异常。
- [ ] 在 [layout_probe.gd:55](../game/probe/layout_probe.gd#L55) 的 `_check_one()` 内追加:`stage.bg_texture` 非空、纹理非空、`resource_path` 以 `_dungeon.png` 结尾(L1 真实入口);记录 `label` 便于两档定位。
- [ ] 窄测:
`D:/code/godot/Godot_v4.7.2-stable_win64_console.exe --headless --path game --script res://tests/unit/presentation/stage_background_test.gd`
`D:/code/godot/Godot_v4.7.2-stable_win64_console.exe --headless --path game res://probe/layout_probe.tscn`
验收:三值各命中对应文件;未知/空串→dungeon;目标缺图→dungeon→平色;真实选路进 L1 后背景为 dungeon。
产出:`TEX_STAGE_BG_FMT`、`bg_texture`、`set_board_type`、两处接板同步、背景选图/回退断言。
### T3 连续地面层与几何(0.75d)
取用:T1 的 `ground_h`;T2 的舞台图层序与 `_load_stage_texture`;T0 已入包的地面件。
接口块:
```gdscript
const TEX_STAGE_GROUND := "res://assets/art/scene/scene_stage_ground.png"
var ground_layer: TextureRect
func _build_ground(layout: BattleLayoutTable) -> void
```
步骤:
- [ ] 在 [ui_kit.gd:250](../game/presentation/views/ui_kit.gd#L250) 新增 `TEX_STAGE_GROUND`;注释写「三关共用、无 board_type 后缀、不吃 tint」。
- [ ] 在 [battle_stage_view.gd:14](../game/presentation/views/battle_stage_view.gd#L14) 成员区新增 `var ground_layer: TextureRect`。
- [ ] 在 [battle_stage_view.gd:27](../game/presentation/views/battle_stage_view.gd#L27) 的 `_init` 中,`_build_backdrop()` 之后、`_build_world_stage()` 之前调用 `_build_ground(layout)`。
- [ ] 新增 `_build_ground(layout)`:全幅 `TextureRect`,`set_anchors_preset(PRESET_BOTTOM_WIDE)` 后四 offset 归零再把 `offset_top = -float(layout.ground_h)`;`expand_mode=EXPAND_IGNORE_SIZE`、`stretch_mode=STRETCH_SCALE`、`mouse_filter=IGNORE`;`texture = _load_stage_texture(UiKit.TEX_STAGE_GROUND)`;`visible = texture != null`。
- [ ] 不修改 `standee_body.gd`;小石台仍在世界内站桩底绘制,天然位于地面层之上。
- [ ] 在 `stage_background_test.gd` 写 `_test_ground_layer_geometry()`:
1. 地面纹理可加载且尺寸 `(1280, layout.ground_h)`。
2. `ground_layer.anchor_left==0`、`anchor_top==1`、`anchor_right==1`、`anchor_bottom==1`;`offset_left==0`、`offset_right==0`、`offset_bottom==0`、`offset_top == -layout.ground_h`。
3. 把 stage 尺寸设为 `Vector2(1280, layout.stage_h)` 并加树一帧后,`ground_layer.size == Vector2(1280, layout.ground_h)`、`ground_layer.position.y == layout.stage_h - layout.ground_h`。
4. `ground_layer.get_index()` 大于 `bg_texture.get_index()`、小于 `world.get_parent().get_parent().get_index()`。
- [ ] 在 [layout_probe.gd:55](../game/probe/layout_probe.gd#L55) 追加:`ground_layer` 可见、`ground_layer.size.y == layout.ground_h`(两档都成立;宽度随档位变化不判)。
- [ ] 窄测:
`D:/code/godot/Godot_v4.7.2-stable_win64_console.exe --headless --path game --script res://tests/unit/presentation/stage_background_test.gd`
`D:/code/godot/Godot_v4.7.2-stable_win64_console.exe --headless --path game res://probe/layout_probe.tscn`
`D:/code/godot/Godot_v4.7.2-stable_win64_console.exe --headless --path game --script res://tests/unit/presentation/standee_present_values_test.gd`(地台件 V9 不动)。
验收:地面层底边贴 B 区底、高读表、全宽、位于背景与世界之间;小石台仍在其上;缺图时地面隐藏不崩。
产出:`TEX_STAGE_GROUND`、`ground_layer`、`_build_ground`、地面几何断言。
### T4 四柱光柱与舞台底源常量退役(0.5d)
取用:T2/T3 已完成的舞台图层;现有 `UiKit._beams_rect()` 菜单斜光带不在退役面;art-bible §4.1 换色合并③。
步骤:
- [ ] 删除 [battle_stage_view.gd:44](../game/presentation/views/battle_stage_view.gd#L44) 的 `_build_beams_layer()` 调用。
- [ ] 删除 [battle_stage_view.gd:50](../game/presentation/views/battle_stage_view.gd#L50) 的 `_build_beams_layer()` 与 [battle_stage_view.gd:145](../game/presentation/views/battle_stage_view.gd#L145) 的 `_draw_light_beams()`。
- [ ] 删除 [ui_kit.gd:186](../game/presentation/views/ui_kit.gd#L186) 的 `BEAM_LIGHT` 常量;平色回退能力由下一步改指 `SLOT_BACKDROP` 承接。
- [ ] 按 art-bible §4.1 换色合并③:把 [battle_stage_view.gd:39](../game/presentation/views/battle_stage_view.gd#L39) 的 `UiKit.STAGE_BG` 改指 `UiKit.SLOT_BACKDROP`(#3E362C,合并目标);删除 [ui_kit.gd:185](../game/presentation/views/ui_kit.gd#L185) 的 `STAGE_BG` 常量。
- [ ] 把 [theme_projection_test.gd:669](../game/tests/unit/presentation/theme_projection_test.gd#L669) 的 `uikit_s.STAGE_BG` 改读 `uikit_s.SLOT_BACKDROP`;把 [ui_contrast_probe.gd:30](../game/probe/ui_contrast_probe.gd#L30) 的 `UiKit.STAGE_BG` 改读 `UiKit.SLOT_BACKDROP`;两处阈值与断言文案不变,标签可注「合并目标」。
- [ ] 更新 `battle_stage_view.gd` 顶注与 `_build_backdrop()` 注释:去掉「四柱/光柱氛围层」表述,写明「背景三关变体→连续地面→世界站桩;光柱层已退役,不迁入背景;平色回退走合并目标 `SLOT_BACKDROP`」。
- [ ] 在 `stage_background_test.gd` 写 `_test_beams_retired()`:
1. 读 `res://presentation/views/battle_stage_view.gd` 源码,断言不含 `_build_beams_layer`、`_draw_light_beams`、`BEAM_LIGHT`,且含 `UiKit.SLOT_BACKDROP`。
2. `load("res://presentation/views/ui_kit.gd").get_script_constant_map()` 不含 `BEAM_LIGHT` 与 `STAGE_BG`。
3. 断言菜单 `_beams_rect()` 仍在(`haskey("_beams_rect")` 或调用返回 TextureRect),防止误删菜单斜光带。
- [ ] 静态核实全仓代码 `wall_ambient` 仅 `ui_kit.gd:249` 注释一处;不新增该标识符。
- [ ] 窄测:
`D:/code/godot/Godot_v4.7.2-stable_win64_console.exe --headless --path game --script res://tests/unit/presentation/stage_background_test.gd`
`D:/code/godot/Godot_v4.7.2-stable_win64_console.exe --headless --path game --script res://tests/unit/presentation/theme_projection_test.gd`
`D:/code/godot/Godot_v4.7.2-stable_win64_console.exe --headless --path game res://probe/ui_contrast_probe.tscn`
验收:舞台无光柱层与相关常量;舞台底源常量退场、回退改指合并目标;菜单斜光带与两处对比锚仍绿;缺图态仍无光柱。
产出:光柱层退役、`_test_beams_retired`、注释口径更新。
### T5 回归、渲染闸与产出物(0.75d)
取用:T0–T4 全部产物;`tools/run_all_gates.sh` 为唯一闸入口;独立验收审计未参与实现。
步骤:
- [ ] 运行开发期关联窄测:
`D:/code/godot/Godot_v4.7.2-stable_win64_console.exe --headless --path game --script res://tests/run_all.gd -- --only=stage_background|standee_present_values|standee_fx_sweep|pacing_queue|theme_projection|config_db`
- [ ] 出红只做红件最小单元复跑;禁在波内追加全量档。
- [ ] 里程碑出口跑一次代码域全套闸:
`bash tools/run_all_gates.sh --code`
- [ ] 回执必须 `all_green=true`、`dirty_game=false`;重点读 `05 渲染闸`:`shot_checker` 的 C 区文字 WCAG ≥4.5、纹理幅度 ≤18、明度三档带 `info>world>bottom` 全过;棋盘三张、菜单、关卡 golden 零变化。任何新增红停卡,禁带红合回。
- [ ] 独立验收审计由未参与实现的会话或子代理执行,产出 `reports/iter<N>-验收审计-<日期>.md`;未过禁合并。
- [ ] 轻闸全绿、合并前写齐三份:
1. `reports/iter<N>-实现报告-<日期>.md`
2. `reports/iter<N>-代拍板追认单-<日期>.md`
3. `reports/iter<N>-反哺点-<日期>.md`
- [ ] 实现报告须含:T0–T5 状态、V1–V8 实跑读数、S13 前后数、资产四件尺寸、渲染闸逐项读数、玩家目检总清单(登记不阻塞:三关背景可辨、无光柱、远景有纵深、地面为泥土非瓷砖且不亮、结算带压住地面底带、站桩踩在连续地面/小石台上)。
- [ ] 反哺点逐条覆盖第六节九个目标;每条写文件、节、原句、拟改句、依据,并明确「实现批未写 design/、未写根流程清单、未写 game/tests/README.md」。
- [ ] 本批不新增 golden、不改 `shot_checker` 阈值、不删既有断言。
完成定义:三份产出物齐全+代码域闸全绿+验收审计通过,才进入合回;合回后按项目现行机制由本地 CI 复验。
## 十一、验证闸:改动—验收对照表
| 需求点 | 改动(文件/行为) | 验收测试(名称+落点) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|
| V1 `ground_h` 字段与校验 | schema 加字段+地面校验辅助;表回填 100;工具读取 | `stage_background_test.gd:_test_layout_ground_field`;`config_db_test.gd:_test_manifest_dir_sync` | 单元 | `BattleLayoutTable.validate()`;`ConfigDB.load_tables()` | 表值=100;默认表 validate 空;`ground_h=20` 与 `=200` 各得一条含 `ground_h` 的错误;工具 load() 得 100 | 新增:B 区舞台背景三关变体与连续地面层(按 board_type 选图/地面层高度读布局表/四柱光柱退役) |
| V2 背景按 board_type 选图 | `TEX_STAGE_BG_FMT`+`set_board_type`+两处接板同步 | `stage_background_test.gd:_test_background_selection`;`layout_probe.gd:_check_one` | 单元+探针 | `BattleStageView.set_board_type()`;`level_screen.press_candidate(0)`→`board_changed` | 三值纹理路径逐值对应且尺寸 1280×252;L1 真实进入后路径以 `_dungeon.png` 结尾 | 新增:B 区舞台背景三关变体与连续地面层(按 board_type 选图/地面层高度读布局表/四柱光柱退役) |
| V3 缺图回退 | `_load_stage_texture`+回退链 | `stage_background_test.gd:_test_background_fallback` | 单元 | `BattleStageView.set_board_type("underdark")`(子类缺图) | 目标缺→dungeon 路径;全缺→`texture=null`、`visible=false`、无异常 | 新增:B 区舞台背景三关变体与连续地面层(按 board_type 选图/地面层高度读布局表/四柱光柱退役) |
| V4 连续地面层几何 | `TEX_STAGE_GROUND`+`_build_ground` | `stage_background_test.gd:_test_ground_layer_geometry`;`layout_probe.gd:_check_one` | 单元+探针 | 舞台构造+真实进战斗屏 | 纹理 1280×100;anchor 0/1/1/1;`offset_top=-100`;1280 档 `size.y=100`;图层序 bg<ground<world;探针两档 `size.y=ground_h` | 新增:B 区舞台背景三关变体与连续地面层(按 board_type 选图/地面层高度读布局表/四柱光柱退役) |
| V5 四柱光柱与舞台底源常量退役 | 删舞台光柱层、`BEAM_LIGHT`、`STAGE_BG`;回退改指 `SLOT_BACKDROP` | `stage_background_test.gd:_test_beams_retired`;`theme_projection_test.gd:_smoke_contrast_inks`;`ui_contrast_probe.gd:_ready` | 单元+探针 | `BattleStageView` 构造+`UiKit` 常量表;`ui_contrast_probe.tscn` | 舞台源码零 `_build_beams_layer`/`_draw_light_beams`/`BEAM_LIGHT` 且含 `UiKit.SLOT_BACKDROP`;UiKit 常量表无 `BEAM_LIGHT`/`STAGE_BG`;菜单 `_beams_rect` 仍在;两处舞台底对比锚读合并目标且阈值不变 | 新增:B 区舞台背景三关变体与连续地面层(按 board_type 选图/地面层高度读布局表/四柱光柱退役) |
| V6 接板真实链路 | main 与调试就绪两处同步 board_type | `layout_probe.gd:_check_one`;`stage_background_test.gd:_test_background_selection` 的源码锚 | 探针+单元 | `level_screen.press_candidate(0)`→`board_changed` | L1 舞台背景路径为 `_dungeon.png`;源码锚 `main.gd` 与 `main_debug_flow.gd` 均含 `stage.set_board_type(` | 新增:B 区舞台背景三关变体与连续地面层(按 board_type 选图/地面层高度读布局表/四柱光柱退役) |
| V7 既有呈现回归 | 不改站桩/明细/棋盘;只换舞台底图 | `standee_present_values_test.gd:_init`;`standee_fx_sweep_test.gd:_init`;`pacing_queue_test.gd:_init`;`layout_probe.gd:_check_one` | 单元+集成+探针 | 现有各套件真实入口 | 地台 48×12、站桩几何、排播、三区几何全绿;渲染闸 shot_checker 三项与明度带全过;棋盘/菜单/关卡 golden 零变化 | 既有:站桩敌人呈现与结算演出落点;既有:战斗屏三区几何与棋盘格边长(分辨率两档×四档板型) |
| V8 能力行名实与套件登记 | `run_all.gd` 登记;README 写卡段入表 | `run_all.gd` manifest 与整套 `stage_background_test.gd` | 单元 | `res://tests/run_all.gd` | 套件在 manifest 且 exit 0;能力行代表用例与函数名逐字一致;`capability_audit` 零红 | 新增:B 区舞台背景三关变体与连续地面层(按 board_type 选图/地面层高度读布局表/四柱光柱退役) |
落点集中:V1 归 T1;V2/V3/V6 归 T2;V4 归 T3;V5 归 T4;V7/V8 归 T5。全表名实核对归 T5 与独立审计。
## 十二、测试方式与测试削弱申报
自动验证:
- V1–V6 全部从真实入口或舞台直建公共面驱动;缺图路径用子类覆写 `_load_stage_texture` 构造观测,不改包内资产、不注入破坏。
- 真实接板链路只认 `board_changed` 与调试就绪两条既有入口;不建后门 API、不在产品码写测试专用分支。
- 渲染闸为窗口化实跑;`shot_checker` 阈值与 golden 不因本批改动。
真人目检(登记不阻塞,写入实现报告):
- 三关背景可辨为不同洞窟(地精暖石/卓尔冷蓝灰/灰矮人灰黑),远景有纵深、非贴墙、无孤立圆柱贴顶。
- 背景无光柱/光带/光源实体;任何缺图态也不出现光柱。
- 连续地面读作泥土/碎石,不是瓷砖/石板;全幅只零星小石、不成排成堆;中低明度不刺眼。
- 站桩与小石台踩在连续地面上;结算期明细带压住地面底带,不出现半截地台/悬空。
- B 区文字(轮次牌、演出提示、明细带)对背景/地面可读,无字压纹理。
测试削弱申报:
- 零删除、零放宽、零换下层直调。唯一允许的改读:`theme_projection_test.gd:669` 与 `ui_contrast_probe.gd:30` 的舞台底对比锚由 `STAGE_BG` 改读 `SLOT_BACKDROP`(art-bible §4.1 换色合并③,目标色 #3E362C);阈值、断言文案与覆盖不变。
- 舞台四柱层退役不涉任何现存断言(全仓核实:光柱断言只针对菜单 `UiKit._beams_rect`)。
- `layout_probe` 只追加背景/地面断言,不改既有三区几何判据。
- 若实现期发现任何既有断言因换图而红,先停卡呈报并列入本表,禁静默删/改阈值。
## 十三、估时与切分预案
| 卡 | T0 | T1 | T2 | T3 | T4 | T5 | 合计 |
|---|---:|---:|---:|---:|---:|---:|---:|
| 工作日 | 0.25 | 0.5 | 1.0 | 0.75 | 0.5 | 0.75 | **3.75d** |
浮动 ±0.75d(渲染闸首跑与两档探针等待占大头)。
切分预案:若 T2/T3 超软盒,段一=T0–T2(资产前置、布局字段、背景选图,约 1.75d);段二=T3–T5(地面层、光柱退役、闸与产出物,约 2.0d)。两段各自可测;段一合回前必须保证光柱层仍在时背景已正确显示(不半删),段二再退役光柱。禁在段一合回。
## 十四、异常分级
L1(自救一次):
- 编译错误、签名拼写、`run_all.gd` 登记遗漏、测试 helper 顺序。
- 注释措辞与私有局部变量命名。
L2(记录继续;同一红连续三次升 L3):
- 与本批无关的存量红,先按回执归因并留档。
- 行数较 T0 预期漂移但 S13 键不升。
L3(立即停卡写报告):
- CI 状态红未修。
- 四件资产缺位或尺寸不符(停卡退回 asset-ingest;禁实现期裁图代偿)。
- 机检键/计数与卡片契约互斥;**上游缺陷停卡退回写卡段,禁为凑绿保留无效成员或造第三条路**。
- `battle_stage_view` 类变量 >15、公开方法 >20,或 S13 基线外新增键无法在不改契约下消除。
- `ground_h` 校验与既有跨字段校验冲突,或必须改 `log_band_h_*` 才能成立。
- 渲染闸新增红(文字对比、纹理幅度、明度三档带、golden)且不属于可归因的既有存量红。
- 任何验收行无法从真实入口绑定特有可观测提交面。
- 必须改 `design/`、根流程清单或 `game/tests/README.md` 才能过关。
## 十五、代拍板白名单
允许实现期自行拍板:
1. 私有函数在指定文件内的顺序、局部变量名;签名与行为不变。
2. 测试 helper 的顺序与断言消息措辞;不得改判据值、阈值与层级。
3. 注释与日志文案;不得引入「光柱仍在」类误导表述,不得写变更历史。
4. `TextureRect` 的 `expand_mode`/`stretch_mode` 写法细节,只要满足基准档 1×、全幅锚点与尺寸判据。
5. B 区 1px 面板描边的可见性处理(被背景覆盖或另加描边薄层均可);不得为描边缩放/裁切纹理,且不得新增类变量。
6. 既有错误扫描暴露的本文件纯格式问题,在不改语义范围内一次修净。
超出必须呈报:
- 任何资产尺寸、`ground_h` 取值、`board_type` 词表、回退链顺序、图层序、文件职责、T 卡验收落点。
- 任何对 `shot_checker`、golden、既有断言或探针判据的改动。
- 任何新增 ConfigDB 容器、Core 字段、UI 组件或第二套板类型选择逻辑。
## 十六、待裁点与开工门
待裁点:**零**。
卡内 provisional(不是设计待裁):
- `ground_h = 100`——按候选出图 1280×100 工艺回填;作者后续可直接调表值,不重开设计。
- 背景/地面文件名与路径格式——art-bible/asset-path-map 已定,本卡只落常量。
- 缺图回退链顺序——dungeon → 平色,按 C7 执行。
开工门:
1. 四件终稿已入包且尺寸对(T0 实读);缺位退 asset-ingest。
2. 待办清单条目状态=美术设计已闭合+已写卡,实况载本卡路径。
3. 经 iter-plan 编入迭代后由 `/iter` 发令开工;本卡无迭代外执行通道。
4. CI 绿、T0 基线无漂移。
5. 本卡估时 3.75~4.5 个工作日;是否单独成批或与邻卡凑迭代归 iter-plan,本卡不代裁。
@@ -0,0 +1,208 @@
# 需求卡片——战斗编排归约批(battle_orchestrator 类变量 38→15)
> **版本状态**:v1.0 定稿——零待裁点(2026-10-29 用户裁:RoundCycle/BattleFacts 两件形态、encounter 归 BattleFacts、attune 改判、treasure_inventory 改址追认、完美账写口升级可裁量)。
> **接收方**:待办清单条目「战斗域结构深拆批——效果发射端口+宿主瘦身+掷格/受理分件(2026-10-27 登记,来源=批次移交)」——本卡承接其中 battle_orchestrator 瘦身面(architecture 轴丁);该条目的效果发射端口与 reward_economy 分件两子项不在本卡。
> **来源**:`reports/设计-战斗编排类变量归约-2026-10-29.md`(设计讨论段定稿,五待裁点 2026-10-29 用户裁全闭合)。**唯一事实源**:该设计文档全文 + `design/engineering/architecture/architecture.md` v1.25「战斗编排域拆件定稿」节轴丁与「模块归属·功能层」RoundCycle/BattleFacts 两行。
## 1. 目标与完成定义
这批做什么:把战斗结算编排宿主 `game/core/battle_orchestrator.gd` 的 38 个类变量收敛到 15(=gdstyle 阈值,合规)。手段=按变化原因拆两枚新件收编 22 个成员——**RoundCycle**(轮循环驱动件:五段段件持有、段序执行、结算重入门闸、开轮摇号、踩雷计数账)与 **BattleFacts**(战斗事实件:受理事实 encounter、轮 facts 缓冲、封印判定账、装板溯源、条件计数、同调快照;attune 状态两成员随件、行为函数留宿主)——外加两项单点处置:treasure_inventory 注入改址(level_runner 经 RewardGrant 出口直注,原「外部赋值路径零改址」句经用户追认失效)与 _hero_atk 转派生读。
什么状态算完:
1. 宿主类变量实测 15、两新件零 gdstyle 键、battle_orchestrator 全文件零超标键(第 9 节键账)。
2. 游戏行为零变化:同种子完整局步骤流、事件流、两快照载荷逐位一致(第 4 节红线;第 11 节 V0 行)。
3. 批末代码域闸全绿(冒烟+系统测试+单元集成关联档+探针+静态扫描),键账对账完成(第 12 节)。
4. 实现报告与反哺点清单落 `reports/`(T4 产出物落位卡)。
## 2. 设计事实源
- `reports/设计-战斗编排类变量归约-2026-10-29.md`——设计讨论段定稿全文。逐成员去向(38 项五去向)、两新件形态与耦合边界、attune 重裁决、已否决切法、随迁键义务、行为零变化风险点、键账预期、改址盘点,全部以该文档对应节为唯一合同;本卡不复制其表格,T0 逐名对账时引用。
- `design/engineering/architecture/architecture.md` v1.25——「战斗编排域拆件定稿」节轴丁两件(RoundCycle/BattleFacts,跨件单向接线、段类随动、attune 改判、S13 键账收敛义务、验收红线)与「模块归属·功能层」两行、「测试与质量域」S13 豁免第三条注销句——实现照册施工。
- 五待裁点裁决(2026-10-29 用户裁,对应设计文档 §13):①encounter 归战斗事实件=采纳;②treasure_inventory 注入改址=追认(「外部赋值路径零改址」句失效);③attune 重裁决=采纳「状态归 facts、行为留宿主」;④完美账写口升级=采纳(grant_segment 三处直写改经 facts 三方法);⑤对拍闸已随 2026-10-30 工程批退役(用户裁:整局重放对拍不再作验收载体)——原 PARITY 批准待裁点就此注销。
## 3. 现状事实(代码级,2026-10-29 实查;开工 T0 按当轮 master 重测复核)
- `tools/gdstyle_baseline.txt:9-10`——battle_orchestrator.gd 现登记两条类级键:`quality/max-class-variables = 38`、`quality/max-file-length = 1035`;**该文件零函数级键**(59 个函数全部在默认阈值内——设计文档 §7 前提成立,T0 复核)。
- 宿主 38 类变量声明区=`battle_orchestrator.gd:37-85` 与 `:223-227`(逐名清单见设计文档 §2 表)。宿主改后保留 15:db、rng、minesweeper、action_economy、_enemy_system、_status_effects、_reward_economy、_damage、_fx_host、_reward_grant、round_index、battle_result、nest_preview_count、_rounds、_facts。
- **编队前置实态**:迭代 42(gdstyle 尾波清偿批,roadmap 在册)合回后轴丙 BoardInstaller 已建——`_board_generator` 成员随件退役(38→37)、装板域六函数迁出、宿主复位块留薄壳 `_install_and_reset`、文件长键归绿;届时宿主约 890 行/37 成员,本卡叠加其上。**本卡在迭代 42 合回之前禁开工**;T0 按当轮 master 重测对账。
- 段驱动现态:五段构造 `battle_orchestrator.gd:256-260`(授予/战斗两段三引用形,aura/decay/verdict 单引用形);三闸 `_maybe_settle` :592-597;段序体 `_settle` :602-613(终局早退不回置 _settling);开轮摇号 `_roll_round_actions` :677-721(behavior_roll 流 :717,mines_hits 转存 :720-721);`_on_round_end` 末行 :589 调 `_maybe_settle`。
- 事实族写读点:缓冲追加 `_on_cell_revealed` :554-580(身份快照捕获 :576 留宿主);`_on_seal_judged` :583;`_facts_path` 写 `_on_round_end` :588;轮复位 `_reset_round_facts` :976-979(三调用点 :273/:810/:862);封印/完美/标错/板序/溯源清零在装板复位块 :442-446(迭代 42 后归宿主薄壳);`_refresh_used_this_round` 复位点 `_exit_distribution` :811;完美谓词 `perfect_sweep_earned` :1033-1035。
- treasure_inventory:宿主声明+setter 转发块 `battle_orchestrator.gd:48-52`;唯一外部注入点 `level_runner.gd:520`;宿主读 :111/:203/:450/:858;`grant_segment.gd:370-371` 读 `oc.treasure_inventory`。
- _hero_atk:声明 `battle_orchestrator.gd:227`、受理写入 :304、spawn 消费 :305、`combat_segment.gd:56` 消费 `oc._hero_atk`。
- attune 外部三面(零改址标的):`attune_has` 公有面消费=table_structure_guard_test 起战断言(:162/:166)与 breakpoint_resume_test;`attune_param_sum`=main.gd:567 与 treasure_effects_test;`attune_convert_state`=treasure_interact_controller.gd:125。三面全部留宿主公有面。
- 冻结面:`nest_preview_count` 外部直读=main.gd:536-537+treasure_effects_test:153;`round_index` 公有直读=system_test.gd:447-462(st.round_index)等四套件约 15 处。
- **设计文档 §11 漏列一处(T0 实查补入)**:`settle_segments_test.gd:27` 接线断言 `oc._grant_seg != null and oc._grant_seg.oc == oc`——段件迁 RoundCycle 后必红,须改指 `oc._rounds._grant_seg`。
- 对拍闸(原闸 11 与 PARITY_TOUCH_FACES 触面判定)已随 2026-10-30 工程批退役——本批无触面批准事项;T0 复核以此为准。
- `game/tests/static_scan.sh`——S8 await 文件集(:317,9 文件)与 S7 B1 域文件集(:359,9 文件)均未含两新件路径;round_cycle.gd 经 oc 调 B2 符号(`_enemy_system` 族)须随批增行,battle_facts.gd 零协作调用不入清单。
## 4. 设计契约(违反即返工的红线条款)
- 🔴 **行为零变化(本批总判据)**:同种子下事件流/步骤流/两快照载荷/存档往返逐位一致;玩家可见面零变化;`design/gdd/systems/` 零修订预期。
- 🔴 **RNG 取号序零漂移(封闭流随件迁移先例句)**:behavior_roll 随 `roll_round_actions` 迁 RoundCycle——流名、开流时点、取号序逐字(先例句=「fx_reveal 封闭流随件迁移取号序不变」同款);encounter/gp_drop/board_gen/variant_place/fx_reveal 五流留原地零触碰;零 `randomize()`/自建随机。
- 🔴 **信号顺序契约冻结**:五信号(step_row/battle_finished/round_started/board_changed/settlement_snapshot)留宿主;发射语句零迁移、发射时序零变化;A2 三 connect(:251-254)逐字。
- 🔴 **两快照出口签名与载荷逐字不变**:presentation_snapshot/diagnostic_snapshot 字段名、嵌套结构、值口径逐字——内部读数改指两件投影后值恒等(round_index/attune_safe_seen/完美三账/hero_atk 派生读均受理后不变量)。
- 🔴 **明细行协议词表零触碰**:基础 9 类+扩展行词表、SOURCE_EXEMPT_TYPES/SOURCE_EXEMPT_CLASSES 两常量、`_emit_row`/`_assert_row_source` 行发射基建留宿主零迁移。
- 🔴 **行为零变化承载(对拍闸退役后)**:同种子逐位一致由关联套件的既有回放断言与两快照恒等断言承载;对拍闸(原闸 11)已随 2026-10-30 工程批退役,无闸级对拍批准事项。
- 🔴 **拆分边界纪律**(判据权威=code-conventions §1.1,此处立卡内执行条款):①每个拆出单元须有可陈述的职责语句与单一变化原因(实现报告逐件一行承载);②拆出单元须有集体身份——命不出名字、只能说「剩下的成员」的打包=凑计数袋,禁;③「过阈值」只许作为发现信号,作为拆分或收拢的动机即违规;④按纪律拆不出内聚单元 → 停卡呈报走豁免/还债通道,禁硬拆凑绿;⑤拆分沿职责轴不沿阈值轴。两新件职责语句见第 8 节(RoundCycle=轮结算周期的推进结构;BattleFacts=战斗事实的记录与查询口径)。
- 🔴 **禁为机检文本保留无效成员**:22 成员随件迁出+treasure_inventory/_hero_atk 两成员退役=宿主删 24 项(37−22−2+RoundCycle/BattleFacts 两新件接线引用=宿主 15,账平——grilling 复核订正原算术),禁保留别名、别名转发属性或空壳;机检键与卡片契约互斥时,实现段一律停卡呈报,不得自造第三条路。
- 🔴 **随迁键收敛义务**:迁移函数逐字纪律——`roll_round_actions`(45 行/分支≈8 贴线)、`settle_if_due`、`reset_round`、三 mark 方法迁移与改指**禁顺手增分支/局部**;函数迁入新文件若出超标键=卡内同步收敛(拆助手函数,拆分不改语义;先例=迭代 40 卡① 12 随迁键收敛),禁带新键进批末闸。
- 🔴 **段类接线改形守 Middle Man 禁壳**:段类对宿主的直调形态不变(段类经宿主引用直调,现状形态);段内改指一律调用点改指(`oc._X` → `oc._facts.X`/`reward_grant.treasure_inventory`),宿主与新件禁留转发壳。
- 🔴 **_fatal 与 battle_result 状态机唯一写点留宿主**:RoundCycle/段类经 oc 直调 fatal 面零改形;BoardInstaller(迭代 42 建件)fatal Callable 零触碰。
- 🔴 **BattleFacts 成员冻结**:15/15 贴顶——实现期禁增员,增员即停卡;扩容阀=下一张要加事实成员的卡先把封印判定账五成员二次拆出(SealLedger,−5)再落新账,禁硬挤。
- 🔴 **reset_round 复位边界**:只清 reveals/seals/path 三项、**不碰 refresh_used**——_battle_over 后快照读到的 refresh_used 必须保持末轮值(设计文档 §8.5 险点,对照表 V2 行断言钉住)。
## 5. 范围边界
做什么:设计文档 §2 逐成员去向表的全部迁移与改址、两新件建件、treasure_inventory 改址、_hero_atk 派生读、随迁键收敛、S7/S8 静态扫描随动、对照表新增断言四条。
不做什么:
- 轴丙 BoardInstaller 建件——迭代 42 在册卡执行,本卡前置、不重复。
- 五段段类职责与段序语义零改写(只改指);`_exit_distribution` 留宿主(设计文档 §6.5 已否决迁驱动件——判定段直调宿主,零新引用环)。
- attune 行为函数留宿主(attune_has/attune_param_sum/attune_convert_state/积点自动兑付体/充能重置零迁——设计文档 §5 重裁决);AttuneLoadout 零触碰。
- nest_preview_count 冻结面、round_index 公有直读面、A2 三事件订阅面——零变化。
- 数值表、RNG 流词表、信号载荷 schema、明细行词表——零触碰;本批零数值改动,MC 零跑(第 13 节)。
- `game/tests/README.md`、`design/` 全目录、根规则文件——实现批禁写(反哺点通道,第 6 节)。
- 效果发射端口定形与 reward_economy 分件——归接收方条目其余子项,另行设计讨论。
## 6. 关联文档同步面
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|---|---|---|
| design/engineering/architecture/architecture.md | 轴丁两行与功能层 RoundCycle/BattleFacts 行——设计已闭合落文 v1.25,实现照册施工;「测试与质量域」S13 豁免第三条注销句已预写注销(本批键账达成即生效,未达成=停卡非落文);两行「构造=引用束注入」句与本卡三参直构/零参直构实态的口径差;批末成员数/行数/公开方法数实测值与在册数字出入 | 设计权威文档——实现批禁直改;出入逐条列进 `reports/iter<N>-反哺点-<日期>.md`,用户裁决后归文档批落文 |
| game/tests/README.md | 本批零新增能力、零入口与代表用例名变更(测试改指只动成员寻址;新增断言四条全部内嵌既有函数);能力清单零增删改 | 机械面文档——实现批禁写;批末收尾核对表上名字与实际落地一致(改名则回表) |
| design/gdd/systems/(全树) | 无关联文档——结构整改不改游戏规则与玩家可见行为 | 无修订预期;若实现中发现契约句被触碰,停卡呈报走反哺点通道 |
## 7. 卡前文件结构图
| 文件 | 职责 | 改动性质 |
|---|---|---|
| game/core/battle_facts.gd | 战斗事实件(新增,architecture v1.25 功能层在册)——受理事实/轮 facts 缓冲/封印判定账/溯源/条件计数/同调快照,自带轮复位与完美账写口 | 新增(非行为改动——成员迁移;验收=对照表 V1/V2/V6 行) |
| game/core/settlement/round_cycle.gd | 轮循环驱动件(新增,同在册)——五段段件持有与段序执行、结算重入门闸、开轮摇号、踩雷计数账 | 新增(非行为改动;验收=V1/V3 行) |
| game/core/battle_orchestrator.gd | 战斗结算编排中枢——宿主 15 成员定着、行发射基建、状态机、两快照出口、attune 行为读数与触发面 | 修改(非行为改动——成员改指、三函数迁出、派生读、注入改址;验收=V0–V5 行) |
| game/core/settlement/grant_segment.gd | 授予段——事实族改指约 23 处+完美三处直写改经三 mark 方法 | 修改(非行为改动) |
| game/core/settlement/combat_segment.gd | 战斗段——2 处改指(oc._facts_reveals 扫描、oc._hero_atk 派生调) | 修改(非行为改动) |
| game/core/level_runner.gd | 关卡域生命周期——库存注入 1 行改经 `reward_grant()` 出口直注 | 修改(非行为改动——注入路径改址,注入时序与消费面零变化;验收=V5) |
| game/tests/static_scan.sh | 静态扫描域承载——S7 B1 域文件集与 S8 await 文件集增行 round_cycle.gd | 修改(工程随动,architecture 拆件定稿节 S7/S8 随动条在册) |
| game/tests/unit/battle_settlement/seal_polarity_test.gd · unit/core/feat_vouchers_test.gd · unit/battle_settlement/trigger_cond_test.gd · unit/battle_settlement/round_flow_skill_pool_test.gd · unit/core/settle_segments_test.gd · unit/core/treasure_effects_test.gd · unit/core/adventure_feats_test.gd · unit/core/meta_progression_forge_test.gd · unit/battle_settlement/roll_multiplier_test.gd | 成员寻址改指(断言条件与期望值零变化)+新增断言内嵌既有函数(V1/V2/V4/V5) | 修改(改指=非行为改动;新增断言行=对照表对应行) |
aura/decay/verdict 三段、battle_fx_host、reward_grant、damage_controller、main.gd、treasure_interact_controller、board_installer——零改动(设计文档 §11 盘点)。新增件「为什么不能复用」理由与唯一落点核查见第 8 节;对不上即卡片不成立。
## 8. 落位与可复用性预检
- **battle_facts.gd(新增)**:复用面核查——战斗事实记录面现行只摊在 battle_orchestrator 成员区(全仓 grep 同名与同义标识符:`_facts_reveals`/`_seal_consumed`/`_perfect_*` 等无第二实现),无既有件可复用。不能并入 BattleFxHost(效果引擎宿主域——变化原因是效果发射与施加,不是事实记录)、不能并入 RewardGrant(授予管线域——事实账不是授予物)、不能并入五段段类(段类只搬运时序零持有账——缓冲写读跨段跨界,归宿主编排面)、不能并入 AttuneLoadout(营地/冒险域充能物化单源,迭代 39 已闭合契约——重开已闭合边界=设计文档 §5 理由 4 否决)。落点唯一:`game/core/battle_facts.gd`。分层:core 层 RefCounted,零注入引用、零信号、零协作对象调用——纯数据+谓词+写口;身份快照捕获(query_full_snapshot)留宿主 `_on_cell_revealed`,防它变成第二编排面。
- **round_cycle.gd(新增)**:复用面核查——轮结算周期推进机构(段件持有/重入闸/摇号/踩雷账)现行只存在于宿主三函数+五成员,无第二实现。不能并入 BattleFxHost/RewardGrant(变化原因不同,同上)、不能并入任一段类(它是段件的序主人——持段件者不能是被持者)。落点唯一:`game/core/settlement/round_cycle.gd`(与五段段件同目录)。分层:core 层 RefCounted、零 await;随机只经 `oc.rng` 的 behavior_roll 封闭流。
- **引用束注入构成**:引用束先例(BattleFxHost/RewardGrant 的字典束)防的是 `_init` max-parameters 新键——本批两新件参数均未触发:RoundCycle `_init(host, fx_host, reward_grant)` 三参直构(fx_host/reward_grant 仅作段构造透传,不落成员);BattleFacts 零参直构。architecture 两行「构造=引用束注入」句按设计文档 §3/§4 实态执行(三参直构无需束),出入随反哺点申报。
- **依赖方向**:宿主→两新件单向(宿主 `_init` 建件并接线,每战新建同灭);RoundCycle 持 `oc`=五段段类既定同款形态(段类已持宿主引用直调——非新增反向引用),除 `oc` 外禁持宿主其他成员、禁回调宿主私有族;BattleFacts 不持任何对象引用——宿主与段类经注入引用直读写(fx_host._fx_bonus_delta 跨件直读写同款现状形态)。新件之间零互引。
- **新增函数**:宿主 `_hero_atk()` 派生读=`_journal()`「读面即引用、无第二账」同款先例(encounter 受理后只读,派生值恒等);`reset_round`=原 `_reset_round_facts` 逐字;三 mark 方法=新写口(升级采纳案)。零新增数据件、零新增常量表。
## 9. 实现规范预算(新件对照 gdstyle 默认阈值;写码前对账,超预算面=停卡退回写卡段)
| 新件 | 公开方法 ≤20 | 类变量 ≤15 | 迁移函数对账(基线源函数键) |
|---|---|---|---|
| battle_facts.gd | 预算 4(reset_round+mark 三方法;设计文档 §10 表载 5 属含 `_init` 宽口径计数差,两口径均 ≤20 零键风险) | 15(贴顶——实现期禁增员,增员即停卡;扩容阀=SealLedger 二次拆出) | `reset_round`=原 `_reset_round_facts` 逐字(基线无其函数级键);三 mark 新增小函数远在阈值内 |
| round_cycle.gd | 预算 3(settle_if_due/roll_round_actions/is_settling) | 8(oc+五段段件+_settling+mines_hits) | `settle_if_due`=`_maybe_settle`+`_settle` 合体(两源函数基线零键;闸序与段序逐字);`roll_round_actions` 45 行/分支≈8 贴线——迁移禁增分支/局部,确需增条件即停手核对 gdstyle;`is_settling` 新增小函数 |
存量触面一查:battle_orchestrator 类变量 37(轴丙后实测)→15 只降、文件长约 890→约 830 只降(均阈值内,S13 键较登记值只降不升——达成手段=本卡迁移,无豁免申报);grant_segment/combat_segment 改指零新增键(`_judge_seal` 等函数体只换成员寻址);level_runner 改 1 行零新增键。两新件与改址后宿主、段类落地后先跑 `python tools/gdstyle_gate.py` 预检一次再进批末闸(T4 步骤)。`_init` 形态:RoundCycle 三参/BattleFacts 零参(max-parameters 阈值 5 未触发)。新增文件全类型标注(S9——容器参数化走 `Dictionary[Variant, Variant]` 现行口径);头注按 code-conventions §1.4.1(职责语句+封闭面声明,禁变更叙事、禁文档反链)。
## 10. 任务卡 T0..T4(估时为区间;工作量限制只属迭代层)
**T0 重测对账(0.25–0.5 工作日)**(前置:迭代 42 合回——BoardInstaller 在库;产出:逐成员对账结论与改址点名清单,后续各卡取用)
- [ ] 以当轮 master 重测 battle_orchestrator.gd 类变量逐名清单,对账设计文档 §2 表五去向(留宿主/RoundCycle/BattleFacts/退役改址/派生读;轴丙后实态 37 项,`_board_generator` 行应已消失)——对不上即停卡呈报
- [ ] 复核 gdstyle 基线:battle_orchestrator 函数级键数(预期零——漂移即停卡呈报);类变量键现值与文件长键现状(应已随轴丙归绿或基线已 refresh)
- [ ] 复核第 3/7/9 节全部 file:line 引用与设计文档 §11 改址盘点实数(grant_segment 约 23–25 处、测试各套件逐处点名——含 settle_segments_test:27 补入项);漂移处就地改卡并记录
**T1 BattleFacts 建件与事实成员迁移(0.75–1 工作日)**(取用:T0 对账清单;产出:`_facts` 在座、事实族 15 成员归件——T2/T3 引用其成员名)
- [ ] 建 `game/core/battle_facts.gd`:class_name BattleFacts,extends RefCounted;15 类变量初值逐字承原宿主声明(encounter/reveals/seals/path/refresh_used/board_seq/board_from_midround/seal_consumed/seal_miss_seen/perfect_hit_true/perfect_hit_false/perfect_forgiven/feat_first_dig_used/attunement/attune_safe_seen);公开方法 4:`reset_round()`(原 `_reset_round_facts` 逐字——只清 reveals/seals/path 三项,不碰 refresh_used)、`mark_perfect_hit()`、`mark_perfect_miss()`、`mark_perfect_forgiven()`;头注写职责语句+成员封闭面+零注入零信号零协作调用
- [ ] 宿主 `_init` 建 `_facts = BattleFacts.new()`;事实族成员全量改指:宿主声明删 15 项、读写点改 `_facts.X`(encounter 全部读点——_journal/_attune_loadout/_fx_host_fact/受理段/fx_state/两快照/gp_drop,按 T0 点名清单逐处;缓冲追加/复位/装板清零/perfect 谓词同批);`_reset_round_facts` 函数删除,三调用点改调 `_facts.reset_round()`(时序位置逐字)
- [ ] grant_segment 事实族改指(`oc._facts_reveals/_facts_seals/_facts_path/_seal_consumed/_seal_miss_seen/_feat_first_dig_used/_perfect_*` → `oc._facts.X`);完美三处直写改经三 mark 方法(:311/:379/:394——写口升级采纳案;:397 forgiven 读数直读 `_facts.perfect_forgiven` 零变化)
- [ ] 测试改指:seal_polarity_test 8 处(_perfect 直写→_facts.perfect_*)、feat_vouchers_test facts 族、treasure_effects_test:309(ob14.attunement→ob14._facts.attunement)、adventure_feats_test 1 处(encounter 读→_facts.encounter)——断言条件与期望值零变化
- [ ] 新增断言 round_flow_skill_pool_test.gd:_smoke_full_battle 内嵌〔编排归约 V2〕:终局后 `presentation_snapshot()["refresh_used"]` 等于末轮结算 snapshot 的 economy.refresh_used(复位边界险点,规格见对照表)
- [ ] 孤立验证:`godot --headless --script res://tests/run_all.gd -- --only=seal_polarity,feat_vouchers,treasure_effects,adventure_feats,table_structure_guard,round_flow_skill_pool,variant_placement` 全绿+`python tools/run_smoke.py`(出红只跑红件最小单元)
**T2 RoundCycle 建件与段驱动迁移(0.75–1 工作日)**(取用:T1 的 `_facts`;产出:`_rounds` 在座、段驱动三入口——T3 引用其方法名)
- [ ] 建 `game/core/settlement/round_cycle.gd`:class_name RoundCycle,extends RefCounted;类变量 8(oc/mines_hits 公有+_grant_seg/_aura_seg/_combat_seg/_decay_seg/_verdict_seg/_settling 私有);`_init(host, fx_host_ref, reward_grant_ref)` 三参——五段构造五行从宿主 `_init` 逐字搬入(构造参数与持有形态不变);公开方法 3:`settle_if_due()`(原 `_maybe_settle` 三闸+`_settle` 段序体合体——闸序 settling→battle_result→phase 逐字,终局早退不回置 _settling)、`roll_round_actions()`(原函数逐字迁入——behavior_roll 流名/开流时点/取号序逐字,宿主引用经 oc 改指,禁增分支/局部)、`is_settling()`;头注写职责语句与单一变化原因
- [ ] 宿主 `_init`:五段构造五行迁出,改 `_rounds = RoundCycle.new(self, _fx_host, _reward_grant)`(置于两件建齐与 bind 接线之后——构造序禁环不变);五段成员声明删除;`_maybe_settle`/`_settle`/`_roll_round_actions` 三函数删除
- [ ] 宿主调用点改址:`_on_round_end` 末行→`_rounds.settle_if_due()`;begin_battle 与 `_exit_distribution` 的 `_roll_round_actions()`→`_rounds.roll_round_actions()`;diagnostic_snapshot settling 读→`_rounds.is_settling()`;`_begin_battle_fx_state` 踩雷清零→`_rounds.mines_hits = {"total": 0, "last": 0, "round": 0}`(赋值复位——语句时点逐字);`_book_negative_blast` 两写→`_rounds.mines_hits`
- [ ] 测试改指:trigger_cond_test :119/:126/:131(orch._mines_hits→orch._rounds.mines_hits);settle_segments_test :27(→oc._rounds._grant_seg);round_flow_skill_pool_test:1022 与 feat_vouchers_test 5 处(_grant_seg→_rounds._grant_seg)
- [ ] 新增断言 settle_segments_test.gd(接线检查段内嵌)〔编排归约 V1〕:oc._rounds 非空且 `_rounds.oc == oc`、五段段件齐在 _rounds、oc._facts 非空(规格见对照表)
- [ ] `game/tests/static_scan.sh` S8_FILES(:317)与 S7_B1_SET(:359)增行 `game/core/settlement/round_cycle.gd`(battle_facts.gd 零协作调用不入两清单)
- [ ] 孤立验证:`-- --only=round_flow_skill_pool,settle_segments,trigger_cond,seal_polarity,skill_unlock,roll_multiplier,variant_placement` 全绿+冒烟
**T3 宿主改形收束(0.5–0.75 工作日)**(取用:T1/T2 两件与成员名;产出:宿主 15 成员定着)
- [ ] 宿主 `_rounds`/`_facts` 成员声明落位;已迁成员声明复核清零——类变量实测 15(第 3 节名单),禁无效成员
- [ ] treasure_inventory 改址:宿主成员与 setter 转发块(:48-52)删除;四处读改指 `_reward_grant.treasure_inventory`(_hook_attune_consume/_reseed_attune_charges/装板薄壳叠加层退役/_battle_over 叠加层退役);`level_runner.gd:520` 改 `_settlement.reward_grant().treasure_inventory = treasure_inventory`(注入时序在宿主构造之后不变)
- [ ] _hero_atk 派生读:宿主新增私有函数 `_hero_atk() -> int`(返回 `int(_facts.encounter.get("hero_atk", int(db.combat.hero.atk)))`);受理段写入与 spawn override 改调;`combat_segment.gd:56` oc._hero_atk→oc._hero_atk();_hero_atk 成员删除
- [ ] attune 读数出口核验:attune_has/attune_param_sum/attune_convert_state/_attune_charge_safe_row/_attune_safe_seen_read 读源改 `_facts.attunement`/`_facts.attune_safe_seen`——三个外部消费面(main.gd:567、treasure_interact_controller.gd:125、table_structure_guard_test/breakpoint_resume_test 起战断言)零改址零触碰
- [ ] 新增断言 roll_multiplier_test〔编排归约 V4〕与 treasure_effects_test〔编排归约 V5〕(规格见对照表)
- [ ] 孤立验证:`-- --only=roll_multiplier,treasure_effects,breakpoint_resume,level_shop_economy,round_flow_skill_pool` 全绿+`python tools/run_system_test.py`
**T4 键账对账与收口(0.25–0.5 工作日)**(取用:T0–T3 全部产出;产出:本批交付物)
- [ ] `python tools/gdstyle_gate.py` 预检一次——宿主类变量 15、round_cycle 8、battle_facts 15、文件长 ≤1000(预期约 830)、零基线外新键;出超标键→按第 4 节随迁键收敛义务卡内拆助手后复检
- [ ] 里程碑步出口跑全套闸:`bash tools/run_all_gates.sh --code` 全绿(改动全为代码面);闸 11 PARITY 触面按第 4 节条款——实跑对拍须用户批准发起、不得借机重锚,NEED-APPROVAL 时停步呈用户裁决
- [ ] 键账对账:第 9 节预期逐键核;基线 refresh 由用户发令人工 `python tools/gdstyle_gate.py --refresh`(须 --force——全基线 16 键消失 ≥2 条触发骤降守卫;与姊妹卡同批编队时一次 refresh 合并执行)
- [ ] 产出物落位卡:`reports/iter<N>-实现报告-<日期>.md`(各卡状态+实机目检总清单+实现决定记录+逐拆出单元职责语句一行)与 `reports/iter<N>-反哺点-<日期>.md`(第 6 节同步面逐条落点)写齐方算收口
合计估时约 2.5–3.75 工作日(设计文档 §12 载 2–3 日;上探余量=测试改址逐处点名与 PARITY 批跑配合;PARITY 实跑须用户在场批准,不占卡估时)。切分预案:T1/T2 迁移函数出超标键需卡内拆助手时,超软盒预挂改由 T3 并 T4 吸收。
## 11. 验证闸——改动—验收对照表
域口径:本批改动全为 `game/` 下非 .md 行为载体——批末跑代码域闸(`tools/run_all_gates.sh --code`);里程碑步(T 段)出口跑一次全套闸,波内修复只做出红最小单元的最窄确认,新增测试先行孤立验证再并入全套。测试执行两入口铁规不破。三件保险(冒烟/系统测试/静态扫描)恒跑;02 单元与集成按关联档选套件(上表落点套件并集)。能力清单:本批零新增能力、零入口与代表用例名变更——能力行全部为既有名,零增删改(第 6 节)。**静态判据申报(不入对照表)**:键账收敛与静态随动(宿主 38→15、round_cycle 8/battle_facts 15、零基线外新键、static_scan.sh S7/S8 两清单增行)无运行时可观测提交面——判据=`python tools/gdstyle_gate.py` 与 `game/tests/static_scan.sh` 退出码(T4 执行),属静态判据+评审注记申报观测面局限(test-conventions §8.4 出口)。
| 行 | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|---|
| V0 | 行为零变化(本批总判据) | 全部结构改动(第 7 节清单) | 关联套件零改址应绿(对拍闸已随 2026-10-30 工程批退役——总判据由 V1–V5 各行能力行并集承载);静态判据申报同上(键账收敛与 S7/S8 两清单增行) | 集成 | 真实局 begin_battle→挖掘→结算→终局 | 关联套件全绿且改址面零失败——出红且无改址归因即停机呈报 | 既有:轮内流与结算五段全序;既有:技能池数据面与回放独立;既有:伤害公式与掷点乘区;既有:秘宝结构冻结与 12 件效果 |
| V1 | 两新件建件接线(T1/T2) | battle_facts.gd/round_cycle.gd 新建;宿主 _init 建件接线;五段构造迁 round_cycle | 新增 settle_segments_test.gd 接线检查段内嵌〔编排归约 V1〕:`oc._rounds` 非空且 `_rounds.oc == oc`;五段段件齐在 `_rounds`;`oc._facts` 非空 | 单元 | BattleOrchestrator 直构(settle_segments_test 现行夹具同款) | 编排器接线面(新件在座与宿主回指——接线断言本体) | 既有:轮内流与结算五段全序 |
| V2 | reset_round 复位边界(险点) | battle_facts.reset_round 只清三缓冲;宿主三调用点改调 | 新增 round_flow_skill_pool_test.gd:_smoke_full_battle 内嵌〔编排归约 V2〕:终局后 `presentation_snapshot()["refresh_used"]` == 末轮结算 snapshot `economy.refresh_used` | 单元 | begin_battle→轮内刷新→停手→结算→终局 | 两快照同键值恒等(复位不碰 refresh_used 的可观测提交面) | 既有:轮内流与结算五段全序;既有:停手转存储备与轮内刷新(上限/AP 不重置/刷新图零清图奖励) |
| V3 | 段驱动与摇号迁移(重入门闸/settle_if_due/roll_round_actions/mines_hits 账) | 三函数迁出宿主;宿主调用点改址;trigger_cond_test 3 处改指 | 复用 round_flow_skill_pool_test 全套(_smoke_full_battle/_smoke_settlement_segments/_smoke_skill_pool_replay_independence)、settle_segments_test V4-3 真实一轮、skill_unlock_test、trigger_cond_test(改指后应绿)——零新增断言 | 单元 | begin_battle;stop→WAITING→settle_if_due | 五段裁定行序+settling 闸+终局早退+同种子摇定逐位(behavior_roll 流随件零漂移由既有回放断言钉住)+mines_hits 转存读数 | 既有:轮内流与结算五段全序;既有:技能池数据面与回放独立;既有:Boss 半血解锁技门控 |
| V4 | _hero_atk 派生读 | 成员删→私有函数;combat_segment.gd:56 改调 | 新增 roll_multiplier_test.gd(既有主角攻击链函数内嵌)〔编排归约 V4〕:enc 携 `hero_atk` override 起战→主角攻击单 base_value==override;缺省→base_value==hero 表值 | 单元 | begin_battle(enc)→战斗段主角先手 | 主角攻击单基值(受理后派生值恒等的判据本体) | 既有:伤害公式与掷点乘区 |
| V5 | treasure_inventory 注入改址 | level_runner.gd:520 改经 reward_grant() 出口;宿主四处读改指;宿主 setter 转发块删 | 新增 treasure_effects_test.gd(秘宝使用链内嵌)〔编排归约 V5〕:注入后 `current_battle().reward_grant().treasure_inventory` 与关卡库存同一引用,且 use_treasure 受理走通 | 单元 | LevelRunner 建战注入→use_treasure 四步 | 注入引用同一性+受理面走通(改址后消费面不断链) | 既有:秘宝结构冻结与 12 件效果 |
| V6 | 封印判定账/装板溯源/受理事实迁移(完美写口升级、attune 状态随件) | 事实族改指(grant_segment 约 23 处+测试);三 mark 写口;attune 读源改 _facts | 复用 seal_polarity_test 全套、feat_vouchers_test(契约 2 计数纯净 R2)、variant_placement_test、meta_progression_forge_test、adventure_feats_test、table_structure_guard_test(attune 面零改址应绿——本批最硬的外部面零变化证)——零新增断言 | 单元 | 封印动作→结算;begin/refresh/exit 装板;begin_battle(enc) | 完美三账读数+去重闸+契约 2 计数纯净;刷新图零清图奖励+board_seq;enc 携带键贯通;attune_has/param_sum/convert_state 外部面零变化 | 既有:封印与极性路由/不可逆;既有:清图奖励双份与零路径;既有:变异布置门控;既有:专长(奇物)授予与凭证保底;既有:元进度入账与锻造两轴;既有:装板与开局免费展开(封锁格无资源、计入清图) |
反向核对:diff 中每个行为载体改动均有行——本批申报**行为改动零条**(全部为非行为改动:成员迁移与调用点改指,判断依据=V0 同种子逐位一致证明+既有断言面零改址应绿;完美写口升级=同一时点同一增量改经方法单点,语义逐字)。新增断言四条(V1/V2/V4/V5)全部挂行;孤儿断言零条。测试削弱申报见第 15 节。
## 12. 基线纪律(S13 键账)
1. 本卡键账目标=battle_orchestrator 类变量键归绿(实测 15 后随 refresh 消失);文件长键已由轴丙(迭代 42)归绿,本卡保持文件长 ≤1000(预期约 830)。
2. 禁为过闸 refresh 换绿:基线重生成只由用户发令,批末键账对账后人工 `python tools/gdstyle_gate.py --refresh` 一次执行(禁闸内自动重生成、禁实现批中途 refresh)。
3. 重锚守卫:新基线键数较旧基线少逾 10% 须 `--force` 显式确认——本批与轴丙预期合计消失 ≥2 条(16 键基线),须带 `--force` 由用户执行。
4. 还债=数值下降自然绿:迁移后同键数值下降不判红;出现恶化(同键数值较登记值上升、基线外新键)=停卡呈报,禁自行消化。
5. S13 豁免第三条(battle_orchestrator max-class-variables,architecture v1.25 已预写注销句)随本批达成生效——未达成=停卡呈报,非落文事项。
## 13. MC/数值与 RNG 零触碰声明
本批零数值改动、零数据表改动、零 RNG 流词表改动、零玩法字面量引入——结构整改不改数值与 RNG 消费序。behavior_roll 封闭流随件迁移取号序不变(流名、开流时点、取号序逐字)。数值与 RNG 零触碰则 MC 零跑;对拍闸已随 2026-10-30 工程批退役,无闸级对拍事项。
## 14. 异常分级
- **L1 自救**:改指漏改编译错、测试寻址漏改——就地修复重跑最窄确认。
- **L2 记录继续**:实测行数/改指处数与设计文档「约」值区间偏离、头注指址微调——记入实现报告「实现决定记录」。
- **L3 停机写报告等用户**:①机检预算互斥——两新件实数超第 9 节预算、BattleFacts 需增员、或迁移函数现出超标键=上游缺陷停卡退回写卡段(禁自造第三条路);②encounter 归属被实现期证伪——受理事实与轮 facts 复位节奏冲突实锤、且设计文档 §6.3 两条砍路均破冻结面(宿主 16 不可达)=停卡呈报走判据④通道;③T0 对账不符(成员去向对不上、基线出现函数级键、file:line 漂移过大);④V0 行为零变化被证伪(关联套件出红且无改址归因);⑤断言面被下游兜底吸收致判据绑不上(按 test-conventions §8.4 出口呈报);⑥S13 键恶化或基线外新键。
## 15. 测试削弱申报(允许改动的旧断言及理由)
零申报——本批不删任何断言、不改判据阈值、不缩扫描面、不把真实入口换成下层直调;测试改指只动成员寻址(断言条件与期望值零变化);新增断言四条(V1/V2/V4/V5,全部内嵌既有函数)。未申报的削弱由独立验收审计判红。
## 16. 独立验收审计
合并前由未参与实现的会话或子代理执行;报告落 `reports/iter<N>-验收审计-<日期>.md`。审计至少做四件事(test-conventions §8.7):逐行核对第 11 节对照表(测试存在、真执行、尾缀可 grep、真实入口未绕过改动点);抽查判据绑定面(V2 两快照同键、V4 攻击单基值、V5 引用同一性——当轮真实跑批执行过);检查测试削弱(对照第 15 节零申报);核对全部「非行为改动」判定依据(零漂移证明是否在当轮真实跑批中成立)。未过不得合并。
## 17. 代拍板白名单(允许 agent 自行拍板的微决策)
1. 迁移函数与改指处头注/行注的指址微调(词表与语义不动——「指址须真」纪律)。
2. 调用面改指的机械改写(排版、注释同步、行内换行)。
3. 断言失败消息尾缀编号分配与措辞(〔编排归约 Vn〕系列)。
4. 新件私有成员与小函数命名微调(职责语义不变、公有面契约名逐字不动)。
5. 宿主 _init 内两新件建件语句的次序微调(约束不变:_facts 无依赖先建、_rounds 在两件建齐与 bind 接线之后)。
超清单决策记入实现报告「实现决定记录」节。
## 18. 待裁点
零待裁点——五项待裁点(设计文档 §13)已由用户 2026-10-29 全裁闭合(第 2 节裁决记录),完美账写口升级已按推荐案采纳落卡。**零待裁点,开工门=U0**。编队前置:迭代 42(gdstyle 尾波清偿批,含轴丙 BoardInstaller)合回之后开工;T0 按当轮 master 重测对账。
@@ -1,431 +0,0 @@
# 需求卡片:换图系双基座七件批
> 日期:2026-10-31
> 性质:需求改动实现批卡片;零待裁点,开工门=U0。
> 来源:待办清单「「封锁-蓄力」combo 设计素材」条。唯一事实源:[奇物](../design/gdd/systems/冒险循环/奇物.md) v1.3+[行动经济](../design/gdd/systems/排雷循环/行动经济.md) v1.3+[战斗结算](../design/gdd/systems/战斗循环/战斗结算.md) v1.4+[地图战斗资源](../design/gdd/systems/战斗循环/地图战斗资源.md) v1.3;参考设计过程件:[提案 v0.5](提案-弃图刷新系专长流派-2026-10-30.md)。
> 估时:T0–T8 ≈ **7.75~8.5 个工作日**;切分预案见第十二节。
## 一、设计事实源
本卡实现下列已闭合设计,不重新裁断机制:
| 来源 | 本卡采用的事实 |
|---|---|
| [奇物 v1.3](../design/gdd/systems/冒险循环/奇物.md) | 基座先行原则、七件名称与职责、双基座叠加 |
| [行动经济 v1.3](../design/gdd/systems/排雷循环/行动经济.md) | 付费挖格产 RAP、刷新成本减半、两件基座叠加 |
| [战斗结算 v1.4](../design/gdd/systems/战斗循环/战斗结算.md) | 成功刷新事实、当轮结算兑付、全局 `damage_taken` |
| [地图战斗资源 v1.3](../design/gdd/systems/战斗循环/地图战斗资源.md) | 现行清图奖励语义不变;旧探索进度回收方案已注销 |
| [提案 v0.5](提案-弃图刷新系专长流派-2026-10-30.md) | 七件最终结构与行为验收面;保留作实现参考,不替代 GDD |
## 二、目标与完成定义
交付七件专长:
| 层 | feat_id | 显示名 | 稀有度/cap | provisional 数值 |
|---|---|---|---|---|
| 基座 | `vein_reserve` | 矿脉储能 | excellent/1 | 每次受理的付费挖格 +1 RAP |
| 基座 | `easy_swap` | 省力周转 | excellent/1 | 刷新成本为基线 50% |
| 输出 | `wall_blast` | 崩壁冲击 | excellent/1 | 全体存活敌各受 2 点 |
| 输出 | `charge_rotation` | 蓄力周转 | excellent/1 | 每刷一次 +1 层,上限 3;下一次主角攻击消费全部层 |
| 生存 | `stone_mitigation` | 石层缓冲 | common/1 | 当轮有成功刷新时,每次主角受伤固定 −2 |
| 生存 | `tunnel_rest` | 坑道小憩 | common/1 | 每刷一次累计 1 点恢复,上限 3;本轮授予段合计回血 |
| 资源 | `mine_profit` | 矿道红利 | rare/1 | 每次成功刷新固定 +1 GP |
完成定义:
1. `feats.tres` 30→37 行;稀有度 普通14/优秀13/稀有10/传说0;牌库 132→139。
2. 两件基座可叠加;刷新次数与 RAP 清零限制保持现行。
3. 所有主角伤害路径统一经过 `damage_taken`,每种伤害单据恰发射一次。
4. 刷新效果只在成功刷新后产生;RAP 不足、相位非法、每轮上限均零触发。
5. 崩壁冲击沿用案 C,在战斗段末结账;石层缓冲、坑道小憩、矿道红利均在本轮既有通道兑付。
6. 无七件专长时现行行为逐位不漂移;持有旧 `damage_taken` 专长时按全局受伤语义生效。
7. 新测试套件与计数回归全部通过,旧断言只允许因语义扩展而改,不得放宽阈值。
## 三、现状事实
1. `dig_paid` 在 AP 扣费前发射,消费环已有 counter/grant AP 通道,无 RAP 通道:[action_economy.gd:101](../game/core/action_economy.gd#L101)。
2. `grant_reserve_ap()` 已存在,直接增加 RAP:[action_economy.gd:177](../game/core/action_economy.gd#L177)。
3. `request_refresh()` 固定读全局基线成本:[action_economy.gd:199](../game/core/action_economy.gd#L199)。
4. 刷新成功序=扣 RAP→计数→旧资源退役→旧板退役→装新板:[battle_orchestrator.gd:610](../game/core/battle_orchestrator.gd#L610)。
5. 当前事件词表20种,效果词表32种:[effect_engine.gd:12](../game/core/effect_engine.gd#L12)。
6. `damage_taken` 现只在敌方攻击路径发射:[damage_controller.gd:472](../game/core/damage_controller.gd#L472)。
7. 地形伤害在开单前单独发射并只消费 `damage_reduce/ac_bonus/counter_add`,不消费 shield:[grant_segment.gd:174](../game/core/settlement/grant_segment.gd#L174)。
8. 棋盘主角直伤在控制器终段只做伤害下限后扣血,不发射事件:[damage_controller.gd:569](../game/core/damage_controller.gd#L569)。
9. 危险格与错误封印的负向资源直伤最终进入同一 `board_flat_hero` 单据:[reward_grant.gd:320](../game/core/reward_grant.gd#L320)、[reward_grant.gd:369](../game/core/reward_grant.gd#L369)。
10. 授予段伤害单已有案 C 暂存队列,战斗段末统一补提交:[grant_segment.gd:24](../game/core/settlement/grant_segment.gd#L24)、[combat_segment.gd:114](../game/core/settlement/combat_segment.gd#L114)。
11. `grant_gp` 现消费点写 `reward_grant.escrow` 并发专长 GP 行:[grant_segment.gd:265](../game/core/settlement/grant_segment.gd#L265)。
12. `attack_bonus` 已支持 `value_counter`:[damage_controller.gd:360](../game/core/damage_controller.gd#L360)。
13. GP 袋正常格面行值为3,普通战斗掉落均值3:[reward.tres:184](../game/data/tables/reward.tres#L184)、[shop.tres:7](../game/data/tables/shop.tres#L7)。
14. 现行专长表30行、牌库132;稀有度12/9/9/0:[adventure_feats_test.gd:465](../game/tests/unit/core/adventure_feats_test.gd#L465)。
15. 刷新真实入口回归已覆盖 RAP、AP保留、上限与刷新图零清图:[round_flow_skill_pool_test.gd:145](../game/tests/unit/battle_settlement/round_flow_skill_pool_test.gd#L145)。
16. BattleOrchestrator 当前811行,类变量与文件长度均有 S13 登记值:[battle_orchestrator.gd:600](../game/core/battle_orchestrator.gd#L600)、[gdstyle_baseline.txt:9](../tools/gdstyle_baseline.txt#L9)。
17. `BattleFacts` 成员冻结15/15,不得新增刷新队列:[battle_facts.gd:10](../game/core/battle_facts.gd#L10)。
18. `RewardGrant` 类变量封闭15/15,不得新增 GP/回收队列:[reward_grant.gd:13](../game/core/reward_grant.gd#L13)。
## 四、设计契约
- 🔴 **C1 无专长基线零扰动**:挖格不产 RAP、刷新成本8、伤害事件旧结果、GP与清图路径均保持现行。
- 🔴 **C2 成功刷新才登记**:RAP不足、非Active、每轮第3次均不产生 `board_refreshed`;成本折扣只改变门槛与扣费,不改变拒绝判据。
- 🔴 **C3 全局受伤事件恰一次**:敌方攻击、危险格、错误封印资源格、地形伤害都经统一 `damage_taken`;同一伤害单据不得重复发射。
- 🔴 **C4 减伤固定不堆**:石层缓冲只看当轮是否至少成功刷新一次;同一轮多刷不提高减伤,减后仍走现行全局伤害下限。
- 🔴 **C5 不引入临时生命**:本批不新增HP护盾池、承伤库存或生命上限变化。
- 🔴 **C6 五段时序不变**:崩壁冲击走现有延迟伤害队列;坑道小憩在授予段;GP走现有战斗内缓冲。
- 🔴 **C7 矿道红利不绑清图奖励**:每次成功刷新固定1 GP;不读取旧图探索进度、不触发清图事件。
- 🔴 **C8 数值单源**:RAP产量、50%折扣、群伤、恢复、减伤、GP均从 `feats.tres` 读取;代码零玩法数值字面量。
- 🔴 **C9 词表封闭**:只新增 `refresh_request`、`board_refreshed` 两事件与 `grant_reserve_ap`、`apply_discount` 两效果。
- 🔴 **C10 结构预算**:BattleOrchestrator文件长度与类变量只降不升;新增流程件独立承载刷新生命周期。
- 🔴 **C11 反自动刷新**:仍只允许玩家入口发起,RAP满不自动刷新。
- 🔴 **C12 信息红线**:不揭示格、不改数字、不改棋盘生成分布。
- 🔴 **C13 拆分边界**:`BattleRefreshFlow` 只负责刷新可用性、扣费、换图与成功事实登记;七件效果的算法留在效果引擎、授予段与伤害控制器。
- 🔴 **C14 禁凑计数袋**:不把所有分支堆进一个无名 helper;中央受伤消费件只处理 `damage_taken` 命中组合。
## 五、行为结构
```mermaid
flowchart LR
A[付费挖格受理] -->|矿脉储能| B[RAP增加]
C[玩家请求刷新] -->|省力周转| D[折后成本]
D -->|成功| E[board_refreshed]
E --> F[崩壁冲击:延迟群伤单]
E --> G[蓄力周转:当轮攻击层数]
E --> H[石层缓冲:当轮全局减伤]
E --> I[坑道小憩:当轮累计恢复]
E --> J[矿道红利:1 GP]
K[敌方攻击/危险格/错误封印/地形] --> L[damage_taken 恰一次]
H --> L
```
## 六、范围边界
做:
1. 扩两事件、两效果;统一全局 `damage_taken` 发射与消费。
2. 实现两件基座、三件输出/两件生存/一件资源的数据行与消费点。
3. 拆 `BattleRefreshFlow`,保持编排器入口与唯一通道。
4. 新增七件专项测试,同步词表、专长池与刷新回归。
5. 能力清单入表。
不做:
1. 不做探索进度回收、清图奖励折算或旧图快照。
2. 不做临时生命值或独立护盾池。
3. 不新增 UI、素材、渲染基线、MC档位。
4. 不重构自爆流、不改 `增益状态`、不新增数据表。
5. 不抬高刷新成本,不做全板开,不返 RAP。
## 七、关联文档同步面
| 文档 | 关联点 | 同步义务 |
|---|---|---|
| [奇物](../design/gdd/systems/冒险循环/奇物.md) | 七件由设计声明改为实装;行数、稀有度与验收口径 | 实现批禁写;落 `reports/iter<N>-反哺点-<日期>.md`,用户裁决后文档批执行 |
| [行动经济](../design/gdd/systems/排雷循环/行动经济.md) | 两件基座由待实现改为在册 | 同上 |
| [战斗结算](../design/gdd/systems/战斗循环/战斗结算.md) | 全局受伤事件与刷新事实落码状态 | 同上 |
| [地图战斗资源](../design/gdd/systems/战斗循环/地图战斗资源.md) | 确认清图奖励不受矿道红利改变 | 同上 |
| [架构文档](../design/engineering/architecture/architecture.md) | 新增事件、效果、BattleRefreshFlow与API边界 | 同上 |
| [测试手册](../game/tests/README.md) | 换图系能力行 | 本写卡段已入表;实现批只核对名实一致 |
## 八、文件结构与职责
| 文件 | 职责 | 改动类型 | 验收行 |
|---|---|---|---|
| [effect_engine.gd](../game/core/effect_engine.gd) | 封闭词表扩两事件、两效果 | 行为改动 | V1 |
| [action_economy.gd](../game/core/action_economy.gd) | dig_paid产RAP、折价成本受理 | 行为改动 | V2/V3 |
| [battle_refresh_flow.gd](../game/core/settlement/battle_refresh_flow.gd) | 新建:刷新门、扣费、换图、成功事实 | 行为改动 | V4/V10 |
| [battle_orchestrator.gd](../game/core/battle_orchestrator.gd) | 刷新公开口单行转发;来源豁免 | 行为改动 | V4 |
| [damage_controller.gd](../game/core/damage_controller.gd) | 全局受伤消费、攻击层消费、延迟群伤目标解析 | 行为改动 | V5/V6/V7 |
| [grant_segment.gd](../game/core/settlement/grant_segment.gd) | 刷新命中施加、GP、当轮恢复、地形路径接入统一消费 | 行为改动 | V5/V6/V7/V9 |
| [reward_grant.gd](../game/core/reward_grant.gd) | 群伤单延迟入队 | 行为改动 | V6 |
| [feats.tres](../game/data/tables/feats.tres) | 七行专长与数值 | 行为改动 | V2/V3/V6/V7/V8/V9/V11 |
| [run_all.gd](../game/tests/run_all.gd) | 新测试登记 | 非行为改动 | V12 |
| [refresh_feats_test.gd](../game/tests/unit/battle_settlement/refresh_feats_test.gd) | 新建七件与全局受伤链路专项 | 非行为改动 | V2–V10 |
| [adventure_feats_test.gd](../game/tests/unit/core/adventure_feats_test.gd) | 专长行数、稀有度、牌库 | 非行为改动 | V11 |
| [forge_table_test.gd](../game/tests/unit/data_config/forge_table_test.gd) | 事件/效果闭集计数 | 非行为改动 | V1 |
| [effect_words_t1_test.gd](../game/tests/unit/core/effect_words_t1_test.gd) | 新词在册与出域拒绝 | 非行为改动 | V1 |
| [round_flow_skill_pool_test.gd](../game/tests/unit/battle_settlement/round_flow_skill_pool_test.gd) | 无专长基线回归 | 非行为改动 | V12 |
| [README.md](../game/tests/README.md) | 能力清单 | 非行为改动 | V11 |
## 九、落位与可复用性预检
### 9.1 新增件
| 新件 | 复用结论 | 唯一落点 | 调用路径 |
|---|---|---|---|
| `BattleRefreshFlow` | 已查 `can_refresh`、`player_request_refresh`、`request_refresh`、商店代理、autoplay;没有同时负责成本查询与成功事实登记的现成件。不能复用 GrantSegment,因为刷新发生在授予段外;不能塞 BattleOrchestrator,因其文件长度贴顶 | `game/core/settlement/battle_refresh_flow.gd` | 呈现层→编排器转发→流程件→行动经济/装板壳/授予段 |
| `refresh_feats_test.gd` | 现有刷新测试只覆盖无专长基线;专长宿主没有经真实 `player_request_refresh` 驱动七件的夹具 | `game/tests/unit/battle_settlement/refresh_feats_test.gd` | `settle_batch`/`player_request_refresh`/轮末结算 |
| `_apply_hero_damage_effects` | 复用现有 `_enemy_shield_apply` 的组合算法,不新造事件消费件 | DamageController私有族 | 所有 `damage_taken` 发射点唯一消费 |
### 9.2 实现规范预算
| 触面 | 实测预算 | 结论 |
|---|---|---|
| `battle_refresh_flow.gd` | 公开函数2/类变量0 | ≤20/≤15,通过 |
| `battle_orchestrator.gd` | 类变量38不变;当前811行,删除旧刷新体并改两行转发,目标下降至少8行 | S13只降不升 |
| `action_economy.gd` | 公共方法15→15,仅扩参与局部状态 | ≤20,通过 |
| `grant_segment.gd` | 类变量3→3;公开方法1→2;新增私有施加函数≤4 | ≤20/≤15,通过 |
| `damage_controller.gd` | 公共方法不新增;现有 `_enemy_shield_apply` 改名为 `_apply_hero_damage_effects`,私有函数净增≤2 | S13逐键实测 |
| `reward_grant.gd` | 类变量15→15;新增一个公开延迟入口 | 禁增员,通过 |
| `feats.tres` | 同一专长表30→37 | 无第二数据源 |
## 十、任务卡
### T0 开工基线与预算实测(0.5d)
步骤:
- [ ] 读 `game/tests/.gates/ci-status.json`;CI红未修即停卡。
- [ ] 复核第三节 file:line;任一事实漂移先停卡核对。
- [ ] 跑开发期局部读数:`bash tools/gdstyle.sh game`。
- [ ] 记录 BattleOrchestrator行数/类变量、RewardGrant类变量、DamageController与GrantSegment方法数。
产出:所有结构预算基线;本卡无事实漂移。
### T1 词表扩签与计数(0.5d)
接口块:
- EVENTS 新增:`refresh_request`、`board_refreshed`
- EFFECT_KINDS 新增:`grant_reserve_ap`、`apply_discount`
步骤:
- [ ] 在 [effect_engine.gd:12](../game/core/effect_engine.gd#L12) 追加两事件,并同步 [effect_engine.gd:19](../game/core/effect_engine.gd#L19) 的 MINE_EVENTS。
- [ ] 在 [effect_engine.gd:24](../game/core/effect_engine.gd#L24) 追加两效果;不新增fact/op/DO_KEYS。
- [ ] 更新 [forge_table_test.gd:202](../game/tests/unit/data_config/forge_table_test.gd#L202):EVENTS20→22、EFFECT_KINDS32→34。
- [ ] 更新 [effect_words_t1_test.gd:14](../game/tests/unit/core/effect_words_t1_test.gd#L14):两事件与两效果在册;旧出域负例全部保留。
- [ ] 孤立验证:`effect_words_t1_test.gd`、`forge_table_test.gd`。
验收:词表封闭性无洞,旧词行为不变。
### T2 全局 `damage_taken` 统一(1.75d)
接口块:
```gdscript
func _emit_hero_damage_taken(amount: int, damage_kind: String, source: String, cell: Vector2i, ri: int) -> Dictionary
func _apply_hero_damage_effects(hits: Array, total: int) -> Dictionary
```
步骤:
- [ ] 把 [damage_controller.gd:507](../game/core/damage_controller.gd#L507) 的敌方受伤消费族改名为 `_apply_hero_damage_effects`,保留 shield、damage_reduce、ac_bonus、counter_add 的组合次序。
- [ ] 新增 `_emit_hero_damage_taken()`:payload必含 `kind/amount/source/cell/round/hp_ratio`,dispatch后调用唯一消费族,返回减后金额与命中束。
- [ ] 敌方攻击改走该方法,保持现有“掷点后、交付前”消费时点。
- [ ] `_resolve_board_flat_hero()` 在伤害下限前调用该方法;若单据 context 已标 `hero_damage_consumed=true` 则跳过,避免重复。
- [ ] 地形伤害改为调用该方法并把 `hero_damage_consumed=true` 写入单据 context,删除本地重复消费:[grant_segment.gd:174](../game/core/settlement/grant_segment.gd#L174)。
- [ ] 危险格与错误封印的负向主角直伤经 `board_flat_hero` 自动进入该方法,不新增第二发射点。
- [ ] 写专项函数:
- `test_all_hero_damage_paths_emit_once()`:注入临时 `counter_add damage_taken` 专长,从敌方攻击、危险格、错误封印、地形四种真实入口进入,每种单据恰好计数一次。
- `test_no_duplicate_damage_taken_event()`:同一伤害不得出现两次消费。
- [ ] 窄测:`refresh_feats|damage_controller|seal_polarity|round_flow` 红件最小复跑。
验收:`damage_taken` 字面语义覆盖所有主角承伤;无专长仍逐位保持原伤害。
### T3 两件基座(1d)
接口块:
```gdscript
func request_refresh(cost_override: int = -1) -> bool
static func _effective_refresh_cost(oc: BattleOrchestrator) -> int
```
步骤:
- [ ] 在 [action_economy.gd:101](../game/core/action_economy.gd#L101) 的 `dig_paid` 命中环累计 `grant_reserve_ap`,只在扣费受理后一次性调用 `grant_reserve_ap()`;连锁不二次调用。
- [ ] `refresh_request` 命中只认 `kind=="apply_discount" && mode=="refresh"`;取声明序第一个命中,按 `floor(base*cost_mult/100)` 计算。
- [ ] 新建 `BattleRefreshFlow`:公开 `can_refresh(oc)`、`execute(oc)`;execute只在ActionEconomy扣费成功后继续。
- [ ] 编排器两个公开方法改为单行转发,删除旧刷新体。
- [ ] 写:
- `test_reserve_on_accepted_dig()`:真实挖格入口,RAP+1,AP按表扣。
- `test_refresh_discount_gate_and_charge()`:真实刷新入口成本4,can_refresh同源判断。
- `test_double_base_stack()`:同时持两件时挖格产RAP、刷新扣4。
- `test_no_feats_baseline()`:旧成本与RAP来源逐值不变。
- [ ] 窄测 `--only=refresh_feats|round_flow`。
验收:两件基座改变行为但不破坏现行经济闸。
### T4 成功刷新事实与命中施加(1d)
接口块:
```gdscript
static func execute(oc: BattleOrchestrator) -> bool
func apply_board_refreshed(ri: int) -> void
func defer_ticket(t: Dictionary) -> void
```
步骤:
- [ ] `execute()` 成功序钉死:折价扣RAP→refresh_used+1→旧资源退役→旧板退役→装新板→GrantSegment `apply_board_refreshed(ri)`。
- [ ] install失败时返回false且零效果;成功事实只在新板就位后发射。
- [ ] `apply_board_refreshed()` dispatch一次 `board_refreshed`,payload `{round:ri}`,命中消费:
- `counter_add` → 既有单点落账。
- `grant_gp` → `reward_grant.escrow += value` 并发 `fx_grant_gp` 行。
- `open_ticket && channel=="blast"` → `DamageController.KIND_BOARD_BLAST`、`TARGET_ALL_ALIVE`、`source_class="fx_board_refresh"`,调用新增 `defer_ticket()`。
- [ ] 在 [battle_orchestrator.gd:35](../game/core/battle_orchestrator.gd#L35) 的来源豁免追加 `"fx_board_refresh"`。
- [ ] 写 `test_board_refresh_fact_only_on_success()`、`test_mine_profit_gp()`。
- [ ] 窄测 `--only=refresh_feats|round_flow`。
验收:拒绝刷新零事实;GP固定入账且每轮上限同时限制次数。
### T5 五件后续效果(1.75d)
接口块:
```gdscript
func _apply_hero_damage_effects(hits: Array, total: int) -> Dictionary
func _round_end_apply(ri: int) -> void
```
步骤:
- [ ] 崩壁冲击已在T4延迟开单;确认授予段不结账、战斗段末按存活目标结账,最后敌死亡仍由判定段胜。
- [ ] 石层缓冲用 `round_swap_guard`:成功刷新时+1;`damage_taken` 条件≥1时 `damage_reduce value=2`,不清层、不随伤害段变化。round桶轮始自然清空。
- [ ] 坑道小憩用 `round_swap_rest`:成功刷新累计至上限3;`round_end` 命中 `heal value_counter=round_swap_rest`,调用 `units.heal()`封顶,满血发未生效行;随后同事件行 `counter_add set=0`。
- [ ] 蓄力周转用战斗桶 `swap_charge_layers`:成功刷新至上限3;`attack_commit` 消费全部层数,随后清零;战斗新建自然清空。
- [ ] 写:
- `test_stone_mitigation_all_damage()`
- `test_rest_rotation_cap_and_clear()`
- `test_charge_layers_consumed_same_round()`
- `test_blast_defers_to_combat_segment()`
- [ ] 窄测 `--only=refresh_feats|damage_controller|seal_polarity`。
验收:五件只在成功刷新链生效;固定减伤不堆、恢复累计、GP定额。
### T6 七件数据行与牌库计数(1d)
接口块:`feats.tres` 行键沿用 `feat_id/display_name/rarity/cap/desc/triggers`,不扩schema。
步骤:
- [ ] 追加七行,trigger结构固定:
| feat_id | triggers |
|---|---|
| `vein_reserve` | `dig_paid → grant_reserve_ap value=1` |
| `easy_swap` | `refresh_request → apply_discount mode=refresh cost_mult=50` |
| `wall_blast` | `board_refreshed → open_ticket channel=blast value=2` |
| `charge_rotation` | `board_refreshed when counter<3 → counter_add swap_charge_layers1`;`attack_commit when≥1 → attack_bonus value_counter=swap_charge_layers`;`attack_commit when≥1 → set0` |
| `stone_mitigation` | `board_refreshed → counter_add round_swap_guard1`;`damage_taken when≥1 → damage_reduce value=2` |
| `tunnel_rest` | `board_refreshed when<3 → counter_add round_swap_rest1`;`round_end when≥1 → heal value_counter=round_swap_rest`;`round_end when≥1 → set0` |
| `mine_profit` | `board_refreshed → grant_gp value=1` |
- [ ] desc分别写:挖格储能、刷新半价、刷后群伤、刷后蓄力、当轮减伤、当轮恢复、刷后GP;禁“雷/旗”字面。
- [ ] 行数30→37;稀有度12/9/9/0→14/13/10/0;relic令牌30→37;牌库132→139。
- [ ] 同步 [adventure_feats_test.gd:465](../game/tests/unit/core/adventure_feats_test.gd#L465)、[:476](../game/tests/unit/core/adventure_feats_test.gd#L476),旧30行断言只按实数换代,不降低 validate/禁词检查。
- [ ] 写 `test_seven_feats_validate_and_pool()`。
验收:七件全部数据驱动,跨表计数器引用闭合。
### T7 回归与能力名实核对(0.75d)
步骤:
- [ ] 核对 [README.md](../game/tests/README.md) 五类换图能力行,文件名与测试函数逐字一致。
- [ ] `round_flow_skill_pool_test.gd:_smoke_active_refresh()` 无专长基线断言不删除、不放宽。
- [ ] `seal_polarity_test.gd:_smoke_refresh_provenance_guard()` 继续证明刷新图零清图奖励。
- [ ] 实跑关联窄测:
`--only=refresh_feats|adventure_feats|round_flow|seal_polarity|damage_controller|effect_words|forge_table|config_db`
- [ ] 出红只按红件最小复跑,波内不跑全量。
验收:新增与旧专长并存;无UI/素材改动,不新增golden。
### T8 批末出口与产出物(1d)
步骤:
- [ ] 里程碑出口跑 `bash tools/run_all_gates.sh --code`。
- [ ] 回执必须 `all_green=true`、`dirty_game=false`。
- [ ] 独立验收审计报告 `reports/iter<N>-验收审计-<日期>.md` 未过禁合并。
- [ ] 轻闸全绿、合并前写齐:
1. `reports/iter<N>-实现报告-<日期>.md`
2. `reports/iter<N>-代拍板追认单-<日期>.md`
3. `reports/iter<N>-反哺点-<日期>.md`
- [ ] 实现报告列七卡状态、V1–V12读数、S13前后数、旧damage_taken专长覆盖面变化、玩家主动刷新目检项。
- [ ] 反哺点逐条覆盖第七节六个目标。
完成定义:三份产出物齐全+代码域闸全绿+验收审计通过。
## 十一、验证闸:改动—验收对照表
| 需求点 | 改动(文件/行为) | 验收测试 | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|
| V1 词表扩签 | effect_engine;forge/effect_words | `effect_words_t1_test.gd:_init`;`forge_table_test.gd:_test_effect_kinds_closed` | 单元 | validate与整表加载 | EVENTS=22、EFFECT_KINDS=34、出域仍拒 | 新增:换图系刷新链路与效果词表接线 |
| V2 矿脉储能 | action_economy dig_paid消费 | `refresh_feats_test.gd:test_reserve_on_accepted_dig` | 接口 | `settle_batch(dig)` | RAP恰+1、AP扣值与板资源不变 | 新增:换图基座:挖格产 RAP 与刷新折扣 |
| V3 省力周转 | BattleRefreshFlow成本门 | `test_refresh_discount_gate_and_charge`;`test_double_base_stack` | 接口 | `player_request_refresh()` | base8→扣4;can与执行同源;两件都生效 | 新增:换图基座:挖格产 RAP 与刷新折扣 |
| V4 成功事实 | BattleRefreshFlow install尾点 | `test_board_refresh_fact_only_on_success` | 集成 | `player_request_refresh()` | RAP不足/第3次上限/非Active均board_changed与效果零变化 | 新增:换图系刷新链路与效果词表接线 |
| V5 全局受伤 | damage_controller统一发射消费 | `test_all_hero_damage_paths_emit_once`;`test_no_duplicate_damage_taken_event` | 集成 | 敌方攻击、dig danger、seal wrong、terrain触发 | 每路径一次事件、无重复扣血或重复counter | 新增:换图生存:全局固定减伤与轮末恢复 |
| V6 石层缓冲 | round_swap_guard+damage_reduce | `test_stone_mitigation_all_damage` | 集成 | 刷新→四种真实受伤路径 | 每种伤害最终金额减2;多刷不增加;下限1保持 | 新增:换图生存:全局固定减伤与轮末恢复 |
| V7 崩壁冲击 | open_ticket延迟队列 | `test_blast_defers_to_combat_segment` | 集成 | 刷新→停手 | 授予段无伤害行、战斗段末全体存活敌各受伤 | 新增:换图输出:刷新群伤与蓄力攻击 |
| V8 蓄力周转 | counter+attack_bonus value_counter | `test_charge_layers_consumed_same_round` | 接口 | 两次刷新→本轮主角攻击 | 攻击加2层、随后0;战斗新建0;上限3 | 新增:换图输出:刷新群伤与蓄力攻击 |
| V9 坑道小憩 | round_end heal消费 | `test_rest_rotation_cap_and_clear` | 集成 | 三次刷新→停手 | 回复3、上限3、层清0、hp≤max;满血未生效 | 新增:换图生存:全局固定减伤与轮末恢复 |
| V10 矿道红利 | board_refreshed grant_gp | `test_mine_profit_gp` | 集成 | `player_request_refresh()` | escrow每次成功刷新+1;拒绝零变化;fx_grant_gp行在案 | 新增:换图资源:刷新固定 GP 收益 |
| V11 数据与池 | feats七行;adventure计数 | `test_seven_feats_validate_and_pool`;adventure_feats | 单元 | ConfigDB整表与冒险牌库 | rows37、relic37、14/13/10、deck139、validate空、禁词0 | 既有:专长(奇物)授予与凭证保底 |
| V12 无专长回归 | round_flow/seal旧基线 | `_smoke_active_refresh`;`_smoke_refresh_provenance_guard` | 单元+集成 | 现行刷新/清图入口 | RAP8、AP保留、上限2、刷新图零清图、五段与回放不降 | 既有:停手转存储备与轮内刷新(上限/AP 不重置/刷新图零清图奖励) |
## 十二、测试方式与削弱申报
自动验证:
- V1–V12均从真实公共入口进入;计数器、事件行、escrow、hp与伤害行都是可观测提交面。
- 不造变异或回退hunk证明;临时专长夹具通过现行ConfigDB注入,属正常数据配置路径。
真人目检:
- 登记一项:玩家持基座与收益件后,是否主动规划刷新而非只在坏图刷新。写入实现报告,不阻塞合回。
测试削弱申报:
- 允许把行数、稀有度、事件/效果计数从旧实数改到新实数。
- 允许旧 `damage_taken` 行为测试增加危险格/错误封印路径,以体现用户已裁的全局语义;原敌方攻击与地形断言不得删除或放宽。
- 禁止删除RAP8基线、每轮上限2、AP保留、刷新图零清图、伤害下限、五段序、同种子回放等断言。
## 十三、估时与切分预案
| T0 | T1 | T2 | T3 | T4 | T5 | T6 | T7 | T8 | 合计 |
|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|
| 0.5 | 0.5 | 1.75 | 1 | 1 | 1.75 | 1 | 0.75 | 1 | **8d** |
浮动±0.5d。
切分预案:段一=T0–T4+T6(基座、全局受伤事件、刷新事实、数据接线,约4.75d);段二=T5+T7–T8(五件收益兑现与回归出口,约3.5d)。两段各自独立可测、独立提交。
## 十四、异常分级
L1(自救一次):编译错误、签名拼写、manifest登记遗漏。
L2(记录继续;同红三次升L3):既有无关文档域红;局部测试文案漂移。
L3(停卡写报告):
- CI红未修。
- 同一伤害出现两次 `damage_taken`,或某路径完全不出现。
- 石层缓冲使伤害归零、突破下限或改变治疗语义。
- 刷新生效出现清图奖励/探索进度耦合。
- BattleOrchestrator或RewardGrant结构预算被迫上升。
- 机检键与本卡契约互斥;禁为凑绿保留无效成员。
- 任何需求点找不到真实入口与特有可观测提交面。
## 十五、代拍板白名单
允许实现期自拍:
1. 私有函数换行、局部变量名、内部注释位置。
2. 测试断言消息措辞与helper顺序。
3. 错误扫描暴露的纯格式修复。
4. 不改变语义的前提下复用现有 `units.heal()`、counter API与GP行格式。
超清单必停卡呈报:
- 数值、稀有度、cap、counter_id、事件/效果名、来源类别、文件职责、验收入口。
- 任何把清图奖励、探索进度、临时生命重新引入本批的改法。
## 十六、零待裁点
七件名称、收益对象、全局受伤范围、叠加规则、时序、数值与稀有度均由最终确认单锁定。本卡零待裁点,开工门=U0。
## 十七、开工门
1. 由 iter-plan 编入迭代后,`/iter` 才可开工;无迭代外执行通道。
2. 开工前四份GDD凭据在待办清单闭合、CI绿、T0实测无漂移。
3. 本卡预计8个工作日,符合迭代硬线。
@@ -0,0 +1,195 @@
# 需求卡片——测速循环批(tune_sim_controller 循环内 await 真实消除)
> **版本状态**:v1.1 定稿——零待裁点(2026-10-30 停卡重裁:实现段 T0 三重证据定谳 v1.0 的「潜伏红」前提已被迭代 41 测试债批消化〔215da315——运行态收尾归还 run〕,按停卡呈报建议案剥离已申报行为改动 V3、T0 义务改现状复核、夹具申报差异两处减一处;2026-10-29 原四点裁决中②作废,①③④仍有效——裁决记录见第 15 节)。
> **接收方**:待办清单条目「零豁免五键清偿批——S13 余量五键真修四卡(2026-10-29 登记,来源=会话提及)」——本卡为其四卡中的测速循环批卡。
> **来源**:reports/设计-测速循环去await-2026-10-29.md(2026-10-29 设计闭合;§2.3 潜伏红推演与 §10 待裁点 1 的「还原」申报已随停卡重裁作废,§3–§7 形态与等价性论证仍有效)。**唯一事实源**:`reports/设计-测速循环去await-2026-10-29.md` + `design/engineering/architecture/architecture.md` v1.25「测试与质量域」S13 测量面豁免注销句(2026-10-29 零豁免裁:原循环内 `await` 豁免〔2026-10-27〕注销——tune_sim_controller 改 process_frame 信号常驻连接+步进状态机,每帧一局、帧相位逐点对齐;注销对象是 await 豁免、不依赖行为改动申报,句保持;句内「随批申报行为改动一处」半句已失效,随实现批现状化时一并修正——见第 6 节)+ 停卡呈报三重证据(iter44 worktree 分支 `reports/iter44-实现报告-2026-10-30.md` §5——重裁依据)。
## 1. 目标与完成定义
这批做什么:把 S13 静态质量闸(gdstyle)在册裸键 `game/presentation/tune_sim_controller.gd|quality/await-in-loop` 真实消除——`run(n)` 的 for 循环内 `await process_frame` 改为 process_frame 信号常驻连接+步进状态机(每帧回调执行一局、步尽次帧收尾断连),`run()` 只留函数级一次 `await _batch_finished` 保持协程身份;改后全文件零 for/while,该键从文本形态根除、此文件对这个键结构性免疫。随批执行一项已裁事项:新增双实现对拍套件,把帧相位等价论证变成当轮真实执行证据。**本批零行为改动**——收尾置假已在 run() 尾每批一次执行(迭代 41 测试债批 215da315 归还后的现行形态),本批收尾四语句同帧同相位迁入 `_finish_batch()`,语句集与语义零变化(第 3、4 节)。
什么状态算完:
1. `tune_sim_controller.gd` 全文件零循环、`await` 仅 `run()` 函数级一处;`python tools/gdstyle_gate.py` 对账该裸键消失(消失键不参与红判定)、无基线外新键。
2. 测量语义逐点等价(第 4 节四判据)经双实现对拍在当轮真实跑批中证明——五面对拍全等;wd8 三断言与 ui_tune_probe ⑤ 零改动保持绿。
3. diff 中行为改动零处——收尾四语句迁移为非行为改动(同帧同相位、语义零变化,对照表 V3 行),无任何行为漂移。
4. 脚本错误中断路径差异作为声明缺口写入实现报告(禁静默)。
5. 批末代码域闸全绿;实现报告与反哺点清单写齐方算收口。
## 2. 设计事实源
设计依据唯一出处=`reports/设计-测速循环去await-2026-10-29.md`(2026-10-29 设计闭合,零待裁点):§3 形态评估(process_frame 信号步进状态机采纳)、§4 推荐案(伪代码结构)、§5 等价性证明清单(四判据+已声明缺口)、§6 键账预期——以上各节不受前提消化影响、仍是本卡依据;该文档 §2.3 潜伏红推演与 §10 待裁点 1「还原」申报已作废(前提消化证据见停卡呈报)。架构面凭据=`design/engineering/architecture/architecture.md` v1.25「测试与质量域」S13 测量面豁免注销句(2026-10-29 零豁免裁落文)——豁免注销句保持,句内行为改动申报半句随实现批现状化修正(第 6 节同步面)。前提消化与重裁凭据=iter44 worktree 分支 `reports/iter44-实现报告-2026-10-30.md` §5 停卡呈报(git 历史证据 215da315+T0 两面实跑绿)。待办清单条目「零豁免五键清偿批」状态=已写卡+已编迭代 44(本卡 v1.1 重裁段产出)。
## 3. 现状事实(代码级,2026-10-30 实查;开工 T0 按当轮施工基面重锚——行号基线为本日 master)
- `game/presentation/tune_sim_controller.gd`(全件 68 行):`run(n)` 在 :36-54——:37 置运行态真、:40-42 开共享 JSONL 日志会话、:43 `panel.set_sim_running(true)`、:44 进度 0/n、:45 建 stats 六键束、:46 取自动策略驱动、:47-50 for 循环体(`_run_one_level` → 进度串 → :50 `await panel.get_tree().process_frame`——命中键的语句)、:51-54 收尾四语句(`close_session()` :51 → 报告注入 :52 → `panel.set_sim_running(false)` :53 → `_running = false` :54)——**收尾置假在 run() 尾、for 循环外、每批恰一次**。`_run_one_level` 在 :57 注释/:58-68(5 参),尾部 :66-68 为败局节点记账(defeat 分支)——非置假。类成员 5(db/panel/_base_hp/_driver/_running)+常量 2(:7 SEED_BASE=4200、:8 PlaytestLogger preload);头注 4 行。
- 前提消化定谳(v1.0「静态矛盾推演」作废依据):git 历史——迭代 41 测试债批提交 215da315(2026-10-29 合回)提交信息明载「两个产品回归随批修(……tune_sim 运行态收尾归还 run)」,收尾置假两行由该批归还 run() 尾并随该批申报;v1.0 成文(2026-10-29)与该批合回同日,其「现状考证」被上游批施工消化变质(读法 A;读法 B「考证当时即误读」与 215da315 提交信息矛盾,停卡呈报 §5 不采)。T0 实跑三重证据(iter44 worktree,停卡呈报 §5):wd8 三断言(现位 :145-147)全 PASS(套件 18 checks 全绿);ui_tune_probe 全链路 PASS(⑤ 守卫环 1800 帧预算内退出+输出四串在)。**潜伏红不存在**——两面现行全绿,「零改动转绿」改「零改动保持绿」。
- 断言面一〔wd8〕`game/tests/unit/presentation/standee_fx_sweep_test.gd:139-147`:FakePanel(内类 Node,:20-40——setter 面并入树供 get_tree)+FakeDriver(:44-55——`run_level` 回调内读 `ctrl.is_running()` 逐局记 `seen`);:142 直构控制器(字典夹具 db)、:144 `await ctrl.run(2)`(run 必须可等待、挂起至整批完成的契约)、:145-147 三断言——`drv.seen == [true, true]`/收尾 `not ctrl.is_running() and not panel.running`/报告非空。套件在 run_all.gd manifest 在册(res://tests/unit/presentation/standee_fx_sweep_test.gd,expect 0,manifest :188)。
- 断言面二〔探针 ⑤〕`game/probe/ui_tune_probe.gd:63-83`::65-66 设滑条与 N=10、:67 `press_simulate_for_probe()`(真实按钮 pressed 信号链)、:68-71 守卫环(`while main.ui.modals.debug_overlay.is_running()` 逐帧等——SIM_GUARD_FRAMES=1800 在 :16)、:72-73 预算内未完成判红、:74-83 输出四串断言(关卡完成率/关卡完成剩余 HP 均〔口径换代 V7〕/败北节点/N=10)。面板语义面 `debug_overlay.gd`:`set_sim_running` :81-83 → `_sync_sim_button` :107-110(模拟与两层调试两钮禁用+「模拟中…」文案——浮窗运行态贯穿整批的可见面)、`is_running` :77-79。
- 调用面 `game/presentation/main_debug_flow.gd`:`_on_tune_simulate` :72-77——守卫(活跃结算/冒险早退)后 :77 `root._tune_sim.run(n)` **不 await 调用**(返回的协程态丢弃——新形态必须保持此调用形态可用、零改动);`_start_debug_levels` :84 守卫读 `root._tune_sim.is_running()`(两层调试入口互查守卫)。
- 键账:`tools/gdstyle_baseline.txt:15` = 该文件唯一在册键(await-in-loop 裸键,基线 16 键之一)。S13 扫描面=产品码三目录(game/core+data+presentation——probe/sim/tests 不在面,`game/tests/static_scan.sh` S13 头注在案);S8 文件集=**十文件**显式清单(static_scan.sh :317 现行实查——不含本件);S9/S10 扫描面同不含 game/tests/。
- 产品码 process_frame 订阅面(T0 实查项):本件 :50(循环内 await)+`settlement_fx_view.gd:94`(play_damage_number 内一次性 await 等文本度量——战斗结算呈现期,与模拟批不并存)。现库无「run 途中新增订阅者」场景。
- 报告渲染面 `game/presentation/hud_presenter.gd` :197-218 `tune_sim_report`(静态函数,零触碰计划):空数组 `_mean`/`_p90` 双守卫(:221-227/:230-235)、完成率分母 `maxi(1, n)`(:206)——n=0 退化路径渲染安全(本批对拍 n=0 案的前提,实查在案)。
- 能力表现状:`game/tests/README.md` 能力表「调参测速批量模拟(逐帧步进与统计读数)」行已入表(:131——写卡段 v1.0 同批义务,真实入口=批量模拟入口,代表用例=对拍套件);断言宿主 wd8 套件锚既有行「站桩敌人呈现与结算演出落点」(:130)。
## 4. 设计契约(违反即返工的红线条款,标 🔴 触碰=L3 停机呈报)
- 🔴 **测量语义逐点等价**(设计文档 §5 四判据逐条落卡,双实现对拍为当轮执行证据):
① 步数与帧数一一对应不变——每局恰占一帧:第 i 局恒在调用点同步段(i=0)或第 i 帧信号发射点(i≥1),收尾恒在第 n 帧发射点,n=0 退化路径两形态同为同步收尾零帧;
② 每步工作量与执行相位不变——步进体=同一 `_run_one_level`+同一进度语句;执行点同为 emit process_frame 帧首段(await 恢复点与 connect 回调在引擎内同处一列连接、同一 emit 内被同步调用——设计文档 §4.2 逐步对齐表);
③ 终止条件与终止时读数不变——终止=计数走满 n;close_session/运行态复位/报告注入在同帧执行;
④ 输出逐字不变——报告=未触碰的 `HudPresenter.tune_sim_report`;stats 是 (种子, atk_pct, hp_pct) 的纯函数、帧时点不进测量值;JSONL 由未触碰的自动策略逐行写、close 时点同帧。
违反即返工;等价性对拍失败=L3 停机呈报。
- 🔴 **行为改动零处(收尾语义零变化)**:收尾置假已在 run() 尾每批一次执行(:53-54,215da315 归还后的现行形态)——本批 `_run_one_level`(:58-68)零触碰、运行态复位语义零变化;收尾四语句(:51-54)迁入 `_finish_batch()` 为同帧同相位语句迁移(判据③承载——非行为改动,对照表 V3 行)。禁任何行为漂移——`_on_tune_simulate` 不加运行态早退守卫(设计文档待裁点 3 备选否决)、发布态零触碰、探针①–④⑥–⑩ 段零触碰、`HudPresenter`/`PlaytestLogger`/`sim/level_autoplay.gd`/`debug_overlay.gd` 零触碰。
- 🔴 **脚本错误中断路径差异=声明缺口**(设计文档 §5 缺口 1,接受并文档化):GDScript 无错误陷阱 API、差异不可消除——旧形态步进体内脚本错误=协程死亡静默停摆(运行态永真、报告永不落);新形态=计数未推进、次帧重试同一步(确定性错误逐帧重试,探针 1800 帧守卫可抓;生产态=持续重试的可见坏,与旧「静默卡死」同级不同形)。实现报告文档化义务(T3),禁静默、禁造第三条路(错误陷阱/守卫兜底均已否决);测量批遇错本就整批作废,两形态都不产出可用读数。
- 🔴 **S8 结算路径 await 零命中面不触碰**:本件不在 S8 文件集(十文件显式清单实查不含本件);本批零触碰 S8 文件集与一切闸件。
- 🔴 **拆分边界纪律**(判据权威=code-conventions §1.1,卡内执行条款):本批零拆出单元——步进状态机收编本件(职责语句与不拆理由见第 8 节);①拆出单元须有可陈述职责语句与单一变化原因;②命不出名字、只能说「剩下的成员」的打包=凑计数袋,禁;③「过阈值」只作发现信号——本批键消除靠形态根除、不靠拆件凑数;④按纪律拆不出内聚单元→停卡呈报;⑤禁沿阈值轴拆。
- 🔴 **RNG 与种子零触碰**:SEED_BASE=4200 与逐局种子切分(SEED_BASE+i)零变化——stats 是种子纯函数是等价性论证的前提。
- 🔴 **注释纪律**:新增头注/注释零变更叙事(「由 await 改为信号」类句禁——沿革归 git);S11 注释禁词由术语表解析供给,新增注释用白话描述现行形态与信号契约。
## 5. 范围边界
做什么:第 3 节四件事——T0 现状复核(两面实跑应绿)、`tune_sim_controller.gd` 步进状态机改造(收尾语义零变化)、双实现对拍套件、键账对账与收口。
不做什么(明示去向):
- 零豁免其余四键(main.gd 类变量 49、battle_orchestrator 类变量 38、board_cell_unit 30、standee_body 19)——各归组合根注册面批/战斗编排归约批/呈现层状态件批(同条目四卡,待办清单在册)。
- `tools/gdstyle_baseline.txt` 禁实现批中途刷新——批末由用户人工重生成(第 6 节)。
- `_on_tune_simulate` 运行态早退守卫——不收件(+1 行为面、system_test 前置断言随之需复核,代价大于收益,设计文档待裁点 3 否决)。
- `design/` 整个目录、两份根流程清单——实现批禁写;该改的点列反哺点清单。`game/tests/README.md`:测量面专属能力行已随本卡 v1.0 写卡段同批入表(「调参测速批量模拟」行),实现批禁写红线不变。
- 探针其余段与套件其余断言族(standee_fx_sweep 的 wd2/wd4/wd5/wd12 面)零触碰;`architecture.md` 其余豁免条目(battle_orchestrator 第三条注销句现状化归战斗编排归约批反哺点)零触碰。
## 6. 关联文档同步面
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|---|---|---|
| design/engineering/architecture/architecture.md | 「测试与质量域」S13 测量面豁免注销句(v1.25——「设计闭合、实现批建件」批后现状化;句保持——注销对象是 await 豁免、不依赖行为改动申报;句内「随批申报行为改动一处(收尾置假还原)」半句已失效〔前提被迭代 41 消化、申报已剥离〕,现状化时一并修正为收尾现行陈述) | 设计权威文档——实现批禁直改;逐条列进 `reports/iter44-反哺点-2026-10-30.md`(豁免注销句现状化,该清单 #6 已登记暂停点、随本卡 v1.1 恢复),用户裁决后归文档批落文 |
| game/tests/README.md | 能力表——测量面专属能力行「调参测速批量模拟(逐帧步进与统计读数)」已随本卡写卡段同批入表(真实入口=批量模拟入口,代表用例=本卡对拍套件);manifest 计数行随套件增减浮动(自助声明,零义务) | 机械面文档——实现批禁写;入表已完成于写卡段(本卡 v1.0 同批),实现期零改动 |
| tools/gdstyle_baseline.txt | tune_sim await-in-loop 裸键(:15,该文件唯一在册键)随键消失成死键 | 重生成为人工专用——批末由用户执行 `python tools/gdstyle_gate.py --refresh`(键数 16→15,降幅 <10% 不需 --force);禁实现批中途刷新 |
| design/gdd/(全目录) | 无关联文档——测量工具私有机制改造,不改游戏规则与玩家可见行为(tune_sim 全链路发布态不可达,设计文档 §7.3) | 无修订预期;契约句被触碰=停卡呈报走反哺点通道 |
## 7. 卡前文件结构图(本批新建/修改文件全列)
| 文件 | 新增/复用 | 职责 | 行为改动 |
|---|---|---|---|
| game/presentation/tune_sim_controller.gd | 复用(改造) | 批量模拟控制器——process_frame 信号常驻连接+步进状态机;收尾单点 `_finish_batch`(四语句同帧同相位迁入);全文件零循环 | 非行为改动(结构改形——收尾语义零变化,零漂移由对拍证;回归锚面=对照表 V3 行) |
| game/tests/unit/presentation/tune_sim_batch_parity_test.gd | 新增 | 双实现对拍配对套件——现行 await 形态夹具(内类,收尾在 run() 尾的现行形态)+五面对拍断言 | 非行为改动(测试面) |
| game/tests/run_all.gd | 复用(改造) | manifest 增一行(新套件注册,expect 0) | 非行为改动(测试基建) |
结构图与第 8 节互指:新增件一件(对拍套件),其「为什么不能复用/落点唯一」理由见第 8 节;其余两行均为既有文件改造。行为改动列全为零——每行的验收落点见对照表 V1/V2/V3 行。
## 8. 落位与可复用性预检
- **步进状态机不引入新文件(本件内改造)——为什么不拆新件**:单一职责已在件内——`tune_sim_controller` 的职责就是批量模拟控制,步进机制(每帧一局的节律与帧相位承载)是它的私有运行机制,随批生灭(run 期活成员,批末失效下次 run 重写),没有独立于批量模拟的存在意义;拆出「步进机」件命不出独立职责语句=凑计数袋(code-conventions §1.1 判据②④禁)。复用面核查:全仓 grep 无信号步进机同职责实现可复用;其余四形态(SceneTreeTimer 链/Timer 节点/递归协程/线程)已被设计文档 §3 逐一否决(相位不同或键不消)。
- **对拍套件落 `game/tests/unit/presentation/` 的唯一性与命名**:落点唯一——与断言宿主 wd8 同目录同协议(extends SceneTree+Kit 收尾),单元层承载;命名 `tune_sim_batch_parity_test.gd`(领域命名、无 ID 前缀);grep 同名与同义标识符实查无第二处。**遗留 await 形态副本全仓只许此一份**——产品码禁留第二实现(旧形态只活在测试夹具内);tests/ 不在 S13/S8/S9/S10 扫描面(扫描面=产品码三目录与 S8 文件集,实查在案),夹具内循环 await 合法在册。
- **复用面**:夹具的假面板/假驱动复用 wd8 的形态先例(FakePanel/FakeDriver 同形——代码在各套件内自建,不跨套件共享 helper,禁散落);收尾复用 `test_kit.gd` 的 Kit.finish(零断言专用退出码协议)。
- **分层与交互**:控制器保持 RefCounted、零 Node 入树;process_frame 连接经 `panel.get_tree()` 取树(与现状同一出口);对拍套件 `--script` 模式零 autoload 依赖(db 用字典夹具,同 wd8 :142 先例);零新增跨层出口、零数值表读取、零随机。
## 9. 实现规范预算(gdstyle 默认阈值对账:公开方法 ≤20、类变量 ≤15、单函数分支 ≤8、返回 ≤6、参数 ≤5、局部 ≤10、函数 ≤50 行)
本批零新增产品码文件(改造 `tune_sim_controller.gd` 本件)——改造后该文件键账预期(设计文档 §6 逐规则落卡):
| 规则 | 预期 | 依据 |
|---|---|---|
| quality/await-in-loop(裸键,本案标的) | **消除** | 全文件零 for/while;await 仅 `run()` 函数级一处(`await _batch_finished`)——结构性免疫 |
| quality/allocation-in-loop | 不命中 | 文件零循环;`PlaytestLogger.new()` 在 run 顶层(现状即如此) |
| max-function-length ≤50 | 达标 | run 约 22 行、`_step_frame` 约 12 行、`_finish_batch` 约 6 行、`_run_one_level` 现行 11 行零触碰 |
| max-branches ≤8 | 达标 | `_step_frame` 一个 if/else;run 一个 if/else |
| max-local-variables ≤10 | 达标 | run 局部 3(logger/stats/autoplay——余者转成员);`_step_frame` 局部 1 |
| max-returns ≤6 | 达标 | 全 void |
| max-parameters ≤5 | 临界持平 | `_run_one_level` 5 参逐字保持;两个新函数 0 参 |
| max-class-variables ≤15 | 达标 | 现 5+新增 6=11(`_batch_finished` 信号若被工具计入成员则 12——两值均达标;成员皆 run 期活承载,非凑数袋) |
存量触面一查:基线实查该文件唯一在册键=await-in-loop 裸键(`tools/gdstyle_baseline.txt:15`)——S13 键较登记值只降不升,裸键消失即清偿;死键由批末用户人工 `--refresh` 自然清去(16→15,降幅 <10% 不需 --force)。新增测试件不在 S13/S9/S10/S8 扫描面(第 3 节实查在案);仍按 test-conventions §6 全类型标注自律(参数/返回值/容器全带标注)。
## 10. 禁为机检文本保留无效成员(重构类卡必填条款)
禁止为迎合 S13 机检消息文本(含计数)保留或新增无效成员/别名;本批新增 6 个 run 期活成员皆为 `_step_frame`/`_finish_batch` 读写的承载(`_finished` 若实现期确认零读者,可删——见第 14 节白名单 3,成员 11→10 键账只降不升);机检键与卡片契约互斥时,实现段一律停卡呈报,不得自造第三条路。
## 11. 任务卡 T0..T3(估时为区间;工作量限制只属迭代层——合计 1–1.5 工作日)
**T0 现状复核与读数重锚(0.25 工作日)**
- [ ] 实跑 wd8 单套件(开发期最窄确认,不作验收凭据):`godot --headless --path game --script res://tests/run_all.gd -- --only=standee_fx_sweep`——记录 :145-147 三断言实况,**应绿**(绿=前提已被迭代 41 测试债批消化,按无行为改动形态开工)。套件若因在册无关债先红于 wd8 断言,先核该债修复状态、不得借本批顺手修非申报面——读数以「wd8 断言可达性」为准呈报(L2 记录)
- [ ] 实跑 ui_tune_probe 单探针:`…console.exe --headless --path game res://probe/ui_tune_probe.tscn`——记录 ⑤ 守卫环与输出四串实况,**应在**
- [ ] 判读:两面实跑全绿=重裁前提成立开工;任一面红=现状与重裁前提失配(迭代 41 修复被回退或新潜伏红)——L3 停卡呈报(第 13 节)
- [ ] 按当轮施工基面重锚第 3 节全部 file:line 与成员计数;漂移处就地改卡并记录(本卡行号基线=2026-10-30 master;同迭代卡①改址过 main_debug_flow/ui_tune_probe——两件相关行实测未漂移,仍以 T0 重锚为准)
- [ ] 实查产品码 process_frame 订阅面——预期两处(本件 :50+settlement_fx_view.gd:94);出现 run 途中新增订阅者场景=L2 记录+代码评审注记(设计文档 §5 缺口 2)
产出:现状复核读数(两面绿——前提消化链条的当轮证据,独立验收审计要核对);重锚后行号。
**T1 步进状态机改造(0.25–0.5 工作日)**
- [ ] `tune_sim_controller.gd` 头注增 `_batch_finished` 信号契约一行(code-conventions §2.1——每信号一行:发射时点=报告注入与运行态复位之后;消费方=run() 自身收尾放行,外部 `await run(n)` 经此放行;现 4 行→5 行;禁变更叙事句)
- [ ] 增 `signal _batch_finished` 与 6 个 run 期活成员(名字按设计文档 §4.1 逐字:`_sim_n: int`/`_sim_i: int`/`_sim_stats: Dictionary`/`_sim_autoplay`/`_sim_logger`/`_finished: bool`)
- [ ] `run(n)` 改形:setup 段(:37-46 语句逐字保持);n>0 分支——`is_connected` 守卫 connect `panel.get_tree().process_frame`(恰好连接一次,迭代 39 先例)→ `_step_frame()` 首步同步执行(与 await 形态「第 0 局在调用栈内跑完」对齐)→ `await _batch_finished`(函数级单次 await——键消除落点);n=0 分支直调 `_finish_batch()`(循环零进同步收尾,与 await 形态一致不挂起)
- [ ] 新增 `_step_frame() -> void`(0 参):`_sim_i < _sim_n` 分支——`_run_one_level(_sim_autoplay, _sim_stats, _sim_i, panel, _sim_logger)`+`panel.set_sim_progress("模拟中:%d/%d …" % [_sim_i + 1, _sim_n])`(串逐字保持现码 :49)+`_sim_i += 1`;else 分支——先 disconnect(防再入)→ `_finish_batch()` → `_batch_finished.emit()`
- [ ] 新增 `_finish_batch() -> void`(0 参):收尾四语句由 run() 尾 :51-54 迁入(`close_session()`→报告注入→`panel.set_sim_running(false)`→`_running = false`,同帧同相位——判据③;`_finished = true` 置位为新增首句,对两断言面不可观测——白名单 5)
- [ ] `_run_one_level` **零触碰**(:58-68 逐字保持——败局节点记账非置假;本批行为零改动的锚面)
- [ ] 孤立验证:`--only=standee_fx_sweep` 全绿(wd8 三断言零改动保持绿=收尾语义零变化实证)+ui_tune_probe 单探针绿(probe_gate --full 段承载)
- [ ] 自检:新增头注/注释零变更叙事、S11 禁词零命中
取用:T0 重锚行号。产出:`_batch_finished` 信号与 `_step_frame`/`_finish_batch` 签名(T2 对拍新形态即产品码本体);wd8 保持绿读数。
**T2 双实现对拍夹具(0.25–0.5 工作日)**
- [ ] 建 `game/tests/unit/presentation/tune_sim_batch_parity_test.gd`(extends SceneTree,Kit 收尾,全类型标注):内类 FakePanel(Node——wd8 同形 setter 面,另带进度串/报告记录数组)+FakeDriver(RefCounted——固定返回值两档〔victory/defeat,同 wd8 :53-55 取值〕,零随机;逐局记录帧索引与运行态读数,帧索引经宿主注入的计数 Callable 读取)+AwaitLoopRunner(RefCounted——现 `run()` await 形态逐字副本,含循环内 await 与收尾四语句在 run() 尾的现行形态(:47-54 语句逐字),含自身 `is_running()` 镜像;**与产品码新形态的申报差异仅一处**:批末把 stats 六键束存夹具成员供对拍读取——产品码 stats 经报告公开面观测,第 17 节直查受控例外申报)
- [ ] 对拍驱动:两形态各经 `run(n)` 真实入口驱动(新形态=真 TuneSimScript 直构,旧形态=夹具直构;同参假面板/假驱动各自实例);拓扑钉死——测试宿主先连 process_frame 帧计数、后启动两形态(两形态下「计数先于步进体」相对次序同构,序列可比);n=3 常规+n=0 退化两案
- [ ] 五面对拍断言(落点 `_init`,尾缀〔测速 V1〕..〔测速 V5〕):V1 帧索引序列——两形态逐局记录序列逐位相等(每步恰一帧+相位同点的执行证据);V2 运行态序列——驱动内 `is_running()` 读数序列逐位相等+收尾双运行态假相等;V3 进度串序列——面板记录的 set_sim_progress 串序列逐位相等;V4 stats 六键逐位——夹具暴露 stats 与测试内按假驱动固定返回值重算的六键期望(wins/dmg_all/hp_left_win/hp_boss/rounds_all/death_nodes)逐键相等;V5 报告全文逐字——两形态面板记录的 set_sim_report 串逐字相等,n=3 案含「关卡完成率/关卡完成剩余 HP 均/败北节点/N=」渲染面(n=0 案只断逐字相等——空 stats 渲染无剩余 HP 行,`_mean`/`_p90` 空守卫实查在案)
- [ ] `run_all.gd` manifest 增行 `{"path": "res://tests/unit/presentation/tune_sim_batch_parity_test.gd", "expect": 0}`
- [ ] 孤立验证:`--only=tune_sim_batch_parity` 绿+`--only=standee_fx_sweep` 复跑绿
取用:T1 的产品码新形态与 `_batch_finished` 放行语义。产出:五面对拍断言面(对照表 V1/V2 行验收主体)。
**T3 键账对账与收口(0.25 工作日)**
- [ ] S13 对账:`python tools/gdstyle_gate.py` 输出确认 tune_sim await-in-loop 裸键消失(消失键不参与红判定)、无基线外新键
- [ ] 关联档复跑:`--only=standee_fx_sweep,tune_sim_batch_parity`+ui_tune_probe(probe_gate --full 段)全绿
- [ ] 批末代码域闸全绿:`tools/run_all_gates.sh --code`(改动含 game/ 下非 .md 行为载体——`--code` 档)
- [ ] 错误路径声明缺口写入实现报告(第 4 节 🔴 条全文迁入——禁静默)
- [ ] 产出物落位卡:`reports/iter44-实现报告-2026-10-30.md`(各卡状态+实机目检总清单〔本批零目检项〕+遗留读数义务+实现决定记录)与 `reports/iter44-反哺点清单-2026-10-30.md`(第 6 节同步面逐条落点)写齐,方算收口
编队注记:本卡与零豁免其余三卡无产品码触面交集(本卡触面=tune_sim_controller.gd+game/tests/ 两件);run_all.gd manifest 行与并行批可能交叠——编队归编排段。本卡在 iter44 worktree 施工(卡①卡② 已收口冻结在分支),T0 重锚以 worktree 基面为准。
## 12. 验证闸——改动—验收对照表
域口径:本批改动全为 `game/` 下非 .md 行为载体——批末跑代码域闸;里程碑步(T 段)出口跑一次全套闸,波内修复只做出红最小单元的最窄确认,新增测试先行孤立验证再并入全套(测试执行两入口铁规不破)。三件保险(冒烟/系统测试/静态扫描)恒跑;02 单元与集成按关联档选套件——**本卡显式申报套件:standee_fx_sweep_test(wd8——套件名与涉案文件无字面关联,diff 推导可能漏选,特此申报)+tune_sim_batch_parity_test(新增)**。测试方式两分法:本批全部调试接口自动化(假驱动/假面板直构+真实按钮信号链探针),零用户目检项(tune_sim 全链路发布态不可达——登记不阻塞条款零登记项)。**静态判据申报(不入对照表,test-conventions §8.4 出口)**:S13 await-in-loop 裸键消除无独立运行期提交面——判据=`python tools/gdstyle_gate.py` 与 `game/tests/static_scan.sh` 退出码(T3 执行),属静态判据+评审注记申报观测面局限;对拍夹具不在 S13/S8/S9/S10 扫描面的声明同此口径(扫描面=产品码三目录与 S8 文件集,static_scan.sh 实查在案)。**声明缺口(不入对照表——证明做不出出口)**:脚本错误中断路径差异不可消除,见第 4 节 🔴 条,实现报告文档化(T3)。**能力清单**:本批新增能力一行「调参测速批量模拟(逐帧步进与统计读数)」已随本卡 v1.0 写卡段同批入表(README :131)——对照表三行能力列锚该行;manifest 计数行随套件增减浮动。
| 行 | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|---|
| V1 | 步进状态机改造(循环内 await 消除的落码面) | tune_sim_controller.gd :36-54 改形(run 函数级单次 `await _batch_finished`,全文件零循环;收尾四语句 :51-54 迁入 `_finish_batch`)+:58 起新增 `_step_frame`/`_finish_batch` | 复用 wd8 驱动形态 `await ctrl.run(2)`(:144——run 协程身份契约,零改动);新增对拍 V4/V5(stats 六键逐位+报告逐字,落点 tune_sim_batch_parity_test.gd:_init,尾缀〔测速 V4/V5〕) | 单元 | TuneSimScript 直构(字典夹具 db+假面板+假驱动,wd8 :142 同款)经 `run(n)` 真实入口;对拍两形态同入口 | run 可等待(await 挂起=整批完成放行)+stats 六键逐位+报告全文逐字 | 新增:调参测速批量模拟(逐帧步进与统计读数) |
| V2 | 双实现对拍(帧相位等价的执行化证据) | tune_sim_batch_parity_test.gd 新建+run_all.gd manifest 增行 | 新增五面对拍断言〔测速 V1–V3〕:帧索引序列/运行态序列/进度串序列逐位相等(落点 tune_sim_batch_parity_test.gd:_init) | 单元 | 两形态各经 `run(n)` 真实入口(n=3 常规+n=0 退化);帧索引经测试宿主 process_frame 计数 | 两形态五面记录序列逐位相等(每步恰一帧+相位同点的当轮执行证据——判据本体) | 新增:调参测速批量模拟(逐帧步进与统计读数) |
| V3 | 运行态语义零变化(收尾迁移的回归锚面——非行为改动行) | 收尾四语句(:51-54)迁入 `_finish_batch` 同帧同相位——非行为改动判断依据:语句集与语义零变化、对两断言面不可观测,等价证据由对拍 V2/V5 承载;`_run_one_level` :58-68 零触碰 | 复用 wd8 三断言〔wd8〕(:145-147——`drv.seen == [true, true]`/收尾双运行态假/报告非空——零改动**保持绿**)+ui_tune_probe ⑤ 守卫环与输出四串(:63-83——零改动保持绿) | 单元+探针 | wd8 假驱动回调读 `is_running()`(`await ctrl.run(2)`);探针 `press_simulate_for_probe()` → 按钮 pressed 信号链 → `run(10)` → 守卫环逐帧复查 | 驱动逐局运行态读数序列 [true, true]+收尾双运行态假+守卫环 1800 帧预算内退出+`output_text()` 四关键串(浮窗运行态贯穿整批的可观测提交面——绿=保持绿,非转绿) | 新增:调参测速批量模拟(逐帧步进与统计读数) |
反向核对:diff 中行为改动共零处;其余为非行为改动——V1 结构改形(零漂移判据=对拍五面全等+wd8/probe 零改动保持绿)、V2 测试面新增、V3 回归锚面行(非行为改动)、manifest 增行(测试基建)。孤儿断言:对拍五断言挂 V1/V2 两行,wd8/probe 既有断言挂 V3 行,无孤儿。
## 13. 异常分级
- **L1 自救**:编译错、断言尾缀措辞、夹具记录数组名笔误——就地修复,重跑最窄单元确认。
- **L2 记录继续**:T0 套件因在册无关债先红于 wd8 断言(记录可达性事实,不借批顺手修);行号重锚漂移(就地改卡记录);产品码 process_frame 订阅面发现第三处(记录+评审注记——非 run 途中新增场景不红)。
- **L3 停机写报告等用户**:①T0 两面任一红=现状与重裁前提失配(迭代 41 修复被回退或新潜伏红),停卡呈报;②等价性对拍失败——五面任一不等=测量语义漂移,设计前提崩塌;③机检预算互斥——改造后实测键超第 9 节预算或基线外新键=上游缺陷停卡退回写卡段(含禁为机检保留无效成员条款冲突);④S13 对账 await 键未消或冒新键;⑤判据绑不上可观测提交面(证明做不出=停卡呈报,禁自造注入破坏或回退取证)。
## 14. 代拍板白名单(逐条列,超清单记实现报告「实现决定记录」)
1. 断言失败消息尾缀〔测速 V1–V5〕的分配与措辞。
2. 头注 `_batch_finished` 契约行措辞(信号语义与发射时点不变)。
3. `_finished` 成员零读者确认后删去(成员 11→10——键账只降不升,行为与断言面零变化)。
4. 夹具假面板/假驱动成员命名微调(记录语义不变;与 wd8 同形自建、不跨套件共享)。
5. 收尾段语句相对次序——现行 run() 尾次序(close→报告→置假→_running)与设计草图次序(close→置假→_running→报告)对两个断言面均不可观测,两种皆可落码(实现期查 git 历史原序可进一步对齐);`_finished = true` 置位为新增首句(成员写,不可观测)。
6. 排版机械改写(空行、preload 顺序、注释换行)。
## 15. 待裁点
零待裁点,开工门=U0。(裁决记录:2026-10-29 用户裁四点——①信号步进状态机形态采纳〔SceneTreeTimer 链/Timer 节点/递归协程/线程四形态淘汰依据见设计文档 §3〕;②收尾置假还原作为已申报行为改动随批实施【已作废——前提被迭代 41 测试债批 215da315 消化,v1.1 剥离】;③双实现对拍入批;④脚本错误中断路径差异接受并文档化。2026-10-30 停卡重裁(用户裁,按停卡呈报建议案逐条落卡):剥离行为改动申报 V3、T0 义务改现状复核、夹具申报差异两处减一处;重裁沿用 2026-10-29 grilling 复核门结论(reports/复核-grilling-零豁免五卡-2026-10-29.md,修正全落),重裁差异面未新增设计裁决。)
## 16. 测试削弱申报
无申报项——wd8 三断言与 ui_tune_probe ⑤ 零改动零削弱(保持绿);对拍五断言为新增非改判;夹具与产品码新形态的申报差异仅一处(夹具暴露 stats 供对拍读取)系新增件自身设计、设计文档 §5 在案,非既有断言削弱。禁删断言、禁放宽阈值、禁缩小扫描面、禁把真实入口换成下层直调;未申报的削弱由独立验收审计判红。
## 17. 独立验收审计
合并前由未参与实现的会话或子代理执行;报告落 `reports/iter44-验收审计-2026-10-30.md`,未过不得合并。审计至少做五件事:①逐行核对第 12 节对照表(测试存在、真的执行、尾缀可 grep、真实入口未绕过改动点);②抽查判据绑定面——帧索引序列是否真从 process_frame 发射点记录、对拍拓扑两形态是否同构可比、V3 行判据是否钉在运行态提交面(保持绿证据,非终态兜底);③核对现状复核证据在案(T0 两面实跑绿读数+停卡呈报三重证据引注〔215da315 提交信息〕——前提消化链条完整,缺 T0 复核读数=审计不过);④核对行为改动零处——diff 中任何行为改动(含收尾四语句语义漂移)=审计不过,收尾迁移的等价性由对拍 V2 运行态序列+V5 报告逐字承载;⑤检查测试削弱(对照第 16 节零申报)与内部字段直查受控例外(本批零直查——新形态 stats 经报告公开面观测)。
## 18. MC/数值与 RNG 零触碰声明
本批零数值改动、零数据表改动、零 RNG 流变化:SEED_BASE=4200 与逐局种子切分零变化(stats 种子纯函数前提);对拍夹具零随机(假驱动固定返回值)。MC 对拍不跑、零跑批义务(无数值改动——`sim-data/README.md` 档位硬闸:无数值改动零跑)。
@@ -1,188 +0,0 @@
# 需求卡片——站桩名字行提档与地台色合并批(名字行字号 12→14 + 受光线/描边两常量退役改指)
状态行:v1.1 定稿——零待裁点(grilling 复核过:reports/复核-grilling-站桩名字行提档与地台色合并批-2026-10-31.md,三阻断两建议全落;两点裁决已于 2026-10-31 闭合落文 art-bible v3.29,见 §11)
接收方:待办清单条目「迭代 43 批后待裁两点——名字行字号档位/换色常量退役」(状态=文档设计已闭合,本卡写完推进「已写卡」)
来源:**设计事实源**=`design/art/art-bible.md` v3.29——§7.4 小字号豁免条款「站桩名字行同理提档」句(名字行提档 `FS_HINT` 14 归六档、不增列②装饰 caption 在册面、几何随档联动)+§4.1 换色合并登记三处①②(`#C4AC84`→并入掩尘 `#C9AF83`;`#5A4C3A`→并入 `#4C4038`)。验收底线(2026-10-31 用户裁)=名字行清晰可读、长名不截字。
## 1. 目标与完成定义
这批做什么:把 art-bible v3.29 两处新裁决落进代码——①站桩名字行(敌人名+护甲字形+全部宽度测量与基线)从 `FS_CAPTION`(12px)提到 `FS_HINT`(14px),名字行几何随档联动;②`STAND_STONE_RIM`/`STAND_STONE_EDGE` 两枚旧色常量删除,两个绘制点改指合并目标色(站桩石板顶缘受光线与棋盘墙格口沿高光共用枚→掩尘 `BRICK`;石板描边→新常量承载 `#4C4038`),使贴图缺位时的程序化回退绘制与已落合并值的贴图一致。顺带了结迭代 43 移交小件①(能力清单补行——写卡段随本卡同批入表)。
完成定义(全部满足才算完):
1. 名字行五处取值点全取 `UiKit.FS_HINT`,基线偏移按 14px 档重算(0.35h 规则→牌顶+18),素底牌几何单点 `_name_plate_rect`/`_name_baseline` 仍是唯一算式落点。
2. `STAND_STONE_RIM`/`STAND_STONE_EDGE` 在 `ui_kit.gd` 删除且全仓零引用;`UiKit` 脚本常量表断言两枚不在册。
3. 两枚绘制点改指:`cell_base_layer.gd` 口沿高光与 `standee_body.gd` 顶缘受光线→`UiKit.BRICK`;`standee_body.gd` 回退描边→新常量 `UiKit.PLAZA_EDGE`(=Color8(76,64,56))。
4. 渲染 golden 三张板面基线与口沿高光换值一致(改后跑 render_gate,红则重锚三张、重锚后 0.00% 留痕;level_map/menu_boot 不触不重锚)。
5. 能力清单补行落表(`game/tests/README.md` 能力行+覆盖域表战斗表现.md 行,本卡成文同批完成)。
6. 代码域闸全绿;产出物三份落 `reports/`,独立验收审计未过不合并。
## 2. 现状事实
全部行号为 **2026-10-31 实查**——编入后 T0 按 T0 时点 master 重测重锚。
1. 名字行字号取值点五处,全在 `game/presentation/views/standee_body.gd`:`:334-335` 护甲字形宽测量(贴图缺位时)、`:336` 名字宽测量(`_name_plate_rect` 内)、`:467` 护甲字形宽测量(绘制侧)、`:474` 护甲字形绘制、`:476` 名字绘制——全取 `UiKit.FS_CAPTION`。
2. 同文件另有 `FS_CAPTION` 合法在役一处:`:114` 站桩消散提示(§7.4 ②在册面「站桩消散提示」)——本批不动,禁误改。
3. 名字行几何单点:`_name_plate_rect`(`:331-338`,牌高 26 固定=护甲图标 24px+上下各 1px;牌宽=行宽+8 水平居中;牌底沿=地台顶)+`_name_baseline`(`:342-343`,返回 `plate.position + Vector2(4.0, 17.0)`;注释 `:341` 「12px 字形基线=中心+4」)。基线偏移遵循本文件既有 0.35h 规则(立绘字形 `:434` 用 `ts.y * 0.35`;12×0.35≈4.2→4,与 `+4` 吻合)→14×0.35≈4.9→**5**,新基线=牌顶+13+5=**牌顶+18**。
4. 名字行探针 `name_line_probe()`(`standee_body.gd:63`)返回 Dictionary:`baseline_y`/`plinth_top_y`/`plate`/`plate_color`/`armor_icon`/`armor_tex_bound`——消费面=`ui_struct_probe` 与 `standee_present_values_test`。
5. 地台程序化回退(`standee_body.gd:380-383`):`TEX_STAGE_PLAZA` 缺位时三段绘制——板身 `UiKit.STAND_STONE`、描边 `UiKit.STAND_STONE_EDGE`(`:382`)、顶缘受光线 2px `UiKit.STAND_STONE_RIM`(`:383`)。贴图在位时不走此路径(九宫格拉伸域 `:388-393`,贴图已落合并值 `#C9AF83`/`#4C4038`)。
6. 口沿高光:`game/presentation/views/cell_base_layer.gd:176` `canvas.draw_rect(..., UiKit.STAND_STONE_RIM, true)`(墙格南立面受光亮线,线厚常量 `FACADE_HIGHLIGHT_PX := 2.0` 于 `:9`;与地台顶缘线共用同枚常量,行内注释「同值单点」)。设计出处=art-bible §8.2 高墙瓦片体系条(南临空墙格=立面口沿高光 2px `Color8(196,172,132)`)。
7. `ui_kit.gd`:`:188` `STAND_STONE_EDGE := Color8(90, 76, 58)`、`:189` `STAND_STONE_RIM := Color8(196, 172, 132)`;合并目标①=`BRICK := Color8(201, 175, 131)`(`:165` 掩尘,在役);合并目标②=`#4C4038`=Color8(76,64,56)——**全仓无既有 token**(2026-10-31 grep `Color8(76` 零命中),需新常量承载。
8. 全仓 `STAND_STONE_RIM`/`STAND_STONE_EDGE` 引用面=定义 1 处+消费 2 文件 3 行(`:382`/`:383`/`cell_base_layer:176`)——tests/probe/sim 零引用(grep 实查),删除无隐性断裂。
9. 既有断言面 `game/tests/unit/presentation/standee_present_values_test.gd`:V6 硬编码几何读数 `baseline_y=149.0`/`plinth_top_y=158.0`(±0.51);V7 源码锚 `contains("HORIZONTAL_ALIGNMENT_LEFT, -1, UiKit.FS_HINT")`(contains 语义——名字行改 `FS_HINT` 后仍绿,零破坏);V5 先例=「绘制点取某常量」用源码锚承载。
10. golden 触面:`game/tests/golden/` 板面三张(board_L1_dungeon/L2_underdark/L3_deep_underdark)渲染含墙格口沿高光像素——换值后逐像素比对必红;载体=`tools/render_gate.sh`(闸 05,窗口化)+重锚工具 `tools/golden_baseline_refresh.sh`。level_map/menu_boot 与站桩名字行均不在 golden 像素域。
11. 能力清单:`game/tests/README.md` 无 `standee_present_values_test` 代表用例行(迭代 43 移交小件①在册待补,登记规格=能力「站桩呈现定值与素材绑定」/真实入口 `UiKit.load_tex()`/`StandeeBody.name_line_probe()`/代表用例 `standee_present_values_test.gd:_init`)。本会话即写卡会话,随本卡同批补行(§5)。
12. gdstyle:`standee_body.gd` 无基线登记键(迭代 44 收尾 refresh 已清偿);本批零新增成员/函数,S13 预期零新增键。
## 3. 设计契约(违反即返工,标 🔴 触碰=L3 停机呈报)
- 🔴 **两个 12px 位不得混**:`FS_HINT` 只进名字行五取值点;`:114` 站桩消散提示的 `FS_CAPTION` 是 §7.4 ②在册面合法位,禁顺手改。
- 🔴 **合并目标逐位**:受光线绘制点→`UiKit.BRICK`(`#C9AF83`),描边绘制点→`UiKit.PLAZA_EDGE`(=Color8(76,64,56));禁改 `BRICK` 值、禁引入任何近似替代值。
- 🔴 **`STAGE_BG` 零触碰**:§4.1 ③已裁随舞台背景插画批处置——本批不改 `STAGE_BG` 值、不改 `battle_stage_view`、不动 `theme_projection_test.gd:669` 与 `ui_contrast_probe.gd:30`。
- 🔴 **几何单点**:字号与基线联动只落在 `_name_plate_rect`/`_name_baseline` 两个既有单点内;探针、测试、任何调用方不得复写算式。
- 🔴 **常量退役=真删**:`STAND_STONE_RIM`/`STAND_STONE_EDGE` 删除后禁留别名、转发常量或空注释占位(禁为机检保留无效成员)。
- 🔴 **golden 重锚申报制**:三张板面基线重锚仅限口沿高光换值所致,重锚前后读数留实现报告;禁借重锚夹带其他像素变化。
- 🔴 **测试削弱申报制**:允许改动的旧断言全集见 §8 申报节,未申报的删改由独立验收审计判红。
- 🔴 **禁变异类测试与撤销类取证**:不得靠回退 hunk 或注入破坏证明断言有效。
## 4. 范围边界
做:名字行五取值点提档+基线重算+探针增 `name_font_size` 键;`ui_kit.gd` 删两常量+增 `PLAZA_EDGE`;三处绘制点改指;golden 三张板面重锚;既有 V6 读数换代;能力清单补行(写卡段,本卡成文同批)。
不做(明示去向):
1. **`STAGE_BG` 改值**——随「战斗区背景图替换」批(art-bible §4.1 ③改注在案)。
2. **`:114` 消散提示与②在册面其他位**——合法 caption 档,零触碰。
3. **口沿高光独立语义 token 化**——拆枚是命名扩张,值同源且 art-bible 已裁「统一为同一枚」,禁另立。
4. **battle.md/art-bible 直改**——实现批禁写 `design/`;§4.1 源常量名退役后的指称换代走 §5 反哺点通道。
5. **长名截字的主动钳制逻辑**——现行无钳制,本批不新增行为;若目检发现截字=产品面问题走 L3 停卡呈报。
6. **MC/数值验证**——无数值改动零跑。
## 5. 关联文档同步面
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|---|---|---|
| design/art/art-bible.md(设计权威——实现批禁直改) | §4.1 换色合并登记①②句中「代码 `STAND_STONE_RIM`/`STAND_STONE_EDGE`」指称随退役失指;②合并目标 `#4C4038` 需补代码名 `PLAZA_EDGE`;§8.2 口沿高光行「`Color8(196,172,132)`」值随换值换代 | 反哺点通道:逐条列进 `reports/iter<N>-反哺点-<日期>.md`(改哪一节、改成什么、依据=本卡与实测读数),用户裁决后归文档批落文 |
| design/art/art-bible.md §7.4 | 无(提档句 v3.29 已落文,实现后即为合规态) | 无(本行占位——按规约查不出也要写明) |
| game/tests/README.md(机械面——归写卡段维护) | 能力行补行「站桩呈现定值与素材绑定」(迭代 43 移交小件①)+覆盖域表战斗表现.md 行补名 | 写卡段于本卡成文同批入表(已完成),实现批零增删零改行;批末核对表上名字与实况一致 |
| design/gdd/ux/battle.md | 无——`:155` 名字行陈述(纯名字+护甲类型图标)不涉字号与色值 | 无(本行占位) |
## 6. 卡前文件结构图
| 文件 | 职责 | 新增/复用 | 行为改动? |
|---|---|---|---|
| game/presentation/views/ui_kit.gd | 删 `STAND_STONE_EDGE`/`STAND_STONE_RIM` 两常量;原位新增 `PLAZA_EDGE := Color8(76, 64, 56)`(注释=art-bible §4.1 ②合并目标·小石台描边回退用色) | 修改 | 是(色值换——对照表行 3/4) |
| game/presentation/views/standee_body.gd | 名字行五取值点 `FS_CAPTION`→`FS_HINT`;`_name_baseline` 偏移 17.0→18.0+注释换代;回退描边 `:382`→`PLAZA_EDGE`、顶缘线 `:383`→`BRICK`;`name_line_probe` 增 `name_font_size` 键 | 修改 | 是(行 1/2/3/4) |
| game/presentation/views/cell_base_layer.gd | 口沿高光 `:176`→`UiKit.BRICK`+行内注释换代 | 修改 | 是(行 3) |
| game/tests/unit/presentation/standee_present_values_test.gd | 增 V10–V12 断言(提档/退役/新 token);V6 基线读数 149→150(申报) | 修改 | 是(测试面——行 1/2/3/4) |
| game/tests/README.md | 能力行补行+覆盖域表战斗表现.md 行补名 | 修改 | 否(机械面文档,写卡段同批完成) |
| game/tests/run_all.gd | 套件登记注释「V5–V9」→「V5–V12」换代 | 修改 | 否(注释换代,非行为改动) |
不触碰:`battle_stage_view.gd`、`board_view.gd`、`theme_projection_test.gd`、`ui_contrast_probe.gd`、`data/tables/` 全部、`core/` 全部。
## 7. 任务卡 T0..T3
### 7.1 T0——读数重锚与改前基线(估时 0.1 个工作日)
- [ ] 重锚 §2 全部行号(standee_body/cell_base_layer/ui_kit/test 五文件);复核实查结论第 7 条(`#4C4038` 无既有 token)与第 8 条(引用面仅三行)——不符=L3 停卡退回写卡段。
- [ ] 改前读数(孤立验证):单件跑 `standee_present_values_test`(绿)+`python tools/gdstyle_gate.py`(三触面文件零新增键、既有键持平)+窗口化跑 `tools/render_gate.sh`(板面三张绿=改前基线确认,读数进实现报告 T0 节)。
- [ ] 字体度量校验:`f.get_string_size("名", HORIZONTAL_ALIGNMENT_LEFT, -1, 14)` 实测 Fusion Pixel 14px 高度,核对 0.35h 推导(≈5);若实测推导出不同偏移,按实测定值并记实现报告「实现决定记录」。
- 取用:本卡 §2。产出:重锚行号+三份改前读数+基线偏移定值(T1/T2 对拍基准)。
### 7.2 T1——名字行提档(估时 0.15 个工作日)
- [ ] `standee_body.gd` 五取值点(`:334-335`/`:336`/`:467`/`:474`/`:476`)`UiKit.FS_CAPTION`→`UiKit.FS_HINT`;`:114` 消散提示零触碰。
- [ ] `_name_baseline` 返回 `plate.position + Vector2(4.0, 18.0)`;`:341` 注释改「14px 字形基线=中心+5(0.35h 规则,T0 实测校验)」。
- [ ] `name_line_probe()`(`:63`)返回字典增键 `"name_font_size": UiKit.FS_HINT`(值出自几何单点所用字号常量)。
- [ ] `standee_present_values_test.gd` 增三断言(尾缀〔名字行 V10〕):①probe 面——`int(nl.name_font_size) == UiKit.FS_HINT`(几何单点实读);②源码锚——`body_src.contains("HORIZONTAL_ALIGNMENT_LEFT, -1, UiKit.FS_HINT, UiKit.WARM")` 且 `body_src.contains("HORIZONTAL_ALIGNMENT_LEFT, -1, UiKit.FS_HINT, col")`(名字/护甲两绘制点,沿 V7 先例);③计数锚——`body_src.count("UiKit.FS_CAPTION") == 1`(改后全文件仅剩 `:114` 消散提示一处——三处宽度测量点随此锚强制换代)。
- [ ] V6 基线读数 149.0→150.0、判据句「地台顶上方 9px 档」→「8px 档」(§8 申报第 1 条)。
- [ ] 孤立验证:单件跑 `standee_present_values_test`(V5–V10 全绿)+`python tools/gdstyle_gate.py`(standee_body 键只降不升)。
- 取用:T0 重锚行号与偏移定值。产出:`name_font_size` 探针出口(T3 对照表行 1 判据面)+绿的单件日志。
### 7.3 T2——地台色合并(估时 0.15 个工作日)
- [ ] `ui_kit.gd` 删 `:188`/`:189` 两常量;原位新增 `const PLAZA_EDGE := Color8(76, 64, 56)`,注释「小石台描边(art-bible §4.1 换色合并②合并目标——贴图已落此值,缺位回退同值)」。
- [ ] `standee_body.gd:382` `STAND_STONE_EDGE`→`PLAZA_EDGE`;`:383` `STAND_STONE_RIM`→`BRICK`;`:365` 附近回退注释「STAND_STONE 族」句随改。
- [ ] `cell_base_layer.gd:176` `STAND_STONE_RIM`→`BRICK`,行内注释「同值单点」句改「合并归掩尘枚(art-bible §4.1 ①)」。
- [ ] `standee_present_values_test.gd` 增两断言(尾缀〔名字行 V11〕〔名字行 V12〕;常量面载体=`load("res://presentation/views/ui_kit.gd").get_script_constant_map()`——经 Script 对象取常量表,`UiKit` 类引用直调 `get_script()` 不合法〔grilling 实测 parse error〕):V11=常量表无 `STAND_STONE_RIM`/`STAND_STONE_EDGE` 两键、`BRICK` 值=Color8(201,175,131)、源码锚 `body_src.contains("ped.size.x, 2.0), UiKit.BRICK, true")`(顶缘受光线)与 `cell_src.contains("FACADE_HIGHLIGHT_PX), UiKit.BRICK, true")`(口沿高光——`cell_src`=同法读 `res://presentation/views/cell_base_layer.gd`);V12=`PLAZA_EDGE` 值=Color8(76,64,56)(§4.1 ②合并目标逐位)+源码锚 `body_src.contains("UiKit.PLAZA_EDGE")`(回退描边)。
- [ ] `standee_present_values_test.gd` 文件头注释「V5–V9 断言面」句与 `game/tests/run_all.gd` 套件注释同步换代「V5–V12」(非行为改动)。
- [ ] 批内静态取证:`grep -rn "STAND_STONE_RIM\|STAND_STONE_EDGE" game/ tools/ --include="*.gd" --include="*.py" --include="*.sh"` 零命中,输出原文落实现报告(绘制点改指的观测面局限申报见 §8——色值进 draw 命令无运行期读出面,由「常量不在册断言+grep 零引用+PLAZA_EDGE 值断言」三件合成承载)。
- [ ] golden 改后比对:窗口化跑 `tools/render_gate.sh`——板面三张红(口沿高光换值所致)=预期证据,读数落实现报告。
- [ ] golden 重锚:跑 `tools/golden_baseline_refresh.sh` 重锚板面三张基线;复跑 `tools/render_gate.sh` 三张 0.00% 留痕;`level_map`/`menu_boot` 禁触(§3 重锚申报制)。
- [ ] 孤立验证:单件跑 `standee_present_values_test`(V5–V12 全绿)+`python tools/gdstyle_gate.py`(零新增键)。
- 取用:T1 产出与 T0 读数。产出:退役常量断言面+重锚后 golden 三张+grep 取证原文。
### 7.4 T3——批末收口与产出物落位(估时 0.1 个工作日)
- [ ] 批末代码域闸:`tools/run_all_gates.sh --code` 全绿(本批改动含 `game/` 下非 `.md` 行为载体);里程碑步出口跑一次全套;波内修复只做出红最小单元的最窄确认。
- [ ] 能力行核对:`game/tests/README.md` 能力行「站桩呈现定值与素材绑定」与覆盖域表战斗表现.md 行名字与实况一致(本卡成文时已落,实现批禁改)。
- [ ] **产出物落位卡**(轻闸全绿后、合并前写齐,方算收口):
- `reports/iter<N>-实现报告-<日期>.md`——各卡状态+T0 三份改前读数与改后对拍+grep 取证原文+golden 重锚前后读数+实机目检总清单(登记不阻塞三项:名字行清晰可读且长名不截字/墙格口沿亮线观感无异/贴图缺位回退描边与顶缘线观感无异)+实现决定记录。
- `reports/iter<N>-反哺点-<日期>.md`——§5 同步面 art-bible 两行逐条有落点。
- `reports/iter<N>-验收审计-<日期>.md`——独立验收审计(未参与实现的会话或子代理执行,未过不得合并)。
- 取用:T1–T2 全部产出。产出:代码域闸回执+三份 reports/ 产出物。
## 8. 验证闸(改动—验收对照表)
本批两处行为改动(名字行字号与几何、两枚色值换)+一节常量面退役;无新玩法验收。对照表 6 行对应 §1 完成定义第 1–4、6 条;第 5 条(能力行落表)经 T3 核对步承载(本卡成文时已落表)。能力行=**新增:站桩呈现定值与素材绑定**(本卡成文同批入表,见 §5)。
| # | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|---|
| 1 | 名字行字号提档 FS_HINT 14 | `standee_body.gd` 五取值点+`name_line_probe` 增 `name_font_size` | 「名字行绘制与几何取 FS_HINT」`standee_present_values_test.gd:_init`(〔名字行 V10〕) | 单元 | `godot --headless --path game --script res://tests/unit/presentation/standee_present_values_test.gd` | probe 几何单点实读 `name_font_size==UiKit.FS_HINT`+两绘制点源码锚+`FS_CAPTION` 计数锚==1(三处测量点强制换代,沿 V7 先例) | 新增:站桩呈现定值与素材绑定 |
| 2 | 名字行几何随档联动 | `_name_baseline` 偏移 17→18;V6 读数换代 | V6 既有断言更新值(〔样张批 V6〕,申报第 1 条) | 单元 | 同上 | `baseline_y=150±0.51`(牌顶+18)且 `< plinth_top_y`(文字不压地台判据不变) | 新增:站桩呈现定值与素材绑定 |
| 3 | 受光线常量退役改指 BRICK | `ui_kit.gd` 删 `STAND_STONE_RIM`;`standee_body.gd:383`+`cell_base_layer.gd:176` 改指 | 「退役常量不在册+掩尘值逐位」同套件(〔名字行 V11〕) | 单元 | 同上 | 常量表无该键+`BRICK==Color8(201,175,131)`+顶缘线/口沿高光两处源码锚(正证改指目标色);grep 零引用作反证补充(观测面局限申报:色值进 draw 命令无运行期读出面,正证由源码锚承载) | 新增:站桩呈现定值与素材绑定 |
| 4 | 描边常量退役改指新 token | `ui_kit.gd` 删 `STAND_STONE_EDGE`+增 `PLAZA_EDGE`;`standee_body.gd:382` 改指 | 「描边合并目标逐位」同套件(〔名字行 V12〕) | 单元 | 同上 | `PLAZA_EDGE==Color8(76,64,56)`(§4.1 ②目标逐位)+常量表无旧键+描边行源码锚;grep 零引用反证补充 | 新增:站桩呈现定值与素材绑定 |
| 5 | 板面 golden 与口沿高光换值一致 | golden 三张板面基线重锚 | `tools/render_gate.sh` 三张 0.00% | golden | 窗口化 `tools/render_gate.sh` | 重锚后逐像素零差留痕;level_map/menu_boot 零触 | 新增:站桩呈现定值与素材绑定 |
| 6 | 批末收口 | 全批 | 代码域闸 `tools/run_all_gates.sh --code` | 全量闸 | `tools/run_all_gates.sh --code` | 所选域全绿回执(`game/tests/.gates/receipt.json`) | 新增:站桩呈现定值与素材绑定 |
**测试削弱申报**(实现期允许的旧断言改动全集,超出即审计判红):
1. V6 基线读数 `149.0→150.0` 与判据句「9px 档→8px 档」——规格换代(字号 12→14,0.35h 规则推导),非放宽;文字不压地台判据(`baseline_y < plinth_top_y`)零改动。
2. 新增断言=纯增量;V5/V7/V8/V9 判据零改动(V7 源码锚 contains 语义,名字行改档后自动覆盖,零破坏)。
3. golden 三张板面重锚=有意色值换代的基线换代(§3 申报制),重锚前后读数留实现报告。
4. 显式禁止:删任何旧断言、改 `BRICK` 值、把探针/测试的字号读取换成别的入口。
**独立验收审计**:入口与报告=`reports/iter<N>-验收审计-<日期>.md`;审计方=未参与实现的会话或子代理,逐行核对对照表两端、抽查判据绑定面(`name_font_size`/常量表/`PLAZA_EDGE` 值)、核对削弱申报与 golden 重锚申报、确认全文无变异/撤销类取证;未过不得合并。
## 9. 异常分级
- **L1 自救**:单件跑红→定位该件最小单元修后重跑;`--only` 选跑零命中→修正选词重跑。
- **L2 记录继续**:同一红连续 3 次同因→在实现报告「实现决定记录」记因后继续最窄确认。
- **L3 停机写报告等用户**:
1. **机检预算互斥=上游缺陷停卡退回写卡段**——`gdstyle_gate` 出 NEW 键或既有键恶化;本批零新增成员/函数,任何键恶化都不许改基线换绿,禁开豁免。
2. **实机可读面本身不达标**——目检发现名字行截字、叠压血条或 14px 观感劣化;产品面问题停卡呈报,禁缩字号、禁加钳制逻辑凑绿(钳制=行为扩张,归新裁决)。
3. **改前实查与 §2 不符**——引用面超第 8 条清单、`#4C4038` 已有 token、或 V6 读数与实装几何不匹配且非字号所致。
4. **golden 重锚夹带**——重锚后 diff 域超出口沿高光像素带(含名字行字号变化渗入板面基线的可能——板面不含站桩,预期零渗入;若渗入=停卡呈报)。
## 10. 代拍板白名单(逐条列,超清单记实现报告「实现决定记录」)
1. 注释与断言消息文案措辞(判据、数值不变)。
2. `name_line_probe` 新键名(`name_font_size`)与其在返回字典中的位置。
3. 尾缀〔名字行 V10〕–〔名字行 V12〕字样编排(含义不变)。
4. T0 字体度量实测偏移与 0.35h 推导不一致时的定值(按实测,记录依据)。
5. `PLAZA_EDGE` 常量在 `ui_kit.gd` 的落位行与注释句。
## 11. 待裁点
**零待裁点,开工门=U0。** 两点裁决已于 2026-10-31 用户裁闭合并落文 art-bible v3.29(§7.4 名字行提档句、§4.1 换色合并登记句换代;舞台底 `STAGE_BG` 对已裁随背景插画批,不在本卡)。编批由迭代编排段定。
## 12. 落位与可复用性预检
**复用面**:本批零新增文件、零新增函数/类。既有复用——字号档位取 `UiKit.FS_*` 既有单点(§7.4 六档);受光线合并目标复用既有 `BRICK` token;断言承载复用 `standee_present_values_test` 既有套件与源码锚先例(V5/V7);golden 重锚复用既有工具 `golden_baseline_refresh.sh`;能力行补行沿迭代 43 移交小件登记规格,不另立能力名。
**唯一面**:新增常量 `PLAZA_EDGE` 唯一落点=`ui_kit.gd`(色板 token 单点——`#4C4038` 全仓无既有 token,2026-10-31 grep 证实;禁在 `standee_body` 内联字面值);`name_font_size` 探针键唯一落点=`name_line_probe`(探针共用面单点);名字行几何唯一算式落点=`_name_plate_rect`/`_name_baseline`(本批不改此结构)。2026-10-31 实查无同名/同义标识符冲突(`grep PLAZA` 仅 `TEX_STAGE_PLAZA` 纹理路径族)。
**分层与交互面**:全部改动在 presentation 层与单元测试层——零跨层新依赖、零 Core 触碰、零 ConfigDB/RNG 触碰(无随机、无表值变化);探针消费方向不变(`ui_struct_probe`/测试→`name_line_probe` 只读)。
## 13. 禁为机检文本保留无效成员
本批含常量退役——`STAND_STONE_RIM`/`STAND_STONE_EDGE` 删除后禁留别名常量、转发成员或注释占位凑「零引用」判据;机检键与卡片契约互斥时实现段停卡呈报,禁自造第三条路(code-conventions §1.1 同款)。
## 14. 实现规范预算
**新件三查**:本批零新增文件——三查不适用(写「无新增件」)。
**存量触面一查**:`standee_body.gd`(S13 扫描面内,无基线登记键)——零新增成员/函数,`name_line_probe` 返回字典增键非成员,预期 S13 零新增、既有键持平;`ui_kit.gd` 常量净 −1(删 2 增 1);`cell_base_layer.gd` 零成员变化(引用换值)。达成手段:全部改动为常量引用替换与既有函数体内取值/偏移改写。
**指标例外申报**:无。
**估时合计**:T0 0.1+T1 0.15+T2 0.15+T3 0.1=**0.5 个工作日**(区间 0.4–0.6;切分预案=若 T0 字体度量或 golden 重锚节外生枝超软盒,T2 拆出独立卡,T1 先行不阻塞)。
@@ -0,0 +1,337 @@
# 需求卡片——组合根注册面批(main.gd 类变量归 15:界面注册面+三域句柄容器)
状态行:v1.0 定稿——零待裁点(2026-10-29 用户裁:注册面拓扑一门面+三域容器、合同机器迁入、别名消灭清单整体确认;实现层细目授权 agent 按设计文档执行)
接收方:待办清单条目「零豁免五键清偿批——S13 余量五键真修四卡(2026-10-29 登记,来源=会话提及)」——本卡为其四卡之首(组合根注册面批)。
来源:reports/设计-组合根注册面-2026-10-29.md(2026-10-29 设计闭合,**唯一事实源**);architecture 权威=design/engineering/architecture/architecture.md v1.25(2026-10-29——「模块归属·呈现层」表 ui_registry 行、「呈现层装配与会话生命周期」节屏成员寻址迁注册面句=原 S13 豁免登记注销、RunScope 节)。
## 1. 目标与完成定义
这批做什么:把 main.gd(组合根)里散着的屏壳、覆盖层一级句柄与视觉层合同表收进一个「界面注册面」——一个不挂树的 RefCounted 门面件(ui_registry.gd)加三个按领域分的句柄容器(ui_screens/ui_battle/ui_modals),探针和系统测试对界面元素的引用从 `main.X` 一级地址改成 `main.ui.<域容器>.<句柄>` 三段式地址。同时消灭 7 个探针兼容别名/转发成员、退役 6 个 main 纯转发模态方法。main.gd 类变量从 49 降到 15,S13 基线键真实还债,architecture 在册的 S13 豁免登记随批注销。
**行为零变化**:装配序、信号接线、层序(树序=登记序=z 序)、RunScope 会话生命周期、RNG 消费序全部零变化;探针断言只换地址、不换判据。
完成定义(全部满足才算完):
1. 五闸主证全绿——probe_gate 默认段+`--click`+`--full`、render_gate golden 零差异、run_smoke、run_system_test、run_all 02 单元与集成(main.gd 触组合根=横切面,按 AGENTS.md 关联档口径回落全部套件)。
2. static_scan 过——四新文件零新基线键(S9 全类型标注、S10 头注);main.gd 类变量实测 15(键账对账批末申报,基线 refresh 由用户发令)。
3. 改址完整性自检——按 49 名逐名 grep,`game/` 下旧一级路径 `main.<旧名>`/`root.<旧名>`/`self.<旧名>` 残留=0,报告留档。
4. 产出物落 `reports/`——实现报告、反哺点清单、验收审计报告(独立审计未过不合并)。
**编队注记与估时**:本卡与「战斗编排归约批」(battle_orchestrator 拆 RoundCycle/BattleFacts 两件——architecture v1.25 轴丁设计闭合、待写卡)和「测速循环批」(tune_sim_controller 步进状态机——architecture v1.25 S13 测量面豁免注销设计闭合、待写卡)同代待编排;三批无同文件交叠(本批触面=main.gd+main_ui_build+三流程件+探针/测试面)。与迭代 42(在飞:gdstyle 尾波清偿批+level_runner 商店委托层拆除)**存在文件交叠**——并排卡「level_runner 商店委托层拆除」触面含 main.gd(1 处)、main_adventure_flow(6 处)、main_overlay_flow(2 处),全在本批触面集内(grilling 复核证伪原「无交叠」声明,订正);**本批开工前置=迭代 42 合回 master**,T0 按合回点重测改址计数。另与「呈现层状态件批」共享 ui_input_probe.gd 触面(本批改 main.X 地址面、该批改四处 u.face.* 读面)——同代编排时禁并行、先后皆可。估时区间 **3–4 个工作日**(设计文档 §8),低于迭代冻结线(5 个工作日),可编批;编入哪个迭代由迭代编排段定。
## 2. 现状事实
全部行号为 **2026-10-29 实查——本批编入在 gdstyle 尾波补件批相关迭代之前/之后均须 T0 按 T0 时点 master 重测重锚**。
1. `game/presentation/main.gd`(915 行)共 **49 个类变量**(逐名清点 main.gd:61–148,含 3 个委托属性);S13 基线键 `game/presentation/main.gd|quality/max-class-variables = 49`(阈值 15)在 tools/gdstyle_baseline.txt 在册,architecture v1.25 在册 S13 豁免登记〔2026-10-27「组合根类变量面即探针契约面」〕已随 v1.25 注销、待本批真实还债。
2. 视觉层合同机器四样全在 main.gd:`LAYER_CONTRACT` 常量(main.gd:39–59,19 项含 host/shell/tags 标注)、`_apply_layer_contract()`(main.gd:254–279,全仓唯一 move_child 落位点)、`_layer_node(key)`(main.gd:227–248,19 键 match)、`_register_modal(m, tags)`(main.gd:218–224,anchors preset+flow.register)。
3. 探针兼容别名/接缝成员 7 个:`board_view`(main.gd:95)、`ap_bar`(main.gd:96)——赋值点 main_ui_build.gd:48–49;`_modals`(main.gd:129,赋值 main_ui_build.gd:245);`_row_queue`(main.gd:111–113,委托属性读 `_row_pacer.pending_rows()`);`_seed_edit`(main.gd:74,赋值 main_ui_build.gd:208);`_settlement_stop_pending`(main.gd:134–143,读=is_armed()/写=arm()/disarm());`_deferred_modal`(main.gd:148–150,读 `_modal_flow._deferred`)。
4. main 纯转发模态方法 6 个:`_open_modal_after_playback`(main.gd:156–158)、`_on_pump_ended`(main.gd:161–163)、`_open_modal`(main.gd:282–284)、`_close_modal`(main.gd:285–287)、`_on_modal_closed`(main.gd:288–290)、`_input_locked`(main.gd:292–295)——各自一行转呼 `_modal_flow` 真方法。另有一个纯转发方法同批退役:`_flush_row_queue`(main.gd:516,一行转呼 `_row_pacer.flush`)——`_row_pacer` 句柄迁 ui.screens 后调用方 `pacing_queue_test.gd:103` 改调 `main.ui.screens.row_pacer.flush()`(表 D 归宿行)。
5. 装配承接件 main_ui_build.gd:`build(root)` 八步(main_ui_build.gd:21–29),赋值目标全走 `root.X` 一级成员(main_ui_build.gd:38–51 等);`pump_ended` 注入点 main_ui_build.gd:62;context 束注入 `open_modal/close_modal`(main_ui_build.gd:144、168);`_apply_layer_contract()` 末位调用 main_ui_build.gd:247。
6. 消费面引用量(设计文档 §0 机械统计,T0 实跑重计):探针+系统测试 `main.X` 成员引用约 **867 处**;四个流程承接件(main_adventure_flow/main_overlay_flow/main_debug_flow/main_ui_build)`root.X` 引用约 200–350 处(设计文档 §0 与 §3.2 两处统计口径不一,以 T0 映射表脚本实跑计数为准)。抽查实证:ui_input_probe.gd:34–43(seed_edit/level_screen)、system_test.gd:94–109(LAYER_CONTRACT、_layer_node、V2 句柄等价五连比)、smoke_boot.gd:68–75(`main.get()` 6 处)、pacing_queue_test.gd:108/132/147/149(`_row_queue` 3 处+`board_view` 1 处)、source_guard_test.gd:69–77(V1d 层序单口断言,现扫 main.gd 单文件)、theme_projection_test.gd:724–725(V6 断言 main.gd 含 `debug_overlay.diagnose_requested.connect(_on_diagnose_pressed)` 串)。
7. 留 main 的 14 成员(对账见表 B)全部是组合根自身状态、组合根拆件引用、autoload 读视图;`run_scope` 引用(探针约 173 处)零迁移。
8. 探针段构成(architecture「测试与质量域」probe_gate 行):默认段 ui_input_probe/ui_struct_probe/layout_probe/ui_contrast_probe/screen_flow_probe,`--click` 加 ui_click_probe,`--full` 加 ui_probe/ui_tune_probe/t17_defer_probe/fx_probe。
9. meta_progression_forge_test 经 `load("res://presentation/main.gd")` 直呼 static `build_adventure_params`——留 main,零迁移(main.gd:366–376)。
10. 本批不涉 RNG/数值/存档触面;PARITY 触面(battle_orchestrator.gd)不在 diff,无 MC 义务。
## 3. 设计契约(违反即返工,标 🔴 触碰=L3 停机呈报)
- 🔴 **行为零变化**:装配序与 add_child 顺序、信号连接语句逐条不变;层序合同表条目、顺序、tags、host/shell 标注**逐字零变化**只换宿主文件;`_begin_session`/闲时会话/整节点 queue_free 机制一字不动;RNG 消费序零触碰;呈现层订阅禁令与核心写调用唯一出口纪律零触碰。
- 🔴 **探针断言语义零变化**:改址只换地址不换判据——断言条件、尾缀(既有〔装配生命批 V1〕〔装配生命批 V3〕等保留)、消息语义不动;禁借改址删断言、放宽阈值、缩小扫描面。
- 🔴 **拆分边界纪律五条**(判据权威=code-conventions §1.1,此处写红线不复制定义):①每个拆出单元须有可陈述的职责语句与单一变化原因(四件各一句,见 §12 表,实现报告逐件一行承载);②拆出单元须有集体身份——命不出名字、只能说「剩下的成员」的打包=凑计数袋,禁;③「过阈值(49→15)」只许作发现信号,作拆分或收拢动机即违规;④按纪律拆不出内聚单元→停卡呈报走豁免通道,禁硬拆凑绿;⑤禁保留/新增无效成员与别名凑数——本批方向是净消灭(7 成员+6 方法),实现期发现任何「为保地址兼容」新增的转发壳即违契约。
- 🔴 **禁为机检文本保留无效成员**:禁止为迎合机检消息文本(含计数)而保留或新增无效成员/别名;机检键与本卡契约互斥时(如实测出新基线键 NEW 红)一律停卡呈报,不得自造第三条路(详见 §13 条款节)。
- 🔴 **测试削弱申报制**:允许改动的旧断言全集见 §8「测试削弱申报」,未申报的删改由独立验收审计判红。
## 4. 范围边界
做:ui_registry+三域容器建件;合同机器四样迁驻;main.gd 49→15 改形;main_ui_build 与三流程件改址;探针九件+probe_ui_util+smoke_boot+system_test+pacing_queue_test 改址;V1d/V6 源码断言重锚;七别名与六转发方法消灭。
不做(明示去向):
1. architecture.md 直改——实现批禁写 `design/`,ui_registry 行现状化与 main_ui_build 行层序句改指走反哺点通道(§6)。
2. game/tests/README.md 改动——实现批禁写;写卡段义务已核=零增删零改行(§6)。
3. modal_stack.gd/modal_flow.gd 语义改动——两件零触碰,本批只改它们的消费方地址。
4. RunScope/会话生命周期机制、row_pacer 排播时序、T17 挂起编排——零触碰。
5. S13 豁免登记第二/三条(tune_sim_controller、battle_orchestrator)——原文不动,归「战斗编排归约批」「测速循环批」。
6. board_cell_unit/standee_body/board_view 悬停域等结构债——归迭代 42 尾波清偿批,不收件。
7. 基线 refresh——`python tools/gdstyle_gate.py --refresh` 由用户发令人工跑(净减 1 键,低于 10% 骤降守卫,无需 --force);实现批只做键账对账申报。
8. MC/数值验证——无数值改动零跑。
## 5. 关联文档同步面
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|---|---|---|
| design/engineering/architecture/architecture.md(设计权威——实现批禁直改) | ①「模块归属·呈现层」ui_registry 行现登记「实现批建件」态,实现后应现状化;②同表 main_ui_build 行「层序逻辑不在此件——唯一事实源仍是 `main.LAYER_CONTRACT` + `_apply_layer_contract()`」句在实现后失效(唯一事实源迁 ui_registry.LAYER_CONTRACT+ui.apply_layer_contract());③「呈现层装配与会话生命周期」节屏成员寻址迁注册面句 v1.25 已落、实现后核对措辞与实况一致 | 反哺点通道:把上列 ①②③ 逐条列进 `reports/iter<N>-反哺点-<日期>.md`(改哪一节、改成什么、依据=设计文档 §3.3 建议句),用户在会话中裁决后归文档批落文 |
| game/tests/README.md(机械面——实现批禁写) | 本批零新增能力(改址只换地址,能力集不变);受影响存量行核对:「模态覆盖层编排与输入锁」行真实入口(ModalFlow 两个公开方法)与代表用例(modal_flow_test.gd:_init 等)不变;「结算明细带逐行呈现与排播节奏」行代表用例 pacing_queue_test.gd:_init 不变(`文件:函数` 锚不受成员改址影响) | 写卡段义务已当场核完=**零增行、零删行、零改行**;批末收尾只核对表上名字与实际落地一致(改名则回表) |
| design/gdd/ 无关联文档 | 行为零变化,任何系统文档陈述不受影响;层序唯一事实源属 architecture 不属 GDD | 无(本行占位——按规约查不出也要写明) |
## 6. 卡前文件结构图(本批新建/修改文件全列)
| 文件 | 职责 | 新增/复用 | 行为改动? |
|---|---|---|---|
| game/presentation/ui_registry.gd | 界面注册面门面:三容器属性+LAYER_CONTRACT+node(key) 合同寻址+apply_layer_contract(root) 唯一落位口 | 新增(预检 §12) | 非行为改动(新建件承载既有合同——落点变化,对照表行 1/2) |
| game/presentation/ui_screens.gd | 屏壳与全屏容器域句柄册(9 成员) | 新增(预检 §12) | 非行为改动(对照表行 3) |
| game/presentation/ui_battle.gd | 战区视图域句柄册(5 成员) | 新增(预检 §12) | 非行为改动(对照表行 3/4) |
| game/presentation/ui_modals.gd | 模态层域句柄册+ModalFlow 持有+register_layer(14 成员) | 新增(预检 §12) | 非行为改动(对照表行 3/7) |
| game/presentation/main.gd | 组合根改形:49→15;合同机器与转发方法迁出;内部取址改 ui.*;头注追加注册面句 | 修改 | 非行为改动(纯结构——装配/接线/层序/RNG 零变化,四闸主证;对照表行 2/6/7) |
| game/presentation/main_ui_build.gd | 八步赋值目标改 root.ui.*;context 束与 pump_ended 注入改址;_seed_edit/_modals 赋值行退役 | 修改 | 非行为改动(八步顺序/add_child 序/连接语句逐条不变;对照表行 3) |
| game/presentation/main_adventure_flow.gd/main_overlay_flow.gd/main_debug_flow.gd | root.X 同表映射(模态口改指 root.ui.modals.flow;句柄读改 root.ui.*) | 修改 | 非行为改动(对照表行 3/7) |
| game/probe/ 九探针+probe_ui_util.gd(凡 T0 映射表命中的 main.X 引用件) | 旧地址→main.ui.* 机械改写 | 修改 | 非行为改动(断言语义零变化;对照表行 4/6) |
| game/tests/smoke_boot.gd | get() 键改址(4 改 2 留) | 修改 | 非行为改动(对照表行 3) |
| game/tests/system_test.gd | main.X 改址(V1a/V1c/V2 句柄等价/V3 矩阵取址两处) | 修改 | 非行为改动(判据零变化;对照表行 1/5) |
| game/tests/unit/contracts/source_guard_test.gd | V1d 重锚(单文件扫描→全目录扫描,判据强化) | 修改 | 非行为改动(断言改写已申报;对照表行 8) |
| game/tests/unit/presentation/theme_projection_test.gd | V6 断言串改新连接串 | 修改 | 非行为改动(断言改写已申报;对照表行 9) |
| game/tests/unit/presentation/pacing_queue_test.gd | board_view/_row_queue 改址(3+1 处) | 修改 | 非行为改动(对照表行 6) |
不触碰:modal_flow.gd/modal_stack.gd/row_pacer.gd/ui_assembler.gd/run_scope.gd/meta_progression_forge_test.gd(static 入口零迁移)/全部 core 与 data。
## 7. 任务卡 T0..T4
### 7.1 地址契约(全批唯一映射依据——表 A/B/C/D 与设计文档 §1.2 对账表同源)
**表 A:迁入注册面的 28 个 main 成员**(容器内成员名去下划线=公共地址面):
| 现成员(2026-10-29 行号) | 新地址 | 现成员 | 新地址 |
|---|---|---|---|
| `_menu_screen`(:100) | ui.screens.menu_screen | `legend_overlay`(:116) | ui.modals.legend_overlay |
| `_camp_screen`(:101) | ui.screens.camp_screen | `node_overlay`(:117) | ui.modals.node_overlay |
| `_adventure_screen`(:102) | ui.screens.adventure_screen | `level_screen`(:83) | ui.modals.level_screen |
| `_start_overlay`(:79) | ui.screens.start_overlay | `curio_overlay`(:78) | ui.modals.curio_overlay |
| `_battle_root`(:84) | ui.screens.battle_root | `_end_overlay`(:80) | ui.modals.end_overlay |
| `_inter_overlay`(:81) | ui.screens.inter_overlay | `shop_overlay`(:118) | ui.modals.shop_overlay |
| `_inter_label`(:82) | ui.screens.inter_label | `camp_overlay`(:119) | ui.modals.camp_overlay |
| `debug_badge`(:126) | ui.screens.debug_badge | `settings_overlay`(:121) | ui.modals.settings_overlay |
| `_row_pacer`(:105) | ui.screens.row_pacer | `status_panel`(:122) | ui.modals.status_panel |
| `stage`(:91) | ui.battle.stage | `career_overlay`(:123) | ui.modals.career_overlay |
| `log_view`(:92) | ui.battle.log_view | `save_select_overlay`(:124) | ui.modals.save_select_overlay |
| `info_panel`(:93) | ui.battle.info_panel | `confirm_dialog`(:75) | ui.modals.confirm_dialog |
| `board_zone`(:94) | ui.battle.board_zone | `debug_overlay`(:125) | ui.modals.debug_overlay |
| `settlement_fx`(:97) | ui.battle.settlement_fx | `_modal_flow`(:128) | ui.modals.flow |
**表 B:留 main 的 14+1**:db、run_scope、save_manager、meta、settings_store、logger、_debug_entry、_confirm_consumer、_confirm_consumer_slot、_debug、_treasure_ui、_bonus、_camp_pres、_tune_sim(保留理由逐个=组合根自身状态/拆件引用/autoload 读视图,见设计文档 §1.2 第二表)+新增 `ui: UiRegistry`。改后 15,恰在阈内。
**表 C:消灭的 7 个别名/接缝成员**:
| 成员 | 本体 | 消灭后地址 |
|---|---|---|
| board_view(:95) | =board_zone.board_view | ui.battle.board_zone.board_view |
| ap_bar(:96) | =board_zone.ap_bar | ui.battle.board_zone.ap_bar |
| _modals(:129) | =_modal_flow.stack | ui.modals.flow.stack |
| _row_queue(:111) | 委托属性=_row_pacer.pending_rows() | ui.screens.row_pacer.pending_rows()(同一 Array 引用,语义不变) |
| _seed_edit(:74) | =debug_overlay.seed_edit | ui.modals.debug_overlay.seed_edit.text(main._seed_value 唯一消费点) |
| _settlement_stop_pending(:134) | 委托属性读=is_armed()写=arm()/disarm() | run_scope.settlement_stop_timer 直呼同名面 |
| _deferred_modal(:148) | 委托属性=_modal_flow._deferred | ui.modals.flow._deferred |
**表 D:方法/函数级改址**:
| 旧地址 | 新地址 | 消费方 |
|---|---|---|
| main._layer_node(key) | main.ui.node(key) | system_test V1c(实查 source 点 system_test.gd:97;设计文档记 3 处——T0 重计) |
| main._register_modal(m, tags) | ui_modals.register_layer(m, tags)(逐字迁入:anchors preset+flow.register) | 仅 _apply_layer_contract 内部消费,随迁 |
| main._apply_layer_contract() | main.ui.apply_layer_contract(root)(root 作参传入,main_ui_build.gd:247 调用点改) | 装配尾唯一调用点 |
| main._open_modal(m) | main.ui.modals.flow.open(m) | 探针各 1 处+流程件 root. 共约 23 处(T0 重计);main 内部调用点(_on_confirm_accepted 等)同改 |
| main._close_modal(m)/main._on_modal_closed(m) | main.ui.modals.flow.close(m)(信号 bind 目标 main_ui_build.gd:99/209 改 flow.close.bind) | 同上 |
| main._input_locked() | main.ui.modals.flow.locks_input() | 探针 18 处(T0 重计)+main._on_board_action/_on_stop_pressed/_on_refresh_confirmed 内部 |
| main._open_modal_after_playback(m) | main.ui.modals.flow.open_after_playback(m) | 流程件 root. 2 处+探针(T0 重计) |
| main._on_pump_ended | main.ui.modals.flow.pump_ended | row_pacer.pump_ended 注入点 main_ui_build.gd:62 |
| smoke_boot `main.get("_start_overlay"/"debug_badge"/"legend_overlay"/"status_panel")` | `main.get("ui").<域>.<名′>`(get 只解析一层,后续走公共字段) | smoke_boot.gd:70/73/74/75;`get("run_scope")`/`get("settings_store")` 零迁移 |
| source_guard V1d 串 | 重锚:扫全 `game/presentation/*.gd`,`move_child(` 只允许出现在 ui_registry.gd 的 apply_layer_contract 函数体内(从扫单文件变扫全目录——判据强化) | source_guard_test.gd:69–77 |
| main._flush_row_queue() | main.ui.screens.row_pacer.flush()(转发壳随 `_row_pacer` 迁移退役) | pacing_queue_test.gd:103 |
| theme_projection V6 串 | 改断言新串 `ui.modals.debug_overlay.diagnose_requested.connect(_on_diagnose_pressed)`(连接语句本体随 T2 改写 main.gd:209) | theme_projection_test.gd:724–725 |
### 7.2 新件接口块(T1 定义,T2 起逐字取用;类型标注义务=S9 过)
```
# game/presentation/ui_registry.gd —— 界面注册面(RefCounted,不挂树,零信号连接,零会话期引用)
class_name UiRegistry
extends RefCounted
const ModalStack := preload("res://presentation/modal_stack.gd")
const LAYER_CONTRACT: Array[Dictionary] = [ …main.gd:39-59 内容逐字迁入,一项不增不减不改… ]
var screens: UiScreens
var battle: UiBattle
var modals: UiModals
func node(key: String) -> Node # 合同寻址:_layer_node 的 19 键 match 逐字迁入
func apply_layer_contract(root: Control) -> void # 落位算法逐字搬运(move_child 单口;登记经 modals.register_layer)
# game/presentation/ui_screens.gd —— 屏壳与全屏容器域(RefCounted,纯字段无方法)
class_name UiScreens
extends RefCounted
var menu_screen: Control
var camp_screen: Control
var adventure_screen: Control
var start_overlay: Control
var battle_root: Control
var inter_overlay: Control
var inter_label: Label
var debug_badge: Button
var row_pacer: RowPacer # 经 preload 常量取型(res://presentation/row_pacer.gd 非 class_name 全局)
# game/presentation/ui_battle.gd —— 战区视图域(RefCounted,纯字段无方法)
class_name UiBattle
extends RefCounted
var stage: BattleStageView
var log_view: BattleLogView
var info_panel: HeroInfoPanelView
var board_zone: BoardZoneView
var settlement_fx: SettlementFxView
# game/presentation/ui_modals.gd —— 模态层域(RefCounted)
class_name UiModals
extends RefCounted
var flow: ModalFlow
var legend_overlay: LegendOverlay
var node_overlay: NodeOverlay
var level_screen: LevelMapScreen
var curio_overlay: CurioPickOverlay
var end_overlay: BattleEndOverlay
var shop_overlay: ShopOverlay
var camp_overlay: CampOverlay
var settings_overlay: SettingsOverlay
var status_panel: StatusPanel
var career_overlay: CareerOverlay
var save_select_overlay: SaveSelectOverlay
var confirm_dialog: ConfirmDialog
var debug_overlay: DebugOverlay
func register_layer(m: Control, tags: Array = []) -> void # _register_modal 逐字迁入
```
(main.gd 现有类型标注逐字沿用:ui_battle/ui_modals 十八句柄的类型名=main.gd:78–125 在用全局类名;ui_screens 三屏壳标 Control,若 T1 实测场景根基类不符,按代拍板白名单第 6 条取实际基类。)
### 7.3 T0——读数重锚与对账(估时 0.5 个工作日)
- [ ] 按 T0 时点 master 重测重锚本卡全部行号与计数:main.gd 类变量实数(gdstyle 读数)、合同机器四样行位、七别名与六转发方法行位、六转发方法的全部调用点清单(main 内部+流程件+探针+system_test 分文件计数)。
- [ ] 49 成员逐一对账:对照本卡表 A/B/C 逐名核对仍在位、仍归该档(迁移 28/留 14/消灭 7)——任何一名对不上=L3 停卡呈报(设计文档 §1.2 对账表为第二依据)。
- [ ] 映射表脚本生成+对账:探针九件+probe_ui_util+smoke_boot+system_test+四流程件的 `main.X`/`root.X` 全量计数与旧→新映射(机械生成+人工复核语义位——属性读写约 750 处、方法调用四类、字符串键 6 处、源码断言 2 条);设计文档 867/350/200 三处统计口径以本次实跑为准并在实现报告记数。
- [ ] 未登记源码断言排查:grep `presentation/main.gd` 于 game/tests+game/probe 全部源码断言面——只许 V1d/V6 两条命中;新发现=L3 停卡补申报,禁自行改判。
- [ ] 迁移函数对账:查 tools/gdstyle_baseline.txt 中 main.gd 的 `_apply_layer_contract`/`_layer_node`/`_register_modal` 源函数键——branches/returns/函数长有超默认登记值的,迁移即拆函数(拆分不改语义)。
- [ ] 孤立验证(改前基线读数):`python tools/gdstyle_gate.py`(采集 main.gd=49 读数)+`godot --headless --path game --script res://tests/run_all.gd -- --only=source_guard`(绿)。
- 取用:本卡 §7.1 四表。产出:重锚后的映射表与对账表(实现报告附件节,T2/T3/T4 消费)。
### 7.4 T1——注册面与三域容器建件(估时 1 个工作日)
- [ ] 按 §7.2 接口块建 ui_registry.gd:LAYER_CONTRACT 自 main.gd:39–59 逐字迁入(ModalStack 常量引用随迁);`node(key)` 19 键 match 逐字;`apply_layer_contract(root)` 落位算法逐字搬运(move_child 单口语义不变)。
- [ ] 建 ui_screens/ui_battle/ui_modals(成员与类型按 §7.2;ui_modals.register_layer 自 main.gd:218–224 逐字迁入);四件全类型标注、`_init` 不收参(容器由门面构造)。
- [ ] 四件 class_name(UiRegistry/UiScreens/UiBattle/UiModals)+跑一次编辑器扫描刷新全局类缓存+同步 .uid(code-conventions 语言纪律 5——T2 main.gd 类型标注 UiRegistry 在 --script 模式可解析的前置);文件头 `##` 注释介绍模块(禁变更叙事、禁文档反向链接)。
- [ ] 孤立验证:`game/tests/static_scan.sh`(S9 四新件零红+S10 头注过+S13 四新件零新键)+`godot --headless --path game --script res://tests/run_all.gd -- --only=source_guard`(V8 全库扫描仍绿——新件零字符串 Callable)。
- 取用:T0 映射表。产出:四件公开面(UiRegistry.new()/.screens/.battle/.modals/.node(key)/.apply_layer_contract(root)/modals.register_layer(m, tags)——T2 逐字消费)。
### 7.5 T2——main.gd 改形与装配/流程件改址(估时 1–1.5 个工作日)
- [ ] main.gd 新增 `var ui: UiRegistry`;`_ready` 在 `_build_ui()` 之前 `ui = UiRegistry.new()`(容器随门面构造;装配在 _ready 建闲时会话之前完成——时序零变化)。
- [ ] 表 A 28 成员迁出:main 内部全部取址同步改 `ui.*`(含 main.gd:199–200 启动态两行、_seed_value:911、_on_confirm_accepted/_start_adventure/_resume_from_menu/_replay_locked_click 等内部调用点改指 ui.modals.flow.*/ui.screens.row_pacer.pending_rows());合同机器四样自 main 删除(随 T1 迁驻)。
- [ ] main_ui_build.gd:八步赋值目标改 `root.ui.<域>.<名′>`(八步顺序、add_child 顺序、连接语句逐条不变);`root._seed_edit` 赋值行(:208)删除;`pump_ended` 注入改 `root.ui.modals.flow.pump_ended`(:62);`root._modals` 赋值行(:245)保留至 T4;context 束 overlay/toast/start_overlay/board_view 键值改址(:137–147、:163–169,注入时点与值不变);`_apply_layer_contract` 调用改 `root.ui.apply_layer_contract(root)`(:247)。
- [ ] 三流程件 root.X 按表 A/D 同表映射(root._open_modal/_close_modal/_open_modal_after_playback/_input_locked → root.ui.modals.flow.*;`_settlement_stop_pending` 写点改 `run_scope.settlement_stop_timer.arm()/disarm()`——写点计数 T0 对账)。
- [ ] smoke_boot.gd get() 改址(4 改 2 留,§7.1 表 D)。
- [ ] source_guard_test.gd V1d 重锚为全目录扫描(尾缀〔注册面 V1〕);theme_projection_test.gd V6 改断言新串(尾缀〔注册面 V2〕)——两条改写即 §8 申报的测试改动全集。
- [ ] 孤立验证:`python tools/run_smoke.py`(冒烟绿=装配链完整)+`godot --headless --path game --script res://tests/run_all.gd -- --only=source_guard,theme_projection,meta_progression_forge`(三套件绿——V1d/V6 重锚后绿、static 入口零变化)+`python tools/gdstyle_gate.py`(main.gd 类变量读数记录——此轮含 7 别名=22,基线键 49 内不红,读数进实现报告)。系统测试与探针此轮预期红(消费面未改址——T3 收口),不构成本卡验证面。
- 取用:T1 四件公开面。产出:main.ui.* 地址面全量生效的组合根(T3 消费)。
### 7.6 T3——探针/系统测试/单元批量改址(估时 1 个工作日)
- [ ] 探针九件+probe_ui_util 按 T0 映射表机械改写:属性读/写改 `main.ui.<域>.<名′>`;四类方法调用按表 D;`var bv = main.board_view` 型局部承接改 `var bv = main.ui.battle.board_zone.board_view`(每文件 1–2 处)。
- [ ] 接缝三件:ui_struct_probe 的 `main._modals` → `main.ui.modals.flow.stack`(登记序断言);t17_defer_probe 的 `main._deferred_modal` → `main.ui.modals.flow._deferred`(挂起态断言);ui_click_probe 的 `_settlement_stop_pending` 读点 → `main.run_scope.settlement_stop_timer.is_armed()`。
- [ ] system_test.gd 改址:V1c 的 `main.LAYER_CONTRACT`→`main.ui.LAYER_CONTRACT`、`main._layer_node`→`main.ui.node`;V2 句柄等价断言(:107–109)改 ui 地址(等价语义不变:ui.battle.board_zone.board_view == ui.screens.adventure_screen.board_view 型);V1a 候选清单与全件 main.X 逐表映射;V3 矩阵 `_face_snapshot` 的 `main._modal_flow`→`main.ui.modals.flow`、`main._row_pacer`→`main.ui.screens.row_pacer`(其余四持件取址不变)。
- [ ] pacing_queue_test.gd:`main.board_view`→`main.ui.battle.board_zone.board_view`(:132);`main._row_queue`→`main.ui.screens.row_pacer.pending_rows()`(:108/:147/:149,实查 3 处)。
- [ ] 改址完整性自检:映射表驱动 49 名逐名 grep——`game/` 下(探针/tests/流程件/main 自身)旧一级路径 `main.<旧名>`/`root.<旧名>`/`self.<旧名>` 残留=0,报告留档(实现报告对照表挂行)。
- [ ] 孤立验证:`tools/probe_gate.sh --click --full`(全段退出码 0)+`python tools/run_system_test.py`(V1–V9 摘要 0 失败)+`python tools/run_smoke.py`+`godot --headless --path game --script res://tests/run_all.gd -- --only=pacing_queue,source_guard`。
- 取用:T2 地址面。产出:全部消费面新地址(T4 前提——别名/转发方法零消费方)。
### 7.7 T4——别名与转发方法消灭+批末收口(估时 0.5–1 个工作日)
- [ ] 删 main.gd 七别名/接缝成员(表 C——此点已零消费方)与六转发方法(§2 第 4 条清单);删 main_ui_build.gd:245 `root._modals` 赋值行;main.gd 类变量终态 **15**。
- [ ] 文件头注随迁改写:main.gd 头注追加一句「界面句柄与层清单在 ui 注册面(ui_registry.gd)」;main_ui_build.gd 头注「层序唯一事实源」句改指 ui_registry(指址改写、词面语义不变)。
- [ ] 逐卡扫尾孤立验证:`tools/render_gate.sh`(golden 零差异)+`tools/probe_gate.sh --click --full`+`python tools/run_smoke.py`+`python tools/run_system_test.py`+`godot --headless --path game --script res://tests/run_all.gd -- --only=pacing_queue,modal_flow,source_guard,theme_projection,meta_progression_forge`。
- [ ] 批末全量:`tools/run_all_gates.sh --code` 全绿(main.gd 触组合根=横切面——02 单元与集成按 AGENTS.md 横切面口径回落全部套件;冒烟/系统测试/静态扫描三件保险恒跑)。里程碑步出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试先行孤立验证再并入全套。
- [ ] S13 键账对账申报:main.gd 键 49→15 只降不升、四新件零新键;基线 refresh 由用户发令人工跑(--refresh,净减 1 键低于骤降守卫)。
- [ ] **产出物落位卡**(轻闸全绿后、合并前写齐,方算收口):`reports/iter<N>-实现报告-<日期>.md`——各卡状态+实机目检总清单(登记不阻塞:注册面改址后实机过一遍三屏切换与模态开合)+遗留读数义务(基线 refresh)+实现决定记录+改址计数与 grep 自检留档;`reports/iter<N>-反哺点-<日期>.md`——§5 同步面所列 architecture 三条逐条有落点;`reports/iter<N>-验收审计-<日期>.md`——独立验收审计(未参与实现的会话或子代理执行,未过不得合并)。
- 取用:T3 零消费方清单。产出:终态 main.gd(15 var)+三份 reports/ 产出物。
## 8. 验证闸(改动—验收对照表)
本批全部改动为**非行为改动**(结构与地址重构):每行判断依据=改前改后在同一输入上行为一致,由探针/系统测试/冒烟/渲染 golden 四闸主证(真实入口全绿),静态 grep 只作完整性辅证。调试接口/目检两分法:本批无新玩法能力,验证全走自动化载体;用户目检仅一条登记项(T4 实机过三屏与模态开合),登记不阻塞。**静态判据申报(不入对照表,test-conventions §8.4 出口——grilling 复核订正)**:S13 键账对账(main.gd 实测 15、四新件零新键、基线 refresh 由用户发令)与映射表驱动 grep 残留=0 自检无独立运行期提交面——判据=`python tools/gdstyle_gate.py`/`game/tests/static_scan.sh` 退出码与 T3 grep 自检留档,属静态判据+评审注记申报观测面局限;对照表行 2/11 只承载其运行面回归与全量闸半边。
| # | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|---|
| 1 | 注册面建件+合同机器迁驻(层序零变化) | 新建 ui_registry.gd(LAYER_CONTRACT main.gd:39–59 逐字迁入);ui_screens/ui_battle/ui_modals 建件 | 系统测试 V1c「合同树序链逐对保序」(system_test.gd:94–106 改址 main.ui.LAYER_CONTRACT/main.ui.node,尾缀〔装配生命批 V1〕保留) | 系统测试 | `python tools/run_system_test.py` | 运行期树序逐对保序=LAYER_CONTRACT 序(get_index 链——层序零变化的运行期提交面) | 既有:模态覆盖层编排与输入锁 |
| 2 | main.gd 改形回归(49→15 结构改形) | main.gd:61–148 改形(28 迁出+7 消灭+1 新增);六转发方法退役 | 批末 run_smoke+run_system_test 双宿主摘要 0 失败(改形回归主证;S13 键账静态判据见域口径申报) | 冒烟+系统测试 | `python tools/run_smoke.py`;`python tools/run_system_test.py` | 双宿主摘要 0 失败(改形后全链路回归面) | 既有:模态覆盖层编排与输入锁 |
| 3 | 装配与流程件改址(root.ui.*) | main_ui_build.gd 八步赋值目标;三流程件+context 束+pump_ended 注入点;smoke_boot.gd:70/73/74/75 | 冒烟主屏存活面六断言(smoke_boot.gd:64–75 改址后全绿)+系统测试 V2「组合根句柄指向屏壳成员」等价断言(system_test.gd:107–109 改址,五连比同指) | 冒烟+系统测试 | `python tools/run_smoke.py`;`python tools/run_system_test.py` | 启动态装配句柄在座且等价断言两侧同指一对象(多一跳取到同一引用) | 既有:模态覆盖层编排与输入锁 |
| 4 | 探针面批量改址(约 867 处) | 探针九件+probe_ui_util 旧地址→main.ui.*(只换地址不换判据) | probe_gate 全段退出码 0(ui_input_probe 全 case/ui_struct_probe/layout_probe/ui_contrast_probe/screen_flow_probe+--click ui_click_probe+--full ui_probe/ui_tune_probe/t17_defer_probe/fx_probe) | 探针 | `tools/probe_gate.sh --click --full`(单件形态:`godot --headless --path game res://probe/ui_input_probe.tscn` 等) | 探针经新地址取到同一节点并驱动真实输入路径(改址完整性的第一消费方主证) | 既有:棋盘悬停反馈(三语义光标/目标格边框/路径预览点迹) |
| 5 | 系统测试面改址+RunScope 生命周期零变化 | system_test.gd main.X 改址;V3 矩阵取址两处(_modal_flow→main.ui.modals.flow、_row_pacer→main.ui.screens.row_pacer) | 系统测试 V1–V9 全绿(含 V3a–V3i 九阶段×五引用面矩阵,尾缀〔装配生命批 V3〕保留) | 系统测试 | `python tools/run_system_test.py` | 第五引用面逐面同源比对(回调悬挂=红——存活性矩阵判据零变化) | 既有:模态覆盖层编排与输入锁 |
| 6 | 别名/接缝成员消灭(7 个) | main.gd:74/95/96/111/129/134/148 消灭;消费方改址(pacing_queue_test.gd:108/132/147/149、ui_struct_probe、t17_defer_probe、ui_click_probe、main 自身 4 处 _row_queue) | run_all 选跑 pacing_queue 绿(排空零分叉/零丢行/延迟双态/会话清队断言改址后判据不变)+ui_struct_probe 登记序断言+t17_defer_probe 挂起态断言 | 单元+探针 | `godot --headless --path game --script res://tests/run_all.gd -- --only=pacing_queue`;`tools/probe_gate.sh --full` | 属性链与别名取到同一对象引用(断言逐条等价——同一 Array/同一节点的可观测面) | 既有:结算明细带逐行呈现与排播节奏 |
| 7 | 六个 main 纯转发模态方法退役 | main.gd:156/161/282/285/288/292 退役;调用方改指 ui.modals.flow 五个真方法+注入点 main_ui_build.gd:62 | modal_flow 单元套件绿+系统测试 V3g 模态开合段+ui_click_probe 模态开合路径 | 单元+系统测试+探针 | `godot --headless --path game --script res://tests/run_all.gd -- --only=modal_flow`;`python tools/run_system_test.py`;`tools/probe_gate.sh --click` | 经真方法开合编排(遮挡互斥/锁谓词/挂起兜底行为面零变化——开合后可见性与锁态提交面) | 既有:模态覆盖层编排与输入锁 |
| 8 | V1d 源码断言重锚 | source_guard_test.gd:69–77 重锚为全目录扫描(move_child 只许在 ui_registry.gd apply_layer_contract 体内) | 「V1d 层序落位单口」重锚断言,尾缀〔注册面 V1〕 | 单元 | `godot --headless --path game --script res://tests/run_all.gd -- --only=source_guard` | 源码契约扫描面(扫描面>0 前置——全 presentation 目录零第二落位点) | 既有:模态覆盖层编排与输入锁 |
| 9 | V6 源码断言改串 | theme_projection_test.gd:724–725 改断言新连接串 | 「V6 转储入口连接随迁」新串断言,尾缀〔注册面 V2〕 | 单元 | `godot --headless --path game --script res://tests/run_all.gd -- --only=theme_projection` | main.gd 源码含新连接串(同一连接的宿主面改写) | 既有:UI 全局主题与按钮五态(含对比度锚) |
| 10 | 视觉零变化主证 | 全批呈现层地址重构(像素面零改动) | render_gate golden 零差异(shot_probe 七屏+菜单 golden+棋盘 golden) | 探针/golden | `tools/render_gate.sh` | 截图与基线图逐像素容差零差异(视觉零变化的独立主证——出现任何此前不存在的差异即 L3) | 既有:站桩敌人呈现与结算演出落点 |
| 11 | 改址完整性收口 | 全批改址面(49 名逐名) | 批末代码域闸全绿(`tools/run_all_gates.sh --code`,02 横切面回落全量套件);映射表驱动 grep 自检=T3 步骤义务(静态判据,见域口径申报) | 全量闸 | `tools/run_all_gates.sh --code` | 所选域全绿回执 | 既有:模态覆盖层编排与输入锁 |
**测试削弱申报**(实现期允许的旧断言改动全集,超出即审计判红):
1. V1d:扫描面从「main.gd 单文件」扩为「全 game/presentation/*.gd」——判据强化,非削弱。
2. V6:断言串从 main.gd 旧连接串改为新连接串——同一连接的宿主面改写,断言不删除。
3. 冒烟/系统测试/探针/pacing 各断言:只改地址字面,判据与既有尾缀不动——零删除、零放宽、零换下层直调。
4. 七别名+六转发方法随批退役=test-conventions §5.5 同生死条款的执行:消费方断言已全部改指新地址,旧地址无断言残留(T3 grep 自检为证)。
**独立验收审计**:入口与报告=`reports/iter<N>-验收审计-<日期>.md`;审计方=未参与实现的会话或子代理,逐行核对对照表、抽查判据绑定面、检查测试削弱、核对静态判据行的观测面局限注记;未过不得合并。
## 9. 异常分级
- **L1 自救**:单点漏改址→grep 定位补改后重跑该闸段;`--only` 选跑零命中(用法错 exit 2)→修正选词重跑;探针段超时→孤立复跑该段定位。
- **L2 记录继续**:同一红闸连续 3 次同因→升级记录并在实现报告「实现决定记录」节记因后继续最窄确认。
- **L3 停机写报告等用户**:
1. **行为零变化契约触探**——任一闸出现改前不存在的红且定位为层序/时序/接线行为变化;render golden 出现任何此前不存在的差异。
2. **机检预算互斥=上游缺陷停卡退回写卡段**——四新件或 main 终态实测超 §14 预算、或 static_scan 出基线外 NEW 红键;禁开豁免、禁自造第三条路。
3. T0 对账失败——49 名逐一对账与表 A/B/C 任一名对不上,或发现未登记的 main.gd 源码字符串断言。
4. 拆分边界④触发——按纪律拆不出内聚单元(本设计已拆出,若实现期发现表 A 归档错误的成员强行迁入会破集体身份时适用)。
## 10. 代拍板白名单(逐条列,超清单记实现报告「实现决定记录」)
1. 改址机械改写:映射表内旧→新地址的行内改写、被改行注释内旧地址字面同步更新(判据不动)。
2. 重锚断言的消息文字措辞(V1d/V6 两条——尾缀〔注册面 V1〕〔注册面 V2〕与判据不变)。
3. 迁移函数/成员头注按新宿主改写指址(词面随迁、语义不改)。
4. 探针内局部承接变量名保留或内联(`var bv` 型——判据不变)。
5. grep 自检留档在实现报告内的节名与格式。
6. ui_screens 三屏壳句柄静态类型在 Control 与实测场景根实际基类之间取(判据=S9 过+赋值编译过;成员名与地址面不变)。
7. main 内部调用点在 T2 先改真方法、转发方法留至 T4 删除的批内中间态时序(终态零转发壳)。
## 11. 待裁点
**零待裁点,开工门=U0。** 设计文档 §8 五项待裁点已于 2026-10-29 用户全裁:①注册面拓扑=一门面+三域容器;②合同机器随批迁入注册面;③七别名消灭+六转发方法退役+容器内成员去下划线——清单整体确认;④run_all 关联档口径=main.gd 触组合根按横切面回落全部套件;⑤编批归迭代编排段定(本卡估时 3–4 个工作日在冻结线内)。
## 12. 落位与可复用性预检
**复用面**(逐个排除既有件——为什么不能复用):
- **modal_flow.gd(ModalFlow)**:模态编排纯逻辑——开合编排、输入锁谓词、T17 挂起。它管行为不管地址;注册面管「元素清单、层序、寻址」,是它的宿主容器(flow 挂在 ui_modals 里)。职责语句不同,不能拿它当注册面。
- **modal_stack.gd(ModalStack)**:登记册数据结构(遮挡记账),被 ModalFlow 持有;层序合同表与三域寻址不归它。非候选。
- **ui_assembler.gd**:无态静态装配工厂——装配期造控件用完即弃,不持任何句柄;注册面是随 main 常驻的句柄容器。把「造」和「持」并进一件会让静态工厂变有态,破坏现行职责。
- **run_scope.gd**:局态节点——装的是会话状态不是界面元素清单;173 处探针引用零迁移义务已核。非候选。
- 形态先例(非复用对象):ConfigDB 迭代 41 三张域容器(config_domain_combat/run/crossrun.gd)解决过同构的成员数超标问题——本批三容器即同一形态在呈现层的落法。
**唯一面**:层序合同唯一事实源随迁 ui_registry.LAYER_CONTRACT(main.gd 侧删除,不双写);合同寻址唯一口=ui_registry.node();模态登记唯一口=ui_modals.register_layer()。2026-10-29 实查 game/presentation/ 下无 ui_registry/ui_screens/ui_battle/ui_modals 同名或同义件(architecture v1.25 登记「实现批建件」即此四名,盘上未建)——新增无第二落点。
**分层与交互面**(调用路径显式):
- 读地址路径:views/探针/流程件 → `main.ui.<域容器>.<句柄>` → 容器字段 → 节点。三段式每段有领域含义(组合根→注册面→域→元素),与 ConfigDB 的 `db.<域容器>.<成员>` 两段式同构。
- 注册面禁反向持有:不持 main、不持 run_scope、零信号连接、零核心写调用、零 `_process`——依赖单向(views→信号→组合根→core)零触碰;组合根单点装配不变(信号连接仍在组合根与 main_ui_build)。
- 构造路径:main._ready 建 `ui = UiRegistry.new()`(门面自建三容器),main_ui_build 八步向容器登记;四件全 RefCounted 不挂树(节点本体树位与 add_child 归属零变化——row_pacer 仍 add_child 到 main,注册面只持引用)。
- Core 零 UI 红线零触碰:本批改动全部在 game/presentation/ 与测试面。
## 13. 禁为机检文本保留无效成员(重构类卡必填条款)
禁止为迎合机检消息文本(含计数)而保留或新增无效成员/别名:main.gd 终态 15 个类变量必须个个有 §7.1 表 B 的职责理由,禁留空占位或替身成员凑计数;四新件的字段必须个个是表 A 在册句柄或 flow,禁加「以防万一」的空槽。机检键与本卡契约互斥时(如实测出新基线键 NEW 红、或键账与申报不符),实现段一律停卡呈报走 L3,不得自造第三条路。判据权威=code-conventions §1.1⑤。
## 14. 实现规范预算(gdstyle 默认阈值:公开方法 ≤20、类变量 ≤15、单函数分支 ≤8、返回 ≤6)
| 新件 | 公开方法 | 类变量 | 阈值判定 |
|---|---|---|---|
| ui_registry.gd | 2(node/apply_layer_contract) | 3(三容器属性;LAYER_CONTRACT 为常量不占 var) | 双达 |
| ui_screens.gd | 0 | 9 | 双达 |
| ui_battle.gd | 0 | 5 | 双达 |
| ui_modals.gd | 1(register_layer) | 14(13 句柄+flow) | 双达(余量 1——第 14 个模态句柄出现即触发拆分审视,作发现信号用) |
- 迁移函数对账:`_apply_layer_contract`/`_layer_node`/`_register_modal` 自 main.gd 迁入,T0 查 gdstyle_baseline.txt 源函数键——超默认登记值的迁移即拆函数(拆分不改语义);node(key) 的 19 键 match 与合同落位循环预期在默认分支阈内(设计文档 §7 同判断),实测出新键=基线外 NEW 红=L3 停卡(禁开豁免)。
- 存量触面一查:本批触碰的 presentation 存量件(main.gd/main_ui_build.gd/三流程件)预期「S13 键较登记值只降不升」——main.gd 49→15;main_ui_build 与三流程件零成员变化(仅语句内地址改写);达成手段=表 A/C 全量迁移+别名净消灭。
- 指标例外申报:无(本批不需要任何超默认面;main.gd 改后 15 在阈内,S13 豁免登记注销后不留新例外)。
## 15. 源码级断言与探针契约面的随批义务(防漏项清单)
1. V1d(source_guard_test.gd:69–77)与 V6(theme_projection_test.gd:724–725)随批重锚——本卡已全量排查 main.gd 源码断言面仅此两条(T0 复核义务不豁免)。
2. 探针段覆盖义务:probe_gate 必须 `--click`+`--full` 全跑——ui_click_probe 是最大改址户,只跑默认段会漏最深的改址面。
3. 冒烟 V1 族 get() 键、系统测试 V1c/V2/V3 取址、pacing `_row_queue` 三处——都在 §7.1 表 D 与 T3 清单内,T0 映射表生成后逐条打钩对账。
@@ -1,447 +1,308 @@
# 需求卡片:营地场景图新建批(交互式营地 · 七物件绑定 · 四柜台拆解)· 营地交互重做卡④
- 版本:**v3.0(现行有效卡)**。留痕:2026-10-21 用户令退回美术设计段待闭合;2026-10-31 用户令重立——美术设计已闭合(样张过审+art-bible 条款版本),据 req-card 第〇步重立为现行有效卡,零设计待裁点。
- 来源:[需求澄清-营地交互重做-2026-10-18.md](需求澄清-营地交互重做-2026-10-18.md)(目标体验原话/目标结构树+纵深稿/裁决 5·6·7·8·10/验收方式/切批原则④)+ 样张过审(2026-10-31 用户裁定,清单 [artwork/candidates/_终稿裁定-2026-10-31.txt](../artwork/candidates/_终稿裁定-2026-10-31.txt):各素材第一张样本稿为终稿、保留全部待选稿)+ [art-bible.md](../design/art/art-bible.md) v3.24 §6.2(营地场景 10 层口径)(**唯一事实源**:样张过审 2026-10-31 + art-bible.md v3.24 §6.2;配套 [camp.md](../design/gdd/ux/camp.md) v2.2/[camp-scene-prompts.md](../design/art/camp-scene-prompts.md) v1.2/[asset-path-map.md](../design/art/asset-path-map.md)/[art-assets-checklist.md](../design/art/art-assets-checklist.md) §3.5 同步;需求澄清为目标体验事实源)
- 版本:**v2.3**(2026-10-21 用户令:**退回美术设计段**——美术轨凭据缺(P1–P5 未销号),按 req-card 第〇步不具写卡资格;**本卡非有效卡**,内容保留作美术设计段输入(Q4/Q5/Q6/Q8 已裁记录+七物件绑定表+七物件绑定现状定性),美术设计闭合(样张过审+art-bible 条款版本)后**重立卡**,再谈编迭代。🔴 归属纪律:卡只登记缺口与已有裁断,前置由谁解决/何时解决/设计稿与素材由谁产出**由用户定**(美术/设计线=用户自立批,铁律 2),Agent 不代跑不代产)
- 来源:[需求澄清-营地交互重做-2026-10-18.md](需求澄清-营地交互重做-2026-10-18.md)(唯一事实源:①目标体验原话、②参照与反参照、③非目标、④目标结构树+纵深稿、⑤裁决 5/6/7/8/10、⑥验收方式、⑦切批原则④、⑧遗留)+ [camp.md](../design/gdd/ux/camp.md) v1.5 + [art-bible](../design/art/art-bible.md) §6.2/§7.5
- 归属:呈现层+美术线(`game/presentation/` + 场景素材)——营地交互重做五卡之四,**最大件**
- 排期:未编入(2026-10-18 用户令:需求卡片不预占迭代号,批次归属按工作量另裁)
- 开工门:**零设计待裁点,开工门=U0**;编入迭代由 iter-plan 段发令,代码段按 `/iter` 开工,代码段开工门见 §0(不阻塞本卡作为有效卡与编迭代)
- 开工门:**前置条件销号后进代码实现**(设计前置闸纪律不变:设计定稿前禁 `/iter` 开本卡代码段——美术素材线按铁律 2 走自立批并行推进,不占迭代位);前置解决清单见下方
## 🔧 状态:现行有效卡(v3.0,2026-10-31 重立)
## 🔧 状态:已退回美术设计段 · 非有效卡(2026-10-21 用户令;美术设计闭合后重立卡,再谈编迭代)
本卡设计线已闭合,凭据见 §0「重立凭据」:样张过审(2026-10-31)+ art-bible v3.24 §6.2 条款版本齐备。设计待裁点清零、开工门=U0;未编入迭代,编入由 iter-plan 段发令。属呈现层+美术线,五卡之四。
**背景**:本卡是新内容+新美术件需求,按 2026-10-10 用户立规(req-card 设计前置检查),设计定稿前不进代码实现。v1.x 曾用「待裁点」覆盖设计缺项(渠道/规格/设计稿/参照物),违立规;v2.0 一度按「回设计段」移出序列;v2.1 一度把「批内解决」执行成「Agent 代跑设计稿」——**v2.2 用户令终订:本卡是批内成员,前置条件在批内登记、逐项销号;但由谁解决、何时解决由用户定,美术/设计线是用户自立批(铁律 2),Agent 不代跑不代产**。设计前置闸纪律不变(设计定稿前禁 `/iter` 开本卡代码段),执行方式是「批内销号」而非剔除,也非 Agent 代劳。
**归属纪律**:本卡只登记代码段开工门与已裁断。前置由谁解决、何时解决、设计稿与素材由谁产出由用户定——美术/设计线=用户自立批(铁律 2),Agent 不代跑、不代产、不自行开工设计稿。素材终稿落 `game/assets/art/` 属实现段 T1/`asset-ingest` 第 3 步,不属写卡门(用户 2026-10-31 令:只生成素材、不做后处理,开工时另发令)。
**前置条件销号清单**(五项重启条件转为批内登记项):
**批内批次次序(铁律 2:美术素材走自立批、不占迭代位;先产图后改代码)**:美术设计已闭合(样张过审)→ 场景素材后处理与入库(自立批,产物 `artwork/`→`game/assets/art/scene/`)→ 本卡代码段 `/iter`(与卡⑤ 同波)。工程面 ①②③ 代码已随迭代 33 合回(卡①②③ 已按吸收即死退役);④⑤ 未编排,编入哪一迭代由用户经迭代编排段发令。
| # | 前置条件 | 归属 | 状态(2026-10-18) | 解决路径 |
| -- | ------------------------- | -------------------------- | -------------- | ----------------------------------------------------------------------------------- |
| P1 | Q1 美术渠道裁定(A/B) | **用户**(一句话裁) | ⬜ 待裁 | 阻塞场景方向稿与规格路径分支;裁后由用户定推进方式 |
| P2 | 像素规格有着落 | 用户线(裁断已在卡:Q6 甲) | 🟨 半消 | Q6 甲已裁:Q1 裁 A 时用过渡规格(1280 工程档+烛光黄 #F6C667/木色 #8A5A34);终档归样张批冻结清单后置换(反哺点登记)——执行由用户线定 |
| P3 | 点选反馈设计稿(悬停高亮/提示文案/可点区域判定) | **用户线**(美术/设计归用户自立批——铁律 2) | ⬜ 未启动 | 澄清⑧3 已登记缺口;产出方式有备(Q8 甲=出稿呈裁)但**未受命开工**——2026-10-18 曾越权起草 v0.1,已按用户令撤回;待用户方向 |
| P4 | 参照物 | **用户**后续找 | ⬜ 待补 | 找到后与纵深稿对表;结构性冲突=呈报订正构图,禁批内私改 |
| P5 | GDD/art-bible 营地条款落文 | 文档批(P1–P4 定稿后,用户发令) | ⬜ 未启动 | camp.md 整体改版+art-bible §6.2/§7.5/§2.8 改版 |
## 0. 前置依赖与代码段开工门
**批内批次次序(铁律 2:美术素材走自立批、不占迭代位;先产图后改代码)**:P1–P4 销号(设计定稿)→ 场景图美术产出(自立批,素材线并行推进,产物归档 artwork/→game/assets/art/)→ P5 文档落文 → 本卡代码段 `/iter`(与 ⑤ 同波)。工程面 ①②③ 代码在美术线推进期间并行开发、先行交付(③ 进档落点按 Q3 裁定乙暂行接现役 CampOverlay,本卡落地时改挂)——**四卡同在批内,分波收口,不是剔除**。
### 0.1 重立凭据(已齐,非待裁点)
**归属纪律(2026-10-18 用户令订正,v2.2)**:本卡只负责**登记前置缺口与已有裁断**;前置条件由谁来解决、何时解决、设计稿/素材由谁产出,**由用户定**——美术/设计线是用户自立批(铁律 2),Agent 不代跑、不代产、不自行开工设计稿。本卡曾越权起草点选反馈设计稿 v0.1(2026-10-18),已按用户令撤回删除;Q8(出稿呈裁)仅是「若用户发令出稿时的产出方式」预裁,非开工授权。
req-card 第〇步+卡头 2026-10-21 退回令口径=美术设计闭合(样张过审+art-bible 条款版本)。两样已齐:
**已裁事项(2026-10-18 grilling 轮次)**:
- **样张过审**=用户 2026-10-31 裁定「保留全部待选稿、各素材第一张样本稿为终稿、每个都还可以接受」(清单 `artwork/candidates/_终稿裁定-2026-10-31.txt`),用户准备在游戏内做最终审核。
- **art-bible 条款版本**=`art-bible.md v3.24 §6.2`(营地场景 10 层口径;camp.md v2.2/camp-scene-prompts.md v1.2/asset-path-map.md/art-assets-checklist.md §3.5/评估报告同步)。
- Q4=甲:最近冒险条带随四柜台拆解撤下,生涯.md P6 同批注销(代拍板留痕);
- Q5=甲:ConfirmDialog 扩第三钮(继续上一段冒险/开始新冒险/取消,cancelled 恒=无变更退回营地);
- Q6=甲:Q1 裁 A 时过渡尺寸档=现役 1280 工程档+烛光黄 #F6C667/木色 #8A5A34 既有规格,终档归样张批冻结后置换(反哺点登记);
- Q8=甲:设计稿产出方式=批内出稿呈裁(方向稿先行纪律照旧——2~3 张低成本方向稿供选划,判完方向才精制);
- Q3 设计稿只覆盖根态点选反馈;进界面后的叠层规则随承载形态裁定派生(独立全屏页=场景根隐藏/单一内页切换=场景根留底)。
两样齐 ⇒ 重立卡判据齐,本卡为现行有效卡。P3/P5 等未销号项属**代码段开工门**,不阻塞重立卡。
**仍待用户裁**:Q1 美术渠道 A/B(我的推荐:**A · CC0 改色**——06:23 已有配色规格、成本低、方向稿不受「从零构图」拖累;B 依赖规格清单输入且周期长。你说过不替你选,但我把推荐摊开了,等你一句 A 或 B,方向稿当天就能出);Q2 参照物(你后续找)。
### 0.2 P1–P5 前置现状(已裁/已补项写进卡,不再当待裁点)
## 0. 前置依赖与并行性(批内视角,v2.1)
| # | 前置条件 | 归属 | 现状 | 落点 |
| -- | ------- | ---- | ---- | ---- |
| P1 | Q1 美术渠道裁定(A/B) | 用户 | **已裁=B·插画级新产**(2026-10-22);✦ 渠道作者自跑远程生图管线,规格沿用 art-bible §6.2/§8.1/§8.2 既有裁决 | art-assets-checklist.md §3.5 |
| P2 | 像素规格 | 用户线 | **Q6 甲过渡口径已裁**:现役 1280 工程档(1280×800)+烛光黄 #F6C667/木色 #8A5A34;2× 源档出图、最近邻降采样;终档归样张批冻结清单后置换(反哺点登记),执行归用户线 | 契约 8 |
| P3 | 点选反馈设计稿(悬停高亮/提示文案/可点区域判定) | 用户线 | **代码段开工门**:camp.md v2.2 已定四态规格;设计稿细化未受命开工,Agent 不代跑不代产 | §0.3 |
| P4 | 参照物 | 用户 | **已补**(2026-10-23)=`artwork/2026-10-23-营地场景/Gemini_Generated_Image_ykrc0nykrc0nykrc.jpg`,已进 camp-scene-prompts.md §1 登记为「作者提供的参照物」,与纵深稿对过表、围墙结构冲突已呈报;参照物只是参考图,保留 `artwork/`、不入 git、不入游戏目录 | camp-scene-prompts.md §1 |
| P5 | GDD/art-bible 营地条款落文 | 文档批(用户发令) | **代码段开工门**:camp.md v2.2/art-bible v3.24 §6.2 已先行落文新形态;实装状态回填与 §7.5/§2.8 同步归文档批,实现批禁写 `design/` | §5 反哺点 |
> 本卡在批内,前置条件解决中(见卡头销号清单)——本节描述批内并行关系,非排期承诺。
### 0.3 代码段 `/iter` 开工门(不是设计待裁点,不阻塞重立卡与编迭代)
下列项属代码段开工门;未销号即需开工对应任务段=§8 L3 停机呈报,禁批内自补、禁 T0 现场发挥:
1. **P3 点选反馈设计稿**:悬停高亮/提示文案/可点区域判定三项细化稿(camp.md v2.2 已定四态规格与名牌参数,设计稿只细化呈现,不阻塞本卡成立)。
2. **P5 GDD/art-bible 条款落文**:文档批对实装状态、§7.5/§2.8 的回填(实现批禁写 `design/`,逐条列 `reports/iter<N>-反哺点-<日期>.md`)。
3. **camp-scene-prompts.md §5 五个待裁点**:帐篷尺寸(现 300×170 待重定)/门扇高宽(现 240×220,围墙带仅 43px 高、叠放关系待裁)/布告板位置(现 y330 悬空、建议 (845,268,130,140) 挂回围墙带)/描边颜色追认(现按奶油色、去底技术前提,改深灰褐须换去底方案)/营地环境子板色值(art-bible §4.1 数值单点,待作者拍板)。五点阻塞坐标表定稿与接线,不阻塞出图(样张已过审)。
4. **十张终稿后处理与入库**:终稿此刻=原始候选图本身(带通道水印、浅灰不透明底、画布 2560×1600 或 1024×1024),未做去底/擦水印/降采样/裁围墙细条;落 `game/assets/art/scene/` 属实现段 T1/`asset-ingest` 第 3 步,用户 2026-10-31 令只生成素材不做后续工序,开工时另发令。
### 0.4 10 层拆分(现行口径,覆盖旧 8/9 张)
| z | 层 | 内容 | 可点 |
| -- | -- | ---- | ---- |
| z0 | `scene_camp_bg` | 不透明全幅=天空+远山+整片地面+门洞内一条通向远处的小路 | 否 |
| z1 | `scene_camp_wall` | 透明底,横贯全宽密排竖木桩墙(左右两段)+两根略高门柱;门洞 x520–760 留透明缺口透出 bg 小路;落盘按细条 (0,240,1280,70) 裁、不做全幅 | 否 |
| z2 | `scene_camp_board` 布告板 | 挂围墙带,点进图鉴占位 | 是 |
| z3 | `scene_camp_gate` 门扇 | 半开双扇,叠在门洞上(高宽待 §0.3 裁) | 是 |
| z4 | `scene_camp_dummy` 木桩/`scene_camp_forge` 锻炉/`scene_camp_tent` 帐篷 | 木桩、锻炉可点;帐篷承载件不可点 | 部分 |
| z5 | `scene_camp_chest` 宝箱/`scene_camp_notebook` 笔记本 | 宝箱、帐篷旁笔记本 | 是 |
| z6 | `scene_camp_campfire` 篝火 | 最前;命中矩形只取下半(火堆),上半火焰只展示 | 是 |
围墙从背景层独立成层(z1),门洞小路画在 bg 层(z0)。**中景带自画面底部往上约 2/3 处起**;近景物件可压住围墙,**唯一例外=中间门洞必须留空、不被任何物件遮挡**。坐标草案与分层验收判据见 [camp-scene-prompts.md](../design/art/camp-scene-prompts.md) §2.3/§4(10 张口径现行事实源)与 [布局草案-1280x800.html](../artwork/2026-10-23-营地场景/布局草案-1280x800.html)。
### 0.5 跨卡接口与并行性(批内视角,非排期承诺)
- 卡③(选档界面)Q3 已裁乙:随 ①②③ 工程波先行时进档/新档暂行接现役 CampOverlay——**本卡代码波落地后,营地入口从现役 CampOverlay 改挂场景图,现役 CampOverlay 随之拆解退役**(卡③ 暂行接线与本次改挂的二次验证面在卡③ T2/实现报告登记)。
- 卡⑤(ESC 浮窗与营地顶栏)落在本批新建的场景屏顶栏位——两卡触碰同一新屏,建议同批或卡⑤ 随后。**跨卡接口**:①场景屏顶栏位(T2 预留);②**营地刷新单口**(T3 定义:各写口尾→现开界面刷新+场景根 HUD 刷新一闸完成)——卡⑤ HUD 刷新挂该单口,非已退役的 `refresh_camp`;③ConfirmDialog 三钮化与消费方编排(T4,卡③ 契约 3 同款互指);④子界面返回钮承诺(T3);⑤篝火二次确认走 ConfirmDialog 先例(camp.md v2.2 已裁必须)。
- 样张线关系:营地屏整屏样张是 art-bible §1.4 四屏之一,现列 06「待设计」排队行——本卡不跑整屏样张闸、不替代样张批,只按既有约束(契约 7/9)生产与自检;营地屏样张义务留原排队行(反哺点注记)。文档既定序列(排队行措辞「终稿后再出样」)本就终稿先于营地样张,故 T1 终稿落盘不构成违背 art-bible §7.5「前置」条(§5 反哺点已注)。
- 卡③(选档界面)Q3 已裁乙:随①②③工程波先行时进档/新档暂行接现役 CampOverlay——**本卡代码波落地后,营地入口从现役 CampOverlay 改挂场景图,现役 CampOverlay 随之拆解退役**(卡③暂行接线与本次改挂的二次验证面在卡③ T2/实现报告登记)。
- 卡⑤(ESC 浮窗与营地顶栏)落在本批新建的场景屏顶栏位——两卡触碰同一新屏,建议同批或卡⑤随后。**跨卡接口(v1.1 补全)**:①场景屏顶栏位(T2 预留);②**营地刷新单口**(T3 定义:各写口尾→现开界面刷新+场景根 HUD 刷新一闸完成)——卡⑤ HUD 刷新挂该单口,非已退役的 `refresh_camp`;③ConfirmDialog 三钮化与消费方编排(T4,卡③ 契约 3 同款互指);④子界面返回钮承诺(T3)。
- 美术线与代码线的批次关系:T1(素材产出)与 T2–T4(代码)可分批——素材先归档齐、代码后挂(用户批次归属裁,本卡不预占)。
- 样张线关系:**营地屏的整屏样张是 art-bible §1.4 四屏之一,现列 06「待设计」排队行**(样张批 Q2 甲案:本批只判战斗屏,余三屏排队)——本卡**不跑整屏样张闸、不替代样张批**,只按既有约束(§3 契约 7/9)生产与自检;营地屏样张义务留原排队行(反哺点注记)。文档既定序列(排队行措辞「终稿后再出样」)本就终稿先于营地样张,故 T1 终稿落盘不构成违背 art-bible §7.5「前置」条(§5 反哺点已注)。
## 1. 目标与完成定义
**目标(澄清①一句提炼照录)**:营地首页从「文字按钮菜单 + 列表式覆盖层」改为「**一张可点击的营地场景图**」——点场景中的具体物件进入对应功能界面。用户原话照录:「我是希望有一个营地地图的游戏画面;或者是一张营地的图片,跟 UI 的交互是点击图片中的某一处地方,然后再进入界面。不是完全普通的那种 UI 设计,不是各种框框的……我点击某些具体的东西之后,就可以进入对应的操作界面。」(称呼订正:「它就是一个营地的画面;并不是一张地图。」)
**目标(澄清①一句提炼照录)**:营地首页从「文字按钮菜单 + 列表式覆盖层」改为「**一张可点击的营地场景图**」——点场景中的具体物件进入对应功能界面。用户原话照录:「我是希望有一个营地地图的游戏画面;或者是一张营地的图片,跟 UI 的交互是点击图片中的某一处地方,然后再进入界面。不是完全普通的那种 UI 设计,不是各种框框的……我点击某些具体的东西之后,就可以进入对应的操作界面。」(称呼订正:「它就是一个营地的画面;并不是一张地图。」)
**七物件绑定(camp.md v2.2 §场景构成与七物件绑定,逐一落地)**:
**七物件绑定(澄清④结构树照录,逐一落地)**:
| 物件 | 进入 | 备注(现状定性+现行约束) |
| ---- | ---- | ------------------------ |
| 大门(半开门扇,门洞内一条通向远处的小路) | 冒险(选路屏/战斗屏已实现不动;断点弹窗移位) | 入口新建+动线迁移;点大门永远先出确认(有断点=三出口,无=是否开始新冒险) |
| 锻炉·铁砧 | 锻造工坊 | 界面已实现·入口改挂;未解锁=禁用态(降明度+去饱和) |
| 宝箱 | 秘宝匣 | 界面已实现·入口改挂;未解锁=禁用态 |
| 帐篷旁笔记本 | 生涯记录 | 界面已实现·入口改挂;生涯页返回钮文案禁含「营地」字样 |
| 木桩 | 树淬炼天赋树 | 界面已实现·入口改挂 |
| 布告板/悬赏板 | 奖励格图鉴 | 界面已实现·入口改挂;内容冻结未激活,点进看占位(**不是禁用态**) |
| 篝火 | 离开营地/回主菜单 | 新建小动线;**必须二次确认**;命中区只含火堆、不含火焰 |
| 帐篷 | — | 承载件不可点;落地尺寸与占位范围待作者重定(代码段开工门,camp-scene-prompts §5) |
| 物件 | 绑定目标 | 现状定性 |
| ------- | -------------------------- | ------------ |
| 营地大门 | 冒险(选路屏/战斗屏已实现,不动;断点弹窗保留移位) | 入口新建+动线迁徒 |
| 锻炉·铁砧 | 锻造工坊 | 界面已实现 · 入口改挂 |
| 宝箱 | 秘宝匣 | 界面已实现 · 入口改挂 |
| 床铺旁笔记本 | 生涯记录 | 界面已实现 · 入口改挂 |
| 木桩 | 树淬炼天赋树 | 界面已实现 · 入口改挂 |
| 布告板/悬赏板 | 奖励格图鉴 | 界面已实现 · 入口改挂 |
| 篝火 | 离开营地/回主菜单 | 新建小动线 |
**纵深稿(用户原话照录)**:「远景是天空;中景是一个围栏,还有营地大门;近景中间是一个篝火;左边是锻炉铁砧;右边是我们的床铺,宝箱等。」(承载件落地为帐篷,见 §0.4 z4。)
**纵深稿(用户原话照录)**:「远景是天空;中景是一个围栏,还有营地大门;近景中间是一个篝火;左边是锻炉铁砧;右边是我们的床铺,宝箱等。」
**大门两分支(裁决 5 照录,Q5 已裁=甲)**:有未完冒险 → ConfirmDialog 三出口「继续上一段冒险/开始新冒险/取消」;无未完冒险 → 「是否开始新冒险:是/否」。**点大门永远先出确认,不直接进冒险**;cancelled 恒=无变更退回营地。
**大门两分支(裁决 5 照录)**:有未完冒险 → 弹「继续上一段冒险 / 开始新冒险」;无未完冒险 → 弹「是否开始新冒险:是/否」。**点大门永远先出确认,不直接进冒险**(「断点续玩也是开始冒险的两个分支之一……它算是开始冒险的一个子节点」)。**「有断点」分支的三出口弹窗形态待裁(Q5)**——现役 ConfirmDialog 双钮表达不了两个肯定性动作。
**钥石余额(裁决 10 照录)**:场景**顶部小 HUD 栏**(高 48px 全宽窄条、浮层覆盖不挤压画面;承载落卡⑤)。
**钥石余额(裁决 10 照录)**:场景**顶部小 HUD 栏**(用户原话「先按顶部小HUD栏设计」——provisional 措辞留痕;承载落卡⑤)。
**相对现状,新增了什么**:
1. 交互式营地场景图(10 层场景素材+场景屏+七物件命中区与点选交互)——从零新建;
2. 现四柜台覆盖层(CampOverlay)拆解:锻造工坊/秘宝匣/天赋树/奖励格图鉴四界面抽为独立可开界面,入口改挂场景物件;生涯页入口自主菜单改挂帐篷旁笔记本;
3. 大门动线(开始冒险/继续上局两分支+断点确认弹窗从主菜单移位);
4. 篝火回主菜单小动线(带二次确认);场景屏顶栏预留位(卡⑤ HUD);
5. camp 截图断言段与六探针营地段的迁移(**现无 camp 逐像素 golden 基线**——见契约 10)。
1. 交互式营地场景图(场景素材+场景屏+七物件命中区与点选交互)——从零新建;
2. 现四柜台覆盖层(CampOverlay)拆解:锻造工坊/秘宝匣/天赋树/奖励格图鉴四界面抽为独立可开界面,入口改挂场景物件;生涯页入口自主菜单改挂笔记本;
3. 大门动线(开始冒险/继续上局两分支+断点确认弹窗从主菜单移位);
4. 篝火回主菜单小动线;场景屏顶栏预留位(卡⑤ HUD);
5. camp 截图断言段与六探针营地段的迁移(**现无 camp 逐像素 golden 基线**——v1.1 订正,见契约 10)。
**完成定义**:
1. 营地首页=可点击场景图(10 层按 §0.4 铺底、门洞留空);七物件绑定逐一在役,点各物件进对应界面;
2. 四柜台拆解完毕:CampOverlay 覆盖层形态退役,五界面(锻造/秘宝/生涯/天赋树/图鉴)经新入口可达且**功能与写口链路零回归**(presenter 改造=承载面迁移的一部分——见契约 4);
3. 大门两分支确认弹窗在役;点大门不直接进冒险;cancelled 无变更退回;
4. 篝火经二次确认可回主菜单;场景屏顶栏预留位就绪(卡⑤ 联验);
5. camp 截图=场景图形态(迭代内验收=截图对比,澄清⑥);探针断言迁移完毕;
6. 美术约束(48 色板/禁入带/语义色/WCAG)入闸或登记缺口;**用户目检项登记 07**(生命周期末步,不阻塞);
1. 营地首页=可点击场景图;七物件绑定逐一在役,点各物件进对应界面;
2. 四柜台拆解完毕:CampOverlay 覆盖层形态退役,五界面(锻造/秘宝/生涯/天赋树/图鉴)经新入口可达且**功能与写口链路零回归**(presenter 改造=承载面迁移的一部分——见契约 4);
3. 大门两分支确认弹窗在役;点大门不直接进冒险;
4. 篝火可回主菜单;场景屏顶栏预留位就绪(卡⑤联验);
5. camp 截图=场景图形态(迭代内验收=截图对比,澄清⑥);探针断言迁移完毕;
6. 美术约束(48 色板/禁入带/语义色/WCAG)入闸或登记缺口;**用户目检项登记 07**(生命周期末步,不阻塞);
7. 批末重闸按改动域选档全绿;三份 `reports/` 产出物写齐(T6)。
## 2. 现状事实(开工日 T0 复核行号)
## 2. 现状事实(2026-10-18 实查;开工日 T0 复核行号)
| # | 事实 | 出处 |
| --- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| F1 | 营地场景图完全不存在(澄清④判定「完全没有 · 新建」);现营地=CampOverlay 四柜台覆盖层(树淬炼/锻造工坊/秘宝匣/奖励格图鉴并排,迭代 21 T6 程序占位重排——代码注释原文「视觉终稿归 HUD 营地视觉批」) | `需求澄清-营地交互重做-2026-10-18.md` §④;`game/presentation/views/camp_overlay_view.gd:86-87` |
| F2 | 营地屏壳(CampScreen)持 CampOverlay 成员;组合根 `main.camp_overlay` 句柄指向屏壳成员(探针挂载假设) | `game/presentation/scenes/camp_screen.gd:8-14`;`main.gd:112` |
| F3 | CampOverlay 结构:顶栏铭牌+钥石徽(:64-84);四柜台并排横滚(树淬炼 :99-109/锻造工坊 :111-137/秘宝匣 :139-159/奖励格图鉴 :161-172);底栏关闭钮+最近冒险条带(:174-189);钥匙门判据读树投影(:287-296);图鉴柜台=结构位预留(:168「内容排 Alpha」) | `camp_overlay_view.gd` 各处 |
| F4 | 五目标界面现状:锻造工坊=CampOverlay 内工作间(`_forge_workbench` 两区六路线);秘宝匣=`_ws_scroll`/`_workshop_holder`(12 件+同调装配段+Y 升级行);天赋树=`_tree_holder`(脉分组行板+Fork 双态钮);图鉴=占位;生涯=**已独立全屏页**(CareerOverlay,入口现居主菜单生涯钮,自带返回钮) | `camp_overlay_view.gd:116-137`/:144-159/:99-109/:161-172;`views/career_overlay.gd`;`main.gd:332` |
| F5 | 营地购买写口链路:视图只发意图信号(`buy_requested`/`tree_buy_requested`/`forge_*` 等),组合根经 CampShopPresenter 转 MetaProgression 写口;投影数据=`camp_shop_presenter.gd:62-72` `camp_data()` 单点 | `camp_overlay_view.gd:8-15`;`camp_shop_presenter.gd:62-72` |
| F6 | 断点确认弹窗现居主菜单开始冒险路径(有断点先出 ConfirmDialog 再开局)——随卡②撤钮整体移交本卡大门 | `main.gd:475-497` |
| F7 | 冒险屏已实现不动:选路屏(LevelMapScreen,`route_chosen` 前进唯一通道)与战斗屏宿住 AdventureScreen;组合根侧:`_start_adventure_from_menu`(:475-484)/`_on_confirm_new_adventure`(:487-492)/`_resume_from_menu`(:518-536)/`_start_adventure`(:579-597)/`build_adventure_params`(:564-574) | `views/level_map_screen.gd:7`;`scenes/adventure_screen.gd:36-37`;`main.gd` 各处 |
| F8 | 探针面营地段(全部随本批迁移):ui_probe(营地入口+余额+秘宝匣 12 行断言 :28-55,深员 `_balance_label`/`_tree_buy_btns`/`_workshop_rows` :39-52)、ui_click_probe(营地购买全链 :53-127;**断点确认段 :500-528**〔经 lvbtn 驱动 ConfirmDialog 取消/开新冒险——被卡②撤钮+本批弹窗移位双杀〕)、screen_flow_probe(营地可见态键 :53 直读 `main.camp_overlay.visible`;营地开合 :109-125 回退段直呼 `main.camp_overlay.closed.emit()`;菜单→冒险 lvbtn 步 :130-136)、shot_probe(camp 截图+「关闭营地」钮收闭 :126-133)、ui_struct_probe(camp 结构审计 :41-49;同槽特例断言 :331/:373)、smoke_all(V2 营地屏壳实例化 :170-171;V3g 营地模态开合 :405-435;**camp_overlay_view.gd 源码断言段 :6469-6475**〔三条锁四柜台等高形态本身——`Vector2(0,336)`×3/`SIZE_FILL`×4/`SIZE_SHRINK_CENTER`≥3,随形态退役〕)、ui_contrast_probe(营地令牌段 :48-55〔UiKit 令牌恒等式,不随拆解红;新界面若不再消费 `CAMP_HEADER_BAND`/`CAMP_ROW_PLATE` 则段标签虚挂,须核签〕)、**forge_workbench_test.gd 单测**(:33 直载 camp_overlay_view.gd 并消费 `_forge_rows`/`_forge_workbench`/`open_camp`/`refresh_camp`/三 forge 信号——CampOverlay 一删即红) | `game/smoke/` 各处+`game/tests/unit/presentation/forge_workbench_test.gd:33` |
| F9 | camp UX spec 现行 **camp.md v2.2** 已落文可点击场景图形态(定位/场景构成与七物件绑定/10 层拆分/点选反馈四态/顶栏 48px/叠层与开合);本批实现=**对齐** v2.2,旧三柜台形态已由 v2.2 取代,本批只需回填实装状态与目检结论 | `design/gdd/ux/camp.md:10-51` |
| F10 | art-bible 现行 **v3.24 §6.2** 已落文营地场景 10 层口径(z0 bg 不透明全幅/z1 wall 透明细条门洞缺口/八物件层/篝火命中只下半/围墙落盘 (0,240,1280,70));§7.5 营地界面已改为「可点击场景图+七物件点选」画法;§2.8 承载元素同述;本批实现=对齐现行条款 | `design/art/art-bible.md` §6.2/§7.5/§2.8 |
| F11 | 图鉴内容在册挂起:奖励格图鉴柜台已随配比预设批整体挂起冻结(2026-10-05 用户令,06 在册),重启须用户另行发令——本批只改入口不激活内容 | `design/gdd/systems/跨局循环/生涯.md:63` |
| F12 | 贴图重构批搁置未废:营地与元进度件终稿置换(06:21-27)等交互重做定形后再议(澄清③1/§⑧5)——本批不清偿该债;四柜台拆解后原「柜台场景贴图」债对象变化,随该批重新评估 | `design/gdd/06-待办清单.md:21-27`;`需求澄清-营地交互重做-2026-10-18.md` §③1/§⑧5 |
| F13 | 营地底栏「最近冒险」条带与生涯历史回看同源(同一份 `recent_summaries`),其去留=生涯.md P6 待裁点(期二必答)——CampOverlay 拆解后该条带无处挂,**Q4 已裁=甲**(随四柜台拆解撤下,逐局历史回看归生涯,生涯.md P6 同批注销) | `camp_overlay_view.gd:186-189`/:536-549;`生涯.md:69` |
| F14 | 素材线纪律:`artwork/` 不入 git(`.gitignore:51` 忽略行)——批次 worktree 内无该目录、主工作区 D:/code/g-plan2 实体存在(在途工作区);涉素材脚本须传主区绝对路径否则静默 0 张;素材替换前先归档旧档;终稿归 `game/assets/art/scene/`,消费常量 `UiKit.TEX_CAMP_*`(asset-path-map.md §3/art-assets-checklist.md §3.5) | `AGENTS.md:32`;`.gitignore:51`;art-bible §8.3 归档纪律 |
| F15 | 美术硬约束继续有效(澄清③4):明亮轻快像素风、**48 色板、HSV 300°–345° 禁入带、语义色纪律、WCAG ≥4.5:1**——全局约束,不在本讨论范围翻案 | `需求澄清-营地交互重做-2026-10-18.md` §③4 |
| F16 | 像素级规格已定(Q6 甲过渡口径+渠道 B):1280×800 工程档、烛光黄 #F6C667/木色 #8A5A34、2× 源档出图最近邻降采样(art-assets-checklist.md §3.5);终档归样张批冻结清单后置换(反哺点);卡内禁自定像素规格数值 | `design/art/art-assets-checklist.md` §3.5;`design/art/art-bible.md` §6.2 |
| F17 | 机检工具面:**截屏级 48 色计数不在役**;在役=`tools/palette_check.py`(art-bible §8.3①挂点——48 设计色板令牌+新增色双门)+`tools/standee_asset_check.py`(像素画单张 32 色冻结执法);`tools/render_gate.sh`(shot_probe 七屏→shot_checker 语义断言;golden 段=棋盘三张+menu_boot 四张,**无 camp golden**——shot_checker.py:143 明载「camp/level 走骨架+目检清单」);shot_checker 段=屏级骨架/文字 WCAG/明度三档带/文字禁压纹理/文字在判据 | `tools/palette_check.py`;`tools/standee_asset_check.py`;`tools/render_gate.sh`;`tools/shot_checker.py:143` |
| F18 | 参照物已补(2026-10-23)=`artwork/2026-10-23-营地场景/Gemini_Generated_Image_ykrc0nykrc0nykrc.jpg`,已进 camp-scene-prompts.md §1 风格参考图表登记为「作者提供的参照物」,与纵深稿对过表、围墙结构冲突已呈报;参照物只是参考图,保留 `artwork/`、不入 git、不入游戏目录 | `design/art/camp-scene-prompts.md` §1;`artwork/2026-10-23-营地场景/` |
| F19 | 10 层拆分现行口径(覆盖旧 8/9 张):art-bible v3.24 §6.2/camp.md v2.2/camp-scene-prompts.md v1.2/asset-path-map.md §3/art-assets-checklist.md §3.5 同步;围墙从背景层独立成 z1、门洞小路画在 z0 bg 层;围墙落盘细条 (0,240,1280,70) 不做全幅 | `design/art/art-bible.md` §6.2;`design/gdd/ux/camp.md:27-31` |
| F20 | 样张过审与终稿裁定(2026-10-31 用户裁定):保留全部待选稿、各素材第一张样本稿为终稿、「目前我看每个都还可以接受」,用户准备在游戏内做最终审核;终稿此刻=原始候选图本身,未做去底/擦水印/降采样/裁细条等任何后处理(用户 2026-10-31 令只生成素材不做后续工序);清单=`artwork/candidates/_终稿裁定-2026-10-31.txt` | `artwork/candidates/_终稿裁定-2026-10-31.txt` |
| # | 事实 | 出处 |
| --- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| F1 | 营地场景图完全不存在(澄清④判定「完全没有 · 新建」);现营地=CampOverlay 四柜台覆盖层(树淬炼/锻造工坊/秘宝匣/奖励格图鉴并排,迭代 21 T6 程序占位重排——代码注释原文「视觉终稿归 HUD 营地视觉批」) | `需求澄清-营地交互重做-2026-10-18.md` §④;`game/presentation/views/camp_overlay_view.gd:86-87` |
| F2 | 营地屏壳(CampScreen)持 CampOverlay 成员;组合根 `main.camp_overlay` 句柄指向屏壳成员(探针挂载假设) | `game/presentation/scenes/camp_screen.gd:8-14`;`main.gd:112` |
| F3 | CampOverlay 结构:顶栏铭牌+钥石徽(:64-84);四柜台并排横滚(树淬炼 :99-109/锻造工坊 :111-137/秘宝匣 :139-159/奖励格图鉴 :161-172);底栏关闭钮+最近冒险条带(:174-189);钥匙门判据读树投影(:287-296);图鉴柜台=结构位预留(:168「内容排 Alpha」) | `camp_overlay_view.gd` 各处 |
| F4 | 五目标界面现状:锻造工坊=CampOverlay 内工作间(`_forge_workbench` 两区六路线);秘宝匣=`_ws_scroll`/`_workshop_holder`(12 件+同调装配段+Y 升级行);天赋树=`_tree_holder`(脉分组行板+Fork 双态钮);图鉴=占位;生涯=**已独立全屏页**(CareerOverlay,入口现居主菜单生涯钮,自带返回钮) | `camp_overlay_view.gd:116-137`/:144-159/:99-109/:161-172;`views/career_overlay.gd`;`main.gd:332` |
| F5 | 营地购买写口链路:视图只发意图信号(`buy_requested`/`tree_buy_requested`/`forge_*` 等),组合根经 CampShopPresenter 转 MetaProgression 写口;投影数据=`camp_shop_presenter.gd:62-72` `camp_data()` 单点 | `camp_overlay_view.gd:8-15`;`camp_shop_presenter.gd:62-72` |
| F6 | 断点确认弹窗现居主菜单开始冒险路径(有断点先出 ConfirmDialog 再开局)——随卡②撤钮整体移交本卡大门 | `main.gd:475-497` |
| F7 | 冒险屏已实现不动:选路屏(LevelMapScreen,`route_chosen` 前进唯一通道)与战斗屏宿住 AdventureScreen;组合根侧:`_start_adventure_from_menu`(:475-484)/`_on_confirm_new_adventure`(:487-492)/`_resume_from_menu`(:518-536)/`_start_adventure`(:579-597)/`build_adventure_params`(:564-574) | `views/level_map_screen.gd:7`;`scenes/adventure_screen.gd:36-37`;`main.gd` 各处(v1.1 行号订正) |
| F8 | 探针面营地段(全部随本批迁移,v1.1 补列):ui_probe(营地入口+余额+秘宝匣 12 行断言 :28-55,深员 `_balance_label`/`_tree_buy_btns`/`_workshop_rows` :39-52)、ui_click_probe(营地购买全链 :53-127;**断点确认段 :500-528**〔经 lvbtn 驱动 ConfirmDialog 取消/开新冒险——被卡②撤钮+本批弹窗移位双杀,v1.1 补列〕)、screen_flow_probe(营地可见态键 :53 直读 `main.camp_overlay.visible`;营地开合 :109-125 回退段直呼 `main.camp_overlay.closed.emit()`;菜单→冒险 lvbtn 步 :130-136)、shot_probe(camp 截图+「关闭营地」钮收闭 :126-133)、ui_struct_probe(camp 结构审计 :41-49;同槽特例断言 :331/:373)、smoke_all(V2 营地屏壳实例化 :170-171;V3g 营地模态开合 :405-435;**camp_overlay_view.gd 源码断言段 :6469-6475**〔三条锁四柜台等高形态本身——`Vector2(0,336)`×3/`SIZE_FILL`×4/`SIZE_SHRINK_CENTER`≥3,随形态退役〕)、ui_contrast_probe(营地令牌段 :48-55〔UiKit 令牌恒等式,不随拆解红;新界面若不再消费 `CAMP_HEADER_BAND`/`CAMP_ROW_PLATE` 则段标签虚挂,须核签〕)、**forge_workbench_test.gd 单测**(:33 直载 camp_overlay_view.gd 并消费 `_forge_rows`/`_forge_workbench`/`open_camp`/`refresh_camp`/三 forge 信号——CampOverlay 一删即红) | `game/smoke/` 各处+`game/tests/unit/presentation/forge_workbench_test.gd:33` |
| F9 | camp UX spec 形态记述将整体退役:三柜台列/顶栏铭牌钥石徽/底栏关闭钮+最近冒险条带(v1.5,事实源声明= camp_overlay_view.gd 实态;条带实述于 :19-20) | `design/gdd/ux/camp.md:14-20` |
| F10 | art-bible 营地条款将失义:§6.2 营地场景「三柜台在烛光下一字排开,钥石余额常驻顶栏」;§7.5 营地界面「三柜台界面画法……视觉终稿以表现层样张过审为前置」;§2.8 承载元素同述 | `design/art/art-bible.md:366-369`/:436-438`/:136-140` |
| F11 | 图鉴内容在册挂起:奖励格图鉴柜台已随配比预设批整体挂起冻结(2026-10-05 用户令,06 在册),重启须用户另行发令——本批只改入口不激活内容 | `design/gdd/systems/跨局循环/生涯.md:63` |
| F12 | 贴图重构批搁置未废:营地与元进度件终稿置换(06:21-27)等交互重做定形后再议(澄清③1/§⑧5)——本批不清偿该债;四柜台拆解后原「柜台场景贴图」债对象变化,随该批重新评估 | `design/gdd/06-待办清单.md:21-27`;`需求澄清-营地交互重做-2026-10-18.md` §③1/§⑧5 |
| F13 | 营地底栏「最近冒险」条带与生涯历史回看同源(同一份 `recent_summaries`),其去留=生涯.md P6 待裁点(期二必答)——CampOverlay 拆解后该条带无处挂,P6 被迫提前面对(本卡 Q4) | `camp_overlay_view.gd:186-189`/:536-549;`生涯.md:69`/:91-101\` |
| F14 | 素材线纪律:`artwork/` 不入 git(`.gitignore:51` 忽略行)——批次 worktree 内无该目录、主工作区 D:/code/g-plan2 实体存在(在途工作区);涉素材脚本须传主区绝对路径否则静默 0 张;素材替换前先归档旧档;终稿归 `game/assets/art/` | `AGENTS.md:32`;`.gitignore:51`;art-bible §8.3 归档纪律(v1.1 行号与表述订正) |
| F15 | 美术硬约束继续有效(澄清③4):明亮轻快像素风、**48 色板、HSV 300°–345° 禁入带、语义色纪律、WCAG ≥4.5:1**——全局约束,不在本讨论范围翻案 | `需求澄清-营地交互重做-2026-10-18.md` §③4 |
| F16 | 像素级规格不在本卡硬定(澄清③5):尺寸档/色板/明度档归「战斗一屏样张批」冻结的规格清单——该批现列 06「待设计」未排期(2026-10-17 用户令自迭代 30 剔除),本卡只写指针并登记依赖(缺口连带裁=Q6) | `需求澄清-营地交互重做-2026-10-18.md` §③5;`design/gdd/06-待办清单.md`(迭代 30 剔除卡②③ 条) |
| F17 | 机检工具面(v1.1 订正):**截屏级 48 色计数不在役**;在役=`tools/palette_check.py`(art-bible §8.3①挂点——48 设计色板令牌+新增色双门)+`tools/standee_asset_check.py`(像素画单张 32 色冻结执法);`tools/render_gate.sh`(shot_probe 七屏→shot_checker 语义断言;golden 段=棋盘三张+menu_boot 四张,**无 camp golden**——shot_checker.py:143 明载「camp/level 走骨架+目检清单」);shot_checker 段=屏级骨架/文字 WCAG/明度三档带/文字禁压纹理/文字在判据 | `tools/palette_check.py`;`tools/standee_asset_check.py`;`tools/render_gate.sh`;`tools/shot_checker.py:143` |
## 3. 设计契约(红线,违反 = L3 停机呈报)
## 3. 设计契约(红线,违反 = L3 停机呈报)
🔴 **契约 1 · 交互式场景图形态**:营地首页=一张可点击的营地场景图,点物件进界面(澄清①)。**禁退回文字按钮列表+面板覆盖层形态**(澄清②反参照:「完全普通的那种 UI 设计」「各种框框」——用户判现状「交互流程完全错误」)。
🔴 **契约 1 · 交互式场景图形态**:营地首页=一张可点击的营地场景图,点物件进界面(澄清①)。**禁退回文字按钮列表+面板覆盖层形态**(澄清②反参照:「完全普通的那种 UI 设计」「各种框框」——用户判现状「交互流程完全错误」)。
🔴 **契约 2 · 七物件绑定逐一落地**:大门/锻炉铁砧/宝箱/帐篷旁笔记本/木桩/布告板/篝火七个绑定(§1 表)缺一不可;禁合并、禁以「其他入口」替代(如顶栏文字钮)。帐篷为承载件、不可点。
🔴 **契约 2 · 七物件绑定逐一落地**:大门/锻炉铁砧/宝箱/笔记本/木桩/布告板/篝火七个绑定(§1 表)缺一不可;禁合并、禁以「其他入口」替代(如顶栏文字钮)。
🔴 **契约 3 · 大门两分支**(裁决 5,Q5 已裁=甲):有未完冒险→ConfirmDialog 三出口「继续上一段冒险/开始新冒险/取消」;无→「是否开始新冒险:是/否」弹窗。**点大门永远先出确认,不直接进冒险**;cancelled 恒=无变更退回营地;弹窗类=ConfirmDialog(三钮化+消费方编排=T4,卡③ 契约 3 同款互指)。
🔴 **契约 3 · 大门两分支**(裁决 5):有未完冒险→「继续上一段冒险/开始新冒险」二选一弹窗(**三出口形态=Q5 待裁**);无→「是否开始新冒险:是/否」弹窗。**点大门永远先出确认,不直接进冒险**;弹窗类=ConfirmDialog(三钮化+消费方编排=T4,卡③ 契约 3 同款互指)。
🔴 **契约 4 · 已实现界面只改挂不重做+presenter 承接面**:锻造工坊/秘宝匣/天赋树/图鉴/生涯五界面「界面已实现 · 入口改挂」——功能、行板、写口链路零重设计(拆解=承载面迁移)。**presenter 改造=承载面迁移的一部分**:`camp_shop_presenter.gd` 持 `camp_overlay` 句柄(:10)、七条写口尾全部 `camp_overlay.refresh_camp(camp_data())`(:85/93/105/117/129/142/154/168)、`CampFlowContext` 持类型化字段(camp_flow_context.gd:10/22/29)、open/close 编排(:41-56)——**写口语义零改≠presenter 文件零改**:投影目标改线(五界面/场景根)、写口尾刷新改路由、open/close 编排随入口从 campbtn 迁位到卡③ 进档动作、ctx 字段语义订正、探针缝保位(main.gd:1163-1171)。改造纪律:`on_camp_attune_toggle`(:98-106)尾只 refresh_camp、不调 `_refresh_presentations`(与其余六口不一致)——**保持原样,禁「顺手统一」防行为漂移**。
🔴 **契约 4 · 已实现界面只改挂不重做+presenter 承接面(v1.1 精确化)**:锻造工坊/秘宝匣/天赋树/图鉴/生涯五界面「界面已实现 · 入口改挂」——功能、行板、写口链路零重设计(拆解=承载面迁移)。**presenter 改造=承载面迁移的一部分**:`camp_shop_presenter.gd` 持 `camp_overlay` 句柄(:10)、七条写口尾全部 `camp_overlay.refresh_camp(camp_data())`(:85/93/105/117/129/142/154/168)、`CampFlowContext` 持类型化字段(camp_flow_context.gd:10/22/29)、open/close 编排(:41-56)——**写口语义零改≠presenter 文件零改**:投影目标改线(五界面/场景根)、写口尾刷新改路由、open/close 编排随入口从 campbtn 迁位到卡③进档动作、ctx 字段语义订正、探针缝保缝(main.gd:1163-1171)。改造纪律:`on_camp_attune_toggle`(:98-106)尾只 refresh_camp、不调 `_refresh_presentations`(与其余六口不一致)——**保持原样,禁「顺手统一」防行为漂移**。
🔴 **契约 5 · 图鉴内容保持挂起**:只改入口(布告板),不激活图鉴内容(F11:2026-10-05 用户令冻结,重启须用户发令);布告板点开的图鉴=现行占位态(T3 定义占位壳),不是禁用态(camp.md v2.2)。
🔴 **契约 5 · 图鉴内容保持挂起**:只改入口(布告板),不激活图鉴内容(F11:2026-10-05 用户令冻结,重启须用户发令);布告板点开的图鉴=现行占位态(T3 定义占位壳)。
🔴 **契约 6 · 冒险进行中不开营地**(澄清③6):营地是存档语境(局外)枢纽,现状口径延续;局内只读面=状态面板(在役,本批零改动——其「营地三柜台进度」文案若因拆解失义,列反哺点归文档批订正)。
🔴 **契约 7 · 美术硬约束+10 层红线**:48 色板、HSV 300°–345° 禁入带、语义色纪律、WCAG ≥4.5:1(F15);场景素材全局纹理过滤=Nearest(project.godot 现行默认,像素纪律)。**10 层拆分按 §0.4**:z0 bg 不透明全幅(含门洞小路)、z1 wall 透明细条 (0,240,1280,70) 门洞 x520–760 留透明缺口、z2–z6 八物件层;围墙禁并回背景层、门洞禁填死、门洞禁被任何物件遮挡。点选反馈四态(悬停=轮廓亮边+浮动〔整像素吸附〕+名牌〔物件下方 8px 居中、字号 14、对比 ≥4.5:1〕/按下=位移 1px/禁用=降明度+去饱和〔仅锻炉、宝箱〕/已解锁=常态)零新素材、全程序化;命中区两两不相交、不越画面、不侵入顶栏禁区 y≤48。篝火命中矩形只取下半(火堆),火焰只展示。
🔴 **契约 6 · 冒险进行中不开营地**(澄清③6):营地是存档语境(局外)枢纽,现状口径延续;局内只读面=状态面板(在役,本批零改动——其「营地三柜台进度」文案若因拆解失义,列反哺点归文档批订正)。
🔴 **契约 8 · 像素规格不硬定**:尺寸档/色板/明度档只写指针(Q6 甲过渡口径=1280 工程档+烛光黄/木色,落 art-bible §6.2/art-assets-checklist §3.5,F16);卡内禁自定像素规格数值;终档置换归反哺点,执行归用户线;禁批内自补、禁 T0 现场发挥。
🔴 **契约 7 · 美术硬约束**:48 色板、HSV 300°–345° 禁入带、语义色纪律、WCAG ≥4.5:1(F15);场景素材全局纹理过滤=Nearest(project.godot 现行默认,像素纪律)。
🔴 **契约 9 · 迭代内验收=截图对比+终稿落盘口径**(澄清⑥):camp 截图须为场景图形态;用户实机目检=生命周期最后一步、统一进行、**不阻塞迭代**——目检项登记 07 清单即完成义务。**T1 终稿落 `game/assets/art/scene/` 的「验收」口径=迭代内验收**(截图对比+shot_checker 机检+样张过审留痕)——营地屏整屏样张按既定排队行延后(§0.5),不构成对 art-bible §7.5「前置」条的违背(§5 反哺点注)。
🔴 **契约 8 · 像素规格不硬定**:尺寸档/色板/明度档只写指针(战斗一屏样张批冻结的规格清单,F16);卡内禁自定像素规格数值;规格清单未产出时的输入缺口=Q6 裁定(禁批内自补、禁 T0 现场发挥)。
🔴 **契约 10 · 探针断言迁移契约**(属仓库既有测试纪律的卡内成文,非用户裁决):F8 全量位点逐点显式迁移并留痕;**现无 camp 逐像素 golden 基线**(F17:golden 现役仅棋盘三张+menu_boot)——本批不建 camp golden(「把不存在的东西列进迁移清单」禁),camp 截图验收=shot_probe 出图+shot_checker 语义断言段;若要新建 camp golden 须另裁登记(L3)。
🔴 **契约 9 · 迭代内验收=截图对比+终稿落盘口径(v1.1 补)**(澄清⑥):camp 截图须为场景图形态;用户实机目检=生命周期最后一步、统一进行、**不阻塞迭代**——目检项登记 07 清单即完成义务。**T1 终稿落 `game/assets/art/` 的「验收」口径=迭代内验收**(截图对比+shot_checker 机检+方向稿用户选划)——营地屏整屏样张按既定排队行延后(§0),不构成对 art-bible §7.5「前置」条的违背(§5 反哺点注)。
🔴 **契约 11 · 拆分边界纪律**(结构类卡必填,判据权威=`design/engineering/code-conventions.md` §1.1,本卡写条款、不复制定文):本卡含「四柜台拆解」,拆分沿**职责轴**不沿阈值轴——每个拆出单元(锻造/秘宝/天赋树/图鉴四界面 view)须有可陈述的职责语句与单一变化原因、须有集体身份(命不出名字、只能说「剩下的成员」的打包=凑计数袋,禁);「过阈值」只许作为发现信号,作为拆分或收拢的动机即违规;按纪律拆不出内聚单元 → 停卡呈报走豁免/还债通道,禁硬拆凑绿(写进 §8 L3)。实现报告逐件一行承载职责语句。
🔴 **契约 12 · 禁为机检文本保留无效成员**(重构类卡必填条款,与 code-conventions §1.1 同款):禁止为迎合机检消息文本(含计数)而保留或新增无效成员/别名;机检键与卡片契约互斥时,实现段一律停卡呈报,不得自造第三条路。
🔴 **契约 10 · 探针断言迁移契约(v1.1 订正,属仓库既有测试纪律的卡内成文,非用户裁决)**:F8 全量位点逐点显式迁移并留痕;**现无 camp 逐像素 golden 基线**(F17:golden 现役仅棋盘三张+menu_boot)——本批不建 camp golden(「把不存在的东西列进迁移清单」禁),camp 截图验收=shot_probe 出图+shot_checker 语义断言段;若要新建 camp golden 须另裁登记(L3)。
## 4. 范围边界
**做**:场景屏+10 层场景素材铺底+七物件命中区与点选交互(反馈细节按 §0.3 P3 设计稿、四态规格按 camp.md v2.2);四柜台拆解与五界面入口改挂(含 presenter 承接面改造);大门动线两分支+断点弹窗移位;篝火回主菜单小动线(带二次确认);场景屏顶栏预留位;断言/探针迁移;反哺点清单。
**做**:场景素材产出(渠道按 Q1 裁定);场景屏+七物件命中区与点选交互(反馈细节按 Q3 设计稿);四柜台拆解与五界面入口改挂(含 presenter 承接面改造);大门动线两分支+断点弹窗移位;篝火回主菜单;场景屏顶栏预留位;断言/探针迁移;反哺点清单。
**不做**(明示去向):
- **不做贴图重构批**(澄清③1):柜台场景贴图/钥石顶栏图标/永久强化条目图标的达标化置换——搁置未废,待交互重做完形后重新评估立项(F12);
- **不做贴图重构批**(澄清③1):柜台场景贴图/钥石顶栏图标/永久强化条目图标的达标化置换——搁置未废,待交互重做完形后重新评估立项(F12);
- 不激活图鉴内容(契约 5);
- 不改五界面功能与写口链路(契约 4);
- 不改冒险屏/选路屏/战斗屏本体(F7 已实现不动);
- 不做整屏样张闸、不替代样张批、不新建 camp golden(§0.5/契约 10);
- 不改冒险屏/选路屏/战斗屏本体(F7 已实现不动);
- 不做整屏样张闸、不替代样张批、不新建 camp golden(§0/契约 10);
- 局内状态面板零改动(契约 6);
- 素材后处理与入库属实现段 T1/`asset-ingest` 第 3 步、开工另发令(§0.3-4),不属写卡门;
- ESC 浮窗与顶栏 HUD 实现 → 卡⑤(本卡只留顶栏位+定义刷新单口);
- 选档界面/主菜单/数据层 → 卡③/卡②/卡①。
- 选档界面/主菜单/数据层 → 卡③/卡②/卡①。
## 5. 关联文档同步面
> **现行口径**:实现批禁写 `design/` 整目录与根规则文件,唯一可写目录=`reports/`(+`game/` 实施本体);设计权威文档(GDD/art-bible)与机械面文档(roadmap/体验验证清单/README)对代码实现批一律不直改,逐条列进 `reports/iter<N>-反哺点-<日期>.md`,用户裁决后归文档批落文;本卡全表义务格一律为「反哺点 · 列清单」。camp.md v2.2/art-bible v3.24 §6.2 已先行落文 10 层新形态,本批实现=对齐现行条款,反哺义务为**实装状态回填+目检结论**,非形态改版。美术素材产物按素材线纪律落 `artwork/`(在途)→ `game/assets/art/scene/`(终稿),不随 git 合并(F14)。
> **v1.3 口径**:本批禁写 `design/` 整目录与根规则文件,唯一可写目录 = `reports/`;下表一律执行为列进反哺点清单。美术素材产物按素材线纪律落 `artwork/`(在途)→ `game/assets/art/`(终稿),不随 git 合并(F14)。
| 文档 | 关联点 | 同步义务 |
|---|---|---|
| `design/gdd/ux/camp.md` v2.2 | §定位/§场景构成与七物件绑定/§点选反馈/§顶栏/§叠层与开合:新形态已落文,本批实现后回填实装状态、样张过审留痕、实机目检结论 | 反哺点 · 列清单(实现批禁写 `design/`) |
| `design/art/art-bible.md` v3.24 | §6.2 营地场景 10 层口径已落文;§7.5 营地界面画法、§2.8 承载元素、§1.4 营地屏整屏样张排队行注记(本批不跑样张闸) | 反哺点 · 列清单(权威面零直改,过用户裁决后归文档批) |
| `design/gdd/systems/跨局循环/生涯.md` | :69 与营地边界表(条带 `_rebuild_recent` 随 CampOverlay 拆解去向=Q4 已裁甲);:63 图鉴挂起条(入口改挂注记) | 反哺点 · 列清单 |
| `design/gdd/ux/camp.md` | :14-20 布局与交互节(三柜台列/顶栏/底栏)+:10 定位句(主菜单入口)+头注事实源声明(=camp_overlay_view.gd 实态)——四柜台形态整体退役、入口改挂场景物件 | 反哺点 · spec 整体改版重写(形态节退役+新形态成文) |
| `design/art/art-bible.md` | §6.2 营地场景(三柜台一字排开→交互式场景纵深稿);§7.5 营地界面(三柜台画法→五界面画法+场景图画法);§2.8 承载元素;营地屏整屏样张排队行注记(本批不跑闸);**§7.5「视觉终稿以表现层样张过审为前置」条与本批的关系=样张排队行既定延后(终稿后再出样),防文档批误判违例**(v1.1 补注) | 反哺点 · 列清单(权威面零直改,过用户裁决后归文档批) |
| `design/gdd/systems/跨局循环/生涯.md` | :69 与营地边界表(条带 `_rebuild_recent` 随 CampOverlay 拆解去向=Q4);:63 图鉴挂起条(入口改挂注记) | 反哺点 · 列清单(P6 去留随 Q4 裁定) |
| `design/gdd/08-Alpha版本标准.md` | 「三 · 界面」营地行(:104)形态注记改写——状态列可改;注记改写列反哺点;增删行须用户裁(三卡统一口径) | 反哺点 · 列清单 |
| `design/gdd/06-待办清单.md` | 本卡登记条;UI 贴图重构批条(:21-27)注记「四柜台对象变化、重评待交互重做完形」;图鉴挂起条注记 | 反哺点 · 列清单(实现批禁写待办清单) |
| `design/gdd/07-体验验证清单.md` | 新增实机目检条(场景观感/七物件辨识与点选反馈/大门两分支/篝火动线)——登记不阻塞 | 反哺点 · 列清单(实现批禁写体验验证清单,入册条目由文档批落) |
| `roadmap.md` | 迭代行编入/状态刷新 | 反哺点 · 列清单(实现批禁写 roadmap) |
| `game/tests/README.md` | 能力行入表(§7 对照表「能力行」列定名) | 写卡段定名(本卡只写卡内能力行文字,README 由主 Agent 统一收口);实现批只核对名实一致,禁写 |
| `game/presentation/*`、`game/smoke/*`、`game/tests/**`(含 forge_workbench_test 迁移面)、`game/tests/golden/*`(仅棋盘/menu 既有基线复跑)、`game/assets/art/scene/*`(10 层终稿) | 实现/断言/终稿素材本体 | 实施本体(可写) |
| `tools/shot_checker.py` | camp 取样面语义断言段(文字 WCAG/明度三档带/文字禁压纹理/文字在判据扩 camp) | 实施本体(可写,属工具/测试面) |
## 卡前·文件结构与职责(T0 前)
定义 T 卡前先列全本批新建/修改文件,一文件一职责。**每个文件行标「行为改动/非行为改动」并指向 §7 对照表行号;「落位」列与「落位与可复用性预检」节互指**(标「新建」的必须能在预检节指到不能复用的理由与唯一落点核查)。行号为开工日 T0 复核对象。
| 文件 | 职责 | 改动类型 | 落位 | 对照表行 |
|---|---|---|---|---|
| `game/presentation/views/camp_scene_view.gd` | 交互式营地场景图视图:10 层纹理铺底(z0–z6)+七物件命中区+点选反馈四态+名牌 | 行为改动 | 新建 | V1/V2/V9/V10 |
| `game/data/tables/camp_scene_layout.tres` | 10 层贴图矩形/命中矩形/z 序/门洞缺口坐标(数值单一事实源 `data/tables/`,坐标最终值随 §0.3 代码段开工门裁定落入,本卡不硬定) | 行为改动 | 新建 | V1/V2/V9 |
| `game/presentation/views/camp_refresh_bus.gd` | 营地刷新单口:各写口尾→现开界面刷新+场景根 HUD 刷新一闸完成(卡⑤ 同口挂接) | 行为改动 | 新建 | V8/B1 |
| `game/presentation/views/forge_view.gd` | 锻造工坊独立可开界面(自 CampOverlay `_forge_workbench` 抽出,界面逻辑复用) | 行为改动 | 新建(抽出) | V4/B2 |
| `game/presentation/views/treasure_view.gd` | 秘宝匣独立可开界面(自 `_ws_scroll`/`_workshop_holder` 抽出) | 行为改动 | 新建(抽出) | V4/B2 |
| `game/presentation/views/tree_view.gd` | 天赋树独立可开界面(自 `_tree_holder` 抽出) | 行为改动 | 新建(抽出) | V4/B2 |
| `game/presentation/views/codex_view.gd` | 奖励格图鉴独立可开界面占位壳(内容保持挂起,契约 5) | 行为改动 | 新建(抽出) | V4/V6/B2 |
| `game/presentation/scenes/camp_screen.gd` | 屏壳改造:持 camp_scene_view 取代 CampOverlay 成员+顶栏 HUD 预留位+模态栈单口 | 行为改动 | 复用既有(改造) | V1/V8 |
| `game/presentation/views/camp_overlay_view.gd` | 四柜台覆盖层拆解后退役(无消费面即删,吸收即死) | 行为改动 | 退役 | V4/V9/B2 |
| `game/presentation/views/career_overlay.gd` | 生涯页入口自主菜单改挂帐篷旁笔记本(本体零改,返回钮文案禁含「营地」) | 行为改动 | 复用既有(改入口) | V5 |
| `game/presentation/views/confirm_dialog.gd` | 三钮化(继续上一段冒险/开始新冒险/取消) | 行为改动 | 复用既有(改) | V3/B1 |
| `game/presentation/presenters/camp_shop_presenter.gd` | 投影目标改线+七写口尾刷新改路由+open/close 编排迁位(契约 4) | 行为改动 | 复用既有(改) | V4/V8/B1 |
| `game/presentation/core/camp_flow_context.gd` | 类型化字段语义订正 | 行为改动 | 复用既有(改) | V4/B1 |
| `main.gd`(组合根) | 断点弹窗移位+ConfirmDialog 三钮消费方编排+营地入口改挂+篝火动线+开层互斥/关层收闭 | 行为改动 | 复用既有(改) | V3/V4/V7/B1 |
| `game/assets/art/scene/scene_camp_*.png`(10 张) | 10 层场景素材终稿(asset-ingest 第 3 步拷入,命名对齐 `UiKit.TEX_CAMP_*`) | 非行为改动(美术资源) | asset-ingest | V1/V10 |
| `game/smoke/shot_probe.gd` | camp 截图路径改场景图+收闭改接篝火动线 | 非行为改动(测试面) | 复用既有(改) | V1 |
| `game/smoke/ui_click_probe.gd` | 七物件可达+大门两分支+断点确认段改走大门+写口链迁移+深员改指 | 非行为改动(测试面) | 复用既有(改) | V2/V3/V4 |
| `game/smoke/ui_probe.gd` | 营地入口/余额/秘宝匣深员改指新界面 | 非行为改动(测试面) | 复用既有(改) | V4 |
| `game/smoke/screen_flow_probe.gd` | 营地键新语义+回退段改新场景根 closed/篝火动线 | 非行为改动(测试面) | 复用既有(改) | V7 |
| `game/smoke/ui_struct_probe.gd` | 反参照结构禁词+生涯段驱动改接+图鉴占位锚定 | 非行为改动(测试面) | 复用既有(改) | V5/V6/V9 |
| `game/smoke/ui_contrast_probe.gd` | 营地令牌段核签(CAMP_HEADER_BAND/CAMP_ROW_PLATE 消费判定) | 非行为改动(测试面) | 复用既有(改) | V10 |
| `game/smoke/smoke_all.gd` | V2 实例化/V3g 模态开合改指+`camp_overlay_view.gd` 源码断言段 :6469-6475 重写或注销 | 非行为改动(测试面) | 复用既有(改) | V4/B2 |
| `game/tests/unit/presentation/forge_workbench_test.gd` | 随锻造视图抽出同迁(断言零改、只换承载类) | 非行为改动(测试面) | 复用既有(改) | V4/B2 |
| `tools/shot_checker.py` | camp 取样面语义断言段 | 非行为改动(工具/测试) | 复用既有(改) | V10 |
| `game/tests/README.md` | 能力行入表(四列:能力|系统|真实入口|代表用例) | 非行为改动(文档,写卡段) | 主 Agent 统一收口 | 全表能力行 |
| `reports/iter<N>-实现报告-<日期>.md`/`reports/iter<N>-反哺点-<日期>.md`/`reports/iter<N>-验收审计-<日期>.md` | T6 三份产出物 | 非行为改动(过程件) | 新建 | T6 |
## 落位与可复用性预检
定义 T 卡前,对本批每个**新增文件/新增函数/新增数据件**过三问(复用面/唯一面/分层与交互面),与「卡前·文件结构与职责」互指。生效=2026-10-21 用户立规;本卡虽文件名日期 2026-10-18,经 2026-10-31 用户明令重立为现行有效卡,按现行规则补齐。
### 新增件三问
| 新件 | 复用面(grep 同职责实现) | 唯一面(grep 同名同义标识符) | 分层与交互面(调用路径+跨层出口) |
|---|---|---|---|
| `camp_scene_view.gd` | 盘上视图件=CampOverlay(四柜台覆盖层,形态本批退役、与场景图形态正交,反参照禁复用)、CareerOverlay(生涯全屏页,职责不同)、camp_screen.gd(屏壳)。**无**「场景图铺底+七物件命中区+点选反馈」同职责实现 → 不能复用,须新建视图件;屏壳复用既有 `camp_screen.gd` 改造,不新建屏壳 | grep `camp_scene`/`scene_camp` 视图标识符盘上无第二处;素材消费常量 `UiKit.TEX_CAMP_*` 单点(asset-path-map.md §3),不另立路径常量 | 呈现层视图,零 Core 写调用;命中区 `_gui_input()` → `object_pressed(key: String)` 信号 → 组合根 → 开界面/写口;10 层装载经 `UiKit.load_tex()`(exists 守卫、禁 preload);不直连 MetaProgression |
| `camp_scene_layout.tres` | grep `game/data/tables/` 无营地坐标表;坐标草案在 artwork HTML(不入 git)与 camp-scene-prompts §2.3(设计文档,非运行时数据源)。数值单一事实源要求落 `data/tables/` → 新建 | 坐标事实只此一处;禁在 `camp_scene_view.gd`/探针/T 卡各写一份坐标字面量(契约 8 禁自定规格、数值单点) | 视图启动时经 ConfigDB 单点读取;坐标最终值随 §0.3 代码段开工门(camp-scene-prompts §5 五裁点)裁定落入,本卡只定结构键不定值 |
| `camp_refresh_bus.gd` | grep 现役 `refresh_camp` 绑定 CampOverlay 句柄(F5),随四柜台形态**退役**(卡⑤/§0.5 明确「非已退役的 refresh_camp」);新单口须同时刷新现开界面与场景根 HUD、职责不同 → 不能复用,须新建 | grep `camp_refresh`/刷新单口类标识符盘上无第二处;卡⑤ HUD 刷新挂此单口,不另立第二口 | 组合根拆件:七写口尾 → `CampRefreshBus.refresh(camp_data: Dictionary) -> void` → 现开界面刷新+场景根 HUD 刷新;一次性刷新,不新增写口语义(契约 4) |
| `forge_view.gd`/`treasure_view.gd`/`tree_view.gd`/`codex_view.gd` | 界面逻辑**已实现**于 CampOverlay 内(F4:`_forge_workbench`/`_ws_scroll`/`_tree_holder`/图鉴占位);本批是抽出承载壳、**复用既有界面逻辑**(行板/写口链路零重设计,契约 4),非从零新写 → 新建壳、迁移逻辑 | grep `forge_view`/`treasure_view`/`tree_view`/`codex_view`/`_forge_rows`/`_forge_workbench` 盘上无第二处定义;`forge_workbench_test.gd:33` 消费 `_forge_rows`/`_forge_workbench`,抽出后同迁,断言零改只换承载类 | 各视图发意图信号(`buy_requested`/`tree_buy_requested`/`forge_*`)→ 组合根 → CampShopPresenter → MetaProgression 写口(Core 零 UI 不破);五界面各带返回/关闭钮;开合走模态栈单口、层序入 `LAYER_CONTRACT` |
### 非新增件说明
- `camp_screen.gd`/`camp_shop_presenter.gd`/`camp_flow_context.gd`/`confirm_dialog.gd`/`career_overlay.gd`/`main.gd`:存量文件改造,不新增文件;公开方法/成员预算见「实现规范预算」存量触面一查。
- `camp_overlay_view.gd`:四柜台拆解后无消费面即删(吸收即死),禁留死代码;`main.camp_overlay` 探针句柄迁移留痕(F2/F8)。
- `game/tests/golden/*`:棋盘三张+menu_boot 既有基线复跑,不新建 camp golden(契约 10)。
- **数据件**:本卡纯呈现层,零玩法数值、无新增 `data/tables/` 玩法表(`camp_scene_layout.tres` 为呈现坐标件,非玩法数值);数值单一事实源 `data/tables/` 不被玩法值触碰;RNG 零新增(RNG 单点 RngService 不被触碰);Core 零 UI 依赖不因新增场景屏绕过。
## 实现规范预算
定义接口块/文件结构图前,对本批每个**新增文件**对照 gdstyle 默认阈值做预算,与接口块及「卡前·文件结构与职责」互指。**生效说明**:规范写「生效=文件名日期 ≥2026-10-27,此前卡片属历史留档不回头改」——本卡经 2026-10-31 用户明令重立为现行有效卡,按现行规则补齐,不援引「不回头改」跳过。gdstyle v0.4.0 默认阈值:**公开方法 ≤20、类变量 ≤15、单函数分支 ≤8、返回 ≤6**(阈值取工具默认,改阈值=基线口径变须在本批重生成)。
### 新件三查
| 触面 | ①公开方法数 | ②成员变量数 | ③迁移函数对账 | 结论 |
|---|---|---|---|---|
| `camp_scene_view.gd` | 预期 ≤8:`setup_layers()`/`bind_hotspots()`/`set_feedback_state()`/`get_hotspot_rect()`/`set_hud_band()`/`_on_hotspot_input()` 等,远低 ≤20 | 预期 ≤12:10 层纹理句柄+命中区表+反馈态+名牌节点;收编进内聚结构,低 ≤15 | 无自存量文件迁入函数 | 三查通过;T0 实测实数回填,超阈值即拆件或砍面(砍面=退设计段裁职责) |
| `camp_refresh_bus.gd` | 预期 ≤3:`refresh()`/`bind_targets()`/`_dispatch()`,远低 ≤20 | 预期 ≤4:现开界面句柄+场景根 HUD 句柄+投影数据,低 ≤15 | 自 `camp_shop_presenter.gd` 迁入刷新路由;先查 `tools/gdstyle_baseline.txt` 源函数键,branches/returns/函数长超默认登记值的迁移即拆函数(拆分不改语义,不算迎合机检) | 三查通过;迁入后补跑 S13,不凭旧读数放行 |
| 四界面 view(各) | 各预期 ≤6:`open()`/`close()`/`bind_rows()`/`_on_action()` 等,远低 ≤20 | 各预期 ≤10:复用既有行板成员(`_forge_workbench`/`_ws_scroll`/`_tree_holder`),低 ≤15 | 自 `camp_overlay_view.gd` 迁入对应界面函数;逐个对 `tools/gdstyle_baseline.txt` 源键,超登记值即拆函数 | 三查通过;抽出后实测实数回填 |
| `camp_scene_layout.tres` | 不适用(数据件,无方法) | 不适用(结构键,非类变量) | 不适用(无迁入函数) | 结构键唯一,坐标值随 §0.3 开工门落入 |
### 存量触面一查
本卡触碰存量文件:`camp_screen.gd`/`camp_shop_presenter.gd`/`camp_flow_context.gd`/`confirm_dialog.gd`/`career_overlay.gd`/`camp_overlay_view.gd`(退役)/`main.gd`/探针七件/`forge_workbench_test.gd`。**T0 读数步骤写明「S13 键较 `tools/gdstyle_baseline.txt` 登记值只降不升」的预期与达成手段**:CampOverlay 拆解=删四柜台代码(键只降);`camp_shop_presenter.gd` 改造=投影目标改线、不新增公开方法/成员;`main.gd` 组合根=断点弹窗移位+消费方编排(新增私有状态量一枚,S13 类级键只降不升);探针改接=替换断言段、不新增扫描面键。任何 S13 键被迫上升=§8 L3 停卡。
### 指标例外通道
现预算内,无需例外。若场景视图十层句柄+七命中区+反馈态实测超 15 类变量,或组合根成员超基线,设「指标例外申报」节——键名+理由+用户特批落基线;未申报的超预算面进实现段=停卡退回写卡段(写进 §8 L3)。
| `design/gdd/06-待办清单.md` | 本卡登记条;UI 贴图重构批条(:21-27)注记「四柜台对象变化、重评待交互重做完形」;图鉴挂起条注记 | 反哺点 · 列清单 |
| `design/gdd/07-体验验证清单.md` | 新增实机目检条(场景观感/七物件辨识与点选反馈/大门两分支/篝火动线)——登记不阻塞 | 反哺点 · 列清单 |
| `roadmap.md` | 迭代行编入/状态刷新 | 反哺点 · 列清单 |
| `game/presentation/*`、`game/smoke/*`、`game/tests/**`(v1.1 补——forge_workbench_test 迁移面)、`game/tests/golden/*`(仅棋盘/menu 既有基线复跑)、`game/assets/art/*` | 实现/断言/终稿素材本体 | 实施本体(可写) |
## 6. 任务卡
> 估时按 Claude 工作日口径;每卡出口自跑轻闸;开工日 T0 复核全部行号。步骤用 `- [ ]` 复选框记步,一步=一个动作+一个可核查结果;每卡声明「取用/产出」接口块,后卡引用的名字与早卡定义逐字一致;禁占位待定句式(不决定任何事的行不留)。**天然切分点=T1 出口**(场景素材归档齐)——美术线与代码线可分批交付(用户批次归属裁);若单批跑超迭代盒,T3 末(四柜台拆解完)为次切分点。
> 估时按 Claude 工作日口径;每卡出口自跑轻闸;开工日 T0 复核全部行号。**估时主变量=美术渠道(Q1 待裁)、点选反馈设计稿往返(Q3)与规格输入(Q6)**。
### T0 事实坐实与设计输入齐备检查(≈0.5d)
- 取用:待办清单条目状态(文档设计已闭合+美术设计已闭合+已写卡)、§0 重立凭据、art-bible v3.24 §6.2、camp.md v2.2、camp-scene-prompts.md v1.2、`_终稿裁定-2026-10-31.txt`、布局草案-1280x800.html。
- [ ] 复核 §2 F1–F20 全部 `file:line` 行号;四柜台界面清单与探针面清单(F8)逐点过——漂移即停卡核对,不猜行号。
- [ ] 设计输入齐备检查:Q1(美术渠道=B 已裁)/Q2(参照物已补)/Q4(条带=甲)/Q5(三钮=甲)/Q6(过渡口径=甲)/Q8(出稿方式=甲)状态逐项核为已裁;**代码段开工门**(§0.3:P3/P5/camp-scene-prompts §5 五裁点/素材后处理入库)状态逐项核——未销号项对应的任务段禁开工(缺输入=呈报,禁批内自补)。
- [ ] 规格清单依赖核检:样张批规格清单产出时点 vs 本批排期——按 Q6 甲过渡口径执行(1280 工程档+烛光黄/木色,终档置换归反哺点),禁 T0 现场发挥。
- [ ] 跑 `bash tools/gdstyle.sh game` 开发期局部读数,记录 `camp_screen.gd`/`camp_shop_presenter.gd`/`main.gd` 当前行数、类变量、公开方法数;登记 S13 基线键(预期只降不升)。本步为最窄确认,不构成验收。
- [ ] 与卡③ 对齐 ConfirmDialog 消费方编排机制(T4 互指)、与卡⑤ 对齐顶栏位与营地刷新单口(§0.5 跨卡接口)。
- 产出:基线 commit、S13 实数、设计凭据核对表、代码段开工门未销号清单;后续卡只按本卡契约施工。
- 复核 §2 全部行号;四柜台界面清单与探针面清单(F8)逐点过;
- 设计输入齐备检查:Q1(美术渠道)/Q2(参照物)/Q3(点选反馈细节)/Q4(条带去留)/Q5(三出口弹窗)/Q6(规格缺口)状态逐项核——**未裁项对应的任务段禁开工**(缺输入=呈报,禁批内自补);
- 规格清单依赖核检:战斗一屏样张批(06 待设计)产出时点 vs 本批排期——按 Q6 裁定执行(禁 T0 现场发挥);
- 与卡③对齐 ConfirmDialog 消费方编排机制(T4 互指)、与卡⑤对齐顶栏位与刷新单口(§0 跨卡接口)。
### T1 场景素材终稿录入(asset-ingest 第 3 步,≈1–1.5d,用户另发令)
### T1 场景美术产出(≈2–4d,渠道 A/B 待裁 Q1)
- 取用:P1=B 渠道已裁(2026-10-22)、P4 参照物已补(2026-10-23)、Q6 甲过渡口径已裁(1280×800+烛光黄/木色、2× 源档最近邻降采样)、`_终稿裁定-2026-10-31.txt`(各素材第一张样本稿为终稿、保留全部待选稿)、camp-scene-prompts.md §2–§4。
- [ ] 按终稿裁定清单核对十层指定文件(z0 bg/z1 wall/z2–z6 八物件层),确认各取第一张样本稿为终稿、其余候选保留不删。
- [ ] 用户发令后做后处理:去底转透明(bg 不去底、全幅不透明)/擦通道水印/降采样到 1280×800(整数倍)/围墙层裁细条 (0,240,1280,70) 不做全幅/色板量化/四联底测试条——工具清单见 `design/art/art-pipeline-tools.md`;**用户 2026-10-31 令只生成素材不做后续工序,本步须开工另发令**。
- [ ] 产物落盘:`artwork/`(在途,主区绝对路径)→ 验收后终稿 `game/assets/art/scene/`;替换先归档旧档;命名 `scene_camp_<键>.png` 对齐消费常量 `UiKit.TEX_CAMP_*`(asset-path-map.md §3/art-assets-checklist.md §3.5,先定资源路径常量、素材名跟它走,防断链)。
- [ ] 美术硬约束入产线(契约 7):48 色板/HSV 300°–345° 禁入带/语义色/WCAG/Nearest;**色板机检二器复用**(`palette_check.py` 48 令牌+新增色双门/`standee_asset_check.py` 像素 32 色冻结)。
- [ ] 方向稿选划留痕:用户 2026-10-31 已裁「第一张样本稿为终稿、保留全部待选稿、每个都还可以接受」,选划三段表进开工单;本批不再重跑方向稿工序。
- [ ] 终稿落盘「验收」口径=契约 9(迭代内验收:截图对比+shot_checker 机检+样张过审留痕)。
- 产出:十层终稿入 `game/assets/art/scene/`(`UiKit.TEX_CAMP_*` 常量对齐)+素材线在途/归档清单;T2 可挂接。
- 按纵深稿构图(远景天空/中景围栏+大门/近景篝火居中/左锻炉铁砧/右床铺+宝箱)出场景图;七物件可辨性=第一合格线(玩家一眼找到点哪);
- 美术硬约束入产线(契约 7):48 色板/禁入带/语义色/WCAG/Nearest;**色板机检二器复用**(palette_check.py 48 令牌+新增色双门/standee_asset_check.py 像素 32 色冻结——v1.1 订正:非「全仓无工具」);
- 尺寸档=样张批规格清单指针(契约 8);按 Q6 裁定执行过渡口径或挂起;
- 产物按素材线纪律落盘(F14):在途 `artwork/`(主区绝对路径)→ 验收后终稿 `game/assets/art/`;替换先归档旧档;**命名纪律**:art-bible §8.3:503(`<域>_<对象键>_<状态|变体>.png`)+doc-conventions §12 三段式「终稿文件名=代码消费名——先定资源路径常量,素材名跟它走,防断链」(v1.1 补指针);
- 终稿落盘「验收」口径=契约 9(迭代内验收三件套);
- **防不满意工序**:场景图先出 2–3 张低成本方向稿供用户选划,判完方向才精制(样张卡「方向稿先行」同型纪律;选划记录三段表进开工单)。⚠ 本条为**本卡自我从严的执行纪律**,非用户新裁决——用户若要以单路线直接精制,从其裁。
### T2 场景视图与点选交互(≈1.5–2d)
- 取用:T1 十层终稿 `UiKit.TEX_CAMP_*`、`camp_scene_layout.tres` 坐标结构键、camp.md v2.2 点选反馈四态规格、§0.3 P3 设计稿(代码段开工门)。
- [ ] 在 `game/presentation/views/camp_scene_view.gd` 实现 `setup_layers()`:按 §0.4 z0–z6 铺 10 层(bg 不透明全幅/wall 透明细条 (0,240,1280,70)/门洞 x520–760 留透明缺口透出 bg 小路/八物件层);围墙不并回背景层、门洞不填死、门洞不被任何物件遮挡。
- [ ] 实现七物件命中区 `bind_hotspots()` 与 `get_hotspot_rect()`:读 `camp_scene_layout.tres` 坐标键;七件两两不相交、不越画面、不侵入顶栏禁区 y≤48;篝火命中矩形只取下半(火堆),火焰只展示。
- [ ] 实现点选反馈四态 `set_feedback_state()`(零新素材、全程序化):悬停=轮廓亮边+浮动(整像素吸附)+名牌(下方 8px 居中、字号 14、对比 ≥4.5:1)/按下=位移 1px/禁用=降明度+去饱和(仅锻炉、宝箱)/已解锁=常态;提示文案与可点区域视觉按 §0.3 P3 设计稿销号后落(未销号=本段禁开工)。
- [ ] 场景屏顶栏预留位 `set_hud_band()`(高 48px 浮层覆盖、不挤压画面,卡⑤ 填值);刷新入口=本卡 T3 定义的营地刷新单口(卡⑤ 同口挂接)。
- [ ] 叠层规则显式派生并写入 V2 断言:随 §9 第 2 条承载形态裁定派生——独立全屏页=场景根隐藏(生涯先例)/单一内页切换=场景根留底;「缩放虚化」是两选项之外的第三形态(涉新演出面+素材),禁批内自选(若设计稿/用户想要,升格裁点)。
- [ ] 键盘焦点/手柄不涉(08:191-192 排 Beta;ESC 属卡⑤ 用户明示裁决面)。
- 产出:`CampSceneView.setup_layers()`/`bind_hotspots()`/`set_feedback_state()`/`get_hotspot_rect()`/`set_hud_band()`,`object_pressed(key: String)` 信号;T3 按接口块接线。
- 场景屏承载(camp_screen 屏壳改造 vs 新屏壳——§9 拍板):场景图铺底+七物件命中区;
- 点选交互:命中区判定+反馈形态按 Q3 设计稿(悬停高亮/提示文案/可点区域判定三项);
- **场景屏顶栏预留位(v1.1 注明)**:卡⑤ HUD 落位;**刷新入口=本卡 T3 定义的营地刷新单口**(卡⑤同口挂接);
- **叠层规则显式派生(v1.1 补)**:随 §9 第 2 条承载形态裁定派生并写入 V2 断言——独立全屏页=场景根隐藏(生涯先例);单一内页切换=场景根留底;「缩放虚化」是两选项之外的第三形态(涉新演出面+素材),禁批内自选(若设计稿/用户想要,升格裁点);
- 键盘焦点/手柄不涉(08:191-192 排 Beta;ESC 属卡⑤用户明示裁决面)。
### T3 四柜台拆解与入口改挂(≈2–2.5d)
- 取用:T2 的 `CampSceneView`(`object_pressed(key: String)`)、F4 五界面实态、F5 写口链、§0.5 跨卡接口。
- [ ] 锻造工坊/秘宝匣/天赋树/图鉴四界面自 CampOverlay 抽出为独立可开界面(`forge_view.gd`/`treasure_view.gd`/`tree_view.gd`/`codex_view.gd`,承载形态=§9 拍板;约束=写口链路零改、零新素材、界面逻辑复用);**五界面各带返回/关闭钮**(现四者共用 CampOverlay 底栏关闭钮随拆解消失,卡⑤ Q1 甲案前提即此)。
- [ ] 按契约 11 拆分边界纪律落四界面:每界面写职责语句与单一变化原因(实现报告逐件一行)、有集体身份;禁凑计数袋、禁沿阈值轴硬拆;拆不出内聚单元=停卡呈报走豁免。
- [ ] 生涯页入口自主菜单生涯钮改挂帐篷旁笔记本(CareerOverlay 本体零改);**生涯页返回钮文案禁含「营地」字样**(ui_struct_probe.gd:382 nojump 禁词表含「营地」——career_overlay.gd:27 现「返回」安全,改文案时避坑)。
- [ ] 入口改挂后各界面开合走模态栈单口;层序入 `LAYER_CONTRACT`。
- [ ] **CampShopPresenter 承接面改造(契约 4)**:投影目标改线(五界面/场景根)、七写口尾刷新改路由(经营地刷新单口——**各写口尾→现开界面刷新+场景根 HUD 刷新一闸完成**)、open/close 编排从 campbtn 迁位到卡③ 进档动作、CampFlowContext 字段语义订正、探针缝保位(main.gd:1163-1171);`on_camp_attune_toggle`(:98-106)尾只 refresh_camp、不调 `_refresh_presentations` 保持原样。
- [ ] 新建 `camp_refresh_bus.gd` 实现 `CampRefreshBus.refresh(camp_data: Dictionary) -> void`(T0 接口块);卡⑤ HUD 刷新挂此单口,非已退役的 `refresh_camp`。
- [ ] **图鉴占位态(契约 5)**:独立界面壳=§9 第 2 条承载形态;文案照录 camp_overlay_view.gd:168 现行锁文,「柜台结构位预留」中『柜台』称谓随形态订正(L2 记录,零新文案);V6 断言锚定新视图占位标签。
- [ ] **开层互斥与关层收闭**:营地开层时选档层被模态栈遮挡隐藏(卡③ T2 同口径);篝火/ESC 回主菜单=营地层与选档层同收+开始层恢复(现役 on_camp_closed 模式只视野开始层,选档层不在其视野——须显式)。
- [ ] CampOverlay 类退役处理(拆解后无消费面即删——吸收即死);`main.camp_overlay` 探针句柄迁移留痕。
- [ ] 最近冒险条带去向按 Q4=甲执行(随四柜台拆解一并撤下,逐局历史回看归生涯,生涯.md P6 同批注销——反哺点)。
- 产出:五界面独立可开(各带返回/关闭钮)+`CampRefreshBus.refresh()` 单口+CampOverlay 退役;T4 按接口块消费。
- 锻造工坊/秘宝匣/天赋树/图鉴四界面自 CampOverlay 抽出为独立可开界面(承载形态=§9 拍板:各自独立全屏页〔生涯先例〕vs 单一营地内页切换——约束=写口链路零改、零新素材);**五界面各带返回/关闭钮**(v1.1 补承诺——现四者共用 CampOverlay 底栏关闭钮随拆解消失,卡⑤ Q1 甲案前提即此);
- 生涯页入口自主菜单生涯钮改挂床铺旁笔记本(CareerOverlay 本体零改);**生涯页返回钮文案禁含「营地」字样**(ui_struct_probe.gd:382 nojump 禁词表含「营地」——career_overlay.gd:27 现「返回」安全,改文案时避坑,v1.1 补坑注);
- 入口改挂后各界面开合走模态栈单口;层序入 `LAYER_CONTRACT`;
- **CampShopPresenter 承接面改造(v1.1 补条,契约 4)**:投影目标改线(五界面/场景根)、七写口尾刷新改路由(经营地刷新单口——**各写口尾→现开界面刷新+场景根 HUD 刷新一闸完成**)、open/close 编排从 campbtn 迁位到卡③进档动作、CampFlowContext 字段语义订正、探针缝保缝(main.gd:1163-1171);改造纪律见契约 4(attune 尾不一致口保持原样);
- **图鉴占位态(v1.1 补条)**:独立界面壳=§9 第 2 条承载形态;文案照录 camp_overlay_view.gd:168 现行锁文,「柜台结构位预留」中『柜台』称谓随形态订正(L2 记录,零新文案);V6 断言锚定新视图占位标签;
- **开层互斥与关层收闭(v1.1 补条)**:营地开层时选档层被模态栈遮挡隐藏(卡③ T2 同口径);篝火/ESC 回主菜单=营地层与选档层同收+开始层恢复(现役 on_camp_closed 模式只视野开始层,选档层不在其视野——须显式);
- CampOverlay 类退役处理(拆解后无消费面即删——吸收即死纪律);`main.camp_overlay` 探针句柄迁移留痕;
- 最近冒险条带去向按 Q4 裁定执行。
### T4 大门动线(≈1–1.5d)
- 取用:T2 的 `object_pressed(key: String)`、T3 的 `CampRefreshBus`、F6/F7 断点弹窗与冒险编排、Q5 已裁=甲三钮化、卡③ ConfirmDialog 契约 3。
- [ ] 大门点击→两分支确认弹窗(裁决 5):有断点=ConfirmDialog 三出口「继续上一段冒险/开始新冒险/取消」;无断点=「是否开始新冒险:是/否」;点大门永远先出确认、不直接进冒险。
- [ ] **三出口弹窗形态(Q5 已裁=甲)**:ConfirmDialog 三钮化+**消费方编排**(组合根单实例+待确认消费方状态量:open 前设、confirmed/cancelled 后分派;cancelled 恒=无变更退回营地;禁每次 connect/disconnect 漂移、禁双常驻静态接线——卡③ 契约 3 同款互指)。
- [ ] 断点弹窗自主菜单移位(main.gd:475-497 逻辑整体迁来,卡②已摘除原调用)。
- [ ] 「继续上一段冒险」接现役续玩编排(`_resume_from_menu` 同源);「开始新冒险」接现役开局编排(`_start_adventure` 同源)——冒险屏/选路屏/战斗屏零改(F7)。
- [ ] 冒险发起后营地场景屏隐藏;**终局落点不变量**:现役口径=终局 continue 回主菜单(main.gd:703)——若后续改落点为营地,营地语境可能出现未收束会话,卡⑤「返回主菜单」动线须补 `_begin_session(false)`,两卡 T0 互证。
- [ ] 篝火回主菜单动线:命中区只含火堆(不含火焰),**必须二次确认**(camp.md v2.2 已裁,走 ConfirmDialog 先例);确认后营地层与选档层同收+开始层恢复(T3 开层互斥/关层收闭同口径)。
- [ ] `_refresh_resume_button` **不复用**(大门两分支直读 `has_breakpoint`,无钮可刷——函数随卡②删,防两卡互以为对方在处理)。
- 产出:大门两分支+三钮消费方编排+篝火二次确认动线;T5 按接口块验收。
- 大门点击→两分支确认弹窗(裁决 5):有断点=「继续上一段冒险/开始新冒险」二选一;无断点=「是否开始新冒险:是/否」;
- **三出口弹窗形态(Q5 已裁=甲)**:ConfirmDialog 三钮化+**消费方编排**(组合根单实例+待确认消费方状态量:open 前设、confirmed/cancelled 后分派;禁每次 connect/disconnect 漂移、禁双常驻静态接线——卡③ 契约 3 同款互指);
- 断点弹窗自主菜单移位(main.gd:475-497 逻辑整体迁来,卡②已摘除原调用);
- 「继续上一段冒险」接现役续玩编排(`_resume_from_menu` 同源);「开始新冒险」接现役开局编排(`_start_adventure` 同源)——冒险屏/选路屏/战斗屏零改(F7);
- 冒险发起后营地场景屏隐藏;**终局落点不变量(v1.1 补)**:现役口径=终局 continue 回主菜单(main.gd:703)——若后续改落点为营地,营地语境可能出现未收束会话,卡⑤「返回主菜单」动线须补 `_begin_session(false)`,两卡 T0 互证;
- `_refresh_resume_button` **不复用**(大门两分支直读 `has_breakpoint`,无钮可刷——v1.1 明示,函数随卡②删,防两卡互以为对方在处理)。
### T5 断言、探针与截图迁移批(≈2–2.5d)
### T5 断言、探针与 golden 迁移批(≈2–2.5d)
- 取用:T2/T3/T4 全部产物、F8 全量探针位点、F17 机检工具面、契约 10。
- [ ] shot_probe:camp 截图路径改(进入存档→选档→进档→营地场景图);截图自检存在且非空;**camp 段收闭改接**:现经「关闭营地」钮收闭(:133)——营地根态无关闭钮(出口=篝火/ESC),改篝火动线或调试直改 visible。
- [ ] **无 camp golden**(契约 10):camp 验收=shot_probe 出图+shot_checker 语义断言段(文字 WCAG/明度三档带/文字禁压纹理/文字在判据扩 camp 取样面);棋盘/menu 既有 golden 复跑。
- [ ] F8 全量位点逐点迁移:
- [ ] 探针深员改指表:ui_probe `_balance_label`/`_tree_buy_btns`/`_workshop_rows`(:39-52)、ui_click_probe `_tree_buy_btns`/`_tree_fork_btns`+三处 `main.camp_overlay.refresh_camp(main._camp_data())` 直呼(:72/99/110)、ui_struct_probe audit 根(:45)——「改挂新入口」不够,这些是成员级耦合;七命中区与笔记本命中区的探针寻址名随 T2 命名稳定化一并定。
- [ ] smoke_all:6469-6475 源码断言段:三条锁四柜台等高形态本身——按新形态重写或注销(四栏等高纪律是否迁入新界面=§9 第 2 条裁后定)。
- [ ] ui_click_probe:500-528 断点确认段:改走大门路径断言(与 V3 合并或互指;卡② T2 明列移交、本卡 T5 接收)。
- [ ] ui_contrast_probe:48-55 营地令牌段:核签(新界面仍消费 `CAMP_HEADER_BAND`/`CAMP_ROW_PLATE`=段留;不再消费=段随注销)。
- [ ] forge_workbench_test.gd 单测:随锻造视图抽出同迁(断言零改、只换承载类);V4 复跑清单补该单测。
- [ ] 生涯段驱动改接:ui_struct_probe:54-69 与 shot_probe:103-124 现经 `_start_overlay`「生涯」钮驱动——改挂后须合成点击场景笔记本命中区;命中区若为 TextureRect/Area2D 而非 Button,`ProbeUiUtil.find_button` 失效,寻址面随 T2 扩展。
- [ ] screen_flow_probe 营地键新语义::53 改指新场景根句柄;子界面开态时键真值按 T2 叠层规则派生;:119-125 回退段改新场景根 closed 信号或篝火动线。
- [ ] 多卡共改文件分界:screen_flow_probe(入口路径段归卡②、键语义/开合/篝火段归本卡)、ui_click_probe(入口路径归卡②、槽操作路径归卡③、营地段+断点确认段归本卡)——每条探针注分界。
- [ ] 新增断言段(**正向验收断言,从真实入口进入、判据绑被测改动特有的可观测提交面**):七物件逐一可达对应界面;大门两分支;点大门不直接进冒险(绑 `confirmed` 信号与 `route_chosen` 未发);点大门→开局后营地场景屏隐藏;图鉴=占位挂起态;场景根态无文字按钮列表/无四柜台面板(反参照纪律断言);presenter 七写口尾→现开界面刷新+场景根 HUD 刷新一闸(绑刷新单口调用记录与 HUD 状态源取值);三钮弹窗 cancelled 恒=无变更退回营地(绑写口零调用+营地根 visible)。**判据绑不上=静态判据+评审注记申报观测面局限,证明做不出=停卡呈报;断言只在当轮真实跑批执行并通过,不做注入破坏。**
- [ ] 美术约束机检:shot_checker 现役段扩 camp 取样;截屏级 48 色计数是否新建=§9 第 5 条拍板(依赖 §0.3 环境子板色值代码段开工门销号)。
- 产出:探针/断言迁移留痕表(F8 全量位点逐点「改前→改后」)+新增断言段;T6 收口。
- shot_probe:camp 截图路径改(进入存档→选档→进档→营地场景图);截图自检存在且非空;**camp 段收闭改缆(v1.1 补)**:现经「关闭营地」钮收闭(:133)——营地根态无关闭钮(出口=篝火/ESC),改篝火动线或调试直改 visible;
- **无 camp golden**(契约 10):camp 验收=shot_probe 出图+shot_checker 语义断言段(文字 WCAG/明度三档带/文字禁压纹理/文字在判据扩 camp 取样面);棋盘/menu 既有 golden 复跑;
- F8 全量位点逐点迁移(v1.1 补列项):
- **探针深员改指表**:ui_probe `_balance_label`/`_tree_buy_btns`/`_workshop_rows`(:39-52)、ui_click_probe `_tree_buy_btns`/`_tree_fork_btns`+三处 `main.camp_overlay.refresh_camp(main._camp_data())` 直呼(:72/99/110)、ui_struct_probe audit 根(:45)——「改挂新入口」不够,这些是成员级耦合;七命中区与笔记本命中区的探针寻址名随 T2 命名稳定化一并定;
- **smoke_all:6469-6475 源码断言段**:三条锁四柜台等高形态本身——按新形态重写或注销(四栏等高纪律是否迁入新界面=§9 第 2 条裁后定);
- **ui_click_probe:500-528 断点确认段**:改走大门路径断言(与 V3 合并或互指;卡② T2 明列移交、本卡 T5 接收);
- **ui_contrast_probe:48-55 营地令牌段**:核签(新界面仍消费 `CAMP_HEADER_BAND`/`CAMP_ROW_PLATE`=段留;不再消费=段随注销);
- **forge_workbench_test.gd 单测**:随锻造视图抽出同迁(断言零改、只换承载类);V4 复跑清单补该单测;
- **生涯段驱动改缆**:ui_struct_probe:54-69 与 shot_probe:103-124 现经 `_start_overlay`「生涯」钮驱动——改挂后须合成点击场景笔记本命中区;命中区若为 TextureRect/Area2D 而非 Button,`ProbeUiUtil.find_button` 失效,寻址面随 T2 扩展;
- **screen_flow_probe 营地键新语义**::53 改指新场景根句柄;子界面开态时键真值按 T2 叠层规则派生;:119-125 回退段改新场景根 closed 信号或篝火动线;
- **多卡共改文件分界**:screen_flow_probe(入口路径段归卡②、键语义/开合/篝火段归本卡)、ui_click_probe(入口路径归卡②、槽操作路径归卡③、营地段+断点确认段归本卡)——每条探针注分界;
- 新增断言段:七物件逐一可达对应界面;大门两分支;点大门不直接进冒险;**点大门→开局后营地场景屏隐藏(v1.1 补)**;图鉴=占位挂起态;场景根态无文字按钮列表/无四柜台面板(反参照纪律断言);
- 美术约束机检:shot_checker 现役段扩 camp 取样;截屏级 48 色计数是否新建=§9 第 5 条拍板(依赖样张批规格清单,随 Q6 一并裁);
- **变异验证伴生**:某物件命中区漏绑(预期可达性断言红)、大门直连开局绕过确认(预期分支断言红)、图鉴内容激活(预期挂起态断言红)、**presenter 某写口尾漏挂新界面刷新**(预期余额/HUD 不同步红——v1.1 补)、**三钮弹窗取消被接成写档动作**(预期无变更退回红——v1.1 补);注入→最窄闸见红→精确还原→记录。
### T6 产出物落位卡(≈0.5d,末卡)
- 取用:T0–T5 全部产物。
- [ ] 里程碑步(波/T 段)出口跑一次代码域全套闸:`bash tools/run_all_gates.sh --code`;回执 `all_green=true`;任何新增红停卡,不得带红合回。波内修复只做出红最小单元的最窄确认;新增测试/工具先行孤立验证再并入全套。
- [ ] 独立验收审计由未参与实现的会话/子代理执行,产出 `reports/iter<N>-验收审计-<日期>.md`;未过禁合并(审计入口见 §7)。
- [ ] 轻闸全绿、合并前写齐三份 `reports/`:
- [ ] `reports/iter<N>-实现报告-<日期>.md`(各卡状态+实机目检总清单+遗留读数义务+实现决定记录/代拍板追认单+探针迁移留痕表+方向稿选划留痕〔已由 2026-10-31 裁定〕);
- [ ] `reports/iter<N>-反哺点-<日期>.md`(§5 每条有落点:文件/节/原句/拟改句/依据,明确「实现批未写 design/」);
- [ ] `reports/iter<N>-验收审计-<日期>.md`(独立审计逐行「通过/缺漏/例外及依据」)。
- [ ] 用户目检项登记 07 清单(场景观感/七物件辨识与点选反馈/大门两分支/篝火动线),登记完成即卡内义务了结,不阻塞批末收尾/合并/下一迭代开工。
- 产出:三份 `reports/` 齐全+代码域闸全绿+验收审计通过,方算收口;合回后由本地 CI 全量域闸复验。
三份 `reports/` 写齐(实现报告含方向稿选划记录三段表、探针迁移留痕表、变异记录表、目检总清单/代拍板追认单/反哺点清单)。
**估时合计 ≈9–12d**(presenter 承接面+三钮弹窗+探针深员面增量;T1 为素材录入、美术创作主体归美术自立批已完成)。
**估时合计 ≈9–12d**(v1.1 上调:presenter 承接面+三钮弹窗+坏槽态联动+探针深员面增量)。**天然切分点=T1 出口**(场景素材归档齐)——美术线与代码线可分批交付(用户批次归属裁);若单批跑超迭代盒,T3 末(四柜台拆解完)为次切分点。
## 7. 验证闸:改动—验收对照表
## 7. 验证闸(逐需求点验收清单)
七格表:需求点|改动(文件:行/行为)|验收测试(名称+落点+尾缀)|层级(单元/接口/集成/探针)|真实入口|判据绑定面|能力行。**每个需求点至少一行;每个行为改动至少一行(V1–V13 需求点行+B1–B2 行为改动专行);每行必须有真实入口和判据绑定面——缺任一项=该需求点未验收,卡片不成立。** 断言尾缀〔营地图批 Vn〕/〔营地图批 Bn〕,与卡片清单互相 grep。能力行格式 `既有:<能力名>`/`新增:<能力名>`,两形态名称都须在 `game/tests/README.md` 能力表在场(既有=现役在场名,新增=本卡定名、由主 Agent 统一收口入表;本卡只写卡内能力行文字,README 由主 Agent 收口)。
| # | 需求点 | 测什么 | 落点/判定手段 |
|---|---|---|---|
| V1 | 场景图形态(机检半) | camp 截图=场景图形态(非四柜台覆盖层) | shot_probe camp 截图+shot_checker 结构禁词(与 V9 同)——**「七要素可辨(构图)」归 V11 目检**(v1.1 拆半:shot_checker 不判构图) |
| V2 | 七物件可达性 | 点每物件→对应界面可见+营地场景按 T2 叠层规则退避 | ui_click_probe 七段合成点击(新断言;命中区寻址面随 T2) |
| V3 | 大门两分支+开局收闭 | 有断点=弹二选一;无断点=弹是否开始;点大门不直接进冒险;点确认开局后营地场景屏隐藏 | 探针合成点击+状态断言(夹具经调试接口直写/清断点) |
| V4 | 五界面功能+写口链零回归 | 树购买/Fork 切换/锻造三意图/秘宝购买/同调装配/图鉴占位——既有断言全链复跑绿;presenter 各写口尾的 MetaProgression 原语调用序列不变(v1.1 扩) | ui_click_probe 迁移段+smoke `_face_snapshot` 段+forge_workbench_test 迁移复跑 |
| V5 | 生涯只读契约保持 | 生涯页经笔记本可达;页内零跳转零动效契约不破(三契约只约束页子树、不依赖入口位置——v1.1 证实原样成立) | ui_struct_probe career 段迁移复跑 |
| V6 | 图鉴挂起态 | 布告板→图鉴=占位态;内容零激活 | 探针禁词/禁行断言(锚定新视图占位标签) |
| V7 | 篝火动线 | 点篝火→营地隐藏+选档层同收+主菜单可见 | screen_flow_probe 型断言 |
| V8 | 顶栏预留位 | 场景屏顶栏 HUD 位存在(卡⑤联验填值+刷新单口挂接) | 结构断言+跨卡联验 |
| V9 | 反参照纪律 | 营地根态无文字按钮列表、无四柜台面板 | ui_struct_probe 结构禁词断言 |
| V10 | 美术约束 | 文字 WCAG/明度三档带/文字禁压纹理底;素材色板(palette_check/standee 二器或截屏计数若建) | shot_checker 段扩 camp 取样+§9 第 5 条拍板面 |
| V11 | 目检项登记 | 场景观感/七物件辨识(纵深稿构图可辨)/点选反馈/大门两分支/篝火动线入 07 | 件核(登记不阻塞,澄清⑥) |
| V12 | 探针迁移留痕核验 | F8 全量位点逐点有「改前→改后」记录(契约 10 留痕义务) | 件核对表(T6 追认单) |
| V13 | 反哺点清单 | §5 每条有落点 | 件核对表 |
| 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|
| V1 场景图形态(机检半) | `camp_scene_view.gd` 10 层铺底(z0 不透明全幅含门洞小路/z1 透明细条 (0,240,1280,70) 门洞缺口/z2–z6);`camp_screen.gd` 改挂;`shot_probe.gd` camp 段 | `shot_probe.gd:_ready`(camp 截图段)〔营地图批 V1〕+`shot_checker.py` 结构禁词段 | 探针 | 进入存档→选档→进档→营地场景屏(shot_probe 驱动) | camp 截图出图非空+shot_checker 结构禁词命中(无四柜台覆盖层/无文字按钮列表);「七要素可辨(构图)」归 V11 目检 | 新增:营地场景图十层铺底与门洞留空呈现 |
| V2 七物件可达性+叠层退避 | `camp_scene_view.gd` 七命中区+`object_pressed` 信号;`camp_scene_layout.tres` 坐标键;组合根开界面 | `ui_click_probe.gd:_ready`(七物件合成点击段)〔营地图批 V2〕 | 探针 | 命中区 `_gui_input()` → `object_pressed(key)` → 组合根开界面 | 七物件各自对应界面 visible 断言+场景根按 T2 叠层规则退避(树序/可见性);绑 `object_pressed` 信号发射面 | 既有:模态覆盖层编排与输入锁;新增:营地七物件命中区点选与分界面可达 |
| V3 大门两分支+开局收闭 | `main.gd:475-497` 断点弹窗移位;`confirm_dialog.gd` 三钮化;消费方编排 | `ui_click_probe.gd:_ready`(大门两分支段/断点确认段 :500-528)〔营地图批 V3〕 | 探针 | 大门命中区 → ConfirmDialog(三出口)→ `main._on_confirm_new_adventure()`/`_resume_from_menu()` | 有断点三出口/无断点两出口;点大门不直接进冒险(绑 `confirmed` 信号与 `route_chosen` 未发);cancelled 绑写口零调用+营地根 visible;开局后营地场景屏隐藏 | 既有:断点片段往返与续玩幂等;新增:营地大门两分支确认与断点续玩接线 |
| V4 五界面功能+写口链零回归 | 四界面 view 抽出;`camp_shop_presenter.gd` 承接面;`camp_flow_context.gd` 字段;`forge_workbench_test.gd` 迁移 | `forge_workbench_test.gd:_test_forge_rows`〔营地图批 V4〕+`ui_click_probe.gd:_ready`(写口链段)+`smoke_all.gd:_face_snapshot` 段 | 单元+探针 | 五界面意图信号(`buy_requested`/`tree_buy_requested`/`forge_*`)→ CampShopPresenter → MetaProgression 写口 | 树购买/Fork 切换/锻造三意图/秘宝购买/同调装配既有断言全链复跑绿;presenter 各写口尾 MetaProgression 原语调用序列不变(绑调用序列,不绑终态兜底) | 既有:元进度入账与锻造两轴;新增:四柜台拆解后五界面入口改挂与写口零回归 |
| V5 生涯只读契约保持 | `career_overlay.gd` 入口改挂笔记本;`ui_struct_probe.gd`/`shot_probe.gd` 生涯段驱动改接 | `ui_struct_probe.gd:_ready`(career 段)〔营地图批 V5〕 | 探针 | 笔记本命中区 → `CareerOverlay.open()` | 生涯页经笔记本可达+页内零跳转零动效契约三断言不破(三契约只约束页子树、不依赖入口位置);返回钮文案禁含「营地」 | 新增:营地篝火回主菜单与笔记本改挂动线 |
| V6 图鉴挂起态 | `codex_view.gd` 占位壳;布告板命中区 | `ui_struct_probe.gd:_ready`(占位禁词/禁行段)〔营地图批 V6〕 | 探针 | 布告板命中区 → 图鉴占位视图 | 锚定新视图占位标签(现行锁文「柜台结构位预留」称谓随形态订正)+内容零激活禁行断言;不是禁用态 | 新增:营地图鉴占位挂起态与反参照结构纪律 |
| V7 篝火动线(二次确认) | `main.gd` 篝火回主菜单+开层互斥/关层收闭;`screen_flow_probe.gd` 段 | `screen_flow_probe.gd:_ready`(篝火/开合段)〔营地图批 V7〕 | 探针 | 篝火命中区(只下半火堆)→ ConfirmDialog 二次确认 → 主菜单 | 二次确认弹窗 `confirmed` 信号先于关层;确认后营地隐藏+选档层同收+主菜单可见(绑可见性/层序);命中区只含火堆不含火焰 | 新增:营地篝火回主菜单与笔记本改挂动线 |
| V8 顶栏预留位+刷新单口 | `camp_scene_view.gd` 顶栏 HUD 位;`camp_refresh_bus.gd` 新建;presenter 七写口尾改路由 | `ui_struct_probe.gd:_ready`(顶栏位段)〔营地图批 V8〕+`ui_click_probe.gd:_ready`(写口尾刷新段) | 探针 | 写口尾 → `CampRefreshBus.refresh(camp_data)` → 现开界面刷新+场景根 HUD 刷新 | 场景屏顶栏 HUD 位存在(结构断言,高 48px 浮层);各写口尾→现开界面刷新+场景根 HUD 刷新一闸完成(绑刷新单口调用记录与 HUD 状态源取值);卡⑤ 联验填值 | 新增:营地刷新单口与场景根 HUD 同步 |
| V9 反参照纪律 | `camp_scene_view.gd` 根态;`camp_overlay_view.gd` 退役;`smoke_all.gd:6469-6475` 源码断言段 | `ui_struct_probe.gd:_ready`(结构禁词段)〔营地图批 V9〕 | 探针 | 营地根态场景树审计 | 营地根态无文字按钮列表、无四柜台面板(结构禁词断言);四柜台等高源码断言按新形态重写或注销(迁移留痕) | 新增:营地图鉴占位挂起态与反参照结构纪律 |
| V10 美术约束 | `tools/shot_checker.py` camp 取样面;`ui_contrast_probe.gd` 令牌核签;素材色板二器 | `ui_contrast_probe.gd:_ready`(营地令牌段)〔营地图批 V10〕+`shot_checker.py` WCAG/明度三档带段 | 探针(机检) | camp 截图+素材文件(`palette_check.py`/`standee_asset_check.py`) | 文字 WCAG ≥4.5:1/明度三档带/文字禁压纹理底/文字在判据;素材色板(48 令牌+新增色双门/像素 32 色冻结);§9 第 5 条拍板截屏计数面 | 既有:UI 全局主题与按钮五态(含对比度锚);新增:营地场景图十层铺底与门洞留空呈现 |
| V11 目检项登记 | `reports/iter<N>-实现报告-<日期>.md` 实机目检总清单 | 件核对(07 清单登记,登记不阻塞)〔营地图批 V11〕 | 用户目检(非自动化) | 用户实机(生命周期末步统一进行,不阻塞迭代) | 场景观感/七物件辨识(纵深稿构图可辨)/点选反馈/大门两分支/篝火动线入 07 清单=登记即义务了结 | 新增:营地场景图十层铺底与门洞留空呈现 |
| V12 探针迁移留痕核验 | F8 全量位点逐点迁移 | 件核对表(T6 追认单)〔营地图批 V12〕 | 件核对(非自动化) | 探针脚本 diff 对账 | F8 全量位点逐点有「改前→改后」记录(契约 10 留痕义务) | 既有:模态覆盖层编排与输入锁;新增:营地七物件命中区点选与分界面可达 |
| V13 反哺点清单 | §5 每条有落点 | 件核对表〔营地图批 V13〕 | 件核对(非自动化) | §5 同步面逐条对账 | §5 每条有 `reports/iter<N>-反哺点-<日期>.md` 落点 | 既有:模态覆盖层编排与输入锁 |
| B1 组合根接线总改造(行为改动专行) | `main.gd`(断点弹窗移位+三钮消费方编排+营地入口改挂+篝火动线+开层互斥);`confirm_dialog.gd` 三钮;`camp_shop_presenter.gd` 写口尾路由;`camp_flow_context.gd` 字段;`camp_refresh_bus.gd` 单口 | `ui_click_probe.gd:_ready`(断点确认段)+`screen_flow_probe.gd:_ready`(篝火段)〔营地图批 B1〕 | 集成 | `_on_confirm_new_adventure()`/`_resume_from_menu()`/`_start_adventure()`/`CampRefreshBus.refresh()` | 三钮消费方编排:open 前设消费方、confirmed/cancelled 后分派;cancelled 绑写口零调用;写口尾绑 `CampRefreshBus.refresh()` 调用记录+现开界面+场景根 HUD 同刷;`on_camp_attune_toggle` 尾只 refresh_camp 保持原样 | 既有:断点片段往返与续玩幂等;新增:营地刷新单口与场景根 HUD 同步 |
| B2 CampOverlay 退役+五界面抽出(行为改动专行) | `camp_overlay_view.gd` 退役;四界面 view 抽出;`career_overlay.gd` 入口改挂;`smoke_all.gd:6469-6475` 源码断言段 | `smoke_all.gd:_ready`(源码断言段重写)+`forge_workbench_test.gd:_test_forge_rows`(承载类换)〔营地图批 B2〕 | 集成 | 五界面 `open()`/`close()` → 模态栈单口 | CampOverlay 无消费面即删(吸收即死,绑 `main.camp_overlay` 句柄迁移留痕);四界面各带返回/关闭钮;拆分沿职责轴(契约 11:职责语句/单一变化原因/集体身份,禁凑计数袋) | 既有:元进度入账与锻造两轴;新增:四柜台拆解后五界面入口改挂与写口零回归 |
**测试方式两分法**:V1–V10、V12 机检自动化(能力验证经调试接口直改断点/钥石/解锁状态,沿用 DebugOverlay/DS_DEBUG 门控);V11 归用户目检(生命周期末步统一进行,不阻塞迭代)。
**落点集中**:V1/V9/V11/V12 → T5/T6;V2/V8 → T2/T3;V3/V7 → T4;V4/V5/V6 → T3;V10 → T5;V13 → T6;B1 → T3/T4;B2 → T3/T5。全表名实核对归 T6。
**测试方式两分法**:V1–V10、B1–B2 机检自动化(能力验证经调试接口直改断点/钥石/解锁状态,沿用 DebugOverlay/DS_DEBUG 门控,不走正常资源积累流程);V11 归用户目检(生命周期末步统一进行,不阻塞迭代);V12/V13 为件核对表(非自动化,T6 追认单)。**用户目检一律「登记不阻塞」**:登记完成即卡内义务了结,验收时间由用户自行安排,不得作为批末收尾、合并或下一迭代开工的前置条件。
**判据绑定面口径**:每个行为改动的验收断言从真实入口进入、判据绑被测改动特有的可观测提交面(信号/事件/入参/状态源取值/绘制记录/可见性/树序),在当轮真实跑批中执行并通过(2026-10-24/2026-10-28 用户两裁:断言从真实入口进、判据钉可观测提交面,人为制造红属伪造证据)。判据绑不上(纯防御分支、release 独有位)=静态判据+评审注记申报观测面局限,**证明做不出=停卡呈报**。配判据按强弱分层配齐:运行期断言(可见性/树序/状态源取值)抓状态类缺陷,golden 逐像素抓内容观感类缺陷(本卡无 camp golden,用 shot_checker 语义断言段+目检),占比/统计类判据只兜「整框空白/整框糊」、是补充不是主力(细则=test-conventions §8.4)。
**测试削弱申报**(实现期未申报的削弱由独立验收审计判红):允许改/删的旧断言逐条列——
| 旧断言 | 允许处置 | 理由 |
|---|---|---|
| `smoke_all.gd:6469-6475` 三条锁四柜台等高形态源码断言(`Vector2(0,336)`×3/`SIZE_FILL`×4/`SIZE_SHRINK_CENTER`≥3) | 按新形态重写或注销 | CampOverlay 四柜台形态退役,旧形态断言失去对象(吸收即死,不保留无效断言) |
| `ui_contrast_probe.gd:48-55` 营地令牌段 | 核签后段留或随注销 | 新界面若不再消费 `CAMP_HEADER_BAND`/`CAMP_ROW_PLATE` 则段标签虚挂;仍消费则保留 |
| `ui_click_probe.gd:500-528` 断点确认段(经 lvbtn 驱动) | 改走大门路径断言 | 卡②撤钮+本批弹窗移位双杀,改挂大门命中区(与 V3 合并或互指) |
| `ui_probe.gd:39-52` 深员(`_balance_label`/`_tree_buy_btns`/`_workshop_rows`) | 改指新界面/场景根成员 | 成员级耦合随四柜台拆解迁移,寻址名随 T2 稳定化 |
| `screen_flow_probe.gd:53`/:109-125 营地键/回退段直呼 `main.camp_overlay` | 改指新场景根句柄/closed 信号 | 句柄迁移到新场景根(F2/F8) |
| `shot_probe.gd:126-133` camp 收闭段经「关闭营地」钮 | 改篝火动线或调试直改 visible | 营地根态无关闭钮(出口=篝火/ESC) |
| `ui_struct_probe.gd:54-69`/`shot_probe.gd:103-124` 生涯段经 `_start_overlay`「生涯」钮 | 合成点击笔记本命中区 | 入口改挂帐篷旁笔记本,驱动改接 |
| `forge_workbench_test.gd:33` 直载 `camp_overlay_view.gd` | 随锻造视图抽出同迁,断言零改只换承载类 | 承载类迁移,行板/写口逻辑复用(契约 4) |
**禁止削弱声明**:除上列外,实现期不得删除断言、放宽阈值、缩小扫描面、把真实入口换成下层直调。五界面写口链(V4)、生涯只读契约(V5)、图鉴挂起态(V6)、美术约束(V10)的既有断言全链复跑绿,禁削弱;棋盘三张+menu_boot 既有 golden 逐像素复跑、不放宽容差;不新建 camp golden(契约 10,若新建须另裁 L3)。
**独立验收审计**:合并前由未参与实现的会话/子代理执行,入口为审计只读本卡、实际对照表、diff、测试文件与实现报告,自跑最窄测试抽查、不采信报告「已全绿」;至少四件事——①逐行核对照表(测试存在、真的执行、尾缀能 grep 到、真实入口没有绕过改动点)②抽查判据绑定面(绑被测改动特有可观测提交面、当轮真实跑批执行过)③检查测试削弱(删除断言/放宽阈值/缩小扫描面/换下层直调逐处要本卡申报或用户批准)④核内部字段直查的受控例外(该行为无公开可观测面可钉时已在对照表注明理由)。报告落 **`reports/iter<N>-验收审计-<日期>.md`**,逐行「通过/缺漏/例外及依据」,未通过不得合并。测试执行两入口铁规不变:审计在迭代 loop 内启动的子代理算 loop,另开会话须用户点名。
**闸口径**:轻闸每卡出口自跑;批末重闸按改动域选档(本批碰 `game/` 代码/断言/终稿素材 → `--code`)全绿才合并;MC 零跑(零数值零行为——纯呈现+承载迁移)。卡内不写死闸件名单,域划分唯一出处在 `tools/run_all_gates.sh`。回归措辞按模板:里程碑步(波/T 段)出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试/工具先行孤立验证再并入全套。
**闸口径**:轻闸每卡出口自跑;批末重闸按改动域选档(本批碰 `game/` 代码/断言/终稿素材 → `--code`)全绿才合并;MC 零跑(零数值零行为——纯呈现+承载迁移)。
## 8. 异常分级
- **L1(自救一次)**:断言写法、探针路径、命中区微调、命名、编译错误、签名拼写、测试套件 manifest 登记遗漏。
- **L2(记录继续;同一红连续三次升 L3)**:场景屏承载形态选择(§9 域内)、点选反馈参数(§0.3 P3 设计稿域内)、四界面承载形态(§9 域内)、图鉴占位文案称谓订正、行数较 T0 预期漂移但 S13 键不升。
- **L3(立即停卡写报告等用户)**:
- 代码段开工门未销号即需开工对应任务段(§0.3:P3 点选反馈设计稿/P5 GDD·art-bible 落文/camp-scene-prompts §5 五裁点/素材后处理入库);
- 规格清单(样张批)终档置换未按反哺点登记;
- golden 漂移越出预期面(若涉及既有棋盘/menu 基线);
- 发现五界面任一功能/写口链路被意外触碰(契约 4 破);
- 参照物与纵深稿结构性冲突再现(P4 已补、冲突已呈报,禁批内自行改构图);
- 美术渠道 B 执行中撞墙(插画级新产达不到七物件可辨性);
- 提议新建 camp golden(契约 10——须另裁);
- 任何验收行无法从真实入口绑定特有可观测提交面(证明做不出=停卡呈报);
- **机检预算互斥=上游缺陷停卡退回写卡段**:实现规范预算超默认未走指标例外申报、或 S13 键较登记值上升、或机检键/计数与卡片契约互斥——一律停该卡呈报退回写卡段,禁为凑绿保留无效成员、造第三条路或内联求裁(契约 12/第 13 节合流);
- **拆分边界**:按契约 11 拆不出内聚单元(只能凑计数袋/沿阈值轴硬拆)=停卡呈报走豁免/还债通道,禁硬拆凑绿。
- **L1(自救)**:断言写法、探针路径、命中区微调、命名。
- **L2(记录继续)**:场景屏承载形态选择(§9 域内)、点选反馈参数(Q3 设计稿域内)、四界面承载形态(§9 域内)、方向稿张数在 2–3 内自选、图鉴占位文案称谓订正。
- **L3(停机呈报)**:Q1–Q6 未裁即需开工对应任务段;规格清单(样张批)晚于本批且 Q6 未裁;golden 漂移越出预期面(若涉及既有棋盘/menu 基线);发现五界面任一功能/写口链路被意外触碰(契约 4 破);参照物到手后与纵深稿结构性冲突(呈报,禁批内自行改构图);美术渠道 A/B 执行中撞墙(如 CC0 改色达不到七物件可辨性);提议新建 camp golden(契约 10——须另裁)。
## 9. 代拍板白名单(超清单必呈报)
> 篝火二次确认已由 camp.md v2.2 裁定为**必须**(走 ConfirmDialog 先例),不属代拍板域。
1. 场景屏承载形态(camp_screen 屏壳改造 vs 新屏壳)——约束:`LAYER_CONTRACT` 更新+探针挂载面迁移留痕。
2. 五界面拆出后的承载形态(独立全屏页 vs 单一内页切换)+**叠层规则派生**(独立全屏页=场景根隐藏/单一内页切换=场景根留底;写入 V2 断言;「缩放虚化」禁自选)。
3. 七物件命中区实现(TextureRect 分区 vs 其他)与点选反馈参数(§0.3 P3 设计稿域内)。
4. 截屏级 48 色计数工具是否新建及落点(现役=素材级二器 F17;截屏级依赖 §0.3 环境子板色值代码段开工门销号后定)。
5. CampOverlay 类退役范围(整类删 vs 留片段)——约束:吸收即死,禁留死代码。
6. 提交切分与 worktree 分支命名。
2. 五界面拆出后的承载形态(独立全屏页 vs 单一内页切换)+**叠层规则派生**(v1.1:独立全屏页=场景根隐藏/单一内页切换=场景根留底;写入 V2 断言;「缩放虚化」禁自选)。
3. 七物件命中区实现(TextureRect 分区 vs 其他)与点选反馈参数(Q3 裁定域内)。
4. 篝火是否需二次确认——默认直回(营地每笔消费即时写盘,无未保存风险——存档序列化.md:121);如判需确认,走 ConfirmDialog 先例。
5. 截屏级 48 色计数工具是否新建及落点(现役=素材级二器,F17;截屏级依赖样张批规格清单,随 Q6 一并裁)。
6. CampOverlay 类退役范围(整类删 vs 留片段)——约束:吸收即死,禁留死代码。
7. 提交切分与 worktree 分支命名。
超出必须呈报:任何数值、像素规格、事件名、命中区绑定目标、文件职责、T 卡验收落点、五界面写口链路、拆分单元职责。
## 10. 裁点与设计议程(v2.1:本卡在批内,以下为前置解决议程)
## 10. 待裁点:零待裁点,开工门=U0
> Q4/Q5/Q6/Q8 已裁(裁定见卡头);Q1/Q2 仍待用户。本节约等于批内设计段的工作清单。
**本卡设计待裁点清零,开工门=U0。** Q1/Q2/Q4/Q5/Q6/Q8 均已裁(下列为现行裁定留痕,非待裁点,实现期禁自行改值):
### Q1 · 营地场景图的美术渠道(**仍待用户裁——批内第一议程,阻塞 P2 规格分支与方向稿**)
- **Q1 美术渠道=B·插画级新产**(2026-10-22 用户裁):✦ 渠道作者自跑远程生图管线;规格沿用 art-bible §6.2/§8.1/§8.2 既有裁决(art-assets-checklist.md §3.5)。
- **Q2 参照物=已补**(2026-10-23):`artwork/2026-10-23-营地场景/Gemini_Generated_Image_ykrc0nykrc0nykrc.jpg`,已进 camp-scene-prompts.md §1 登记为「作者提供的参照物」,与纵深稿对过表、围墙结构冲突已呈报;参照物只是参考图,保留 `artwork/`、不入 git、不入游戏目录。
- **Q4 营地底栏「最近冒险」条带去留=甲**(2026-10-18):随四柜台拆解一并撤下,逐局历史回看整体归生涯(期二承接);生涯.md P6 同批注销(反哺点)。
- **Q5 大门「有断点」分支三出口弹窗=甲**(2026-10-18):ConfirmDialog 扩第三钮(继续上一段冒险/开始新冒险/取消,cancelled 恒=无变更退回营地);卡③ 契约 3 已按三钮化落定(删档确认只用取消/确认)。
- **Q6 Q1 与规格清单缺口连带裁=甲**(2026-10-18):过渡尺寸档=现役 1280 工程档(1280×800)+烛光黄 #F6C667/木色 #8A5A34;渠道 B 已裁(2026-10-22),规格落 art-bible v3.24 §6.2/art-assets-checklist.md §3.5(2× 源档出图、最近邻降采样到 1280×800);终档归样张批冻结清单后置换(反哺点登记),执行归用户线。
- **Q8 设计稿产出方式=甲**(2026-10-18):批内出稿呈裁(方向稿先行纪律照旧——方向稿选划已由 2026-10-31 样张过审裁定完成,各素材第一张样本稿为终稿、保留全部待选稿)。
**背景**:澄清⑧2——「美术渠道 A/B 未裁:CC0 改色 vs 插画级新产——原贴图批的渠道问题对营地场景图同样成立,本讨论未裁决」。
**代码段 `/iter` 开工门(不是设计待裁点,不阻塞重立卡与编迭代)**,见 §0.3:P3 点选反馈设计稿、P5 GDD/art-bible 条款落文、camp-scene-prompts.md §5 五个待裁点(帐篷尺寸/门扇高宽/布告板位置/描边颜色追认/环境子板色值)、十张终稿后处理与落 `game/assets/art/scene/`(实现段 T1/`asset-ingest` 第 3 步,用户 2026-10-31 令只生成素材不做后续,开工时另发令)。编入哪一迭代归 iter-plan 段发令,本卡不代裁。
**我的推荐:A · CC0 改色**(理由:06:23 已有配色规格〔烛光黄 #F6C667 配木色 #8A5A34〕与渠道合法性记载、零新绘成本、方向稿不受「从零构图」拖累;B 依赖尚未冻结的规格清单且周期长)。用户此前令不代裁——推荐已摊开,等你一句 A 或 B,方向稿(T1 防不满意工序)当天可出。
| 案 | 内容 | 代价 |
|---|---|---|
| A · CC0 改色 | 通用场景素材改色复用(06:23 载明该渠道对营地件合法:烛光黄 #F6C667 配木色 #8A5A34 已有规格) | 快、零新绘成本;上限=改色件构图不完全贴合七物件+纵深稿,可能要容忍「近似构图」 |
| B · 插画级新产 | 按纵深稿全新绘制(像素级) | 七物件与构图完全受控;成本高、周期长,且依赖规格清单输入(F16)——须走「等样张批规格清单」或用户另裁过渡规格 |
连带:渠道裁定影响 T1 估时(A 趋下限、B 趋上限)与切分点位置;「归建卡时或样张批规格语境下裁」(澄清⑧2 原文)。
### Q2 · 参照物(**待补输入**)
澄清②/§⑧1:用户原话「目前还没有一个参照,我可以后续找一下」——参照物找到后补充进本卡(与纵深稿对表,结构性冲突=呈报,禁批内自行改构图)。
### Q3 · 物件点选反馈细节(设计稿产出方式已裁=批内出稿呈裁)
澄清⑧3:「悬停高亮/提示文案/可点区域判定」未谈。三项形态归设计稿阶段——**产出方式已裁(Q8=批内出稿呈裁,方向稿先行纪律照旧)**;设计稿只覆盖根态点选反馈,不覆盖进界面后的叠层规则(叠层=随承载形态裁定派生:独立全屏页=场景根隐藏/单一内页切换=场景根留底;「缩放虚化」是第三形态,涉新演出面+素材,禁批内自选)。
### Q4 · 营地底栏「最近冒险」条带去留(**已裁=甲**)
**裁定(2026-10-18)**:甲——随四柜台拆解一并撤下,逐局历史回看整体归生涯(期二承接);生涯.md P6 同批注销(反哺点)。代拍板留痕(用户令「事项按推荐的来」,本项无推荐案,取默认甲=分工矩阵干净、逐局历史只剩一个权威呈现面;追认单可 veto)。
### Q5 · 大门「有断点」分支的三出口弹窗形态(**已裁=甲**)
**裁定(2026-10-18)**:甲——ConfirmDialog 扩第三钮(继续上一段冒险/开始新冒险/取消,cancelled 恒=无变更退回营地)。推荐案,用户令按推荐执行。连带:卡③ 契约 3 已按三钮化落定(删档确认只用取消/确认);类签名变更随本卡重新立卡时的实现落地,卡③ T0 对齐。
### Q6 · Q1 与规格清单缺口的连带裁(**已裁=甲**)
**裁定(2026-10-18)**:甲——Q1 裁 A 同时订过渡口径:「过渡尺寸档=现役 1280 工程档+烛光黄 #F6C667/木色 #8A5A34 既有规格;终档归样张批冻结后置换(反哺点登记)」。推荐案,用户令按推荐执行。若 Q1 裁 B(插画级新产),过渡口径不成立——B 依赖规格清单,须走乙案「T1 等样张批规格清单产出才开」或用户另行裁定过渡规格。
---
**审查回写要点**:v1.0→v1.1(2026-10-18 grilling 子 Agent 对抗审查回写)——事实订正 6 处:E1「48 色工具全仓不在役」→截屏级不在役/素材级二器在役(F17/§9-5/V10/T5 连带);E2「camp golden」五处不存在→删并立契约 10 不建;E3 F7 行号(_start_adventure :579-597 等);E4 F14 .gitignore:51+「恒无」表述订正;E5 存档序列化 :122→:121(卡⑤同订);E6 行号微漂(ui_struct_probe :41-49、smoke_all :170-171、camp.md :19-20)。自扩订正:契约 10 标仓库纪律成文。卡内可收 15 项:presenter 承接面(T3/契约 4)、叠层规则派生(T2/§9-2)、ConfirmDialog 消费方编排(T4)、生涯探针驱动改缆+返回钮文案坑(T3/T5)、图鉴占位态(T3)、screen_flow 键新语义(T5)、HUD 刷新单口(T2/T3)、深员改指表(T5)、源码断言段重写(T5)、shot_probe 收闭改缆(T5)、forge_workbench_test 迁移+§5 补 tests 可写面(T5/§5)、断点确认段补列(F8/T5)、contrast 段核签(T5)、素材命名指针(T1)、终稿落盘口径(T1/契约 9/§5)。跨卡对齐:HUD 刷新挂点(§0 接口+卡⑤订正)、ConfirmDialog 类事实双向失效(Q5)、开层互斥/关层收闭(T3+卡③ T2)、探针文件分界(T5)、`_refresh_resume_button` 不复用(T4)。验收补:V1 拆半、V3 扩、V4 扩、V12 留痕行、变异补二条。新增待裁点 Q5 三出口弹窗、Q6 规格缺口连带;估时 8.5–11.5d→9–12d。用户面裁决(①④⑤裁决 5/10)零改动。
+4 -5
View File
@@ -5,8 +5,8 @@
## 当前位(只回答「现在该做什么」;三行内随批次换代,禁止在此扩写成状态快照)
- **阶段**:M3——Alpha 版本的完整实现(2026-10-09 立规:未明令宣布完成前停留 M3,迭代只排 M3 需求,M4 不排期;根目录 stage.txt 为旧阶段开关仅存档)。
- **迭代位**:迭代 1–45 全部已完成——迭代 45(呈现层状态件+gdstyle 尾波补件两卡)2026-10-31 合回(合并提交 f817ab2d,独立验收审计通过零缺漏,行为零变化),批后收尾闭合(2026-10-31):反哺点七条处置闭合(architecture 六条落文=breakpoint_store/board_hover/单格两件/站桩两件四行现状化+构造句改述与 7 项引用束/15 贴顶实况+gdstyle 截断缺陷节清偿结果;第 7 条工具观察迁待办新条)、目检三项登记体验验证清单 ㊸、产出物退役九件(两报告/反哺点/审计/两停机呈报+两卡+两设计文档)、worktree 两件清理(iter45+assert-slim-b2)。迭代 44 收尾记录见 git 提交 9eedf896。
- **下一步**:迭代 46 进行中〔用户裁拆批 2026-10-31〕——卡A 换图系双基座七件批+卡B 站桩名字行提档与地台色合并批已收口,代码域闸全绿且独立验收审计通过,合回与 CI 待发令;卡C 棋盘格边长口径收口批停摆退回写卡段:触发卡片 L3 #2 停机点,14×14 板基座档实测 28px 低于 battle.md 可读下限 30px、系存量事实首测非本批回归,读数与读法甲/乙裁决点见 reports/停机呈报-棋盘格边长口径收口批-2026-10-31.md,裁决后重立卡。待编池:营地交互重做卡⑤(排卡④之后)、卡④(美术设计已闭合=样张过审 2026-10-31+art-bible v3.24 §6.2,待用户发令重立卡)、冒险前资源配比预设(冻结备选)、迭代 30 原卡②③(2026-10-17 已剔出迭代 30 规划、退回待设计,待美术/设计定稿后重新立卡)。
- **迭代位**:迭代 1–43 全部已完成——迭代 43(战斗一屏样张批)2026-10-30 合回(合并提交 3b66d1a6),同日完成批后收尾(反哺点 13 条处置闭合:落文四处 art-bible v3.23/art-prompts v2.10/战斗表现 v1.2/test-conventions 旧句清偿,消解三条,移交待办清单两条目;产出物与两卡需求卡片退役;方向稿目检登记体验验证清单 ㊶)。迭代 42 收尾记录见 git 提交 7ec2af58。
- **下一步**:迭代 44 待开工(组合根注册面+战斗编排归约+测速循环三卡,编队前置=迭代 42 合回已满足)——开工前宜裁 PARITY 对拍漂移查因/重锚(闸 11 触面)与迭代 43 批后待裁三点(待办清单在册)。待编池:营地交互重做卡⑤(排卡④之后)、卡④(已退回美术设计段,美术设计闭合后重立卡)、冒险前资源配比预设(冻结备选)、迭代 30 原卡②③(2026-10-17 已剔出迭代 30 规划、退回待设计,待美术/设计定稿后重新立卡)。批后可裁事项:gdstyle 基线 refresh 收账随零豁免各批合回一次人工 `--refresh --force`(待办清单在册)。
## 里程碑时间线
@@ -77,9 +77,8 @@
| 迭代 41 | 已完成(2026-10-29) | 已退役(git 历史可考) | 2026-10-27 | ≈13.15 个工作日〔用户特批 2026-10-27 超 10 个工作日〕 | 已退役(git 历史可考) |
| 迭代 42 | 已完成(2026-10-29) | 已退役(git 历史可考) | 2026-10-29 | ≈5.375 个工作日 | 已退役(git 历史可考) |
| 迭代 43 | 已完成(2026-10-30) | 已退役(git 历史可考) | 2026-10-29 | ≈6.5 个工作日 | 已退役(git 历史可考) |
| 迭代 44 | 已完成(2026-10-30) | 已退役(git 历史可考) | 2026-10-29 | ≈7.875 个工作日 | 已退役(git 历史可考) |
| 迭代 45 | 已完成(2026-10-31) | 已退役(git 历史可考) | 2026-10-29 | ≈7 个工作日 | 已退役(git 历史可考) |
| 迭代 46 | 进行中 | reports/需求卡片-换图系双基座七件批-2026-10-31.md<br>reports/需求卡片-站桩名字行提档与地台色合并批-2026-10-31.md | 2026-10-31 | ≈8.625 个工作日 | — |
| 迭代 44 | 待开工 | reports/需求卡片-组合根注册面批-2026-10-29.md<br>reports/需求卡片-战斗编排归约批-2026-10-29.md<br>reports/需求卡片-测速循环批-2026-10-29.md | 2026-10-29 | ≈7.875 个工作日 | — |
| 迭代 45 | 待开工 | reports/需求卡片-呈现层状态件批-2026-10-29.md<br>reports/需求卡片-gdstyle尾波补件批-2026-10-29.md | 2026-10-29 | ≈7 个工作日 | — |
- 迭代 38 收口为带红合并〔用户特批 2026-10-26〕:09 静态扫描 S13 gdstyle 恶化 2 条经批准记入基线存量红(git 提交 c4c69701),卡② 停卡退上游,处方已于 2026-10-26 修订定稿 v1.3(git 提交 b3ea7532),随「gdstyle 存量债全量清偿」条目波 7 待编排。
- 迭代 39 收口为带红合并〔用户特批 2026-10-27〕:02 EV 锚 goblin 0.9148∉[1.00,1.20](触发器批有意行为改动,fp f74b9a48ef4a)已随 EV 锚重锚批换带归绿(git 提交 ba5105aa);08d 生涯.md:55 行号漂移已随 2026-10-28 批后收尾反哺落文修复归绿。三卡拆分后终局 gdstyle 恶化 2 条(battle_orchestrator max-file-length、level_map_screen max-class-variables)归迭代 40 卡①还债与迭代 41 存量债序列。
+1 -6
View File
@@ -69,12 +69,7 @@ entry = {"commit": tip,
try:
with open(gates_dir + "/receipt.json", encoding="utf-8") as f:
r = json.load(f)
# 回执只有确属本跑(commit 对齐)才采信——闸在起手自检即中止时不写新回执,
# 盘上旧回执是上一跑的读数,当作本次红项会撒谎(2026-10-31 实跑缺陷修正)
if r.get("commit") == tip:
entry["red_gates"] = [g["name"] for g in r.get("gates", []) if str(g.get("exit")) != "0"]
else:
entry["note"] = "闸未跑完(起手自检或早期中止,回执为上一跑旧件)——红项读数不可用,看 key_lines 与 ci.log"
entry["red_gates"] = [g["name"] for g in r.get("gates", []) if str(g.get("exit")) != "0"]
except Exception:
pass
try:
+14 -3
View File
@@ -5,8 +5,19 @@
# 判定=键不在基线红(NEW)、同键数值较登记值恶化红(WORSENED)、改小/持平不红。
# 重生成=人工专用:python tools/gdstyle_gate.py --refresh(禁清基线换绿;改规则口径/工具升级须随批
# 重生成;新键数较旧基线少逾 10% 须加 --force 显式确认)。
game/core/adventure_runner.gd|quality/max-class-variables = 23
game/core/adventure_runner.gd|quality/max-class-variables = 28
game/core/battle_orchestrator.gd|quality/max-class-variables = 38
game/core/battle_orchestrator.gd|quality/max-file-length = 1035
game/core/level_runner.gd|quality/max-class-variables = 30
game/core/level_runner.gd|quality/max-public-methods = 33
game/presentation/views/board_view.gd|quality/max-class-variables = 31
game/core/level_runner.gd|quality/max-public-methods = 50
game/core/level_runner.gd|quality/max-returns|_enter_node = 7
game/presentation/main.gd|quality/max-class-variables = 49
game/presentation/tune_sim_controller.gd|quality/await-in-loop|'await' used inside a loop
game/presentation/views/board_cell_unit.gd|quality/max-class-variables = 30
game/presentation/views/board_view.gd|quality/allocation-in-loop|object allocation '.new()' inside a loop
game/presentation/views/board_view.gd|quality/max-branches|_paint_cell = 24
game/presentation/views/board_view.gd|quality/max-class-variables = 32
game/presentation/views/board_view.gd|quality/max-function-length|_paint_cell = 139
game/presentation/views/board_view.gd|quality/max-local-variables|_paint_cell = 22
game/presentation/views/board_view.gd|quality/max-public-methods = 27
game/presentation/views/standee_body.gd|quality/max-class-variables = 19
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
# 直改车道闸(git pre-commit,2026-10-30 本地 CI 化换代)——提交点现场跑文档域闸
# (tools/run_all_gates.sh --docs,秒级文本扫描):绿=落地,红=中止。
# 代码面提交不再拦(2026-10-30 用户裁:主区直改全面放开)——代码验证归合回后的本地 CI
# (tools/hooks/post-merge 全量跑批;CI 红态下 tools/hooks/post-commit 追绿复验)。
# 合并收尾提交跳过(MERGE_HEAD 在=冲突合并的收尾 commit)——内容归合回后的 CI 全量验。
# --no-verify 绕过仅属用户(agent 侧由 worktree-guard 拦截)。
set -u
REPO="$(git rev-parse --show-toplevel)"
# 合并收尾提交:跳过文档闸,交合回后 CI
[ -f "$(git rev-parse --git-dir)/MERGE_HEAD" ] && exit 0
RC=0
bash "$REPO/tools/run_all_gates.sh" --docs || RC=$?
if [ "$RC" -eq 0 ]; then
exit 0
elif [ "$RC" -eq 1 ]; then
echo "[直改闸] 文档域闸有新增红,提交已拦。修上方红项后重新 commit,钩子会自动重跑闸;禁跑代码域/游戏类测试,与本次红项无关。" >&2
else
echo "[直改闸] 闸脚本自身故障(退出码 $RC),不是文档红——把本输出原样呈报用户,勿改文档、勿跑替代测试。" >&2
fi
exit 1
-24
View File
@@ -1,24 +0,0 @@
# -*- coding: utf-8 -*-
"""战斗屏布局表读取(`game/data/tables/battle_layout.tres` 单点)。
样张渲染工具不另立布局常量:B 区高 / C 区宽 / AP 条高 / 明细带两态高一律读该表,
与游戏侧 `ConfigDb.presentation.battle_layout` 同源。
"""
import os
import re
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TABLE_PATH = os.path.join(ROOT, "game", "data", "tables", "battle_layout.tres")
FIELDS = ("stage_h", "info_panel_w", "ap_bar_h", "log_band_h_dig", "log_band_h_settle")
def load(path=TABLE_PATH):
with open(path, encoding="utf-8") as f:
text = f.read()
vals = {}
for key in FIELDS:
m = re.search(r"^%s\s*=\s*(\d+)\s*$" % key, text, re.M)
if m is None:
raise ValueError("battle_layout.tres 缺字段或非整数值: %s" % key)
vals[key] = int(m.group(1))
return vals
Loaded 100 of 105 files, more files were not shown because too many files have changed in this diff. Show more